diff options
1712 files changed, 28549 insertions, 9374 deletions
diff --git a/.editorconfig b/.editorconfig deleted file mode 100644 index 9ac24be468..0000000000 --- a/.editorconfig +++ /dev/null @@ -1,14 +0,0 @@ -root = true - -[*] -charset = utf-8 -indent_size = 4 -indent_style = space -insert_final_newline = true -trim_trailing_whitespace = true - -[Makefile] -indent_style = tab - -[*.{yml,yaml}] -indent_size = 2 diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 7d6bcd2bc4..50b0cf02bc 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -42,8 +42,8 @@ jobs: needs: setup strategy: matrix: - runner: [windows-large, macos-12-large] - configuration: ${{ fromJSON(needs.setup.outputs.configurations) }} + runner: ${{ fromJson((github.ref_type == 'tag' && startsWith(github.ref, 'refs/tags/Second_Life')) && '["windows-large","macos-15-xlarge"]' || '["windows-latest","macos-15"]') }} + configuration: ${{ fromJson(needs.setup.outputs.configurations) }} runs-on: ${{ matrix.runner }} outputs: viewer_channel: ${{ steps.build.outputs.viewer_channel }} @@ -64,7 +64,7 @@ jobs: # autobuild-package.xml. AUTOBUILD_VCS_INFO: "true" AUTOBUILD_VSVER: "170" - DEVELOPER_DIR: "/Applications/Xcode_14.0.1.app/Contents/Developer" + DEVELOPER_DIR: "/Applications/Xcode_16.1.app/Contents/Developer" # Ensure that Linden viewer builds engage Bugsplat. BUGSPLAT_DB: ${{ needs.setup.outputs.bugsplat_db }} build_coverity: false diff --git a/.github/workflows/cla.yaml b/.github/workflows/cla.yaml index 013adc9ca8..7866f943b5 100644 --- a/.github/workflows/cla.yaml +++ b/.github/workflows/cla.yaml @@ -23,4 +23,4 @@ jobs: path-to-signatures: signatures.json remote-organization-name: secondlife remote-repository-name: cla-signatures - allowlist: callum@mbp.localdomain + allowlist: callum@mbp.localdomain,rye@lindenlab.com diff --git a/.github/workflows/tag-release.yaml b/.github/workflows/tag-release.yaml index 65d1d43a83..24ee2de794 100644 --- a/.github/workflows/tag-release.yaml +++ b/.github/workflows/tag-release.yaml @@ -37,7 +37,12 @@ jobs: - name: Update Tag uses: actions/github-script@v7.0.1 with: - github-token: ${{ secrets.GITHUB_TOKEN }} + # use a real access token instead of GITHUB_TOKEN default. + # required so that the results of this tag creation can trigger the build workflow + # https://stackoverflow.com/a/71372524 + # https://docs.github.com/en/actions/using-workflows/triggering-a-workflow#triggering-a-workflow-from-a-workflow + # this token will need to be renewed anually in January + github-token: ${{ secrets.LL_TAG_RELEASE_TOKEN }} script: | github.rest.git.createRef({ owner: context.repo.owner, diff --git a/.gitignore b/.gitignore index 3b3666af84..c4b559f016 100755 --- a/.gitignore +++ b/.gitignore @@ -21,12 +21,13 @@ CMakeCache.txt cmake_install.cmake LICENSES build-darwin-* +build-freebsd-* build-linux-* +build-mingw-* debian/files debian/secondlife-appearance-utility* debian/secondlife-viewer* indra/.distcc -indra/cmake/* indra/out/* indra/packages/* diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 6bd8a2b74c..d75a765a61 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,8 +1,8 @@ # Contributor guidelines -Thanks for your interest in contributing to Second Life! This document +Thanks for your interest in contributing to Megapahit! This document summarizes some of the most important points for people looking to contribute -to the platform especially those looking to provide bug reports and code +to the project especially those looking to provide bug reports and code changes. ## Table of contents @@ -13,46 +13,40 @@ changes. ## Communication -Second Life has multiple channels for communication. Some of these channels are +Megapahit has multiple channels for communication. Some of these channels are more end-user focused, while others are more tailored for developer-to-developer or support. -- [feedback.secondlife.com][] is Second Life's primary community engagement +- [Bugzilla][] is Megapahit's primary community engagement forum. Ideas and bug reports should be placed here unless they relate to ongoing development issues and developer-to-developer communication. -- [Public user groups][slug] are held on a regular basis, including those for - discussing open source development, content creation, server topics and more. +- [IRC][] is publishing updates on a regular basis, including those for + announcing Git commit logs, nightly build URLs and more. - [Github issues][] provide a means for staff to organize their work and collaborate with other developers. By default most user-facing - discussions should happen on [feedback.secondlife.com][] so that they are + discussions should happen on [Bugzilla][] so that they are visible to more people, can build consensus, and be placed onto our public roadmap. Github issues are useful for collaboration between viewer forks and the official upstream and when engineering-specific and technical collaboration is beneficial. -- [Official forums][] exist for many topics including content creation, - scripting, social topics and more. -- The [opensource-dev mailing list][] is useful for announcements and +- The [in-world group][] exists for many topics including content creation, + scripting, social topics and more, and are useful for announcements and discussion between viewer maintainers. +- Our [Discord][] is available for real-time discussion. ## Reporting bugs and requesting features -Report bugs and provide ideas for features using the respective board on Second -Life's feedback portal: +Report bugs and provide ideas for features using the respective board on Megapahit's +feedback portal: -- [Features](https://feedback.secondlife.com/feature-requests) -- [Scripting bugs](https://feedback.secondlife.com/scripting-bugs) -- [Scripting features](https://feedback.secondlife.com/scripting-features) -- [Server bugs](https://feedback.secondlife.com/scripting-bugs) -- [Viewer bugs](https://feedback.secondlife.com/bug-reports) -- [Web/Marketplace bugs](https://feedback.secondlife.com/web-bugs) -- [Web/Marketplace features](https://feedback.secondlife.com/web-features) +- [Viewer bugs and features](https://megapahit.com/enter_bug.cgi?product=Viewer) -Creating posts on feedback.secondlife.com is important as it allows the greatest -exposure and input from Second Life users. It also allows Linden Lab staff to +Creating posts on Bugzilla is important as it allows the greatest +exposure and input from Second Life users. It also allows Megapahit staff to place work on a single public roadmap. -Issues created on feedback.secondlife.com are imported onto Github after they +Issues created on Github or Discord are imported onto Bugzilla after they have been reviewed by staff and accepted. ## Contributing pull requests @@ -60,7 +54,7 @@ have been reviewed by staff and accepted. If you wish to contribute a new pull request, please ensure that: - You talk to other developers about how best to implement the work. -- The functionality is desired. Be sure to talk to users and Second Life staff to ensure +- The functionality is desired. Be sure to talk to users and Megapahit staff to ensure the work is a good idea and will be accepted. - The work is high quality and the PR follows [PR etiquette][] - You have tested the work locally @@ -68,9 +62,9 @@ If you wish to contribute a new pull request, please ensure that: The [Git Style Guide](https://github.com/agis/git-style-guide) is also a good reference for best git practices. -[feedback.secondlife.com]: https://feedback.secondlife.com -[slug]: https://community.secondlife.com/blogs/entry/6509-introducing-the-second-life-public-calendar/ +[Bugzilla]: https://megapahit.com +[IRC]: irc://megapahit.net/#viewer [PR etiquette]: https://gist.github.com/mikepea/863f63d6e37281e329f8 -[Github issues]: https://github.com/secondlife/viewer/issues -[Official forums]: https://community.secondlife.com/forums/ -[opensource-dev mailing list]: https://wiki.secondlife.com/wiki/OpenSource-Dev +[Github issues]: https://github.com/megapahit/viewer/issues +[in-world group]: https://world.secondlife.com/group/1142646c-5fb2-162c-ecf8-c5e422ab5c6d +[Discord]: https://discord.gg/jpt33HPVEK @@ -1,44 +1,133 @@ -<picture> - <source media="(prefers-color-scheme: dark)" srcset="doc/sl-logo-dark.png"> - <source media="(prefers-color-scheme: light)" srcset="doc/sl-logo.png"> - <img alt="Second Life Logo" src="doc/sl-logo.png"> -</picture> +## Third Party Viewer -**[Second Life][] is a free 3D virtual world where users can create, connect and chat with others from around the -world.** This repository contains the source code for the official client. - -## Open Source - -Second Life provides a huge variety of tools for expression, content creation, socialization and play. Its vibrancy is -only possible because of input and contributions from its residents. The client codebase has been open source since -2007 and is available under the LGPL license. The [Open Source Portal][] contains additional information about Linden -Lab's open source history and projects. +As a third party maintained fork of the [Second Life][] viewer, which includes Apple Silicon native builds, Megapahit viewer is indexed in the [Third Party Viewer Directory][tpv]. ## Download -Most people use a pre-built viewer release to access Second Life. Windows and macOS builds are +Most people use a pre-built viewer release to access Second Life. macOS, GNU/Linux and FreeBSD builds are [published on the official website][download]. More experimental viewers, such as release candidates and -project viewers, are detailed on the [Alternate Viewers page](https://releasenotes.secondlife.com/viewer.html). +project viewers, would be detailed on the same page, [in-world group][] notices, or [Discord][] server. -### Third Party Viewers +## Build Instructions -Third party maintained forks, which include Linux compatible builds, are indexed in the [Third Party Viewer Directory][tpv]. +``` +$ git clone git://megapahit.org/viewer.git +$ cd viewer +$ mkdir build-`uname -s|tr '[:upper:]' '[:lower:]'`-`uname -m` +$ cd build-`uname -s|tr '[:upper:]' '[:lower:]'`-`uname -m` +``` -## Build Instructions +### Arch +``` +$ sudo pacman -S cmake base-devel python apr-util boost fltk glm glu hunspell minizip nanosvg libnghttp2 libpipewire sdl2 vlc libvorbis xxhash +$ export LL_BUILD="-O3 -std=c++20 -fPIC -DLL_LINUX=1" +$ cmake -DCMAKE_BUILD_TYPE:STRING=Release -DADDRESS_SIZE:STRING=64 -DUSESYSTEMLIBS:BOOL=ON -DUSE_OPENAL:BOOL=OFF -DUSE_FMODSTUDIO:BOOL=ON -DENABLE_MEDIA_PLUGINS:BOOL=ON -DLL_TESTS:BOOL=OFF -DNDOF:BOOL=ON -DROOT_PROJECT_NAME:STRING=Megapahit -DVIEWER_CHANNEL:STRING=Megapahit -DVIEWER_BINARY_NAME:STRING=megapahit -DBUILD_SHARED_LIBS:BOOL=OFF -DINSTALL:BOOL=ON -DPACKAGE:BOOL=ON -DCMAKE_INSTALL_PREFIX:PATH=/usr ../indra +$ make -j`nproc` +$ makepkg -R +$ sudo pacman -U megapahit-`cat newview/viewer_version.txt|sed 's/\(.*\)\./\1-/'`-`uname -m`.pkg.tar.zst +$ megapahit +``` + +### Debian + +``` +$ sudo apt install cmake pkg-config libxml2-utils libalut-dev libaprutil1-dev libboost-fiber1.81-dev libboost-json1.81-dev libboost-program-options1.81-dev libboost-regex1.81-dev libboost-url1.81-dev libexpat1-dev libfltk1.3-dev libfontconfig-dev libfreetype-dev libglu1-mesa-dev libhunspell-dev libjpeg-dev libmeshoptimizer-dev libminizip-dev libnghttp2-dev libpipewire-0.3-dev libpng-dev libsdl2-dev libvlc-dev libvlccore-dev libvorbis-dev libxft-dev libxml2-dev libxxhash-dev +$ export LL_BUILD="-O3 -std=c++20 -fPIC -DLL_LINUX=1" +$ cmake -DCMAKE_BUILD_TYPE:STRING=Release -DADDRESS_SIZE:STRING=64 -DUSESYSTEMLIBS:BOOL=ON -DUSE_OPENAL:BOOL=ON -DUSE_FMODSTUDIO:BOOL=OFF -DENABLE_MEDIA_PLUGINS:BOOL=ON -DLL_TESTS:BOOL=OFF -DNDOF:BOOL=ON -DROOT_PROJECT_NAME:STRING=Megapahit -DVIEWER_CHANNEL:STRING=Megapahit -DVIEWER_BINARY_NAME:STRING=megapahit -DBUILD_SHARED_LIBS:BOOL=OFF -DINSTALL:BOOL=ON -DPACKAGE:BOOL=ON ../indra +$ make -j`nproc` +$ cpack -G DEB +$ sudo apt install ./megapahit-`cat newview/viewer_version.txt`-Linux.deb +$ megapahit +``` + +### Fedora + +``` +$ sudo dnf install cmake gcc-c++ patch patchelf rpm-build perl-FindBin apr-util-devel boost-devel boost-url expat-devel fltk-devel glm-devel mesa-libGLU-devel hunspell-devel minizip-ng-compat-devel libnghttp2-devel nanosvg-devel pipewire-devel pulseaudio-libs-devel SDL2-devel vlc-devel libvorbis-devel libXcursor-devel libXfixes-devel libXinerama-devel xxhash-devel +$ export LL_BUILD="-O3 -std=c++20 -fPIC -DLL_LINUX=1" +$ cmake -DCMAKE_BUILD_TYPE:STRING=Release -DADDRESS_SIZE:STRING=64 -DUSESYSTEMLIBS:BOOL=ON -DUSE_OPENAL:BOOL=OFF -DUSE_FMODSTUDIO:BOOL=ON -DENABLE_MEDIA_PLUGINS:BOOL=ON -DLL_TESTS:BOOL=OFF -DNDOF:BOOL=ON -DROOT_PROJECT_NAME:STRING=Megapahit -DVIEWER_CHANNEL:STRING=Megapahit -DVIEWER_BINARY_NAME:STRING=megapahit -DBUILD_SHARED_LIBS:BOOL=OFF -DINSTALL:BOOL=ON -DPACKAGE:BOOL=ON ../indra +$ make -j`nproc` +$ cpack -G RPM +$ sudo dnf install megapahit-`cat newview/viewer_version.txt`-Linux.rpm +$ megapahit +``` + +### FreeBSD +``` +$ sudo su - +# portmaster devel/cmake devel/pkgconf audio/freealut devel/apr1 devel/boost-libs x11-toolkits/fltk math/glm textproc/hunspell misc/meshoptimizer archivers/minizip graphics/nanosvg www/libnghttp2 devel/sdl20 multimedia/vlc audio/libvorbis devel/xxhash +# exit +$ setenv LL_BUILD "-O3 -std=c++20 -fPIC" +$ cmake -DCMAKE_BUILD_TYPE:STRING=Release -DADDRESS_SIZE:STRING=64 -DUSESYSTEMLIBS:BOOL=ON -DUSE_OPENAL:BOOL=ON -DUSE_FMODSTUDIO:BOOL=OFF -DENABLE_MEDIA_PLUGINS:BOOL=ON -DLL_TESTS:BOOL=OFF -DNDOF:BOOL=OFF -DROOT_PROJECT_NAME:STRING=Megapahit -DVIEWER_CHANNEL:STRING=Megapahit -DVIEWER_BINARY_NAME:STRING=megapahit -DBUILD_SHARED_LIBS:BOOL=OFF -DINSTALL:BOOL=ON -DPACKAGE:BOOL=ON ../indra +$ make -j`nproc` +$ sudo cpack -G FREEBSD +$ sudo pkg add megapahit-`cat newview/viewer_version.txt`-FreeBSD.pkg +$ sudo pkg set -yA 1 freealut apr1 fltk hunspell meshoptimizer minizip nanosvg sdl20 vlc libvorbis +$ megapahit +``` + +### Gentoo +``` +$ su - +# eselect repository add megapahit git git://megapahit.org/ebuild.git +# emaint sync -r megapahit +# emerge -a megapahit +# exit +$ megapahit +``` + +### macOS + +``` +$ sudo port install cmake pkgconfig freealut +universal apr-util +universal boost187 +universal glm hunspell +universal freetype +universal libjpeg-turbo +universal minizip +universal libvorbis +universal xxhashlib +$ export LL_BUILD="-O3 -gdwarf-2 -stdlib=libc++ -mmacosx-version-min=11 -iwithsysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk -std=c++20 -fPIC -DLL_RELEASE=1 -DLL_RELEASE_FOR_DOWNLOAD=1 -DNDEBUG -DPIC -DLL_DARWIN=1" +$ cmake -DCMAKE_BUILD_TYPE:STRING=Release -DADDRESS_SIZE:STRING=64 -DUSESYSTEMLIBS:BOOL=ON -DUSE_OPENAL:BOOL=ON -DUSE_FMODSTUDIO:BOOL=OFF -DENABLE_MEDIA_PLUGINS:BOOL=ON -DLL_TESTS:BOOL=OFF -DNDOF:BOOL=ON -DROOT_PROJECT_NAME:STRING=Megapahit -DVIEWER_CHANNEL:STRING=Megapahit -DVIEWER_BINARY_NAME:STRING=megapahit -DBUILD_SHARED_LIBS:BOOL=OFF -DINSTALL:BOOL=ON -DPACKAGE:BOOL=OFF -DCMAKE_INSTALL_PREFIX:PATH=newview/Megapahit.app/Contents/Resources -DCMAKE_OSX_ARCHITECTURES:STRING=`uname -m` -DCMAKE_OSX_DEPLOYMENT_TARGET:STRING=11 -DENABLE_SIGNING:BOOL=ON -DSIGNING_IDENTITY:STRING=- ../indra +$ make -j`sysctl -n hw.ncpu` +$ make install +$ open newview/Megapahit.app +``` + +### openSUSE Tumbleweed + +``` +$ sudo zypper install gcc-c++ patchelf apr-util-devel boost-devel libboost_program_options-devel libboost_url1_87_0-devel libboost_context-devel libboost_fiber-devel libboost_filesystem-devel libboost_regex-devel libboost_system-devel libboost_thread-devel libexpat-devel fltk-devel glu-devel hunspell-devel minizip-devel nanosvg-devel libnghttp2-devel pipewire-devel libpulse-devel libSDL2_gfx-1_0-0 libSDL2_gfx-devel sdl2-compat-devel vlc-devel libvorbis-devel xxhash-devel zlib-ng-devel libXrender-devel libXcursor-devel libXfixes-devel libXext-devel libXft-devel libXinerama-devel freetype2-devel fontconfig-devel libjpeg8-devel libjpeg8-devel freealut-devel +$ export LL_BUILD="-O3 -std=c++20 -fPIC -DLL_LINUX=1" +$ cmake -DCMAKE_BUILD_TYPE:STRING=Release -DADDRESS_SIZE:STRING=64 -DUSESYSTEMLIBS:BOOL=ON -DUSE_OPENAL:BOOL=ON -DENABLE_MEDIA_PLUGINS:BOOL=ON -DLL_TESTS:BOOL=OFF -DNDOF:BOOL=ON -DROOT_PROJECT_NAME:STRING=Megapahit -DVIEWER_CHANNEL:STRING=Megapahit -DVIEWER_BINARY_NAME:STRING=megapahit -DBUILD_SHARED_LIBS:BOOL=OFF -DINSTALL:BOOL=ON -DPACKAGE:BOOL=ON ../indra +$ make -j`nproc` +$ cpack -G RPM +$ rpm --addsign megapahit-`cat newview/viewer_version.txt`-Linux.rpm (Set up pgp public key first) +$ sudo rpm -i megapahit-`cat newview/viewer_version.txt`-Linux.rpm +$ megapahit +``` -[Windows](https://wiki.secondlife.com/wiki/Build_the_Viewer_on_Windows) +### Ubuntu -[Mac](https://wiki.secondlife.com/wiki/Build_the_Viewer_on_macOS) +``` +$ sudo apt install cmake pkg-config libxml2-utils libaprutil1-dev libboost-fiber-dev libboost-json-dev libboost-program-options-dev libboost-regex-dev libboost-url-dev libexpat1-dev libfltk1.3-dev libfontconfig-dev libfreetype-dev libglu1-mesa-dev libhunspell-dev libjpeg-dev libmeshoptimizer-dev libminizip-dev libnanosvg-dev libnghttp2-dev libpipewire-0.3-dev libpng-dev libsdl2-dev libvlc-dev libvlccore-dev libvorbis-dev libxft-dev libxml2-dev libxxhash-dev +$ export LL_BUILD="-O3 -std=c++20 -fPIC -DLL_LINUX=1" +$ cmake -DCMAKE_BUILD_TYPE:STRING=Release -DADDRESS_SIZE:STRING=64 -DUSESYSTEMLIBS:BOOL=ON -DUSE_OPENAL:BOOL=OFF -DUSE_FMODSTUDIO:BOOL=ON -DENABLE_MEDIA_PLUGINS:BOOL=ON -DLL_TESTS:BOOL=OFF -DNDOF:BOOL=ON -DROOT_PROJECT_NAME:STRING=Megapahit -DVIEWER_CHANNEL:STRING=Megapahit -DVIEWER_BINARY_NAME:STRING=megapahit -DBUILD_SHARED_LIBS:BOOL=OFF -DINSTALL:BOOL=ON -DPACKAGE:BOOL=ON ../indra +$ make -j`nproc` +$ cpack -G DEB +$ sudo apt install ./megapahit-`cat newview/viewer_version.txt`-Linux.deb +$ megapahit +``` -[Linux](https://wiki.secondlife.com/wiki/Build_the_Viewer_on_Linux) +### Windows +``` +$ pacman -S mingw-w64-clang-aarch64-cmake mingw-w64-clang-aarch64-pkgconf mingw-w64-clang-aarch64-freealut mingw-w64-clang-aarch64-apr-util mingw-w64-clang-aarch64-boost mingw-w64-clang-aarch64-fltk mingw-w64-clang-aarch64-glm mingw-w64-clang-aarch64-hunspell mingw-w64-clang-aarch64-minizip mingw-w64-clang-aarch64-nghttp2 mingw-w64-clang-aarch64-SDL2 mingw-w64-clang-aarch64-vlc mingw-w64-clang-aarch64-libvorbis mingw-w64-clang-aarch64-xxhash +$ export LL_BUILD="-O3 -std=c++20 -fPIC -DLL_WINDOWS=1" +$ cmake -DCMAKE_BUILD_TYPE:STRING=Release -DADDRESS_SIZE:STRING=64 -DUSESYSTEMLIBS:BOOL=ON -DUSE_OPENAL:BOOL=ON -DUSE_FMODSTUDIO:BOOL=OFF -DENABLE_MEDIA_PLUGINS:BOOL=OFF -DLL_TESTS:BOOL=OFF -DNDOF:BOOL=OFF -DROOT_PROJECT_NAME:STRING=Megapahit -DVIEWER_CHANNEL:STRING=Megapahit -DVIEWER_BINARY_NAME:STRING=megapahit -DBUILD_SHARED_LIBS:BOOL=OFF -DINSTALL:BOOL=OFF -DPACKAGE:BOOL=OFF ../indra +``` ## Contribute -Help make Second Life better! You can get involved with improvements by filing bugs, suggesting enhancements, submitting +Help make Megapahit better! You can get involved with improvements by filing bugs, suggesting enhancements, submitting pull requests and more. See the [CONTRIBUTING][] and the [open source portal][] for details. [Second Life]: https://secondlife.com/ -[download]: https://secondlife.com/support/downloads/ -[tpv]: http://wiki.secondlife.com/wiki/Third_Party_Viewer_Directory +[download]: https://megapahit.net +[tpv]: http://wiki.secondlife.com/wiki/Third_Party_Viewer_Directory/Megapahit [open source portal]: http://wiki.secondlife.com/wiki/Open_Source_Portal -[contributing]: https://github.com/secondlife/viewer/blob/main/CONTRIBUTING.md +[contributing]: https://megapahit.org/viewer.git/tree/CONTRIBUTING.md +[in-world group]: https://world.secondlife.com/group/1142646c-5fb2-162c-ecf8-c5e422ab5c6d +[Discord]: https://discord.gg/jpt33HPVEK diff --git a/autobuild.xml b/autobuild.xml index 95ee34439b..e22c5a25f2 100644 --- a/autobuild.xml +++ b/autobuild.xml @@ -7,7 +7,7 @@ <string>autobuild</string> <key>installables</key> <map> - <key>SDL</key> + <key>SDL2</key> <map> <key>platforms</key> <map> @@ -16,9 +16,11 @@ <key>archive</key> <map> <key>hash</key> - <string>7ea2df03bfc35c06acf23dd9e734adac</string> + <string>ceb0392106c2f50d79dc724fd5a6d8ec82b92cdb</string> + <key>hash_algorithm</key> + <string>sha1</string> <key>url</key> - <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/1103/2554/SDL-1.2.15-linux64-501092.tar.bz2</string> + <string>https://github.com/secondlife/3p-sdl2/releases/download/v2.28.0-r3/SDL2-2.28.0-linux64-8663899652.tar.zst</string> </map> <key>name</key> <string>linux64</string> @@ -27,16 +29,46 @@ <key>license</key> <string>lgpl</string> <key>license_file</key> - <string>LICENSES/SDL.txt</string> + <string>LICENSES/SDL2.txt</string> <key>copyright</key> - <string>Copyright (C) 1997-2012 Sam Lantinga</string> + <string>Copyright (C) 1997-2022 Sam Lantinga (slouken@libsdl.org)</string> <key>version</key> - <string>1.2.15</string> + <string>2.28.0</string> <key>name</key> - <string>SDL</string> + <string>SDL2</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> </map> + <key>fltk</key> + <map> + <key>platforms</key> + <map> + <key>linux64</key> + <map> + <key>archive</key> + <map> + <key>hash</key> + <string>691fef2ddd57d7b6c26e87fc82d9ace3f54e078c</string> + <key>hash_algorithm</key> + <string>sha1</string> + <key>url</key> + <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> + </map> + </map> + <key>license</key> + <string>LGPL/fltk</string> + <key>license_file</key> + <string>LICENSES/fltk.txt</string> + <key>copyright</key> + <string>Copyright (C) fltk project</string> + <key>version</key> + <string>1.3.5</string> + <key>name</key> + <string>fltk</string> + </map> <key>apr_suite</key> <map> <key>platforms</key> @@ -284,12 +316,14 @@ <key>archive</key> <map> <key>hash</key> - <string>77c53daf558f51aec6e9f4bd9e930a103630ee7d</string> + <string>aea0bed0f953a9371b9091f09230b41597f891f7</string> <key>hash_algorithm</key> <string>sha1</string> <key>url</key> - <string>https://github.com/secondlife/3p-cubemap_to_eqr_js/releases/download/v1.1.0-d7afe27/cubemaptoequirectangular-1.1.0-linux64-d7afe27.tar.zst</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> </map> <key>windows64</key> <map> @@ -330,7 +364,7 @@ <key>hash_algorithm</key> <string>sha1</string> <key>url</key> - <string>https://github.com/secondlife/3p-curl/releases/download/v7.54.1-r1/curl-7.54.1-10342910827-darwin64-10342910827.tar.zst</string> + <string>https://megapahit.net/downloads/curl-7.54.1-10342910827-darwin64-10342910827.tar.zst</string> </map> <key>name</key> <string>darwin64</string> @@ -817,34 +851,6 @@ <key>name</key> <string>gstreamer</string> </map> - <key>gtk-atk-pango-glib</key> - <map> - <key>platforms</key> - <map> - <key>linux64</key> - <map> - <key>archive</key> - <map> - <key>hash</key> - <string>de7bba8fd2275a11b077b124413065d0</string> - <key>url</key> - <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/p64_3p-gtk-atk-pango-glib/rev/314220/arch/Linux/installer/gtk_atk_pango_glib-0.1-linux64-314220.tar.bz2</string> - </map> - <key>name</key> - <string>linux64</string> - </map> - </map> - <key>license</key> - <string>lgpl</string> - <key>license_file</key> - <string>LICENSES/gtk-atk-pango-glib.txt</string> - <key>copyright</key> - <string>Copyright (various, see sources)</string> - <key>version</key> - <string>0.1</string> - <key>name</key> - <string>gtk-atk-pango-glib</string> - </map> <key>havok-source</key> <map> <key>platforms</key> @@ -869,10 +875,14 @@ <map> <key>archive</key> <map> + <key>creds</key> + <string>github</string> <key>hash</key> - <string>00d0333936a67059a43a6ec8ac38d564</string> + <string>ebfb82b6143874e7938b9d1e8a70d0a2e28aa818</string> + <key>hash_algorithm</key> + <string>sha1</string> <key>url</key> - <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/748/1563/havok_source-2012.1-2-linux64-500739.tar.bz2</string> + <string>https://api.github.com/repos/secondlife/3p-havok-source/releases/assets/108912599</string> </map> <key>name</key> <string>linux64</string> @@ -930,11 +940,11 @@ <key>archive</key> <map> <key>hash</key> - <string>35d6a617444fde9c8a5e998ef29dc43b95747637</string> + <string>23daab838f4b8f92e5dc1a2f6c568cb7b0cb43b7</string> <key>hash_algorithm</key> <string>sha1</string> <key>url</key> - <string>https://github.com/secondlife/3p-jpeg_encoder_js/releases/download/v1.0-9165e47/jpegencoderbasic-1.0-linux64-9165e47.tar.zst</string> + <string>https://github.com/secondlife/3p-jpeg_encoder_js/releases/download/v1.0-790015a/jpegencoderbasic-1.0-linux64-790015a.tar.zst</string> </map> </map> <key>windows64</key> @@ -1556,18 +1566,6 @@ <key>name</key> <string>darwin64</string> </map> - <key>linux64</key> - <map> - <key>archive</key> - <map> - <key>hash</key> - <string>711f4ec769e4b5f59ba25ee43c11bcbc</string> - <key>url</key> - <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/4724/14846/llphysicsextensions_stub-1.0.504712-linux64-504712.tar.bz2</string> - </map> - <key>name</key> - <string>linux64</string> - </map> <key>windows64</key> <map> <key>archive</key> @@ -2017,6 +2015,23 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string> </map> <key>open-libndofdev</key> <map> + <key>platforms</key> + <map> + <key>linux64</key> + <map> + <key>archive</key> + <map> + <key>hash</key> + <string>f215c7e1a10f04a2c18cbb837e0039521fd150b6</string> + <key>hash_algorithm</key> + <string>sha1</string> + <key>url</key> + <string>https://github.com/secondlife/3p-open-libndofdev/releases/download/v1.14-r2/open_libndofdev-0.14.8730039102-linux64-8730039102.tar.zst</string> + </map> + <key>name</key> + <string>linux64</string> + </map> + </map> <key>license</key> <string>BSD</string> <key>license_file</key> @@ -2024,7 +2039,7 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string> <key>copyright</key> <string>Copyright (c) 2008, Jan Ciger (jan.ciger (at) gmail.com)</string> <key>version</key> - <string>0.3</string> + <string>0.14.8730039102</string> <key>name</key> <string>open-libndofdev</string> <key>description</key> @@ -2039,11 +2054,11 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string> <key>archive</key> <map> <key>hash</key> - <string>191e4ef07a35f7147708415465191ce7622e3012</string> + <string>a3cc405d48a48a474d05b3de3d28da2005d80037</string> <key>hash_algorithm</key> <string>sha1</string> <key>url</key> - <string>https://github.com/secondlife/3p-openal-soft/releases/download/v1.23.1-8668009/openal-1.23.1-darwin64-8979520327.tar.zst</string> + <string>https://github.com/secondlife/3p-openal-soft/releases/download/v1.24.2-r1/openal-1.24.2-r1-darwin64-13245988487.tar.zst</string> </map> <key>name</key> <string>darwin64</string> @@ -2053,11 +2068,11 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string> <key>archive</key> <map> <key>hash</key> - <string>3bd8c9028ef42bdb43c7422e7d324e213fdb081e</string> + <string>a2b63f0f85ca156c59ee1d34ef96c8e50b89153c</string> <key>hash_algorithm</key> <string>sha1</string> <key>url</key> - <string>https://github.com/secondlife/3p-openal-soft/releases/download/v1.23.1-8668009/openal-1.23.1-linux64-8979520327.tar.zst</string> + <string>https://github.com/secondlife/3p-openal-soft/releases/download/v1.24.2-r1/openal-1.24.2-r1-linux64-13245988487.tar.zst</string> </map> <key>name</key> <string>linux64</string> @@ -2067,11 +2082,11 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string> <key>archive</key> <map> <key>hash</key> - <string>4b849609abec790e89be5fad8ddee3717ee301c4</string> + <string>8ad24fba1191c9cb0d2ab36e64b04b4648a99f43</string> <key>hash_algorithm</key> <string>sha1</string> <key>url</key> - <string>https://github.com/secondlife/3p-openal-soft/releases/download/v1.23.1-8668009/openal-1.23.1-windows64-8979520327.tar.zst</string> + <string>https://github.com/secondlife/3p-openal-soft/releases/download/v1.24.2-r1/openal-1.24.2-r1-windows64-13245988487.tar.zst</string> </map> <key>name</key> <string>windows64</string> @@ -2099,11 +2114,11 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string> <key>archive</key> <map> <key>hash</key> - <string>76444e37be0cfccdbb5921370ba150ded2bf3c59</string> + <string>c16deaf773cb2a5d001732122ee3ec74db1dceeb</string> <key>hash_algorithm</key> <string>sha1</string> <key>url</key> - <string>https://github.com/secondlife/3p-openjpeg/releases/download/v2.5.2-r1/openjpeg-2.5.2.10604495243-darwin64-10604495243.tar.zst</string> + <string>https://github.com/secondlife/3p-openjpeg/releases/download/v2.5.0.ea12248/openjpeg-2.5.0.ea12248-darwin64-ea12248.tar.zst</string> </map> <key>name</key> <string>darwin64</string> @@ -2113,11 +2128,11 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string> <key>archive</key> <map> <key>hash</key> - <string>6bd289a9c4564b80369ce40ecbb24a213c2732ff</string> + <string>8c277dde6076fb682cb07264dd70f6f2298b633f</string> <key>hash_algorithm</key> <string>sha1</string> <key>url</key> - <string>https://github.com/secondlife/3p-openjpeg/releases/download/v2.5.2-r1/openjpeg-2.5.2.10604495243-linux64-10604495243.tar.zst</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> @@ -2127,11 +2142,11 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string> <key>archive</key> <map> <key>hash</key> - <string>5e6e0180adc01e07438cb98daec96543b5d85019</string> + <string>2abf9535adf21ebdf2295f8a680300432abe6280</string> <key>hash_algorithm</key> <string>sha1</string> <key>url</key> - <string>https://github.com/secondlife/3p-openjpeg/releases/download/v2.5.2-r1/openjpeg-2.5.2.10604495243-windows64-10604495243.tar.zst</string> + <string>https://github.com/secondlife/3p-openjpeg/releases/download/v2.5.0.ea12248/openjpeg-2.5.0.ea12248-windows64-ea12248.tar.zst</string> </map> <key>name</key> <string>windows64</string> @@ -2163,7 +2178,7 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string> <key>hash_algorithm</key> <string>sha1</string> <key>url</key> - <string>https://github.com/secondlife/3p-openssl/releases/download/v1.1.1w-r1/openssl-1.1.1w-darwin64-10329796904.tar.zst</string> + <string>https://megapahit.net/downloads/openssl-1.1.1w-darwin64-10329796904.tar.zst</string> </map> <key>name</key> <string>darwin64</string> @@ -2353,11 +2368,11 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string> <key>archive</key> <map> <key>hash</key> - <string>9de1295b157c9913c28be81ff933c73493ecc132</string> + <string>982c0fa427458082ea9e3cb9603904210732b64e</string> <key>hash_algorithm</key> <string>sha1</string> <key>url</key> - <string>https://github.com/secondlife/3p-three_js/releases/download/v0.132.2-b8f6746/threejs-0.132.2-linux64-b8f6746.tar.zst</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> </map> <key>windows64</key> @@ -3014,14 +3029,15 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string> <key>build</key> <map> <key>command</key> - <string>xcodebuild</string> + <string>cmake</string> <key>options</key> <array> - <string>-configuration</string> + <string>--build</string> + <string>.</string> + <string>--config</string> <string>RelWithDebInfo</string> - <string>-project</string> - <string>SecondLife.xcodeproj</string> - <string>-parallelizeTargets</string> + <string>--parallel</string> + <string>$AUTOBUILD_CPU_COUNT</string> </array> </map> <key>default</key> @@ -3042,14 +3058,15 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string> <key>build</key> <map> <key>command</key> - <string>xcodebuild</string> + <string>cmake</string> <key>options</key> <array> - <string>-configuration</string> + <string>--build</string> + <string>.</string> + <string>--config</string> <string>RelWithDebInfo</string> - <string>-project</string> - <string>SecondLife.xcodeproj</string> - <string>-parallelizeTargets</string> + <string>--parallel</string> + <string>$AUTOBUILD_CPU_COUNT</string> </array> </map> <key>name</key> @@ -3072,14 +3089,15 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string> <key>build</key> <map> <key>command</key> - <string>xcodebuild</string> + <string>cmake</string> <key>options</key> <array> - <string>-configuration</string> + <string>--build</string> + <string>.</string> + <string>--config</string> <string>Release</string> - <string>-project</string> - <string>SecondLife.xcodeproj</string> - <string>-parallelizeTargets</string> + <string>--parallel</string> + <string>$AUTOBUILD_CPU_COUNT</string> </array> </map> <key>name</key> @@ -3098,14 +3116,15 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string> <key>build</key> <map> <key>command</key> - <string>xcodebuild</string> + <string>cmake</string> <key>options</key> <array> - <string>-configuration</string> + <string>--build</string> + <string>.</string> + <string>--config</string> <string>Release</string> - <string>-project</string> - <string>SecondLife.xcodeproj</string> - <string>-parallelizeTargets</string> + <string>--parallel</string> + <string>$AUTOBUILD_CPU_COUNT</string> </array> </map> <key>name</key> @@ -3155,6 +3174,7 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string> <string>-G</string> <string>Ninja</string> <string>-DLL_TESTS=Off</string> + <string>-DUSE_OPENAL=On</string> </array> </map> <key>build</key> @@ -45,7 +45,7 @@ build_dir_Darwin() build_dir_Linux() { - echo build-linux-i686 + echo build-linux-x86_64 } build_dir_CYGWIN() @@ -163,6 +163,22 @@ pre_build() fi fi + if [[ "$arch" == "Linux" ]] + then + # RELEASE_CRASH_REPORTING is tuned on unconditionaly, this is fine but not for Linux as of now (due to missing breakpad/crashpad support) + RELEASE_CRASH_REPORTING=OFF + + # Builds turn on HAVOK even when config is ReleaseOS. + # This needs AUTOBUILD_GITHUB_TOKEN to be set in the environment. But this is not set for PRs apparently. + # Still this seemlingy works on Windows and Mac, why not on the Linux runner? Mystery to be solved elsewhere. + + + if [[ "$variant" == "ReleaseOS" ]] + then + HAVOK=OFF + fi + fi + if [ "${RELEASE_CRASH_REPORTING:-}" != "OFF" ] then case "$arch" in @@ -185,9 +201,17 @@ pre_build() # honor autobuild_configure_parameters same as sling-buildscripts eval_autobuild_configure_parameters=$(eval $(echo echo $autobuild_configure_parameters)) + # We build the viewer on Linux, but we haven't committed to support the + # Linux viewer. As of 2024-05-30, Linux build-time test infrastructure is + # not in place, so don't even bother running tests on Linux. + if [[ "$RUNNER_OS" == "Linux" ]] + then LL_TESTS=OFF + else LL_TESTS=ON + fi + "$autobuild" configure --quiet -c $variant \ ${eval_autobuild_configure_parameters:---} \ - -DLL_TESTS:BOOL=ON \ + -DLL_TESTS:BOOL=$LL_TESTS \ -DPACKAGE:BOOL=ON \ -DHAVOK:BOOL="$HAVOK" \ -DRELEASE_CRASH_REPORTING:BOOL="$RELEASE_CRASH_REPORTING" \ @@ -196,6 +220,7 @@ pre_build() -DVIEWER_CHANNEL:STRING="${viewer_channel}" \ -DGRID:STRING="\"$viewer_grid\"" \ -DTEMPLATE_VERIFIER_OPTIONS:STRING="$template_verifier_options" $template_verifier_master_url \ + $CMAKE_OPTIONS \ "${SIGNING[@]}" \ || fatal "$variant configuration failed" diff --git a/indra/CMakeLists.txt b/indra/CMakeLists.txt index 422927704a..5bf08f63aa 100644 --- a/indra/CMakeLists.txt +++ b/indra/CMakeLists.txt @@ -24,11 +24,20 @@ if( USE_CONAN ) set( USE_AUTOBUILD_3P OFF ) conan_basic_setup(TARGETS NO_OUTPUT_DIRS) add_compile_definitions(LL_USESYSTEMLIBS USE_CONAN NO_AUTOBUILD_3P) +elseif( USESYSTEMLIBS ) + set( USE_CONAN OFF ) + set( USE_AUTOBUILD_3P OFF ) + add_compile_definitions(LL_USESYSTEMLIBS) else() set( USE_CONAN OFF ) set( USE_AUTOBUILD_3P ON ) endif() +if (NOT DEFINED CMAKE_CXX_STANDARD) + set(CMAKE_CXX_STANDARD 20) +endif() +set(CMAKE_CXX_STANDARD_REQUIRED ON) + include(Variables) include(BuildVersion) @@ -54,7 +63,9 @@ add_subdirectory(${LIBS_OPEN_PREFIX}llmessage) add_subdirectory(${LIBS_OPEN_PREFIX}llprimitive) add_subdirectory(${LIBS_OPEN_PREFIX}llrender) add_subdirectory(${LIBS_OPEN_PREFIX}llfilesystem) +if (NOT CMAKE_SYSTEM_NAME MATCHES FreeBSD) add_subdirectory(${LIBS_OPEN_PREFIX}llwebrtc) +endif (NOT CMAKE_SYSTEM_NAME MATCHES FreeBSD) add_subdirectory(${LIBS_OPEN_PREFIX}llwindow) add_subdirectory(${LIBS_OPEN_PREFIX}llxml) @@ -112,7 +123,7 @@ else (USE_BUGSPLAT) endif (USE_BUGSPLAT) add_subdirectory(${VIEWER_PREFIX}newview) -add_dependencies(viewer secondlife-bin) +add_dependencies(viewer ${VIEWER_BINARY_NAME}) add_subdirectory(${VIEWER_PREFIX}doxygen EXCLUDE_FROM_ALL) diff --git a/indra/cmake/00-Common.cmake b/indra/cmake/00-Common.cmake index 39f26ced5d..8fd5e4020c 100644 --- a/indra/cmake/00-Common.cmake +++ b/indra/cmake/00-Common.cmake @@ -15,6 +15,7 @@ include_guard() include(Variables) +include(Linker) # We go to some trouble to set LL_BUILD to the set of relevant compiler flags. set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} $ENV{LL_BUILD}") @@ -32,9 +33,13 @@ add_compile_definitions( ADDRESS_SIZE=${ADDRESS_SIZE}) # -- which we do. Without one or the other, we get a ton of Boost warnings. add_compile_definitions(BOOST_BIND_GLOBAL_PLACEHOLDERS) +if(CMAKE_OSX_ARCHITECTURES MATCHES arm64 OR CMAKE_SYSTEM_PROCESSOR MATCHES aarch64) +add_compile_definitions(GLM_FORCE_DEFAULT_ALIGNED_GENTYPES=1 GLM_FORCE_NEON=1 GLM_ENABLE_EXPERIMENTAL=1) +else() # Force enable SSE2 instructions in GLM per the manual # https://github.com/g-truc/glm/blob/master/manual.md#section2_10 -add_compile_definitions(GLM_FORCE_DEFAULT_ALIGNED_GENTYPES=1 GLM_FORCE_SSE2=1) +add_compile_definitions(GLM_FORCE_DEFAULT_ALIGNED_GENTYPES=1 GLM_FORCE_SSE2=1 GLM_ENABLE_EXPERIMENTAL=1) +endif() # Configure crash reporting set(RELEASE_CRASH_REPORTING OFF CACHE BOOL "Enable use of crash reporting in release builds") @@ -48,12 +53,17 @@ if(NON_RELEASE_CRASH_REPORTING) add_compile_definitions( LL_SEND_CRASH_REPORTS=1) endif() +set(USE_LTO OFF CACHE BOOL "Enable Link Time Optimization") +if(USE_LTO) + set(CMAKE_INTERPROCEDURAL_OPTIMIZATION ON) +endif() + # Don't bother with a MinSizeRel or Debug builds. set(CMAKE_CONFIGURATION_TYPES "RelWithDebInfo;Release" CACHE STRING "Supported build types." FORCE) # Platform-specific compilation flags. -if (WINDOWS) +if (NOT CMAKE_CXX_COMPILER_ID MATCHES GNU AND WINDOWS) # Don't build DLLs. set(BUILD_SHARED_LIBS OFF) @@ -101,7 +111,7 @@ if (WINDOWS) #ND: When using something like buildcache (https://github.com/mbitsnbites/buildcache) # to make those wrappers work /Zi must be changed to /Z7, as /Zi due to it's nature is not compatible with caching - if( ${CMAKE_CXX_COMPILER_LAUNCHER} MATCHES ".*cache.*") + if(${CMAKE_CXX_COMPILER_LAUNCHER} MATCHES ".*cache.*") add_compile_options( /Z7 ) string(REPLACE "/Zi" "/Z7" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}") string(REPLACE "/Zi" "/Z7" CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE}") @@ -109,52 +119,109 @@ if (WINDOWS) string(REPLACE "/Zi" "/Z7" CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO}") string(REPLACE "/Zi" "/Z7" CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO}") endif() -endif (WINDOWS) - +endif (NOT CMAKE_CXX_COMPILER_ID MATCHES GNU AND WINDOWS) -if (LINUX) - set(CMAKE_SKIP_RPATH TRUE) +if (LINUX OR CMAKE_SYSTEM_NAME MATCHES "FreeBSD") + set( CMAKE_BUILD_WITH_INSTALL_RPATH TRUE ) + set( CMAKE_INSTALL_RPATH $ORIGIN $ORIGIN/../lib ) + set(CMAKE_EXE_LINKER_FLAGS "-Wl,--exclude-libs,ALL") - # EXTERNAL_TOS - # force this platform to accept TOS via external browser + find_program(CCACHE_EXE ccache) + if(CCACHE_EXE AND NOT DISABLE_CCACHE) + set(CMAKE_C_COMPILER_LAUNCHER ${CCACHE_EXE} ) + set(CMAKE_CXX_COMPILER_LAUNCHER ${CCACHE_EXE} ) + endif() - # LL_IGNORE_SIGCHLD - # don't catch SIGCHLD in our base application class for the viewer - some of - # our 3rd party libs may need their *own* SIGCHLD handler to work. Sigh! The - # viewer doesn't need to catch SIGCHLD anyway. + # LL_IGNORE_SIGCHLD + # don't catch SIGCHLD in our base application class for the viewer - some of + # our 3rd party libs may need their *own* SIGCHLD handler to work. Sigh! The + # viewer doesn't need to catch SIGCHLD anyway. add_compile_definitions( _REENTRANT - _FORTIFY_SOURCE=2 - EXTERNAL_TOS - APPID=secondlife + APPID=megapahit LL_IGNORE_SIGCHLD ) + + if( ENABLE_ASAN ) + add_compile_options(-U_FORTIFY_SOURCE + -fsanitize=address + --param asan-stack=0 + ) + add_link_options(-fsanitize=address) + else() + add_compile_definitions( _FORTIFY_SOURCE=2 ) + endif() + + if (CMAKE_SYSTEM_NAME MATCHES "FreeBSD") + add_compile_definitions(EXTERNAL_TOS) + endif (CMAKE_SYSTEM_NAME MATCHES "FreeBSD") + add_compile_options( - -fexceptions - -fno-math-errno - -fno-strict-aliasing - -fsigned-char - -msse2 - -mfpmath=sse - -pthread - -Wno-parentheses - -Wno-deprecated - -fvisibility=hidden + -fexceptions + -fno-math-errno + -fno-strict-aliasing + -fsigned-char + -pthread ) - if (ADDRESS_SIZE EQUAL 32) - add_compile_options(-march=pentium4) - endif (ADDRESS_SIZE EQUAL 32) + if (CMAKE_SYSTEM_NAME MATCHES x86_64) + add_compile_options( + -msse2 + -mfpmath=sse + ) + endif () + + if (NOT BUILD_SHARED_LIBS) + add_compile_options(-fvisibility=hidden) + endif (NOT BUILD_SHARED_LIBS) + + set(GCC_CLANG_COMPATIBLE_WARNINGS + -Wno-parentheses + -Wno-deprecated + -Wno-c++20-compat + -Wno-pessimizing-move + ) + + set(CLANG_WARNINGS + ${GCC_CLANG_COMPATIBLE_WARNINGS} + # Put clang specific warning configuration here + ) + + set(GCC_WARNINGS + ${GCC_CLANG_COMPATIBLE_WARNINGS} + -Wno-dangling-pointer + ) + + if (CMAKE_SYSTEM_PROCESSOR MATCHES aarch64) + set(GCC_WARNINGS + ${GCC_WARNINGS} + -Wno-cpp + ) + endif () + add_link_options( + -Wl,--no-keep-memory + -Wl,--build-id + -Wl,--no-undefined + ) + if (NOT GCC_DISABLE_FATAL_WARNINGS) + add_compile_options( -Werror ) + endif (NOT GCC_DISABLE_FATAL_WARNINGS) # this stops us requiring a really recent glibc at runtime add_compile_options(-fno-stack-protector) - # linking can be very memory-hungry, especially the final viewer link - set(CMAKE_CXX_LINK_FLAGS "-Wl,--no-keep-memory") - - set(CMAKE_CXX_FLAGS_DEBUG "-fno-inline ${CMAKE_CXX_FLAGS_DEBUG}") -endif (LINUX) + if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang") + # ND: clang is a bit more picky than GCC, the latter seems to auto include -lstdc++ and -lm. The former not so and thus fails to link + add_link_options( + -lstdc++ + -lm + ) + add_compile_options(${CLANG_WARNINGS}) + else() + add_compile_options(${GCC_WARNINGS}) + endif() +endif (LINUX OR CMAKE_SYSTEM_NAME MATCHES "FreeBSD") if (DARWIN) # Warnings should be fatal -- thanks, Nicky Perian, for spotting reversed default @@ -177,15 +244,9 @@ if (DARWIN) # required for clang-15/xcode-15 since our boost package still uses deprecated std::unary_function/binary_function # see https://developer.apple.com/documentation/xcode-release-notes/xcode-15-release-notes#C++-Standard-Library add_compile_definitions(_LIBCPP_ENABLE_CXX17_REMOVED_UNARY_BINARY_FUNCTION) -endif (DARWIN) -if (LINUX OR DARWIN) set(GCC_WARNINGS -Wall -Wno-sign-compare -Wno-trigraphs) - if (NOT GCC_DISABLE_FATAL_WARNINGS) - list(APPEND GCC_WARNINGS -Werror) - endif (NOT GCC_DISABLE_FATAL_WARNINGS) - list(APPEND GCC_WARNINGS -Wno-reorder -Wno-non-virtual-dtor ) if (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 13) @@ -194,7 +255,4 @@ if (LINUX OR DARWIN) add_compile_options(${GCC_WARNINGS}) add_compile_options(-m${ADDRESS_SIZE}) -endif (LINUX OR DARWIN) - - - +endif () diff --git a/indra/cmake/APR.cmake b/indra/cmake/APR.cmake index 97b316c4c7..506f792570 100644 --- a/indra/cmake/APR.cmake +++ b/indra/cmake/APR.cmake @@ -5,6 +5,15 @@ include_guard() add_library( ll::apr INTERFACE IMPORTED ) +if (NOT (USE_AUTOBUILD_3P OR USE_CONAN)) + include(FindPkgConfig) + pkg_check_modules(Apr REQUIRED apr-1 apr-util-1) + target_include_directories(ll::apr SYSTEM INTERFACE ${Apr_INCLUDE_DIRS}) + target_link_directories(ll::apr INTERFACE ${Apr_LIBRARY_DIRS}) + target_link_libraries(ll::apr INTERFACE ${Apr_LIBRARIES}) + return () +endif () + use_system_binary( apr apr-util ) use_prebuilt_binary(apr_suite) diff --git a/indra/cmake/Audio.cmake b/indra/cmake/Audio.cmake index 8c82749cab..3c4c0ef1a7 100644 --- a/indra/cmake/Audio.cmake +++ b/indra/cmake/Audio.cmake @@ -5,6 +5,15 @@ include(Prebuilt) include_guard() add_library( ll::vorbis INTERFACE IMPORTED ) +if (NOT (USE_AUTOBUILD_3P OR USE_CONAN)) + include(FindPkgConfig) + pkg_check_modules(Vorbis REQUIRED ogg vorbis vorbisenc vorbisfile) + target_include_directories(ll::vorbis SYSTEM INTERFACE ${Vorbis_INCLUDE_DIRS}) + target_link_directories(ll::vorbis INTERFACE ${Vorbis_LIBRARY_DIRS}) + target_link_libraries(ll::vorbis INTERFACE ${Vorbis_LIBRARIES}) + return () +endif () + use_system_binary(vorbis) use_prebuilt_binary(ogg_vorbis) target_include_directories( ll::vorbis SYSTEM INTERFACE ${LIBS_PREBUILT_DIR}/include ) diff --git a/indra/cmake/Boost.cmake b/indra/cmake/Boost.cmake index 8c5b946753..c9688d0fe0 100644 --- a/indra/cmake/Boost.cmake +++ b/indra/cmake/Boost.cmake @@ -8,6 +8,30 @@ if( USE_CONAN ) target_link_libraries( ll::boost INTERFACE CONAN_PKG::boost ) target_compile_definitions( ll::boost INTERFACE BOOST_ALLOW_DEPRECATED_HEADERS BOOST_BIND_GLOBAL_PLACEHOLDERS ) return() +elseif( NOT USE_AUTOBUILD_3P ) + if (WINDOWS) + set(sfx -mt) + target_include_directories( ll::boost SYSTEM INTERFACE /opt/local/x86_64-w64-mingw32/include) + target_link_directories( ll::boost INTERFACE /opt/local/x86_64-w64-mingw32/lib) + elseif (DARWIN) + set(sfx -mt) + target_include_directories( ll::boost SYSTEM INTERFACE /opt/local/libexec/boost/1.87/include) + target_link_directories( ll::boost INTERFACE /opt/local/libexec/boost/1.87/lib) + else (WINDOWS) + find_package( Boost REQUIRED ) + endif (WINDOWS) + target_link_libraries( ll::boost INTERFACE + boost_context${sfx} + boost_fiber${sfx} + boost_filesystem${sfx} + boost_program_options${sfx} + boost_regex${sfx} + boost_system${sfx} + boost_thread${sfx} + boost_url${sfx} + ) + target_compile_definitions( ll::boost INTERFACE BOOST_BIND_GLOBAL_PLACEHOLDERS ) + return() endif() use_prebuilt_binary(boost) @@ -28,12 +52,11 @@ if (WINDOWS) libboost_url-mt${addrsfx}) elseif (LINUX) target_link_libraries( ll::boost INTERFACE - boost_context-mt${addrsfx} boost_fiber-mt${addrsfx} + boost_context-mt${addrsfx} boost_filesystem-mt${addrsfx} boost_program_options-mt${addrsfx} boost_regex-mt${addrsfx} - boost_signals-mt${addrsfx} boost_system-mt${addrsfx} boost_thread-mt${addrsfx} boost_url-mt${addrsfx}) diff --git a/indra/cmake/CEFPlugin.cmake b/indra/cmake/CEFPlugin.cmake index 9b77becf29..119a41f570 100644 --- a/indra/cmake/CEFPlugin.cmake +++ b/indra/cmake/CEFPlugin.cmake @@ -5,7 +5,46 @@ include(Prebuilt) include_guard() add_library( ll::cef INTERFACE IMPORTED ) +if (CMAKE_OSX_ARCHITECTURES MATCHES arm64) + if (${PREBUILD_TRACKING_DIR}/sentinel_installed IS_NEWER_THAN ${PREBUILD_TRACKING_DIR}/dullahan_installed OR NOT ${dullahan_installed} EQUAL 0) + if (NOT EXISTS ${CMAKE_BINARY_DIR}/dullahan-1.14.0.202312131437_118.7.1_g99817d2_chromium-118.0.5993.119-darwin64-242070244.tar.bz2) + file(DOWNLOAD + https://megapahit.net/downloads/dullahan-1.14.0.202312131437_118.7.1_g99817d2_chromium-118.0.5993.119-darwin64-242070244.tar.bz2 + ${CMAKE_BINARY_DIR}/dullahan-1.14.0.202312131437_118.7.1_g99817d2_chromium-118.0.5993.119-darwin64-242070244.tar.bz2 + SHOW_PROGRESS + ) + endif (NOT EXISTS ${CMAKE_BINARY_DIR}/dullahan-1.14.0.202312131437_118.7.1_g99817d2_chromium-118.0.5993.119-darwin64-242070244.tar.bz2) + file(ARCHIVE_EXTRACT + INPUT ${CMAKE_BINARY_DIR}/dullahan-1.14.0.202312131437_118.7.1_g99817d2_chromium-118.0.5993.119-darwin64-242070244.tar.bz2 + DESTINATION ${LIBS_PREBUILT_DIR} + ) + file(WRITE ${PREBUILD_TRACKING_DIR}/dullahan_installed "0") + endif (${PREBUILD_TRACKING_DIR}/sentinel_installed IS_NEWER_THAN ${PREBUILD_TRACKING_DIR}/dullahan_installed OR NOT ${dullahan_installed} EQUAL 0) +elseif (CMAKE_OSX_ARCHITECTURES MATCHES x86_64) + if (${PREBUILD_TRACKING_DIR}/sentinel_installed IS_NEWER_THAN ${PREBUILD_TRACKING_DIR}/dullahan_installed OR NOT ${dullahan_installed} EQUAL 0) + if (NOT EXISTS ${CMAKE_BINARY_DIR}/dullahan-1.14.0.202312131437_118.7.1_g99817d2_chromium-118.0.5993.119-darwin64-242070158.tar.bz2) + file(DOWNLOAD + https://megapahit.net/downloads/dullahan-1.14.0.202312131437_118.7.1_g99817d2_chromium-118.0.5993.119-darwin64-242070158.tar.bz2 + ${CMAKE_BINARY_DIR}/dullahan-1.14.0.202312131437_118.7.1_g99817d2_chromium-118.0.5993.119-darwin64-242070158.tar.bz2 + SHOW_PROGRESS + ) + endif (NOT EXISTS ${CMAKE_BINARY_DIR}/dullahan-1.14.0.202312131437_118.7.1_g99817d2_chromium-118.0.5993.119-darwin64-242070158.tar.bz2) + file(ARCHIVE_EXTRACT + INPUT ${CMAKE_BINARY_DIR}/dullahan-1.14.0.202312131437_118.7.1_g99817d2_chromium-118.0.5993.119-darwin64-242070158.tar.bz2 + DESTINATION ${LIBS_PREBUILT_DIR} + ) + file(WRITE ${PREBUILD_TRACKING_DIR}/dullahan_installed "0") + endif (${PREBUILD_TRACKING_DIR}/sentinel_installed IS_NEWER_THAN ${PREBUILD_TRACKING_DIR}/dullahan_installed OR NOT ${dullahan_installed} EQUAL 0) +else (CMAKE_OSX_ARCHITECTURES MATCHES arm64) use_prebuilt_binary(dullahan) + if (${LINUX_DISTRO} MATCHES fedora) + execute_process( + COMMAND patchelf --remove-rpath bin/release/dullahan_host + WORKING_DIRECTORY ${LIBS_PREBUILT_DIR} + ) + endif (${LINUX_DISTRO} MATCHES fedora) +endif (CMAKE_OSX_ARCHITECTURES MATCHES arm64) + target_include_directories( ll::cef SYSTEM INTERFACE ${LIBS_PREBUILT_DIR}/include/cef) if (WINDOWS) @@ -33,4 +72,9 @@ elseif (DARWIN) ) elseif (LINUX) + target_link_libraries( ll::cef INTERFACE + libdullahan.a + cef + cef_dll_wrapper.a + ) endif (WINDOWS) diff --git a/indra/cmake/CMakeLists.txt b/indra/cmake/CMakeLists.txt index cc217b0563..5525ac9f24 100644 --- a/indra/cmake/CMakeLists.txt +++ b/indra/cmake/CMakeLists.txt @@ -15,7 +15,6 @@ set(cmake_SOURCE_FILES CEFPlugin.cmake CEFPlugin.cmake CMakeCopyIfDifferent.cmake - ConfigurePkgConfig.cmake CURL.cmake Copy3rdPartyLibs.cmake DBusGlib.cmake @@ -23,6 +22,7 @@ set(cmake_SOURCE_FILES DragDrop.cmake EXPAT.cmake FindAutobuild.cmake + FMODSTUDIO.cmake FreeType.cmake GLEXT.cmake GLH.cmake diff --git a/indra/cmake/CURL.cmake b/indra/cmake/CURL.cmake index eea0a2da62..7f50975ea8 100644 --- a/indra/cmake/CURL.cmake +++ b/indra/cmake/CURL.cmake @@ -5,9 +5,103 @@ include(Linking) include_guard() add_library( ll::libcurl INTERFACE IMPORTED ) +if (NOT USESYSTEMLIBS) use_system_binary(libcurl) +endif (NOT USESYSTEMLIBS) +if (LINUX AND CMAKE_SYSTEM_PROCESSOR MATCHES x86_64 OR DARWIN OR NOT USESYSTEMLIBS) use_prebuilt_binary(curl) -if (WINDOWS) + if (DARWIN) + execute_process( + COMMAND lipo -archs libcurl.a + WORKING_DIRECTORY ${LIBS_PREBUILT_DIR}/lib/release + OUTPUT_VARIABLE curl_archs + OUTPUT_STRIP_TRAILING_WHITESPACE + ) + if (NOT ${curl_archs} STREQUAL ${CMAKE_OSX_ARCHITECTURES}) + execute_process( + COMMAND lipo + libcurl.a + -thin ${CMAKE_OSX_ARCHITECTURES} + -output libcurl.a + WORKING_DIRECTORY ${LIBS_PREBUILT_DIR}/lib/release + ) + endif (NOT ${curl_archs} STREQUAL ${CMAKE_OSX_ARCHITECTURES}) + endif (DARWIN) +elseif (${PREBUILD_TRACKING_DIR}/sentinel_installed IS_NEWER_THAN ${PREBUILD_TRACKING_DIR}/curl_installed OR NOT ${curl_installed} EQUAL 0) + if (NOT EXISTS ${CMAKE_BINARY_DIR}/3p-curl-7.54.1-r1.tar.gz) + file(DOWNLOAD + https://github.com/secondlife/3p-curl/archive/refs/tags/v7.54.1-r1.tar.gz + ${CMAKE_BINARY_DIR}/3p-curl-7.54.1-r1.tar.gz + ) + endif (NOT EXISTS ${CMAKE_BINARY_DIR}/3p-curl-7.54.1-r1.tar.gz) + file(ARCHIVE_EXTRACT + INPUT ${CMAKE_BINARY_DIR}/3p-curl-7.54.1-r1.tar.gz + DESTINATION ${CMAKE_BINARY_DIR} + ) + if (CMAKE_SYSTEM_PROCESSOR MATCHES aarch64 AND (${LINUX_DISTRO} MATCHES fedora)) + execute_process( + COMMAND sed -i netrc.c -e "s/defined(HAVE_GETPWUID_R)/0/g" netrc.c + WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/3p-curl-7.54.1-r1/curl/lib + ) + endif () + file( + COPY + ${CMAKE_BINARY_DIR}/3p-curl-7.54.1-r1/curl/include/curl/curl.h + ${CMAKE_BINARY_DIR}/3p-curl-7.54.1-r1/curl/include/curl/curlbuild.h + ${CMAKE_BINARY_DIR}/3p-curl-7.54.1-r1/curl/include/curl/curlrules.h + ${CMAKE_BINARY_DIR}/3p-curl-7.54.1-r1/curl/include/curl/curlver.h + ${CMAKE_BINARY_DIR}/3p-curl-7.54.1-r1/curl/include/curl/easy.h + ${CMAKE_BINARY_DIR}/3p-curl-7.54.1-r1/curl/include/curl/mprintf.h + ${CMAKE_BINARY_DIR}/3p-curl-7.54.1-r1/curl/include/curl/multi.h + ${CMAKE_BINARY_DIR}/3p-curl-7.54.1-r1/curl/include/curl/stdcheaders.h + ${CMAKE_BINARY_DIR}/3p-curl-7.54.1-r1/curl/include/curl/system.h + ${CMAKE_BINARY_DIR}/3p-curl-7.54.1-r1/curl/include/curl/typecheck-gcc.h + DESTINATION ${LIBS_PREBUILT_DIR}/include/curl + ) + file( + COPY + ${LIBS_PREBUILT_DIR}/lib/release/libcrypto.a + ${LIBS_PREBUILT_DIR}/lib/release/libssl.a + DESTINATION ${LIBS_PREBUILT_DIR}/lib + ) + if (CMAKE_SYSTEM_NAME MATCHES FreeBSD) + message("We need to temporarily have OpenSSL3 header directory and libraries renamed just until the libcurl building process with OpenSSL1.1 now is finished.") + execute_process(COMMAND sudo mv /usr/include/openssl /usr/include/openssl3) + execute_process(COMMAND sudo mv /usr/lib/libcrypto.a /usr/lib/libcrypto.a.3) + execute_process(COMMAND sudo mv /usr/lib/libcrypto.so /usr/lib/libcrypto.so.3) + execute_process(COMMAND sudo mv /usr/lib/libssl.a /usr/lib/libssl.a.3) + execute_process(COMMAND sudo mv /usr/lib/libssl.so /usr/lib/libssl.so.3) + endif (CMAKE_SYSTEM_NAME MATCHES FreeBSD) + set(ENV{CFLAGS} "-std=c90") + execute_process( + COMMAND ./configure --disable-alt-svc --disable-dict --disable-doh --disable-file --disable-gopher --disable-headers-api --disable-hsts --disable-imap --disable-ldap --disable-ldaps --disable-libcurl-option --disable-manual --disable-mqtt --disable-ntlm --disable-ntlm-wb --disable-pop3 --disable-rtsp --disable-shared --disable-smb --disable-smtp --disable-sspi --disable-telnet --disable-tftp --disable-tls-srp --disable-unix-sockets --disable-verbose --disable-versioned-symbols --enable-threaded-resolver --with-ssl=${LIBS_PREBUILT_DIR} --without-libidn2 --without-libpsl --without-libssh2 + WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/3p-curl-7.54.1-r1/curl + ) + execute_process( + COMMAND make -j${MAKE_JOBS} + WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/3p-curl-7.54.1-r1/curl + RESULT_VARIABLE curl_installed + ) + unset(ENV{CFLAGS}) + file( + COPY ${CMAKE_BINARY_DIR}/3p-curl-7.54.1-r1/curl/lib/.libs/libcurl.a + DESTINATION ${LIBS_PREBUILT_DIR}/lib/release + ) + if (CMAKE_SYSTEM_NAME MATCHES FreeBSD) + execute_process(COMMAND sudo mv /usr/include/openssl3 /usr/include/openssl) + execute_process(COMMAND sudo mv /usr/lib/libcrypto.a.3 /usr/lib/libcrypto.a) + execute_process(COMMAND sudo mv /usr/lib/libcrypto.so.3 /usr/lib/libcrypto.so) + execute_process(COMMAND sudo mv /usr/lib/libssl.a.3 /usr/lib/libssl.a) + execute_process(COMMAND sudo mv /usr/lib/libssl.so.3 /usr/lib/libssl.so) + message("OpenSSL3 header directory and library names have been restored.") + endif (CMAKE_SYSTEM_NAME MATCHES FreeBSD) + file(REMOVE + ${LIBS_PREBUILT_DIR}/lib/libcrypto.a + ${LIBS_PREBUILT_DIR}/lib/libssl.a + ) + file(WRITE ${PREBUILD_TRACKING_DIR}/curl_installed "${curl_installed}") +endif (LINUX AND CMAKE_SYSTEM_PROCESSOR MATCHES x86_64 OR DARWIN OR NOT USESYSTEMLIBS) +if (WINDOWS AND NOT USESYSTEMLIBS) target_link_libraries(ll::libcurl INTERFACE ${ARCH_PREBUILT_DIRS_RELEASE}/libcurl.lib ll::openssl diff --git a/indra/cmake/ConfigurePkgConfig.cmake b/indra/cmake/ConfigurePkgConfig.cmake deleted file mode 100644 index 9e798d663b..0000000000 --- a/indra/cmake/ConfigurePkgConfig.cmake +++ /dev/null @@ -1,74 +0,0 @@ -# -*- cmake -*- - -SET(DEBUG_PKG_CONFIG "YES") - -# Don't change this if manually set by user. -IF("$ENV{PKG_CONFIG_LIBDIR}" STREQUAL "") - - # Guess at architecture-specific system library paths. - if (ADDRESS_SIZE EQUAL 32) - SET(PKG_CONFIG_NO_MULTI_GUESS /usr/lib32 /usr/lib) - SET(PKG_CONFIG_NO_MULTI_LOCAL_GUESS /usr/local/lib32 /usr/local/lib) - SET(PKG_CONFIG_MULTI_GUESS /usr/lib/i386-linux-gnu) - SET(PKG_CONFIG_MULTI_LOCAL_GUESS /usr/local/lib/i386-linux-gnu) - else (ADDRESS_SIZE EQUAL 32) - SET(PKG_CONFIG_NO_MULTI_GUESS /usr/lib64 /usr/lib) - SET(PKG_CONFIG_NO_MULTI_LOCAL_GUESS /usr/local/lib64 /usr/local/lib) - SET(PKG_CONFIG_MULTI_GUESS /usr/local/lib/x86_64-linux-gnu) - SET(PKG_CONFIG_MULTI_LOCAL_GUESS /usr/local/lib/x86_64-linux-gnu) - endif (ADDRESS_SIZE EQUAL 32) - - # Use DPKG architecture, if available. - IF (${DPKG_ARCH}) - SET(PKG_CONFIG_MULTI_GUESS /usr/lib/${DPKG_ARCH}) - SET(PKG_CONFIG_MULTI_LOCAL_GUESS /usrlocal/lib/${DPKG_ARCH}) - ENDIF (${DPKG_ARCH}) - - # Explicitly include anything listed in PKG_CONFIG_PATH - string(REPLACE ":" ";" PKG_CONFIG_PATH_LIST "$ENV{PKG_CONFIG_PATH}") - FOREACH(PKG_CONFIG_DIR ${PKG_CONFIG_PATH_LIST}) - SET(VALID_PKG_LIBDIRS "${VALID_PKG_LIBDIRS}:${PKG_CONFIG_DIR}/pkgconfig") - ENDFOREACH(PKG_CONFIG_DIR) - - # Look for valid pkgconfig directories. - FIND_PATH(PKG_CONFIG_ENV pkgconfig ENV LD_LIBRARY_PATH) - FIND_PATH(PKG_CONFIG_MULTI pkgconfig HINT ${PKG_CONFIG_MULTI_GUESS}) - FIND_PATH(PKG_CONFIG_MULTI_LOCAL pkgconfig HINT ${PKG_CONFIG_MULTI_LOCAL_GUESS}) - FIND_PATH(PKG_CONFIG_NO_MULTI pkgconfig HINT ${PKG_CONFIG_NO_MULTI_GUESS}) - FIND_PATH(PKG_CONFIG_NO_MULTI_LOCAL pkgconfig HINT ${PKG_CONFIG_NO_MULTI_LOCAL_GUESS}) - - # Add anything we found to our list. - IF(NOT PKG_CONFIG_ENV STREQUAL PKG_CONFIG_ENV-NOTFOUND) - SET(VALID_PKG_LIBDIRS "${VALID_PKG_LIBDIRS}:${PKG_CONFIG_ENV}/pkgconfig") - ENDIF(NOT PKG_CONFIG_ENV STREQUAL PKG_CONFIG_ENV-NOTFOUND) - - IF(NOT PKG_CONFIG_MULTI STREQUAL PKG_CONFIG_MULTI-NOTFOUND) - SET(VALID_PKG_LIBDIRS "${VALID_PKG_LIBDIRS}:${PKG_CONFIG_MULTI}/pkgconfig") - ENDIF(NOT PKG_CONFIG_MULTI STREQUAL PKG_CONFIG_MULTI-NOTFOUND) - - IF(NOT PKG_CONFIG_MULTI_LOCAL STREQUAL PKG_CONFIG_MULTI_LOCAL-NOTFOUND) - SET(VALID_PKG_LIBDIRS "${VALID_PKG_LIBDIRS}:${PKG_CONFIG_MULTI_LOCAL}/pkgconfig") - ENDIF(NOT PKG_CONFIG_MULTI_LOCAL STREQUAL PKG_CONFIG_MULTI_LOCAL-NOTFOUND) - - IF(NOT PKG_CONFIG_NO_MULTI STREQUAL PKG_CONFIG_NO_MULTI-NOTFOUND) - SET(VALID_PKG_LIBDIRS "${VALID_PKG_LIBDIRS}:${PKG_CONFIG_NO_MULTI}/pkgconfig") - ENDIF(NOT PKG_CONFIG_NO_MULTI STREQUAL PKG_CONFIG_NO_MULTI-NOTFOUND) - - IF(NOT PKG_CONFIG_NO_MULTI_LOCAL STREQUAL PKG_CONFIG_NO_MULTI_LOCAL-NOTFOUND) - SET(VALID_PKG_LIBDIRS "${VALID_PKG_LIBDIRS}:${PKG_CONFIG_NO_MULTI_LOCAL}/pkgconfig") - ENDIF(NOT PKG_CONFIG_NO_MULTI_LOCAL STREQUAL PKG_CONFIG_NO_MULTI_LOCAL-NOTFOUND) - - # Also add some non-architecture specific package locations. - SET(VALID_PKG_LIBDIRS "${VALID_PKG_LIBDIRS}:/usr/share/pkgconfig:/usr/local/share/pkgconfig") - - # Remove first unwanted ':' - string(SUBSTRING ${VALID_PKG_LIBDIRS} 1 -1 VALID_PKG_LIBDIRS) - - # Set PKG_CONFIG_LIBDIR environment. - SET(ENV{PKG_CONFIG_LIBDIR} ${VALID_PKG_LIBDIRS}) -ENDIF("$ENV{PKG_CONFIG_LIBDIR}" STREQUAL "") - -IF(DEBUG_PKG_CONFIG) - MESSAGE(STATUS "Using PKG_CONFIG_LIBDIR=$ENV{PKG_CONFIG_LIBDIR}") -ENDIF(DEBUG_PKG_CONFIG) - diff --git a/indra/cmake/FMODSTUDIO.cmake b/indra/cmake/FMODSTUDIO.cmake new file mode 100644 index 0000000000..d97251885f --- /dev/null +++ b/indra/cmake/FMODSTUDIO.cmake @@ -0,0 +1,120 @@ +# -*- cmake -*- + +include_guard() + +# FMODSTUDIO can be set when launching the make using the argument -DUSE_FMODSTUDIO:BOOL=ON +# When building using proprietary binaries though (i.e. having access to LL private servers), +# we always build with FMODSTUDIO. +if (INSTALL_PROPRIETARY) + set(USE_FMODSTUDIO ON CACHE BOOL "Using FMODSTUDIO sound library.") +endif (INSTALL_PROPRIETARY) + +# ND: To streamline arguments passed, switch from FMODSTUDIO to USE_FMODSTUDIO +# To not break all old build scripts convert old arguments but warn about it +if(FMODSTUDIO) + message( WARNING "Use of the FMODSTUDIO argument is deprecated, please switch to USE_FMODSTUDIO") + set(USE_FMODSTUDIO ${FMODSTUDIO}) +endif() + +if (USE_FMODSTUDIO) + add_library( ll::fmodstudio INTERFACE IMPORTED ) + target_compile_definitions( ll::fmodstudio INTERFACE LL_FMODSTUDIO=1) + + if (FMODSTUDIO_LIBRARY AND FMODSTUDIO_INCLUDE_DIR) + # If the path have been specified in the arguments, use that + + target_link_libraries(ll::fmodstudio INTERFACE ${FMODSTUDIO_LIBRARY}) + target_include_directories( ll::fmodstudio SYSTEM INTERFACE ${FMODSTUDIO_INCLUDE_DIR}) + else (FMODSTUDIO_LIBRARY AND FMODSTUDIO_INCLUDE_DIR) + # If not, we're going to try to get the package listed in autobuild.xml + # Note: if you're not using INSTALL_PROPRIETARY, the package URL should be local (file:/// URL) + # as accessing the private LL location will fail if you don't have the credential + include(Prebuilt) + if (USESYSTEMLIBS AND (${PREBUILD_TRACKING_DIR}/sentinel_installed IS_NEWER_THAN ${PREBUILD_TRACKING_DIR}/fmodstudio_installed OR NOT ${fmodstudio_installed} EQUAL 0)) + file(MAKE_DIRECTORY ${LIBS_PREBUILT_DIR}/lib/release) + if (DARWIN) + execute_process( + COMMAND hdiutil attach -noverify fmodstudioapi20228mac-installer.dmg + WORKING_DIRECTORY $ENV{HOME}/Downloads + ) + file( + COPY + /Volumes/FMOD\ Programmers\ API\ Mac/FMOD\ Programmers\ API/api/core/inc/fmod.h + /Volumes/FMOD\ Programmers\ API\ Mac/FMOD\ Programmers\ API/api/core/inc/fmod.hpp + /Volumes/FMOD\ Programmers\ API\ Mac/FMOD\ Programmers\ API/api/core/inc/fmod_codec.h + /Volumes/FMOD\ Programmers\ API\ Mac/FMOD\ Programmers\ API/api/core/inc/fmod_common.h + /Volumes/FMOD\ Programmers\ API\ Mac/FMOD\ Programmers\ API/api/core/inc/fmod_dsp.h + /Volumes/FMOD\ Programmers\ API\ Mac/FMOD\ Programmers\ API/api/core/inc/fmod_dsp_effects.h + /Volumes/FMOD\ Programmers\ API\ Mac/FMOD\ Programmers\ API/api/core/inc/fmod_errors.h + /Volumes/FMOD\ Programmers\ API\ Mac/FMOD\ Programmers\ API/api/core/inc/fmod_output.h + DESTINATION ${LIBS_PREBUILT_DIR}/include/fmodstudio + ) + execute_process( + COMMAND lipo + lib/libfmod.dylib + -thin ${CMAKE_OSX_ARCHITECTURES} + -output ${LIBS_PREBUILT_DIR}/lib/release/libfmod.dylib + WORKING_DIRECTORY /Volumes/FMOD\ Programmers\ API\ Mac/FMOD\ Programmers\ API/api/core + ) + execute_process( + COMMAND hdiutil detach FMOD\ Programmers\ API\ Mac + WORKING_DIRECTORY /Volumes + RESULT_VARIABLE fmodstudio_installed + ) + file(WRITE ${PREBUILD_TRACKING_DIR}/fmodstudio_installed "${fmodstudio_installed}") + else (DARWIN) + file(ARCHIVE_EXTRACT + INPUT $ENV{HOME}/Downloads/fmodstudioapi20228linux.tar.gz + DESTINATION ${CMAKE_BINARY_DIR} + ) + file( + COPY + ${CMAKE_BINARY_DIR}/fmodstudioapi20228linux/api/core/inc/fmod.h + ${CMAKE_BINARY_DIR}/fmodstudioapi20228linux/api/core/inc/fmod.hpp + ${CMAKE_BINARY_DIR}/fmodstudioapi20228linux/api/core/inc/fmod_codec.h + ${CMAKE_BINARY_DIR}/fmodstudioapi20228linux/api/core/inc/fmod_common.h + ${CMAKE_BINARY_DIR}/fmodstudioapi20228linux/api/core/inc/fmod_dsp.h + ${CMAKE_BINARY_DIR}/fmodstudioapi20228linux/api/core/inc/fmod_dsp_effects.h + ${CMAKE_BINARY_DIR}/fmodstudioapi20228linux/api/core/inc/fmod_errors.h + ${CMAKE_BINARY_DIR}/fmodstudioapi20228linux/api/core/inc/fmod_output.h + DESTINATION ${LIBS_PREBUILT_DIR}/include/fmodstudio + ) + if (CMAKE_SYSTEM_PROCESSOR MATCHES aarch64) + file( + COPY + ${CMAKE_BINARY_DIR}/fmodstudioapi20228linux/api/core/lib/arm64/libfmod.so + ${CMAKE_BINARY_DIR}/fmodstudioapi20228linux/api/core/lib/arm64/libfmod.so.13 + ${CMAKE_BINARY_DIR}/fmodstudioapi20228linux/api/core/lib/arm64/libfmod.so.13.28 + DESTINATION ${LIBS_PREBUILT_DIR}/lib/release + FOLLOW_SYMLINK_CHAIN + ) + else () + file( + COPY + ${CMAKE_BINARY_DIR}/fmodstudioapi20228linux/api/core/lib/${CMAKE_SYSTEM_PROCESSOR}/libfmod.so + ${CMAKE_BINARY_DIR}/fmodstudioapi20228linux/api/core/lib/${CMAKE_SYSTEM_PROCESSOR}/libfmod.so.13 + ${CMAKE_BINARY_DIR}/fmodstudioapi20228linux/api/core/lib/${CMAKE_SYSTEM_PROCESSOR}/libfmod.so.13.28 + DESTINATION ${LIBS_PREBUILT_DIR}/lib/release + FOLLOW_SYMLINK_CHAIN + ) + endif (CMAKE_SYSTEM_PROCESSOR MATCHES aarch64) + file(WRITE ${PREBUILD_TRACKING_DIR}/fmodstudio_installed "0") + endif (DARWIN) + else (USESYSTEMLIBS AND (${PREBUILD_TRACKING_DIR}/sentinel_installed IS_NEWER_THAN ${PREBUILD_TRACKING_DIR}/fmodstudio_installed OR NOT ${fmodstudio_installed} EQUAL 0)) + use_prebuilt_binary(fmodstudio) + endif (USESYSTEMLIBS AND (${PREBUILD_TRACKING_DIR}/sentinel_installed IS_NEWER_THAN ${PREBUILD_TRACKING_DIR}/fmodstudio_installed OR NOT ${fmodstudio_installed} EQUAL 0)) + if (WINDOWS) + target_link_libraries( ll::fmodstudio INTERFACE fmod_vc) + elseif (DARWIN) + #despite files being called libfmod.dylib, we are searching for fmod + target_link_libraries( ll::fmodstudio INTERFACE fmod) + elseif (LINUX) + target_link_libraries( ll::fmodstudio INTERFACE fmod) + endif (WINDOWS) + + target_include_directories( ll::fmodstudio SYSTEM INTERFACE ${LIBS_PREBUILT_DIR}/include/fmodstudio) + endif (FMODSTUDIO_LIBRARY AND FMODSTUDIO_INCLUDE_DIR) +else() + set( USE_FMODSTUDIO "OFF") +endif () + diff --git a/indra/cmake/FindPipeWire.cmake b/indra/cmake/FindPipeWire.cmake new file mode 100644 index 0000000000..868acf5ec1 --- /dev/null +++ b/indra/cmake/FindPipeWire.cmake @@ -0,0 +1,100 @@ +# cmake-format: off +# .rst: FindPipeWire +# ------- +# +# Try to find PipeWire on a Unix system. +# +# This will define the following variables: +# +# ``PIPEWIRE_FOUND`` True if (the requested version of) PipeWire is available +# ``PIPEWIRE_VERSION`` The version of PipeWire ``PIPEWIRE_LIBRARIES`` This can +# be passed to target_link_libraries() instead of the ``PipeWire::PipeWire`` +# target ``PIPEWIRE_INCLUDE_DIRS`` This should be passed to +# target_include_directories() if the target is not used for linking +# ``PIPEWIRE_COMPILE_FLAGS`` This should be passed to target_compile_options() +# if the target is not used for linking +# +# If ``PIPEWIRE_FOUND`` is TRUE, it will also define the following imported +# target: +# +# ``PipeWire::PipeWire`` The PipeWire library +# +# In general we recommend using the imported target, as it is easier to use. +# Bear in mind, however, that if the target is in the link interface of an +# exported library, it must be made available by the package config file. + +# ============================================================================= +# Copyright 2014 Alex Merry <alex.merry@kde.org> Copyright 2014 Martin Gräßlin +# <mgraesslin@kde.org> Copyright 2018-2020 Jan Grulich <jgrulich@redhat.com> +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the copyright notice, this list +# of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the copyright notice, this +# list of conditions and the following disclaimer in the documentation and/or +# other materials provided with the distribution. +# 3. The name of the author may not be used to endorse or promote products +# derived from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED +# WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO +# EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR +# BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER +# IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# ============================================================================= +# cmake-format: on + +# Use pkg-config to get the directories and then use these values in the FIND_PATH() and FIND_LIBRARY() calls +find_package(PkgConfig QUIET) + +pkg_search_module(PKG_PIPEWIRE QUIET libpipewire-0.3) +pkg_search_module(PKG_SPA QUIET libspa-0.2) + +set(PIPEWIRE_COMPILE_FLAGS "${PKG_PIPEWIRE_CFLAGS}" "${PKG_SPA_CFLAGS}") +set(PIPEWIRE_VERSION "${PKG_PIPEWIRE_VERSION}") + +find_path( + PIPEWIRE_INCLUDE_DIRS + NAMES pipewire/pipewire.h + HINTS ${PKG_PIPEWIRE_INCLUDE_DIRS} ${PKG_PIPEWIRE_INCLUDE_DIRS}/pipewire-0.3) + +find_path( + SPA_INCLUDE_DIRS + NAMES spa/param/props.h + HINTS ${PKG_SPA_INCLUDE_DIRS} ${PKG_SPA_INCLUDE_DIRS}/spa-0.2) + +find_library( + PIPEWIRE_LIBRARIES + NAMES pipewire-0.3 + HINTS ${PKG_PIPEWIRE_LIBRARY_DIRS}) + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args( + PipeWire + FOUND_VAR PIPEWIRE_FOUND + REQUIRED_VARS PIPEWIRE_LIBRARIES PIPEWIRE_INCLUDE_DIRS SPA_INCLUDE_DIRS + VERSION_VAR PIPEWIRE_VERSION) + +if(PIPEWIRE_FOUND AND NOT TARGET PipeWire::PipeWire) + add_library(PipeWire::PipeWire UNKNOWN IMPORTED) + set_target_properties( + PipeWire::PipeWire + PROPERTIES IMPORTED_LOCATION "${PIPEWIRE_LIBRARIES}" + INTERFACE_COMPILE_OPTIONS "${PIPEWIRE_COMPILE_FLAGS}" + INTERFACE_INCLUDE_DIRECTORIES "${PIPEWIRE_INCLUDE_DIRS};${SPA_INCLUDE_DIRS}") +endif() + +mark_as_advanced(PIPEWIRE_LIBRARIES PIPEWIRE_INCLUDE_DIRS) + +include(FeatureSummary) +set_package_properties( + PipeWire PROPERTIES + URL "https://www.pipewire.org" + DESCRIPTION "PipeWire - multimedia processing") diff --git a/indra/cmake/FreeType.cmake b/indra/cmake/FreeType.cmake index 563491556d..7683fe364a 100644 --- a/indra/cmake/FreeType.cmake +++ b/indra/cmake/FreeType.cmake @@ -5,6 +5,14 @@ include(Linking) include_guard() add_library( ll::freetype INTERFACE IMPORTED ) +if (USESYSTEMLIBS) + include(FindPkgConfig) + pkg_check_modules(Freetype REQUIRED freetype2) + target_include_directories( ll::freetype SYSTEM INTERFACE ${Freetype_INCLUDE_DIRS} ) + target_link_directories( ll::freetype INTERFACE ${Freetype_LIBRARY_DIRS} ) + target_link_libraries( ll::freetype INTERFACE ${Freetype_LIBRARIES} ) + return () +endif (USESYSTEMLIBS) use_system_binary(freetype) use_prebuilt_binary(freetype) target_include_directories( ll::freetype SYSTEM INTERFACE ${LIBS_PREBUILT_DIR}/include/freetype2/) diff --git a/indra/cmake/GLEXT.cmake b/indra/cmake/GLEXT.cmake index a780966f0c..ea349237d3 100644 --- a/indra/cmake/GLEXT.cmake +++ b/indra/cmake/GLEXT.cmake @@ -3,7 +3,10 @@ include(Prebuilt) include(GLH) add_library( ll::glext INTERFACE IMPORTED ) -use_system_binary(glext) -use_prebuilt_binary(glext) +if (USESYSTEMLIBS) + return () +endif () +use_system_binary(glext) +use_prebuilt_binary(glext) diff --git a/indra/cmake/GLH.cmake b/indra/cmake/GLH.cmake index 0cefc3543a..648a08454b 100644 --- a/indra/cmake/GLH.cmake +++ b/indra/cmake/GLH.cmake @@ -2,6 +2,9 @@ include(Prebuilt) add_library( ll::glh_linear INTERFACE IMPORTED ) +target_include_directories( ll::glh_linear SYSTEM INTERFACE ${LIBS_PREBUILT_DIR}/include) +if (NOT USESYSTEMLIBS) use_system_binary( glh_linear ) +endif (NOT USESYSTEMLIBS) use_prebuilt_binary(glh_linear) diff --git a/indra/cmake/GLIB.cmake b/indra/cmake/GLIB.cmake new file mode 100644 index 0000000000..f52cbb7f87 --- /dev/null +++ b/indra/cmake/GLIB.cmake @@ -0,0 +1,22 @@ +include_guard() + +include(Prebuilt) + +add_library( ll::glib INTERFACE IMPORTED ) +add_library( ll::glib_headers INTERFACE IMPORTED ) +add_library( ll::gio INTERFACE IMPORTED ) + +if( LINUX ) + find_package(PkgConfig REQUIRED) + pkg_search_module(GLIB REQUIRED glib-2.0) + pkg_search_module(GIO REQUIRED gio-2.0) + + target_include_directories( ll::glib SYSTEM INTERFACE ${GLIB_INCLUDE_DIRS} ) + target_link_libraries( ll::glib INTERFACE ${GLIB_LDFLAGS} ) + target_compile_definitions( ll::glib INTERFACE -DLL_GLIB=1) + + target_include_directories( ll::glib_headers SYSTEM INTERFACE ${GLIB_INCLUDE_DIRS} ) + target_compile_definitions( ll::glib_headers INTERFACE -DLL_GLIB=1) + + target_link_libraries( ll::gio INTERFACE ${GIO_LDFLAGS} ) +endif() diff --git a/indra/cmake/GLM.cmake b/indra/cmake/GLM.cmake index 84b155f6c5..d411c049ec 100644 --- a/indra/cmake/GLM.cmake +++ b/indra/cmake/GLM.cmake @@ -3,5 +3,12 @@ include(Prebuilt) add_library( ll::glm INTERFACE IMPORTED ) +if (NOT USESYSTEMLIBS) use_system_binary( glm ) +elseif (NOT (${LINUX_DISTRO} MATCHES debian OR (${LINUX_DISTRO} MATCHES ubuntu) OR (${LINUX_DISTRO} MATCHES opensuse-tumbleweed))) + find_package( glm REQUIRED ) +endif (NOT USESYSTEMLIBS) + +if (${LINUX_DISTRO} MATCHES debian OR (${LINUX_DISTRO} MATCHES ubuntu) OR (${LINUX_DISTRO} MATCHES opensuse-tumbleweed) OR NOT USESYSTEMLIBS) use_prebuilt_binary(glm) +endif () diff --git a/indra/cmake/GStreamer10Plugin.cmake b/indra/cmake/GStreamer10Plugin.cmake new file mode 100644 index 0000000000..160844ef68 --- /dev/null +++ b/indra/cmake/GStreamer10Plugin.cmake @@ -0,0 +1,27 @@ +# -*- cmake -*- + +include_guard() + +include(Prebuilt) +include(GLIB) + +add_library( ll::gstreamer10 INTERFACE IMPORTED ) + +if (LINUX OR CMAKE_SYSTEM_NAME MATCHES "FreeBSD") + include(FindPkgConfig) + + pkg_check_modules(GSTREAMER10 REQUIRED gstreamer-1.0) + pkg_check_modules(GSTREAMER10_PLUGINS_BASE REQUIRED gstreamer-plugins-base-1.0) + + target_include_directories( ll::gstreamer10 SYSTEM INTERFACE ${GSTREAMER10_INCLUDE_DIRS}) + target_link_libraries( ll::gstreamer10 INTERFACE ll::glib_headers) + +endif () + +if (GSTREAMER10_FOUND AND GSTREAMER10_PLUGINS_BASE_FOUND) + set(GSTREAMER10 ON CACHE BOOL "Build with GStreamer-1.0 streaming media support.") +endif (GSTREAMER10_FOUND AND GSTREAMER10_PLUGINS_BASE_FOUND) + +if (GSTREAMER10) + add_definitions(-DLL_GSTREAMER10_ENABLED=1) +endif (GSTREAMER10) diff --git a/indra/cmake/LLAddBuildTest.cmake b/indra/cmake/LLAddBuildTest.cmake index 6408f1200c..5d96a4398f 100644 --- a/indra/cmake/LLAddBuildTest.cmake +++ b/indra/cmake/LLAddBuildTest.cmake @@ -1,4 +1,11 @@ # -*- cmake -*- + +include_guard() + +if( NOT LL_TESTS ) + return() +endif() + include(00-Common) include(LLTestCommand) include(bugsplat) diff --git a/indra/cmake/LLCoreHttp.cmake b/indra/cmake/LLCoreHttp.cmake index 22ed5fef9c..5464e4d327 100644 --- a/indra/cmake/LLCoreHttp.cmake +++ b/indra/cmake/LLCoreHttp.cmake @@ -1,5 +1,5 @@ # -*- cmake -*- -include(CURL) include(OpenSSL) +include(CURL) include(NGHTTP2) diff --git a/indra/cmake/LLPrimitive.cmake b/indra/cmake/LLPrimitive.cmake index d0a52ffb63..d94def5808 100644 --- a/indra/cmake/LLPrimitive.cmake +++ b/indra/cmake/LLPrimitive.cmake @@ -18,6 +18,118 @@ if( USE_CONAN ) "${CONAN_INCLUDE_DIRS_COLLADADOM}/collada-dom/1.4/" ) endif() +if( USESYSTEMLIBS ) + if( WINDOWS ) + include(FindPkgConfig) + pkg_check_modules(Colladadom REQUIRED collada-dom-141) + target_compile_definitions( ll::colladadom INTERFACE COLLADA_DOM_SUPPORT141 ) + target_include_directories( ll::colladadom SYSTEM INTERFACE ${Colladadom_INCLUDE_DIRS} ) + target_link_directories( ll::colladadom INTERFACE ${Colladadom_LIBRARY_DIRS} ) + target_link_libraries( ll::colladadom INTERFACE ${Colladadom_LIBRARIES} ) + return () + elseif( LINUX OR CMAKE_SYSTEM_NAME MATCHES FreeBSD ) + # Build of the collada-dom for Linux and FreeBSD is done in + # indra/llprimitive/CMakeLists.txt + return () + else( WINDOWS ) + include(FindPkgConfig) + pkg_check_modules(Minizip REQUIRED minizip) + pkg_check_modules(Libxml2 REQUIRED libxml-2.0) + target_link_libraries( ll::minizip-ng INTERFACE ${Minizip_LIBRARIES} ) + target_link_libraries( ll::libxml INTERFACE ${Libxml2_LIBRARIES} ) + if( ${PREBUILD_TRACKING_DIR}/sentinel_installed IS_NEWER_THAN ${PREBUILD_TRACKING_DIR}/colladadom_installed OR NOT ${colladadom_installed} EQUAL 0 ) + if( NOT EXISTS ${CMAKE_BINARY_DIR}/3p-colladadom-2.3-r8.tar.gz ) + file(DOWNLOAD + https://github.com/secondlife/3p-colladadom/archive/refs/tags/v2.3-r8.tar.gz + ${CMAKE_BINARY_DIR}/3p-colladadom-2.3-r8.tar.gz + ) + endif( NOT EXISTS ${CMAKE_BINARY_DIR}/3p-colladadom-2.3-r8.tar.gz ) + file(ARCHIVE_EXTRACT + INPUT ${CMAKE_BINARY_DIR}/3p-colladadom-2.3-r8.tar.gz + DESTINATION ${CMAKE_BINARY_DIR} + ) + file(MAKE_DIRECTORY ${LIBS_PREBUILT_DIR}/include/collada/1.4) + if( DARWIN ) + try_compile(COLLADADOM_RESULT + PROJECT colladadom + SOURCE_DIR ${CMAKE_BINARY_DIR}/3p-colladadom-2.3-r8 + BINARY_DIR ${CMAKE_BINARY_DIR}/3p-colladadom-2.3-r8 + TARGET collada14dom + CMAKE_FLAGS + -DCMAKE_CXX_STANDARD:STRING=17 + -DCMAKE_CXX_FLAGS:STRING=-I${Minizip_INCLUDE_DIRS} + "-DCMAKE_SHARED_LINKER_FLAGS:STRING=-L${Minizip_LIBRARY_DIRS} -L${Minizip_LIBRARY_DIRS}exec/boost/1.87/lib" + -DCMAKE_OSX_ARCHITECTURES:STRING=${CMAKE_OSX_ARCHITECTURES} + -DCMAKE_OSX_DEPLOYMENT_TARGET:STRING=${CMAKE_OSX_DEPLOYMENT_TARGET} + -DZLIB_LIBRARIES:STRING=${Libxml2_LIBRARIES} + -DBoost_FILESYSTEM_LIBRARY:STRING=boost_filesystem-mt + -DBoost_SYSTEM_LIBRARY:STRING=boost_system-mt + -DEXTRA_COMPILE_FLAGS:STRING=-I${Libxml2_INCLUDE_DIRS} + -DBoost_CFLAGS:STRING=-I${Libxml2_LIBRARY_DIRS}exec/boost/1.87/include + -DOPT_COLLADA14:BOOL=ON + -DCOLLADA_DOM_INCLUDE_INSTALL_DIR:FILEPATH=${LIBS_PREBUILT_DIR}/include/collada + -DCOLLADA_DOM_SOVERSION:STRING=0 + -DCOLLADA_DOM_VERSION:STRING=2.3-r8 + OUTPUT_VARIABLE colladadom_installed + ) + if( ${COLLADADOM_RESULT} ) + file( + COPY + ${CMAKE_BINARY_DIR}/3p-colladadom-2.3-r8/src/1.4/libcollada14dom.2.3-r8.dylib + ${CMAKE_BINARY_DIR}/3p-colladadom-2.3-r8/src/1.4/libcollada14dom.0.dylib + ${CMAKE_BINARY_DIR}/3p-colladadom-2.3-r8/src/1.4/libcollada14dom.dylib + DESTINATION ${LIBS_PREBUILT_DIR}/lib/release + FOLLOW_SYMLINK_CHAIN + ) + endif( ${COLLADADOM_RESULT} ) + else( DARWIN ) + execute_process( + COMMAND sed -i "" -e "s/SHARED/STATIC/g" 1.4/CMakeLists.txt + WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/3p-colladadom-2.3-r8/src + ) + try_compile(COLLADADOM_RESULT + PROJECT colladadom + SOURCE_DIR ${CMAKE_BINARY_DIR}/3p-colladadom-2.3-r8 + BINARY_DIR ${CMAKE_BINARY_DIR}/3p-colladadom-2.3-r8 + TARGET collada14dom + CMAKE_FLAGS + -DCMAKE_CXX_STANDARD:STRING=17 + -DCMAKE_CXX_FLAGS:STRING=-I${Minizip_INCLUDE_DIRS} + -DCMAKE_SHARED_LINKER_FLAGS:STRING=-L${Minizip_LIBRARY_DIRS} + -DZLIB_LIBRARIES:STRING=${Libxml2_LIBRARIES} + -DBoost_FILESYSTEM_LIBRARY:STRING=boost_filesystem + -DBoost_SYSTEM_LIBRARY:STRING=boost_system + -DEXTRA_COMPILE_FLAGS:STRING=-I${Libxml2_INCLUDE_DIRS} + -DOPT_COLLADA14:BOOL=ON + -DCOLLADA_DOM_INCLUDE_INSTALL_DIR:FILEPATH=${LIBS_PREBUILT_DIR}/include/collada + -DCOLLADA_DOM_SOVERSION:STRING=0 + -DCOLLADA_DOM_VERSION:STRING=2.3-r8 + OUTPUT_VARIABLE colladadom_installed + ) + if( ${COLLADADOM_RESULT} ) + file( + COPY ${CMAKE_BINARY_DIR}/3p-colladadom-2.3-r8/src/1.4/libcollada14dom.a + DESTINATION ${LIBS_PREBUILT_DIR}/lib/release + ) + endif( ${COLLADADOM_RESULT} ) + endif( DARWIN ) + if( ${COLLADADOM_RESULT} ) + file(REMOVE_RECURSE ${LIBS_PREBUILT_DIR}/include/collada/1.4) + file( + COPY + ${CMAKE_BINARY_DIR}/3p-colladadom-2.3-r8/include/1.4 + ${CMAKE_BINARY_DIR}/3p-colladadom-2.3-r8/include/1.5 + ${CMAKE_BINARY_DIR}/3p-colladadom-2.3-r8/include/dae + ${CMAKE_BINARY_DIR}/3p-colladadom-2.3-r8/include/dae.h + ${CMAKE_BINARY_DIR}/3p-colladadom-2.3-r8/include/dom.h + ${CMAKE_BINARY_DIR}/3p-colladadom-2.3-r8/include/modules + DESTINATION ${LIBS_PREBUILT_DIR}/include/collada + ) + file(WRITE ${PREBUILD_TRACKING_DIR}/colladadom_installed "${colladadom_installed}") + endif( ${COLLADADOM_RESULT} ) + endif( ${PREBUILD_TRACKING_DIR}/sentinel_installed IS_NEWER_THAN ${PREBUILD_TRACKING_DIR}/colladadom_installed OR NOT ${colladadom_installed} EQUAL 0 ) + endif( WINDOWS ) +else( USESYSTEMLIBS ) use_system_binary( colladadom ) use_prebuilt_binary(colladadom) @@ -35,6 +147,7 @@ if (WINDOWS) else() target_link_libraries( ll::libxml INTERFACE ${ARCH_PREBUILT_DIRS_RELEASE}/libxml2.a) endif() +endif( USESYSTEMLIBS ) target_include_directories( ll::colladadom SYSTEM INTERFACE ${LIBS_PREBUILT_DIR}/include/collada @@ -42,8 +155,6 @@ target_include_directories( ll::colladadom SYSTEM INTERFACE ) if (WINDOWS) target_link_libraries(ll::colladadom INTERFACE ${ARCH_PREBUILT_DIRS_RELEASE}/libcollada14dom23-s.lib ll::libxml ll::minizip-ng ) -elseif (DARWIN) - target_link_libraries(ll::colladadom INTERFACE collada14dom ll::boost ll::libxml ll::minizip-ng) -elseif (LINUX) +else () target_link_libraries(ll::colladadom INTERFACE collada14dom ll::boost ll::libxml ll::minizip-ng) endif() diff --git a/indra/cmake/LLWindow.cmake b/indra/cmake/LLWindow.cmake index 2e1b601b79..31907d31df 100644 --- a/indra/cmake/LLWindow.cmake +++ b/indra/cmake/LLWindow.cmake @@ -7,16 +7,27 @@ include(Prebuilt) include_guard() add_library( ll::SDL INTERFACE IMPORTED ) +if (USESYSTEMLIBS AND NOT (WINDOWS OR DARWIN)) + include(FindPkgConfig) + pkg_check_modules(Sdl2 REQUIRED sdl2) + target_compile_definitions( ll::SDL INTERFACE LL_SDL=1) + target_include_directories(ll::SDL SYSTEM INTERFACE ${Sdl2_INCLUDE_DIRS}) + target_link_directories(ll::SDL INTERFACE ${Sdl2_LIBRARY_DIRS}) + if (LINUX OR CMAKE_SYSTEM_NAME MATCHES "FreeBSD") + list(APPEND Sdl2_LIBRARIES X11) + endif () + target_link_libraries(ll::SDL INTERFACE ${Sdl2_LIBRARIES}) + return () +endif () + if (LINUX) #Must come first as use_system_binary can exit this file early - target_compile_definitions( ll::SDL INTERFACE LL_SDL=1) + target_compile_definitions( ll::SDL INTERFACE LL_SDL_VERSION=2 LL_SDL) - use_system_binary(SDL) - use_prebuilt_binary(SDL) + #find_package(SDL2 REQUIRED) + #target_link_libraries( ll::SDL INTERFACE SDL2::SDL2 SDL2::SDL2main X11) - target_include_directories( ll::SDL SYSTEM INTERFACE ${LIBS_PREBUILT_DIR}/include) - target_link_libraries( ll::SDL INTERFACE SDL directfb fusion direct X11) + use_prebuilt_binary(SDL2) + target_link_libraries( ll::SDL INTERFACE SDL2 X11) endif (LINUX) - - diff --git a/indra/cmake/LibVLCPlugin.cmake b/indra/cmake/LibVLCPlugin.cmake index 599ce02844..779576a485 100644 --- a/indra/cmake/LibVLCPlugin.cmake +++ b/indra/cmake/LibVLCPlugin.cmake @@ -5,9 +5,56 @@ include(Prebuilt) include_guard() add_library( ll::libvlc INTERFACE IMPORTED ) +if (USESYSTEMLIBS) + if (DARWIN) + if (CMAKE_OSX_ARCHITECTURES MATCHES arm64) + if (${PREBUILD_TRACKING_DIR}/sentinel_installed IS_NEWER_THAN ${PREBUILD_TRACKING_DIR}/vlc_installed OR NOT ${vlc_installed} EQUAL 0) + if (NOT EXISTS ${CMAKE_BINARY_DIR}/vlc-3.0.21-arm64.dmg) + file(DOWNLOAD + https://get.videolan.org/vlc/3.0.21/macosx/vlc-3.0.21-arm64.dmg + ${CMAKE_BINARY_DIR}/vlc-3.0.21-arm64.dmg + ) + endif (NOT EXISTS ${CMAKE_BINARY_DIR}/vlc-3.0.21-arm64.dmg) + file(WRITE ${PREBUILD_TRACKING_DIR}/vlc_installed "0") + endif (${PREBUILD_TRACKING_DIR}/sentinel_installed IS_NEWER_THAN ${PREBUILD_TRACKING_DIR}/vlc_installed OR NOT ${vlc_installed} EQUAL 0) + execute_process( + COMMAND hdiutil attach -noverify vlc-3.0.21-arm64.dmg + WORKING_DIRECTORY ${CMAKE_BINARY_DIR} + ) + else (CMAKE_OSX_ARCHITECTURES MATCHES arm64) + if (${PREBUILD_TRACKING_DIR}/sentinel_installed IS_NEWER_THAN ${PREBUILD_TRACKING_DIR}/vlc_installed OR NOT ${vlc_installed} EQUAL 0) + if (NOT EXISTS ${CMAKE_BINARY_DIR}/vlc-3.0.21-intel64.dmg) + file(DOWNLOAD + https://get.videolan.org/vlc/3.0.21/macosx/vlc-3.0.21-intel64.dmg + ${CMAKE_BINARY_DIR}/vlc-3.0.21-intel64.dmg + ) + endif (NOT EXISTS ${CMAKE_BINARY_DIR}/vlc-3.0.21-intel64.dmg) + file(WRITE ${PREBUILD_TRACKING_DIR}/vlc_installed "0") + endif (${PREBUILD_TRACKING_DIR}/sentinel_installed IS_NEWER_THAN ${PREBUILD_TRACKING_DIR}/vlc_installed OR NOT ${vlc_installed} EQUAL 0) + execute_process( + COMMAND hdiutil attach -noverify vlc-3.0.21-intel64.dmg + WORKING_DIRECTORY ${CMAKE_BINARY_DIR} + ) + endif (CMAKE_OSX_ARCHITECTURES MATCHES arm64) + target_include_directories( ll::libvlc SYSTEM INTERFACE /Volumes/VLC\ media\ player/VLC.app/Contents/MacOS/include) + target_link_directories( ll::libvlc INTERFACE /Volumes/VLC\ media\ player/VLC.app/Contents/MacOS/lib) + target_link_libraries( ll::libvlc INTERFACE vlc vlccore ) + else (DARWIN) + include(FindPkgConfig) + pkg_check_modules(Libvlc REQUIRED libvlc vlc-plugin) + target_include_directories( ll::libvlc SYSTEM INTERFACE ${Libvlc_INCLUDE_DIRS} ) + target_link_directories( ll::libvlc INTERFACE ${Libvlc_LIBRARY_DIRS} ) + target_link_libraries( ll::libvlc INTERFACE ${Libvlc_LIBRARIES} ) + endif (DARWIN) + set(LIBVLCPLUGIN ON CACHE BOOL + "LIBVLCPLUGIN support for the llplugin/llmedia test apps.") + return() +else (USESYSTEMLIBS) + use_prebuilt_binary(vlc-bin) set(LIBVLCPLUGIN ON CACHE BOOL "LIBVLCPLUGIN support for the llplugin/llmedia test apps.") +endif (USESYSTEMLIBS) if (WINDOWS) target_link_libraries( ll::libvlc INTERFACE diff --git a/indra/cmake/LibraryInstall.cmake b/indra/cmake/LibraryInstall.cmake new file mode 100644 index 0000000000..a843f40c99 --- /dev/null +++ b/indra/cmake/LibraryInstall.cmake @@ -0,0 +1,13 @@ +list(REMOVE_ITEM ${PROJECT_NAME}_HEADER_FILES CMakeLists.txt) +#install(FILES ${${PROJECT_NAME}_HEADER_FILES} +# DESTINATION include/${PROJECT_NAME}) +if (BUILD_SHARED_LIBS) + if (${LINUX_DISTRO} MATCHES debian OR (${LINUX_DISTRO} MATCHES ubuntu)) + set(_LIB lib/${ARCH}-linux-gnu) + elseif (${LINUX_DISTRO} MATCHES fedora OR (${LINUX_DISTRO} MATCHES opensuse-tumbleweed) OR (${LINUX_DISTRO} MATCHES gentoo)) + set(_LIB lib${ADDRESS_SIZE}) + else () + set(_LIB lib) + endif () + install(TARGETS ${PROJECT_NAME} DESTINATION ${_LIB}) +endif () diff --git a/indra/cmake/Linker.cmake b/indra/cmake/Linker.cmake new file mode 100644 index 0000000000..8016842192 --- /dev/null +++ b/indra/cmake/Linker.cmake @@ -0,0 +1,11 @@ +include_guard(GLOBAL) + +if( LINK_WITH_MOLD ) + find_program(MOLD_BIN mold) + if(MOLD_BIN) + message(STATUS "Mold linker found: ${MOLD_BIN}. Enabling mold as active linker.") + add_link_options("-fuse-ld=${MOLD_BIN}") + else() + message(STATUS "Mold linker not found. Using default linker.") + endif() +endif() diff --git a/indra/cmake/Linking.cmake b/indra/cmake/Linking.cmake index 1d757abeff..8e91dac109 100644 --- a/indra/cmake/Linking.cmake +++ b/indra/cmake/Linking.cmake @@ -66,7 +66,7 @@ elseif (WINDOWS) rpcrt4.lib legacy_stdio_definitions ) -else() +elseif (DARWIN) include(CMakeFindFrameworks) find_library(COREFOUNDATION_LIBRARY CoreFoundation) find_library(CARBON_LIBRARY Carbon) diff --git a/indra/cmake/Meshoptimizer.cmake b/indra/cmake/Meshoptimizer.cmake index fd144d2b97..20eef33d7c 100644 --- a/indra/cmake/Meshoptimizer.cmake +++ b/indra/cmake/Meshoptimizer.cmake @@ -6,15 +6,63 @@ include(Prebuilt) include_guard() add_library( ll::meshoptimizer INTERFACE IMPORTED ) +if (NOT USESYSTEMLIBS) use_system_binary(meshoptimizer) +elseif (${LINUX_DISTRO} MATCHES debian OR (${LINUX_DISTRO} MATCHES ubuntu) OR CMAKE_SYSTEM_NAME MATCHES FreeBSD) + find_package(meshoptimizer) + target_link_libraries( ll::meshoptimizer INTERFACE meshoptimizer) + return () +endif (NOT USESYSTEMLIBS) + +if (LINUX AND CMAKE_SYSTEM_PROCESSOR MATCHES x86_64 AND NOT (${LINUX_DISTRO} MATCHES gentoo) OR NOT USESYSTEMLIBS) use_prebuilt_binary(meshoptimizer) +elseif (${PREBUILD_TRACKING_DIR}/sentinel_installed IS_NEWER_THAN ${PREBUILD_TRACKING_DIR}/meshoptimizer_installed OR NOT ${meshoptimizer_installed} EQUAL 0) + if (NOT EXISTS ${CMAKE_BINARY_DIR}/meshoptimizer-0.21.tar.gz) + file(DOWNLOAD + https://github.com/zeux/meshoptimizer/archive/refs/tags/v0.21.tar.gz + ${CMAKE_BINARY_DIR}/meshoptimizer-0.21.tar.gz + ) + endif (NOT EXISTS ${CMAKE_BINARY_DIR}/meshoptimizer-0.21.tar.gz) + file(ARCHIVE_EXTRACT + INPUT ${CMAKE_BINARY_DIR}/meshoptimizer-0.21.tar.gz + DESTINATION ${CMAKE_BINARY_DIR} + ) + if (DARWIN) + try_compile(MESHOPTIMIZER_RESULT + PROJECT meshoptimizer + SOURCE_DIR ${CMAKE_BINARY_DIR}/meshoptimizer-0.21 + BINARY_DIR ${CMAKE_BINARY_DIR}/meshoptimizer-0.21 + TARGET meshoptimizer + CMAKE_FLAGS + -DCMAKE_OSX_DEPLOYMENT_TARGET:STRING=${CMAKE_OSX_DEPLOYMENT_TARGET} + OUTPUT_VARIABLE meshoptimizer_installed + ) + else () + try_compile(MESHOPTIMIZER_RESULT + PROJECT meshoptimizer + SOURCE_DIR ${CMAKE_BINARY_DIR}/meshoptimizer-0.21 + BINARY_DIR ${CMAKE_BINARY_DIR}/meshoptimizer-0.21 + TARGET meshoptimizer + OUTPUT_VARIABLE meshoptimizer_installed + ) + endif (DARWIN) + if (${MESHOPTIMIZER_RESULT}) + file( + COPY ${CMAKE_BINARY_DIR}/meshoptimizer-0.21/src/meshoptimizer.h + DESTINATION ${LIBS_PREBUILT_DIR}/include/meshoptimizer + ) + file( + COPY ${CMAKE_BINARY_DIR}/meshoptimizer-0.21/libmeshoptimizer.a + DESTINATION ${LIBS_PREBUILT_DIR}/lib/release + ) + file(WRITE ${PREBUILD_TRACKING_DIR}/meshoptimizer_installed "${meshoptimizer_installed}") + endif (${MESHOPTIMIZER_RESULT}) +endif (LINUX AND CMAKE_SYSTEM_PROCESSOR MATCHES x86_64 AND NOT (${LINUX_DISTRO} MATCHES gentoo) OR NOT USESYSTEMLIBS) -if (WINDOWS) +if (NOT USESYSTEMLIBS AND WINDOWS) target_link_libraries( ll::meshoptimizer INTERFACE meshoptimizer.lib) -elseif (LINUX) - target_link_libraries( ll::meshoptimizer INTERFACE meshoptimizer.o) -elseif (DARWIN) +else (NOT USESYSTEMLIBS AND WINDOWS) target_link_libraries( ll::meshoptimizer INTERFACE libmeshoptimizer.a) -endif (WINDOWS) +endif (NOT USESYSTEMLIBS AND WINDOWS) target_include_directories( ll::meshoptimizer SYSTEM INTERFACE ${LIBS_PREBUILT_DIR}/include/meshoptimizer) diff --git a/indra/cmake/Mikktspace.cmake b/indra/cmake/Mikktspace.cmake index 9fd2becba4..c73321e313 100644 --- a/indra/cmake/Mikktspace.cmake +++ b/indra/cmake/Mikktspace.cmake @@ -1,6 +1,4 @@ # -*- cmake -*- include(Prebuilt) -if (NOT USESYSTEMLIBS) use_prebuilt_binary(mikktspace) -endif (NOT USESYSTEMLIBS) diff --git a/indra/cmake/NDOF.cmake b/indra/cmake/NDOF.cmake index b88fbccf2a..0b0a2b6ca9 100644 --- a/indra/cmake/NDOF.cmake +++ b/indra/cmake/NDOF.cmake @@ -8,7 +8,39 @@ add_library( ll::ndof INTERFACE IMPORTED ) if (NDOF) if (WINDOWS OR DARWIN) + if (NOT USESYSTEMLIBS) use_prebuilt_binary(libndofdev) + elseif (DARWIN AND (${PREBUILD_TRACKING_DIR}/sentinel_installed IS_NEWER_THAN ${PREBUILD_TRACKING_DIR}/libndofdev_installed OR NOT ${libndofdev_installed} EQUAL 0)) + file(DOWNLOAD + https://github.com/secondlife/3p-libndofdev/archive/refs/tags/v0.1.8e9edc7.tar.gz + ${CMAKE_BINARY_DIR}/3p-libndofdev-0.1.8e9edc7.tar.gz + ) + file(ARCHIVE_EXTRACT + INPUT ${CMAKE_BINARY_DIR}/3p-libndofdev-0.1.8e9edc7.tar.gz + DESTINATION ${CMAKE_BINARY_DIR} + ) + try_compile(LIBNDOFDEV_RESULT + PROJECT libndofdev + SOURCE_DIR ${CMAKE_BINARY_DIR}/3p-libndofdev-0.1.8e9edc7/libndofdev + BINARY_DIR ${CMAKE_BINARY_DIR}/3p-libndofdev-0.1.8e9edc7/libndofdev + TARGET ndofdev + CMAKE_FLAGS + -DCMAKE_C_FLAGS:STRING=-DTARGET_OS_MAC\ -Wno-int-conversion + -DCMAKE_OSX_DEPLOYMENT_TARGET:STRING=${CMAKE_OSX_DEPLOYMENT_TARGET} + OUTPUT_VARIABLE libndofdev_installed + ) + if (${LIBNDOFDEV_RESULT}) + file( + COPY ${CMAKE_BINARY_DIR}/3p-libndofdev-0.1.8e9edc7/libndofdev/src/ndofdev_external.h + DESTINATION ${LIBS_PREBUILT_DIR}/include + ) + file( + COPY ${CMAKE_BINARY_DIR}/3p-libndofdev-0.1.8e9edc7/libndofdev/src/libndofdev.dylib + DESTINATION ${LIBS_PREBUILT_DIR}/lib/release + ) + file(WRITE ${PREBUILD_TRACKING_DIR}/libndofdev_installed "${libndofdev_installed}") + endif (${LIBNDOFDEV_RESULT}) + endif (NOT USESYSTEMLIBS) elseif (LINUX) use_prebuilt_binary(open-libndofdev) endif (WINDOWS OR DARWIN) @@ -19,6 +51,6 @@ if (NDOF) target_link_libraries( ll::ndof INTERFACE ndofdev) endif (WINDOWS) target_compile_definitions( ll::ndof INTERFACE LIB_NDOF=1) +else() + add_compile_options(-ULIB_NDOF) endif (NDOF) - - diff --git a/indra/cmake/OPENAL.cmake b/indra/cmake/OPENAL.cmake index 347dd02cd7..6555027dc1 100644 --- a/indra/cmake/OPENAL.cmake +++ b/indra/cmake/OPENAL.cmake @@ -18,6 +18,17 @@ endif() if (USE_OPENAL) add_library( ll::openal INTERFACE IMPORTED ) + + if (NOT (USE_AUTOBUILD_3P OR USE_CONAN)) + target_compile_definitions( ll::openal INTERFACE LL_OPENAL=1) + include(FindPkgConfig) + pkg_check_modules(Openal REQUIRED freealut) + target_include_directories(ll::openal SYSTEM INTERFACE ${Openal_INCLUDE_DIRS}) + target_link_directories(ll::openal INTERFACE ${Openal_LIBRARY_DIRS}) + target_link_libraries(ll::openal INTERFACE ${Openal_LIBRARIES}) + return () + endif () + target_include_directories( ll::openal SYSTEM INTERFACE "${LIBS_PREBUILT_DIR}/include/AL") target_compile_definitions( ll::openal INTERFACE LL_OPENAL=1) use_prebuilt_binary(openal) diff --git a/indra/cmake/OpenJPEG.cmake b/indra/cmake/OpenJPEG.cmake index c4aab2e9e5..d4304f93b3 100644 --- a/indra/cmake/OpenJPEG.cmake +++ b/indra/cmake/OpenJPEG.cmake @@ -4,8 +4,64 @@ include(Prebuilt) include_guard() add_library( ll::openjpeg INTERFACE IMPORTED ) +if (NOT USESYSTEMLIBS) use_system_binary(openjpeg) +endif (NOT USESYSTEMLIBS) +if (LINUX AND CMAKE_SYSTEM_PROCESSOR MATCHES x86_64 OR NOT USESYSTEMLIBS) use_prebuilt_binary(openjpeg) +elseif (${PREBUILD_TRACKING_DIR}/sentinel_installed IS_NEWER_THAN ${PREBUILD_TRACKING_DIR}/openjpeg_installed OR NOT ${openjpeg_installed} EQUAL 0) + if (NOT EXISTS ${CMAKE_BINARY_DIR}/3p-openjpeg-2.5.0.ea12248.tar.gz) + file(DOWNLOAD + https://github.com/secondlife/3p-openjpeg/archive/refs/tags/v2.5.0.ea12248.tar.gz + ${CMAKE_BINARY_DIR}/3p-openjpeg-2.5.0.ea12248.tar.gz + ) + endif (NOT EXISTS ${CMAKE_BINARY_DIR}/3p-openjpeg-2.5.0.ea12248.tar.gz) + file(ARCHIVE_EXTRACT + INPUT ${CMAKE_BINARY_DIR}/3p-openjpeg-2.5.0.ea12248.tar.gz + DESTINATION ${CMAKE_BINARY_DIR} + ) + if (DARWIN) + try_compile(OPENJPEG_RESULT + PROJECT OPENJPEG + SOURCE_DIR ${CMAKE_BINARY_DIR}/3p-openjpeg-2.5.0.ea12248/openjpeg + BINARY_DIR ${CMAKE_BINARY_DIR}/3p-openjpeg-2.5.0.ea12248/openjpeg + TARGET openjp2 + CMAKE_FLAGS + -DBUILD_SHARED_LIBS:BOOL=${BUILD_SHARED_LIBS} + -DCMAKE_BUILD_WITH_INSTALL_RPATH:BOOL=ON + -DCMAKE_OSX_DEPLOYMENT_TARGET:STRING=${CMAKE_OSX_DEPLOYMENT_TARGET} + OUTPUT_VARIABLE openjpeg_installed + ) + else () + try_compile(OPENJPEG_RESULT + PROJECT OPENJPEG + SOURCE_DIR ${CMAKE_BINARY_DIR}/3p-openjpeg-2.5.0.ea12248/openjpeg + BINARY_DIR ${CMAKE_BINARY_DIR}/3p-openjpeg-2.5.0.ea12248/openjpeg + TARGET openjp2 + CMAKE_FLAGS + -DBUILD_SHARED_LIBS:BOOL=${BUILD_SHARED_LIBS} + -DCMAKE_BUILD_WITH_INSTALL_RPATH:BOOL=ON + OUTPUT_VARIABLE openjpeg_installed + ) + endif (DARWIN) + if (${OPENJPEG_RESULT}) + file( + COPY + ${CMAKE_BINARY_DIR}/3p-openjpeg-2.5.0.ea12248/openjpeg/src/lib/openjp2/cio.h + ${CMAKE_BINARY_DIR}/3p-openjpeg-2.5.0.ea12248/openjpeg/src/lib/openjp2/event.h + ${CMAKE_BINARY_DIR}/3p-openjpeg-2.5.0.ea12248/openjpeg/src/lib/openjp2/openjpeg.h + ${CMAKE_BINARY_DIR}/3p-openjpeg-2.5.0.ea12248/openjpeg/src/lib/openjp2/opj_config.h + ${CMAKE_BINARY_DIR}/3p-openjpeg-2.5.0.ea12248/openjpeg/src/lib/openjp2/opj_config_private.h + ${CMAKE_BINARY_DIR}/3p-openjpeg-2.5.0.ea12248/openjpeg/src/lib/openjp2/opj_stdint.h + DESTINATION ${LIBS_PREBUILT_DIR}/include/openjpeg + ) + file( + COPY ${CMAKE_BINARY_DIR}/3p-openjpeg-2.5.0.ea12248/openjpeg/bin/libopenjp2.a + DESTINATION ${LIBS_PREBUILT_DIR}/lib/release + ) + file(WRITE ${PREBUILD_TRACKING_DIR}/openjpeg_installed "${openjpeg_installed}") + endif (${OPENJPEG_RESULT}) +endif (LINUX AND CMAKE_SYSTEM_PROCESSOR MATCHES x86_64 OR NOT USESYSTEMLIBS) target_link_libraries(ll::openjpeg INTERFACE openjp2 ) -target_include_directories( ll::openjpeg SYSTEM INTERFACE ${LIBS_PREBUILT_DIR}/include/openjpeg) +target_include_directories( ll::openjpeg SYSTEM INTERFACE ${LIBS_PREBUILT_DIR}/include) diff --git a/indra/cmake/OpenSSL.cmake b/indra/cmake/OpenSSL.cmake index 67a84e14af..43470032a9 100644 --- a/indra/cmake/OpenSSL.cmake +++ b/indra/cmake/OpenSSL.cmake @@ -5,14 +5,187 @@ include(Linking) include_guard() add_library( ll::openssl INTERFACE IMPORTED ) +if (NOT USESYSTEMLIBS) use_system_binary(openssl) +endif (NOT USESYSTEMLIBS) +if (LINUX AND CMAKE_SYSTEM_PROCESSOR MATCHES x86_64 OR DARWIN OR NOT USESYSTEMLIBS) use_prebuilt_binary(openssl) -if (WINDOWS) + if (DARWIN) + execute_process( + COMMAND lipo -archs libcrypto.a + WORKING_DIRECTORY ${LIBS_PREBUILT_DIR}/lib/release + OUTPUT_VARIABLE crypto_archs + OUTPUT_STRIP_TRAILING_WHITESPACE + ) + if (NOT ${crypto_archs} STREQUAL ${CMAKE_OSX_ARCHITECTURES}) + execute_process( + COMMAND lipo + libcrypto.a + -thin ${CMAKE_OSX_ARCHITECTURES} + -output libcrypto.a + WORKING_DIRECTORY ${LIBS_PREBUILT_DIR}/lib/release + ) + endif (NOT ${crypto_archs} STREQUAL ${CMAKE_OSX_ARCHITECTURES}) + execute_process( + COMMAND lipo -archs libssl.a + WORKING_DIRECTORY ${LIBS_PREBUILT_DIR}/lib/release + OUTPUT_VARIABLE ssl_archs + OUTPUT_STRIP_TRAILING_WHITESPACE + ) + if (NOT ${ssl_archs} STREQUAL ${CMAKE_OSX_ARCHITECTURES}) + execute_process( + COMMAND lipo + libssl.a + -thin ${CMAKE_OSX_ARCHITECTURES} + -output libssl.a + WORKING_DIRECTORY ${LIBS_PREBUILT_DIR}/lib/release + ) + endif (NOT ${ssl_archs} STREQUAL ${CMAKE_OSX_ARCHITECTURES}) + endif (DARWIN) +elseif (${PREBUILD_TRACKING_DIR}/sentinel_installed IS_NEWER_THAN ${PREBUILD_TRACKING_DIR}/openssl_installed OR NOT ${openssl_installed} EQUAL 0) + if (NOT EXISTS ${CMAKE_BINARY_DIR}/OpenSSL_1_1_1w.tar.gz) + file(DOWNLOAD + https://github.com/openssl/openssl/archive/refs/tags/OpenSSL_1_1_1w.tar.gz + ${CMAKE_BINARY_DIR}/OpenSSL_1_1_1w.tar.gz + ) + endif (NOT EXISTS ${CMAKE_BINARY_DIR}/OpenSSL_1_1_1w.tar.gz) + file(ARCHIVE_EXTRACT + INPUT ${CMAKE_BINARY_DIR}/OpenSSL_1_1_1w.tar.gz + DESTINATION ${CMAKE_BINARY_DIR} + ) + execute_process( + COMMAND ./config no-shared + WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/openssl-OpenSSL_1_1_1w + ) + execute_process( + COMMAND make -j${MAKE_JOBS} + WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/openssl-OpenSSL_1_1_1w + RESULT_VARIABLE openssl_installed + ) + file( + COPY + ${CMAKE_BINARY_DIR}/openssl-OpenSSL_1_1_1w/include/openssl/aes.h + ${CMAKE_BINARY_DIR}/openssl-OpenSSL_1_1_1w/include/openssl/asn1.h + ${CMAKE_BINARY_DIR}/openssl-OpenSSL_1_1_1w/include/openssl/asn1_mac.h + ${CMAKE_BINARY_DIR}/openssl-OpenSSL_1_1_1w/include/openssl/asn1err.h + ${CMAKE_BINARY_DIR}/openssl-OpenSSL_1_1_1w/include/openssl/asn1t.h + ${CMAKE_BINARY_DIR}/openssl-OpenSSL_1_1_1w/include/openssl/async.h + ${CMAKE_BINARY_DIR}/openssl-OpenSSL_1_1_1w/include/openssl/asyncerr.h + ${CMAKE_BINARY_DIR}/openssl-OpenSSL_1_1_1w/include/openssl/bio.h + ${CMAKE_BINARY_DIR}/openssl-OpenSSL_1_1_1w/include/openssl/bioerr.h + ${CMAKE_BINARY_DIR}/openssl-OpenSSL_1_1_1w/include/openssl/blowfish.h + ${CMAKE_BINARY_DIR}/openssl-OpenSSL_1_1_1w/include/openssl/bn.h + ${CMAKE_BINARY_DIR}/openssl-OpenSSL_1_1_1w/include/openssl/bnerr.h + ${CMAKE_BINARY_DIR}/openssl-OpenSSL_1_1_1w/include/openssl/buffer.h + ${CMAKE_BINARY_DIR}/openssl-OpenSSL_1_1_1w/include/openssl/buffererr.h + ${CMAKE_BINARY_DIR}/openssl-OpenSSL_1_1_1w/include/openssl/camellia.h + ${CMAKE_BINARY_DIR}/openssl-OpenSSL_1_1_1w/include/openssl/cast.h + ${CMAKE_BINARY_DIR}/openssl-OpenSSL_1_1_1w/include/openssl/cmac.h + ${CMAKE_BINARY_DIR}/openssl-OpenSSL_1_1_1w/include/openssl/cms.h + ${CMAKE_BINARY_DIR}/openssl-OpenSSL_1_1_1w/include/openssl/cmserr.h + ${CMAKE_BINARY_DIR}/openssl-OpenSSL_1_1_1w/include/openssl/comp.h + ${CMAKE_BINARY_DIR}/openssl-OpenSSL_1_1_1w/include/openssl/comperr.h + ${CMAKE_BINARY_DIR}/openssl-OpenSSL_1_1_1w/include/openssl/conf.h + ${CMAKE_BINARY_DIR}/openssl-OpenSSL_1_1_1w/include/openssl/conf_api.h + ${CMAKE_BINARY_DIR}/openssl-OpenSSL_1_1_1w/include/openssl/conferr.h + ${CMAKE_BINARY_DIR}/openssl-OpenSSL_1_1_1w/include/openssl/crypto.h + ${CMAKE_BINARY_DIR}/openssl-OpenSSL_1_1_1w/include/openssl/cryptoerr.h + ${CMAKE_BINARY_DIR}/openssl-OpenSSL_1_1_1w/include/openssl/ct.h + ${CMAKE_BINARY_DIR}/openssl-OpenSSL_1_1_1w/include/openssl/cterr.h + ${CMAKE_BINARY_DIR}/openssl-OpenSSL_1_1_1w/include/openssl/des.h + ${CMAKE_BINARY_DIR}/openssl-OpenSSL_1_1_1w/include/openssl/dh.h + ${CMAKE_BINARY_DIR}/openssl-OpenSSL_1_1_1w/include/openssl/dherr.h + ${CMAKE_BINARY_DIR}/openssl-OpenSSL_1_1_1w/include/openssl/dsa.h + ${CMAKE_BINARY_DIR}/openssl-OpenSSL_1_1_1w/include/openssl/dsaerr.h + ${CMAKE_BINARY_DIR}/openssl-OpenSSL_1_1_1w/include/openssl/dtls1.h + ${CMAKE_BINARY_DIR}/openssl-OpenSSL_1_1_1w/include/openssl/e_os2.h + ${CMAKE_BINARY_DIR}/openssl-OpenSSL_1_1_1w/include/openssl/ebcdic.h + ${CMAKE_BINARY_DIR}/openssl-OpenSSL_1_1_1w/include/openssl/ec.h + ${CMAKE_BINARY_DIR}/openssl-OpenSSL_1_1_1w/include/openssl/ecdh.h + ${CMAKE_BINARY_DIR}/openssl-OpenSSL_1_1_1w/include/openssl/ecdsa.h + ${CMAKE_BINARY_DIR}/openssl-OpenSSL_1_1_1w/include/openssl/ecerr.h + ${CMAKE_BINARY_DIR}/openssl-OpenSSL_1_1_1w/include/openssl/engine.h + ${CMAKE_BINARY_DIR}/openssl-OpenSSL_1_1_1w/include/openssl/engineerr.h + ${CMAKE_BINARY_DIR}/openssl-OpenSSL_1_1_1w/include/openssl/err.h + ${CMAKE_BINARY_DIR}/openssl-OpenSSL_1_1_1w/include/openssl/evp.h + ${CMAKE_BINARY_DIR}/openssl-OpenSSL_1_1_1w/include/openssl/evperr.h + ${CMAKE_BINARY_DIR}/openssl-OpenSSL_1_1_1w/include/openssl/hmac.h + ${CMAKE_BINARY_DIR}/openssl-OpenSSL_1_1_1w/include/openssl/idea.h + ${CMAKE_BINARY_DIR}/openssl-OpenSSL_1_1_1w/include/openssl/kdf.h + ${CMAKE_BINARY_DIR}/openssl-OpenSSL_1_1_1w/include/openssl/kdferr.h + ${CMAKE_BINARY_DIR}/openssl-OpenSSL_1_1_1w/include/openssl/lhash.h + ${CMAKE_BINARY_DIR}/openssl-OpenSSL_1_1_1w/include/openssl/md2.h + ${CMAKE_BINARY_DIR}/openssl-OpenSSL_1_1_1w/include/openssl/md4.h + ${CMAKE_BINARY_DIR}/openssl-OpenSSL_1_1_1w/include/openssl/md5.h + ${CMAKE_BINARY_DIR}/openssl-OpenSSL_1_1_1w/include/openssl/mdc2.h + ${CMAKE_BINARY_DIR}/openssl-OpenSSL_1_1_1w/include/openssl/modes.h + ${CMAKE_BINARY_DIR}/openssl-OpenSSL_1_1_1w/include/openssl/obj_mac.h + ${CMAKE_BINARY_DIR}/openssl-OpenSSL_1_1_1w/include/openssl/objects.h + ${CMAKE_BINARY_DIR}/openssl-OpenSSL_1_1_1w/include/openssl/objectserr.h + ${CMAKE_BINARY_DIR}/openssl-OpenSSL_1_1_1w/include/openssl/ocsp.h + ${CMAKE_BINARY_DIR}/openssl-OpenSSL_1_1_1w/include/openssl/ocsperr.h + ${CMAKE_BINARY_DIR}/openssl-OpenSSL_1_1_1w/include/openssl/opensslconf.h + ${CMAKE_BINARY_DIR}/openssl-OpenSSL_1_1_1w/include/openssl/opensslv.h + ${CMAKE_BINARY_DIR}/openssl-OpenSSL_1_1_1w/include/openssl/ossl_typ.h + ${CMAKE_BINARY_DIR}/openssl-OpenSSL_1_1_1w/include/openssl/pem.h + ${CMAKE_BINARY_DIR}/openssl-OpenSSL_1_1_1w/include/openssl/pem2.h + ${CMAKE_BINARY_DIR}/openssl-OpenSSL_1_1_1w/include/openssl/pemerr.h + ${CMAKE_BINARY_DIR}/openssl-OpenSSL_1_1_1w/include/openssl/pkcs12.h + ${CMAKE_BINARY_DIR}/openssl-OpenSSL_1_1_1w/include/openssl/pkcs12err.h + ${CMAKE_BINARY_DIR}/openssl-OpenSSL_1_1_1w/include/openssl/pkcs7.h + ${CMAKE_BINARY_DIR}/openssl-OpenSSL_1_1_1w/include/openssl/pkcs7err.h + ${CMAKE_BINARY_DIR}/openssl-OpenSSL_1_1_1w/include/openssl/rand.h + ${CMAKE_BINARY_DIR}/openssl-OpenSSL_1_1_1w/include/openssl/rand_drbg.h + ${CMAKE_BINARY_DIR}/openssl-OpenSSL_1_1_1w/include/openssl/randerr.h + ${CMAKE_BINARY_DIR}/openssl-OpenSSL_1_1_1w/include/openssl/rc2.h + ${CMAKE_BINARY_DIR}/openssl-OpenSSL_1_1_1w/include/openssl/rc4.h + ${CMAKE_BINARY_DIR}/openssl-OpenSSL_1_1_1w/include/openssl/rc5.h + ${CMAKE_BINARY_DIR}/openssl-OpenSSL_1_1_1w/include/openssl/ripemd.h + ${CMAKE_BINARY_DIR}/openssl-OpenSSL_1_1_1w/include/openssl/rsa.h + ${CMAKE_BINARY_DIR}/openssl-OpenSSL_1_1_1w/include/openssl/rsaerr.h + ${CMAKE_BINARY_DIR}/openssl-OpenSSL_1_1_1w/include/openssl/safestack.h + ${CMAKE_BINARY_DIR}/openssl-OpenSSL_1_1_1w/include/openssl/seed.h + ${CMAKE_BINARY_DIR}/openssl-OpenSSL_1_1_1w/include/openssl/sha.h + ${CMAKE_BINARY_DIR}/openssl-OpenSSL_1_1_1w/include/openssl/srp.h + ${CMAKE_BINARY_DIR}/openssl-OpenSSL_1_1_1w/include/openssl/srtp.h + ${CMAKE_BINARY_DIR}/openssl-OpenSSL_1_1_1w/include/openssl/ssl.h + ${CMAKE_BINARY_DIR}/openssl-OpenSSL_1_1_1w/include/openssl/ssl2.h + ${CMAKE_BINARY_DIR}/openssl-OpenSSL_1_1_1w/include/openssl/ssl3.h + ${CMAKE_BINARY_DIR}/openssl-OpenSSL_1_1_1w/include/openssl/sslerr.h + ${CMAKE_BINARY_DIR}/openssl-OpenSSL_1_1_1w/include/openssl/stack.h + ${CMAKE_BINARY_DIR}/openssl-OpenSSL_1_1_1w/include/openssl/store.h + ${CMAKE_BINARY_DIR}/openssl-OpenSSL_1_1_1w/include/openssl/storeerr.h + ${CMAKE_BINARY_DIR}/openssl-OpenSSL_1_1_1w/include/openssl/symhacks.h + ${CMAKE_BINARY_DIR}/openssl-OpenSSL_1_1_1w/include/openssl/tls1.h + ${CMAKE_BINARY_DIR}/openssl-OpenSSL_1_1_1w/include/openssl/ts.h + ${CMAKE_BINARY_DIR}/openssl-OpenSSL_1_1_1w/include/openssl/tserr.h + ${CMAKE_BINARY_DIR}/openssl-OpenSSL_1_1_1w/include/openssl/txt_db.h + ${CMAKE_BINARY_DIR}/openssl-OpenSSL_1_1_1w/include/openssl/ui.h + ${CMAKE_BINARY_DIR}/openssl-OpenSSL_1_1_1w/include/openssl/uierr.h + ${CMAKE_BINARY_DIR}/openssl-OpenSSL_1_1_1w/include/openssl/whrlpool.h + ${CMAKE_BINARY_DIR}/openssl-OpenSSL_1_1_1w/include/openssl/x509.h + ${CMAKE_BINARY_DIR}/openssl-OpenSSL_1_1_1w/include/openssl/x509_vfy.h + ${CMAKE_BINARY_DIR}/openssl-OpenSSL_1_1_1w/include/openssl/x509err.h + ${CMAKE_BINARY_DIR}/openssl-OpenSSL_1_1_1w/include/openssl/x509v3.h + ${CMAKE_BINARY_DIR}/openssl-OpenSSL_1_1_1w/include/openssl/x509v3err.h + DESTINATION ${LIBS_PREBUILT_DIR}/include/openssl + ) + file( + COPY + ${CMAKE_BINARY_DIR}/openssl-OpenSSL_1_1_1w/libcrypto.a + ${CMAKE_BINARY_DIR}/openssl-OpenSSL_1_1_1w/libssl.a + DESTINATION ${LIBS_PREBUILT_DIR}/lib/release + ) + file(WRITE ${PREBUILD_TRACKING_DIR}/openssl_installed "${openssl_installed}") +endif (LINUX AND CMAKE_SYSTEM_PROCESSOR MATCHES x86_64 OR DARWIN OR NOT USESYSTEMLIBS) +if (WINDOWS AND NOT USESYSTEMLIBS) target_link_libraries(ll::openssl INTERFACE ${ARCH_PREBUILT_DIRS_RELEASE}/libssl.lib ${ARCH_PREBUILT_DIRS_RELEASE}/libcrypto.lib Crypt32.lib) elseif (LINUX) target_link_libraries(ll::openssl INTERFACE ${ARCH_PREBUILT_DIRS_RELEASE}/libssl.a ${ARCH_PREBUILT_DIRS_RELEASE}/libcrypto.a dl) else() target_link_libraries(ll::openssl INTERFACE ssl crypto) -endif (WINDOWS) +endif (WINDOWS AND NOT USESYSTEMLIBS) +if (NOT (WINDOWS AND USESYSTEMLIBS)) target_include_directories( ll::openssl SYSTEM INTERFACE ${LIBS_PREBUILT_DIR}/include) +endif (NOT (WINDOWS AND USESYSTEMLIBS)) diff --git a/indra/cmake/OpenXR.cmake b/indra/cmake/OpenXR.cmake index 2cc862b927..b37ed50939 100644 --- a/indra/cmake/OpenXR.cmake +++ b/indra/cmake/OpenXR.cmake @@ -8,6 +8,8 @@ add_library( ll::openxr INTERFACE IMPORTED ) if(USE_CONAN ) target_link_libraries( ll::openxr INTERFACE CONAN_PKG::openxr ) return() +elseif (CMAKE_SYSTEM_PROCESSOR MATCHES aarch64) + return() endif() use_prebuilt_binary(openxr) diff --git a/indra/cmake/Prebuilt.cmake b/indra/cmake/Prebuilt.cmake index 634cc15c21..751e83051f 100644 --- a/indra/cmake/Prebuilt.cmake +++ b/indra/cmake/Prebuilt.cmake @@ -40,6 +40,38 @@ macro (use_prebuilt_binary _binary) --install-dir=${AUTOBUILD_INSTALL_DIR} ${_binary} ") endif(DEBUG_PREBUILT) + if(USESYSTEMLIBS) + execute_process(COMMAND xmllint + --xpath + "//map/map/map/map/map/map/string[contains(text(),'${_binary}')][contains(text(),'common')]/text()" autobuild.xml + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/.. + OUTPUT_VARIABLE package_url + OUTPUT_STRIP_TRAILING_WHITESPACE + ) + if ("${package_url}" STREQUAL "") + string(TOLOWER ${CMAKE_SYSTEM_NAME} system_name) + if (${system_name} MATCHES freebsd) + set(system_name "linux") + endif (${system_name} MATCHES freebsd) + execute_process(COMMAND xmllint + --xpath + "//map/map/map/map/map/map/string[contains(text(),'${_binary}')][contains(text(),'${system_name}')]/text()" autobuild.xml + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/.. + OUTPUT_VARIABLE package_url + OUTPUT_STRIP_TRAILING_WHITESPACE + ) + endif ("${package_url}" STREQUAL "") + string(REGEX REPLACE "^https?://(megapahit.net/downloads|github.com/secondlife|automated-builds-secondlife-com.s3.amazonaws.com/ct2).*/" "" package_name ${package_url}) + file(DOWNLOAD + ${package_url} + ${CMAKE_BINARY_DIR}/${package_name} + ) + file(ARCHIVE_EXTRACT + INPUT ${CMAKE_BINARY_DIR}/${package_name} + DESTINATION ${AUTOBUILD_INSTALL_DIR} + ) + set(${_binary}_installed 0) + else(USESYSTEMLIBS) execute_process(COMMAND "${AUTOBUILD_EXECUTABLE}" install --install-dir=${AUTOBUILD_INSTALL_DIR} @@ -47,6 +79,7 @@ macro (use_prebuilt_binary _binary) WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}" RESULT_VARIABLE ${_binary}_installed ) + endif(USESYSTEMLIBS) file(WRITE ${PREBUILD_TRACKING_DIR}/${_binary}_installed "${${_binary}_installed}") endif(${PREBUILD_TRACKING_DIR}/sentinel_installed IS_NEWER_THAN ${PREBUILD_TRACKING_DIR}/${_binary}_installed OR NOT ${${_binary}_installed} EQUAL 0) @@ -67,6 +100,33 @@ macro ( use_system_binary package ) endif() endforeach() return() + elseif( NOT USE_AUTOBUILD_3P ) + include(FindPkgConfig) + pkg_check_modules(${package} ${package}) + if( ${package}_FOUND ) + target_link_directories( ll::${package} INTERFACE ${${package}_LIBRARY_DIRS} ) + else() + pkg_check_modules(${package} lib${package}) + if( ${package}_FOUND ) + target_link_directories( ll::${package} INTERFACE ${${package}_LIBRARY_DIRS} ) + else() + find_package( ${package} REQUIRED ) + endif() + endif() + target_include_directories( ll::${package} SYSTEM INTERFACE ${${package}_INCLUDE_DIRS} ) + target_link_libraries( ll::${package} INTERFACE ${${package}_LIBRARIES} ) + return() endif() endmacro() +find_package(Patch) + +# Download the third party software archive and patch it. +macro(prepare_thirdparty url filename dirname patch hash) + file(DOWNLOAD ${url} ${filename}) + file(ARCHIVE_EXTRACT INPUT ${filename} + DESTINATION ${CMAKE_BINARY_DIR}) + execute_process(COMMAND ${Patch_EXECUTABLE} "-p1" "-i" + ${CMAKE_SOURCE_DIR}/../patches/${patch} + WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/${dirname}) +endmacro() diff --git a/indra/cmake/UI.cmake b/indra/cmake/UI.cmake index 8f135676d6..a3423bb895 100644 --- a/indra/cmake/UI.cmake +++ b/indra/cmake/UI.cmake @@ -1,36 +1,36 @@ # -*- cmake -*- include(Prebuilt) include(FreeType) +include(GLIB) add_library( ll::uilibraries INTERFACE IMPORTED ) -if (LINUX) - target_compile_definitions(ll::uilibraries INTERFACE LL_GTK=1 LL_X11=1 ) +if (LINUX OR CMAKE_SYSTEM_NAME MATCHES "FreeBSD") + if (NOT USESYSTEMLIBS) + use_prebuilt_binary(fltk) + endif () + target_compile_definitions(ll::uilibraries INTERFACE LL_FLTK=1 LL_X11=1 ) if( USE_CONAN ) - target_link_libraries( ll::uilibraries INTERFACE CONAN_PKG::gtk ) return() endif() - use_prebuilt_binary(gtk-atk-pango-glib) target_link_libraries( ll::uilibraries INTERFACE - atk-1.0 - gdk-x11-2.0 - gdk_pixbuf-2.0 - Xinerama - glib-2.0 - gmodule-2.0 - gobject-2.0 - gthread-2.0 - gtk-x11-2.0 - pango-1.0 - pangoft2-1.0 - pangox-1.0 - pangoxft-1.0 + fltk + Xrender + Xcursor + Xfixes + Xext + Xft Xinerama + ll::fontconfig ll::freetype - ) -endif (LINUX) + ll::SDL + ll::glib + ll::gio + ) + +endif (LINUX OR CMAKE_SYSTEM_NAME MATCHES "FreeBSD") if( WINDOWS ) target_link_libraries( ll::uilibraries INTERFACE opengl32 @@ -48,7 +48,8 @@ if( WINDOWS ) ) endif() +if (NOT USESYSTEMLIBS) target_include_directories( ll::uilibraries SYSTEM INTERFACE ${LIBS_PREBUILT_DIR}/include ) - +endif () diff --git a/indra/cmake/UnixInstall.cmake b/indra/cmake/UnixInstall.cmake index 139be0a008..1fd17a0142 100644 --- a/indra/cmake/UnixInstall.cmake +++ b/indra/cmake/UnixInstall.cmake @@ -6,14 +6,21 @@ set(INSTALL OFF CACHE BOOL "Generate install target.") if (INSTALL) + if (CMAKE_SYSTEM_NAME MATCHES FreeBSD) + set(INSTALL_PREFIX ${CMAKE_INSTALL_PREFIX} CACHE PATH + "Top-level installation directory.") + else (CMAKE_SYSTEM_NAME MATCHES FreeBSD) set(INSTALL_PREFIX /usr CACHE PATH "Top-level installation directory.") + endif (CMAKE_SYSTEM_NAME MATCHES FreeBSD) - if (EXISTS /lib64) - set(_LIB lib64) - else (EXISTS /lib64) + if (${LINUX_DISTRO} MATCHES debian OR (${LINUX_DISTRO} MATCHES ubuntu)) + set(_LIB lib/${ARCH}-linux-gnu) + elseif (${LINUX_DISTRO} MATCHES fedora OR (${LINUX_DISTRO} MATCHES opensuse-tumbleweed) OR (${LINUX_DISTRO} MATCHES gentoo)) + set(_LIB lib${ADDRESS_SIZE}) + else () set(_LIB lib) - endif (EXISTS /lib64) + endif () set(INSTALL_LIBRARY_DIR ${INSTALL_PREFIX}/${_LIB} CACHE PATH "Installation directory for read-only shared files.") @@ -25,7 +32,16 @@ if (INSTALL) CACHE PATH "Installation directory for binaries.") - set(APP_SHARE_DIR ${INSTALL_SHARE_DIR}/secondlife-${viewer_VERSION} + set(APP_SHARE_DIR ${INSTALL_SHARE_DIR}/${VIEWER_BINARY_NAME} CACHE PATH "Installation directory for read-only data files.") + if (${LINUX_DISTRO} MATCHES arch) + set(APP_LIBEXEC_DIR ${INSTALL_PREFIX}/lib/${VIEWER_BINARY_NAME} + CACHE PATH + "Installation directory for non-manual executables.") + else (${LINUX_DISTRO} MATCHES arch) + set(APP_LIBEXEC_DIR ${INSTALL_PREFIX}/libexec/${VIEWER_BINARY_NAME} + CACHE PATH + "Installation directory for non-manual executables.") + endif (${LINUX_DISTRO} MATCHES arch) endif (INSTALL) diff --git a/indra/cmake/Variables.cmake b/indra/cmake/Variables.cmake index 5b3aeb8b7f..c287f135fe 100644 --- a/indra/cmake/Variables.cmake +++ b/indra/cmake/Variables.cmake @@ -101,12 +101,15 @@ else (ADDRESS_SIZE EQUAL 32) endif() endif (ADDRESS_SIZE EQUAL 32) +cmake_host_system_information(RESULT MAKE_JOBS QUERY NUMBER_OF_LOGICAL_CORES) + if (${CMAKE_SYSTEM_NAME} MATCHES "Windows") set(WINDOWS ON BOOL FORCE) endif (${CMAKE_SYSTEM_NAME} MATCHES "Windows") if (${CMAKE_SYSTEM_NAME} MATCHES "Linux") set(LINUX ON BOOl FORCE) + cmake_host_system_information(RESULT LINUX_DISTRO QUERY DISTRIB_ID) if (ADDRESS_SIZE EQUAL 32) set(DEB_ARCHITECTURE i386) @@ -117,7 +120,7 @@ if (${CMAKE_SYSTEM_NAME} MATCHES "Linux") set(FIND_LIBRARY_USE_LIB64_PATHS ON) endif (ADDRESS_SIZE EQUAL 32) - execute_process(COMMAND dpkg-architecture -a${DEB_ARCHITECTURE} -qDEB_HOST_MULTIARCH + execute_process(COMMAND dpkg-architecture -a${DEB_ARCHITECTURE} -qDEB_HOST_MULTIARCH RESULT_VARIABLE DPKG_RESULT OUTPUT_VARIABLE DPKG_ARCH OUTPUT_STRIP_TRAILING_WHITESPACE ERROR_QUIET) @@ -127,8 +130,6 @@ if (${CMAKE_SYSTEM_NAME} MATCHES "Linux") set(CMAKE_SYSTEM_LIBRARY_PATH /usr/lib/${DPKG_ARCH} /usr/local/lib/${DPKG_ARCH} ${CMAKE_SYSTEM_LIBRARY_PATH}) endif (DPKG_RESULT EQUAL 0) - include(ConfigurePkgConfig) - if (INSTALL_PROPRIETARY) # Only turn on headless if we can find osmesa libraries. include(FindPkgConfig) @@ -204,7 +205,7 @@ if (${CMAKE_SYSTEM_NAME} MATCHES "Darwin") set(CMAKE_XCODE_ATTRIBUTE_CODE_SIGN_ENTITLEMENTS "") set(CMAKE_XCODE_ATTRIBUTE_DISABLE_MANUAL_TARGET_ORDER_BUILD_WARNING YES) set(CMAKE_XCODE_ATTRIBUTE_GCC_WARN_64_TO_32_BIT_CONVERSION NO) - set(CMAKE_OSX_ARCHITECTURES "${ARCH}") + #set(CMAKE_OSX_ARCHITECTURES "${ARCH}") string(REPLACE "i686" "i386" CMAKE_OSX_ARCHITECTURES "${CMAKE_OSX_ARCHITECTURES}") string(REPLACE "AMD64" "x86_64" CMAKE_OSX_ARCHITECTURES "${CMAKE_OSX_ARCHITECTURES}") endif (${CMAKE_SYSTEM_NAME} MATCHES "Darwin") diff --git a/indra/cmake/ViewerMiscLibs.cmake b/indra/cmake/ViewerMiscLibs.cmake index cae68fbc11..13f5ebf862 100644 --- a/indra/cmake/ViewerMiscLibs.cmake +++ b/indra/cmake/ViewerMiscLibs.cmake @@ -1,23 +1,23 @@ # -*- cmake -*- include(Prebuilt) -if (LINUX) - #use_prebuilt_binary(libuuid) +if (NOT (WINDOWS OR DARWIN)) add_library( ll::fontconfig INTERFACE IMPORTED ) - if( NOT USE_CONAN ) - use_prebuilt_binary(fontconfig) - else() - target_link_libraries( ll::fontconfig INTERFACE CONAN_PKG::fontconfig ) - endif() -endif (LINUX) + find_package(Fontconfig REQUIRED) + target_link_libraries( ll::fontconfig INTERFACE Fontconfig::Fontconfig ) +endif (NOT (WINDOWS OR DARWIN)) -if( NOT USE_CONAN ) +if( USE_AUTOBUILD_3P ) use_prebuilt_binary(libhunspell) endif() +if (NOT USESYSTEMLIBS) use_prebuilt_binary(slvoice) +endif (NOT USESYSTEMLIBS) +if ((${LINUX_DISTRO} MATCHES debian OR WINDOWS OR DARWIN) OR NOT USESYSTEMLIBS) use_prebuilt_binary(nanosvg) +endif ((${LINUX_DISTRO} MATCHES debian OR WINDOWS OR DARWIN) OR NOT USESYSTEMLIBS) use_prebuilt_binary(viewer-fonts) use_prebuilt_binary(emoji_shortcodes) diff --git a/indra/cmake/VulkanGltf.cmake b/indra/cmake/VulkanGltf.cmake index 94541d5307..d7083a33c9 100644 --- a/indra/cmake/VulkanGltf.cmake +++ b/indra/cmake/VulkanGltf.cmake @@ -1,5 +1,7 @@ # -*- cmake -*- include(Prebuilt) +if (NOT USESYSTEMLIBS) use_prebuilt_binary(vulkan_gltf) +endif () diff --git a/indra/cmake/WebRTC.cmake b/indra/cmake/WebRTC.cmake index 230522a40a..a5c821f32a 100644 --- a/indra/cmake/WebRTC.cmake +++ b/indra/cmake/WebRTC.cmake @@ -6,7 +6,78 @@ include_guard() add_library( ll::webrtc INTERFACE IMPORTED ) target_include_directories( ll::webrtc SYSTEM INTERFACE "${LIBS_PREBUILT_DIR}/include/webrtc" "${LIBS_PREBUILT_DIR}/include/webrtc/third_party/abseil-cpp") +if (${LINUX_DISTRO} MATCHES debian OR CMAKE_OSX_ARCHITECTURES MATCHES x86_64) use_prebuilt_binary(webrtc) +elseif (NOT (WINDOWS OR CMAKE_SYSTEM_NAME MATCHES FreeBSD)) + target_compile_definitions(ll::webrtc INTERFACE CM_WEBRTC=1) + if (${PREBUILD_TRACKING_DIR}/sentinel_installed IS_NEWER_THAN ${PREBUILD_TRACKING_DIR}/webrtc_installed OR NOT ${webrtc_installed} EQUAL 0) + if (DARWIN) + set(WEBRTC_PLATFORM macos-arm64) + elseif (CMAKE_SYSTEM_PROCESSOR MATCHES aarch64) + set(WEBRTC_PLATFORM linux-arm64) + else () + set(WEBRTC_PLATFORM linux-x64) + endif (DARWIN) + if (NOT EXISTS ${CMAKE_BINARY_DIR}/libwebrtc-${WEBRTC_PLATFORM}.tar.xz) + file(DOWNLOAD + https://github.com/crow-misia/libwebrtc-bin/releases/download/114.5735.6.1/libwebrtc-${WEBRTC_PLATFORM}.tar.xz + ${CMAKE_BINARY_DIR}/libwebrtc-${WEBRTC_PLATFORM}.tar.xz + SHOW_PROGRESS + ) + endif (NOT EXISTS ${CMAKE_BINARY_DIR}/libwebrtc-${WEBRTC_PLATFORM}.tar.xz) + file(ARCHIVE_EXTRACT + INPUT ${CMAKE_BINARY_DIR}/libwebrtc-${WEBRTC_PLATFORM}.tar.xz + DESTINATION ${LIBS_PREBUILT_DIR} + ) + file(REMOVE_RECURSE ${LIBS_PREBUILT_DIR}/include/webrtc) + file(MAKE_DIRECTORY ${LIBS_PREBUILT_DIR}/include/webrtc) + foreach(directory + api + audio + base + build + buildtools + call + common_audio + common_video + examples + logging + media + modules + net + p2p + pc + rtc_base + rtc_tools + sdk + stats + system_wrappers + test + testing + third_party + tools + video + ) + file(RENAME + ${LIBS_PREBUILT_DIR}/include/${directory} + ${LIBS_PREBUILT_DIR}/include/webrtc/${directory} + ) + endforeach() + file(RENAME + ${LIBS_PREBUILT_DIR}/lib/libwebrtc.a + ${LIBS_PREBUILT_DIR}/lib/release/libwebrtc.a + ) + if (CMAKE_OSX_ARCHITECTURES MATCHES arm64) + file(REMOVE_RECURSE ${LIBS_PREBUILT_DIR}/lib/release/WebRTC.framework) + file(RENAME + ${LIBS_PREBUILT_DIR}/Frameworks/WebRTC.xcframework/${WEBRTC_PLATFORM}/WebRTC.framework + ${LIBS_PREBUILT_DIR}/lib/release/WebRTC.framework + ) + file(REMOVE_RECURSE ${LIBS_PREBUILT_DIR}/Frameworks) + endif (CMAKE_OSX_ARCHITECTURES MATCHES arm64) + file(WRITE ${PREBUILD_TRACKING_DIR}/webrtc_installed "0") + endif (${PREBUILD_TRACKING_DIR}/sentinel_installed IS_NEWER_THAN ${PREBUILD_TRACKING_DIR}/webrtc_installed OR NOT ${webrtc_installed} EQUAL 0) +endif (${LINUX_DISTRO} MATCHES debian OR CMAKE_OSX_ARCHITECTURES MATCHES x86_64) if (WINDOWS) target_link_libraries( ll::webrtc INTERFACE webrtc.lib ) diff --git a/indra/cmake/ZLIBNG.cmake b/indra/cmake/ZLIBNG.cmake index d7b920da26..5aa54b0152 100644 --- a/indra/cmake/ZLIBNG.cmake +++ b/indra/cmake/ZLIBNG.cmake @@ -8,6 +8,12 @@ add_library( ll::zlib-ng INTERFACE IMPORTED ) if(USE_CONAN ) target_link_libraries( ll::zlib-ng INTERFACE CONAN_PKG::zlib ) return() +elseif(NOT USE_AUTOBUILD_3P) + pkg_check_modules(Zlib REQUIRED zlib) + target_include_directories( ll::zlib-ng SYSTEM INTERFACE ${Zlib_INCLUDE_DIRS}) + target_link_directories( ll::zlib-ng INTERFACE ${Zlib_LIBRARY_DIRS} ) + target_link_libraries( ll::zlib-ng INTERFACE ${Zlib_LIBRARIES}) + return() endif() use_prebuilt_binary(zlib-ng) diff --git a/indra/cmake/xxHash.cmake b/indra/cmake/xxHash.cmake index a7c1cba62c..2dcab005ba 100644 --- a/indra/cmake/xxHash.cmake +++ b/indra/cmake/xxHash.cmake @@ -5,4 +5,11 @@ endif (XXHASH_CMAKE_INCLUDED) set (XXHASH_CMAKE_INCLUDED TRUE) include(Prebuilt) + +if (NOT (USE_AUTOBUILD_3P OR USE_CONAN)) + include(FindPkgConfig) + pkg_check_modules(Xxhash REQUIRED libxxhash) + return () +endif () + use_prebuilt_binary(xxhash) diff --git a/indra/linux_crash_logger/llcrashloggerlinux.cpp b/indra/linux_crash_logger/llcrashloggerlinux.cpp index 9b40de741e..7992f59b36 100644 --- a/indra/linux_crash_logger/llcrashloggerlinux.cpp +++ b/indra/linux_crash_logger/llcrashloggerlinux.cpp @@ -38,9 +38,6 @@ #include "lldir.h" #include "llsdserialize.h" -#if LL_GTK -# include "gtk/gtk.h" -#endif // LL_GTK #define MAX_LOADSTRING 100 @@ -54,52 +51,9 @@ static const char dialog_text[] = static const char dialog_title[] = "Second Life Crash Logger"; -#if LL_GTK -static void response_callback (GtkDialog *dialog, - gint arg1, - gpointer user_data) -{ - gint *response = (gint*)user_data; - *response = arg1; - gtk_widget_destroy(GTK_WIDGET(dialog)); - gtk_main_quit(); -} -#endif // LL_GTK - static BOOL do_ask_dialog(void) { -#if LL_GTK - gtk_disable_setlocale(); - if (!gtk_init_check(NULL, NULL)) { - LL_INFOS() << "Could not initialize GTK for 'ask to send crash report' dialog; not sending report." << LL_ENDL; - return FALSE; - } - - GtkWidget *win = NULL; - GtkDialogFlags flags = GTK_DIALOG_MODAL; - GtkMessageType messagetype = GTK_MESSAGE_QUESTION; - GtkButtonsType buttons = GTK_BUTTONS_YES_NO; - gint response = GTK_RESPONSE_NONE; - - win = gtk_message_dialog_new(NULL, - flags, messagetype, buttons, - "%s", dialog_text); - gtk_window_set_type_hint(GTK_WINDOW(win), - GDK_WINDOW_TYPE_HINT_DIALOG); - gtk_window_set_title(GTK_WINDOW(win), dialog_title); - g_signal_connect (win, - "response", - G_CALLBACK (response_callback), - &response); - gtk_widget_show_all (win); - gtk_main(); - - return (GTK_RESPONSE_OK == response || - GTK_RESPONSE_YES == response || - GTK_RESPONSE_APPLY == response); -#else - return FALSE; -#endif // LL_GTK + // Ask to send crash report. Yes/No dialog. } LLCrashLoggerLinux::LLCrashLoggerLinux(void) diff --git a/indra/llappearance/CMakeLists.txt b/indra/llappearance/CMakeLists.txt index c3be8bc78e..f3f822f61c 100644 --- a/indra/llappearance/CMakeLists.txt +++ b/indra/llappearance/CMakeLists.txt @@ -84,3 +84,5 @@ if (BUILD_HEADLESS) llcommon ) endif (BUILD_HEADLESS) + +include(LibraryInstall) diff --git a/indra/llappearance/llavatarappearance.cpp b/indra/llappearance/llavatarappearance.cpp index 95d55c835f..3d66809ed6 100644 --- a/indra/llappearance/llavatarappearance.cpp +++ b/indra/llappearance/llavatarappearance.cpp @@ -799,7 +799,6 @@ void LLAvatarAppearance::buildCharacter() bool status = loadAvatar(); stop_glerror(); -// gPrintMessagesThisFrame = true; LL_DEBUGS() << "Avatar load took " << timer.getElapsedTimeF32() << " seconds." << LL_ENDL; if (!status) diff --git a/indra/llappearance/llavatarappearancedefines.cpp b/indra/llappearance/llavatarappearancedefines.cpp index 5f98f2c8c1..47798844bc 100644 --- a/indra/llappearance/llavatarappearancedefines.cpp +++ b/indra/llappearance/llavatarappearancedefines.cpp @@ -300,7 +300,8 @@ EBakedTextureIndex LLAvatarAppearanceDictionary::findBakedByImageName(std::strin LLWearableType::EType LLAvatarAppearanceDictionary::getTEWearableType(ETextureIndex index ) const { - return getTexture(index)->mWearableType; + auto* tex = getTexture(index); + return tex ? tex->mWearableType : LLWearableType::WT_INVALID; } // static diff --git a/indra/llappearance/llpolymesh.cpp b/indra/llappearance/llpolymesh.cpp index 97f9ca68b6..719381b4fc 100644 --- a/indra/llappearance/llpolymesh.cpp +++ b/indra/llappearance/llpolymesh.cpp @@ -981,7 +981,7 @@ void LLPolyMesh::initializeForMorph() LLVector4a::memcpyNonAliased16((F32*) mScaledNormals, (F32*) mSharedData->mBaseNormals, sizeof(LLVector4a) * mSharedData->mNumVertices); LLVector4a::memcpyNonAliased16((F32*) mBinormals, (F32*) mSharedData->mBaseNormals, sizeof(LLVector4a) * mSharedData->mNumVertices); LLVector4a::memcpyNonAliased16((F32*) mScaledBinormals, (F32*) mSharedData->mBaseNormals, sizeof(LLVector4a) * mSharedData->mNumVertices); - LLVector4a::memcpyNonAliased16((F32*) mTexCoords, (F32*) mSharedData->mTexCoords, sizeof(LLVector2) * (mSharedData->mNumVertices + mSharedData->mNumVertices%2)); + memcpy((F32*) mTexCoords, (F32*) mSharedData->mTexCoords, sizeof(LLVector2) * (mSharedData->mNumVertices)); // allocated in LLPolyMeshSharedData::allocateVertexData for (S32 i = 0; i < mSharedData->mNumVertices; ++i) { diff --git a/indra/llappearance/lltexlayer.cpp b/indra/llappearance/lltexlayer.cpp index aa48a2d621..e368ace35e 100644 --- a/indra/llappearance/lltexlayer.cpp +++ b/indra/llappearance/lltexlayer.cpp @@ -1443,7 +1443,9 @@ void LLTexLayer::renderMorphMasks(S32 x, S32 y, S32 width, S32 height, const LLC gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, 0); } +#if GL_VERSION_1_1 glGetTexImage(LLTexUnit::getInternalType(LLTexUnit::TT_TEXTURE), 0, GL_RGBA, GL_UNSIGNED_BYTE, temp); +#endif U8* alpha_cursor = alpha_data; U8* pixel = temp; diff --git a/indra/llappearance/llwearable.cpp b/indra/llappearance/llwearable.cpp index a7e5292fed..4acb0ef3d4 100644 --- a/indra/llappearance/llwearable.cpp +++ b/indra/llappearance/llwearable.cpp @@ -645,27 +645,28 @@ void LLWearable::addVisualParam(LLVisualParam *param) void LLWearable::setVisualParamWeight(S32 param_index, F32 value) { - if( is_in_map(mVisualParamIndexMap, param_index ) ) + visual_param_index_map_t::iterator found = mVisualParamIndexMap.find(param_index); + if(found != mVisualParamIndexMap.end()) { - LLVisualParam *wearable_param = mVisualParamIndexMap[param_index]; + LLVisualParam *wearable_param = found->second; wearable_param->setWeight(value); } else { - LL_ERRS() << "LLWearable::setVisualParam passed invalid parameter index: " << param_index << " for wearable type: " << this->getName() << LL_ENDL; + LL_WARNS() << "LLWearable::setVisualParam passed invalid parameter index: " << param_index << " for wearable type: " << this->getName() << LL_ENDL; } } F32 LLWearable::getVisualParamWeight(S32 param_index) const { - if( is_in_map(mVisualParamIndexMap, param_index ) ) + visual_param_index_map_t::const_iterator found = mVisualParamIndexMap.find(param_index); + if(found != mVisualParamIndexMap.end()) { - const LLVisualParam *wearable_param = mVisualParamIndexMap.find(param_index)->second; - return wearable_param->getWeight(); + return found->second->getWeight(); } else { - LL_WARNS() << "LLWerable::getVisualParam passed invalid parameter index: " << param_index << " for wearable type: " << this->getName() << LL_ENDL; + LL_WARNS() << "LLWearable::getVisualParam passed invalid parameter index: " << param_index << " for wearable type: " << this->getName() << LL_ENDL; } return (F32)-1.0; } @@ -726,7 +727,7 @@ void LLWearable::writeToAvatar(LLAvatarAppearance* avatarp) if (!avatarp) return; // Pull params - for( LLVisualParam* param = avatarp->getFirstVisualParam(); param; param = avatarp->getNextVisualParam() ) + for( const LLVisualParam* param = avatarp->getFirstVisualParam(); param; param = avatarp->getNextVisualParam() ) { // cross-wearable parameters are not authoritative, as they are driven by a different wearable. So don't copy the values to the // avatar object if cross wearable. Cross wearable params get their values from the avatar, they shouldn't write the other way. diff --git a/indra/llaudio/CMakeLists.txt b/indra/llaudio/CMakeLists.txt index 9278d3c488..f36da83c69 100644 --- a/indra/llaudio/CMakeLists.txt +++ b/indra/llaudio/CMakeLists.txt @@ -4,6 +4,7 @@ project(llaudio) include(00-Common) include(LLAudio) +include(FMODSTUDIO) include(OPENAL) include(LLCommon) @@ -24,6 +25,20 @@ set(llaudio_HEADER_FILES llwindgen.h ) +if (TARGET ll::fmodstudio) + list(APPEND llaudio_SOURCE_FILES + llaudioengine_fmodstudio.cpp + lllistener_fmodstudio.cpp + llstreamingaudio_fmodstudio.cpp + ) + + list(APPEND llaudio_HEADER_FILES + llaudioengine_fmodstudio.h + lllistener_fmodstudio.h + llstreamingaudio_fmodstudio.h + ) +endif () + if (TARGET ll::openal) list(APPEND llaudio_SOURCE_FILES llaudioengine_openal.cpp @@ -54,3 +69,5 @@ endif() if( TARGET ll::fmodstudio ) target_link_libraries( llaudio ll::fmodstudio ) endif() + +include(LibraryInstall) diff --git a/indra/llaudio/llaudioengine_fmodstudio.cpp b/indra/llaudio/llaudioengine_fmodstudio.cpp new file mode 100644 index 0000000000..b4e8407083 --- /dev/null +++ b/indra/llaudio/llaudioengine_fmodstudio.cpp @@ -0,0 +1,756 @@ +/** + * @file audioengine_fmodstudio.cpp + * @brief Implementation of LLAudioEngine class abstracting the audio + * support as a FMODSTUDIO implementation + * + * $LicenseInfo:firstyear=2020&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2020, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#include "linden_common.h" + +#include "llstreamingaudio.h" +#include "llstreamingaudio_fmodstudio.h" + +#include "llaudioengine_fmodstudio.h" +#include "lllistener_fmodstudio.h" + +#include "llerror.h" +#include "llmath.h" +#include "llrand.h" + +#include "fmodstudio/fmod.hpp" +#include "fmodstudio/fmod_errors.h" +#include "lldir.h" +#include "llapr.h" + +#include "sound_ids.h" + +FMOD_RESULT F_CALLBACK windCallback(FMOD_DSP_STATE *dsp_state, float *inbuffer, float *outbuffer, unsigned int length, int inchannels, int *outchannels); + +FMOD::ChannelGroup *LLAudioEngine_FMODSTUDIO::mChannelGroups[LLAudioEngine::AUDIO_TYPE_COUNT] = {0}; + +LLAudioEngine_FMODSTUDIO::LLAudioEngine_FMODSTUDIO(bool enable_profiler) +: mInited(false), + mWindGen(NULL), + mWindDSP(NULL), + mSystem(NULL), + mEnableProfiler(enable_profiler), + mWindDSPDesc(NULL) +{ +} + + +LLAudioEngine_FMODSTUDIO::~LLAudioEngine_FMODSTUDIO() +{ + // mWindDSPDesc, mWindGen and mWindDSP get cleaned up on cleanupWind in LLAudioEngine::shutdown() + // mSystem gets cleaned up at shutdown() +} + + +static inline bool Check_FMOD_Error(FMOD_RESULT result, const char *string) +{ + if (result == FMOD_OK) + return false; + LL_DEBUGS("FMOD") << string << " Error: " << FMOD_ErrorString(result) << LL_ENDL; + return true; +} + +bool LLAudioEngine_FMODSTUDIO::init(void* userdata, const std::string &app_title) +{ + U32 version; + FMOD_RESULT result; + + LL_DEBUGS("AppInit") << "LLAudioEngine_FMODSTUDIO::init() initializing FMOD" << LL_ENDL; + + result = FMOD::System_Create(&mSystem); + if (Check_FMOD_Error(result, "FMOD::System_Create")) + return false; + + //will call LLAudioEngine_FMODSTUDIO::allocateListener, which needs a valid mSystem pointer. + LLAudioEngine::init(userdata, app_title); + + result = mSystem->getVersion(&version); + Check_FMOD_Error(result, "FMOD::System::getVersion"); + + if (version < FMOD_VERSION) + { + LL_WARNS("AppInit") << "FMOD Studio version mismatch, actual: " << version + << " expected:" << FMOD_VERSION << LL_ENDL; + } + + // In this case, all sounds, PLUS wind and stream will be software. + result = mSystem->setSoftwareChannels(LL_MAX_AUDIO_CHANNELS + 2); + Check_FMOD_Error(result, "FMOD::System::setSoftwareChannels"); + + FMOD_ADVANCEDSETTINGS settings; + memset(&settings, 0, sizeof(settings)); + settings.cbSize = sizeof(FMOD_ADVANCEDSETTINGS); + settings.resamplerMethod = FMOD_DSP_RESAMPLER_LINEAR; + + result = mSystem->setAdvancedSettings(&settings); + Check_FMOD_Error(result, "FMOD::System::setAdvancedSettings"); + + // FMOD_INIT_THREAD_UNSAFE Disables thread safety for API calls. + // Only use this if FMOD is being called from a single thread, and if Studio API is not being used. + U32 fmod_flags = FMOD_INIT_NORMAL | FMOD_INIT_3D_RIGHTHANDED | FMOD_INIT_THREAD_UNSAFE; + if (mEnableProfiler) + { + fmod_flags |= FMOD_INIT_PROFILE_ENABLE; + } + +#if LL_LINUX + bool audio_ok = false; + + if (!audio_ok) + { + const char* env_string = getenv("LL_BAD_FMOD_PULSEAUDIO"); + if (NULL == env_string) + { + LL_DEBUGS("AppInit") << "Trying PulseAudio audio output..." << LL_ENDL; + if (mSystem->setOutput(FMOD_OUTPUTTYPE_PULSEAUDIO) == FMOD_OK && + (result = mSystem->init(LL_MAX_AUDIO_CHANNELS + 2, fmod_flags, const_cast<char*>(app_title.c_str()))) == FMOD_OK) + { + LL_DEBUGS("AppInit") << "PulseAudio output initialized OKAY" << LL_ENDL; + audio_ok = true; + } + else + { + Check_FMOD_Error(result, "PulseAudio audio output FAILED to initialize"); + } + } + else + { + LL_DEBUGS("AppInit") << "PulseAudio audio output SKIPPED" << LL_ENDL; + } + } + if (!audio_ok) + { + const char* env_string = getenv("LL_BAD_FMOD_ALSA"); + if (NULL == env_string) + { + LL_DEBUGS("AppInit") << "Trying ALSA audio output..." << LL_ENDL; + if (mSystem->setOutput(FMOD_OUTPUTTYPE_ALSA) == FMOD_OK && + (result = mSystem->init(LL_MAX_AUDIO_CHANNELS + 2, fmod_flags, 0)) == FMOD_OK) + { + LL_DEBUGS("AppInit") << "ALSA audio output initialized OKAY" << LL_ENDL; + audio_ok = true; + } + else + { + Check_FMOD_Error(result, "ALSA audio output FAILED to initialize"); + } + } + else + { + LL_DEBUGS("AppInit") << "ALSA audio output SKIPPED" << LL_ENDL; + } + } + if (!audio_ok) + { + LL_WARNS("AppInit") << "Overall audio init failure." << LL_ENDL; + return false; + } + + // We're interested in logging which output method we + // ended up with, for QA purposes. + FMOD_OUTPUTTYPE output_type; + mSystem->getOutput(&output_type); + switch (output_type) + { + case FMOD_OUTPUTTYPE_NOSOUND: + LL_INFOS("AppInit") << "Audio output: NoSound" << LL_ENDL; break; + case FMOD_OUTPUTTYPE_PULSEAUDIO: + LL_INFOS("AppInit") << "Audio output: PulseAudio" << LL_ENDL; break; + case FMOD_OUTPUTTYPE_ALSA: + LL_INFOS("AppInit") << "Audio output: ALSA" << LL_ENDL; break; + default: + LL_INFOS("AppInit") << "Audio output: Unknown!" << LL_ENDL; break; + }; +#else // LL_LINUX + + // initialize the FMOD engine + // number of channel in this case looks to be identiacal to number of max simultaneously + // playing objects and we can set practically any number + result = mSystem->init(LL_MAX_AUDIO_CHANNELS + 2, fmod_flags, 0); + if (Check_FMOD_Error(result, "Error initializing FMOD Studio with default settins, retrying with other format")) + { + result = mSystem->setSoftwareFormat(44100, FMOD_SPEAKERMODE_STEREO, 0/*- ignore*/); + if (Check_FMOD_Error(result, "Error setting sotware format. Can't init.")) + { + return false; + } + result = mSystem->init(LL_MAX_AUDIO_CHANNELS + 2, fmod_flags, 0); + } + if (Check_FMOD_Error(result, "Error initializing FMOD Studio")) + { + // If it fails here and (result == FMOD_ERR_OUTPUT_CREATEBUFFER), + // we can retry with other settings + return false; + } +#endif + + LL_INFOS("AppInit") << "LLAudioEngine_FMODSTUDIO::init() FMOD Studio initialized correctly" << LL_ENDL; + + int r_numbuffers, r_samplerate, r_channels; + unsigned int r_bufferlength; + char r_name[512]; + int latency = 100; + mSystem->getDSPBufferSize(&r_bufferlength, &r_numbuffers); + LL_INFOS("AppInit") << "LLAudioEngine_FMODSTUDIO::init(): r_bufferlength=" << r_bufferlength << " bytes" << LL_ENDL; + LL_INFOS("AppInit") << "LLAudioEngine_FMODSTUDIO::init(): r_numbuffers=" << r_numbuffers << LL_ENDL; + + mSystem->getDriverInfo(0, r_name, 511, NULL, &r_samplerate, NULL, &r_channels); + r_name[511] = '\0'; + LL_INFOS("AppInit") << "LLAudioEngine_FMODSTUDIO::init(): r_name=\"" << r_name << "\"" << LL_ENDL; + + if (r_samplerate != 0) + latency = (int)(1000.0f * r_bufferlength * r_numbuffers / r_samplerate); + LL_INFOS("AppInit") << "LLAudioEngine_FMODSTUDIO::init(): latency=" << latency << "ms" << LL_ENDL; + + mInited = true; + + LL_INFOS("AppInit") << "LLAudioEngine_FMODSTUDIO::init(): initialization complete." << LL_ENDL; + + return true; +} + + +std::string LLAudioEngine_FMODSTUDIO::getDriverName(bool verbose) +{ + llassert_always(mSystem); + if (verbose) + { + U32 version; + if (!Check_FMOD_Error(mSystem->getVersion(&version), "FMOD::System::getVersion")) + { + return llformat("FMOD Studio %1x.%02x.%02x (Firelight Technologies Pty Ltd)", version >> 16, version >> 8 & 0x000000FF, version & 0x000000FF); + } + } + return "FMOD STUDIO"; +} + + +// create our favourite FMOD-native streaming audio implementation +LLStreamingAudioInterface *LLAudioEngine_FMODSTUDIO::createDefaultStreamingAudioImpl() const +{ + return new LLStreamingAudio_FMODSTUDIO(mSystem); +} + + +void LLAudioEngine_FMODSTUDIO::allocateListener(void) +{ + mListenerp = (LLListener *) new LLListener_FMODSTUDIO(mSystem); + if (!mListenerp) + { + LL_WARNS("FMOD") << "Listener creation failed" << LL_ENDL; + } +} + + +void LLAudioEngine_FMODSTUDIO::shutdown() +{ + stopInternetStream(); + + LL_INFOS("FMOD") << "About to LLAudioEngine::shutdown()" << LL_ENDL; + LLAudioEngine::shutdown(); + + LL_INFOS("FMOD") << "LLAudioEngine_FMODSTUDIO::shutdown() closing FMOD Studio" << LL_ENDL; + if (mSystem) + { + mSystem->close(); + mSystem->release(); + } + LL_INFOS("FMOD") << "LLAudioEngine_FMODSTUDIO::shutdown() done closing FMOD Studio" << LL_ENDL; + + delete mListenerp; + mListenerp = NULL; +} + + +LLAudioBuffer * LLAudioEngine_FMODSTUDIO::createBuffer() +{ + return new LLAudioBufferFMODSTUDIO(mSystem); +} + + +LLAudioChannel * LLAudioEngine_FMODSTUDIO::createChannel() +{ + return new LLAudioChannelFMODSTUDIO(mSystem); +} + +bool LLAudioEngine_FMODSTUDIO::initWind() +{ + mNextWindUpdate = 0.0; + + if (!mWindDSPDesc) + { + mWindDSPDesc = new FMOD_DSP_DESCRIPTION(); + } + + if (!mWindDSP) + { + memset(mWindDSPDesc, 0, sizeof(*mWindDSPDesc)); //Set everything to zero + strncpy(mWindDSPDesc->name, "Wind Unit", sizeof(mWindDSPDesc->name)); + mWindDSPDesc->pluginsdkversion = FMOD_PLUGIN_SDK_VERSION; + mWindDSPDesc->read = &windCallback; // Assign callback - may be called from arbitrary threads + if (Check_FMOD_Error(mSystem->createDSP(mWindDSPDesc, &mWindDSP), "FMOD::createDSP")) + return false; + + if (mWindGen) + delete mWindGen; + + int frequency = 44100; + + FMOD_SPEAKERMODE mode; + if (Check_FMOD_Error(mSystem->getSoftwareFormat(&frequency, &mode, nullptr), "FMOD::System::getSoftwareFormat")) + { + cleanupWind(); + return false; + } + + mWindGen = new LLWindGen<MIXBUFFERFORMAT>((U32)frequency); + + if (Check_FMOD_Error(mWindDSP->setUserData((void*)mWindGen), "FMOD::DSP::setUserData")) + { + cleanupWind(); + return false; + } + if (Check_FMOD_Error(mWindDSP->setChannelFormat(FMOD_CHANNELMASK_STEREO, 2, mode), "FMOD::DSP::setChannelFormat")) + { + cleanupWind(); + return false; + } + } + + // *TODO: Should this guard against multiple plays? + if (Check_FMOD_Error(mSystem->playDSP(mWindDSP, nullptr, false, nullptr), "FMOD::System::playDSP")) + { + cleanupWind(); + return false; + } + return true; +} + + +void LLAudioEngine_FMODSTUDIO::cleanupWind() +{ + if (mWindDSP) + { + FMOD::ChannelGroup* master_group = NULL; + if (!Check_FMOD_Error(mSystem->getMasterChannelGroup(&master_group), "FMOD::System::getMasterChannelGroup") + && master_group) + { + master_group->removeDSP(mWindDSP); + } + mWindDSP->release(); + mWindDSP = NULL; + } + + delete mWindDSPDesc; + mWindDSPDesc = NULL; + + delete mWindGen; + mWindGen = NULL; +} + + +//----------------------------------------------------------------------- +void LLAudioEngine_FMODSTUDIO::updateWind(LLVector3 wind_vec, F32 camera_height_above_water) +{ + LLVector3 wind_pos; + F64 pitch; + F64 center_freq; + + if (!mEnableWind) + { + return; + } + + if (mWindUpdateTimer.checkExpirationAndReset(LL_WIND_UPDATE_INTERVAL)) + { + + // wind comes in as Linden coordinate (+X = forward, +Y = left, +Z = up) + // need to convert this to the conventional orientation DS3D and OpenAL use + // where +X = right, +Y = up, +Z = backwards + + wind_vec.setVec(-wind_vec.mV[1], wind_vec.mV[2], -wind_vec.mV[0]); + + // cerr << "Wind update" << endl; + + pitch = 1.0 + mapWindVecToPitch(wind_vec); + center_freq = 80.0 * pow(pitch, 2.5*(mapWindVecToGain(wind_vec) + 1.0)); + + mWindGen->mTargetFreq = (F32)center_freq; + mWindGen->mTargetGain = (F32)mapWindVecToGain(wind_vec) * mMaxWindGain; + mWindGen->mTargetPanGainR = (F32)mapWindVecToPan(wind_vec); + } +} + +//----------------------------------------------------------------------- +void LLAudioEngine_FMODSTUDIO::setInternalGain(F32 gain) +{ + if (!mInited) + { + return; + } + + gain = llclamp(gain, 0.0f, 1.0f); + + FMOD::ChannelGroup* master_group = NULL; + if (!Check_FMOD_Error(mSystem->getMasterChannelGroup(&master_group), "FMOD::System::getMasterChannelGroup") + && master_group) + { + master_group->setVolume(gain); + } + + LLStreamingAudioInterface *saimpl = getStreamingAudioImpl(); + if (saimpl) + { + // fmod likes its streaming audio channel gain re-asserted after + // master volume change. + saimpl->setGain(saimpl->getGain()); + } +} + +// +// LLAudioChannelFMODSTUDIO implementation +// + +LLAudioChannelFMODSTUDIO::LLAudioChannelFMODSTUDIO(FMOD::System *system) : LLAudioChannel(), mSystemp(system), mChannelp(NULL), mLastSamplePos(0) +{ +} + + +LLAudioChannelFMODSTUDIO::~LLAudioChannelFMODSTUDIO() +{ + cleanup(); +} + +bool LLAudioChannelFMODSTUDIO::updateBuffer() +{ + if (!mCurrentSourcep) + { + // This channel isn't associated with any source, nothing + // to be updated + return false; + } + + if (LLAudioChannel::updateBuffer()) + { + // Base class update returned true, which means that we need to actually + // set up the channel for a different buffer. + + LLAudioBufferFMODSTUDIO *bufferp = (LLAudioBufferFMODSTUDIO *)mCurrentSourcep->getCurrentBuffer(); + + // Grab the FMOD sample associated with the buffer + FMOD::Sound *soundp = bufferp->getSound(); + if (!soundp) + { + // This is bad, there should ALWAYS be a sound associated with a legit + // buffer. + LL_ERRS() << "No FMOD sound!" << LL_ENDL; + return false; + } + + + // Actually play the sound. Start it off paused so we can do all the necessary + // setup. + if (!mChannelp) + { + FMOD_RESULT result = getSystem()->playSound(soundp, NULL /*free channel?*/, true, &mChannelp); + Check_FMOD_Error(result, "FMOD::System::playSound"); + } + + // Setting up channel mChannelID + } + + // If we have a source for the channel, we need to update its gain. + if (mCurrentSourcep) + { + // SJB: warnings can spam and hurt framerate, disabling + //FMOD_RESULT result; + + mChannelp->setVolume(getSecondaryGain() * mCurrentSourcep->getGain()); + //Check_FMOD_Error(result, "FMOD::Channel::setVolume"); + + mChannelp->setMode(mCurrentSourcep->isLoop() ? FMOD_LOOP_NORMAL : FMOD_LOOP_OFF); + /*if(Check_FMOD_Error(result, "FMOD::Channel::setMode")) + { + S32 index; + mChannelp->getIndex(&index); + LL_WARNS() << "Channel " << index << "Source ID: " << mCurrentSourcep->getID() + << " at " << mCurrentSourcep->getPositionGlobal() << LL_ENDL; + }*/ + } + + return true; +} + + +void LLAudioChannelFMODSTUDIO::update3DPosition() +{ + if (!mChannelp) + { + // We're not actually a live channel (i.e., we're not playing back anything) + return; + } + + LLAudioBufferFMODSTUDIO *bufferp = (LLAudioBufferFMODSTUDIO *)mCurrentBufferp; + if (!bufferp) + { + // We don't have a buffer associated with us (should really have been picked up + // by the above if. + return; + } + + if (mCurrentSourcep->isForcedPriority()) + { + // Prioritized UI and preview sounds don't need to do any positional updates. + set3DMode(false); + } + else + { + // Localized sound. Update the position and velocity of the sound. + set3DMode(true); + + LLVector3 float_pos; + float_pos.setVec(mCurrentSourcep->getPositionGlobal()); + FMOD_RESULT result = mChannelp->set3DAttributes((FMOD_VECTOR*)float_pos.mV, (FMOD_VECTOR*)mCurrentSourcep->getVelocity().mV); + Check_FMOD_Error(result, "FMOD::Channel::set3DAttributes"); + } +} + + +void LLAudioChannelFMODSTUDIO::updateLoop() +{ + if (!mChannelp) + { + // May want to clear up the loop/sample counters. + return; + } + + // + // Hack: We keep track of whether we looped or not by seeing when the + // sample position looks like it's going backwards. Not reliable; may + // yield false negatives. + // + U32 cur_pos; + mChannelp->getPosition(&cur_pos, FMOD_TIMEUNIT_PCMBYTES); + + if (cur_pos < (U32)mLastSamplePos) + { + mLoopedThisFrame = true; + } + mLastSamplePos = cur_pos; +} + + +void LLAudioChannelFMODSTUDIO::cleanup() +{ + if (!mChannelp) + { + // Aborting cleanup with no channel handle. + return; + } + + //Cleaning up channel mChannelID + Check_FMOD_Error(mChannelp->stop(), "FMOD::Channel::stop"); + + mCurrentBufferp = NULL; + mChannelp = NULL; +} + + +void LLAudioChannelFMODSTUDIO::play() +{ + if (!mChannelp) + { + LL_WARNS() << "Playing without a channel handle, aborting" << LL_ENDL; + return; + } + + Check_FMOD_Error(mChannelp->setPaused(false), "FMOD::Channel::pause"); + + getSource()->setPlayedOnce(true); + + if (LLAudioEngine_FMODSTUDIO::mChannelGroups[getSource()->getType()]) + mChannelp->setChannelGroup(LLAudioEngine_FMODSTUDIO::mChannelGroups[getSource()->getType()]); +} + + +void LLAudioChannelFMODSTUDIO::playSynced(LLAudioChannel *channelp) +{ + LLAudioChannelFMODSTUDIO *fmod_channelp = (LLAudioChannelFMODSTUDIO*)channelp; + if (!(fmod_channelp->mChannelp && mChannelp)) + { + // Don't have channels allocated to both the master and the slave + return; + } + + U32 cur_pos; + if (Check_FMOD_Error(mChannelp->getPosition(&cur_pos, FMOD_TIMEUNIT_PCMBYTES), "Unable to retrieve current position")) + return; + + cur_pos %= mCurrentBufferp->getLength(); + + // Try to match the position of our sync master + Check_FMOD_Error(mChannelp->setPosition(cur_pos, FMOD_TIMEUNIT_PCMBYTES), "Unable to set current position"); + + // Start us playing + play(); +} + + +bool LLAudioChannelFMODSTUDIO::isPlaying() +{ + if (!mChannelp) + { + return false; + } + + bool paused, playing; + mChannelp->getPaused(&paused); + mChannelp->isPlaying(&playing); + return !paused && playing; +} + + +// +// LLAudioChannelFMODSTUDIO implementation +// + + +LLAudioBufferFMODSTUDIO::LLAudioBufferFMODSTUDIO(FMOD::System *system) : mSystemp(system), mSoundp(NULL) +{ +} + + +LLAudioBufferFMODSTUDIO::~LLAudioBufferFMODSTUDIO() +{ + if (mSoundp) + { + mSoundp->release(); + mSoundp = NULL; + } +} + + +bool LLAudioBufferFMODSTUDIO::loadWAV(const std::string& filename) +{ + // Try to open a wav file from disk. This will eventually go away, as we don't + // really want to block doing this. + if (filename.empty()) + { + // invalid filename, abort. + return false; + } + + if (!gDirUtilp->fileExists(filename)) + { + // File not found, abort. + return false; + } + + if (mSoundp) + { + // If there's already something loaded in this buffer, clean it up. + mSoundp->release(); + mSoundp = NULL; + } + + FMOD_MODE base_mode = FMOD_LOOP_NORMAL; + FMOD_CREATESOUNDEXINFO exinfo; + memset(&exinfo, 0, sizeof(exinfo)); + exinfo.cbsize = sizeof(exinfo); + exinfo.suggestedsoundtype = FMOD_SOUND_TYPE_WAV; //Hint to speed up loading. + // Load up the wav file into an fmod sample (since 1.05 fmod studio expects everything in UTF-8) + FMOD_RESULT result = getSystem()->createSound(filename.c_str(), base_mode, &exinfo, &mSoundp); + + if (result != FMOD_OK) + { + // We failed to load the file for some reason. + LL_WARNS() << "Could not load data '" << filename << "': " << FMOD_ErrorString(result) << LL_ENDL; + + // + // If we EVER want to load wav files provided by end users, we need + // to rethink this! + // + // file is probably corrupt - remove it. + LLFile::remove(filename); + return false; + } + + // Everything went well, return true + return true; +} + + +U32 LLAudioBufferFMODSTUDIO::getLength() +{ + if (!mSoundp) + { + return 0; + } + + U32 length; + mSoundp->getLength(&length, FMOD_TIMEUNIT_PCMBYTES); + return length; +} + + +void LLAudioChannelFMODSTUDIO::set3DMode(bool use3d) +{ + FMOD_MODE current_mode; + if (mChannelp->getMode(¤t_mode) != FMOD_OK) + return; + FMOD_MODE new_mode = current_mode; + new_mode &= ~(use3d ? FMOD_2D : FMOD_3D); + new_mode |= use3d ? FMOD_3D : FMOD_2D; + + if (current_mode != new_mode) + { + mChannelp->setMode(new_mode); + } +} + +// *NOTE: This is almost certainly being called on the mixer thread, +// not the main thread. May have implications for callees or audio +// engine shutdown. + +FMOD_RESULT F_CALLBACK windCallback(FMOD_DSP_STATE *dsp_state, float *inbuffer, float *outbuffer, unsigned int length, int inchannels, int *outchannels) +{ + // inbuffer = fmod's original mixbuffer. + // outbuffer = the buffer passed from the previous DSP unit. + // length = length in samples at this mix time. + + LLWindGen<LLAudioEngine_FMODSTUDIO::MIXBUFFERFORMAT> *windgen = NULL; + FMOD::DSP *thisdsp = (FMOD::DSP *)dsp_state->instance; + + thisdsp->getUserData((void **)&windgen); + + if (windgen) + { + windgen->windGenerate((LLAudioEngine_FMODSTUDIO::MIXBUFFERFORMAT *)outbuffer, length); + } + + return FMOD_OK; +} diff --git a/indra/llaudio/llaudioengine_fmodstudio.h b/indra/llaudio/llaudioengine_fmodstudio.h new file mode 100644 index 0000000000..eb346e0466 --- /dev/null +++ b/indra/llaudio/llaudioengine_fmodstudio.h @@ -0,0 +1,131 @@ +/** + * @file audioengine_fmodstudio.h + * @brief Definition of LLAudioEngine class abstracting the audio + * support as a FMODSTUDIO implementation + * + * $LicenseInfo:firstyear=2020&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2020, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#ifndef LL_AUDIOENGINE_FMODSTUDIO_H +#define LL_AUDIOENGINE_FMODSTUDIO_H + +#include "llaudioengine.h" +#include "llwindgen.h" + +//Stubs +class LLAudioStreamManagerFMODSTUDIO; +namespace FMOD +{ + class System; + class Channel; + class ChannelGroup; + class Sound; + class DSP; +} +typedef struct FMOD_DSP_DESCRIPTION FMOD_DSP_DESCRIPTION; + +//Interfaces +class LLAudioEngine_FMODSTUDIO : public LLAudioEngine +{ +public: + LLAudioEngine_FMODSTUDIO(bool enable_profiler); + virtual ~LLAudioEngine_FMODSTUDIO(); + + // initialization/startup/shutdown + virtual bool init(void *user_data, const std::string &app_title); + virtual std::string getDriverName(bool verbose); + virtual LLStreamingAudioInterface* createDefaultStreamingAudioImpl() const; + virtual void allocateListener(); + + virtual void shutdown(); + + /*virtual*/ bool initWind(); + /*virtual*/ void cleanupWind(); + + /*virtual*/void updateWind(LLVector3 direction, F32 camera_height_above_water); + + typedef F32 MIXBUFFERFORMAT; + + FMOD::System *getSystem() const {return mSystem;} +protected: + /*virtual*/ LLAudioBuffer *createBuffer(); // Get a free buffer, or flush an existing one if you have to. + /*virtual*/ LLAudioChannel *createChannel(); // Create a new audio channel. + + /*virtual*/ void setInternalGain(F32 gain); + + bool mInited; + + LLWindGen<MIXBUFFERFORMAT> *mWindGen; + + FMOD_DSP_DESCRIPTION *mWindDSPDesc; + FMOD::DSP *mWindDSP; + FMOD::System *mSystem; + bool mEnableProfiler; + +public: + static FMOD::ChannelGroup *mChannelGroups[LLAudioEngine::AUDIO_TYPE_COUNT]; +}; + + +class LLAudioChannelFMODSTUDIO : public LLAudioChannel +{ +public: + LLAudioChannelFMODSTUDIO(FMOD::System *audioengine); + virtual ~LLAudioChannelFMODSTUDIO(); + +protected: + /*virtual*/ void play(); + /*virtual*/ void playSynced(LLAudioChannel *channelp); + /*virtual*/ void cleanup(); + /*virtual*/ bool isPlaying(); + + /*virtual*/ bool updateBuffer(); + /*virtual*/ void update3DPosition(); + /*virtual*/ void updateLoop(); + + void set3DMode(bool use3d); +protected: + FMOD::System *getSystem() const {return mSystemp;} + FMOD::System *mSystemp; + FMOD::Channel *mChannelp; + S32 mLastSamplePos; +}; + + +class LLAudioBufferFMODSTUDIO : public LLAudioBuffer +{ +public: + LLAudioBufferFMODSTUDIO(FMOD::System *audioengine); + virtual ~LLAudioBufferFMODSTUDIO(); + + /*virtual*/ bool loadWAV(const std::string& filename); + /*virtual*/ U32 getLength(); + friend class LLAudioChannelFMODSTUDIO; +protected: + FMOD::System *getSystem() const {return mSystemp;} + FMOD::System *mSystemp; + FMOD::Sound *getSound() const{ return mSoundp; } + FMOD::Sound *mSoundp; +}; + + +#endif // LL_AUDIOENGINE_FMODSTUDIO_H diff --git a/indra/llaudio/llaudioengine_openal.cpp b/indra/llaudio/llaudioengine_openal.cpp index 18d682b554..755547bfaa 100644 --- a/indra/llaudio/llaudioengine_openal.cpp +++ b/indra/llaudio/llaudioengine_openal.cpp @@ -79,7 +79,7 @@ bool LLAudioEngine_OpenAL::init(void* userdata, const std::string &app_title) ALCdevice *device = alcGetContextsDevice(alcGetCurrentContext()); alcGetIntegerv(device, ALC_MAJOR_VERSION, 1, &major); - alcGetIntegerv(device, ALC_MAJOR_VERSION, 1, &minor); + alcGetIntegerv(device, ALC_MINOR_VERSION, 1, &minor); LL_INFOS() << "ALC version: " << major << "." << minor << LL_ENDL; LL_INFOS() << "ALC default device: " @@ -190,6 +190,8 @@ LLAudioChannelOpenAL::~LLAudioChannelOpenAL() void LLAudioChannelOpenAL::cleanup() { alSourceStop(mALSource); + alSourcei(mALSource, AL_BUFFER, AL_NONE); + mCurrentBufferp = NULL; } diff --git a/indra/llaudio/lllistener_fmodstudio.cpp b/indra/llaudio/lllistener_fmodstudio.cpp new file mode 100644 index 0000000000..9dc55eec79 --- /dev/null +++ b/indra/llaudio/lllistener_fmodstudio.cpp @@ -0,0 +1,136 @@ +/** + * @file listener_fmodstudio.cpp + * @brief Implementation of LISTENER class abstracting the audio + * support as a FMODSTUDIO implementation + * + * $LicenseInfo:firstyear=2020&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2020, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#include "linden_common.h" +#include "llaudioengine.h" +#include "lllistener_fmodstudio.h" +#include "fmodstudio/fmod.hpp" + +//----------------------------------------------------------------------- +// constructor +//----------------------------------------------------------------------- +LLListener_FMODSTUDIO::LLListener_FMODSTUDIO(FMOD::System *system) +{ + mSystem = system; + init(); +} + +//----------------------------------------------------------------------- +LLListener_FMODSTUDIO::~LLListener_FMODSTUDIO() +{ +} + +//----------------------------------------------------------------------- +void LLListener_FMODSTUDIO::init(void) +{ + // do inherited + LLListener::init(); + mDopplerFactor = 1.0f; + mRolloffFactor = 1.0f; +} + +//----------------------------------------------------------------------- +void LLListener_FMODSTUDIO::translate(LLVector3 offset) +{ + LLListener::translate(offset); + + mSystem->set3DListenerAttributes(0, (FMOD_VECTOR*)mPosition.mV, NULL, (FMOD_VECTOR*)mListenAt.mV, (FMOD_VECTOR*)mListenUp.mV); +} + +//----------------------------------------------------------------------- +void LLListener_FMODSTUDIO::setPosition(LLVector3 pos) +{ + LLListener::setPosition(pos); + + mSystem->set3DListenerAttributes(0, (FMOD_VECTOR*)mPosition.mV, NULL, (FMOD_VECTOR*)mListenAt.mV, (FMOD_VECTOR*)mListenUp.mV); +} + +//----------------------------------------------------------------------- +void LLListener_FMODSTUDIO::setVelocity(LLVector3 vel) +{ + LLListener::setVelocity(vel); + + mSystem->set3DListenerAttributes(0, NULL, (FMOD_VECTOR*)mVelocity.mV, (FMOD_VECTOR*)mListenAt.mV, (FMOD_VECTOR*)mListenUp.mV); +} + +//----------------------------------------------------------------------- +void LLListener_FMODSTUDIO::orient(LLVector3 up, LLVector3 at) +{ + LLListener::orient(up, at); + + // at = -at; by default Fmod studio is 'left-handed' but we are providing + // flag FMOD_INIT_3D_RIGHTHANDED so no correction are needed + + mSystem->set3DListenerAttributes(0, NULL, NULL, (FMOD_VECTOR*)at.mV, (FMOD_VECTOR*)up.mV); +} + +//----------------------------------------------------------------------- +void LLListener_FMODSTUDIO::commitDeferredChanges() +{ + if (!mSystem) + { + return; + } + + mSystem->update(); +} + + +void LLListener_FMODSTUDIO::setRolloffFactor(F32 factor) +{ + //An internal FMOD optimization skips 3D updates if there have not been changes to the 3D sound environment. + // (this was true for FMODex, looks to be still true for FMOD STUDIO, but needs a recheck) + //Sadly, a change in rolloff is not accounted for, thus we must touch the listener properties as well. + //In short: Changing the position ticks a dirtyflag inside fmod, which makes it not skip 3D processing next update call. + if (mRolloffFactor != factor) + { + LLVector3 pos = mPosition - LLVector3(0.f, 0.f, .1f); + mSystem->set3DListenerAttributes(0, (FMOD_VECTOR*)pos.mV, NULL, NULL, NULL); + mSystem->set3DListenerAttributes(0, (FMOD_VECTOR*)mPosition.mV, NULL, NULL, NULL); + } + mRolloffFactor = factor; + mSystem->set3DSettings(mDopplerFactor, 1.f, mRolloffFactor); +} + + +F32 LLListener_FMODSTUDIO::getRolloffFactor() +{ + return mRolloffFactor; +} + + +void LLListener_FMODSTUDIO::setDopplerFactor(F32 factor) +{ + mDopplerFactor = factor; + mSystem->set3DSettings(mDopplerFactor, 1.f, mRolloffFactor); +} + + +F32 LLListener_FMODSTUDIO::getDopplerFactor() +{ + return mDopplerFactor; +} diff --git a/indra/llaudio/lllistener_fmodstudio.h b/indra/llaudio/lllistener_fmodstudio.h new file mode 100644 index 0000000000..5287cbedc6 --- /dev/null +++ b/indra/llaudio/lllistener_fmodstudio.h @@ -0,0 +1,65 @@ +/** + * @file listener_fmodstudio.h + * @brief Description of LISTENER class abstracting the audio support + * as an FMOD 3D implementation + * + * $LicenseInfo:firstyear=2020&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2020, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#ifndef LL_LISTENER_FMODSTUDIO_H +#define LL_LISTENER_FMODSTUDIO_H + +#include "lllistener.h" + +//Stubs +namespace FMOD +{ + class System; +} + +//Interfaces +class LLListener_FMODSTUDIO : public LLListener +{ +public: + LLListener_FMODSTUDIO(FMOD::System *system); + virtual ~LLListener_FMODSTUDIO(); + virtual void init(); + + virtual void translate(LLVector3 offset); + virtual void setPosition(LLVector3 pos); + virtual void setVelocity(LLVector3 vel); + virtual void orient(LLVector3 up, LLVector3 at); + virtual void commitDeferredChanges(); + + virtual void setDopplerFactor(F32 factor); + virtual F32 getDopplerFactor(); + virtual void setRolloffFactor(F32 factor); + virtual F32 getRolloffFactor(); +protected: + FMOD::System *mSystem; + F32 mDopplerFactor; + F32 mRolloffFactor; +}; + +#endif + + diff --git a/indra/llaudio/lllistener_openal.h b/indra/llaudio/lllistener_openal.h index f1b69ddcef..12d9aa6611 100644 --- a/indra/llaudio/lllistener_openal.h +++ b/indra/llaudio/lllistener_openal.h @@ -31,7 +31,13 @@ #include "lllistener.h" #include "AL/al.h" +#ifdef LL_DARWIN +#undef __APPLE__ +#endif #include "AL/alut.h" +#ifdef LL_DARWIN +#define __APPLE__ +#endif #include "AL/alext.h" class LLListener_OpenAL : public LLListener diff --git a/indra/llaudio/llstreamingaudio_fmodstudio.cpp b/indra/llaudio/llstreamingaudio_fmodstudio.cpp new file mode 100644 index 0000000000..22fc86c0cd --- /dev/null +++ b/indra/llaudio/llstreamingaudio_fmodstudio.cpp @@ -0,0 +1,481 @@ +/** + * @file streamingaudio_fmodstudio.cpp + * @brief LLStreamingAudio_FMODSTUDIO implementation + * + * $LicenseInfo:firstyear=2020&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2020, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#include "linden_common.h" + +#include "llmath.h" + +#include "fmodstudio/fmod.hpp" +#include "fmodstudio/fmod_errors.h" + +#include "llstreamingaudio_fmodstudio.h" + + +class LLAudioStreamManagerFMODSTUDIO +{ +public: + LLAudioStreamManagerFMODSTUDIO(FMOD::System *system, const std::string& url); + FMOD::Channel* startStream(); + bool stopStream(); // Returns true if the stream was successfully stopped. + bool ready(); + + const std::string& getURL() { return mInternetStreamURL; } + + FMOD_OPENSTATE getOpenState(unsigned int* percentbuffered = NULL, bool* starving = NULL, bool* diskbusy = NULL); +protected: + FMOD::System* mSystem; + FMOD::Channel* mStreamChannel; + FMOD::Sound* mInternetStream; + bool mReady; + + std::string mInternetStreamURL; +}; + + + +//--------------------------------------------------------------------------- +// Internet Streaming +//--------------------------------------------------------------------------- +LLStreamingAudio_FMODSTUDIO::LLStreamingAudio_FMODSTUDIO(FMOD::System *system) : +mSystem(system), +mCurrentInternetStreamp(NULL), +mFMODInternetStreamChannelp(NULL), +mGain(1.0f), +mRetryCount(0) +{ + // Number of milliseconds of audio to buffer for the audio card. + // Must be larger than the usual Second Life frame stutter time. + const U32 buffer_seconds = 10; //sec + const U32 estimated_bitrate = 128; //kbit/sec + FMOD_RESULT result = mSystem->setStreamBufferSize(estimated_bitrate * buffer_seconds * 128/*bytes/kbit*/, FMOD_TIMEUNIT_RAWBYTES); + if (result != FMOD_OK) + { + LL_WARNS("FMOD") << "setStreamBufferSize error: " << FMOD_ErrorString(result) << LL_ENDL; + } + + // Here's where we set the size of the network buffer and some buffering + // parameters. In this case we want a network buffer of 16k, we want it + // to prebuffer 40% of that when we first connect, and we want it + // to rebuffer 80% of that whenever we encounter a buffer underrun. + + // Leave the net buffer properties at the default. + //FSOUND_Stream_Net_SetBufferProperties(20000, 40, 80); +} + + +LLStreamingAudio_FMODSTUDIO::~LLStreamingAudio_FMODSTUDIO() +{ + if (mCurrentInternetStreamp) + { + // Isn't supposed to hapen, stream should be clear by now, + // and if it does, we are likely going to crash. + LL_WARNS("FMOD") << "mCurrentInternetStreamp not null on shutdown!" << LL_ENDL; + stop(); + } + + // Kill dead internet streams, if possible + killDeadStreams(); + + if (!mDeadStreams.empty()) + { + // LLStreamingAudio_FMODSTUDIO was inited on startup + // and should be destroyed on shutdown, it should + // wait for streams to die to not cause crashes or + // leaks. + // Ideally we need to wait on some kind of callback + // to release() streams correctly, but 200 ms should + // be enough and we can't wait forever. + LL_INFOS("FMOD") << "Waiting for " << (S32)mDeadStreams.size() << " streams to stop" << LL_ENDL; + for (S32 i = 0; i < 20; i++) + { + const U32 ms_delay = 10; + ms_sleep(ms_delay); // rude, but not many options here + killDeadStreams(); + if (mDeadStreams.empty()) + { + LL_INFOS("FMOD") << "All streams stopped after " << (S32)((i + 1) * ms_delay) << "ms" << LL_ENDL; + break; + } + } + } + + if (!mDeadStreams.empty()) + { + LL_WARNS("FMOD") << "Failed to kill some audio streams" << LL_ENDL; + } +} + +void LLStreamingAudio_FMODSTUDIO::killDeadStreams() +{ + std::list<LLAudioStreamManagerFMODSTUDIO *>::iterator iter; + for (iter = mDeadStreams.begin(); iter != mDeadStreams.end();) + { + LLAudioStreamManagerFMODSTUDIO *streamp = *iter; + if (streamp->stopStream()) + { + LL_INFOS("FMOD") << "Closed dead stream" << LL_ENDL; + delete streamp; + iter = mDeadStreams.erase(iter); + } + else + { + iter++; + } + } +} + +void LLStreamingAudio_FMODSTUDIO::start(const std::string& url) +{ + //if (!mInited) + //{ + // LL_WARNS() << "startInternetStream before audio initialized" << LL_ENDL; + // return; + //} + + // "stop" stream but don't clear url, etc. in case url == mInternetStreamURL + stop(); + + if (!url.empty()) + { + LL_INFOS("FMOD") << "Starting internet stream: " << url << LL_ENDL; + mCurrentInternetStreamp = new LLAudioStreamManagerFMODSTUDIO(mSystem, url); + mURL = url; + } + else + { + LL_INFOS("FMOD") << "Set internet stream to null" << LL_ENDL; + mURL.clear(); + } + + mRetryCount = 0; +} + + +void LLStreamingAudio_FMODSTUDIO::update() +{ + // Kill dead internet streams, if possible + killDeadStreams(); + + // Don't do anything if there are no streams playing + if (!mCurrentInternetStreamp) + { + return; + } + + unsigned int progress; + bool starving; + bool diskbusy; + FMOD_OPENSTATE open_state = mCurrentInternetStreamp->getOpenState(&progress, &starving, &diskbusy); + + if (open_state == FMOD_OPENSTATE_READY) + { + // Stream is live + + // start the stream if it's ready + if (!mFMODInternetStreamChannelp && + (mFMODInternetStreamChannelp = mCurrentInternetStreamp->startStream())) + { + // Reset volume to previously set volume + setGain(getGain()); + mFMODInternetStreamChannelp->setPaused(false); + } + mRetryCount = 0; + } + else if (open_state == FMOD_OPENSTATE_ERROR) + { + LL_INFOS("FMOD") << "State: FMOD_OPENSTATE_ERROR" + << " Progress: " << U32(progress) + << " Starving: " << S32(starving) + << " Diskbusy: " << S32(diskbusy) << LL_ENDL; + if (mRetryCount < 2) + { + // Retry + std::string url = mURL; + stop(); // might drop mURL, drops mCurrentInternetStreamp + + mRetryCount++; + + if (!url.empty()) + { + LL_INFOS("FMOD") << "Restarting internet stream: " << url << ", attempt " << (mRetryCount + 1) << LL_ENDL; + mCurrentInternetStreamp = new LLAudioStreamManagerFMODSTUDIO(mSystem, url); + mURL = url; + } + } + else + { + stop(); + } + return; + } + + if (mFMODInternetStreamChannelp) + { + FMOD::Sound *sound = NULL; + + if (mFMODInternetStreamChannelp->getCurrentSound(&sound) == FMOD_OK && sound) + { + FMOD_TAG tag; + S32 tagcount, dirtytagcount; + + if (sound->getNumTags(&tagcount, &dirtytagcount) == FMOD_OK && dirtytagcount) + { + for (S32 i = 0; i < tagcount; ++i) + { + if (sound->getTag(NULL, i, &tag) != FMOD_OK) + continue; + + if (tag.type == FMOD_TAGTYPE_FMOD) + { + if (!strcmp(tag.name, "Sample Rate Change")) + { + LL_INFOS("FMOD") << "Stream forced changing sample rate to " << *((float *)tag.data) << LL_ENDL; + mFMODInternetStreamChannelp->setFrequency(*((float *)tag.data)); + } + continue; + } + } + } + + if (starving) + { + bool paused = false; + mFMODInternetStreamChannelp->getPaused(&paused); + if (!paused) + { + LL_INFOS("FMOD") << "Stream starvation detected! Pausing stream until buffer nearly full." << LL_ENDL; + LL_INFOS("FMOD") << " (diskbusy=" << diskbusy << ")" << LL_ENDL; + LL_INFOS("FMOD") << " (progress=" << progress << ")" << LL_ENDL; + mFMODInternetStreamChannelp->setPaused(true); + } + } + else if (progress > 80) + { + mFMODInternetStreamChannelp->setPaused(false); + } + } + } +} + +void LLStreamingAudio_FMODSTUDIO::stop() +{ + if (mFMODInternetStreamChannelp) + { + mFMODInternetStreamChannelp->setPaused(true); + mFMODInternetStreamChannelp->setPriority(0); + mFMODInternetStreamChannelp = NULL; + } + + if (mCurrentInternetStreamp) + { + LL_INFOS("FMOD") << "Stopping internet stream: " << mCurrentInternetStreamp->getURL() << LL_ENDL; + if (mCurrentInternetStreamp->stopStream()) + { + delete mCurrentInternetStreamp; + } + else + { + LL_WARNS("FMOD") << "Pushing stream to dead list: " << mCurrentInternetStreamp->getURL() << LL_ENDL; + mDeadStreams.push_back(mCurrentInternetStreamp); + } + mCurrentInternetStreamp = NULL; + //mURL.clear(); + } +} + +void LLStreamingAudio_FMODSTUDIO::pause(int pauseopt) +{ + if (pauseopt < 0) + { + pauseopt = mCurrentInternetStreamp ? 1 : 0; + } + + if (pauseopt) + { + if (mCurrentInternetStreamp) + { + LL_INFOS("FMOD") << "Pausing internet stream" << LL_ENDL; + stop(); + } + } + else + { + start(getURL()); + } +} + + +// A stream is "playing" if it has been requested to start. That +// doesn't necessarily mean audio is coming out of the speakers. +int LLStreamingAudio_FMODSTUDIO::isPlaying() +{ + if (mCurrentInternetStreamp) + { + return 1; // Active and playing + } + else if (!mURL.empty()) + { + return 2; // "Paused" + } + else + { + return 0; + } +} + + +F32 LLStreamingAudio_FMODSTUDIO::getGain() +{ + return mGain; +} + + +std::string LLStreamingAudio_FMODSTUDIO::getURL() +{ + return mURL; +} + + +void LLStreamingAudio_FMODSTUDIO::setGain(F32 vol) +{ + mGain = vol; + + if (mFMODInternetStreamChannelp) + { + vol = llclamp(vol * vol, 0.f, 1.f); //should vol be squared here? + + mFMODInternetStreamChannelp->setVolume(vol); + } +} + +/////////////////////////////////////////////////////// +// manager of possibly-multiple internet audio streams + +LLAudioStreamManagerFMODSTUDIO::LLAudioStreamManagerFMODSTUDIO(FMOD::System *system, const std::string& url) : +mSystem(system), +mStreamChannel(NULL), +mInternetStream(NULL), +mReady(false) +{ + mInternetStreamURL = url; + + FMOD_RESULT result = mSystem->createStream(url.c_str(), FMOD_2D | FMOD_NONBLOCKING | FMOD_IGNORETAGS, 0, &mInternetStream); + + if (result != FMOD_OK) + { + LL_WARNS("FMOD") << "Couldn't open fmod stream, error " + << FMOD_ErrorString(result) + << LL_ENDL; + mReady = false; + return; + } + + mReady = true; +} + +FMOD::Channel *LLAudioStreamManagerFMODSTUDIO::startStream() +{ + // We need a live and opened stream before we try and play it. + if (!mInternetStream || getOpenState() != FMOD_OPENSTATE_READY) + { + LL_WARNS("FMOD") << "No internet stream to start playing!" << LL_ENDL; + return NULL; + } + + if (mStreamChannel) + return mStreamChannel; //Already have a channel for this stream. + + FMOD_RESULT result = mSystem->playSound(mInternetStream, NULL, true, &mStreamChannel); + if (result != FMOD_OK) + { + LL_WARNS("FMOD") << FMOD_ErrorString(result) << LL_ENDL; + } + return mStreamChannel; +} + +bool LLAudioStreamManagerFMODSTUDIO::stopStream() +{ + if (mInternetStream) + { + + + bool close = true; + switch (getOpenState()) + { + case FMOD_OPENSTATE_CONNECTING: + close = false; + break; + default: + close = true; + } + + if (close) + { + mInternetStream->release(); + mStreamChannel = NULL; + mInternetStream = NULL; + return true; + } + else + { + return false; + } + } + else + { + return true; + } +} + +FMOD_OPENSTATE LLAudioStreamManagerFMODSTUDIO::getOpenState(unsigned int* percentbuffered, bool* starving, bool* diskbusy) +{ + FMOD_OPENSTATE state; + FMOD_RESULT result = mInternetStream->getOpenState(&state, percentbuffered, starving, diskbusy); + if (result != FMOD_OK) + { + LL_WARNS("FMOD") << FMOD_ErrorString(result) << LL_ENDL; + } + return state; +} + +void LLStreamingAudio_FMODSTUDIO::setBufferSizes(U32 streambuffertime, U32 decodebuffertime) +{ + FMOD_RESULT result = mSystem->setStreamBufferSize(streambuffertime / 1000 * 128 * 128, FMOD_TIMEUNIT_RAWBYTES); + if (result != FMOD_OK) + { + LL_WARNS("FMOD") << "setStreamBufferSize error: " << FMOD_ErrorString(result) << LL_ENDL; + return; + } + FMOD_ADVANCEDSETTINGS settings; + memset(&settings, 0, sizeof(settings)); + settings.cbSize = sizeof(settings); + settings.defaultDecodeBufferSize = decodebuffertime;//ms + result = mSystem->setAdvancedSettings(&settings); + if (result != FMOD_OK) + { + LL_WARNS("FMOD") << "setAdvancedSettings error: " << FMOD_ErrorString(result) << LL_ENDL; + } +} diff --git a/indra/llaudio/llstreamingaudio_fmodstudio.h b/indra/llaudio/llstreamingaudio_fmodstudio.h new file mode 100644 index 0000000000..2127841809 --- /dev/null +++ b/indra/llaudio/llstreamingaudio_fmodstudio.h @@ -0,0 +1,76 @@ +/** + * @file streamingaudio_fmodstudio.h + * @brief Definition of LLStreamingAudio_FMODSTUDIO implementation + * + * $LicenseInfo:firstyear=2020&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2020, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#ifndef LL_STREAMINGAUDIO_FMODSTUDIO_H +#define LL_STREAMINGAUDIO_FMODSTUDIO_H + +#include "stdtypes.h" // from llcommon + +#include "llstreamingaudio.h" +#include "lltimer.h" + +//Stubs +class LLAudioStreamManagerFMODSTUDIO; +namespace FMOD +{ + class System; + class Channel; +} + +//Interfaces +class LLStreamingAudio_FMODSTUDIO : public LLStreamingAudioInterface +{ +public: + LLStreamingAudio_FMODSTUDIO(FMOD::System *system); + /*virtual*/ ~LLStreamingAudio_FMODSTUDIO(); + + /*virtual*/ void start(const std::string& url); + /*virtual*/ void stop(); + /*virtual*/ void pause(S32 pause); + /*virtual*/ void update(); + /*virtual*/ S32 isPlaying(); + /*virtual*/ void setGain(F32 vol); + /*virtual*/ F32 getGain(); + /*virtual*/ std::string getURL(); + + /*virtual*/ bool supportsAdjustableBufferSizes(){return true;} + /*virtual*/ void setBufferSizes(U32 streambuffertime, U32 decodebuffertime); +private: + void killDeadStreams(); + + FMOD::System *mSystem; + + LLAudioStreamManagerFMODSTUDIO *mCurrentInternetStreamp; + FMOD::Channel *mFMODInternetStreamChannelp; + std::list<LLAudioStreamManagerFMODSTUDIO *> mDeadStreams; + + std::string mURL; + F32 mGain; + S32 mRetryCount; +}; + + +#endif // LL_STREAMINGAUDIO_FMODSTUDIO_H diff --git a/indra/llcharacter/CMakeLists.txt b/indra/llcharacter/CMakeLists.txt index bc45eb474a..7c158c4ff9 100644 --- a/indra/llcharacter/CMakeLists.txt +++ b/indra/llcharacter/CMakeLists.txt @@ -70,3 +70,5 @@ target_link_libraries( llfilesystem llxml ) + +include(LibraryInstall) diff --git a/indra/llcommon/CMakeLists.txt b/indra/llcommon/CMakeLists.txt index a504e71340..7c49eb8904 100644 --- a/indra/llcommon/CMakeLists.txt +++ b/indra/llcommon/CMakeLists.txt @@ -8,7 +8,9 @@ include(bugsplat) include(Linking) include(Boost) include(LLSharedLibs) +if (USE_AUTOBUILD_3P OR USE_CONAN) include(Copy3rdPartyLibs) +endif () include(ZLIBNG) include(Tracy) @@ -157,6 +159,7 @@ set(llcommon_HEADER_FILES lleventdispatcher.h lleventfilter.h llevents.h + lleventtimer.h lleventemitter.h llexception.h llfasttimer.h @@ -181,6 +184,7 @@ set(llcommon_HEADER_FILES llliveappconfig.h lllivefile.h llmainthreadtask.h + llmake.h llmd5.h llmemory.h llmemorystream.h @@ -243,7 +247,9 @@ set(llcommon_HEADER_FILES llwin32headers.h llworkerthread.h hbxxh.h + is_approx_equal_fraction.h lockstatic.h + mutex.h stdtypes.h stringize.h threadpool.h @@ -282,7 +288,42 @@ target_link_libraries( target_include_directories(llcommon INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}) target_include_directories(llcommon PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}) +if (CMAKE_OSX_ARCHITECTURES MATCHES arm64 OR CMAKE_SYSTEM_PROCESSOR MATCHES aarch64) + if (${PREBUILD_TRACKING_DIR}/sentinel_installed IS_NEWER_THAN ${PREBUILD_TRACKING_DIR}/sse2neon_installed OR NOT ${sse2neon_installed} EQUAL 0) + file(MAKE_DIRECTORY ${LIBS_PREBUILT_DIR}/include/sse2neon) + if (NOT EXISTS ${LIBS_PREBUILT_DIR}/include/sse2neon/sse2neon.h) + file(DOWNLOAD + https://raw.githubusercontent.com/DLTcollab/sse2neon/master/sse2neon.h + ${LIBS_PREBUILT_DIR}/include/sse2neon/sse2neon.h + ) + endif (NOT EXISTS ${LIBS_PREBUILT_DIR}/include/sse2neon/sse2neon.h) + file(WRITE ${PREBUILD_TRACKING_DIR}/sse2neon_installed "0") + endif (${PREBUILD_TRACKING_DIR}/sentinel_installed IS_NEWER_THAN ${PREBUILD_TRACKING_DIR}/sse2neon_installed OR NOT ${sse2neon_installed} EQUAL 0) + target_include_directories(llcommon PUBLIC ${LIBS_PREBUILT_DIR}/include/sse2neon) +elseif (${LINUX_DISTRO} MATCHES debian OR (${LINUX_DISTRO} MATCHES ubuntu) OR (${LINUX_DISTRO} MATCHES opensuse-tumbleweed)) + target_include_directories(llcommon PUBLIC ${LIBS_PREBUILT_DIR}/include) +endif (CMAKE_OSX_ARCHITECTURES MATCHES arm64 OR CMAKE_SYSTEM_PROCESSOR MATCHES aarch64) + +if (USE_AUTOBUILD_3P OR USE_CONAN) add_dependencies(llcommon stage_third_party_libs) +else () + target_compile_options(${PROJECT_NAME} PUBLIC -Wno-deprecated-declarations) + if (CMAKE_CXX_COMPILER_ID MATCHES "GNU") + set_source_files_properties( + llapp.cpp + llsdutil.cpp + PROPERTIES COMPILE_FLAGS -Wno-stringop-truncation) + set_source_files_properties( + llevent.cpp + llfasttimer.cpp + PROPERTIES COMPILE_FLAGS -Wno-nonnull) + elseif (LINUX AND CMAKE_CXX_COMPILER_ID MATCHES "Clang") + set_source_files_properties(llsys.cpp PROPERTIES + COMPILE_FLAGS -Wno-unused-but-set-variable) + endif() +endif () + +include(LibraryInstall) if (LL_TESTS) include(LLAddBuildTest) diff --git a/indra/llcommon/always_return.h b/indra/llcommon/always_return.h index a206471da5..b99eb49096 100644 --- a/indra/llcommon/always_return.h +++ b/indra/llcommon/always_return.h @@ -79,6 +79,22 @@ namespace LL DESIRED mDefault; }; + // specialize for AlwaysReturn<void> + template <> + struct AlwaysReturn<void> + { + public: + AlwaysReturn() {} + + // callable returns a type not convertible to DESIRED, return default + template <typename CALLABLE, typename... ARGS> + void operator()(CALLABLE&& callable, ARGS&&... args) + { + // discard whatever callable(args) returns + std::forward<CALLABLE>(callable)(std::forward<ARGS>(args)...); + } + }; + /** * always_return<T>(some_function, some_args...) calls * some_function(some_args...). It is guaranteed to return a value of type diff --git a/indra/llcommon/fsyspath.h b/indra/llcommon/fsyspath.h index 1b4aec09b4..e9c96edce3 100644 --- a/indra/llcommon/fsyspath.h +++ b/indra/llcommon/fsyspath.h @@ -68,7 +68,11 @@ public: } // shadow base-class string() method with UTF-8 aware method - std::string string() const { return super::u8string(); } + std::string string() const + { + auto u8 = super::u8string(); + return std::string(u8.begin(), u8.end()); + } // On Posix systems, where value_type is already char, this operator // std::string() method shadows the base class operator string_type() // method. But on Windows, where value_type is wchar_t, the base class diff --git a/indra/llcommon/hbxxh.cpp b/indra/llcommon/hbxxh.cpp index 41d797a7e3..8ccf8dfcbe 100644 --- a/indra/llcommon/hbxxh.cpp +++ b/indra/llcommon/hbxxh.cpp @@ -34,7 +34,11 @@ // in your build, in which case the latter would be used instead. For ARM64 // builds, this would also automatically enable NEON vectorization. #define XXH_INLINE_ALL +#if LL_USESYSTEMLIBS +#include <xxhash.h> +#else #include "xxhash/xxhash.h" +#endif #include "hbxxh.h" diff --git a/indra/llcommon/llapp.h b/indra/llcommon/llapp.h index 3d18864b80..57f5a112d9 100644 --- a/indra/llcommon/llapp.h +++ b/indra/llcommon/llapp.h @@ -282,7 +282,7 @@ public: LLRunner& getRunner() { return mRunner; } #ifdef LL_WINDOWS - virtual void reportCrashToBugsplat(void* pExcepInfo /*EXCEPTION_POINTERS*/) { } + virtual bool reportCrashToBugsplat(void* pExcepInfo /*EXCEPTION_POINTERS*/) { return false; } #endif public: diff --git a/indra/llcommon/llapr.h b/indra/llcommon/llapr.h index 693cd7c01f..13597d56a4 100644 --- a/indra/llcommon/llapr.h +++ b/indra/llcommon/llapr.h @@ -42,6 +42,7 @@ #include "llstring.h" #include "mutex.h" +#include <memory> struct apr_dso_handle_t; /** diff --git a/indra/llcommon/llcoros.cpp b/indra/llcommon/llcoros.cpp index 1539b48bd3..9e95d9c85f 100644 --- a/indra/llcommon/llcoros.cpp +++ b/indra/llcommon/llcoros.cpp @@ -310,26 +310,55 @@ namespace static const U32 STATUS_MSC_EXCEPTION = 0xE06D7363; // compiler specific -U32 exception_filter(U32 code, struct _EXCEPTION_POINTERS *exception_infop) +U32 exception_filter(U32 code, struct _EXCEPTION_POINTERS* exception_infop) { - if (code == STATUS_MSC_EXCEPTION) + if (LLApp::instance()->reportCrashToBugsplat((void*)exception_infop)) + { + // Handled + return EXCEPTION_CONTINUE_SEARCH; + } + else if (code == STATUS_MSC_EXCEPTION) { // C++ exception, go on return EXCEPTION_CONTINUE_SEARCH; } else { - // handle it + // handle it, convert to std::exception return EXCEPTION_EXECUTE_HANDLER; } + + return EXCEPTION_CONTINUE_SEARCH; } -void sehandle(const LLCoros::callable_t& callable) +void cpphandle(const LLCoros::callable_t& callable, const std::string& name) { - __try + // SE and C++ can not coexists, thus two handlers + try { callable(); } + catch (const LLCoros::Stop& exc) + { + LL_INFOS("LLCoros") << "coroutine " << name << " terminating because " + << exc.what() << LL_ENDL; + } + catch (const LLContinueError&) + { + // Any uncaught exception derived from LLContinueError will be caught + // here and logged. This coroutine will terminate but the rest of the + // viewer will carry on. + LOG_UNHANDLED_EXCEPTION(STRINGIZE("coroutine " << name)); + } +} + +void sehandle(const LLCoros::callable_t& callable, const std::string& name) +{ + __try + { + // handle stop and continue exceptions first + cpphandle(callable, name); + } __except (exception_filter(GetExceptionCode(), GetExceptionInformation())) { // convert to C++ styled exception @@ -340,16 +369,7 @@ void sehandle(const LLCoros::callable_t& callable) throw std::exception(integer_string); } } - -#else // ! LL_WINDOWS - -inline void sehandle(const LLCoros::callable_t& callable) -{ - callable(); -} - -#endif // ! LL_WINDOWS - +#endif // LL_WINDOWS } // anonymous namespace // Top-level wrapper around caller's coroutine callable. @@ -362,10 +382,14 @@ void LLCoros::toplevel(std::string name, callable_t callable) // set it as current mCurrent.reset(&corodata); +#ifdef LL_WINDOWS + // can not use __try directly, toplevel requires unwinding, thus use of a wrapper + sehandle(callable, name); +#else // LL_WINDOWS // run the code the caller actually wants in the coroutine try { - sehandle(callable); + callable(); } catch (const Stop& exc) { @@ -387,6 +411,7 @@ void LLCoros::toplevel(std::string name, callable_t callable) << name << LL_ENDL; LLCoros::instance().saveException(name, std::current_exception()); } +#endif // else LL_WINDOWS } //static diff --git a/indra/llcommon/lldate.cpp b/indra/llcommon/lldate.cpp index b38864688d..5205699b92 100644 --- a/indra/llcommon/lldate.cpp +++ b/indra/llcommon/lldate.cpp @@ -77,6 +77,15 @@ std::string LLDate::asRFC1123() const return toHTTPDateString (std::string ("%A, %d %b %Y %H:%M:%S GMT")); } +std::string LLDate::toLocalDateString (std::string fmt) const +{ + LL_PROFILE_ZONE_SCOPED; + + time_t locSeconds = (time_t) mSecondsSinceEpoch; + struct tm * lt = localtime (&locSeconds); + return toHTTPDateString(lt, fmt); +} + std::string LLDate::toHTTPDateString (std::string fmt) const { LL_PROFILE_ZONE_SCOPED; diff --git a/indra/llcommon/lldate.h b/indra/llcommon/lldate.h index 1a69a04232..34c8692f20 100644 --- a/indra/llcommon/lldate.h +++ b/indra/llcommon/lldate.h @@ -77,6 +77,7 @@ public: std::string asRFC1123() const; void toStream(std::ostream&) const; bool split(S32 *year, S32 *month = NULL, S32 *day = NULL, S32 *hour = NULL, S32 *min = NULL, S32 *sec = NULL) const; + std::string toLocalDateString(std::string fmt) const; std::string toHTTPDateString (std::string fmt) const; static std::string toHTTPDateString (tm * gmt, std::string fmt); /** diff --git a/indra/llcommon/llerror.cpp b/indra/llcommon/llerror.cpp index 90c6ba309b..d834098994 100644 --- a/indra/llcommon/llerror.cpp +++ b/indra/llcommon/llerror.cpp @@ -1604,11 +1604,11 @@ namespace LLError std::string LLUserWarningMsg::sLocalizedOutOfMemoryWarning; LLUserWarningMsg::Handler LLUserWarningMsg::sHandler; - void LLUserWarningMsg::show(const std::string& message) + void LLUserWarningMsg::show(const std::string& message, S32 error_code) { if (sHandler) { - sHandler(std::string(), message); + sHandler(std::string(), message, error_code); } } @@ -1616,7 +1616,7 @@ namespace LLError { if (sHandler && !sLocalizedOutOfMemoryTitle.empty()) { - sHandler(sLocalizedOutOfMemoryTitle, sLocalizedOutOfMemoryWarning); + sHandler(sLocalizedOutOfMemoryTitle, sLocalizedOutOfMemoryWarning, ERROR_BAD_ALLOC); } } @@ -1627,7 +1627,7 @@ namespace LLError "Second Life viewer couldn't access some of the files it needs and will be closed." "\n\nPlease reinstall viewer from https://secondlife.com/support/downloads/ and " "contact https://support.secondlife.com if issue persists after reinstall."; - sHandler("Missing Files", error_string); + sHandler("Missing Files", error_string, ERROR_MISSING_FILES); } void LLUserWarningMsg::setHandler(const LLUserWarningMsg::Handler &handler) diff --git a/indra/llcommon/llerror.h b/indra/llcommon/llerror.h index 8a143ff30a..41893a35e5 100644 --- a/indra/llcommon/llerror.h +++ b/indra/llcommon/llerror.h @@ -308,7 +308,16 @@ namespace LLError class LLUserWarningMsg { public: - typedef std::function<void(const std::string&, const std::string&)> Handler; + // error codes, tranlates to last_exec states like LAST_EXEC_OTHER_CRASH + typedef enum + { + ERROR_OTHER = 0, + ERROR_BAD_ALLOC = 1, + ERROR_MISSING_FILES = 2, + } eLastExecEvent; + + // tittle, message and error code to include in error marker file + typedef std::function<void(const std::string&, const std::string&, S32 error_code)> Handler; static void setHandler(const Handler&); static void setOutOfMemoryStrings(const std::string& title, const std::string& message); @@ -316,7 +325,7 @@ namespace LLError static void showOutOfMemory(); static void showMissingFiles(); // Genering error - static void show(const std::string&); + static void show(const std::string&, S32 error_code = -1); private: // needs to be preallocated before viewer runs out of memory diff --git a/indra/llcommon/llexception.cpp b/indra/llcommon/llexception.cpp index c0154a569f..107fdc2b2d 100644 --- a/indra/llcommon/llexception.cpp +++ b/indra/llcommon/llexception.cpp @@ -15,7 +15,12 @@ #include "llexception.h" // STL headers // std headers +#include <iomanip> +#include <sstream> #include <typeinfo> +#if LL_WINDOWS +#include <excpt.h> +#endif // LL_WINDOWS // external library headers #include <boost/exception/diagnostic_information.hpp> #include <boost/exception/error_info.hpp> @@ -29,7 +34,6 @@ // On Windows, header-only implementation causes macro collisions -- use // prebuilt library #define BOOST_STACKTRACE_LINK -#include <excpt.h> #endif // LL_WINDOWS #include <boost/stacktrace.hpp> @@ -94,25 +98,47 @@ void annotate_exception_(boost::exception& exc) // For windows SEH exception handling we sometimes need a filter that will // separate C++ exceptions from C SEH exceptions -static const U32 STATUS_MSC_EXCEPTION = 0xE06D7363; // compiler specific +static constexpr U32 STATUS_MSC_EXCEPTION = 0xE06D7363; // compiler specific +static constexpr U32 STATUS_STACK_FULL = 0xC00000FD; -U32 msc_exception_filter(U32 code, struct _EXCEPTION_POINTERS *exception_infop) +void LL::seh::fill_stacktrace(std::string& stacktrace, U32 code) { - const auto stack = to_string(boost::stacktrace::stacktrace()); - LL_WARNS() << "SEH Exception handled (that probably shouldn't be): Code " << code - << "\n Stack trace: \n" - << stack << LL_ENDL; + // Sadly, despite its diagnostic importance, trying to capture a + // stacktrace when the stack is already blown only terminates us faster. + if (code == STATUS_STACK_FULL) + { + stacktrace = "(stack overflow, no traceback)"; + } + else + { + stacktrace = to_string(boost::stacktrace::stacktrace()); + } +} +U32 LL::seh::common_filter(U32 code, struct _EXCEPTION_POINTERS*) +{ if (code == STATUS_MSC_EXCEPTION) { - // C++ exception, go on + // C++ exception, don't stop at this handler return EXCEPTION_CONTINUE_SEARCH; } else { - // handle it + // This is a non-C++ exception, e.g. hardware check. + // Pass control into the handler block. return EXCEPTION_EXECUTE_HANDLER; } } +void LL::seh::rethrow(U32 code, const std::string& stacktrace) +{ + std::ostringstream out; + out << "Windows exception 0x" << std::hex << code; + if (! stacktrace.empty()) + { + out << '\n' << stacktrace; + } + LLTHROW(Windows_SEH_exception(out.str())); +} + #endif //LL_WINDOWS diff --git a/indra/llcommon/llexception.h b/indra/llcommon/llexception.h index 68e609444e..f58a553eb3 100644 --- a/indra/llcommon/llexception.h +++ b/indra/llcommon/llexception.h @@ -12,6 +12,7 @@ #if ! defined(LL_LLEXCEPTION_H) #define LL_LLEXCEPTION_H +#include "always_return.h" #include <stdexcept> #include <boost/exception/exception.hpp> #include <boost/throw_exception.hpp> @@ -102,14 +103,115 @@ void crash_on_unhandled_exception_(const char*, int, const char*, const std::str log_unhandled_exception_(__FILE__, __LINE__, BOOST_CURRENT_FUNCTION, CONTEXT) void log_unhandled_exception_(const char*, int, const char*, const std::string&); +/***************************************************************************** +* Structured Exception Handling +*****************************************************************************/ +// this is used in platform-generic code -- define outside #if LL_WINDOWS +struct Windows_SEH_exception: public LLException +{ + Windows_SEH_exception(const std::string& what): LLException(what) {} +}; + +namespace LL +{ +namespace seh +{ + +#if LL_WINDOWS //------------------------------------------------------------- + +void fill_stacktrace(std::string& stacktrace, U32 code); + +// wrapper around caller's U32 filter(U32 code, struct _EXCEPTION_POINTERS*) +// filter function: capture a stacktrace, if possible, before forwarding the +// call to the caller's filter() function +template <typename FILTER> +U32 filter_(std::string& stacktrace, FILTER&& filter, + U32 code, struct _EXCEPTION_POINTERS* exptrs) +{ + // By the time the handler gets control, the stack has been unwound, + // so report the stack trace now at filter() time. + fill_stacktrace(stacktrace, code); + return std::forward<FILTER>(filter)(code, exptrs); +} + +template <typename TRYCODE, typename FILTER, typename HANDLER> +auto catcher_inner(std::string& stacktrace, + TRYCODE&& trycode, FILTER&& filter, HANDLER&& handler) +{ + __try + { + return std::forward<TRYCODE>(trycode)(); + } + __except (filter_(stacktrace, + std::forward<FILTER>(filter), + GetExceptionCode(), GetExceptionInformation())) + { + return always_return<decltype(trycode())>( + std::forward<HANDLER>(handler), GetExceptionCode(), stacktrace); + } +} + +// triadic variant specifies try(), filter(U32, struct _EXCEPTION_POINTERS*), +// handler(U32, const std::string& stacktrace) +// stacktrace may or may not be available +template <typename TRYCODE, typename FILTER, typename HANDLER> +auto catcher(TRYCODE&& trycode, FILTER&& filter, HANDLER&& handler) +{ + // Construct and destroy this stacktrace string in the outer function + // because we can't do either in the function with __try/__except. + std::string stacktrace; + return catcher_inner(stacktrace, + std::forward<TRYCODE>(trycode), + std::forward<FILTER>(filter), + std::forward<HANDLER>(handler)); +} -#if LL_WINDOWS +// common_filter() handles the typical case in which we want our handler +// clause to handle only Structured Exceptions rather than explicitly-thrown +// C++ exceptions +U32 common_filter(U32 code, struct _EXCEPTION_POINTERS*); + +// dyadic variant specifies try(), handler(U32, stacktrace), assumes common_filter() +template <typename TRYCODE, typename HANDLER> +auto catcher(TRYCODE&& trycode, HANDLER&& handler) +{ + return catcher(std::forward<TRYCODE>(trycode), + common_filter, + std::forward<HANDLER>(handler)); +} + +// monadic variant specifies try(), assumes default filter and handler +template <typename TRYCODE> +auto catcher(TRYCODE&& trycode) +{ + return catcher(std::forward<TRYCODE>(trycode), rethrow); +} + +[[noreturn]] void rethrow(U32 code, const std::string& stacktrace); + +#else // not LL_WINDOWS ----------------------------------------------------- + +template <typename TRYCODE, typename FILTER, typename HANDLER> +auto catcher(TRYCODE&& trycode, FILTER&&, HANDLER&&) +{ + return std::forward<TRYCODE>(trycode)(); +} + +template <typename TRYCODE, typename HANDLER> +auto catcher(TRYCODE&& trycode, HANDLER&&) +{ + return std::forward<TRYCODE>(trycode)(); +} + +template <typename TRYCODE> +auto catcher(TRYCODE&& trycode) +{ + return std::forward<TRYCODE>(trycode)(); +} -// SEH exception filtering for use in __try __except -// Separates C++ exceptions from C SEH exceptions -// Todo: might be good idea to do some kind of seh_to_msc_wrapper(function, ARGS&&); -U32 msc_exception_filter(U32 code, struct _EXCEPTION_POINTERS *exception_infop); +#endif // not LL_WINDOWS ----------------------------------------------------- -#endif //LL_WINDOWS +} // namespace LL::seh +} // namespace LL #endif /* ! defined(LL_LLEXCEPTION_H) */ diff --git a/indra/llcommon/llfasttimer.cpp b/indra/llcommon/llfasttimer.cpp index 722743f453..7ceb57336e 100644 --- a/indra/llcommon/llfasttimer.cpp +++ b/indra/llcommon/llfasttimer.cpp @@ -43,7 +43,7 @@ #if LL_WINDOWS #include "lltimer.h" -#elif LL_LINUX +#elif LL_LINUX || __FreeBSD__ #include <sys/time.h> #include <sched.h> #include "lltimer.h" diff --git a/indra/llcommon/llfasttimer.h b/indra/llcommon/llfasttimer.h index 09fcf8a1af..a69a03e419 100644 --- a/indra/llcommon/llfasttimer.h +++ b/indra/llcommon/llfasttimer.h @@ -127,8 +127,22 @@ public: #endif +#if (LL_DARWIN && defined(__arm64__)) -#if (LL_LINUX) && !(defined(__i386__) || defined(__amd64__)) + static U32 getCPUClockCount64() + { + U64 t = clock_gettime_nsec_np(CLOCK_UPTIME_RAW); + return t/1000; + } + + static U64 getCPUClockCount32() + { + return (U32) (getCPUClockCount64() >> 8); + } + +#endif + +#if (LL_LINUX && !(defined(__i386__) || defined(__amd64__))) // // Linux implementation of CPU clock - non-x86. // This is accurate but SLOW! Only use out of desperation. @@ -159,7 +173,7 @@ public: #endif // (LL_LINUX) && !(defined(__i386__) || defined(__amd64__)) -#if (LL_LINUX || LL_DARWIN) && (defined(__i386__) || defined(__amd64__)) +#if (LL_LINUX || LL_DARWIN || __FreeBSD__) && (defined(__i386__) || defined(__amd64__)) // // Mac+Linux FAST x86 implementation of CPU clock static U32 getCPUClockCount32() diff --git a/indra/llcommon/llmemory.h b/indra/llcommon/llmemory.h index b616edfde7..4a9359f8e2 100644 --- a/indra/llcommon/llmemory.h +++ b/indra/llcommon/llmemory.h @@ -52,7 +52,7 @@ class LLMutex ; #define LL_DEFAULT_HEAP_ALIGN 8 #elif LL_DARWIN #define LL_DEFAULT_HEAP_ALIGN 16 -#elif LL_LINUX +#elif LL_LINUX || __FreeBSD__ #define LL_DEFAULT_HEAP_ALIGN 8 #endif @@ -71,7 +71,11 @@ LL_COMMON_API void ll_assert_aligned_func(uintptr_t ptr,U32 alignment); #define ll_assert_aligned(ptr,alignment) #endif +#if defined(__i386__) || defined(__x86_64__) #include <xmmintrin.h> +#else +#include <sse2neon.h> +#endif template <typename T> T* LL_NEXT_ALIGNED_ADDRESS(T* address) { @@ -85,7 +89,7 @@ template <typename T> T* LL_NEXT_ALIGNED_ADDRESS_64(T* address) (uintptr_t(address) + 0x3F) & ~0x3F); } -#if LL_LINUX || LL_DARWIN +#if LL_LINUX || LL_DARWIN || __FreeBSD__ #define LL_ALIGN_PREFIX(x) #define LL_ALIGN_POSTFIX(x) __attribute__((aligned(x))) diff --git a/indra/llcommon/llpreprocessor.h b/indra/llcommon/llpreprocessor.h index b499a9ce10..e9f07f6fdf 100644 --- a/indra/llcommon/llpreprocessor.h +++ b/indra/llcommon/llpreprocessor.h @@ -32,9 +32,11 @@ #ifdef LL_LINUX #define __ENABLE_WSTRING #include <endian.h> +#elif defined(__FreeBSD__) +#include <sys/endian.h> #endif // LL_LINUX -#if (defined(LL_WINDOWS) || (defined(LL_LINUX) && (__BYTE_ORDER == __LITTLE_ENDIAN)) || (defined(LL_DARWIN) && defined(__LITTLE_ENDIAN__))) +#if (defined(LL_WINDOWS) || (defined(LL_LINUX) && (__BYTE_ORDER == __LITTLE_ENDIAN)) || (defined(LL_DARWIN) && defined(__LITTLE_ENDIAN__)) || (defined(__FreeBSD__) && (_BYTE_ORDER == _LITTLE_ENDIAN))) #define LL_LITTLE_ENDIAN 1 #else #define LL_BIG_ENDIAN 1 @@ -77,7 +79,7 @@ #endif // Deal with minor differences on Unixy OSes. -#if LL_DARWIN || LL_LINUX +#if LL_DARWIN || LL_LINUX || __FreeBSD__ // Different name, same functionality. #define stricmp strcasecmp #define strnicmp strncasecmp diff --git a/indra/llcommon/llprocess.cpp b/indra/llcommon/llprocess.cpp index 912e596c3f..2800cc5608 100644 --- a/indra/llcommon/llprocess.cpp +++ b/indra/llcommon/llprocess.cpp @@ -176,13 +176,13 @@ public: // In general, our streambuf might contain a number of different // physical buffers; iterate over those. bool keepwriting = true; - for (const_buffer_sequence::const_iterator bufi(bufs.begin()), bufend(bufs.end()); + for (auto bufi = buffer_sequence_begin(bufs), bufend = buffer_sequence_end(bufs); bufi != bufend && keepwriting; ++bufi) { // http://www.boost.org/doc/libs/1_49_0_beta1/doc/html/boost_asio/reference/buffer.html#boost_asio.reference.buffer.accessing_buffer_contents // Although apr_file_write() accepts const void*, we // manipulate const char* so we can increment the pointer. - const char* remainptr = boost::asio::buffer_cast<const char*>(*bufi); + const char* remainptr = static_cast<const char*>((*bufi).data()); std::size_t remainlen = boost::asio::buffer_size(*bufi); while (remainlen) { @@ -377,14 +377,14 @@ public: // In general, the mutable_buffer_sequence returned by prepare() might // contain a number of different physical buffers; iterate over those. std::size_t tocommit(0); - for (mutable_buffer_sequence::const_iterator bufi(bufs.begin()), bufend(bufs.end()); + for (auto bufi = buffer_sequence_begin(bufs), bufend = buffer_sequence_end(bufs); bufi != bufend; ++bufi) { // http://www.boost.org/doc/libs/1_49_0_beta1/doc/html/boost_asio/reference/buffer.html#boost_asio.reference.buffer.accessing_buffer_contents std::size_t toread(boost::asio::buffer_size(*bufi)); apr_size_t gotten(toread); apr_status_t err = apr_file_read(mPipe, - boost::asio::buffer_cast<void*>(*bufi), + static_cast<void*>((*bufi).data()), &gotten); // EAGAIN is exactly what we want from a nonblocking pipe. // Rather than waiting for data, it should return immediately. @@ -691,10 +691,22 @@ LLProcess::LLProcess(const LLSDOrParams& params): // terminate with a null pointer argv.push_back(NULL); + // create an env vector for the child process + std::vector<const char*> envv; + + // Add environment value assignments. See above remarks about c_str(). + for (const std::string& env : params.envs) + { + envv.push_back(env.c_str()); + } + + // terminate with a null pointer + envv.push_back(NULL); + // Launch! The NULL would be the environment block, if we were passing // one. Hand-expand chkapr() macro so we can fill in the actual command // string instead of the variable names. - if (ll_apr_warn_status(apr_proc_create(&mProcess, argv[0], &argv[0], NULL, procattr, + if (ll_apr_warn_status(apr_proc_create(&mProcess, argv[0], &argv[0], &envv[0], procattr, mPool))) { LLTHROW(LLProcessError(STRINGIZE(params << " failed"))); diff --git a/indra/llcommon/llprocess.h b/indra/llcommon/llprocess.h index cc2d6566fc..52b5e0f562 100644 --- a/indra/llcommon/llprocess.h +++ b/indra/llcommon/llprocess.h @@ -38,7 +38,7 @@ #if LL_WINDOWS #include "llwin32headers.h" // for HANDLE -#elif LL_LINUX +#elif LL_LINUX || __FreeBSD__ #if defined(Status) #undef Status #endif @@ -163,6 +163,7 @@ public: Params(): executable("executable"), args("args"), + envs("envs"), cwd("cwd"), autokill("autokill", true), attached("attached", true), @@ -180,6 +181,10 @@ public: * argument while assembling the command line. */ Multiple<std::string> args; + /** + * zero or more additional command-line environment values. + */ + Multiple<std::string> envs; /// current working directory, if need it changed Optional<std::string> cwd; /// implicitly kill child process on termination of parent, whether diff --git a/indra/llcommon/llprocessor.cpp b/indra/llcommon/llprocessor.cpp index a783e18e49..9b3cdf4df5 100644 --- a/indra/llcommon/llprocessor.cpp +++ b/indra/llcommon/llprocessor.cpp @@ -638,6 +638,13 @@ public: { getCPUIDInfo(); uint64_t frequency = getSysctlInt64("hw.cpufrequency"); + if (!frequency) { + auto tbfrequency = getSysctlInt64("hw.tbfrequency"); + struct clockinfo clockrate; + auto clockrate_len = sizeof(clockrate); + if (!sysctlbyname("kern.clockrate", &clockrate, &clockrate_len, NULL, 0)) + frequency = tbfrequency * clockrate.hz; + } setInfo(eFrequency, (F64)frequency / (F64)1000000); } @@ -743,12 +750,14 @@ private: : "0" (level)) #endif +#if __i386__ || __x86_64__ unsigned int eax, ebx, ecx, edx; __cpuid(0x1, eax, ebx, ecx, edx); if(feature_infos[0] != (S32)edx) { LL_WARNS() << "machdep.cpu.feature_bits doesn't match expected cpuid result!" << LL_ENDL; } +#endif // __i386__ || __x86_64__ #endif // LL_RELEASE_FOR_DOWNLOAD @@ -793,20 +802,150 @@ private: } }; +#elif __FreeBSD__ + +#include <sys/sysctl.h> +class LLProcessorInfoFreeBSDImpl : public LLProcessorInfoImpl +{ +public: + LLProcessorInfoFreeBSDImpl() + { + size_t len = 0; + using std::string; + + char cpu_brand_string[0x40]; + len = sizeof cpu_brand_string; + memset(cpu_brand_string, '\0', len); + sysctlbyname("hw.model", (void *)cpu_brand_string, &len, + NULL, 0); + cpu_brand_string[0x3f] = '\0'; + setInfo(eBrandName, cpu_brand_string); + + uint64_t cpu_frequency = 0; + len = sizeof cpu_frequency; + sysctlbyname("hw.clockrate", (void *)&cpu_frequency, &len, + NULL, 0); + setInfo(eFrequency, (F64)cpu_frequency); + + auto dmesgboot = LLFile::fopen("/var/run/dmesg.boot", "rb"); + std::ostringstream s; + if (dmesgboot) { + char line[MAX_STRING]; + memset(line, 0, MAX_STRING); + while (fgets(line, MAX_STRING, dmesgboot)) { + line[strlen(line) - 1] = ' '; + s << line; + s << std::endl; + } + fclose(dmesgboot); + s << std::endl; + } + + auto dmesgboot_str = s.str(); + int decimal; + + auto idx1 = dmesgboot_str.find_first_of("\"") + 1; + auto idx2 = (idx1 != string::npos) + ? dmesgboot_str.find_first_of("\"", idx1) + : string::npos; + auto vendor = dmesgboot_str.substr(idx1, idx2 - idx1); + if (vendor.length() > 0) setInfo(eVendor, vendor.c_str()); + + idx1 = dmesgboot_str.find_first_of("=", idx2); + idx1 = dmesgboot_str.find_first_of("=", idx1 + 1) + 3; + idx2 = dmesgboot_str.find_first_of(" ", idx1); + auto family = dmesgboot_str.substr(idx1, idx2 - idx1); + std::istringstream(family) >> std::hex >> decimal; + setInfo(eFamily, decimal); + setInfo(eFamilyName, compute_CPUFamilyName(vendor.c_str(), + decimal, 0)); + + idx1 = dmesgboot_str.find_first_of("=", idx2) + 3; + idx2 = dmesgboot_str.find_first_of(" ", idx1); + auto model = dmesgboot_str.substr(idx1, idx2 - idx1); + std::istringstream(model) >> std::hex >> decimal; + setInfo(eModel, decimal); + + idx1 = dmesgboot_str.find_first_of("=", idx2) + 1; + idx2 = dmesgboot_str.find_first_of("\n", idx1); + auto stepping = dmesgboot_str.substr(idx1, idx2 - idx1); + setInfo(eStepping, std::stoi(stepping)); + + if (dmesgboot_str.find(",SSE,") != string::npos) + setExtension(cpu_feature_names[eSSE_Ext]); + + if (dmesgboot_str.find(",SSE2,") != string::npos) + setExtension(cpu_feature_names[eSSE2_Ext]); + + if (dmesgboot_str.find("<SSE3,") != string::npos) + setExtension(cpu_feature_names[eSSE3_Features]); + + if (dmesgboot_str.find(",SSSE3,") != string::npos) + setExtension(cpu_feature_names[eSSE3S_Features]); + + if (dmesgboot_str.find(",SSE4.1,") != string::npos) + setExtension(cpu_feature_names[eSSE4_1_Features]); + + if (dmesgboot_str.find(",SSE4.2,") != string::npos) + setExtension(cpu_feature_names[eSSE4_2_Features]); + + if (dmesgboot_str.find(",SSE4A,") != string::npos) + setExtension(cpu_feature_names[eSSE4a_Features]); + } + + virtual ~LLProcessorInfoFreeBSDImpl() {} +}; + #elif LL_LINUX + +// *NOTE:Mani - eww, macros! srry. +#define LLPI_SET_INFO_STRING(llpi_id, cpuinfo_id) \ + if (!cpuinfo[cpuinfo_id].empty()) \ + { setInfo(llpi_id, cpuinfo[cpuinfo_id]);} + +#define LLPI_SET_INFO_INT(llpi_id, cpuinfo_id) \ + {\ + S32 result; \ + if (!cpuinfo[cpuinfo_id].empty() \ + && LLStringUtil::convertToS32(cpuinfo[cpuinfo_id], result)) \ + { setInfo(llpi_id, result);} \ + } + const char CPUINFO_FILE[] = "/proc/cpuinfo"; -class LLProcessorInfoLinuxImpl : public LLProcessorInfoImpl -{ +class LLProcessorInfoLinuxImpl : public LLProcessorInfoImpl { public: - LLProcessorInfoLinuxImpl() - { + LLProcessorInfoLinuxImpl() { get_proc_cpuinfo(); } virtual ~LLProcessorInfoLinuxImpl() {} + private: + F64 getCPUMaxMHZ() + { + // Nicky: We just look into cpu0. In theory we could iterate over all cores + // "/sys/devices/system/cpu/cpu*/cpufreq/cpuinfo_max_freq" + // But those should not fluctuate that much? + std::ifstream fIn { "/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq" }; + + if( !fIn.is_open() ) + return 0.0; + + std::string strLine; + fIn >> strLine; + if( strLine.empty() ) + return 0.0l; + + F64 mhz {}; + if( !LLStringUtil::convertToF64(strLine, mhz ) ) + return 0.0; + + mhz = mhz / 1000.0; + return mhz; + } + void get_proc_cpuinfo() { std::map< std::string, std::string > cpuinfo; @@ -835,32 +974,25 @@ private: std::string llinename(linename); LLStringUtil::toLower(llinename); std::string lineval( spacespot + 1, nlspot ); - cpuinfo[ llinename ] = lineval; + cpuinfo[ llinename ] = lineval; } fclose(cpuinfo_fp); } -# if LL_X86 -// *NOTE:Mani - eww, macros! srry. -#define LLPI_SET_INFO_STRING(llpi_id, cpuinfo_id) \ - if (!cpuinfo[cpuinfo_id].empty()) \ - { setInfo(llpi_id, cpuinfo[cpuinfo_id]);} - -#define LLPI_SET_INFO_INT(llpi_id, cpuinfo_id) \ - {\ - S32 result; \ - if (!cpuinfo[cpuinfo_id].empty() \ - && LLStringUtil::convertToS32(cpuinfo[cpuinfo_id], result)) \ - { setInfo(llpi_id, result);} \ + F64 mhzFromSys = getCPUMaxMHZ(); + F64 mhzFromProc {}; + if( !LLStringUtil::convertToF64(cpuinfo["cpu mhz"], mhzFromProc ) ) + mhzFromProc = 0.0; + if (mhzFromSys > 1.0 && mhzFromSys > mhzFromProc ) + { + setInfo( eFrequency, mhzFromSys ); } - - F64 mhz; - if (LLStringUtil::convertToF64(cpuinfo["cpu mhz"], mhz) - && 200.0 < mhz && mhz < 10000.0) + else if ( 200.0 < mhzFromProc && mhzFromProc < 10000.0) { - setInfo(eFrequency,(F64)(mhz)); + setInfo(eFrequency,(F64)(mhzFromProc)); } +# if LL_X86 LLPI_SET_INFO_STRING(eBrandName, "model name"); LLPI_SET_INFO_STRING(eVendor, "vendor_id"); @@ -868,7 +1000,7 @@ private: LLPI_SET_INFO_INT(eModel, "model"); - S32 family; + S32 family{}; if (!cpuinfo["cpu family"].empty() && LLStringUtil::convertToS32(cpuinfo["cpu family"], family)) { @@ -973,6 +1105,9 @@ LLProcessorInfo::LLProcessorInfo() : mImpl(NULL) #elif LL_DARWIN static LLProcessorInfoDarwinImpl the_impl; mImpl = &the_impl; +#elif __FreeBSD__ + static LLProcessorInfoFreeBSDImpl the_impl; + mImpl = &the_impl; #else static LLProcessorInfoLinuxImpl the_impl; mImpl = &the_impl; diff --git a/indra/llcommon/llqueuedthread.cpp b/indra/llcommon/llqueuedthread.cpp index 1c4ac5a7bf..0196a24b18 100644 --- a/indra/llcommon/llqueuedthread.cpp +++ b/indra/llcommon/llqueuedthread.cpp @@ -146,7 +146,7 @@ size_t LLQueuedThread::updateQueue(F32 max_time_ms) // schedule a call to threadedUpdate for every call to updateQueue if (!isQuitting()) { - mRequestQueue.post([=]() + mRequestQueue.post([=, this]() { LL_PROFILE_ZONE_NAMED_CATEGORY_THREAD("qt - update"); mIdleThread = false; @@ -474,7 +474,7 @@ void LLQueuedThread::processRequest(LLQueuedThread::QueuedRequest* req) #else using namespace std::chrono_literals; auto retry_time = LL::WorkQueue::TimePoint::clock::now() + 16ms; - mRequestQueue.post([=] + mRequestQueue.post([=, this] { LL_PROFILE_ZONE_NAMED("processRequest - retry"); if (LL::WorkQueue::TimePoint::clock::now() < retry_time) diff --git a/indra/llcommon/llsdutil.cpp b/indra/llcommon/llsdutil.cpp index dbd89118c9..9fa27cee78 100644 --- a/indra/llcommon/llsdutil.cpp +++ b/indra/llcommon/llsdutil.cpp @@ -35,7 +35,7 @@ # include "llwin32headers.h" // for htonl #elif LL_LINUX # include <netinet/in.h> -#elif LL_DARWIN +#elif LL_DARWIN || __FreeBSD__ # include <arpa/inet.h> #endif @@ -160,7 +160,7 @@ LLSD ll_binary_from_string(const LLSD& sd) char* ll_print_sd(const LLSD& sd) { const U32 bufferSize = 10 * 1024; - static char buffer[bufferSize]; + static char buffer[bufferSize + 1]; std::ostringstream stream; //stream.rdbuf()->pubsetbuf(buffer, bufferSize); stream << LLSDOStreamer<LLSDXMLFormatter>(sd); @@ -182,7 +182,7 @@ char* ll_pretty_print_sd_ptr(const LLSD* sd) char* ll_pretty_print_sd(const LLSD& sd) { const U32 bufferSize = 100 * 1024; - static char buffer[bufferSize]; + static char buffer[bufferSize + 1]; std::ostringstream stream; //stream.rdbuf()->pubsetbuf(buffer, bufferSize); stream << LLSDOStreamer<LLSDXMLFormatter>(sd, LLSDFormatter::OPTIONS_PRETTY); diff --git a/indra/llcommon/llstring.h b/indra/llcommon/llstring.h index db716b1431..7a8edc176d 100644 --- a/indra/llcommon/llstring.h +++ b/indra/llcommon/llstring.h @@ -53,6 +53,7 @@ class LLSD; #if LL_DARWIN || LL_LINUX // Template specialization of char_traits for U16s. Only necessary on Mac and Linux (exists on Windows already) #include <cstring> +#include <memory> namespace std { diff --git a/indra/llcommon/llsys.cpp b/indra/llcommon/llsys.cpp index 3f33ad61c5..94d59adf29 100644 --- a/indra/llcommon/llsys.cpp +++ b/indra/llcommon/llsys.cpp @@ -83,8 +83,13 @@ using namespace llsd; # include <sys/sysinfo.h> # include <stdexcept> const char MEMINFO_FILE[] = "/proc/meminfo"; +#ifdef __GNU__ # include <gnu/libc-version.h> #endif +#elif __FreeBSD__ +# include <sys/sysctl.h> +# include <sys/utsname.h> +#endif LLCPUInfo gSysCPU; LLMemoryInfo gSysMemory; @@ -340,6 +345,8 @@ LLOSInfo::LLOSInfo() : mOSString = mOSStringSimple; } +#ifdef __GNU__ + const char OS_VERSION_MATCH_EXPRESSION[] = "([0-9]+)\\.([0-9]+)(\\.([0-9]+))?"; boost::regex os_version_parse(OS_VERSION_MATCH_EXPRESSION); boost::smatch matched; @@ -403,6 +410,8 @@ LLOSInfo::LLOSInfo() : LL_WARNS("AppInit") << "glibc version '" << glibc_version << "' cannot be parsed to three numbers; using all zeros" << LL_ENDL; } +#endif // __GNU__ + #else struct utsname un; @@ -429,6 +438,13 @@ LLOSInfo::LLOSInfo() : if (simple.length() > 0) mOSStringSimple = simple; } + else if (ostype == "FreeBSD") + { + // Only care about major and minor FreeBSD versions, truncate at first '-' + std::string simple = mOSStringSimple.substr(0, mOSStringSimple.find_first_of("-", 0)); + if (simple.length() > 0) + mOSStringSimple = simple; + } } else { @@ -504,57 +520,46 @@ const S32 LLOSInfo::getOSBitness() const return mOSBitness; } -//static -U32 LLOSInfo::getProcessVirtualSizeKB() -{ - U32 virtual_size = 0; -#if LL_LINUX -# define STATUS_SIZE 2048 - LLFILE* status_filep = LLFile::fopen("/proc/self/status", "rb"); - if (status_filep) - { - S32 numRead = 0; - char buff[STATUS_SIZE]; /* Flawfinder: ignore */ +namespace { - size_t nbytes = fread(buff, 1, STATUS_SIZE-1, status_filep); - buff[nbytes] = '\0'; + U32 readFromProcStat( std::string entryName ) + { + U32 val{}; +#if LL_LINUX + constexpr U32 STATUS_SIZE = 2048; - // All these guys return numbers in KB - char *memp = strstr(buff, "VmSize:"); - if (memp) + LLFILE* status_filep = LLFile::fopen("/proc/self/status", "rb"); + if (status_filep) { - numRead += sscanf(memp, "%*s %u", &virtual_size); + char buff[STATUS_SIZE]; /* Flawfinder: ignore */ + + size_t nbytes = fread(buff, 1, STATUS_SIZE-1, status_filep); + buff[nbytes] = '\0'; + + // All these guys return numbers in KB + char *memp = strstr(buff, entryName.c_str()); + if (memp) + { + (void) sscanf(memp, "%*s %u", &val); + } + fclose(status_filep); } - fclose(status_filep); - } #endif - return virtual_size; + return val; + } + } //static -U32 LLOSInfo::getProcessResidentSizeKB() +U32 LLOSInfo::getProcessVirtualSizeKB() { - U32 resident_size = 0; -#if LL_LINUX - LLFILE* status_filep = LLFile::fopen("/proc/self/status", "rb"); - if (status_filep != NULL) - { - S32 numRead = 0; - char buff[STATUS_SIZE]; /* Flawfinder: ignore */ - - size_t nbytes = fread(buff, 1, STATUS_SIZE-1, status_filep); - buff[nbytes] = '\0'; + return readFromProcStat( "VmSize:" ); +} - // All these guys return numbers in KB - char *memp = strstr(buff, "VmRSS:"); - if (memp) - { - numRead += sscanf(memp, "%*s %u", &resident_size); - } - fclose(status_filep); - } -#endif - return resident_size; +//static +U32 LLOSInfo::getProcessResidentSizeKB() +{ + return readFromProcStat( "VmRSS:" ); } //static @@ -765,13 +770,17 @@ static U32Kilobytes LLMemoryAdjustKBResult(U32Kilobytes inKB) } #endif -#if LL_DARWIN +#if LL_DARWIN || __FreeBSD__ // static U32Kilobytes LLMemoryInfo::getHardwareMemSize() { // This might work on Linux as well. Someone check... uint64_t phys = 0; +#if LL_DARWIN int mib[2] = { CTL_HW, HW_MEMSIZE }; +#else + int mib[2] = { CTL_HW, HW_PHYSMEM }; +#endif size_t len = sizeof(phys); sysctl(mib, 2, &phys, &len, NULL, 0); @@ -785,7 +794,7 @@ U32Kilobytes LLMemoryInfo::getPhysicalMemoryKB() const #if LL_WINDOWS return LLMemoryAdjustKBResult(U32Kilobytes(mStatsMap["Total Physical KB"].asInteger())); -#elif LL_DARWIN +#elif LL_DARWIN || __FreeBSD__ return getHardwareMemSize(); #elif LL_LINUX diff --git a/indra/llcommon/llsys.h b/indra/llcommon/llsys.h index 827b0dc048..c8ff4dd98a 100644 --- a/indra/llcommon/llsys.h +++ b/indra/llcommon/llsys.h @@ -130,7 +130,7 @@ public: void stream(std::ostream& s) const; ///< output text info to s U32Kilobytes getPhysicalMemoryKB() const; -#if LL_DARWIN +#if LL_DARWIN || __FreeBSD__ static U32Kilobytes getHardwareMemSize(); // Because some Mac linkers won't let us reference extern gSysMemory from a different lib. #endif diff --git a/indra/llcommon/llthreadsafequeue.h b/indra/llcommon/llthreadsafequeue.h index 034e3f7897..85fcbbacac 100644 --- a/indra/llcommon/llthreadsafequeue.h +++ b/indra/llcommon/llthreadsafequeue.h @@ -452,7 +452,11 @@ ElementT LLThreadSafeQueue<ElementT, QueueT>::pop(void) // so we can finish draining the queue. pop_result popped = pop_(lock1, value); if (popped == POPPED) +#if LL_LINUX + return value; +#else return std::move(value); +#endif // Once the queue is DONE, there will never be any more coming. if (popped == DONE) diff --git a/indra/llcommon/lltimer.cpp b/indra/llcommon/lltimer.cpp index f36d223100..4e15ae29a9 100644 --- a/indra/llcommon/lltimer.cpp +++ b/indra/llcommon/lltimer.cpp @@ -35,7 +35,7 @@ #if LL_WINDOWS # include "llwin32headers.h" -#elif LL_LINUX || LL_DARWIN +#elif LL_LINUX || LL_DARWIN || __FreeBSD__ # include <errno.h> # include <sys/time.h> #else @@ -115,7 +115,7 @@ void ms_sleep(U32 ms) #endif -#elif LL_LINUX || LL_DARWIN +#elif LL_LINUX || LL_DARWIN || __FreeBSD__ static void _sleep_loop(struct timespec& thiswait) { struct timespec nextwait; @@ -233,7 +233,7 @@ F64 calc_clock_frequency() #endif // LL_WINDOWS -#if LL_LINUX || LL_DARWIN +#if LL_LINUX || LL_DARWIN || __FreeBSD__ // Both Linux and Mac use gettimeofday for accurate time F64 calc_clock_frequency() { diff --git a/indra/llcommon/lluuid.cpp b/indra/llcommon/lluuid.cpp index b9bd27aa17..6d7cf473f5 100644 --- a/indra/llcommon/lluuid.cpp +++ b/indra/llcommon/lluuid.cpp @@ -520,7 +520,7 @@ S32 LLUUID::getNodeID(unsigned char* node_id) #include <net/if.h> #include <net/if_types.h> #include <net/if_dl.h> -#include <net/route.h> +//#include <net/route.h> #include <ifaddrs.h> // static @@ -604,7 +604,7 @@ S32 LLUUID::getNodeID(unsigned char* node_id) #define HAVE_NETINET_IN_H #ifdef HAVE_NETINET_IN_H #include <netinet/in.h> -#if !LL_DARWIN +#if !LL_DARWIN && !__FreeBSD__ #include <linux/sockios.h> #endif #endif diff --git a/indra/llcommon/stdtypes.h b/indra/llcommon/stdtypes.h index 28e50b3d21..b40a718593 100644 --- a/indra/llcommon/stdtypes.h +++ b/indra/llcommon/stdtypes.h @@ -29,6 +29,7 @@ #include <cassert> #include <cfloat> #include <climits> +#include <cstddef> #include <limits> #include <type_traits> @@ -71,7 +72,7 @@ typedef unsigned __int64 U64; #else typedef long long int S64; typedef long long unsigned int U64; -#if LL_DARWIN || LL_LINUX +#if LL_DARWIN || LL_LINUX || __FreeBSD__ #define S64L(a) (a##LL) #define U64L(a) (a##ULL) #endif @@ -113,6 +114,10 @@ typedef U32 TPACKETID; #define FALSE (0) #endif +#if __FreeBSD__ +#undef NULL +#endif + #ifndef NULL #define NULL (0) #endif diff --git a/indra/llcommon/tests/llleap_test.cpp b/indra/llcommon/tests/llleap_test.cpp index fa48bcdefd..3fb25b4cef 100644 --- a/indra/llcommon/tests/llleap_test.cpp +++ b/indra/llcommon/tests/llleap_test.cpp @@ -35,7 +35,7 @@ // causes Windows abdominal pain such that it later fails code-signing in some // mysterious way. Entirely suppressing these LLLeap tests pushes the failure // rate MUCH lower. Can we re-enable them with a smaller data size on Windows? -const size_t BUFFERED_LENGTH = 100*1024; +const size_t BUFFERED_LENGTH = 1023*1024; #else // not Windows const size_t BUFFERED_LENGTH = 1023*1024; // try wrangling just under a megabyte of data diff --git a/indra/llcommon/tests/llstring_test.cpp b/indra/llcommon/tests/llstring_test.cpp index b18712b8e9..b68c63a15f 100644 --- a/indra/llcommon/tests/llstring_test.cpp +++ b/indra/llcommon/tests/llstring_test.cpp @@ -377,7 +377,7 @@ namespace tut { F32 value; std::string str_val("2147483647"); //0x7FFFFFFF - ensure("1: convertToF32 failed", LLStringUtil::convertToF32(str_val, value) && value == 2147483647); + ensure("1: convertToF32 failed", LLStringUtil::convertToF32(str_val, value) && value == 2147483647.f); str_val = "0"; ensure("2: convertToF32 failed", LLStringUtil::convertToF32(str_val, value) && value == 0); @@ -399,7 +399,7 @@ namespace tut { F64 value; std::string str_val("9223372036854775807"); //0x7FFFFFFFFFFFFFFF - ensure("1: convertToF64 failed", LLStringUtil::convertToF64(str_val, value) && value == 9223372036854775807LL); + ensure("1: convertToF64 failed", LLStringUtil::convertToF64(str_val, value) && value == 9223372036854775807.); str_val = "0"; ensure("2: convertToF64 failed", LLStringUtil::convertToF64(str_val, value) && value == 0.0F); diff --git a/indra/llcommon/workqueue.cpp b/indra/llcommon/workqueue.cpp index 6066e74fb5..c8ece616b2 100644 --- a/indra/llcommon/workqueue.cpp +++ b/indra/llcommon/workqueue.cpp @@ -17,6 +17,7 @@ // std headers // external library headers // other Linden headers +#include "llapp.h" #include "llcoros.h" #include LLCOROS_MUTEX_HEADER #include "llerror.h" @@ -102,19 +103,95 @@ std::string LL::WorkQueueBase::makeName(const std::string& name) return STRINGIZE("WorkQueue" << num); } +namespace +{ +#if LL_WINDOWS + + static const U32 STATUS_MSC_EXCEPTION = 0xE06D7363; // compiler specific + + U32 exception_filter(U32 code, struct _EXCEPTION_POINTERS* exception_infop) + { + if (LLApp::instance()->reportCrashToBugsplat((void*)exception_infop)) + { + // Handled + return EXCEPTION_CONTINUE_SEARCH; + } + else if (code == STATUS_MSC_EXCEPTION) + { + // C++ exception, go on + return EXCEPTION_CONTINUE_SEARCH; + } + else + { + // handle it, convert to std::exception + return EXCEPTION_EXECUTE_HANDLER; + } + + return EXCEPTION_CONTINUE_SEARCH; + } + + void cpphandle(const LL::WorkQueueBase::Work& work) + { + // SE and C++ can not coexists, thus two handlers + try + { + work(); + } + catch (const LLContinueError&) + { + // Any uncaught exception derived from LLContinueError will be caught + // here and logged. This coroutine will terminate but the rest of the + // viewer will carry on. + LOG_UNHANDLED_EXCEPTION(STRINGIZE("LLContinue in work queue")); + } + } + + void sehandle(const LL::WorkQueueBase::Work& work) + { + __try + { + // handle stop and continue exceptions first + cpphandle(work); + } + __except (exception_filter(GetExceptionCode(), GetExceptionInformation())) + { + // convert to C++ styled exception + char integer_string[512]; + sprintf(integer_string, "SEH, code: %lu\n", GetExceptionCode()); + throw std::exception(integer_string); + } + } +#endif // LL_WINDOWS +} // anonymous namespace + void LL::WorkQueueBase::callWork(const Work& work) { LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD; + +#ifdef LL_WINDOWS + // can not use __try directly, toplevel requires unwinding, thus use of a wrapper + sehandle(work); +#else // LL_WINDOWS try { work(); } - catch (...) + catch (LLContinueError&) { - // No matter what goes wrong with any individual work item, the worker - // thread must go on! Log our own instance name with the exception. LOG_UNHANDLED_EXCEPTION(getKey()); } + catch (...) + { + // Stash any other kind of uncaught exception to be rethrown by main thread. + LL_WARNS("LLCoros") << "Capturing and rethrowing uncaught exception in WorkQueueBase " + << getKey() << LL_ENDL; + + LL::WorkQueue::ptr_t main_queue = LL::WorkQueue::getInstance("mainloop"); + main_queue->post( + // Bind the current exception, rethrow it in main loop. + [exc = std::current_exception()]() { std::rethrow_exception(exc); }); + } +#endif // else LL_WINDOWS } void LL::WorkQueueBase::error(const std::string& msg) diff --git a/indra/llcorehttp/CMakeLists.txt b/indra/llcorehttp/CMakeLists.txt index 05b788a433..ab3a86b37e 100644 --- a/indra/llcorehttp/CMakeLists.txt +++ b/indra/llcorehttp/CMakeLists.txt @@ -8,9 +8,10 @@ include(OpenSSL) include(NGHTTP2) include(ZLIBNG) include(LLCoreHttp) +if (LL_TESTS) include(LLAddBuildTest) +endif () include(LLCommon) -include(Tut) include(bugsplat) set(llcorehttp_SOURCE_FILES @@ -92,6 +93,8 @@ target_include_directories( llcorehttp INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}) # lead to circular dependencies (or in case of cmake, the first project declaring it's dependencies wins) target_include_directories( llcorehttp PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../llmessage) +include(LibraryInstall) + # tests set(LLCOREHTTP_TESTS ON CACHE BOOL "Build and run llcorehttp integration tests specifically") diff --git a/indra/llcrashlogger/CMakeLists.txt b/indra/llcrashlogger/CMakeLists.txt index 6ac73c0d32..3506a35c1e 100644 --- a/indra/llcrashlogger/CMakeLists.txt +++ b/indra/llcrashlogger/CMakeLists.txt @@ -21,3 +21,5 @@ list(APPEND llcrashlogger_SOURCE_FILES ${llcrashlogger_HEADER_FILES}) add_library(llcrashlogger ${llcrashlogger_SOURCE_FILES}) target_link_libraries( llcrashlogger llcommon llmessage llcorehttp llxml llfilesystem ) + +include(LibraryInstall) diff --git a/indra/llfilesystem/CMakeLists.txt b/indra/llfilesystem/CMakeLists.txt index 9f24f75eab..8d85f739b3 100644 --- a/indra/llfilesystem/CMakeLists.txt +++ b/indra/llfilesystem/CMakeLists.txt @@ -4,6 +4,9 @@ project(llfilesystem) include(00-Common) include(LLCommon) +if (LINUX OR CMAKE_SYSTEM_NAME MATCHES FreeBSD) + include(UnixInstall) +endif (LINUX OR CMAKE_SYSTEM_NAME MATCHES FreeBSD) set(llfilesystem_SOURCE_FILES lldir.cpp @@ -30,17 +33,17 @@ if (DARWIN) LIST(APPEND llfilesystem_HEADER_FILES lldir_mac.h) endif (DARWIN) -if (LINUX) +if (LINUX OR CMAKE_SYSTEM_NAME MATCHES FreeBSD) LIST(APPEND llfilesystem_SOURCE_FILES lldir_linux.cpp) LIST(APPEND llfilesystem_HEADER_FILES lldir_linux.h) if (INSTALL) set_source_files_properties(lldir_linux.cpp PROPERTIES COMPILE_FLAGS - "-DAPP_RO_DATA_DIR=\\\"${APP_SHARE_DIR}\\\"" + "-DAPP_RO_DATA_DIR=\\\"${APP_SHARE_DIR}\\\" -DAPP_LIBEXEC_DIR=\\\"${APP_LIBEXEC_DIR}\\\" -DAPP_PLUGIN_DIR=\\\"${INSTALL_LIBRARY_DIR}\\\"" ) endif (INSTALL) -endif (LINUX) +endif (LINUX OR CMAKE_SYSTEM_NAME MATCHES FreeBSD) if (WINDOWS) LIST(APPEND llfilesystem_SOURCE_FILES lldir_win32.cpp) @@ -55,6 +58,7 @@ target_link_libraries(llfilesystem llcommon ) target_include_directories( llfilesystem INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}) +include(LibraryInstall) # Add tests if (LL_TESTS) diff --git a/indra/llfilesystem/lldir.cpp b/indra/llfilesystem/lldir.cpp index 99d4850610..e8e5d6538b 100644 --- a/indra/llfilesystem/lldir.cpp +++ b/indra/llfilesystem/lldir.cpp @@ -386,7 +386,7 @@ std::string LLDir::buildSLOSCacheDir() const } else { - res = add(getOSCacheDir(), "SecondLife"); + res = add(getOSCacheDir(), "Megapahit"); } return res; } @@ -690,7 +690,7 @@ void LLDir::walkSearchSkinDirs(const std::string& subdir, const std::string& filename, const FUNCTION& function) const { - for (const std::string& skindir : mSearchSkinDirs) + for (std::string skindir : mSearchSkinDirs) { std::string subdir_path(add(skindir, subdir)); for (const std::string& subsubdir : subsubdirs) diff --git a/indra/llfilesystem/lldir_linux.cpp b/indra/llfilesystem/lldir_linux.cpp index b13b42c954..69cfedebc7 100644 --- a/indra/llfilesystem/lldir_linux.cpp +++ b/indra/llfilesystem/lldir_linux.cpp @@ -83,7 +83,11 @@ LLDir_Linux::LLDir_Linux() mExecutableFilename = ""; mExecutablePathAndName = ""; +#ifdef APP_LIBEXEC_DIR + mExecutableDir = APP_LIBEXEC_DIR; +#else mExecutableDir = tmp_str; +#endif mWorkingDir = tmp_str; #ifdef APP_RO_DATA_DIR mAppRODataDir = APP_RO_DATA_DIR; @@ -123,7 +127,7 @@ LLDir_Linux::LLDir_Linux() if ((path_end = strrchr(tmp_str,'/'))) { *path_end = '\0'; - mExecutableDir = tmp_str; + //mExecutableDir = tmp_str; mWorkingDir = tmp_str; mExecutableFilename = path_end+1; } @@ -133,7 +137,11 @@ LLDir_Linux::LLDir_Linux() } } +#ifdef APP_PLUGIN_DIR + mLLPluginDir = APP_PLUGIN_DIR; +#else mLLPluginDir = mExecutableDir + mDirDelimiter + "llplugin"; +#endif // *TODO: don't use /tmp, use $HOME/.secondlife/tmp or something. mTempDir = "/tmp"; @@ -205,7 +213,7 @@ void LLDir_Linux::initAppDirs(const std::string &app_name, LL_WARNS() << "Couldn't create LL_PATH_CACHE dir " << getExpandedFilename(LL_PATH_CACHE,"") << LL_ENDL; } - mCAFile = getExpandedFilename(LL_PATH_EXECUTABLE, "ca-bundle.crt"); + mCAFile = add(mAppRODataDir, "ca-bundle.crt"); } U32 LLDir_Linux::countFilesInDir(const std::string &dirname, const std::string &mask) diff --git a/indra/llfilesystem/lldir_linux.h b/indra/llfilesystem/lldir_linux.h index bd031bd7bb..f9b0427ccd 100644 --- a/indra/llfilesystem/lldir_linux.h +++ b/indra/llfilesystem/lldir_linux.h @@ -24,7 +24,7 @@ * $/LicenseInfo$ */ -#if !LL_LINUX +#if !LL_LINUX && !__FreeBSD__ #error This header must not be included when compiling for any target other than Linux. Consider including lldir.h instead. #endif // !LL_LINUX diff --git a/indra/llfilesystem/lldir_mac.cpp b/indra/llfilesystem/lldir_mac.cpp index b9be75c528..b25c654e31 100644 --- a/indra/llfilesystem/lldir_mac.cpp +++ b/indra/llfilesystem/lldir_mac.cpp @@ -64,7 +64,7 @@ LLDir_Mac::LLDir_Mac() { mDirDelimiter = "/"; - const std::string secondLifeString = "SecondLife"; + const std::string secondLifeString = "Megapahit"; std::string executablepathstr = getSystemExecutableFolder(); diff --git a/indra/llimage/CMakeLists.txt b/indra/llimage/CMakeLists.txt index cc75c463bc..f55d9fdf5e 100644 --- a/indra/llimage/CMakeLists.txt +++ b/indra/llimage/CMakeLists.txt @@ -8,9 +8,13 @@ include(LLImage) include(JPEG) include(LLKDU) include(ZLIBNG) +if (LL_TESTS) include(LLAddBuildTest) +endif () include(bugsplat) +if (LL_TESTS) include(Tut) +endif () set(llimage_SOURCE_FILES llimagebmp.cpp @@ -63,6 +67,18 @@ target_link_libraries(llimage ll::libjpeg ) +if (NOT (USE_AUTOBUILD_3P OR USE_CONAN)) + if (CMAKE_CXX_COMPILER_ID MATCHES "GNU") + set_source_files_properties(llimageworker.cpp PROPERTIES COMPILE_FLAGS -Wno-int-in-bool-context) + set_source_files_properties( + llimage.cpp + llimagefilter.cpp + PROPERTIES COMPILE_FLAGS -Wno-stringop-overflow) + endif() +endif () + +include(LibraryInstall) + # Add tests if (LL_TESTS) SET(llimage_TEST_SOURCE_FILES diff --git a/indra/llimage/llimagejpeg.cpp b/indra/llimage/llimagejpeg.cpp index 0e7ec365d4..dd3efb3459 100644 --- a/indra/llimage/llimagejpeg.cpp +++ b/indra/llimage/llimagejpeg.cpp @@ -79,11 +79,13 @@ bool LLImageJPEG::updateData() //try/catch will crash on Mac and Linux if LLImageJPEG::errorExit throws an error //so as instead, we use setjmp/longjmp to avoid this crash, which is the best we can get. --bao // +#if !(LL_DARWIN && defined(__arm64__)) if(setjmp(sSetjmpBuffer)) { jpeg_destroy_decompress(&cinfo); return false; } +#endif try { // Now we can initialize the JPEG decompression object. @@ -223,11 +225,13 @@ bool LLImageJPEG::decode(LLImageRaw* raw_image, F32 decode_time) //try/catch will crash on Mac and Linux if LLImageJPEG::errorExit throws an error //so as instead, we use setjmp/longjmp to avoid this crash, which is the best we can get. --bao // +#if !(LL_DARWIN && defined(__arm64__)) if(setjmp(sSetjmpBuffer)) { jpeg_destroy_decompress(&cinfo); return true; // done } +#endif try { // Now we can initialize the JPEG decompression object. @@ -433,7 +437,9 @@ void LLImageJPEG::errorExit( j_common_ptr cinfo ) jpeg_destroy(cinfo); // Return control to the setjmp point +#if !(LL_DARWIN && defined(__arm64__)) longjmp(sSetjmpBuffer, 1) ; +#endif } // Decide whether to emit a trace or warning message. @@ -545,6 +551,7 @@ bool LLImageJPEG::encode( const LLImageRaw* raw_image, F32 encode_time ) //try/catch will crash on Mac and Linux if LLImageJPEG::errorExit throws an error //so as instead, we use setjmp/longjmp to avoid this crash, which is the best we can get. --bao // +#if !(LL_DARWIN && defined(__arm64__)) if( setjmp(sSetjmpBuffer) ) { // If we get here, the JPEG code has signaled an error. @@ -555,6 +562,7 @@ bool LLImageJPEG::encode( const LLImageRaw* raw_image, F32 encode_time ) mOutputBufferSize = 0; return false; } +#endif try { diff --git a/indra/llimagej2coj/CMakeLists.txt b/indra/llimagej2coj/CMakeLists.txt index 93e85668dd..5a2aac9e84 100644 --- a/indra/llimagej2coj/CMakeLists.txt +++ b/indra/llimagej2coj/CMakeLists.txt @@ -21,9 +21,11 @@ list(APPEND llimagej2coj_SOURCE_FILES ${llimagej2coj_HEADER_FILES}) add_library (llimagej2coj ${llimagej2coj_SOURCE_FILES}) +include_directories( ${CMAKE_SOURCE_DIR}/llimage ) target_link_libraries( llimagej2coj llcommon - llimage + #llimage ll::openjpeg ) +include(LibraryInstall) diff --git a/indra/llimagej2coj/llimagej2coj.cpp b/indra/llimagej2coj/llimagej2coj.cpp index f4bcb97a5d..1c6b9e423c 100644 --- a/indra/llimagej2coj/llimagej2coj.cpp +++ b/indra/llimagej2coj/llimagej2coj.cpp @@ -28,9 +28,9 @@ #include "llimagej2coj.h" // this is defined so that we get static linking. -#include "openjpeg.h" -#include "event.h" -#include "cio.h" +#include <openjpeg/openjpeg.h> +#include <openjpeg/event.h> +#include <openjpeg/cio.h> #define MAX_ENCODED_DISCARD_LEVELS 5 @@ -617,7 +617,6 @@ public: for (S32 c = 0; c < numcomps; c++) { cmptparm[c].prec = 8; - cmptparm[c].bpp = 8; cmptparm[c].sgnd = 0; cmptparm[c].dx = parameters.subsampling_dx; cmptparm[c].dy = parameters.subsampling_dy; diff --git a/indra/llinventory/CMakeLists.txt b/indra/llinventory/CMakeLists.txt index 93a586759f..88a2c33ae0 100644 --- a/indra/llinventory/CMakeLists.txt +++ b/indra/llinventory/CMakeLists.txt @@ -59,6 +59,8 @@ add_library (llinventory ${llinventory_SOURCE_FILES}) target_link_libraries( llinventory llcommon llmath llmessage llxml ) target_include_directories( llinventory INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}) +include(LibraryInstall) + #add unit tests if (LL_TESTS) INCLUDE(LLAddBuildTest) diff --git a/indra/llinventory/llinventory.cpp b/indra/llinventory/llinventory.cpp index 082d8b2f9f..075abf9536 100644 --- a/indra/llinventory/llinventory.cpp +++ b/indra/llinventory/llinventory.cpp @@ -918,7 +918,7 @@ void LLInventoryItem::asLLSD( LLSD& sd ) const } //sd[INV_FLAGS_LABEL] = (S32)mFlags; sd[INV_FLAGS_LABEL] = ll_sd_from_U32(mFlags); - sd[INV_SALE_INFO_LABEL] = mSaleInfo; + sd[INV_SALE_INFO_LABEL] = mSaleInfo.asLLSD(); sd[INV_NAME_LABEL] = mName; sd[INV_DESC_LABEL] = mDescription; sd[INV_CREATION_DATE_LABEL] = (S32) mCreationDate; diff --git a/indra/llinventory/llsaleinfo.cpp b/indra/llinventory/llsaleinfo.cpp index 98836b178e..35bbc1dbb1 100644 --- a/indra/llinventory/llsaleinfo.cpp +++ b/indra/llinventory/llsaleinfo.cpp @@ -89,8 +89,14 @@ bool LLSaleInfo::exportLegacyStream(std::ostream& output_stream) const LLSD LLSaleInfo::asLLSD() const { - LLSD sd = LLSD(); - sd["sale_type"] = lookup(mSaleType); + LLSD sd; + const char* type = lookup(mSaleType); + if (!type) + { + LL_WARNS_ONCE() << "Unknown sale type: " << mSaleType << LL_ENDL; + type = lookup(LLSaleInfo::FS_NOT); + } + sd["sale_type"] = type; sd["sale_price"] = mSalePrice; return sd; } diff --git a/indra/llinventory/llsettingsbase.cpp b/indra/llinventory/llsettingsbase.cpp index 0ee71de3a1..97979d64e3 100644 --- a/indra/llinventory/llsettingsbase.cpp +++ b/indra/llinventory/llsettingsbase.cpp @@ -130,17 +130,6 @@ void LLSettingsBase::saveValuesIfNeeded() } //========================================================================= -void LLSettingsBase::lerpSettings(LLSettingsBase &other, F64 mix) -{ - LL_PROFILE_ZONE_SCOPED_CATEGORY_ENVIRONMENT; - saveValuesIfNeeded(); - stringset_t skip = getSkipInterpolateKeys(); - stringset_t slerps = getSlerpKeys(); - mSettings = interpolateSDMap(mSettings, other.getSettings(), other.getParameterMap(), mix, skip, slerps); - setDirtyFlag(true); - loadValuesFromLLSD(); -} - void LLSettingsBase::lerpVector2(LLVector2& a, const LLVector2& b, F32 mix) { a.mV[0] = lerp(a.mV[0], b.mV[0], mix); @@ -472,6 +461,7 @@ bool LLSettingsBase::validate() LLSD LLSettingsBase::settingValidation(LLSD &settings, validation_list_t &validations, bool partial) { + using boost::placeholders::_1, boost::placeholders::_2; static Validator validateName(SETTING_NAME, false, LLSD::TypeString, boost::bind(&Validator::verifyStringLength, _1, _2, 63)); static Validator validateId(SETTING_ID, false, LLSD::TypeUUID); static Validator validateHash(SETTING_HASH, false, LLSD::TypeInteger); diff --git a/indra/llinventory/llsettingsbase.h b/indra/llinventory/llsettingsbase.h index 816ff3e111..7de71588ef 100644 --- a/indra/llinventory/llsettingsbase.h +++ b/indra/llinventory/llsettingsbase.h @@ -348,13 +348,8 @@ protected: LLSettingsBase(); LLSettingsBase(const LLSD setting); - static LLSD settingValidation(LLSD settings); - typedef std::set<std::string> stringset_t; - // combining settings objects. Customize for specific setting types - virtual void lerpSettings(LLSettingsBase &other, BlendFactor mix); - // combining settings maps where it can based on mix rate // @settings initial value (mix==0) // @other target value (mix==1) diff --git a/indra/llinventory/llsettingssky.cpp b/indra/llinventory/llsettingssky.cpp index 50b458de14..e8ecc94b4b 100644 --- a/indra/llinventory/llsettingssky.cpp +++ b/indra/llinventory/llsettingssky.cpp @@ -137,7 +137,8 @@ const std::string LLSettingsSky::SETTING_REFLECTION_PROBE_AMBIANCE("reflection_p const LLUUID LLSettingsSky::DEFAULT_ASSET_ID("651510b8-5f4d-8991-1592-e7eeab2a5a06"); -F32 LLSettingsSky::sAutoAdjustProbeAmbiance = 1.f; +const F32 LLSettingsSky::DEFAULT_AUTO_ADJUST_PROBE_AMBIANCE = 1.f; +F32 LLSettingsSky::sAutoAdjustProbeAmbiance = DEFAULT_AUTO_ADJUST_PROBE_AMBIANCE; static const LLUUID DEFAULT_SUN_ID("32bfbcea-24b1-fb9d-1ef9-48a28a63730f"); // dataserver static const LLUUID DEFAULT_MOON_ID("d07f6eed-b96a-47cd-b51d-400ad4a1c428"); // dataserver @@ -150,6 +151,7 @@ const F32 LLSettingsSky::DOME_RADIUS(15000.f); namespace { + using boost::placeholders::_1, boost::placeholders::_2; LLSettingsSky::validation_list_t legacyHazeValidationList() { @@ -2032,43 +2034,43 @@ F32 LLSettingsSky::getGamma() const return mGamma; } -F32 LLSettingsSky::getHDRMin() const +F32 LLSettingsSky::getHDRMin(bool auto_adjust) const { - if (mCanAutoAdjust) + if (mCanAutoAdjust && !auto_adjust) return 0.f; return mHDRMin; } -F32 LLSettingsSky::getHDRMax() const +F32 LLSettingsSky::getHDRMax(bool auto_adjust) const { - if (mCanAutoAdjust) + if (mCanAutoAdjust && !auto_adjust) return 0.f; return mHDRMax; } -F32 LLSettingsSky::getHDROffset() const +F32 LLSettingsSky::getHDROffset(bool auto_adjust) const { - if (mCanAutoAdjust) + if (mCanAutoAdjust && !auto_adjust) return 1.0f; return mHDROffset; } -F32 LLSettingsSky::getTonemapMix() const +F32 LLSettingsSky::getTonemapMix(bool auto_adjust) const { - if (mCanAutoAdjust) + if (mCanAutoAdjust && !auto_adjust) + { + // legacy settings do not support tonemaping return 0.0f; + } return mTonemapMix; } void LLSettingsSky::setTonemapMix(F32 mix) { - if (mCanAutoAdjust) - return; - mTonemapMix = mix; } diff --git a/indra/llinventory/llsettingssky.h b/indra/llinventory/llsettingssky.h index 4c635fd946..ff75aea549 100644 --- a/indra/llinventory/llsettingssky.h +++ b/indra/llinventory/llsettingssky.h @@ -103,6 +103,7 @@ public: static const LLUUID DEFAULT_ASSET_ID; + static const F32 DEFAULT_AUTO_ADJUST_PROBE_AMBIANCE; static F32 sAutoAdjustProbeAmbiance; typedef PTR_NAMESPACE::shared_ptr<LLSettingsSky> ptr_t; @@ -209,10 +210,10 @@ public: F32 getGamma() const; - F32 getHDRMin() const; - F32 getHDRMax() const; - F32 getHDROffset() const; - F32 getTonemapMix() const; + F32 getHDRMin(bool auto_adjust = false) const; + F32 getHDRMax(bool auto_adjust = false) const; + F32 getHDROffset(bool auto_adjust = false) const; + F32 getTonemapMix(bool auto_adjust = false) const; void setTonemapMix(F32 mix); void setGamma(F32 val); diff --git a/indra/llinventory/llsettingswater.cpp b/indra/llinventory/llsettingswater.cpp index b5d59dc497..b8946dbdba 100644 --- a/indra/llinventory/llsettingswater.cpp +++ b/indra/llinventory/llsettingswater.cpp @@ -318,6 +318,7 @@ LLSettingsWater::validation_list_t LLSettingsWater::validationList() if (validation.empty()) { + using boost::placeholders::_1, boost::placeholders::_2; validation.push_back(Validator(SETTING_BLUR_MULTIPLIER, true, LLSD::TypeReal, boost::bind(&Validator::verifyFloatRange, _1, _2, llsd::array(-0.5f, 0.5f)))); validation.push_back(Validator(SETTING_FOG_COLOR, true, LLSD::TypeArray, diff --git a/indra/llkdu/llimagej2ckdu.cpp b/indra/llkdu/llimagej2ckdu.cpp index bf7cfbe071..0d1f2b3006 100644 --- a/indra/llkdu/llimagej2ckdu.cpp +++ b/indra/llkdu/llimagej2ckdu.cpp @@ -279,103 +279,118 @@ void LLImageJ2CKDU::setupCodeStream(LLImageJ2C &base, bool keep_codestream, ECod { LLImageDataLock lock(&base); - S32 data_size = base.getDataSize(); - S32 max_bytes = (base.getMaxBytes() ? base.getMaxBytes() : data_size); + try + { - // - // Initialization - // - mCodeStreamp.reset(); + S32 data_size = base.getDataSize(); + S32 max_bytes = (base.getMaxBytes() ? base.getMaxBytes() : data_size); - // It's not clear to nat under what circumstances we would reuse a - // pre-existing LLKDUMemSource instance. As of 2016-08-05, it consists of - // two U32s and a pointer, so it's not as if it would be a huge overhead - // to allocate a new one every time. - // Also -- why is base.getData() tested specifically here? If that returns - // NULL, shouldn't we bail out of the whole method? - if (!mInputp && base.getData()) - { - // The compressed data has been loaded - // Setup the source for the codestream - mInputp.reset(new LLKDUMemSource(base.getData(), data_size)); - } + // + // Initialization + // + mCodeStreamp.reset(); - if (mInputp) - { - // This is LLKDUMemSource::reset(), not boost::scoped_ptr::reset(). - mInputp->reset(); - } + // It's not clear to nat under what circumstances we would reuse a + // pre-existing LLKDUMemSource instance. As of 2016-08-05, it consists of + // two U32s and a pointer, so it's not as if it would be a huge overhead + // to allocate a new one every time. + // Also -- why is base.getData() tested specifically here? If that returns + // NULL, shouldn't we bail out of the whole method? + if (!mInputp && base.getData()) + { + // The compressed data has been loaded + // Setup the source for the codestream + mInputp.reset(new LLKDUMemSource(base.getData(), data_size)); + } - mCodeStreamp->create(mInputp.get()); - - // Set the maximum number of bytes to use from the codestream - // *TODO: This seems to be wrong. The base class should have no idea of - // how j2c compression works so no good way of computing what's the byte - // range to be used. - mCodeStreamp->set_max_bytes(max_bytes,true); - - // If you want to flip or rotate the image for some reason, change - // the resolution, or identify a restricted region of interest, this is - // the place to do it. You may use "kdu_codestream::change_appearance" - // and "kdu_codestream::apply_input_restrictions" for this purpose. - // If you wish to truncate the code-stream prior to decompression, you - // may use "kdu_codestream::set_max_bytes". - // If you wish to retain all compressed data so that the material - // can be decompressed multiple times, possibly with different appearance - // parameters, you should call "kdu_codestream::set_persistent" here. - // There are a variety of other features which must be enabled at - // this point if you want to take advantage of them. See the - // descriptions appearing with the "kdu_codestream" interface functions - // in "kdu_compressed.h" for an itemized account of these capabilities. - - switch (mode) - { - case MODE_FAST: - mCodeStreamp->set_fast(); - break; - case MODE_RESILIENT: - mCodeStreamp->set_resilient(); - break; - case MODE_FUSSY: - mCodeStreamp->set_fussy(); - break; - default: - llassert(0); - mCodeStreamp->set_fast(); - } + if (mInputp) + { + // This is LLKDUMemSource::reset(), not boost::scoped_ptr::reset(). + mInputp->reset(); + } - kdu_dims dims; - mCodeStreamp->get_dims(0,dims); + mCodeStreamp->create(mInputp.get()); + + // Set the maximum number of bytes to use from the codestream + // *TODO: This seems to be wrong. The base class should have no idea of + // how j2c compression works so no good way of computing what's the byte + // range to be used. + mCodeStreamp->set_max_bytes(max_bytes, true); + + // If you want to flip or rotate the image for some reason, change + // the resolution, or identify a restricted region of interest, this is + // the place to do it. You may use "kdu_codestream::change_appearance" + // and "kdu_codestream::apply_input_restrictions" for this purpose. + // If you wish to truncate the code-stream prior to decompression, you + // may use "kdu_codestream::set_max_bytes". + // If you wish to retain all compressed data so that the material + // can be decompressed multiple times, possibly with different appearance + // parameters, you should call "kdu_codestream::set_persistent" here. + // There are a variety of other features which must be enabled at + // this point if you want to take advantage of them. See the + // descriptions appearing with the "kdu_codestream" interface functions + // in "kdu_compressed.h" for an itemized account of these capabilities. + + switch (mode) + { + case MODE_FAST: + mCodeStreamp->set_fast(); + break; + case MODE_RESILIENT: + mCodeStreamp->set_resilient(); + break; + case MODE_FUSSY: + mCodeStreamp->set_fussy(); + break; + default: + llassert(0); + mCodeStreamp->set_fast(); + } + + kdu_dims dims; + mCodeStreamp->get_dims(0, dims); - S32 components = mCodeStreamp->get_num_components(); + S32 components = mCodeStreamp->get_num_components(); - // Check that components have consistent dimensions (for PPM file) - for (int idx = 1; idx < components; ++idx) - { - kdu_dims other_dims; - mCodeStreamp->get_dims(idx, other_dims); - if (other_dims != dims) + // Check that components have consistent dimensions (for PPM file) + for (int idx = 1; idx < components; ++idx) { - // This method is only called from methods that catch KDUError. - // We want to fail the image load, not crash the viewer. - LLTHROW(KDUError(STRINGIZE("Component " << idx << " dimensions " - << stringize(other_dims) - << " do not match component 0 dimensions " - << stringize(dims) << "!"))); + kdu_dims other_dims; + mCodeStreamp->get_dims(idx, other_dims); + if (other_dims != dims) + { + // This method is only called from methods that catch KDUError. + // We want to fail the image load, not crash the viewer. + LLTHROW(KDUError(STRINGIZE("Component " << idx << " dimensions " + << stringize(other_dims) + << " do not match component 0 dimensions " + << stringize(dims) << "!"))); + } } - } - // Get the number of resolution levels in that image - mLevels = mCodeStreamp->get_min_dwt_levels(); + // Get the number of resolution levels in that image + mLevels = mCodeStreamp->get_min_dwt_levels(); - // Set the base dimensions - base.setSize(dims.size.x, dims.size.y, components); - base.setLevels(mLevels); + // Set the base dimensions + base.setSize(dims.size.x, dims.size.y, components); + base.setLevels(mLevels); - if (!keep_codestream) + if (!keep_codestream) + { + mCodeStreamp.reset(); + mInputp.reset(); + } + } + catch (std::bad_alloc&) { - mCodeStreamp.reset(); - mInputp.reset(); + // we are in a thread, can't show an 'out of memory' here, + // main thread will keep going + throw; + } + catch (...) + { + LLTHROW(KDUError(STRINGIZE("Unknown J2C error : " + + boost::current_exception_diagnostic_information() << "!"))); } } diff --git a/indra/llmath/CMakeLists.txt b/indra/llmath/CMakeLists.txt index eb29df245a..c0a62ad225 100644 --- a/indra/llmath/CMakeLists.txt +++ b/indra/llmath/CMakeLists.txt @@ -59,6 +59,7 @@ set(llmath_HEADER_FILES llmath.h llmatrix3a.h llmatrix3a.inl + llmatrix4a.h llmodularmath.h lloctree.h llperlin.h @@ -97,11 +98,20 @@ set(llmath_HEADER_FILES list(APPEND llmath_SOURCE_FILES ${llmath_HEADER_FILES}) +include_directories(${LIBS_PREBUILT_DIR}/include) + add_library (llmath ${llmath_SOURCE_FILES}) target_link_libraries(llmath llcommon llmeshoptimizer) target_include_directories( llmath INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}) +if (USESYSTEMLIBS AND CMAKE_CXX_COMPILER_ID MATCHES "GNU") + set_source_files_properties(llcalc.cpp PROPERTIES + COMPILE_FLAGS -Wno-dangling-pointer) +endif () + +include(LibraryInstall) + # Add tests if (LL_TESTS) include(LLAddBuildTest) diff --git a/indra/llmath/llcalcparser.h b/indra/llmath/llcalcparser.h index ea71752ebc..ec7f6a2cb6 100644 --- a/indra/llmath/llcalcparser.h +++ b/indra/llmath/llcalcparser.h @@ -131,14 +131,14 @@ struct LLCalcParser : grammar<LLCalcParser> power = unary_expr[power.value = arg1] >> - *('^' >> assert_syntax(unary_expr[power.value = phoenix::bind(&powf)(power.value, arg1)])) + *('^' >> assert_syntax(unary_expr[power.value = phoenix::bind(&LLCalcParser::_pow)(self, power.value, arg1)])) ; term = power[term.value = arg1] >> *(('*' >> assert_syntax(power[term.value *= arg1])) | ('/' >> assert_syntax(power[term.value /= arg1])) | - ('%' >> assert_syntax(power[term.value = phoenix::bind(&fmodf)(term.value, arg1)])) + ('%' >> assert_syntax(power[term.value = phoenix::bind(&LLCalcParser::_fmod)(self, term.value, arg1)])) ) ; @@ -177,6 +177,8 @@ private: F32 _floor(const F32& a) const { return (F32)llfloor(a); } F32 _ceil(const F32& a) const { return (F32)llceil(a); } F32 _atan2(const F32& a,const F32& b) const { return atan2(a,b); } + F32 _pow(const F32& a, const F32& b) const { return powf(a, b); } + F32 _fmod(const F32&a, const F32& b) const { return fmodf(a, b); } LLCalc::calc_map_t* mConstants; LLCalc::calc_map_t* mVariables; diff --git a/indra/llmath/llmath.h b/indra/llmath/llmath.h index fa315291a3..a72993a21a 100644 --- a/indra/llmath/llmath.h +++ b/indra/llmath/llmath.h @@ -358,10 +358,14 @@ inline F32 snap_to_sig_figs(F32 foo, S32 sig_figs) return new_foo; } +#ifdef __GNUC__ +using std::lerp; +#else inline F32 lerp(F32 a, F32 b, F32 u) { return a + ((b - a) * u); } +#endif inline F32 lerp2d(F32 x00, F32 x01, F32 x10, F32 x11, F32 u, F32 v) { diff --git a/indra/llmath/llmatrix3a.cpp b/indra/llmath/llmatrix3a.cpp index 48a72e71e1..c0b00201cf 100644 --- a/indra/llmath/llmatrix3a.cpp +++ b/indra/llmath/llmatrix3a.cpp @@ -24,6 +24,8 @@ * $/LicenseInfo$ */ +#include "linden_common.h" + #include "llmath.h" static LL_ALIGN_16(const F32 M_IDENT_3A[12]) = diff --git a/indra/llmath/llmatrix4a.cpp b/indra/llmath/llmatrix4a.cpp index 00e30a248b..bfb4c2b07a 100644 --- a/indra/llmath/llmatrix4a.cpp +++ b/indra/llmath/llmatrix4a.cpp @@ -24,6 +24,8 @@ * $/LicenseInfo$ */ +#include "linden_common.h" + #include "llmath.h" #include "llmatrix4a.h" diff --git a/indra/llmath/llrigginginfo.cpp b/indra/llmath/llrigginginfo.cpp index 23dbddd78e..2f59f685d5 100644 --- a/indra/llmath/llrigginginfo.cpp +++ b/indra/llmath/llrigginginfo.cpp @@ -24,6 +24,8 @@ * $/LicenseInfo$ */ +#include "linden_common.h" + #include "llmath.h" #include "llrigginginfo.h" diff --git a/indra/llmath/llsimdmath.h b/indra/llmath/llsimdmath.h index 40953dc2e8..590d8de92f 100644 --- a/indra/llmath/llsimdmath.h +++ b/indra/llmath/llsimdmath.h @@ -31,7 +31,7 @@ #error "Please include llmath.h before this file." #endif -#if ( ( LL_DARWIN || LL_LINUX ) && !(__SSE2__) ) || ( LL_WINDOWS && ( _M_IX86_FP < 2 && ADDRESS_SIZE == 32 ) ) +#if ( ( LL_DARWIN || LL_LINUX ) && !(__SSE2__ || __ARM_NEON) ) || ( LL_WINDOWS && ( _M_IX86_FP < 2 && ADDRESS_SIZE == 32 ) ) #error SSE2 not enabled. LLVector4a and related class will not compile. #endif @@ -39,8 +39,12 @@ #include <stdint.h> #endif +#if defined(__i386__) || defined(__x86_64__) #include <xmmintrin.h> #include <emmintrin.h> +#else +#include <sse2neon.h> +#endif #include "llmemory.h" #include "llsimdtypes.h" diff --git a/indra/llmath/llvector4a.cpp b/indra/llmath/llvector4a.cpp index 0ac91366b6..b81d50f0f9 100644 --- a/indra/llmath/llvector4a.cpp +++ b/indra/llmath/llvector4a.cpp @@ -24,6 +24,8 @@ * $/LicenseInfo$ */ +#include "linden_common.h" + #include "llmemory.h" #include "llmath.h" #include "llquantize.h" diff --git a/indra/llmath/llvector4a.h b/indra/llmath/llvector4a.h index 8ef560dadf..4004852e06 100644 --- a/indra/llmath/llvector4a.h +++ b/indra/llmath/llvector4a.h @@ -33,6 +33,9 @@ class LLRotation; #include <assert.h> #include "llpreprocessor.h" #include "llmemory.h" +#include "glm/vec3.hpp" +#include "glm/vec4.hpp" +#include "glm/gtc/type_ptr.hpp" /////////////////////////////////// // FIRST TIME USERS PLEASE READ @@ -364,6 +367,16 @@ public: inline operator LLQuad() const; + explicit inline operator glm::vec3() const + { + return glm::make_vec3(getF32ptr()); + }; + + explicit inline operator glm::vec4() const + { + return glm::make_vec4(getF32ptr()); + }; + private: LLQuad mQ{}; }; diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index 44b6e7923b..6335da5b62 100644 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -55,7 +55,11 @@ #include "mikktspace/mikktspace.hh" +#if LL_USESYSTEMLIBS +#include <meshoptimizer.h> +#else #include "meshoptimizer/meshoptimizer.h" +#endif #define DEBUG_SILHOUETTE_BINORMALS 0 #define DEBUG_SILHOUETTE_NORMALS 0 // TomY: Use this to display normals using the silhouette @@ -5586,14 +5590,22 @@ struct MikktData { U32 count = face->mNumIndices; - p.resize(count); - n.resize(count); - tc.resize(count); - t.resize(count); + try + { + p.resize(count); + n.resize(count); + tc.resize(count); + t.resize(count); - if (face->mWeights) + if (face->mWeights) + { + w.resize(count); + } + } + catch (std::bad_alloc&) { - w.resize(count); + LLError::LLUserWarningMsg::showOutOfMemory(); + LL_ERRS("LLCoros") << "Bad memory allocation in MikktData, elements count: " << count << LL_ENDL; } @@ -5665,7 +5677,16 @@ bool LLVolumeFace::cacheOptimize(bool gen_tangents) // and is executed on a background thread MikktData data(this); mikk::Mikktspace ctx(data); - ctx.genTangSpace(); + try + { + ctx.genTangSpace(); + } + catch (std::bad_alloc&) + { + LLError::LLUserWarningMsg::showOutOfMemory(); + LL_ERRS("LLCoros") << "Bad memory allocation in MikktData::genTangSpace" << LL_ENDL; + } + //re-weld meshopt_Stream mos[] = @@ -5678,7 +5699,15 @@ bool LLVolumeFace::cacheOptimize(bool gen_tangents) }; std::vector<U32> remap; - remap.resize(data.p.size()); + try + { + remap.resize(data.p.size()); + } + catch (std::bad_alloc&) + { + LLError::LLUserWarningMsg::showOutOfMemory(); + LL_ERRS("LLCoros") << "Failed to allocate memory for remap: " << (S32)data.p.size() << LL_ENDL; + } U32 stream_count = data.w.empty() ? 4 : 5; diff --git a/indra/llmath/llvolumeoctree.cpp b/indra/llmath/llvolumeoctree.cpp index 71288daa89..141317ee8d 100644 --- a/indra/llmath/llvolumeoctree.cpp +++ b/indra/llmath/llvolumeoctree.cpp @@ -24,6 +24,8 @@ * $/LicenseInfo$ */ +#include "linden_common.h" + #include "llvolumeoctree.h" #include "llvector4a.h" diff --git a/indra/llmath/v3colorutil.h b/indra/llmath/v3colorutil.h index 62005f76a0..af8799e42a 100644 --- a/indra/llmath/v3colorutil.h +++ b/indra/llmath/v3colorutil.h @@ -28,6 +28,7 @@ #define LL_V3COLORUTIL_H #include "v3color.h" +#include "v4color.h" inline LLColor3 componentDiv(LLColor3 const &left, LLColor3 const & right) { diff --git a/indra/llmath/v3math.h b/indra/llmath/v3math.h index d063b15c74..a3bfa68060 100644 --- a/indra/llmath/v3math.h +++ b/indra/llmath/v3math.h @@ -31,6 +31,11 @@ #include "llmath.h" #include "llsd.h" + +#include "glm/vec3.hpp" +#include "glm/vec4.hpp" +#include "glm/gtc/type_ptr.hpp" + class LLVector2; class LLVector4; class LLVector4a; @@ -66,6 +71,11 @@ class LLVector3 explicit LLVector3(const LLVector4a& vec); // Initializes LLVector4 to (vec[0]. vec[1], vec[2]) explicit LLVector3(const LLSD& sd); + // GLM interop + explicit LLVector3(const glm::vec3& vec); // Initializes LLVector3 to (vec[0]. vec[1], vec[2]) + explicit LLVector3(const glm::vec4& vec); // Initializes LLVector3 to (vec[0]. vec[1], vec[2]) + explicit inline operator glm::vec3() const; // Initializes glm::vec3 to (vec[0]. vec[1], vec[2]) + explicit inline operator glm::vec4() const; // Initializes glm::vec4 to (vec[0]. vec[1], vec[2], 1) LLSD getValue() const; @@ -92,6 +102,8 @@ class LLVector3 inline void set(const F32 *vec); // Sets LLVector3 to vec const LLVector3& set(const LLVector4 &vec); const LLVector3& set(const LLVector3d &vec);// Sets LLVector3 to vec + inline void set(const glm::vec4& vec); // Sets LLVector3 to vec + inline void set(const glm::vec3& vec); // Sets LLVector3 to vec inline void setVec(F32 x, F32 y, F32 z); // deprecated inline void setVec(const LLVector3 &vec); // deprecated @@ -190,6 +202,20 @@ inline LLVector3::LLVector3(const F32 *vec) mV[VZ] = vec[VZ]; } +inline LLVector3::LLVector3(const glm::vec3& vec) +{ + mV[VX] = vec.x; + mV[VY] = vec.y; + mV[VZ] = vec.z; +} + +inline LLVector3::LLVector3(const glm::vec4& vec) +{ + mV[VX] = vec.x; + mV[VY] = vec.y; + mV[VZ] = vec.z; +} + /* inline LLVector3::LLVector3(const LLVector3 ©) { @@ -259,6 +285,20 @@ inline void LLVector3::set(const F32 *vec) mV[2] = vec[2]; } +inline void LLVector3::set(const glm::vec4& vec) +{ + mV[VX] = vec.x; + mV[VY] = vec.y; + mV[VZ] = vec.z; +} + +inline void LLVector3::set(const glm::vec3& vec) +{ + mV[VX] = vec.x; + mV[VY] = vec.y; + mV[VZ] = vec.z; +} + // deprecated inline void LLVector3::setVec(F32 x, F32 y, F32 z) { @@ -471,6 +511,17 @@ inline LLVector3 operator-(const LLVector3 &a) return LLVector3( -a.mV[0], -a.mV[1], -a.mV[2] ); } +inline LLVector3::operator glm::vec3() const +{ + // Do not use glm::make_vec3 it can result in a buffer overrun on some platforms due to glm::vec3 being a simd vector internally + return glm::vec3(mV[VX], mV[VY], mV[VZ]); +} + +inline LLVector3::operator glm::vec4() const +{ + return glm::vec4(mV[VX], mV[VY], mV[VZ], 1.f); +} + inline F32 dist_vec(const LLVector3 &a, const LLVector3 &b) { F32 x = a.mV[0] - b.mV[0]; diff --git a/indra/llmath/v4math.h b/indra/llmath/v4math.h index a5b6f506d7..a4c9668fdd 100644 --- a/indra/llmath/v4math.h +++ b/indra/llmath/v4math.h @@ -32,6 +32,10 @@ #include "v3math.h" #include "v2math.h" +#include "glm/vec3.hpp" +#include "glm/vec4.hpp" +#include "glm/gtc/type_ptr.hpp" + class LLMatrix3; class LLMatrix4; class LLQuaternion; @@ -73,6 +77,11 @@ class LLVector4 mV[3] = (F32)sd[3].asReal(); } + // GLM interop + explicit LLVector4(const glm::vec3& vec); // Initializes LLVector4 to (vec, 1) + explicit LLVector4(const glm::vec4& vec); // Initializes LLVector4 to vec + explicit operator glm::vec3() const; // Initializes glm::vec3 to (vec[0]. vec[1], vec[2]) + explicit operator glm::vec4() const; // Initializes glm::vec4 to (vec[0]. vec[1], vec[2], vec[3]) inline bool isFinite() const; // checks to see if all values of LLVector3 are finite @@ -85,6 +94,8 @@ class LLVector4 inline void set(const LLVector4 &vec); // Sets LLVector4 to vec inline void set(const LLVector3 &vec, F32 w = 1.f); // Sets LLVector4 to LLVector3 vec inline void set(const F32 *vec); // Sets LLVector4 to vec + inline void set(const glm::vec4& vec); // Sets LLVector4 to vec + inline void set(const glm::vec3& vec, F32 w = 1.f); // Sets LLVector4 to LLVector3 vec with w defaulted to 1 inline void setVec(F32 x, F32 y, F32 z); // deprecated inline void setVec(F32 x, F32 y, F32 z, F32 w); // deprecated @@ -223,6 +234,21 @@ inline LLVector4::LLVector4(const LLSD &sd) setValue(sd); } +inline LLVector4::LLVector4(const glm::vec3& vec) +{ + mV[VX] = vec.x; + mV[VY] = vec.y; + mV[VZ] = vec.z; + mV[VW] = 1.f; +} + +inline LLVector4::LLVector4(const glm::vec4& vec) +{ + mV[VX] = vec.x; + mV[VY] = vec.y; + mV[VZ] = vec.z; + mV[VW] = vec.w; +} inline bool LLVector4::isFinite() const { @@ -297,6 +323,21 @@ inline void LLVector4::set(const F32 *vec) mV[VW] = vec[VW]; } +inline void LLVector4::set(const glm::vec4& vec) +{ + mV[VX] = vec.x; + mV[VY] = vec.y; + mV[VZ] = vec.z; + mV[VW] = vec.w; +} + +inline void LLVector4::set(const glm::vec3& vec, F32 w) +{ + mV[VX] = vec.x; + mV[VY] = vec.y; + mV[VZ] = vec.z; + mV[VW] = w; +} // deprecated inline void LLVector4::setVec(F32 x, F32 y, F32 z) @@ -466,6 +507,16 @@ inline LLVector4 operator-(const LLVector4 &a) return LLVector4( -a.mV[VX], -a.mV[VY], -a.mV[VZ] ); } +inline LLVector4::operator glm::vec3() const +{ + return glm::vec3(mV[VX], mV[VY], mV[VZ]); +} + +inline LLVector4::operator glm::vec4() const +{ + return glm::make_vec4(mV); +} + inline F32 dist_vec(const LLVector4 &a, const LLVector4 &b) { LLVector4 vec = a - b; diff --git a/indra/llmeshoptimizer/CMakeLists.txt b/indra/llmeshoptimizer/CMakeLists.txt index dfac44c296..100e4448cb 100644 --- a/indra/llmeshoptimizer/CMakeLists.txt +++ b/indra/llmeshoptimizer/CMakeLists.txt @@ -25,10 +25,12 @@ list(APPEND llmeshoptimizer_SOURCE_FILES ${llmeshoptimizer_HEADER_FILES}) add_library (llmeshoptimizer ${llmeshoptimizer_SOURCE_FILES}) target_include_directories( llmeshoptimizer INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}) +include_directories(${CMAKE_SOURCE_DIR}/llmath) target_link_libraries(llmeshoptimizer llcommon - llmath ll::meshoptimizer) +include(LibraryInstall) + # Add tests diff --git a/indra/llmessage/CMakeLists.txt b/indra/llmessage/CMakeLists.txt index b2757a7306..5ca62352a3 100644 --- a/indra/llmessage/CMakeLists.txt +++ b/indra/llmessage/CMakeLists.txt @@ -3,12 +3,14 @@ project(llmessage) include(00-Common) +if (LL_TESTS) include(LLAddBuildTest) +endif () include(LLCommon) include(LLCoreHttp) +if (LL_TESTS) include(LLAddBuildTest) -include(Python) -include(Tut) +endif () include(Python) set(llmessage_SOURCE_FILES @@ -128,6 +130,7 @@ set(llmessage_HEADER_FILES llmessagebuilder.h llmessageconfig.h llmessagereader.h + llmessagesenderinterface.h llmessagetemplate.h llmessagetemplateparser.h llmessagethrottle.h @@ -194,6 +197,15 @@ target_link_libraries( ) target_include_directories( llmessage INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}) +if (NOT (USE_AUTOBUILD_3P OR USE_CONAN)) + if (CMAKE_CXX_COMPILER_ID MATCHES "GNU") + set_source_files_properties(llnamevalue.cpp PROPERTIES + COMPILE_FLAGS -Wno-stringop-truncation) + endif() +endif () + +include(LibraryInstall) + # tests if (LL_TESTS) SET(llmessage_TEST_SOURCE_FILES diff --git a/indra/llmessage/llassetstorage.cpp b/indra/llmessage/llassetstorage.cpp index 2de59c1b6a..10fd56a68e 100644 --- a/indra/llmessage/llassetstorage.cpp +++ b/indra/llmessage/llassetstorage.cpp @@ -585,7 +585,8 @@ void LLAssetStorage::getAssetData(const LLUUID uuid, // static void LLAssetStorage::removeAndCallbackPendingDownloads(const LLUUID& file_id, LLAssetType::EType file_type, const LLUUID& callback_id, LLAssetType::EType callback_type, - S32 result_code, LLExtStat ext_status) + S32 result_code, LLExtStat ext_status, + S32 bytes_fetched) { // find and callback ALL pending requests for this UUID // SJB: We process the callbacks in reverse order, I do not know if this is important, @@ -598,6 +599,10 @@ void LLAssetStorage::removeAndCallbackPendingDownloads(const LLUUID& file_id, LL LLAssetRequest* tmp = *curiter; if ((tmp->getUUID() == file_id) && (tmp->getType()== file_type)) { + if (bytes_fetched > 0) + { + tmp->mBytesFetched = bytes_fetched; + } requests.push_front(tmp); iter = gAssetStorage->mPendingDownloads.erase(curiter); } @@ -664,6 +669,7 @@ void LLAssetStorage::downloadCompleteCallback( callback_type = req->getType(); } + S32 bytes_fetched = 0; if (LL_ERR_NOERR == result) { // we might have gotten a zero-size file @@ -677,21 +683,11 @@ void LLAssetStorage::downloadCompleteCallback( } else { -#if 1 - for (request_list_t::iterator iter = gAssetStorage->mPendingDownloads.begin(); - iter != gAssetStorage->mPendingDownloads.end(); ++iter ) - { - LLAssetRequest* dlreq = *iter; - if ((dlreq->getUUID() == file_id) && (dlreq->getType()== file_type)) - { - dlreq->mBytesFetched = vfile.getSize(); - } - } -#endif + bytes_fetched = vfile.getSize(); } } - removeAndCallbackPendingDownloads(file_id, file_type, callback_id, callback_type, result, ext_status); + removeAndCallbackPendingDownloads(file_id, file_type, callback_id, callback_type, result, ext_status, bytes_fetched); } void LLAssetStorage::getEstateAsset( diff --git a/indra/llmessage/llassetstorage.h b/indra/llmessage/llassetstorage.h index 88fa572092..6d6526757d 100644 --- a/indra/llmessage/llassetstorage.h +++ b/indra/llmessage/llassetstorage.h @@ -324,7 +324,8 @@ public: static void removeAndCallbackPendingDownloads(const LLUUID& file_id, LLAssetType::EType file_type, const LLUUID& callback_id, LLAssetType::EType callback_type, - S32 result_code, LLExtStat ext_status); + S32 result_code, LLExtStat ext_status, + S32 bytes_fetched); // download process callbacks static void downloadCompleteCallback( diff --git a/indra/llmessage/llcoproceduremanager.cpp b/indra/llmessage/llcoproceduremanager.cpp index 263670bdac..6a663a8e97 100644 --- a/indra/llmessage/llcoproceduremanager.cpp +++ b/indra/llmessage/llcoproceduremanager.cpp @@ -301,12 +301,12 @@ LLCoprocedurePool::LLCoprocedurePool(const std::string &poolName, size_t size): mPoolSize(size), mActiveCoprocsCount(0), mPending(0), - mPendingCoprocs(std::make_shared<CoprocQueue_t>(LLCoprocedureManager::DEFAULT_QUEUE_SIZE)), mHTTPPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID), mCoroMapping() { try { + mPendingCoprocs = std::make_shared<CoprocQueue_t>(LLCoprocedureManager::DEFAULT_QUEUE_SIZE); // store in our LLTempBoundListener so that when the LLCoprocedurePool is // destroyed, we implicitly disconnect from this LLEventPump // Monitores application status @@ -339,6 +339,11 @@ LLCoprocedurePool::LLCoprocedurePool(const std::string &poolName, size_t size): llassert(0); // Fix Me! Ignoring missing listener! } + catch (std::bad_alloc&) + { + LLError::LLUserWarningMsg::showOutOfMemory(); + LL_ERRS("CoProcMgr") << "Bad memory allocation in LLCoprocedurePool::LLCoprocedurePool!" << LL_ENDL; + } for (size_t count = 0; count < mPoolSize; ++count) { diff --git a/indra/llmessage/llcorehttputil.cpp b/indra/llmessage/llcorehttputil.cpp index 918a69be6f..992e145758 100644 --- a/indra/llmessage/llcorehttputil.cpp +++ b/indra/llmessage/llcorehttputil.cpp @@ -295,7 +295,15 @@ void HttpCoroHandler::onCompleted(LLCore::HttpHandle handle, LLCore::HttpRespons } else { - result = this->handleSuccess(response, status); + try + { + result = this->handleSuccess(response, status); + } + catch (std::bad_alloc&) + { + LLError::LLUserWarningMsg::showOutOfMemory(); + LL_ERRS("CoreHTTP") << "Failed to allocate memory for response handling." << LL_ENDL; + } } buildStatusEntry(response, status, result); diff --git a/indra/llmessage/llexperiencecache.cpp b/indra/llmessage/llexperiencecache.cpp index b5d0c93376..83a070df32 100644 --- a/indra/llmessage/llexperiencecache.cpp +++ b/indra/llmessage/llexperiencecache.cpp @@ -94,6 +94,8 @@ LLExperienceCache::LLExperienceCache() LLExperienceCache::~LLExperienceCache() { + // can exit without cleanup() + sShutdown = true; } void LLExperienceCache::initSingleton() diff --git a/indra/llmessage/llnamevalue.cpp b/indra/llmessage/llnamevalue.cpp index 853ae7df82..05ea3f26a1 100644 --- a/indra/llmessage/llnamevalue.cpp +++ b/indra/llmessage/llnamevalue.cpp @@ -967,4 +967,3 @@ std::ostream& operator<<(std::ostream& s, const LLNameValue &a) } return s; } - diff --git a/indra/llmessage/llpacketbuffer.cpp b/indra/llmessage/llpacketbuffer.cpp index dc5c7a73cb..0b04a560be 100644 --- a/indra/llmessage/llpacketbuffer.cpp +++ b/indra/llmessage/llpacketbuffer.cpp @@ -32,8 +32,6 @@ #include "lltimer.h" #include "llhost.h" -/////////////////////////////////////////////////////////// - LLPacketBuffer::LLPacketBuffer(const LLHost &host, const char *datap, const S32 size) : mHost(host) { mSize = 0; @@ -41,7 +39,7 @@ LLPacketBuffer::LLPacketBuffer(const LLHost &host, const char *datap, const S32 if (size > NET_BUFFER_SIZE) { - LL_ERRS() << "Sending packet > " << NET_BUFFER_SIZE << " of size " << size << LL_ENDL; + LL_ERRS() << "Constructing packet with size=" << size << " > " << NET_BUFFER_SIZE << LL_ENDL; } else { @@ -51,7 +49,6 @@ LLPacketBuffer::LLPacketBuffer(const LLHost &host, const char *datap, const S32 mSize = size; } } - } LLPacketBuffer::LLPacketBuffer (S32 hSocket) @@ -59,18 +56,29 @@ LLPacketBuffer::LLPacketBuffer (S32 hSocket) init(hSocket); } -/////////////////////////////////////////////////////////// - LLPacketBuffer::~LLPacketBuffer () { } -/////////////////////////////////////////////////////////// - -void LLPacketBuffer::init (S32 hSocket) +void LLPacketBuffer::init(S32 hSocket) { mSize = receive_packet(hSocket, mData); mHost = ::get_sender(); mReceivingIF = ::get_receiving_interface(); } +void LLPacketBuffer::init(const char* buffer, S32 data_size, const LLHost& host) +{ + if (data_size > NET_BUFFER_SIZE) + { + LL_ERRS() << "Initializing packet with size=" << data_size << " > " << NET_BUFFER_SIZE << LL_ENDL; + } + else + { + memcpy(mData, buffer, data_size); + mSize = data_size; + mHost = host; + mReceivingIF = ::get_receiving_interface(); + } +} + diff --git a/indra/llmessage/llpacketbuffer.h b/indra/llmessage/llpacketbuffer.h index a2d2973fb0..ac4012d330 100644 --- a/indra/llmessage/llpacketbuffer.h +++ b/indra/llmessage/llpacketbuffer.h @@ -35,20 +35,22 @@ class LLPacketBuffer { public: LLPacketBuffer(const LLHost &host, const char *datap, const S32 size); - LLPacketBuffer(S32 hSocket); // receive a packet + LLPacketBuffer(S32 hSocket); // receive a packet ~LLPacketBuffer(); S32 getSize() const { return mSize; } const char *getData() const { return mData; } LLHost getHost() const { return mHost; } LLHost getReceivingInterface() const { return mReceivingIF; } + void init(S32 hSocket); + void init(const char* buffer, S32 data_size, const LLHost& host); protected: - char mData[NET_BUFFER_SIZE]; // packet data /* Flawfinder : ignore */ - S32 mSize; // size of buffer in bytes - LLHost mHost; // source/dest IP and port - LLHost mReceivingIF; // source/dest IP and port + char mData[NET_BUFFER_SIZE]; // packet data /* Flawfinder : ignore */ + S32 mSize; // size of buffer in bytes + LLHost mHost; // source/dest IP and port + LLHost mReceivingIF; // source/dest IP and port }; #endif diff --git a/indra/llmessage/llpacketring.cpp b/indra/llmessage/llpacketring.cpp index be838770a8..eb6650c6c5 100644 --- a/indra/llmessage/llpacketring.cpp +++ b/indra/llmessage/llpacketring.cpp @@ -1,6 +1,6 @@ /** * @file llpacketring.cpp - * @brief implementation of LLPacketRing class for a packet. + * @brief implementation of LLPacketRing class. * * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code @@ -43,329 +43,323 @@ #include "message.h" #include "u64.h" -/////////////////////////////////////////////////////////// -LLPacketRing::LLPacketRing () : - mUseInThrottle(false), - mUseOutThrottle(false), - mInThrottle(256000.f), - mOutThrottle(64000.f), - mActualBitsIn(0), - mActualBitsOut(0), - mMaxBufferLength(64000), - mInBufferLength(0), - mOutBufferLength(0), - mDropPercentage(0.0f), - mPacketsToDrop(0x0) +constexpr S16 MAX_BUFFER_RING_SIZE = 1024; +constexpr S16 DEFAULT_BUFFER_RING_SIZE = 256; + +LLPacketRing::LLPacketRing () + : mPacketRing(DEFAULT_BUFFER_RING_SIZE, nullptr) { + LLHost invalid_host; + for (size_t i = 0; i < mPacketRing.size(); ++i) + { + mPacketRing[i] = new LLPacketBuffer(invalid_host, nullptr, 0); + } } -/////////////////////////////////////////////////////////// LLPacketRing::~LLPacketRing () { - cleanup(); + for (auto packet : mPacketRing) + { + delete packet; + } + mPacketRing.clear(); + mNumBufferedPackets = 0; + mNumBufferedBytes = 0; + mHeadIndex = 0; } -/////////////////////////////////////////////////////////// -void LLPacketRing::cleanup () +S32 LLPacketRing::receivePacket (S32 socket, char *datap) { - LLPacketBuffer *packetp; + bool drop = computeDrop(); + return (mNumBufferedPackets > 0) ? + receiveOrDropBufferedPacket(datap, drop) : + receiveOrDropPacket(socket, datap, drop); +} - while (!mReceiveQueue.empty()) +bool send_packet_helper(int socket, const char * datap, S32 data_size, LLHost host) +{ + if (!LLProxy::isSOCKSProxyEnabled()) { - packetp = mReceiveQueue.front(); - delete packetp; - mReceiveQueue.pop(); + return send_packet(socket, datap, data_size, host.getAddress(), host.getPort()); } - while (!mSendQueue.empty()) - { - packetp = mSendQueue.front(); - delete packetp; - mSendQueue.pop(); - } -} + char headered_send_buffer[NET_BUFFER_SIZE + SOCKS_HEADER_SIZE]; -/////////////////////////////////////////////////////////// -void LLPacketRing::dropPackets (U32 num_to_drop) -{ - mPacketsToDrop += num_to_drop; -} + proxywrap_t *socks_header = static_cast<proxywrap_t*>(static_cast<void*>(&headered_send_buffer)); + socks_header->rsv = 0; + socks_header->addr = host.getAddress(); + socks_header->port = htons(host.getPort()); + socks_header->atype = ADDRESS_IPV4; + socks_header->frag = 0; -/////////////////////////////////////////////////////////// -void LLPacketRing::setDropPercentage (F32 percent_to_drop) -{ - mDropPercentage = percent_to_drop; -} + memcpy(headered_send_buffer + SOCKS_HEADER_SIZE, datap, data_size); -void LLPacketRing::setUseInThrottle(const bool use_throttle) -{ - mUseInThrottle = use_throttle; + return send_packet( socket, + headered_send_buffer, + data_size + SOCKS_HEADER_SIZE, + LLProxy::getInstance()->getUDPProxy().getAddress(), + LLProxy::getInstance()->getUDPProxy().getPort()); } -void LLPacketRing::setUseOutThrottle(const bool use_throttle) +bool LLPacketRing::sendPacket(int socket, const char * datap, S32 data_size, LLHost host) { - mUseOutThrottle = use_throttle; + mActualBytesOut += data_size; + return send_packet_helper(socket, datap, data_size, host); } -void LLPacketRing::setInBandwidth(const F32 bps) +void LLPacketRing::dropPackets (U32 num_to_drop) { - mInThrottle.setRate(bps); + mPacketsToDrop += num_to_drop; } -void LLPacketRing::setOutBandwidth(const F32 bps) +void LLPacketRing::setDropPercentage (F32 percent_to_drop) { - mOutThrottle.setRate(bps); + mDropPercentage = percent_to_drop; } -/////////////////////////////////////////////////////////// -S32 LLPacketRing::receiveFromRing (S32 socket, char *datap) -{ - if (mInThrottle.checkOverflow(0)) +bool LLPacketRing::computeDrop() +{ + bool drop= (mDropPercentage > 0.0f && (ll_frand(100.f) < mDropPercentage)); + if (drop) { - // We don't have enough bandwidth, don't give them a packet. - return 0; + ++mPacketsToDrop; } - - LLPacketBuffer *packetp = NULL; - if (mReceiveQueue.empty()) + if (mPacketsToDrop > 0) { - // No packets on the queue, don't give them any. - return 0; + --mPacketsToDrop; + drop = true; } - - S32 packet_size = 0; - packetp = mReceiveQueue.front(); - mReceiveQueue.pop(); - packet_size = packetp->getSize(); - if (packetp->getData() != NULL) - { - memcpy(datap, packetp->getData(), packet_size); /*Flawfinder: ignore*/ - } - // need to set sender IP/port!! - mLastSender = packetp->getHost(); - mLastReceivingIF = packetp->getReceivingInterface(); - delete packetp; - - this->mInBufferLength -= packet_size; - - // Adjust the throttle - mInThrottle.throttleOverflow(packet_size * 8.f); - return packet_size; + return drop; } -/////////////////////////////////////////////////////////// -S32 LLPacketRing::receivePacket (S32 socket, char *datap) +S32 LLPacketRing::receiveOrDropPacket(S32 socket, char *datap, bool drop) { S32 packet_size = 0; - // If using the throttle, simulate a limited size input buffer. - if (mUseInThrottle) + // pull straight from socket + if (LLProxy::isSOCKSProxyEnabled()) { - bool done = false; - - // push any current net packet (if any) onto delay ring - while (!done) + char buffer[NET_BUFFER_SIZE + SOCKS_HEADER_SIZE]; /* Flawfinder ignore */ + packet_size = receive_packet(socket, buffer); + if (packet_size > 0) { - LLPacketBuffer *packetp; - packetp = new LLPacketBuffer(socket); - - if (packetp->getSize()) - { - mActualBitsIn += packetp->getSize() * 8; - - // Fake packet loss - if (mDropPercentage && (ll_frand(100.f) < mDropPercentage)) - { - mPacketsToDrop++; - } - - if (mPacketsToDrop) - { - delete packetp; - packetp = NULL; - packet_size = 0; - mPacketsToDrop--; - } - } + mActualBytesIn += packet_size; + } - // If we faked packet loss, then we don't have a packet - // to use for buffer overflow testing - if (packetp) + if (packet_size > SOCKS_HEADER_SIZE) + { + if (drop) { - if (mInBufferLength + packetp->getSize() > mMaxBufferLength) - { - // Toss it. - LL_WARNS() << "Throwing away packet, overflowing buffer" << LL_ENDL; - delete packetp; - packetp = NULL; - } - else if (packetp->getSize()) - { - mReceiveQueue.push(packetp); - mInBufferLength += packetp->getSize(); - } - else - { - delete packetp; - packetp = NULL; - done = true; - } + packet_size = 0; } else { - // No packetp, keep going? - no packetp == faked packet loss - } - } - - // Now, grab data off of the receive queue according to our - // throttled bandwidth settings. - packet_size = receiveFromRing(socket, datap); - } - else - { - // no delay, pull straight from net - if (LLProxy::isSOCKSProxyEnabled()) - { - U8 buffer[NET_BUFFER_SIZE + SOCKS_HEADER_SIZE]; - packet_size = receive_packet(socket, static_cast<char*>(static_cast<void*>(buffer))); - - if (packet_size > SOCKS_HEADER_SIZE) - { // *FIX We are assuming ATYP is 0x01 (IPv4), not 0x03 (hostname) or 0x04 (IPv6) - memcpy(datap, buffer + SOCKS_HEADER_SIZE, packet_size - SOCKS_HEADER_SIZE); + packet_size -= SOCKS_HEADER_SIZE; // The unwrapped packet size + memcpy(datap, buffer + SOCKS_HEADER_SIZE, packet_size); proxywrap_t * header = static_cast<proxywrap_t*>(static_cast<void*>(buffer)); mLastSender.setAddress(header->addr); mLastSender.setPort(ntohs(header->port)); - - packet_size -= SOCKS_HEADER_SIZE; // The unwrapped packet size - } - else - { - packet_size = 0; + mLastReceivingIF = ::get_receiving_interface(); } } else { - packet_size = receive_packet(socket, datap); - mLastSender = ::get_sender(); + packet_size = 0; } - - mLastReceivingIF = ::get_receiving_interface(); - - if (packet_size) // did we actually get a packet? + } + else + { + packet_size = receive_packet(socket, datap); + if (packet_size > 0) { - if (mDropPercentage && (ll_frand(100.f) < mDropPercentage)) + mActualBytesIn += packet_size; + if (drop) { - mPacketsToDrop++; + packet_size = 0; } - - if (mPacketsToDrop) + else { - packet_size = 0; - mPacketsToDrop--; + mLastSender = ::get_sender(); + mLastReceivingIF = ::get_receiving_interface(); } } } - return packet_size; } -bool LLPacketRing::sendPacket(int h_socket, char * send_buffer, S32 buf_size, LLHost host) +S32 LLPacketRing::receiveOrDropBufferedPacket(char *datap, bool drop) { - bool status = true; - if (!mUseOutThrottle) + assert(mNumBufferedPackets > 0); + S32 packet_size = 0; + + S16 ring_size = (S16)(mPacketRing.size()); + S16 packet_index = (mHeadIndex + ring_size - mNumBufferedPackets) % ring_size; + LLPacketBuffer* packet = mPacketRing[packet_index]; + packet_size = packet->getSize(); + mLastSender = packet->getHost(); + mLastReceivingIF = packet->getReceivingInterface(); + + --mNumBufferedPackets; + mNumBufferedBytes -= packet_size; + if (mNumBufferedPackets == 0) { - return sendPacketImpl(h_socket, send_buffer, buf_size, host ); + assert(mNumBufferedBytes == 0); + } + + if (!drop) + { + assert(packet_size > 0); + memcpy(datap, packet->getData(), packet_size); } else { - mActualBitsOut += buf_size * 8; - LLPacketBuffer *packetp = NULL; - // See if we've got enough throttle to send a packet. - while (!mOutThrottle.checkOverflow(0.f)) - { - // While we have enough bandwidth, send a packet from the queue or the current packet + packet_size = 0; + } + return packet_size; +} + +S32 LLPacketRing::bufferInboundPacket(S32 socket) +{ + if (mNumBufferedPackets == mPacketRing.size() && mNumBufferedPackets < MAX_BUFFER_RING_SIZE) + { + expandRing(); + } - S32 packet_size = 0; - if (!mSendQueue.empty()) + LLPacketBuffer* packet = mPacketRing[mHeadIndex]; + S32 old_packet_size = packet->getSize(); + S32 packet_size = 0; + if (LLProxy::isSOCKSProxyEnabled()) + { + char buffer[NET_BUFFER_SIZE + SOCKS_HEADER_SIZE]; /* Flawfinder ignore */ + packet_size = receive_packet(socket, buffer); + if (packet_size > 0) + { + mActualBytesIn += packet_size; + if (packet_size > SOCKS_HEADER_SIZE) { - // Send a packet off of the queue - LLPacketBuffer *packetp = mSendQueue.front(); - mSendQueue.pop(); + // *FIX We are assuming ATYP is 0x01 (IPv4), not 0x03 (hostname) or 0x04 (IPv6) - mOutBufferLength -= packetp->getSize(); - packet_size = packetp->getSize(); + proxywrap_t * header = static_cast<proxywrap_t*>(static_cast<void*>(buffer)); + LLHost sender; + sender.setAddress(header->addr); + sender.setPort(ntohs(header->port)); - status = sendPacketImpl(h_socket, packetp->getData(), packet_size, packetp->getHost()); + packet_size -= SOCKS_HEADER_SIZE; // The unwrapped packet size + packet->init(buffer + SOCKS_HEADER_SIZE, packet_size, sender); - delete packetp; - // Update the throttle - mOutThrottle.throttleOverflow(packet_size * 8.f); + mHeadIndex = (mHeadIndex + 1) % (S16)(mPacketRing.size()); + if (mNumBufferedPackets < MAX_BUFFER_RING_SIZE) + { + ++mNumBufferedPackets; + mNumBufferedBytes += packet_size; + } + else + { + // we overwrote an older packet + mNumBufferedBytes += packet_size - old_packet_size; + } } else { - // If the queue's empty, we can just send this packet right away. - status = sendPacketImpl(h_socket, send_buffer, buf_size, host ); - packet_size = buf_size; - - // Update the throttle - mOutThrottle.throttleOverflow(packet_size * 8.f); - - // This was the packet we're sending now, there are no other packets - // that we need to send - return status; + packet_size = 0; } - - } - - // We haven't sent the incoming packet, add it to the queue - if (mOutBufferLength + buf_size > mMaxBufferLength) - { - // Nuke this packet, we overflowed the buffer. - // Toss it. - LL_WARNS() << "Throwing away outbound packet, overflowing buffer" << LL_ENDL; } - else + } + else + { + packet->init(socket); + packet_size = packet->getSize(); + if (packet_size > 0) { - static LLTimer queue_timer; - if ((mOutBufferLength > 4192) && queue_timer.getElapsedTimeF32() > 1.f) + mActualBytesIn += packet_size; + + mHeadIndex = (mHeadIndex + 1) % (S16)(mPacketRing.size()); + if (mNumBufferedPackets < MAX_BUFFER_RING_SIZE) { - // Add it to the queue - LL_INFOS() << "Outbound packet queue " << mOutBufferLength << " bytes" << LL_ENDL; - queue_timer.reset(); + ++mNumBufferedPackets; + mNumBufferedBytes += packet_size; + } + else + { + // we overwrote an older packet + mNumBufferedBytes += packet_size - old_packet_size; } - packetp = new LLPacketBuffer(host, send_buffer, buf_size); - - mOutBufferLength += packetp->getSize(); - mSendQueue.push(packetp); } } + return packet_size; +} - return status; +S32 LLPacketRing::drainSocket(S32 socket) +{ + // drain into buffer + S32 packet_size = 1; + S32 num_loops = 0; + S32 old_num_packets = mNumBufferedPackets; + while (packet_size > 0) + { + packet_size = bufferInboundPacket(socket); + ++num_loops; + } + S32 num_dropped_packets = (num_loops - 1 + old_num_packets) - mNumBufferedPackets; + if (num_dropped_packets > 0) + { + // It will eventually be accounted by mDroppedPackets + // and mPacketsLost, but track it here for logging purposes. + mNumDroppedPackets += num_dropped_packets; + } + return (S32)(mNumBufferedPackets); } -bool LLPacketRing::sendPacketImpl(int h_socket, const char * send_buffer, S32 buf_size, LLHost host) +bool LLPacketRing::expandRing() { + // compute larger size + constexpr S16 BUFFER_RING_EXPANSION = 256; + S16 old_size = (S16)(mPacketRing.size()); + S16 new_size = llmin(old_size + BUFFER_RING_EXPANSION, MAX_BUFFER_RING_SIZE); + if (new_size == old_size) + { + // mPacketRing is already maxed out + return false; + } - if (!LLProxy::isSOCKSProxyEnabled()) + // make a larger ring and copy packet pointers + std::vector<LLPacketBuffer*> new_ring(new_size, nullptr); + for (S16 i = 0; i < old_size; ++i) { - return send_packet(h_socket, send_buffer, buf_size, host.getAddress(), host.getPort()); + S16 j = (mHeadIndex + i) % old_size; + new_ring[i] = mPacketRing[j]; } - char headered_send_buffer[NET_BUFFER_SIZE + SOCKS_HEADER_SIZE]; + // allocate new packets for the remainder of new_ring + LLHost invalid_host; + for (S16 i = old_size; i < new_size; ++i) + { + new_ring[i] = new LLPacketBuffer(invalid_host, nullptr, 0); + } - proxywrap_t *socks_header = static_cast<proxywrap_t*>(static_cast<void*>(&headered_send_buffer)); - socks_header->rsv = 0; - socks_header->addr = host.getAddress(); - socks_header->port = htons(host.getPort()); - socks_header->atype = ADDRESS_IPV4; - socks_header->frag = 0; + // swap the rings and reset mHeadIndex + mPacketRing.swap(new_ring); + mHeadIndex = mNumBufferedPackets; + return true; +} - memcpy(headered_send_buffer + SOCKS_HEADER_SIZE, send_buffer, buf_size); +F32 LLPacketRing::getBufferLoadRate() const +{ + // goes up to MAX_BUFFER_RING_SIZE + return (F32)mNumBufferedPackets / (F32)DEFAULT_BUFFER_RING_SIZE; +} - return send_packet( h_socket, - headered_send_buffer, - buf_size + SOCKS_HEADER_SIZE, - LLProxy::getInstance()->getUDPProxy().getAddress(), - LLProxy::getInstance()->getUDPProxy().getPort()); +void LLPacketRing::dumpPacketRingStats() +{ + mNumDroppedPacketsTotal += mNumDroppedPackets; + LL_INFOS("Messaging") << "Packet ring stats: " << std::endl + << "Buffered packets: " << mNumBufferedPackets << std::endl + << "Buffered bytes: " << mNumBufferedBytes << std::endl + << "Dropped packets current: " << mNumDroppedPackets << std::endl + << "Dropped packets total: " << mNumDroppedPacketsTotal << std::endl + << "Dropped packets percentage: " << mDropPercentage << "%" << std::endl + << "Actual in bytes: " << mActualBytesIn << std::endl + << "Actual out bytes: " << mActualBytesOut << LL_ENDL; + mNumDroppedPackets = 0; } diff --git a/indra/llmessage/llpacketring.h b/indra/llmessage/llpacketring.h index f0e95f8524..572dcbd271 100644 --- a/indra/llmessage/llpacketring.h +++ b/indra/llmessage/llpacketring.h @@ -25,16 +25,14 @@ * $/LicenseInfo$ */ -#ifndef LL_LLPACKETRING_H -#define LL_LLPACKETRING_H +#pragma once -#include <queue> +#include <vector> #include "llhost.h" #include "llpacketbuffer.h" -#include "llproxy.h" #include "llthrottle.h" -#include "net.h" + class LLPacketRing { @@ -42,60 +40,71 @@ public: LLPacketRing(); ~LLPacketRing(); - void cleanup(); + // receive one packet: either buffered or from the socket + S32 receivePacket (S32 socket, char *datap); + + // send one packet + bool sendPacket(int h_socket, const char * send_buffer, S32 buf_size, LLHost host); + + // drains packets from socket and returns final mNumBufferedPackets + S32 drainSocket(S32 socket); void dropPackets(U32); void setDropPercentage (F32 percent_to_drop); - void setUseInThrottle(const bool use_throttle); - void setUseOutThrottle(const bool use_throttle); - void setInBandwidth(const F32 bps); - void setOutBandwidth(const F32 bps); - S32 receivePacket (S32 socket, char *datap); - S32 receiveFromRing (S32 socket, char *datap); - bool sendPacket(int h_socket, char * send_buffer, S32 buf_size, LLHost host); + inline LLHost getLastSender() const; + inline LLHost getLastReceivingInterface() const; - inline LLHost getLastSender(); - inline LLHost getLastReceivingInterface(); + S32 getActualInBytes() const { return mActualBytesIn; } + S32 getActualOutBytes() const { return mActualBytesOut; } + S32 getAndResetActualInBits() { S32 bits = mActualBytesIn * 8; mActualBytesIn = 0; return bits;} + S32 getAndResetActualOutBits() { S32 bits = mActualBytesOut * 8; mActualBytesOut = 0; return bits;} - S32 getAndResetActualInBits() { S32 bits = mActualBitsIn; mActualBitsIn = 0; return bits;} - S32 getAndResetActualOutBits() { S32 bits = mActualBitsOut; mActualBitsOut = 0; return bits;} -protected: - bool mUseInThrottle; - bool mUseOutThrottle; + S32 getNumBufferedPackets() const { return (S32)(mNumBufferedPackets); } + S32 getNumBufferedBytes() const { return mNumBufferedBytes; } + S32 getNumDroppedPackets() const { return mNumDroppedPacketsTotal + mNumDroppedPackets; } - // For simulating a lower-bandwidth connection - BPS - LLThrottle mInThrottle; - LLThrottle mOutThrottle; + F32 getBufferLoadRate() const; // from 0 to 4 (0 - empty, 1 - default size is full) + void dumpPacketRingStats(); +protected: + // returns 'true' if we should intentionally drop a packet + bool computeDrop(); - S32 mActualBitsIn; - S32 mActualBitsOut; - S32 mMaxBufferLength; // How much data can we queue up before dropping data. - S32 mInBufferLength; // Current incoming buffer length - S32 mOutBufferLength; // Current outgoing buffer length + // returns packet_size of received packet, zero or less if no packet found + S32 receiveOrDropPacket(S32 socket, char *datap, bool drop); + S32 receiveOrDropBufferedPacket(char *datap, bool drop); - F32 mDropPercentage; // % of packets to drop - U32 mPacketsToDrop; // drop next n packets + // returns packet_size of packet buffered + S32 bufferInboundPacket(S32 socket); - std::queue<LLPacketBuffer *> mReceiveQueue; - std::queue<LLPacketBuffer *> mSendQueue; + // returns 'true' if ring was expanded + bool expandRing(); +protected: + std::vector<LLPacketBuffer*> mPacketRing; + S16 mHeadIndex { 0 }; + S16 mNumBufferedPackets { 0 }; + S32 mNumDroppedPackets { 0 }; + S32 mNumDroppedPacketsTotal { 0 }; + S32 mNumBufferedBytes { 0 }; + + S32 mActualBytesIn { 0 }; + S32 mActualBytesOut { 0 }; + F32 mDropPercentage { 0.0f }; // % of inbound packets to drop + U32 mPacketsToDrop { 0 }; // drop next inbound n packets + + // These are the sender and receiving_interface for the last packet delivered by receivePacket() LLHost mLastSender; LLHost mLastReceivingIF; - -private: - bool sendPacketImpl(int h_socket, const char * send_buffer, S32 buf_size, LLHost host); }; -inline LLHost LLPacketRing::getLastSender() +inline LLHost LLPacketRing::getLastSender() const { return mLastSender; } -inline LLHost LLPacketRing::getLastReceivingInterface() +inline LLHost LLPacketRing::getLastReceivingInterface() const { return mLastReceivingIF; } - -#endif diff --git a/indra/llmessage/llproxy.cpp b/indra/llmessage/llproxy.cpp index 864e68998c..d713cb20d9 100644 --- a/indra/llmessage/llproxy.cpp +++ b/indra/llmessage/llproxy.cpp @@ -465,7 +465,7 @@ void LLProxy::applyProxySettings(CURL* handle) /** * @brief Send one TCP packet and receive one in return. * - * This operation is done synchronously with a 1000ms timeout. Therefore, it should not be used when a blocking + * This operation is done synchronously with a 100ms timeout. Therefore, it should not be used when a blocking * operation would impact the operation of the viewer. * * @param handle_ptr Pointer to a connected LLSocket of type STREAM_TCP. @@ -482,7 +482,7 @@ static apr_status_t tcp_blocking_handshake(LLSocket::ptr_t handle, char * dataou apr_size_t expected_len = outlen; - handle->setBlocking(1000); + handle->setBlocking(100000); // 100ms, 100000us. Should be sufficient for localhost, nearby network rv = apr_socket_send(apr_socket, dataout, &outlen); if (APR_SUCCESS != rv) @@ -498,8 +498,6 @@ static apr_status_t tcp_blocking_handshake(LLSocket::ptr_t handle, char * dataou rv = -1; } - ms_sleep(1); - if (APR_SUCCESS == rv) { expected_len = maxinlen; diff --git a/indra/llmessage/lltemplatemessagebuilder.cpp b/indra/llmessage/lltemplatemessagebuilder.cpp index 758d6d343f..883c84c6a5 100644 --- a/indra/llmessage/lltemplatemessagebuilder.cpp +++ b/indra/llmessage/lltemplatemessagebuilder.cpp @@ -28,6 +28,10 @@ #include "lltemplatemessagebuilder.h" +#if __FreeBSD__ +#include <arpa/inet.h> +#endif + #include "llmessagetemplate.h" #include "llmath.h" #include "llquaternion.h" diff --git a/indra/llmessage/lltemplatemessagereader.cpp b/indra/llmessage/lltemplatemessagereader.cpp index b62288590e..7798e5692b 100644 --- a/indra/llmessage/lltemplatemessagereader.cpp +++ b/indra/llmessage/lltemplatemessagereader.cpp @@ -27,6 +27,10 @@ #include "linden_common.h" #include "lltemplatemessagereader.h" +#if __FreeBSD__ +#include <arpa/inet.h> +#endif + #include "llfasttimer.h" #include "llmessagebuilder.h" #include "llmessagetemplate.h" @@ -118,6 +122,9 @@ void LLTemplateMessageReader::getData(const char *blockname, const char *varname { switch( vardata_size ) { + case 0: + // This is here to prevent a memcpy from a null value which is undefined behavior. + break; case 1: *((U8*)datap) = *((U8*)vardata.getData()); break; @@ -286,7 +293,7 @@ void LLTemplateMessageReader::getU8(const char *block, const char *var, void LLTemplateMessageReader::getBOOL(const char *block, const char *var, bool &b, S32 blocknum ) { - U8 value; + U8 value(0); getData(block, var, &value, sizeof(U8), blocknum); b = (bool)value; } @@ -445,7 +452,7 @@ S32 LLTemplateMessageReader::getMessageSize() const // Returns template for the message contained in buffer bool LLTemplateMessageReader::decodeTemplate( const U8* buffer, S32 buffer_size, // inputs - LLMessageTemplate** msg_template ) // outputs + LLMessageTemplate** msg_template, bool custom ) // outputs { const U8* header = buffer + LL_PACKET_ID_SIZE; @@ -487,6 +494,7 @@ bool LLTemplateMessageReader::decodeTemplate( } else // bogus packet received (too short) { + if (!custom) LL_WARNS() << "Packet with unusable length received (too short): " << buffer_size << LL_ENDL; return(false); @@ -499,9 +507,11 @@ bool LLTemplateMessageReader::decodeTemplate( } else { - // MAINT-7482 - make viewer more tolerant of unknown messages. + if (!custom) + { LL_WARNS_ONCE() << "Message #" << std::hex << num << std::dec << " received but not registered!" << LL_ENDL; + } //gMessageSystem->callExceptionFunc(MX_UNREGISTERED_MESSAGE); return(false); } @@ -531,7 +541,7 @@ void LLTemplateMessageReader::logRanOffEndOfPacket( const LLHost& host, const S3 static LLTrace::BlockTimerStatHandle FTM_PROCESS_MESSAGES("Process Messages"); // decode a given message -bool LLTemplateMessageReader::decodeData(const U8* buffer, const LLHost& sender ) +bool LLTemplateMessageReader::decodeData(const U8* buffer, const LLHost& sender, bool custom ) { LL_RECORD_BLOCK_TIME(FTM_PROCESS_MESSAGES); @@ -591,6 +601,7 @@ bool LLTemplateMessageReader::decodeData(const U8* buffer, const LLHost& sender } else { + if (!custom) LL_ERRS() << "Unknown block type" << LL_ENDL; return false; } @@ -637,6 +648,7 @@ bool LLTemplateMessageReader::decodeData(const U8* buffer, const LLHost& sender if ((decode_pos + data_size) > mReceiveSize) { + if (!custom) logRanOffEndOfPacket(sender, decode_pos, data_size); // default to 0 length variable blocks @@ -673,6 +685,7 @@ bool LLTemplateMessageReader::decodeData(const U8* buffer, const LLHost& sender // so, copy data pointer and set data size to fixed size if ((decode_pos + mvci.getSize()) > mReceiveSize) { + if (!custom) logRanOffEndOfPacket(sender, decode_pos, mvci.getSize()); // default to 0s. @@ -697,10 +710,11 @@ bool LLTemplateMessageReader::decodeData(const U8* buffer, const LLHost& sender if (mCurrentRMessageData->mMemberBlocks.empty() && !mCurrentRMessageTemplate->mMemberBlocks.empty()) { - LL_DEBUGS() << "Empty message '" << mCurrentRMessageTemplate->mName << "' (no blocks)" << LL_ENDL; + LL_WARNS() << "Empty message '" << mCurrentRMessageTemplate->mName << "' (no blocks)" << LL_ENDL; return false; } + if (!custom) { static LLTimer decode_timer; @@ -753,11 +767,12 @@ bool LLTemplateMessageReader::decodeData(const U8* buffer, const LLHost& sender bool LLTemplateMessageReader::validateMessage(const U8* buffer, S32 buffer_size, const LLHost& sender, - bool trusted) + bool trusted, + bool custom) { mReceiveSize = buffer_size; - bool valid = decodeTemplate(buffer, buffer_size, &mCurrentRMessageTemplate ); - if(valid) + BOOL valid = decodeTemplate(buffer, buffer_size, &mCurrentRMessageTemplate, custom ); + if(valid && !custom) { mCurrentRMessageTemplate->mReceiveCount++; //LL_DEBUGS() << "MessageRecvd:" @@ -828,3 +843,9 @@ void LLTemplateMessageReader::copyToBuilder(LLMessageBuilder& builder) const } builder.copyFromMessageData(*mCurrentRMessageData); } + +LLMessageTemplate* LLTemplateMessageReader::getTemplate() +{ + return mCurrentRMessageTemplate; +} + diff --git a/indra/llmessage/lltemplatemessagereader.h b/indra/llmessage/lltemplatemessagereader.h index 6f1977cf83..0f7160d328 100644 --- a/indra/llmessage/lltemplatemessagereader.h +++ b/indra/llmessage/lltemplatemessagereader.h @@ -99,25 +99,26 @@ public: virtual void copyToBuilder(LLMessageBuilder&) const; bool validateMessage(const U8* buffer, S32 buffer_size, - const LLHost& sender, bool trusted = false); + const LLHost& sender, bool trusted = false, bool custom = false); bool readMessage(const U8* buffer, const LLHost& sender); bool isTrusted() const; bool isBanned(bool trusted_source) const; bool isUdpBanned() const; + bool decodeData(const U8* buffer, const LLHost& sender, bool custom = false ); + LLMessageTemplate* getTemplate(); + private: void getData(const char *blockname, const char *varname, void *datap, S32 size = 0, S32 blocknum = 0, S32 max_size = S32_MAX); bool decodeTemplate(const U8* buffer, S32 buffer_size, // inputs - LLMessageTemplate** msg_template ); // outputs + LLMessageTemplate** msg_template, bool custom = false ); // outputs void logRanOffEndOfPacket( const LLHost& host, const S32 where, const S32 wanted ); - bool decodeData(const U8* buffer, const LLHost& sender ); - S32 mReceiveSize; LLMessageTemplate* mCurrentRMessageTemplate; LLMsgData* mCurrentRMessageData; diff --git a/indra/llmessage/message.cpp b/indra/llmessage/message.cpp index cfa5178fc6..ad1ff86807 100644 --- a/indra/llmessage/message.cpp +++ b/indra/llmessage/message.cpp @@ -656,8 +656,7 @@ bool LLMessageSystem::checkMessages(LockMessageChecker&, S64 frame_count ) // UseCircuitCode is allowed in even from an invalid circuit, so that // we can toss circuits around. - if( - valid_packet && + else if ( !cdp && (mTemplateMessageReader->getMessageName() != _PREHASH_UseCircuitCode)) @@ -667,8 +666,7 @@ bool LLMessageSystem::checkMessages(LockMessageChecker&, S64 frame_count ) valid_packet = false; } - if( - valid_packet && + if ( valid_packet && cdp && !cdp->getTrusted() && mTemplateMessageReader->isTrusted()) @@ -680,7 +678,7 @@ bool LLMessageSystem::checkMessages(LockMessageChecker&, S64 frame_count ) valid_packet = false; } - if( valid_packet ) + if ( valid_packet ) { logValidMsg(cdp, host, recv_reliable, recv_resent, acks>0 ); valid_packet = mTemplateMessageReader->readMessage(buffer, host); @@ -726,6 +724,7 @@ bool LLMessageSystem::checkMessages(LockMessageChecker&, S64 frame_count ) // Check to see if we need to print debug info if ((mt_sec - mCircuitPrintTime) > mCircuitPrintFreq) { + mPacketRing.dumpPacketRingStats(); dumpCircuitInfo(); mCircuitPrintTime = mt_sec; } @@ -821,6 +820,11 @@ void LLMessageSystem::processAcks(LockMessageChecker&, F32 collect_time) } } +S32 LLMessageSystem::drainUdpSocket() +{ + return mPacketRing.drainSocket(mSocket); +} + void LLMessageSystem::copyMessageReceivedToSend() { // NOTE: babbage: switch builder to match reader to avoid diff --git a/indra/llmessage/message.h b/indra/llmessage/message.h index b4b0d94021..30945cac51 100644 --- a/indra/llmessage/message.h +++ b/indra/llmessage/message.h @@ -417,6 +417,9 @@ public: bool checkMessages(LockMessageChecker&, S64 frame_count = 0 ); void processAcks(LockMessageChecker&, F32 collect_time = 0.f); + // returns total number of buffered packets after the drain + S32 drainUdpSocket(); + bool isMessageFast(const char *msg); bool isMessage(const char *msg) { @@ -535,7 +538,6 @@ public: //void buildMessage(); - S32 zeroCode(U8 **data, S32 *data_size); S32 zeroCodeExpand(U8 **data, S32 *data_size); S32 zeroCodeAdjustCurrentSendTotal(); @@ -752,6 +754,7 @@ public: S32 getReceiveBytes() const; S32 getUnackedListSize() const { return mUnackedListSize; } + F32 getBufferLoadRate() const { return mPacketRing.getBufferLoadRate(); } //const char* getCurrentSMessageName() const { return mCurrentSMessageName; } //const char* getCurrentSBlockName() const { return mCurrentSBlockName; } @@ -839,12 +842,10 @@ private: LLUUID mSessionID; void addTemplate(LLMessageTemplate *templatep); - bool decodeTemplate( const U8* buffer, S32 buffer_size, LLMessageTemplate** msg_template ); void logMsgFromInvalidCircuit( const LLHost& sender, bool recv_reliable ); void logTrustedMsgFromUntrustedCircuit( const LLHost& sender ); void logValidMsg(LLCircuitData *cdp, const LLHost& sender, bool recv_reliable, bool recv_resent, bool recv_acks ); - void logRanOffEndOfPacket( const LLHost& sender ); class LLMessageCountInfo { diff --git a/indra/llmessage/net.cpp b/indra/llmessage/net.cpp index f153c938cf..2be5a9e5b6 100644 --- a/indra/llmessage/net.cpp +++ b/indra/llmessage/net.cpp @@ -76,14 +76,8 @@ static U32 gsnReceivingIFAddr = INVALID_HOST_IP_ADDRESS; // Address to which dat const char* LOOPBACK_ADDRESS_STRING = "127.0.0.1"; const char* BROADCAST_ADDRESS_STRING = "255.255.255.255"; -#if LL_DARWIN - // macOS returns an error when trying to set these to 400000. Smaller values succeed. - const int SEND_BUFFER_SIZE = 200000; - const int RECEIVE_BUFFER_SIZE = 200000; -#else // LL_DARWIN - const int SEND_BUFFER_SIZE = 400000; - const int RECEIVE_BUFFER_SIZE = 400000; -#endif // LL_DARWIN +const int SEND_BUFFER_SIZE = 200000; +const int RECEIVE_BUFFER_SIZE = 800000; // universal functions (cross-platform) diff --git a/indra/llplugin/CMakeLists.txt b/indra/llplugin/CMakeLists.txt index 14a69afe6e..7fa5c957b6 100644 --- a/indra/llplugin/CMakeLists.txt +++ b/indra/llplugin/CMakeLists.txt @@ -31,14 +31,6 @@ set(llplugin_HEADER_FILES llpluginsharedmemory.h ) -if(NOT ADDRESS_SIZE EQUAL 32) - if(WINDOWS) - ##add_definitions(/FIXED:NO) - else(WINDOWS) # not windows therefore gcc LINUX and DARWIN - add_definitions(-fPIC) - endif(WINDOWS) -endif(NOT ADDRESS_SIZE EQUAL 32) - list(APPEND llplugin_SOURCE_FILES ${llplugin_HEADER_FILES}) add_library (llplugin ${llplugin_SOURCE_FILES}) @@ -46,3 +38,4 @@ target_include_directories( llplugin INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}) target_link_libraries( llplugin llcommon llmath llrender llmessage ) add_subdirectory(slplugin) +include(LibraryInstall) diff --git a/indra/llplugin/llpluginclassmedia.cpp b/indra/llplugin/llpluginclassmedia.cpp index 8a356da93a..17f403e8e8 100644 --- a/indra/llplugin/llpluginclassmedia.cpp +++ b/indra/llplugin/llpluginclassmedia.cpp @@ -33,7 +33,9 @@ #include "llpluginmessageclasses.h" #include "llcontrol.h" +#if LL_DARWIN || LL_LINUX || __FreeBSD__ extern LLControlGroup gSavedSettings; +#endif #if LL_DARWIN extern bool gHiDPISupport; #endif @@ -934,8 +936,10 @@ void LLPluginClassMedia::setUserDataPath(const std::string &user_data_path_cache message.setValue("username", username); // cef shares cache between users but creates user-based contexts message.setValue("cef_log_file", user_data_path_cef_log); +#if LL_DARWIN || LL_LINUX || __FreeBSD__ bool cef_verbose_log = gSavedSettings.getBOOL("CefVerboseLog"); message.setValueBoolean("cef_verbose_log", cef_verbose_log); +#endif sendMessage(message); } @@ -981,6 +985,15 @@ void LLPluginClassMedia::enableMediaPluginDebugging( bool enable ) sendMessage( message ); } +#if LL_LINUX +void LLPluginClassMedia::enablePipeWireVolumeCatcher( bool enable ) +{ + LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "enable_pipewire_volume_catcher"); + message.setValueBoolean( "enable", enable ); + sendMessage( message ); +} +#endif + void LLPluginClassMedia::setTarget(const std::string &target) { mTarget = target; @@ -1198,6 +1211,14 @@ void LLPluginClassMedia::receivePluginMessage(const LLPluginMessage &message) mMediaName = message.getValue("name"); mediaEvent(LLPluginClassMediaOwner::MEDIA_EVENT_NAME_CHANGED); } + else if(message_name == "title_text") + { + mMediaTitle = message.getValue("title"); + } + else if(message_name == "nowplaying_text") + { + mMediaNowPlaying = message.getValue("nowplaying"); + } else if(message_name == "pick_file") { mIsMultipleFilePick = message.getValueBoolean("multiple_files"); diff --git a/indra/llplugin/llpluginclassmedia.h b/indra/llplugin/llpluginclassmedia.h index d74b790d8f..80862284ff 100644 --- a/indra/llplugin/llpluginclassmedia.h +++ b/indra/llplugin/llpluginclassmedia.h @@ -135,6 +135,10 @@ public: // Text may be unicode (utf8 encoded) bool textInput(const std::string &text, MASK modifiers, LLSD native_key_data); +#if LL_LINUX + void enablePipeWireVolumeCatcher( bool enable ); +#endif + static std::string sOIDcookieUrl; static std::string sOIDcookieName; static std::string sOIDcookieValue; @@ -307,6 +311,8 @@ public: const std::string& getMediaName() const { return mMediaName; }; + const std::string& getMediaTitle() const { return mMediaTitle; }; + const std::string& getMediaNowPlaying() const { return mMediaNowPlaying; }; std::string getMediaDescription() const { return mMediaDescription; }; // Crash the plugin. If you use this outside of a testbed, you will be punished. @@ -424,6 +430,8 @@ protected: bool mCanPaste; std::string mMediaName; + std::string mMediaTitle; + std::string mMediaNowPlaying; std::string mMediaDescription; LLColor4 mBackgroundColor; diff --git a/indra/llplugin/llpluginprocessparent.cpp b/indra/llplugin/llpluginprocessparent.cpp index 908f3c8ff5..19a0ce639a 100644 --- a/indra/llplugin/llpluginprocessparent.cpp +++ b/indra/llplugin/llpluginprocessparent.cpp @@ -400,9 +400,14 @@ void LLPluginProcessParent::idle(void) apr_sockaddr_t* addr = NULL; mListenSocket = LLSocket::create(gAPRPoolp, LLSocket::STREAM_TCP); mBoundPort = 0; + if (!mListenSocket) + { + killSockets(); + errorState(); + break; + } // This code is based on parts of LLSocket::create() in lliosocket.cpp. - status = apr_sockaddr_info_get( &addr, "127.0.0.1", diff --git a/indra/llplugin/llpluginsharedmemory.cpp b/indra/llplugin/llpluginsharedmemory.cpp index 28a0f0bf4e..955c9f90d7 100644 --- a/indra/llplugin/llpluginsharedmemory.cpp +++ b/indra/llplugin/llpluginsharedmemory.cpp @@ -45,8 +45,12 @@ #define USE_WIN32_SHARED_MEMORY 1 #elif LL_DARWIN #define USE_SHM_OPEN_SHARED_MEMORY 1 +#elif _POSIX_SHARED_MEMORY_OBJECTS == -1 + #define USE_APR_SHARED_MEMORY 1 #elif LL_LINUX #define USE_SHM_OPEN_SHARED_MEMORY 1 +#elif __FreeBSD__ + #define USE_SHM_OPEN_SHARED_MEMORY 1 #endif diff --git a/indra/llplugin/slplugin/CMakeLists.txt b/indra/llplugin/slplugin/CMakeLists.txt index 0ea6495eac..d29731894f 100644 --- a/indra/llplugin/slplugin/CMakeLists.txt +++ b/indra/llplugin/slplugin/CMakeLists.txt @@ -56,10 +56,25 @@ if (DARWIN) COMMAND mkdir ARGS -p - ${CMAKE_CURRENT_BINARY_DIR}/$<IF:$<BOOL:${LL_GENERATOR_IS_MULTI_CONFIG}>,$<CONFIG>,>/SLPlugin.app/Contents/Resources + ${CMAKE_CURRENT_BINARY_DIR}/$<IF:$<BOOL:${LL_GENERATOR_IS_MULTI_CONFIG}>,$<CONFIG>,>/SLPlugin.app/Contents/Frameworks ) endif (DARWIN) +if (BUILD_SHARED_LIBS) + set_target_properties(SLPlugin PROPERTIES LINK_FLAGS_RELEASE + "${LINK_FLAGS_RELEASE} -Wl,--allow-shlib-undefined") +endif () + +if (INSTALL) + if (DARWIN) + install(TARGETS ${PROJECT_NAME} DESTINATION .) + elseif (${LINUX_DISTRO} MATCHES arch) + install(TARGETS ${PROJECT_NAME} DESTINATION lib/${VIEWER_BINARY_NAME}) + else (DARWIN) + install(TARGETS ${PROJECT_NAME} DESTINATION libexec/${VIEWER_BINARY_NAME}) + endif (DARWIN) +endif (INSTALL) + if (LL_TESTS) ll_deploy_sharedlibs_command(SLPlugin) endif (LL_TESTS) diff --git a/indra/llplugin/slplugin/slplugin.cpp b/indra/llplugin/slplugin/slplugin.cpp index 81a27cf2e5..ae26b9d452 100644 --- a/indra/llplugin/slplugin/slplugin.cpp +++ b/indra/llplugin/slplugin/slplugin.cpp @@ -46,7 +46,7 @@ using namespace std; #include "slplugin-objc.h" #endif -#if LL_DARWIN || LL_LINUX +#if LL_DARWIN || LL_LINUX || __FreeBSD__ #include <signal.h> #endif @@ -64,7 +64,7 @@ using namespace std; Now that SLPlugin is a bundled app on the Mac, this is no longer necessary (it can just use a regular Info.plist file), but I'm leaving this comment in for posterity. */ -#if LL_DARWIN || LL_LINUX +#if LL_DARWIN || LL_LINUX || __FreeBSD__ // Signal handlers to make crashes not show an OS dialog... static void crash_handler(int sig) { @@ -163,7 +163,7 @@ int main(int argc, char **argv) // display a crash message if something bad happens. The host app will // see the missing heartbeat and log appropriately. initExceptionHandler(); -#elif LL_DARWIN || LL_LINUX +#elif LL_DARWIN || LL_LINUX || __FreeBSD__ if(argc < 2) { LL_ERRS("slplugin") << "usage: " << argv[0] << " launcher_port" << LL_ENDL; diff --git a/indra/llprimitive/CMakeLists.txt b/indra/llprimitive/CMakeLists.txt index 3d8e02cb16..00d821c470 100644 --- a/indra/llprimitive/CMakeLists.txt +++ b/indra/llprimitive/CMakeLists.txt @@ -3,6 +3,7 @@ project(llprimitive) include(00-Common) +include(Prebuilt) include(LLCommon) include(LLCoreHttp) include(LLPhysicsExtensions) @@ -10,6 +11,27 @@ include(LLPrimitive) include(GLM) include(TinyGLTF) +if(LINUX OR CMAKE_SYSTEM_NAME MATCHES FreeBSD ) + set_property(DIRECTORY APPEND + PROPERTY CMAKE_CONFIGURE_DEPENDS ${CMAKE_SOURCE_DIR}/../patches/collada-dom-v2.3-r8.patch) + prepare_thirdparty( + "https://github.com/secondlife/3p-colladadom/archive/refs/tags/v2.3-r8.tar.gz" + "colladadom-v2.3-r8.tar.gz" + "3p-colladadom-2.3-r8" + "collada-dom-v2.3-r8.patch" + "b36dce3b7be4b49f3c8e4d6c9dbf3529f7ed1f28e64ee45be0e77805f06376b95079798616529302d771ab2b76bf06d2f894ca11e6f7f3097c3f7a05a78c474f" + ) + set(OPT_COLLADA14 TRUE) + add_subdirectory( + "${CMAKE_BINARY_DIR}/3p-colladadom-2.3-r8" "colladadom") + target_include_directories( + ll::colladadom INTERFACE + ${colladadom_SOURCE_DIR}/include + ${colladadom_SOURCE_DIR}/include/1.4 + ) + target_link_libraries( ll::colladadom INTERFACE collada14dom ) +endif(LINUX OR CMAKE_SYSTEM_NAME MATCHES FreeBSD ) + set(llprimitive_SOURCE_FILES lldaeloader.cpp llgltfloader.cpp @@ -72,6 +94,8 @@ target_link_libraries(llprimitive ll::glm ) +include(LibraryInstall) + #add unit tests if (LL_TESTS) INCLUDE(LLAddBuildTest) diff --git a/indra/llprimitive/lldaeloader.h b/indra/llprimitive/lldaeloader.h index 4531e03474..c6e5ea42fc 100644 --- a/indra/llprimitive/lldaeloader.h +++ b/indra/llprimitive/lldaeloader.h @@ -29,6 +29,7 @@ #include "llmodelloader.h" +#ifndef LL_USESYSTEMLIBS class DAE; class daeElement; class domProfile_COMMON; @@ -38,6 +39,7 @@ class domTranslate; class domController; class domSkin; class domMesh; +#endif class LLDAELoader : public LLModelLoader { diff --git a/indra/llprimitive/llgltfmaterial.h b/indra/llprimitive/llgltfmaterial.h index 10df4c8ee1..b89853c9fd 100644 --- a/indra/llprimitive/llgltfmaterial.h +++ b/indra/llprimitive/llgltfmaterial.h @@ -36,6 +36,7 @@ #include <array> #include <string> +#include <array> #include <map> namespace tinygltf diff --git a/indra/llprimitive/llmodel.h b/indra/llprimitive/llmodel.h index fe28926720..309c5df64c 100644 --- a/indra/llprimitive/llmodel.h +++ b/indra/llprimitive/llmodel.h @@ -35,8 +35,10 @@ #include <boost/align/aligned_allocator.hpp> +#ifndef LL_USESYSTEMLIBS class daeElement; class domMesh; +#endif #define MAX_MODEL_FACES 8 diff --git a/indra/llprimitive/llmodelloader.cpp b/indra/llprimitive/llmodelloader.cpp index 7facd53a72..84adec4da5 100644 --- a/indra/llprimitive/llmodelloader.cpp +++ b/indra/llprimitive/llmodelloader.cpp @@ -58,7 +58,7 @@ static void stretch_extents(const LLModel* model, const LLMatrix4a& mat, LLVecto center.setAdd(face.mExtents[0], face.mExtents[1]); center.mul(0.5f); LLVector4a size; - size.setSub(face.mExtents[1],face.mExtents[0]); + size.setSub(face.mExtents[1], face.mExtents[0]); size.mul(0.5f); for (U32 i = 0; i < 8; i++) diff --git a/indra/llprimitive/llprimitive.cpp b/indra/llprimitive/llprimitive.cpp index c5d6076b98..c116f69a6d 100644 --- a/indra/llprimitive/llprimitive.cpp +++ b/indra/llprimitive/llprimitive.cpp @@ -274,7 +274,7 @@ void LLPrimitive::setAllTETextures(const LLUUID &tex_id) //=============================================================== void LLPrimitive::setTE(const U8 index, const LLTextureEntry& te) { - if(mTextureList.copyTexture(index, te) != TEM_CHANGE_NONE && te.getBumpmap() > 0) + if(mTextureList.copyTexture(index, &te) != TEM_CHANGE_NONE && te.getBumpmap() > 0) { mNumBumpmapTEs++; } @@ -753,7 +753,7 @@ void LLPrimitive::copyTEs(const LLPrimitive *primitivep) } for (i = 0; i < num_tes; i++) { - mTextureList.copyTexture(i, *(primitivep->getTE(i))); + mTextureList.copyTexture(i, primitivep->getTE(i)); } } diff --git a/indra/llprimitive/llprimtexturelist.cpp b/indra/llprimitive/llprimtexturelist.cpp index 68f3f5ffac..7f60d8025a 100644 --- a/indra/llprimitive/llprimtexturelist.cpp +++ b/indra/llprimitive/llprimtexturelist.cpp @@ -125,7 +125,7 @@ void LLPrimTextureList::take(LLPrimTextureList& other_list) // virtual // copies LLTextureEntry 'te' // returns TEM_CHANGE_TEXTURE if successful, otherwise TEM_CHANGE_NONE -S32 LLPrimTextureList::copyTexture(const U8 index, const LLTextureEntry& te) +S32 LLPrimTextureList::copyTexture(const U8 index, const LLTextureEntry* te) { if (size_t(index) >= mEntryList.size()) { @@ -137,14 +137,7 @@ S32 LLPrimTextureList::copyTexture(const U8 index, const LLTextureEntry& te) // we're changing an existing entry llassert(mEntryList[index]); delete (mEntryList[index]); - if (&te) - { - mEntryList[index] = te.newCopy(); - } - else - { - mEntryList[index] = LLPrimTextureList::newTextureEntry(); - } + mEntryList[index] = te->newCopy(); return TEM_CHANGE_TEXTURE; } diff --git a/indra/llprimitive/llprimtexturelist.h b/indra/llprimitive/llprimtexturelist.h index 79744e9f08..b8bdad60b3 100644 --- a/indra/llprimitive/llprimtexturelist.h +++ b/indra/llprimitive/llprimtexturelist.h @@ -71,7 +71,7 @@ public: // copies LLTextureEntry 'te' // returns TEM_CHANGE_TEXTURE if successful, otherwise TEM_CHANGE_NONE - S32 copyTexture(const U8 index, const LLTextureEntry& te); + S32 copyTexture(const U8 index, const LLTextureEntry* te); // takes ownership of LLTextureEntry* 'te' // returns TEM_CHANGE_TEXTURE if successful, otherwise TEM_CHANGE_NONE diff --git a/indra/llrender/CMakeLists.txt b/indra/llrender/CMakeLists.txt index ccff7c7a8c..d48b508ddc 100644 --- a/indra/llrender/CMakeLists.txt +++ b/indra/llrender/CMakeLists.txt @@ -108,3 +108,4 @@ target_link_libraries(llrender OpenGL::GLU ) +include(LibraryInstall) diff --git a/indra/llrender/llcubemap.cpp b/indra/llrender/llcubemap.cpp index 26e4aaad52..53691bafe2 100644 --- a/indra/llrender/llcubemap.cpp +++ b/indra/llrender/llcubemap.cpp @@ -214,7 +214,9 @@ void LLCubeMap::initEnvironmentMap(const std::vector<LLPointer<LLImageRaw> >& ra enableTexture(0); bind(); mImages[0]->setFilteringOption(LLTexUnit::TFO_ANISOTROPIC); +#if GL_VERSION_3_2 glEnable(GL_TEXTURE_CUBE_MAP_SEAMLESS); +#endif glGenerateMipmap(GL_TEXTURE_CUBE_MAP); gGL.getTexUnit(0)->disable(); disable(); diff --git a/indra/llrender/llcubemaparray.cpp b/indra/llrender/llcubemaparray.cpp index 4f5e13765a..fb35e002df 100644 --- a/indra/llrender/llcubemaparray.cpp +++ b/indra/llrender/llcubemaparray.cpp @@ -105,16 +105,48 @@ LLCubeMapArray::LLCubeMapArray() } +LLCubeMapArray::LLCubeMapArray(LLCubeMapArray& lhs, U32 width, U32 count) : mTextureStage(0) +{ + mWidth = width; + mCount = count; + + // Allocate a new cubemap array with the same criteria as the incoming cubemap array + allocate(mWidth, lhs.mImage->getComponents(), count, lhs.mImage->getUseMipMaps(), lhs.mHDR); + + // Copy each cubemap from the incoming array to the new array + U32 min_count = std::min(count, lhs.mCount); + for (U32 i = 0; i < min_count * 6; ++i) + { + U32 src_resolution = lhs.mWidth; + U32 dst_resolution = mWidth; + { + GLint components = GL_RGB; + if (mImage->getComponents() == 4) + components = GL_RGBA; + GLint format = GL_RGB; + + // Handle different resolutions by scaling the image + LLPointer<LLImageRaw> src_image = new LLImageRaw(lhs.mWidth, lhs.mWidth, lhs.mImage->getComponents()); + glGetTexImage(GL_TEXTURE_CUBE_MAP_ARRAY, 0, components, GL_UNSIGNED_BYTE, src_image->getData()); + + LLPointer<LLImageRaw> scaled_image = src_image->scaled(mWidth, mWidth); + glTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 0, 0, 0, i, mWidth, mWidth, 1, components, GL_UNSIGNED_BYTE, scaled_image->getData()); + } + } +} + LLCubeMapArray::~LLCubeMapArray() { } -void LLCubeMapArray::allocate(U32 resolution, U32 components, U32 count, bool use_mips) +void LLCubeMapArray::allocate(U32 resolution, U32 components, U32 count, bool use_mips, bool hdr) { U32 texname = 0; mWidth = resolution; mCount = count; + mHDR = hdr; + LLImageGL::generateTextures(1, &texname); mImage = new LLImageGL(resolution, resolution, components, use_mips); @@ -127,13 +159,19 @@ void LLCubeMapArray::allocate(U32 resolution, U32 components, U32 count, bool us bind(0); free_cur_tex_image(); - U32 format = components == 4 ? GL_RGBA16F : GL_RGB16F; + U32 format = components == 4 ? GL_RGBA16F : GL_R11F_G11F_B10F; + if (!hdr) + { + format = components == 4 ? GL_RGBA8 : GL_RGB8; + } U32 mip = 0; U32 mip_resolution = resolution; while (mip_resolution >= 1) { +#if GL_VERSION_4_0 glTexImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, mip, format, mip_resolution, mip_resolution, count * 6, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr); +#endif if (!use_mips) { diff --git a/indra/llrender/llcubemaparray.h b/indra/llrender/llcubemaparray.h index 675aaaf07c..6b4288cb23 100644 --- a/indra/llrender/llcubemaparray.h +++ b/indra/llrender/llcubemaparray.h @@ -36,6 +36,7 @@ class LLCubeMapArray : public LLRefCount { public: LLCubeMapArray(); + LLCubeMapArray(LLCubeMapArray& lhs, U32 width, U32 count); static GLenum sTargets[6]; @@ -52,7 +53,7 @@ public: // components - number of components per pixel // count - number of cube maps in the array // use_mips - if true, mipmaps will be allocated for this cube map array and anisotropic filtering will be used - void allocate(U32 res, U32 components, U32 count, bool use_mips = true); + void allocate(U32 res, U32 components, U32 count, bool use_mips = true, bool hdr = true); void bind(S32 stage); void unbind(); @@ -73,4 +74,5 @@ protected: U32 mWidth = 0; U32 mCount = 0; S32 mTextureStage; + bool mHDR; }; diff --git a/indra/llrender/llfontbitmapcache.cpp b/indra/llrender/llfontbitmapcache.cpp index ee9cfd0719..6a3af1e608 100644 --- a/indra/llrender/llfontbitmapcache.cpp +++ b/indra/llrender/llfontbitmapcache.cpp @@ -107,7 +107,7 @@ bool LLFontBitmapCache::nextOpenPos(S32 width, S32& pos_x, S32& pos_y, EFontGlyp mBitmapHeight = image_height; S32 num_components = getNumComponents(bitmap_type); - mImageRawVec[bitmap_idx].push_back(new LLImageRaw(mBitmapWidth, mBitmapHeight, num_components)); + mImageRawVec[bitmap_idx].emplace_back(new LLImageRaw(mBitmapWidth, mBitmapHeight, num_components)); bitmap_num = static_cast<U32>(mImageRawVec[bitmap_idx].size()) - 1; LLImageRaw* image_raw = getImageRaw(bitmap_type, bitmap_num); @@ -117,7 +117,7 @@ bool LLFontBitmapCache::nextOpenPos(S32 width, S32& pos_x, S32& pos_y, EFontGlyp } // Make corresponding GL image. - mImageGLVec[bitmap_idx].push_back(new LLImageGL(image_raw, false, false)); + mImageGLVec[bitmap_idx].emplace_back(new LLImageGL(image_raw, false, false)); LLImageGL* image_gl = getImageGL(bitmap_type, bitmap_num); // Start at beginning of the new image. @@ -141,6 +141,7 @@ bool LLFontBitmapCache::nextOpenPos(S32 width, S32& pos_x, S32& pos_y, EFontGlyp bitmap_num = getNumBitmaps(bitmap_type) - 1; mCurrentOffsetX[bitmap_idx] += width + 1; + mGeneration++; return true; } @@ -168,6 +169,7 @@ void LLFontBitmapCache::reset() mBitmapWidth = 0; mBitmapHeight = 0; + mGeneration++; } //static diff --git a/indra/llrender/llfontbitmapcache.h b/indra/llrender/llfontbitmapcache.h index f2dfd87877..0ae4e6bed0 100644 --- a/indra/llrender/llfontbitmapcache.h +++ b/indra/llrender/llfontbitmapcache.h @@ -63,6 +63,7 @@ public: U32 getNumBitmaps(EFontGlyphType bitmapType) const { return (bitmapType < EFontGlyphType::Count) ? static_cast<U32>(mImageRawVec[static_cast<U32>(bitmapType)].size()) : 0U; } S32 getBitmapWidth() const { return mBitmapWidth; } S32 getBitmapHeight() const { return mBitmapHeight; } + S32 getCacheGeneration() const { return mGeneration; } protected: static U32 getNumComponents(EFontGlyphType bitmap_type); @@ -74,6 +75,7 @@ private: S32 mCurrentOffsetY[static_cast<U32>(EFontGlyphType::Count)] = { 1 }; S32 mMaxCharWidth = 0; S32 mMaxCharHeight = 0; + S32 mGeneration = 0; std::vector<LLPointer<LLImageRaw>> mImageRawVec[static_cast<U32>(EFontGlyphType::Count)]; std::vector<LLPointer<LLImageGL>> mImageGLVec[static_cast<U32>(EFontGlyphType::Count)]; }; diff --git a/indra/llrender/llfontfreetype.cpp b/indra/llrender/llfontfreetype.cpp index 6128e03fa7..2d8b8a0fee 100644 --- a/indra/llrender/llfontfreetype.cpp +++ b/indra/llrender/llfontfreetype.cpp @@ -52,7 +52,9 @@ #include "llfontbitmapcache.h" #include "llgl.h" -#define ENABLE_OT_SVG_SUPPORT +#if !defined(LL_NO_OTSVG) + #define ENABLE_OT_SVG_SUPPORT +#endif FT_Render_Mode gFontRenderMode = FT_RENDER_MODE_NORMAL; @@ -87,7 +89,7 @@ LLFontManager::LLFontManager() FT_Done_FreeType(gFTLibrary); } -#ifdef ENABLE_OT_SVG_SUPPORT +#if defined(ENABLE_OT_SVG_SUPPORT) SVG_RendererHooks hooks = { LLFontFreeTypeSvgRenderer::OnInit, LLFontFreeTypeSvgRenderer::OnFree, @@ -146,7 +148,6 @@ LLFontFreetype::LLFontFreetype() mIsFallback(false), mFTFace(NULL), mRenderGlyphCount(0), - mAddGlyphCount(0), mStyle(0), mPointSize(0) { @@ -483,8 +484,8 @@ LLFontGlyphInfo* LLFontFreetype::addGlyph(llwchar wch, EFontGlyphType glyph_type continue; } glyph_index = FT_Get_Char_Index(pair.first->mFTFace, wch); - if (glyph_index) - { + if (glyph_index) + { return addGlyphFromFont(pair.first, wch, glyph_index, glyph_type); } @@ -552,7 +553,7 @@ LLFontGlyphInfo* LLFontFreetype::addGlyphFromFont(const LLFontFreetype *fontp, l return NULL; llassert(!mIsFallback); - fontp->renderGlyph(requested_glyph_type, glyph_index); + fontp->renderGlyph(requested_glyph_type, glyph_index, wch); EFontGlyphType bitmap_glyph_type = EFontGlyphType::Unspecified; switch (fontp->mFTFace->glyph->bitmap.pixel_mode) @@ -574,7 +575,6 @@ LLFontGlyphInfo* LLFontFreetype::addGlyphFromFont(const LLFontFreetype *fontp, l S32 pos_x, pos_y; U32 bitmap_num; mFontBitmapCachep->nextOpenPos(width, pos_x, pos_y, bitmap_glyph_type, bitmap_num); - mAddGlyphCount++; LLFontGlyphInfo* gi = new LLFontGlyphInfo(glyph_index, requested_glyph_type); gi->mXBitmapOffset = pos_x; @@ -697,7 +697,7 @@ void LLFontFreetype::insertGlyphInfo(llwchar wch, LLFontGlyphInfo* gi) const } } -void LLFontFreetype::renderGlyph(EFontGlyphType bitmap_type, U32 glyph_index) const +void LLFontFreetype::renderGlyph(EFontGlyphType bitmap_type, U32 glyph_index, llwchar wch) const { if (mFTFace == NULL) return; @@ -712,11 +712,28 @@ void LLFontFreetype::renderGlyph(EFontGlyphType bitmap_type, U32 glyph_index) co FT_Error error = FT_Load_Glyph(mFTFace, glyph_index, load_flags); if (FT_Err_Ok != error) { + if (error == FT_Err_Out_Of_Memory) + { + LLError::LLUserWarningMsg::showOutOfMemory(); + LL_ERRS() << "Out of memory loading glyph for character " << llformat("U+%xu", U32(wch)) << LL_ENDL; + } + std::string message = llformat( - "Error %d (%s) loading glyph %u: bitmap_type=%u, load_flags=%d", - error, FT_Error_String(error), glyph_index, bitmap_type, load_flags); + "Error %d (%s) loading wchar %u glyph %u/%u: bitmap_type=%u, load_flags=%d", + error, FT_Error_String(error), wch, glyph_index, mFTFace->num_glyphs, bitmap_type, load_flags); LL_WARNS_ONCE() << message << LL_ENDL; error = FT_Load_Glyph(mFTFace, glyph_index, load_flags ^ FT_LOAD_COLOR); + if (FT_Err_Invalid_Outline == error + || FT_Err_Invalid_Composite == error + || (FT_Err_Ok != error && LLStringOps::isEmoji(wch))) + { + // value~0 always corresponds to the 'missing glyph' + error = FT_Load_Glyph(mFTFace, 0, FT_LOAD_FORCE_AUTOHINT); + if (FT_Err_Ok != error) + { + LL_ERRS() << "Loading fallback for char '" << (U32)wch << "', glyph " << glyph_index << " failed with error : " << (S32)error << LL_ENDL; + } + } llassert_always_msg(FT_Err_Ok == error, message.c_str()); } diff --git a/indra/llrender/llfontfreetype.h b/indra/llrender/llfontfreetype.h index eba89f5def..783bf4a4b3 100644 --- a/indra/llrender/llfontfreetype.h +++ b/indra/llrender/llfontfreetype.h @@ -156,7 +156,7 @@ private: bool hasGlyph(llwchar wch) const; // Has a glyph for this character LLFontGlyphInfo* addGlyph(llwchar wch, EFontGlyphType glyph_type) const; // Add a new character to the font if necessary LLFontGlyphInfo* addGlyphFromFont(const LLFontFreetype *fontp, llwchar wch, U32 glyph_index, EFontGlyphType bitmap_type) const; // Add a glyph from this font to the other (returns the glyph_index, 0 if not found) - void renderGlyph(EFontGlyphType bitmap_type, U32 glyph_index) const; + void renderGlyph(EFontGlyphType bitmap_type, U32 glyph_index, llwchar wch) const; void insertGlyphInfo(llwchar wch, LLFontGlyphInfo* gi) const; std::string mName; @@ -187,7 +187,6 @@ private: mutable LLFontBitmapCache* mFontBitmapCachep; mutable S32 mRenderGlyphCount; - mutable S32 mAddGlyphCount; }; #endif // LL_FONTFREETYPE_H diff --git a/indra/llrender/llfontfreetypesvg.cpp b/indra/llrender/llfontfreetypesvg.cpp index 71f751329e..04825ae8a3 100644 --- a/indra/llrender/llfontfreetypesvg.cpp +++ b/indra/llrender/llfontfreetypesvg.cpp @@ -34,9 +34,17 @@ #endif #define NANOSVG_IMPLEMENTATION +#if __FreeBSD__ +#include <nanosvg.h> +#else #include <nanosvg/nanosvg.h> +#endif #define NANOSVGRAST_IMPLEMENTATION +#if __FreeBSD__ +#include <nanosvgrast.h> +#else #include <nanosvg/nanosvgrast.h> +#endif #if LL_WINDOWS #pragma warning (pop) @@ -80,6 +88,7 @@ void LLFontFreeTypeSvgRenderer::OnDataFinalizer(void* objectp) //static FT_Error LLFontFreeTypeSvgRenderer::OnPresetGlypthSlot(FT_GlyphSlot glyph_slot, FT_Bool cache, FT_Pointer*) { +#ifndef LL_NO_OTSVG FT_SVG_Document document = static_cast<FT_SVG_Document>(glyph_slot->other); llassert(!glyph_slot->generic.data || !cache || glyph_slot->glyph_index == ((LLSvgRenderData*)glyph_slot->generic.data)->GlyphIndex); @@ -166,6 +175,9 @@ FT_Error LLFontFreeTypeSvgRenderer::OnPresetGlypthSlot(FT_GlyphSlot glyph_slot, } return FT_Err_Ok; +#else + return FT_Err_Unimplemented_Feature; +#endif } // static diff --git a/indra/llrender/llfontfreetypesvg.h b/indra/llrender/llfontfreetypesvg.h index 4170cab273..94b83d5fff 100644 --- a/indra/llrender/llfontfreetypesvg.h +++ b/indra/llrender/llfontfreetypesvg.h @@ -29,7 +29,11 @@ #include <ft2build.h> #include FT_TYPES_H #include FT_MODULE_H -#include FT_OTSVG_H +#ifdef FT_OTSVG_H + #include FT_OTSVG_H +#else + #define LL_NO_OTSVG +#endif // See https://freetype.org/freetype2/docs/reference/ft2-svg_fonts.html class LLFontFreeTypeSvgRenderer diff --git a/indra/llrender/llfontgl.cpp b/indra/llrender/llfontgl.cpp index 4c9a062246..16eec1fdd2 100644 --- a/indra/llrender/llfontgl.cpp +++ b/indra/llrender/llfontgl.cpp @@ -58,6 +58,7 @@ F32 LLFontGL::sVertDPI = 96.f; F32 LLFontGL::sHorizDPI = 96.f; F32 LLFontGL::sScaleX = 1.f; F32 LLFontGL::sScaleY = 1.f; +S32 LLFontGL::sResolutionGeneration = 0; bool LLFontGL::sDisplayFont = true ; std::string LLFontGL::sAppDir; @@ -109,6 +110,12 @@ S32 LLFontGL::getNumFaces(const std::string& filename) return mFontFreetype->getNumFaces(filename); } +S32 LLFontGL::getCacheGeneration() const +{ + const LLFontBitmapCache* font_bitmap_cache = mFontFreetype->getFontBitmapCache(); + return font_bitmap_cache->getCacheGeneration(); +} + S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, const LLRect& rect, const LLColor4 &color, HAlign halign, VAlign valign, U8 style, ShadowType shadow, S32 max_chars, F32* right_x, bool use_ellipses, bool use_color) const { @@ -249,6 +256,10 @@ S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, F32 x, F32 y, cons const LLFontBitmapCache* font_bitmap_cache = mFontFreetype->getFontBitmapCache(); + // This looks wrong, value is dynamic. + // LLFontBitmapCache::nextOpenPos can alter these values when + // new characters get added to cache, which affects whole string. + // Todo: Perhaps value should update after symbols were added? F32 inv_width = 1.f / font_bitmap_cache->getBitmapWidth(); F32 inv_height = 1.f / font_bitmap_cache->getBitmapHeight(); @@ -270,6 +281,10 @@ S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, F32 x, F32 y, cons const LLFontGlyphInfo* next_glyph = NULL; + // string can have more than one glyph per char (ex: bold or shadow), + // make sure that GLYPH_BATCH_SIZE won't end up with half a symbol. + // See drawGlyph. + // Ex: with shadows it's 6 glyps per char. 30 fits exactly 5 chars. static constexpr S32 GLYPH_BATCH_SIZE = 30; static thread_local LLVector4a vertices[GLYPH_BATCH_SIZE * 6]; static thread_local LLVector2 uvs[GLYPH_BATCH_SIZE * 6]; @@ -282,6 +297,7 @@ S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, F32 x, F32 y, cons std::pair<EFontGlyphType, S32> bitmap_entry = std::make_pair(EFontGlyphType::Grayscale, -1); S32 glyph_count = 0; + llwchar last_char = wstr[begin_offset]; for (i = begin_offset; i < begin_offset + length; i++) { llwchar wch = wstr[i]; @@ -299,7 +315,7 @@ S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, F32 x, F32 y, cons } // Per-glyph bitmap texture. std::pair<EFontGlyphType, S32> next_bitmap_entry = fgi->mBitmapEntry; - if (next_bitmap_entry != bitmap_entry) + if (next_bitmap_entry != bitmap_entry || last_char != wch) { // Actually draw the queued glyphs before switching their texture; // otherwise the queued glyphs will be taken from wrong textures. @@ -316,6 +332,11 @@ S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, F32 x, F32 y, cons bitmap_entry = next_bitmap_entry; LLImageGL* font_image = font_bitmap_cache->getImageGL(bitmap_entry.first, bitmap_entry.second); gGL.getTexUnit(0)->bind(font_image); + + // For some reason it's not enough to compare by bitmap_entry. + // Issue hits emojis, japenese and chinese glyphs, only on first run. + // Todo: figure it out, there might be a bug with raw image data. + last_char = wch; } if ((start_x + scaled_max_pixels) < (cur_x + fgi->mXBearing + fgi->mWidth)) diff --git a/indra/llrender/llfontgl.h b/indra/llrender/llfontgl.h index 4bb6c55c65..1c8e036f58 100644 --- a/indra/llrender/llfontgl.h +++ b/indra/llrender/llfontgl.h @@ -90,6 +90,7 @@ public: bool loadFace(const std::string& filename, F32 point_size, const F32 vert_dpi, const F32 horz_dpi, bool is_fallback, S32 face_n); S32 getNumFaces(const std::string& filename); + S32 getCacheGeneration() const; S32 render(const LLWString &text, S32 begin_offset, const LLRect& rect, @@ -224,6 +225,7 @@ public: static F32 sHorizDPI; static F32 sScaleX; static F32 sScaleY; + static S32 sResolutionGeneration; static bool sDisplayFont ; static std::string sAppDir; // For loading fonts diff --git a/indra/llrender/llfontvertexbuffer.cpp b/indra/llrender/llfontvertexbuffer.cpp index 5bd1ca5eed..a223509d30 100644 --- a/indra/llrender/llfontvertexbuffer.cpp +++ b/indra/llrender/llfontvertexbuffer.cpp @@ -146,7 +146,9 @@ S32 LLFontVertexBuffer::render( || mLastScaleY != LLFontGL::sScaleY || mLastVertDPI != LLFontGL::sVertDPI || mLastHorizDPI != LLFontGL::sHorizDPI - || mLastOrigin != LLFontGL::sCurOrigin) + || mLastOrigin != LLFontGL::sCurOrigin + || mLastResGeneration != LLFontGL::sResolutionGeneration + || mLastFontCacheGen != fontp->getCacheGeneration()) { genBuffers(fontp, text, begin_offset, x, y, color, halign, valign, style, shadow, max_chars, max_pixels, right_x, use_ellipses, use_color); @@ -178,6 +180,9 @@ void LLFontVertexBuffer::genBuffers( { // todo: add a debug build assert if this triggers too often for to long? mBufferList.clear(); + // Save before rendreing, it can change mid-render, + // so will need to rerender previous characters + mLastFontCacheGen = fontp->getCacheGeneration(); gGL.beginList(&mBufferList); mChars = fontp->render(text, begin_offset, x, y, color, halign, valign, @@ -201,6 +206,7 @@ void LLFontVertexBuffer::genBuffers( mLastVertDPI = LLFontGL::sVertDPI; mLastHorizDPI = LLFontGL::sHorizDPI; mLastOrigin = LLFontGL::sCurOrigin; + mLastResGeneration = LLFontGL::sResolutionGeneration; if (right_x) { diff --git a/indra/llrender/llfontvertexbuffer.h b/indra/llrender/llfontvertexbuffer.h index af195dfff9..a9e1e2337c 100644 --- a/indra/llrender/llfontvertexbuffer.h +++ b/indra/llrender/llfontvertexbuffer.h @@ -117,8 +117,13 @@ private: F32 mLastScaleY = 1.f; F32 mLastVertDPI = 0.f; F32 mLastHorizDPI = 0.f; + S32 mLastResGeneration = 0; LLCoordGL mLastOrigin; + // Adding new characters to bitmap cache can alter value from getBitmapWidth(); + // which alters whole string. So rerender when new characters were added to cache. + S32 mLastFontCacheGen = 0; + static bool sEnableBufferCollection; }; diff --git a/indra/llrender/llgl.cpp b/indra/llrender/llgl.cpp index 1bc5e79835..3b506d6965 100644 --- a/indra/llrender/llgl.cpp +++ b/indra/llrender/llgl.cpp @@ -76,7 +76,7 @@ static const std::string HEADLESS_VERSION_STRING("1.0"); llofstream gFailLog; -#if GL_ARB_debug_output +#if GL_ARB_debug_output || GL_KHR_debug #ifndef APIENTRY #define APIENTRY @@ -99,9 +99,9 @@ void APIENTRY gl_debug_callback(GLenum source, }*/ if (gGLManager.mIsDisabled && - severity == GL_DEBUG_SEVERITY_HIGH_ARB && - source == GL_DEBUG_SOURCE_API_ARB && - type == GL_DEBUG_TYPE_ERROR_ARB && + severity == GL_DEBUG_SEVERITY_HIGH && + source == GL_DEBUG_SOURCE_API && + type == GL_DEBUG_TYPE_ERROR && id == GL_INVALID_VALUE) { // Suppress messages about deleting already deleted objects called from LLViewerWindow::stopGL() @@ -161,7 +161,11 @@ void APIENTRY gl_debug_callback(GLenum source, if (ubo != 0) { glGetBufferParameteriv(GL_UNIFORM_BUFFER, GL_BUFFER_SIZE, &ubo_size); +#if GL_EXT_buffer_storage + glGetBufferParameteriv(GL_UNIFORM_BUFFER, GL_BUFFER_IMMUTABLE_STORAGE_EXT, &ubo_immutable); +#else glGetBufferParameteriv(GL_UNIFORM_BUFFER, GL_BUFFER_IMMUTABLE_STORAGE, &ubo_immutable); +#endif } // No needs to halt when is called from LLViewerWindow::stopGL() @@ -215,8 +219,6 @@ LLMatrix4 gGLObliqueProjectionInverse; std::list<LLGLUpdate*> LLGLUpdate::sGLQ; -#if (LL_WINDOWS || LL_LINUX) && !LL_MESA_HEADLESS - #if LL_WINDOWS // WGL_ARB_create_context PFNWGLCREATECONTEXTATTRIBSARBPROC wglCreateContextAttribsARB = nullptr; @@ -236,7 +238,7 @@ PFNWGLBLITCONTEXTFRAMEBUFFERAMDPROC wglBlitContextFramebufferAMD = n PFNWGLSWAPINTERVALEXTPROC wglSwapIntervalEXT = nullptr; PFNWGLGETSWAPINTERVALEXTPROC wglGetSwapIntervalEXT = nullptr; -#endif +/* // GL_VERSION_1_2 //PFNGLDRAWRANGEELEMENTSPROC glDrawRangeElements = nullptr; @@ -982,6 +984,7 @@ PFNGLMULTIDRAWARRAYSINDIRECTCOUNTPROC glMultiDrawArraysIndirectCount = nullpt PFNGLMULTIDRAWELEMENTSINDIRECTCOUNTPROC glMultiDrawElementsIndirectCount = nullptr; PFNGLPOLYGONOFFSETCLAMPPROC glPolygonOffsetClamp = nullptr; +*/ #endif LLGLManager gGLManager; @@ -1136,6 +1139,7 @@ bool LLGLManager::initGL() #endif } +#if GL_VERSION_1_3 if (mGLVersion >= 2.1f && LLImageGL::sCompressTextures) { //use texture compression glHint(GL_TEXTURE_COMPRESSION_HINT, GL_NICEST); @@ -1144,6 +1148,7 @@ bool LLGLManager::initGL() { //GL version is < 3.0, always disable texture compression LLImageGL::sCompressTextures = false; } +#endif // Trailing space necessary to keep "nVidia Corpor_ati_on" cards // from being recognized as ATI. @@ -1160,7 +1165,7 @@ bool LLGLManager::initGL() mIsNVIDIA = true; } else if (mGLVendor.find("INTEL") != std::string::npos -#if LL_LINUX +#if LL_LINUX || __FreeBSD__ // The Mesa-based drivers put this in the Renderer string, // not the Vendor string. || mGLRenderer.find("INTEL") != std::string::npos @@ -1254,10 +1259,12 @@ bool LLGLManager::initGL() } glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &mNumTextureImageUnits); +#if GL_VERSION_3_2 glGetIntegerv(GL_MAX_COLOR_TEXTURE_SAMPLES, &mMaxColorTextureSamples); glGetIntegerv(GL_MAX_DEPTH_TEXTURE_SAMPLES, &mMaxDepthTextureSamples); glGetIntegerv(GL_MAX_INTEGER_SAMPLES, &mMaxIntegerSamples); glGetIntegerv(GL_MAX_SAMPLE_MASK_WORDS, &mMaxSampleMaskWords); +#endif glGetIntegerv(GL_MAX_SAMPLES, &mMaxSamples); glGetIntegerv(GL_MAX_VARYING_VECTORS, &mMaxVaryingVectors); glGetIntegerv(GL_MAX_UNIFORM_BLOCK_SIZE, &mMaxUniformBlockSize); @@ -1266,9 +1273,9 @@ bool LLGLManager::initGL() // there's some implementation that reports a crazy value mMaxUniformBlockSize = llmin(mMaxUniformBlockSize, 65536); - if (mGLVersion >= 4.59f) + if (mHasAnisotropic) { - glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY, &mMaxAnisotropy); + glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &mMaxAnisotropy); } initGLStates(); @@ -1408,6 +1415,9 @@ void LLGLManager::shutdownGL() void LLGLManager::initExtensions() { +#if LL_LINUX + glh_init_extensions(""); +#endif #if LL_DARWIN GLint num_extensions = 0; std::string all_extensions{""}; @@ -1430,6 +1440,11 @@ void LLGLManager::initExtensions() mHasCubeMapArray = mGLVersion >= 3.99f; mHasTransformFeedback = mGLVersion >= 3.99f; mHasDebugOutput = mGLVersion >= 4.29f; + mHasAnisotropic = mGLVersion >= 4.59f; + if(!mHasAnisotropic && gGLHExts.mSysExts) + { + mHasAnisotropic = ExtensionExists("GL_EXT_texture_filter_anisotropic", gGLHExts.mSysExts); + } // Misc glGetIntegerv(GL_MAX_ELEMENTS_VERTICES, (GLint*) &mGLMaxVertexRange); @@ -1438,10 +1453,10 @@ void LLGLManager::initExtensions() mInited = true; -#if (LL_WINDOWS || LL_LINUX) && !LL_MESA_HEADLESS +/* +#if LL_WINDOWS LL_DEBUGS("RenderInit") << "GL Probe: Getting symbols" << LL_ENDL; -#if LL_WINDOWS // WGL_AMD_gpu_association wglGetGPUIDsAMD = (PFNWGLGETGPUIDSAMDPROC)GLH_EXT_GET_PROC_ADDRESS("wglGetGPUIDsAMD"); wglGetGPUInfoAMD = (PFNWGLGETGPUINFOAMDPROC)GLH_EXT_GET_PROC_ADDRESS("wglGetGPUInfoAMD"); @@ -1459,8 +1474,6 @@ void LLGLManager::initExtensions() // WGL_ARB_create_context wglCreateContextAttribsARB = (PFNWGLCREATECONTEXTATTRIBSARBPROC)GLH_EXT_GET_PROC_ADDRESS("wglCreateContextAttribsARB"); -#endif - // Load entire OpenGL API through GetProcAddress, leaving sections beyond mGLVersion unloaded @@ -2278,6 +2291,7 @@ void LLGLManager::initExtensions() glPolygonOffsetClamp = (PFNGLPOLYGONOFFSETCLAMPPROC)GLH_EXT_GET_PROC_ADDRESS("glPolygonOffsetClamp"); #endif +*/ } void rotate_quat(LLQuaternion& rotation) @@ -2304,12 +2318,14 @@ void log_glerror() error = glGetError(); while (LL_UNLIKELY(error)) { +#if GLU_VERSION_1_1 GLubyte const * gl_error_msg = gluErrorString(error); if (NULL != gl_error_msg) { LL_WARNS() << "GL Error: " << error << " GL Error String: " << gl_error_msg << LL_ENDL ; } else +#endif // GLU_VERSION_1_1 { // gluErrorString returns NULL for some extensions' error codes. // you'll probably have to grep for the number in glext.h. @@ -2328,6 +2344,7 @@ void do_assert_glerror() if (LL_UNLIKELY(error)) { quit = true; +#if GLU_VERSION_1_1 GLubyte const * gl_error_msg = gluErrorString(error); if (NULL != gl_error_msg) { @@ -2340,6 +2357,7 @@ void do_assert_glerror() } } else +#endif // GLU_VERSION_1_1 { // gluErrorString returns NULL for some extensions' error codes. // you'll probably have to grep for the number in glext.h. @@ -2414,8 +2432,10 @@ void LLGLState::initClass() // sStateMap[GL_TEXTURE_2D] = GL_TRUE; //make sure multisample defaults to disabled +#if GL_EXT_multisample || GL_EXT_multisampled_compatibility sStateMap[GL_MULTISAMPLE] = GL_FALSE; glDisable(GL_MULTISAMPLE); +#endif } //static @@ -2430,6 +2450,7 @@ void LLGLState::restoreGL() void LLGLState::resetTextureStates() { gGL.flush(); +#if GL_VERSION_1_3 GLint maxTextureUnits; glGetIntegerv(GL_MAX_TEXTURE_UNITS_ARB, &maxTextureUnits); @@ -2439,6 +2460,7 @@ void LLGLState::resetTextureStates() glClientActiveTexture(GL_TEXTURE0+j); j == 0 ? gGL.getTexUnit(j)->enable(LLTexUnit::TT_TEXTURE) : gGL.getTexUnit(j)->disable(); } +#endif } void LLGLState::dumpStates() @@ -2458,12 +2480,15 @@ void LLGLState::checkStates(GLboolean writeAlpha) return; } - GLint src; - GLint dst; - glGetIntegerv(GL_BLEND_SRC, &src); - glGetIntegerv(GL_BLEND_DST, &dst); - llassert_always(src == GL_SRC_ALPHA); - llassert_always(dst == GL_ONE_MINUS_SRC_ALPHA); + GLint srcRGB, dstRGB, srcAlpha, dstAlpha; + glGetIntegerv(GL_BLEND_SRC_RGB, &srcRGB); + glGetIntegerv(GL_BLEND_DST_RGB, &dstRGB); + glGetIntegerv(GL_BLEND_SRC_ALPHA, &srcAlpha); + glGetIntegerv(GL_BLEND_DST_ALPHA, &dstAlpha); + llassert_always(srcRGB == GL_SRC_ALPHA); + llassert_always(srcAlpha == GL_SRC_ALPHA); + llassert_always(dstRGB == GL_ONE_MINUS_SRC_ALPHA); + llassert_always(dstAlpha == GL_ONE_MINUS_SRC_ALPHA); // disable for now until usage is consistent //GLboolean colorMask[4]; @@ -2588,6 +2613,7 @@ void parse_gl_version( S32* major, S32* minor, S32* release, std::string* vendor { return; } + LL_INFOS() << "GL: " << version << LL_ENDL; version_string->assign(version); @@ -2963,5 +2989,3 @@ extern "C" __declspec(dllexport) int AmdPowerXpressRequestHighPerformance = 1; } #endif - - diff --git a/indra/llrender/llgl.h b/indra/llrender/llgl.h index 24ba4d6deb..bf8368a7b3 100644 --- a/indra/llrender/llgl.h +++ b/indra/llrender/llgl.h @@ -160,18 +160,17 @@ void assert_glerror(); void clear_glerror(); +#if !LL_RELEASE_FOR_DOWNLOAD # define stop_glerror() assert_glerror() # define llglassertok() assert_glerror() - -// stop_glerror is still needed on OS X but has performance implications -// use macro below to conditionally add stop_glerror to non-release builds -// on OS X -#if LL_DARWIN && !LL_RELEASE_FOR_DOWNLOAD -#define STOP_GLERROR stop_glerror() +# define STOP_GLERROR stop_glerror() #else -#define STOP_GLERROR +# define stop_glerror() +# define llglassertok() +# define STOP_GLERROR #endif + #define llglassertok_always() assert_glerror() //////////////////////// diff --git a/indra/llrender/llglheaders.h b/indra/llrender/llglheaders.h index 3d4dc5e698..a2685376cd 100644 --- a/indra/llrender/llglheaders.h +++ b/indra/llrender/llglheaders.h @@ -27,7 +27,7 @@ #ifndef LL_LLGLHEADERS_H #define LL_LLGLHEADERS_H -#if LL_MESA +#if LL_MESA || LL_LINUX || __FreeBSD__ //---------------------------------------------------------------------------- // MESA headers // quotes so we get libraries/.../GL/ version @@ -41,6 +41,22 @@ # include "GL/glh_extensions.h" # undef __APPLE__ +#elif LL_LINUX +#define GL_GLEXT_PROTOTYPES +#define GLX_GLEXT_PROTOTYPES + +#include "GL/gl.h" +#include "GL/glext.h" +#include "GL/glu.h" + +// The __APPLE__ kludge is to make glh_extensions.h not symbol-clash horribly +# define __APPLE__ +# include "GL/glh_extensions.h" +# undef __APPLE__ + +# include "GL/glx.h" +# include "GL/glxext.h" + #elif LL_WINDOWS //---------------------------------------------------------------------------- // LL_WINDOWS @@ -823,10 +839,14 @@ extern PFNGLPOLYGONOFFSETCLAMPPROC glPolygonOffsetClamp; #define GL_EXT_separate_specular_color 1 #define GL_GLEXT_PROTOTYPES -#include "GL/glext.h" +#include <OpenGL/glext.h> + +#define GL_DO_NOT_WARN_IF_MULTI_GL_VERSION_HEADERS_INCLUDED +#include <OpenGL/gl3.h> #include "GL/glh_extensions.h" +#if 0 // These symbols don't exist on 10.3.9, so they have to be declared weak. Redeclaring them here fixes the problem. // Note that they also must not be called on 10.3.9. This should be taken care of by a runtime check for the existence of the GL extension. #include <AvailabilityMacros.h> @@ -1028,6 +1048,26 @@ extern void glGetBufferPointervARB (GLenum, GLenum, GLvoid* *); #endif #include <OpenGL/gl.h> +#endif // 0 + +#elif LL_LINUX + +#define GL_GLEXT_PROTOTYPES +#define GLX_GLEXT_PROTOTYPES + +#include "GL/gl.h" +#include "GL/glu.h" +#include "GL/glext.h" +#include "GL/glx.h" + +// The __APPLE__ kludge is to make glh_extensions.h not symbol-clash horribly +# define __APPLE__ +# include "GL/glh_extensions.h" +# undef __APPLE__ + +// #include <X11/Xlib.h> +// #include <X11/Xutil.h> +#include "GL/glh_extensions.h" #endif // LL_MESA / LL_WINDOWS / LL_DARWIN diff --git a/indra/llrender/llglslshader.cpp b/indra/llrender/llglslshader.cpp index b3f32fdc83..3d7bf500f1 100644 --- a/indra/llrender/llglslshader.cpp +++ b/indra/llrender/llglslshader.cpp @@ -255,12 +255,18 @@ void LLGLSLShader::placeProfileQuery(bool for_runtime) glGenQueries(1, &mPrimitivesQuery); } - glBeginQuery(GL_TIME_ELAPSED, mTimerQuery); +#if GL_EXT_timer_query || GL_EXT_disjoint_timer_query + glBeginQuery(GL_TIME_ELAPSED_EXT, mTimerQuery); +#endif if (!for_runtime) { +#if GL_VERSION_1_5 glBeginQuery(GL_SAMPLES_PASSED, mSamplesQuery); +#endif +#if GL_VERSION_3_0 glBeginQuery(GL_PRIMITIVES_GENERATED, mPrimitivesQuery); +#endif } } } @@ -271,19 +277,30 @@ bool LLGLSLShader::readProfileQuery(bool for_runtime, bool force_read) { if (!mProfilePending) { - glEndQuery(GL_TIME_ELAPSED); +#if GL_EXT_timer_query || GL_EXT_disjoint_timer_query + glEndQuery(GL_TIME_ELAPSED_EXT); +#endif if (!for_runtime) { +#if GL_VERSION_1_5 glEndQuery(GL_SAMPLES_PASSED); +#endif +#if GL_VERSION_3_0 glEndQuery(GL_PRIMITIVES_GENERATED); +#endif } mProfilePending = for_runtime; } if (mProfilePending && for_runtime && !force_read) { +#if GL_ARB_timer_query GLuint64 result = 0; glGetQueryObjectui64v(mTimerQuery, GL_QUERY_RESULT_AVAILABLE, &result); +#else + GLuint result = 0; + glGetQueryObjectuiv(mTimerQuery, GL_QUERY_RESULT_AVAILABLE, &result); +#endif if (result != GL_TRUE) { @@ -291,22 +308,34 @@ bool LLGLSLShader::readProfileQuery(bool for_runtime, bool force_read) } } +#if GL_ARB_timer_query GLuint64 time_elapsed = 0; glGetQueryObjectui64v(mTimerQuery, GL_QUERY_RESULT, &time_elapsed); +#else + GLuint time_elapsed = 0; + glGetQueryObjectuiv(mTimerQuery, GL_QUERY_RESULT, &time_elapsed); +#endif mTimeElapsed += time_elapsed; mProfilePending = false; if (!for_runtime) { +#if GL_ARB_timer_query GLuint64 samples_passed = 0; glGetQueryObjectui64v(mSamplesQuery, GL_QUERY_RESULT, &samples_passed); GLuint64 primitives_generated = 0; glGetQueryObjectui64v(mPrimitivesQuery, GL_QUERY_RESULT, &primitives_generated); +#else + GLuint primitives_generated = 0; + glGetQueryObjectuiv(mPrimitivesQuery, GL_QUERY_RESULT, &primitives_generated); +#endif sTotalTimeElapsed += time_elapsed; +#if GL_VERSION_1_5 sTotalSamplesDrawn += samples_passed; mSamplesDrawn += samples_passed; +#endif U32 tri_count = (U32)primitives_generated / 3; @@ -721,10 +750,14 @@ void LLGLSLShader::mapUniform(GLint index) case GL_FLOAT_VEC2: size *= 2; break; case GL_FLOAT_VEC3: size *= 3; break; case GL_FLOAT_VEC4: size *= 4; break; +#if GL_VERSION_1_1 case GL_DOUBLE: size *= 2; break; +#if GL_VERSION_4_0 case GL_DOUBLE_VEC2: size *= 2; break; case GL_DOUBLE_VEC3: size *= 6; break; case GL_DOUBLE_VEC4: size *= 8; break; +#endif // GL_VERSION_4_0 +#endif // GL_VERSION_1_1 case GL_INT_VEC2: size *= 2; break; case GL_INT_VEC3: size *= 3; break; case GL_INT_VEC4: size *= 4; break; @@ -743,6 +776,7 @@ void LLGLSLShader::mapUniform(GLint index) case GL_FLOAT_MAT3x4: size *= 12; break; case GL_FLOAT_MAT4x2: size *= 8; break; case GL_FLOAT_MAT4x3: size *= 12; break; +#if GL_VERSION_4_0 case GL_DOUBLE_MAT2: size *= 8; break; case GL_DOUBLE_MAT3: size *= 18; break; case GL_DOUBLE_MAT4: size *= 32; break; @@ -752,6 +786,7 @@ void LLGLSLShader::mapUniform(GLint index) case GL_DOUBLE_MAT3x4: size *= 24; break; case GL_DOUBLE_MAT4x2: size *= 16; break; case GL_DOUBLE_MAT4x3: size *= 24; break; +#endif // GL_VERSION_4_0 } mTotalUniformSize += size; } @@ -815,7 +850,10 @@ GLint LLGLSLShader::mapUniformTextureChannel(GLint location, GLenum type, GLint { LL_PROFILE_ZONE_SCOPED_CATEGORY_SHADER; - if ((type >= GL_SAMPLER_1D && type <= GL_SAMPLER_2D_RECT_SHADOW) || + if ( +#if GL_VERSION_2_0 + (type >= GL_SAMPLER_1D && type <= GL_SAMPLER_2D_RECT_SHADOW) || +#endif type == GL_SAMPLER_2D_MULTISAMPLE || type == GL_SAMPLER_CUBE_MAP_ARRAY) { //this here is a texture diff --git a/indra/llrender/llglslshader.h b/indra/llrender/llglslshader.h index 58c456f134..873ab0cff5 100644 --- a/indra/llrender/llglslshader.h +++ b/indra/llrender/llglslshader.h @@ -59,6 +59,7 @@ public: bool attachNothing = false; bool hasHeroProbes = false; bool isPBRTerrain = false; + bool hasTonemap = false; }; // ============= Structure for caching shader uniforms =============== diff --git a/indra/llrender/llglstates.h b/indra/llrender/llglstates.h index 9bb980d7ad..68d4df8e90 100644 --- a/indra/llrender/llglstates.h +++ b/indra/llrender/llglstates.h @@ -166,6 +166,7 @@ public: //---------------------------------------------------------------------------- +#if GL_VERSION_1_1 class LLGLSSpecular { public: @@ -190,6 +191,7 @@ public: } } }; +#endif //---------------------------------------------------------------------------- diff --git a/indra/llrender/llimagegl.cpp b/indra/llrender/llimagegl.cpp index 3858811a50..0146ed3119 100644 --- a/indra/llrender/llimagegl.cpp +++ b/indra/llrender/llimagegl.cpp @@ -301,40 +301,61 @@ S32 LLImageGL::dataFormatBits(S32 dataformat) { switch (dataformat) { +#if GL_VERSION_3_0 case GL_COMPRESSED_RED: return 8; case GL_COMPRESSED_RG: return 16; +#endif +#if GL_VERSION_1_3 case GL_COMPRESSED_RGB: return 24; +#endif +#if GL_VERSION_2_1 case GL_COMPRESSED_SRGB: return 32; +#endif +#if GL_VERSION_1_3 case GL_COMPRESSED_RGBA: return 32; +#endif +#if GL_VERSION_2_1 case GL_COMPRESSED_SRGB_ALPHA: return 32; +#endif +#if GL_VERSION_1_3 case GL_COMPRESSED_LUMINANCE: return 8; case GL_COMPRESSED_LUMINANCE_ALPHA: return 16; case GL_COMPRESSED_ALPHA: return 8; +#endif +#if GL_EXT_texture_compression_s3tc || GL_EXT_texture_compression_dxt1 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: return 4; - case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT: return 4; case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT: return 8; - case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT: return 8; case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: return 8; +#endif +#if GL_EXT_texture_sRGB || GL_EXT_texture_compression_s3tc_srgb + case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT: return 4; + case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT: return 8; case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT: return 8; +#endif case GL_LUMINANCE: return 8; - case GL_LUMINANCE8: return 8; case GL_ALPHA: return 8; - case GL_ALPHA8: return 8; case GL_RED: return 8; case GL_R8: return 8; +#if GL_VERSION_1_1 + case GL_LUMINANCE8: return 8; + case GL_ALPHA8: return 8; case GL_COLOR_INDEX: return 8; - case GL_LUMINANCE_ALPHA: return 16; case GL_LUMINANCE8_ALPHA8: return 16; +#endif + case GL_LUMINANCE_ALPHA: return 16; case GL_RG: return 16; case GL_RG8: return 16; case GL_RGB: return 24; case GL_SRGB: return 24; case GL_RGB8: return 24; + case GL_R11F_G11F_B10F: return 32; case GL_RGBA: return 32; case GL_RGBA8: return 32; case GL_RGB10_A2: return 32; +#if GL_VERSION_2_1 case GL_SRGB_ALPHA: return 32; case GL_BGRA: return 32; // Used for QuickTime media textures on the Mac +#endif case GL_DEPTH_COMPONENT: return 24; case GL_DEPTH_COMPONENT24: return 24; case GL_R16F: return 16; @@ -356,6 +377,8 @@ S64 LLImageGL::dataFormatBytes(S32 dataformat, S32 width, S32 height) { switch (dataformat) { +#if GL_EXT_texture_compression_s3tc || GL_EXT_texture_compression_dxt1 \ + || GL_EXT_texture_sRGB || GL_EXT_texture_compression_s3tc_srgb case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT: case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT: @@ -365,6 +388,7 @@ S64 LLImageGL::dataFormatBytes(S32 dataformat, S32 width, S32 height) if (width < 4) width = 4; if (height < 4) height = 4; break; +#endif default: break; } @@ -378,23 +402,31 @@ S32 LLImageGL::dataFormatComponents(S32 dataformat) { switch (dataformat) { +#if GL_EXT_texture_compression_s3tc || GL_EXT_texture_compression_dxt1 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: return 3; - case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT: return 3; case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT: return 4; - case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT: return 4; case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: return 4; +#endif +#if GL_EXT_texture_sRGB || GL_EXT_texture_compression_s3tc_srgb + case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT: return 3; + case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT: return 4; case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT: return 4; +#endif case GL_LUMINANCE: return 1; case GL_ALPHA: return 1; case GL_RED: return 1; +#if GL_VERSION_1_1 case GL_COLOR_INDEX: return 1; +#endif case GL_LUMINANCE_ALPHA: return 2; case GL_RG: return 2; case GL_RGB: return 3; case GL_SRGB: return 3; case GL_RGBA: return 4; +#if GL_VERSION_2_1 case GL_SRGB_ALPHA: return 4; case GL_BGRA: return 4; // Used for QuickTime media textures on the Mac +#endif default: LL_ERRS() << "LLImageGL::Unknown format: " << std::hex << dataformat << std::dec << LL_ENDL; return 0; @@ -408,6 +440,8 @@ void LLImageGL::updateStats(F32 current_time) { LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; sLastFrameTime = current_time; + sBindCount = 0; + sUniqueCount = 0; } //---------------------------------------------------------------------------- @@ -794,11 +828,13 @@ bool LLImageGL::setImage(const U8* data_in, bool data_hasmips /* = false */, S32 } else { +#if GL_VERSION_1_1 if(mFormatSwapBytes) { glPixelStorei(GL_UNPACK_SWAP_BYTES, 1); stop_glerror(); } +#endif LLImageGL::setManualImage(mTarget, gl_level, mFormatInternal, w, h, mFormatPrimary, GL_UNSIGNED_BYTE, (GLvoid*)data_in, mAllowCompression); if (gl_level == 0) @@ -807,11 +843,13 @@ bool LLImageGL::setImage(const U8* data_in, bool data_hasmips /* = false */, S32 } updatePickMask(w, h, data_in); +#if GL_VERSION_1_1 if(mFormatSwapBytes) { glPixelStorei(GL_UNPACK_SWAP_BYTES, 0); stop_glerror(); } +#endif stop_glerror(); } @@ -824,11 +862,13 @@ bool LLImageGL::setImage(const U8* data_in, bool data_hasmips /* = false */, S32 { stop_glerror(); { +#if GL_VERSION_1_1 if(mFormatSwapBytes) { glPixelStorei(GL_UNPACK_SWAP_BYTES, 1); stop_glerror(); } +#endif S32 w = getWidth(mCurrentDiscardLevel); S32 h = getHeight(mCurrentDiscardLevel); @@ -838,10 +878,12 @@ bool LLImageGL::setImage(const U8* data_in, bool data_hasmips /* = false */, S32 //use legacy mipmap generation mode (note: making this condional can cause rendering issues) // -- but making it not conditional triggers deprecation warnings when core profile is enabled // (some rendering issues while core profile is enabled are acceptable at this point in time) +#if GL_VERSION_1_4 if (!LLRender::sGLCoreProfile) { glTexParameteri(mTarget, GL_GENERATE_MIPMAP, GL_TRUE); } +#endif LLImageGL::setManualImage(mTarget, 0, mFormatInternal, w, h, @@ -852,11 +894,13 @@ bool LLImageGL::setImage(const U8* data_in, bool data_hasmips /* = false */, S32 updatePickMask(w, h, data_in); +#if GL_VERSION_1_1 if(mFormatSwapBytes) { glPixelStorei(GL_UNPACK_SWAP_BYTES, 0); stop_glerror(); } +#endif if (LLRender::sGLCoreProfile) { @@ -941,11 +985,13 @@ bool LLImageGL::setImage(const U8* data_in, bool data_hasmips /* = false */, S32 llassert(w > 0 && h > 0 && cur_mip_data); (void)cur_mip_data; { +#if GL_VERSION_1_1 if(mFormatSwapBytes) { glPixelStorei(GL_UNPACK_SWAP_BYTES, 1); stop_glerror(); } +#endif LLImageGL::setManualImage(mTarget, m, mFormatInternal, w, h, mFormatPrimary, mFormatType, cur_mip_data, mAllowCompression); if (m == 0) @@ -958,11 +1004,13 @@ bool LLImageGL::setImage(const U8* data_in, bool data_hasmips /* = false */, S32 updatePickMask(w, h, cur_mip_data); } +#if GL_VERSION_1_1 if(mFormatSwapBytes) { glPixelStorei(GL_UNPACK_SWAP_BYTES, 0); stop_glerror(); } +#endif } if (prev_mip_data && prev_mip_data != data_in) { @@ -997,11 +1045,13 @@ bool LLImageGL::setImage(const U8* data_in, bool data_hasmips /* = false */, S32 } else { +#if GL_VERSION_1_1 if(mFormatSwapBytes) { glPixelStorei(GL_UNPACK_SWAP_BYTES, 1); stop_glerror(); } +#endif LLImageGL::setManualImage(mTarget, 0, mFormatInternal, w, h, mFormatPrimary, mFormatType, (GLvoid *)data_in, mAllowCompression); @@ -1011,11 +1061,13 @@ bool LLImageGL::setImage(const U8* data_in, bool data_hasmips /* = false */, S32 stop_glerror(); +#if GL_VERSION_1_1 if(mFormatSwapBytes) { glPixelStorei(GL_UNPACK_SWAP_BYTES, 0); stop_glerror(); } +#endif } } @@ -1031,7 +1083,9 @@ U32 type_width_from_pixtype(U32 pixtype) { case GL_UNSIGNED_BYTE: case GL_BYTE: +#if GL_VERSION_1_2 case GL_UNSIGNED_INT_8_8_8_8_REV: +#endif type_width = 1; break; case GL_UNSIGNED_SHORT: @@ -1178,11 +1232,13 @@ bool LLImageGL::setSubImage(const U8* datap, S32 data_width, S32 data_height, S3 glPixelStorei(GL_UNPACK_ROW_LENGTH, data_width); stop_glerror(); +#if GL_VERSION_1_1 if(mFormatSwapBytes) { glPixelStorei(GL_UNPACK_SWAP_BYTES, 1); stop_glerror(); } +#endif const U8* sub_datap = datap + (y_pos * data_width + x_pos) * getComponents(); // Update the GL texture @@ -1206,11 +1262,13 @@ bool LLImageGL::setSubImage(const U8* datap, S32 data_width, S32 data_height, S3 gGL.getTexUnit(0)->disable(); stop_glerror(); +#if GL_VERSION_1_1 if(mFormatSwapBytes) { glPixelStorei(GL_UNPACK_SWAP_BYTES, 0); stop_glerror(); } +#endif glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); stop_glerror(); @@ -1315,24 +1373,30 @@ void LLImageGL::setManualImage(U32 target, S32 miplevel, S32 intformat, S32 widt { if (pixformat == GL_ALPHA) { //GL_ALPHA is deprecated, convert to RGBA +#if GL_VERSION_3_3 const GLint mask[] = { GL_ZERO, GL_ZERO, GL_ZERO, GL_RED }; glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_RGBA, mask); +#endif pixformat = GL_RED; intformat = GL_R8; } if (pixformat == GL_LUMINANCE) { //GL_LUMINANCE is deprecated, convert to GL_RGBA +#if GL_VERSION_3_3 const GLint mask[] = { GL_RED, GL_RED, GL_RED, GL_ONE }; glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_RGBA, mask); +#endif pixformat = GL_RED; intformat = GL_R8; } if (pixformat == GL_LUMINANCE_ALPHA) { //GL_LUMINANCE_ALPHA is deprecated, convert to RGBA +#if GL_VERSION_3_3 const GLint mask[] = { GL_RED, GL_RED, GL_RED, GL_GREEN }; glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_RGBA, mask); +#endif pixformat = GL_RG; intformat = GL_RG8; } @@ -1409,39 +1473,63 @@ void LLImageGL::setManualImage(U32 target, S32 miplevel, S32 intformat, S32 widt { case GL_RED: case GL_R8: +#if GL_VERSION_3_0 intformat = GL_COMPRESSED_RED; +#endif break; case GL_RG: case GL_RG8: +#if GL_VERSION_3_0 intformat = GL_COMPRESSED_RG; +#endif break; case GL_RGB: case GL_RGB8: +#if GL_VERSION_1_3 intformat = GL_COMPRESSED_RGB; +#endif break; case GL_SRGB: case GL_SRGB8: +#if GL_VERSION_2_1 intformat = GL_COMPRESSED_SRGB; +#endif break; case GL_RGBA: case GL_RGBA8: +#if GL_VERSION_1_3 intformat = GL_COMPRESSED_RGBA; +#endif break; - case GL_SRGB_ALPHA: case GL_SRGB8_ALPHA8: +#if GL_VERSION_2_1 + case GL_SRGB_ALPHA: intformat = GL_COMPRESSED_SRGB_ALPHA; +#endif break; case GL_LUMINANCE: +#if GL_VERSION_1_1 case GL_LUMINANCE8: +#endif +#if GL_VERSION_1_3 intformat = GL_COMPRESSED_LUMINANCE; +#endif break; case GL_LUMINANCE_ALPHA: +#if GL_VERSION_1_1 case GL_LUMINANCE8_ALPHA8: +#endif +#if GL_VERSION_1_3 intformat = GL_COMPRESSED_LUMINANCE_ALPHA; +#endif break; case GL_ALPHA: +#if GL_VERSION_1_1 case GL_ALPHA8: +#endif +#if GL_VERSION_1_3 intformat = GL_COMPRESSED_ALPHA; +#endif break; default: LL_WARNS() << "Could not compress format: " << std::hex << intformat << std::dec << LL_ENDL; @@ -1575,13 +1663,21 @@ bool LLImageGL::createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S { case 1: // Use luminance alpha (for fonts) +#if GL_VERSION_1_1 mFormatInternal = GL_LUMINANCE8; +#else + mFormatInternal = GL_LUMINANCE; +#endif mFormatPrimary = GL_LUMINANCE; mFormatType = GL_UNSIGNED_BYTE; break; case 2: // Use luminance alpha (for fonts) +#if GL_VERSION_1_1 mFormatInternal = GL_LUMINANCE8_ALPHA8; +#else + mFormatInternal = GL_LUMINANCE_ALPHA; +#endif mFormatPrimary = GL_LUMINANCE_ALPHA; mFormatType = GL_UNSIGNED_BYTE; break; @@ -1773,7 +1869,7 @@ void LLImageGL::syncToMainThread(LLGLuint new_tex_name) ref(); LL::WorkQueue::postMaybe( mMainQueue, - [=]() + [=, this]() { LL_PROFILE_ZONE_NAMED("cglt - delete callback"); syncTexName(new_tex_name); @@ -1863,6 +1959,7 @@ bool LLImageGL::readBackRaw(S32 discard_level, LLImageRaw* imageraw, bool compre LLImageDataLock lock(imageraw); +#if GL_VERSION_1_3 if (is_compressed) { LLGLint glbytes; @@ -1889,6 +1986,7 @@ bool LLImageGL::readBackRaw(S32 discard_level, LLImageRaw* imageraw, bool compre glGetTexImage(GL_TEXTURE_2D, gl_discard, mFormatPrimary, mFormatType, (GLvoid*)(imageraw->getData())); //stop_glerror(); } +#endif // GL_VERSION_1_3 //----------------------------------------------------------------------------------------------- if((error = glGetError()) != GL_NO_ERROR) @@ -1977,11 +2075,13 @@ bool LLImageGL::getIsResident(bool test_now) { if (test_now) { +#if GL_VERSION_1_1 if (mTexName != 0) { glAreTexturesResident(1, (GLuint*)&mTexName, &mIsResident); } else +#endif { mIsResident = false; } @@ -2111,12 +2211,16 @@ void LLImageGL::calcAlphaChannelOffsetAndStride() mIsMask = false; return; //no alpha channel. case GL_RGBA: +#if GL_VERSION_2_1 case GL_SRGB_ALPHA: +#endif mAlphaStride = 4; break; +#if GL_EXT_bgra case GL_BGRA_EXT: mAlphaStride = 4; break; +#endif default: break; } @@ -2126,6 +2230,7 @@ void LLImageGL::calcAlphaChannelOffsetAndStride() { mAlphaOffset = mAlphaStride - 1 ; } +#if GL_VERSION_1_2 else if(is_little_endian()) { if (mFormatType == GL_UNSIGNED_INT_8_8_8_8) @@ -2148,10 +2253,15 @@ void LLImageGL::calcAlphaChannelOffsetAndStride() mAlphaOffset = 0 ; } } +#endif // GL_VERSION_1_2 if( mAlphaStride < 1 || //unsupported format - mAlphaOffset < 0 || //unsupported type - (mFormatPrimary == GL_BGRA_EXT && mFormatType != GL_UNSIGNED_BYTE)) //unknown situation + mAlphaOffset < 0 //unsupported type +#if GL_EXT_bgra + || + (mFormatPrimary == GL_BGRA_EXT && mFormatType != GL_UNSIGNED_BYTE) //unknown situation +#endif + ) { LL_WARNS() << "Cannot analyze alpha for image with format type " << std::hex << mFormatType << std::dec << LL_ENDL; @@ -2299,6 +2409,8 @@ bool LLImageGL::isCompressed() bool is_compressed = false; switch (mFormatPrimary) { +#if GL_EXT_texture_compression_s3tc || GL_EXT_texture_compression_dxt1 \ + || GL_EXT_texture_sRGB || GL_EXT_texture_compression_s3tc_srgb case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT: case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT: @@ -2307,6 +2419,7 @@ bool LLImageGL::isCompressed() case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT: is_compressed = true; break; +#endif default: break; } @@ -2323,7 +2436,10 @@ void LLImageGL::updatePickMask(S32 width, S32 height, const U8* data_in) if (mFormatType != GL_UNSIGNED_BYTE || ((mFormatPrimary != GL_RGBA) - && (mFormatPrimary != GL_SRGB_ALPHA))) +#if GL_VERSION_2_1 + && (mFormatPrimary != GL_SRGB_ALPHA) +#endif + )) { //cannot generate a pick mask for this texture freePickMask(); @@ -2503,7 +2619,9 @@ bool LLImageGL::scaleDown(S32 desired_discard) sScratchPBOSize = (U32)size; } +#if GL_VERSION_1_3 glGetTexImage(mTarget, mip, mFormatPrimary, mFormatType, nullptr); +#endif free_tex_image(mTexName); diff --git a/indra/llrender/llpostprocess.cpp b/indra/llrender/llpostprocess.cpp index eef7193c92..2e70c6953d 100644 --- a/indra/llrender/llpostprocess.cpp +++ b/indra/llrender/llpostprocess.cpp @@ -296,8 +296,10 @@ void LLPostProcess::getShaderUniforms(glslUniforms & uniforms, GLuint & prog) void LLPostProcess::doEffects(void) { /// Save GL State +#if GL_VERSION_1_1 glPushAttrib(GL_ALL_ATTRIB_BITS); glPushClientAttrib(GL_ALL_ATTRIB_BITS); +#endif /// Copy the screen buffer to the render texture { @@ -322,15 +324,19 @@ void LLPostProcess::doEffects(void) viewPerspective(); /// Reset GL State +#if GL_VERSION_1_1 glPopClientAttrib(); glPopAttrib(); +#endif checkError(); } void LLPostProcess::copyFrameBuffer(U32 & texture, unsigned int width, unsigned int height) { gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, texture); +#if GL_VERSION_3_1 glCopyTexImage2D(GL_TEXTURE_RECTANGLE, 0, GL_RGBA, 0, 0, width, height, 0); +#endif } void LLPostProcess::drawOrthoQuad(unsigned int width, unsigned int height, QuadType type) @@ -371,8 +377,10 @@ void LLPostProcess::createTexture(LLPointer<LLImageGL>& texture, unsigned int wi if(texture->createGLTexture()) { gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, texture->getTexName()); +#if GL_VERSION_3_1 glTexImage2D(GL_TEXTURE_RECTANGLE, 0, 4, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, &data[0]); +#endif gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR); gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_CLAMP); } @@ -406,18 +414,22 @@ bool LLPostProcess::checkError(void) while (glErr != GL_NO_ERROR) { // shaderErrorLog << (const char *) gluErrorString(glErr) << std::endl; +#if GLU_VERSION_1_1 char const * err_str_raw = (const char *) gluErrorString(glErr); if(err_str_raw == NULL) { +#endif std::ostringstream err_builder; err_builder << "unknown error number " << glErr; mShaderErrorString = err_builder.str(); +#if GLU_VERSION_1_1 } else { mShaderErrorString = err_str_raw; } +#endif retCode = true; glErr = glGetError(); diff --git a/indra/llrender/llrender.cpp b/indra/llrender/llrender.cpp index 1d53850f74..cbb178b6f8 100644 --- a/indra/llrender/llrender.cpp +++ b/indra/llrender/llrender.cpp @@ -84,10 +84,16 @@ static thread_local std::list<LLVertexBufferData> *sBufferDataList = nullptr; static const GLenum sGLTextureType[] = { GL_TEXTURE_2D, +#if GL_VERSION_3_1 GL_TEXTURE_RECTANGLE, +#endif GL_TEXTURE_CUBE_MAP, +#if GL_VERSION_4_0 GL_TEXTURE_CUBE_MAP_ARRAY, +#endif +#if GL_VERSION_3_2 GL_TEXTURE_2D_MULTISAMPLE, +#endif GL_TEXTURE_3D }; @@ -511,21 +517,22 @@ void LLTexUnit::setTextureFilteringOption(LLTexUnit::eTextureFilterOptions optio } } - if (gGLManager.mGLVersion >= 4.59f) + if (gGLManager.mHasAnisotropic) { if (LLImageGL::sGlobalUseAnisotropic && option == TFO_ANISOTROPIC) { - glTexParameterf(sGLTextureType[mCurrTexType], GL_TEXTURE_MAX_ANISOTROPY, gGLManager.mMaxAnisotropy); + glTexParameterf(sGLTextureType[mCurrTexType], GL_TEXTURE_MAX_ANISOTROPY_EXT, gGLManager.mMaxAnisotropy); } else { - glTexParameterf(sGLTextureType[mCurrTexType], GL_TEXTURE_MAX_ANISOTROPY, 1.f); + glTexParameterf(sGLTextureType[mCurrTexType], GL_TEXTURE_MAX_ANISOTROPY_EXT, 1.f); } } } GLint LLTexUnit::getTextureSource(eTextureBlendSrc src) { +#if GL_VERSION_1_3 switch(src) { // All four cases should return the same value. @@ -540,8 +547,10 @@ GLint LLTexUnit::getTextureSource(eTextureBlendSrc src) case TBS_TEX_ALPHA: case TBS_ONE_MINUS_TEX_COLOR: case TBS_ONE_MINUS_TEX_ALPHA: +#endif return GL_TEXTURE; +#if GL_VERSION_1_3 // All four cases should return the same value. case TBS_VERT_COLOR: case TBS_VERT_ALPHA: @@ -560,6 +569,7 @@ GLint LLTexUnit::getTextureSource(eTextureBlendSrc src) LL_WARNS() << "Unknown eTextureBlendSrc: " << src << ". Using Vertex Color instead." << LL_ENDL; return GL_PRIMARY_COLOR; } +#endif } GLint LLTexUnit::getTextureSourceType(eTextureBlendSrc src, bool isAlpha) @@ -606,7 +616,9 @@ void LLTexUnit::setColorScale(S32 scale) { mCurrColorScale = scale; gGL.flush(); +#if GL_VERSION_1_1 glTexEnvi( GL_TEXTURE_ENV, GL_RGB_SCALE, scale ); +#endif } } @@ -616,7 +628,9 @@ void LLTexUnit::setAlphaScale(S32 scale) { mCurrAlphaScale = scale; gGL.flush(); +#if GL_VERSION_1_1 glTexEnvi( GL_TEXTURE_ENV, GL_ALPHA_SCALE, scale ); +#endif } } @@ -737,9 +751,8 @@ void LLLightState::setPosition(const LLVector4& position) ++gGL.mLightHash; mPosition = position; //transform position by current modelview matrix - glm::vec4 pos(glm::make_vec4(position.mV)); - const glm::mat4& mat = gGL.getModelviewMatrix(); - pos = mat * pos; + glm::vec4 pos(position); + pos = gGL.getModelviewMatrix() * pos; mPosition.set(glm::value_ptr(pos)); } @@ -794,7 +807,7 @@ void LLLightState::setSpotDirection(const LLVector3& direction) ++gGL.mLightHash; //transform direction by current modelview matrix - glm::vec3 dir(glm::make_vec3(direction.mV)); + glm::vec3 dir(direction); const glm::mat3 mat(gGL.getModelviewMatrix()); dir = mat * dir; @@ -868,7 +881,9 @@ bool LLRender::init(bool needs_vertex_buffer) glCullFace(GL_BACK); // necessary for reflection maps +#if GL_VERSION_3_2 glEnable(GL_TEXTURE_CUBE_MAP_SEAMLESS); +#endif #if LL_WINDOWS if (glGenVertexArrays == nullptr) @@ -2021,9 +2036,11 @@ void LLRender::debugTexUnits(void) case LLTexUnit::TT_TEXTURE: LL_CONT << "Texture 2D"; break; +#if GL_VERSION_3_1 case LLTexUnit::TT_RECT_TEXTURE: LL_CONT << "Texture Rectangle"; break; +#endif case LLTexUnit::TT_CUBE_MAP: LL_CONT << "Cube Map"; break; @@ -2088,12 +2105,14 @@ void set_last_projection(const glm::mat4& mat) glm::vec3 mul_mat4_vec3(const glm::mat4& mat, const glm::vec3& vec) { - //const float w = vec[0] * mat[0][3] + vec[1] * mat[1][3] + vec[2] * mat[2][3] + mat[3][3]; - //return glm::vec3( - // (vec[0] * mat[0][0] + vec[1] * mat[1][0] + vec[2] * mat[2][0] + mat[3][0]) / w, - // (vec[0] * mat[0][1] + vec[1] * mat[1][1] + vec[2] * mat[2][1] + mat[3][1]) / w, - // (vec[0] * mat[0][2] + vec[1] * mat[1][2] + vec[2] * mat[2][2] + mat[3][2]) / w - //); +#if 1 // SIMD path results in strange crashes. Fall back to scalar for now. + const float w = vec[0] * mat[0][3] + vec[1] * mat[1][3] + vec[2] * mat[2][3] + mat[3][3]; + return glm::vec3( + (vec[0] * mat[0][0] + vec[1] * mat[1][0] + vec[2] * mat[2][0] + mat[3][0]) / w, + (vec[0] * mat[0][1] + vec[1] * mat[1][1] + vec[2] * mat[2][1] + mat[3][1]) / w, + (vec[0] * mat[0][2] + vec[1] * mat[1][2] + vec[2] * mat[2][2] + mat[3][2]) / w + ); +#else LLVector4a x, y, z, s, t, p, q; x.splat(vec.x); @@ -2123,4 +2142,5 @@ glm::vec3 mul_mat4_vec3(const glm::mat4& mat, const glm::vec3& vec) res.setAdd(x, z); res.div(q); return glm::make_vec3(res.getF32ptr()); +#endif } diff --git a/indra/llrender/llrender.h b/indra/llrender/llrender.h index 7b6bd4198b..97c47bcae9 100644 --- a/indra/llrender/llrender.h +++ b/indra/llrender/llrender.h @@ -34,6 +34,7 @@ //#include "linden_common.h" +#include <array> #include "v2math.h" #include "v3math.h" #include "v4coloru.h" @@ -68,10 +69,16 @@ public: typedef enum { TT_TEXTURE = 0, // Standard 2D Texture +#if GL_VERSION_3_1 TT_RECT_TEXTURE, // Non power of 2 texture +#endif TT_CUBE_MAP, // 6-sided cube map texture +#if GL_VERSION_4_0 TT_CUBE_MAP_ARRAY, // Array of cube maps +#endif +#if GL_VERSION_3_2 TT_MULTISAMPLE_TEXTURE, // see GL_ARB_texture_multisample +#endif TT_TEXTURE_3D, // standard 3D Texture TT_NONE, // No texture type is currently enabled } eTextureType; diff --git a/indra/llrender/llrender2dutils.cpp b/indra/llrender/llrender2dutils.cpp index 5b08c29d64..9144ce6d62 100644 --- a/indra/llrender/llrender2dutils.cpp +++ b/indra/llrender/llrender2dutils.cpp @@ -1802,10 +1802,12 @@ void LLRender2D::setLineWidth(F32 width) // If outside the allowed range, glLineWidth fails with "invalid value". // On Darwin, the range is [1, 1]. static GLfloat range[2]{0.0}; +#if GL_VERSION_1_2 if (range[1] == 0) { glGetFloatv(GL_SMOOTH_LINE_WIDTH_RANGE, range); } +#endif width *= lerp(LLRender::sUIGLScaleFactor.mV[VX], LLRender::sUIGLScaleFactor.mV[VY], 0.5f); glLineWidth(llclamp(width, range[0], range[1])); } diff --git a/indra/llrender/llrendertarget.cpp b/indra/llrender/llrendertarget.cpp index 38bc5ff331..0e4aa2ee7a 100644 --- a/indra/llrender/llrendertarget.cpp +++ b/indra/llrender/llrendertarget.cpp @@ -255,12 +255,14 @@ bool LLRenderTarget::addColorAttachment(U32 color_fmt) stop_glerror(); } +#if GL_VERSION_3_1 if (mUsage != LLTexUnit::TT_RECT_TEXTURE) { gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_MIRROR); stop_glerror(); } else +#endif { // ATI doesn't support mirrored repeat for rectangular textures. gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_CLAMP); @@ -429,7 +431,8 @@ void LLRenderTarget::bindTarget() if (mTex.empty()) { //no color buffer to draw to - glDrawBuffer(GL_NONE); + GLenum buffers[] = {GL_NONE}; + glDrawBuffers(0, buffers); glReadBuffer(GL_NONE); } else @@ -499,7 +502,9 @@ void LLRenderTarget::bindTexture(U32 index, S32 channel, LLTexUnit::eTextureFilt { case GL_SRGB: case GL_SRGB8: +#if GL_VERSION_2_1 case GL_SRGB_ALPHA: +#endif case GL_SRGB8_ALPHA8: isSRGB = true; break; @@ -542,7 +547,8 @@ void LLRenderTarget::flush() sCurResX = gGLViewport[2]; sCurResY = gGLViewport[3]; glReadBuffer(GL_BACK); - glDrawBuffer(GL_BACK); + GLenum drawbuffers[] = {GL_BACK}; + glDrawBuffers(1, drawbuffers); } } diff --git a/indra/llrender/llshadermgr.cpp b/indra/llrender/llshadermgr.cpp index 0885740934..4807c12226 100644 --- a/indra/llrender/llshadermgr.cpp +++ b/indra/llrender/llshadermgr.cpp @@ -291,6 +291,14 @@ bool LLShaderMgr::attachShaderFeatures(LLGLSLShader * shader) } } + if (features->hasTonemap) + { + if (!shader->attachFragmentObject("deferred/tonemapUtilF.glsl")) + { + return false; + } + } + // NOTE order of shader object attaching is VERY IMPORTANT!!! if (features->hasAtmospherics) { @@ -466,6 +474,7 @@ GLuint LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shader_lev if (filename.empty()) { + LL_WARNS("ShaderLoading") << "tried loading empty filename" << LL_ENDL; return 0; } @@ -923,6 +932,8 @@ GLuint LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shader_lev } LL_WARNS("ShaderLoading") << "Failed to load " << filename << LL_ENDL; } + + LL_DEBUGS("ShaderLoading") << "loadShaderFile() completed, ret: " << U32(ret) << LL_ENDL; return ret; } @@ -1389,6 +1400,7 @@ void LLShaderMgr::initAttribsAndUniforms() mReservedUniforms.push_back("screenTex"); mReservedUniforms.push_back("screenDepth"); mReservedUniforms.push_back("refTex"); + mReservedUniforms.push_back("exclusionTex"); mReservedUniforms.push_back("eyeVec"); mReservedUniforms.push_back("time"); mReservedUniforms.push_back("waveDir1"); diff --git a/indra/llrender/llshadermgr.h b/indra/llrender/llshadermgr.h index 34bd73a42e..46788841a5 100644 --- a/indra/llrender/llshadermgr.h +++ b/indra/llrender/llshadermgr.h @@ -36,6 +36,8 @@ public: LLShaderMgr(); virtual ~LLShaderMgr(); + // Note: although you can use statically hashed strings to just bind a random uniform, it's generally preferably that you use this. + // Always document what the actual shader uniform is next to the shader uniform in this struct. // clang-format off typedef enum { // Shader uniform name, set in LLShaderMgr::initAttribsAndUniforms() @@ -234,6 +236,7 @@ public: WATER_SCREENTEX, // "screenTex" WATER_SCREENDEPTH, // "screenDepth" WATER_REFTEX, // "refTex" + WATER_EXCLUSIONTEX, // "exclusionTex" WATER_EYEVEC, // "eyeVec" WATER_TIME, // "time" WATER_WAVE_DIR1, // "waveDir1" diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp index 1f0c424188..ac6db0b34f 100644 --- a/indra/llrender/llvertexbuffer.cpp +++ b/indra/llrender/llvertexbuffer.cpp @@ -1707,55 +1707,58 @@ void LLVertexBuffer::setupVertexBuffer() STOP_GLERROR; U8* base = nullptr; + AttributeType loc; + void* ptr = nullptr; + U32 data_mask = LLGLSLShader::sCurBoundShaderPtr->mAttributeMask; if (data_mask & MAP_NORMAL) { - AttributeType loc = TYPE_NORMAL; - void* ptr = (void*)(base + mOffsets[TYPE_NORMAL]); + loc = TYPE_NORMAL; + ptr = (void*)(base + mOffsets[TYPE_NORMAL]); glVertexAttribPointer(loc, 3, GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_NORMAL], ptr); } if (data_mask & MAP_TEXCOORD3) { - AttributeType loc = TYPE_TEXCOORD3; - void* ptr = (void*)(base + mOffsets[TYPE_TEXCOORD3]); + loc = TYPE_TEXCOORD3; + ptr = (void*)(base + mOffsets[TYPE_TEXCOORD3]); glVertexAttribPointer(loc, 2, GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD3], ptr); } if (data_mask & MAP_TEXCOORD2) { - AttributeType loc = TYPE_TEXCOORD2; - void* ptr = (void*)(base + mOffsets[TYPE_TEXCOORD2]); + loc = TYPE_TEXCOORD2; + ptr = (void*)(base + mOffsets[TYPE_TEXCOORD2]); glVertexAttribPointer(loc, 2, GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD2], ptr); } if (data_mask & MAP_TEXCOORD1) { - AttributeType loc = TYPE_TEXCOORD1; - void* ptr = (void*)(base + mOffsets[TYPE_TEXCOORD1]); + loc = TYPE_TEXCOORD1; + ptr = (void*)(base + mOffsets[TYPE_TEXCOORD1]); glVertexAttribPointer(loc, 2, GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD1], ptr); } if (data_mask & MAP_TANGENT) { - AttributeType loc = TYPE_TANGENT; - void* ptr = (void*)(base + mOffsets[TYPE_TANGENT]); + loc = TYPE_TANGENT; + ptr = (void*)(base + mOffsets[TYPE_TANGENT]); glVertexAttribPointer(loc, 4, GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_TANGENT], ptr); } if (data_mask & MAP_TEXCOORD0) { - AttributeType loc = TYPE_TEXCOORD0; - void* ptr = (void*)(base + mOffsets[TYPE_TEXCOORD0]); + loc = TYPE_TEXCOORD0; + ptr = (void*)(base + mOffsets[TYPE_TEXCOORD0]); glVertexAttribPointer(loc, 2, GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD0], ptr); } if (data_mask & MAP_COLOR) { - AttributeType loc = TYPE_COLOR; + loc = TYPE_COLOR; //bind emissive instead of color pointer if emissive is present - void* ptr = (data_mask & MAP_EMISSIVE) ? (void*)(base + mOffsets[TYPE_EMISSIVE]) : (void*)(base + mOffsets[TYPE_COLOR]); + ptr = (data_mask & MAP_EMISSIVE) ? (void*)(base + mOffsets[TYPE_EMISSIVE]) : (void*)(base + mOffsets[TYPE_COLOR]); glVertexAttribPointer(loc, 4, GL_UNSIGNED_BYTE, GL_TRUE, LLVertexBuffer::sTypeSize[TYPE_COLOR], ptr); } if (data_mask & MAP_EMISSIVE) { - AttributeType loc = TYPE_EMISSIVE; - void* ptr = (void*)(base + mOffsets[TYPE_EMISSIVE]); + loc = TYPE_EMISSIVE; + ptr = (void*)(base + mOffsets[TYPE_EMISSIVE]); glVertexAttribPointer(loc, 4, GL_UNSIGNED_BYTE, GL_TRUE, LLVertexBuffer::sTypeSize[TYPE_EMISSIVE], ptr); if (!(data_mask & MAP_COLOR)) @@ -1766,38 +1769,38 @@ void LLVertexBuffer::setupVertexBuffer() } if (data_mask & MAP_WEIGHT) { - AttributeType loc = TYPE_WEIGHT; - void* ptr = (void*)(base + mOffsets[TYPE_WEIGHT]); + loc = TYPE_WEIGHT; + ptr = (void*)(base + mOffsets[TYPE_WEIGHT]); glVertexAttribPointer(loc, 1, GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_WEIGHT], ptr); } if (data_mask & MAP_WEIGHT4) { - AttributeType loc = TYPE_WEIGHT4; - void* ptr = (void*)(base + mOffsets[TYPE_WEIGHT4]); + loc = TYPE_WEIGHT4; + ptr = (void*)(base + mOffsets[TYPE_WEIGHT4]); glVertexAttribPointer(loc, 4, GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_WEIGHT4], ptr); } if (data_mask & MAP_JOINT) { - AttributeType loc = TYPE_JOINT; - void* ptr = (void*)(base + mOffsets[TYPE_JOINT]); + loc = TYPE_JOINT; + ptr = (void*)(base + mOffsets[TYPE_JOINT]); glVertexAttribIPointer(loc, 4, GL_UNSIGNED_SHORT, LLVertexBuffer::sTypeSize[TYPE_JOINT], ptr); } if (data_mask & MAP_CLOTHWEIGHT) { - AttributeType loc = TYPE_CLOTHWEIGHT; - void* ptr = (void*)(base + mOffsets[TYPE_CLOTHWEIGHT]); + loc = TYPE_CLOTHWEIGHT; + ptr = (void*)(base + mOffsets[TYPE_CLOTHWEIGHT]); glVertexAttribPointer(loc, 4, GL_FLOAT, GL_TRUE, LLVertexBuffer::sTypeSize[TYPE_CLOTHWEIGHT], ptr); } if (data_mask & MAP_TEXTURE_INDEX) { - AttributeType loc = TYPE_TEXTURE_INDEX; - void* ptr = (void*)(base + mOffsets[TYPE_VERTEX] + 12); + loc = TYPE_TEXTURE_INDEX; + ptr = (void*)(base + mOffsets[TYPE_VERTEX] + 12); glVertexAttribIPointer(loc, 1, GL_UNSIGNED_INT, LLVertexBuffer::sTypeSize[TYPE_VERTEX], ptr); } if (data_mask & MAP_VERTEX) { - AttributeType loc = TYPE_VERTEX; - void* ptr = (void*)(base + mOffsets[TYPE_VERTEX]); + loc = TYPE_VERTEX; + ptr = (void*)(base + mOffsets[TYPE_VERTEX]); glVertexAttribPointer(loc, 3, GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_VERTEX], ptr); } STOP_GLERROR; @@ -1914,7 +1917,3 @@ void LLVertexBuffer::setIndexData(const U32* data, U32 offset, U32 count) } flush_vbo(GL_ELEMENT_ARRAY_BUFFER, offset * sizeof(U32), (offset + count) * sizeof(U32) - 1, (U8*)data, mMappedIndexData); } - - - - diff --git a/indra/llui/CMakeLists.txt b/indra/llui/CMakeLists.txt index a0314cb5f2..5991a5b35e 100644 --- a/indra/llui/CMakeLists.txt +++ b/indra/llui/CMakeLists.txt @@ -270,6 +270,8 @@ target_link_libraries(llui llcommon ) +include(LibraryInstall) + # Add tests if(LL_TESTS) include(LLAddBuildTest) diff --git a/indra/llui/llbutton.cpp b/indra/llui/llbutton.cpp index 1bce31edb1..d2534b3939 100644 --- a/indra/llui/llbutton.cpp +++ b/indra/llui/llbutton.cpp @@ -837,7 +837,7 @@ void LLButton::draw() // Highlight if needed if( ll::ui::SearchableControl::getHighlighted() ) - label_color = ll::ui::SearchableControl::getHighlightColor(); + label_color = ll::ui::SearchableControl::getHighlightFontColor(); // overlay with keyboard focus border if (hasFocus()) diff --git a/indra/llui/llcommandmanager.cpp b/indra/llui/llcommandmanager.cpp index 03717da80b..b10ec51f18 100644 --- a/indra/llui/llcommandmanager.cpp +++ b/indra/llui/llcommandmanager.cpp @@ -170,12 +170,14 @@ bool LLCommandManager::load() if (!parser.readXUI(commands_file, commandsParams)) { + LLError::LLUserWarningMsg::showMissingFiles(); LL_ERRS() << "Unable to load xml file: " << commands_file << LL_ENDL; return false; } if (!commandsParams.validateBlock()) { + LLError::LLUserWarningMsg::showMissingFiles(); LL_ERRS() << "Invalid commands file: " << commands_file << LL_ENDL; return false; } diff --git a/indra/llui/llfolderview.cpp b/indra/llui/llfolderview.cpp index 42a9e267d2..b664065532 100644 --- a/indra/llui/llfolderview.cpp +++ b/indra/llui/llfolderview.cpp @@ -28,6 +28,7 @@ #include "llfolderview.h" #include "llfolderviewmodel.h" +#include "llcallbacklist.h" #include "llclipboard.h" // *TODO: remove this once hack below gone. #include "llkeyboard.h" #include "lllineeditor.h" @@ -274,7 +275,11 @@ LLFolderView::~LLFolderView( void ) mRenamer = NULL; mStatusTextBox = NULL; - if (mPopupMenuHandle.get()) mPopupMenuHandle.get()->die(); + if (mPopupMenuHandle.get()) + { + mPopupMenuHandle.get()->die(); + gIdleCallbacks.deleteFunction(onIdleUpdateMenu, this); + } mPopupMenuHandle.markDead(); mAutoOpenItems.removeAllNodes(); @@ -1095,7 +1100,10 @@ bool LLFolderView::handleKeyHere( KEY key, MASK mask ) LLMenuGL* menu = (LLMenuGL*)mPopupMenuHandle.get(); if (menu && menu->isOpen()) { - LLMenuGL::sMenuContainer->hideMenus(); + if (LLMenuGL::sMenuContainer->hideMenus()) + { + gIdleCallbacks.deleteFunction(onIdleUpdateMenu, this); + } } switch( key ) @@ -1340,7 +1348,10 @@ bool LLFolderView::handleUnicodeCharHere(llwchar uni_char) LLMenuGL* menu = (LLMenuGL*)mPopupMenuHandle.get(); if (menu && menu->isOpen()) { - LLMenuGL::sMenuContainer->hideMenus(); + if (LLMenuGL::sMenuContainer->hideMenus()) + { + gIdleCallbacks.deleteFunction(onIdleUpdateMenu, this); + } } //do text search @@ -1612,7 +1623,11 @@ void LLFolderView::deleteAllChildren() { LLUI::getInstance()->removePopup(mRenamer); } - if (mPopupMenuHandle.get()) mPopupMenuHandle.get()->die(); + if (mPopupMenuHandle.get()) + { + mPopupMenuHandle.get()->die(); + gIdleCallbacks.deleteFunction(onIdleUpdateMenu, this); + } mPopupMenuHandle.markDead(); mScrollContainer = NULL; mRenameItem = NULL; @@ -1979,9 +1994,24 @@ void LLFolderView::updateMenu() LLMenuGL* menu = (LLMenuGL*)mPopupMenuHandle.get(); if (menu && menu->getVisible()) { - updateMenuOptions(menu); + // When fetching folders in bulk or in parts, each callback + // cause updateMenu individually, so make sure it gets called + // only once per frame, after callbacks are done. + // gIdleCallbacks has built in dupplicate protection. + gIdleCallbacks.addFunction(onIdleUpdateMenu, this); + } +} + +void LLFolderView::onIdleUpdateMenu(void* user_data) +{ + LLFolderView* self = (LLFolderView*)user_data; + LLMenuGL* menu = (LLMenuGL*)self->mPopupMenuHandle.get(); + if (menu) + { + self->updateMenuOptions(menu); menu->needsArrange(); // update menu height if needed } + gIdleCallbacks.deleteFunction(onIdleUpdateMenu, self); } bool LLFolderView::isFolderSelected() diff --git a/indra/llui/llfolderview.h b/indra/llui/llfolderview.h index 62ef2a0626..7ed10d9223 100644 --- a/indra/llui/llfolderview.h +++ b/indra/llui/llfolderview.h @@ -266,6 +266,7 @@ public: private: void updateMenuOptions(LLMenuGL* menu); void updateRenamerPosition(); + static void onIdleUpdateMenu(void* user_data); protected: LLScrollContainer* mScrollContainer; // NULL if this is not a child of a scroll container. @@ -414,6 +415,7 @@ public: virtual void doItem(LLFolderViewItem* item) {} void setApply(bool apply); void clearOpenFolders() { mOpenFolders.clear(); } + bool hasOpenFolders() { return !mOpenFolders.empty(); } protected: std::set<LLUUID> mOpenFolders; bool mApply; diff --git a/indra/llui/llfolderviewitem.cpp b/indra/llui/llfolderviewitem.cpp index 18bde344a0..6d0cfcba95 100644 --- a/indra/llui/llfolderviewitem.cpp +++ b/indra/llui/llfolderviewitem.cpp @@ -23,7 +23,7 @@ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ -#include "../newview/llviewerprecompiledheaders.h" +#include "linden_common.h" #include "llflashtimer.h" diff --git a/indra/llui/llmenugl.cpp b/indra/llui/llmenugl.cpp index 69ffa9a94f..c11b42a348 100644 --- a/indra/llui/llmenugl.cpp +++ b/indra/llui/llmenugl.cpp @@ -508,7 +508,7 @@ void LLMenuItemGL::draw( void ) // Highlight if needed if( ll::ui::SearchableControl::getHighlighted() ) - color = ll::ui::SearchableControl::getHighlightColor(); + color = ll::ui::SearchableControl::getHighlightFontColor(); // Draw the text on top. if (mBriefItem) diff --git a/indra/llui/llnotifications.cpp b/indra/llui/llnotifications.cpp index cd80e7f63f..a05feab1d9 100644 --- a/indra/llui/llnotifications.cpp +++ b/indra/llui/llnotifications.cpp @@ -614,6 +614,13 @@ void LLNotification::cancel() LLSD LLNotification::getResponseTemplate(EResponseTemplateType type) { LLSD response = LLSD::emptyMap(); + + if (!mForm) + { + LL_WARNS("Notifications") << "Null form when getting response template for notification " << getName() << LL_ENDL; + return response; + } + for (S32 element_idx = 0; element_idx < mForm->getNumElements(); ++element_idx) @@ -1249,9 +1256,26 @@ LLNotifications::LLNotifications() LLInstanceTracker<LLNotificationChannel, std::string>::instanceCount(); } + +LLNotifications::~LLNotifications() +{ + // Clear explicitly, something in ~LLNotifications() crashes so narrowing down suspects + pHistoryChannel = nullptr; + pExpirationChannel = nullptr; + mGlobalStrings.clear(); + mTemplates.clear(); + mVisibilityRules.clear(); + mUniqueNotifications.clear(); + mListener = nullptr; +} + void LLNotifications::clear() { - mDefaultChannels.clear(); + mDefaultChannels.clear(); + // At this point mTemplates still gets used by lingering notifications + // to do responses (ex: group notice will call forceResponse()), but + // since network should be down and everything save, it's questionable + // whether it should stay that way } // The expiration channel gets all notifications that are cancelled @@ -1464,6 +1488,13 @@ bool LLNotifications::templateExists(std::string_view name) void LLNotifications::forceResponse(const LLNotification::Params& params, S32 option) { LLNotificationPtr temp_notify(new LLNotification(params)); + + if (!temp_notify->getForm()) + { + LL_WARNS("Notifications") << "Cannot force response for notification with null form: " << (std::string)params.name << LL_ENDL; + return; + } + LLSD response = temp_notify->getResponseTemplate(); LLSD selected_item = temp_notify->getForm()->getElement(option); @@ -1555,7 +1586,7 @@ bool LLNotifications::loadTemplates() gDirUtilp->findSkinnedFilenames(LLDir::XUI, "notifications.xml", LLDir::ALL_SKINS); if (search_paths.empty()) { - LLError::LLUserWarningMsg::show(LLTrans::getString("MBMissingFile")); + LLError::LLUserWarningMsg::show(LLTrans::getString("MBMissingFile"), LLError::LLUserWarningMsg::ERROR_MISSING_FILES); LL_ERRS() << "Problem finding notifications.xml" << LL_ENDL; } @@ -1565,7 +1596,7 @@ bool LLNotifications::loadTemplates() if (!success || root.isNull() || !root->hasName( "notifications" )) { - LLError::LLUserWarningMsg::show(LLTrans::getString("MBMissingFile")); + LLError::LLUserWarningMsg::show(LLTrans::getString("MBMissingFile"), LLError::LLUserWarningMsg::ERROR_MISSING_FILES); LL_ERRS() << "Problem reading XML from UI Notifications file: " << base_filename << LL_ENDL; return false; } @@ -1576,7 +1607,7 @@ bool LLNotifications::loadTemplates() if(!params.validateBlock()) { - LLError::LLUserWarningMsg::show(LLTrans::getString("MBMissingFile")); + LLError::LLUserWarningMsg::show(LLTrans::getString("MBMissingFile"), LLError::LLUserWarningMsg::ERROR_MISSING_FILES); LL_ERRS() << "Problem reading XUI from UI Notifications file: " << base_filename << LL_ENDL; return false; } @@ -1643,7 +1674,7 @@ bool LLNotifications::loadVisibilityRules() if(!params.validateBlock()) { - LLError::LLUserWarningMsg::show(LLTrans::getString("MBMissingFile")); + LLError::LLUserWarningMsg::show(LLTrans::getString("MBMissingFile"), LLError::LLUserWarningMsg::ERROR_MISSING_FILES); LL_ERRS() << "Problem reading UI Notification Visibility Rules file: " << full_filename << LL_ENDL; return false; } diff --git a/indra/llui/llnotifications.h b/indra/llui/llnotifications.h index 46286457cf..138f1969d5 100644 --- a/indra/llui/llnotifications.h +++ b/indra/llui/llnotifications.h @@ -887,7 +887,7 @@ class LLNotifications : { LLSINGLETON(LLNotifications); LOG_CLASS(LLNotifications); - virtual ~LLNotifications() {} + virtual ~LLNotifications(); public: diff --git a/indra/llui/llscrolllistctrl.cpp b/indra/llui/llscrolllistctrl.cpp index 93bd3c6bed..245339b107 100644 --- a/indra/llui/llscrolllistctrl.cpp +++ b/indra/llui/llscrolllistctrl.cpp @@ -3394,7 +3394,7 @@ bool LLScrollListCtrl::highlightMatchingItems(const std::string& filter_str) bool res = false; - setHighlightedColor(LLUIColorTable::instance().getColor("SearchableControlHighlightColor", LLColor4::red)); + setHighlightedColor(LLUIColorTable::instance().getColor("SearchableControlHighlightBgColor", LLColor4::red4)); std::string filter_str_lc(filter_str); LLStringUtil::toLower(filter_str_lc); diff --git a/indra/llui/llsearchablecontrol.h b/indra/llui/llsearchablecontrol.h index 119852b763..bae85fe9a5 100644 --- a/indra/llui/llsearchablecontrol.h +++ b/indra/llui/llsearchablecontrol.h @@ -43,9 +43,15 @@ namespace ll virtual ~SearchableControl() { } - const LLColor4& getHighlightColor( ) const + const LLColor4& getHighlightBgColor( ) const { - static LLUIColor highlight_color = LLUIColorTable::instance().getColor("SearchableControlHighlightColor", LLColor4::red); + static LLUIColor highlight_color = LLUIColorTable::instance().getColor("SearchableControlHighlightBgColor", LLColor4::red4); + return highlight_color.get(); + } + + const LLColor4& getHighlightFontColor() const + { + static LLUIColor highlight_color = LLUIColorTable::instance().getColor("SearchableControlHighlightFontColor", LLColor4::red4); return highlight_color.get(); } diff --git a/indra/llui/llstyle.cpp b/indra/llui/llstyle.cpp index df4b0ef6a0..4714665e8b 100644 --- a/indra/llui/llstyle.cpp +++ b/indra/llui/llstyle.cpp @@ -39,7 +39,7 @@ LLStyle::Params::Params() readonly_color("readonly_color", LLColor4::black), selected_color("selected_color", LLColor4::black), alpha("alpha", 1.f), - font("font", LLFontGL::getFontMonospace()), + font("font", LLStyle::getDefaultFont()), image("image"), link_href("href"), is_link("is_link") @@ -70,6 +70,11 @@ const LLFontGL* LLStyle::getFont() const return mFont; } +const LLFontGL* LLStyle::getDefaultFont() +{ + return LLFontGL::getFontMonospace(); +} + void LLStyle::setLinkHREF(const std::string& href) { mLink = href; diff --git a/indra/llui/llstyle.h b/indra/llui/llstyle.h index e506895de5..0c78fe5a9f 100644 --- a/indra/llui/llstyle.h +++ b/indra/llui/llstyle.h @@ -72,6 +72,7 @@ public: void setFont(const LLFontGL* font); const LLFontGL* getFont() const; + static const LLFontGL* getDefaultFont(); const std::string& getLinkHREF() const { return mLink; } void setLinkHREF(const std::string& href); diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp index cbbf83d679..41e7094163 100644 --- a/indra/llui/lltextbase.cpp +++ b/indra/llui/lltextbase.cpp @@ -1378,7 +1378,7 @@ void LLTextBase::draw() // Draw highlighted if needed if( ll::ui::SearchableControl::getHighlighted() ) { - const LLColor4& bg_color = ll::ui::SearchableControl::getHighlightColor(); + const LLColor4& bg_color = ll::ui::SearchableControl::getHighlightBgColor(); LLRect bg_rect = mVisibleTextRect; if( mScroller ) bg_rect.intersectWith( text_rect ); @@ -1438,7 +1438,8 @@ void LLTextBase::onVisibilityChange( bool new_visibility ) //virtual void LLTextBase::setValue(const LLSD& value ) { - setText(value.asString()); + static const LLStyle::Params input_params = LLStyle::Params(); + setText(value.asString(), input_params); } //virtual @@ -3880,8 +3881,7 @@ bool LLInlineViewSegment::getDimensionsF32(S32 first_char, S32 num_chars, F32& w if (mForceNewLine) { // Chat, string can't be smaller then font height even if it is empty - LLStyleSP s(new LLStyle(LLStyle::Params().visible(true))); - height = s->getFont()->getLineHeight(); + height = LLStyle::getDefaultFont()->getLineHeight(); return true; // new line } @@ -3945,9 +3945,7 @@ void LLInlineViewSegment::linkToDocument(LLTextBase* editor) LLLineBreakTextSegment::LLLineBreakTextSegment(S32 pos):LLTextSegment(pos,pos+1) { - LLStyleSP s( new LLStyle(LLStyle::Params().visible(true))); - - mFontHeight = s->getFont()->getLineHeight(); + mFontHeight = LLStyle::getDefaultFont()->getLineHeight(); } LLLineBreakTextSegment::LLLineBreakTextSegment(LLStyleConstSP style,S32 pos):LLTextSegment(pos,pos+1) { diff --git a/indra/llui/lltextbox.cpp b/indra/llui/lltextbox.cpp index 05af36b71e..9f945d3735 100644 --- a/indra/llui/lltextbox.cpp +++ b/indra/llui/lltextbox.cpp @@ -159,7 +159,8 @@ LLSD LLTextBox::getValue() const bool LLTextBox::setTextArg( const std::string& key, const LLStringExplicit& text ) { mText.setArg(key, text); - LLTextBase::setText(mText.getString()); + static const LLStyle::Params input_params = LLStyle::Params(); + LLTextBase::setText(mText.getString(), input_params); return true; } diff --git a/indra/llui/lltextbox.h b/indra/llui/lltextbox.h index a3cde45cd0..500dc8669f 100644 --- a/indra/llui/lltextbox.h +++ b/indra/llui/lltextbox.h @@ -76,6 +76,12 @@ protected: LLUIString mText; callback_t mClickedCallback; bool mShowCursorHand; + +protected: + virtual std::string _getSearchText() const + { + return LLTextBase::_getSearchText() + mText.getString(); + } }; // Build time optimization, generate once in .cpp file diff --git a/indra/llui/lltexteditor.cpp b/indra/llui/lltexteditor.cpp index 3537c764b9..77a4976f6b 100644 --- a/indra/llui/lltexteditor.cpp +++ b/indra/llui/lltexteditor.cpp @@ -209,8 +209,15 @@ public: } virtual bool execute( LLTextBase* editor, S32* delta ) { - mWString = editor->getWText().substr(getPosition(), mLen); - *delta = remove(editor, getPosition(), mLen ); + try + { + mWString = editor->getWText().substr(getPosition(), mLen); + *delta = remove(editor, getPosition(), mLen); + } + catch (std::out_of_range&) + { + return false; + } return (*delta != 0); } virtual S32 undo( LLTextBase* editor ) diff --git a/indra/llui/lltransutil.cpp b/indra/llui/lltransutil.cpp index 4af5376a8b..e82af0b96f 100644 --- a/indra/llui/lltransutil.cpp +++ b/indra/llui/lltransutil.cpp @@ -48,7 +48,7 @@ bool LLTransUtil::parseStrings(const std::string& xml_filename, const std::set<s "Second Life viewer couldn't access some of the files it needs and will be closed." "\n\nPlease reinstall viewer from https://secondlife.com/support/downloads/ and " "contact https://support.secondlife.com if issue persists after reinstall."; - LLError::LLUserWarningMsg::show(error_string); + LLError::LLUserWarningMsg::show(error_string, LLError::LLUserWarningMsg::ERROR_MISSING_FILES); gDirUtilp->dumpCurrentDirectories(LLError::LEVEL_WARN); LL_ERRS() << "Couldn't load string table " << xml_filename << " " << errno << LL_ENDL; return false; diff --git a/indra/llui/llui.cpp b/indra/llui/llui.cpp index e36dae3955..e7dea79eaa 100644 --- a/indra/llui/llui.cpp +++ b/indra/llui/llui.cpp @@ -231,6 +231,11 @@ void LLUI::getMousePositionScreen(S32 *x, S32 *y) LLCoordGL cursor_pos_gl(cursor_pos_window.convert()); *x = ll_round((F32)cursor_pos_gl.mX / getScaleFactor().mV[VX]); *y = ll_round((F32)cursor_pos_gl.mY / getScaleFactor().mV[VY]); +#if defined(LL_SDL) + *x = *x * LLView::getWindow()->getSystemUISize(); + *y = *y * LLView::getWindow()->getSystemUISize(); +#endif + } void LLUI::setMousePositionLocal(const LLView* viewp, S32 x, S32 y) diff --git a/indra/llui/llui.h b/indra/llui/llui.h index 375cd539b7..9890d3f7ef 100644 --- a/indra/llui/llui.h +++ b/indra/llui/llui.h @@ -31,8 +31,6 @@ #include "llrect.h" #include "llcoord.h" #include "llcontrol.h" -#include "llcoord.h" -#include "llcontrol.h" #include "llinitparam.h" #include "llregistry.h" #include "llrender2dutils.h" diff --git a/indra/llwebrtc/CMakeLists.txt b/indra/llwebrtc/CMakeLists.txt index a18b716003..c4971d44b1 100644 --- a/indra/llwebrtc/CMakeLists.txt +++ b/indra/llwebrtc/CMakeLists.txt @@ -28,7 +28,9 @@ list(APPEND llwebrtc_SOURCE_FILES ${llwebrtc_HEADER_FILES}) add_library (llwebrtc SHARED ${llwebrtc_SOURCE_FILES}) +if (NOT USESYSTEMLIBS) set_target_properties(llwebrtc PROPERTIES PUBLIC_HEADER llwebrtc.h) +endif (NOT USESYSTEMLIBS) if (WINDOWS) cmake_policy(SET CMP0091 NEW) @@ -56,7 +58,7 @@ elseif (DARWIN) set_target_properties(llwebrtc PROPERTIES XCODE_ATTRIBUTE_DEBUG_INFORMATION_FORMAT "dwarf-with-dsym" XCODE_ATTRIBUTE_DWARF_DSYM_FOLDER_PATH "${SYMBOLS_STAGING_DIR}/dSYMs") endif (USE_BUGSPLAT) -elseif (LINUX) +elseif (NOT CMAKE_SYSTEM_NAME MATCHES FreeBSD) target_link_libraries(llwebrtc PRIVATE ll::webrtc) endif (WINDOWS) @@ -74,3 +76,16 @@ ADD_CUSTOM_COMMAND(TARGET llwebrtc POST_BUILD # Add tests if (LL_TESTS) endif (LL_TESTS) + +if (INSTALL) + if (DARWIN) + set(_LIB ../Frameworks) + elseif (${LINUX_DISTRO} MATCHES debian OR (${LINUX_DISTRO} MATCHES ubuntu)) + set(_LIB lib/${ARCH}-linux-gnu) + elseif (${LINUX_DISTRO} MATCHES fedora OR (${LINUX_DISTRO} MATCHES opensuse-tumbleweed) OR (${LINUX_DISTRO} MATCHES gentoo)) + set(_LIB lib${ADDRESS_SIZE}) + else (DARWIN) + set(_LIB lib) + endif (DARWIN) + install(TARGETS ${PROJECT_NAME} DESTINATION ${_LIB}) +endif (INSTALL) diff --git a/indra/llwebrtc/llwebrtc.cpp b/indra/llwebrtc/llwebrtc.cpp index 0daa767766..9b3dde4d0f 100644 --- a/indra/llwebrtc/llwebrtc.cpp +++ b/indra/llwebrtc/llwebrtc.cpp @@ -203,7 +203,9 @@ void LLWebRTCImpl::init() mTuningDeviceModule->SetPlayoutDevice(mPlayoutDevice); mTuningDeviceModule->SetRecordingDevice(mRecordingDevice); mTuningDeviceModule->EnableBuiltInAEC(false); +#if !CM_WEBRTC mTuningDeviceModule->SetAudioDeviceSink(this); +#endif mTuningDeviceModule->InitMicrophone(); mTuningDeviceModule->InitSpeaker(); mTuningDeviceModule->SetStereoRecording(false); diff --git a/indra/llwebrtc/llwebrtc_impl.h b/indra/llwebrtc/llwebrtc_impl.h index b93a1fdb01..99accb2c20 100644 --- a/indra/llwebrtc/llwebrtc_impl.h +++ b/indra/llwebrtc/llwebrtc_impl.h @@ -184,7 +184,11 @@ class LLCustomProcessor : public webrtc::CustomProcessing // Primary singleton implementation for interfacing // with the native webrtc library. +#if CM_WEBRTC +class LLWebRTCImpl : public LLWebRTCDeviceInterface +#else class LLWebRTCImpl : public LLWebRTCDeviceInterface, public webrtc::AudioDeviceSink +#endif { public: LLWebRTCImpl(LLWebRTCLogCallback* logCallback); @@ -219,7 +223,11 @@ class LLWebRTCImpl : public LLWebRTCDeviceInterface, public webrtc::AudioDeviceS // // AudioDeviceSink // +#if CM_WEBRTC + void OnDevicesUpdated(); +#else void OnDevicesUpdated() override; +#endif // // Helpers diff --git a/indra/llwindow/CMakeLists.txt b/indra/llwindow/CMakeLists.txt index 2996f58fe0..ce9134e7f1 100644 --- a/indra/llwindow/CMakeLists.txt +++ b/indra/llwindow/CMakeLists.txt @@ -52,7 +52,6 @@ set(llwindow_LINK_LIBRARIES llcommon llimage llmath - llrender llfilesystem llxml ll::glm @@ -60,11 +59,14 @@ set(llwindow_LINK_LIBRARIES ll::uilibraries ll::SDL ) + +include_directories(${CMAKE_SOURCE_DIR}/llrender) + # Libraries on which this library depends, needed for Linux builds # Sort by high-level to low-level -if (LINUX) - list(APPEND viewer_SOURCE_FILES - llkeyboardsdl.cpp +if (USESYSTEMLIBS AND NOT DARWIN) + list(APPEND viewer_SOURCE_FILES + llkeyboardsdl.cpp llwindowsdl.cpp ) list(APPEND viewer_HEADER_FILES @@ -84,8 +86,7 @@ if (LINUX) fontconfig # For FCInit and other FC* functions. ) endif (BUILD_HEADLESS) - -endif (LINUX) +endif (USESYSTEMLIBS AND NOT DARWIN) if (DARWIN) list(APPEND llwindow_SOURCE_FILES @@ -180,9 +181,11 @@ endif (SDL_FOUND) target_link_libraries (llwindow ${llwindow_LINK_LIBRARIES}) target_include_directories(llwindow INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}) - + if (DARWIN) include(CMakeFindFrameworks) find_library(CARBON_LIBRARY Carbon) target_link_libraries(llwindow ${CARBON_LIBRARY}) endif (DARWIN) + +include(LibraryInstall) diff --git a/indra/llwindow/llkeyboard.cpp b/indra/llwindow/llkeyboard.cpp index 33eebdadd1..a16c0a318a 100644 --- a/indra/llwindow/llkeyboard.cpp +++ b/indra/llwindow/llkeyboard.cpp @@ -41,7 +41,6 @@ std::map<KEY,std::string> LLKeyboard::sKeysToNames; std::map<std::string,KEY> LLKeyboard::sNamesToKeys; LLKeyStringTranslatorFunc* LLKeyboard::mStringTranslator = NULL; // Used for l10n + PC/Mac/Linux accelerator labeling - // // Class Implementation // @@ -195,12 +194,11 @@ void LLKeyboard::resetKeys() } -bool LLKeyboard::translateKey(const U16 os_key, KEY *out_key) +bool LLKeyboard::translateKey(const NATIVE_KEY_TYPE os_key, KEY *out_key) { - std::map<U16, KEY>::iterator iter; // Only translate keys in the map, ignore all other keys for now - iter = mTranslateKeyMap.find(os_key); + auto iter = mTranslateKeyMap.find(os_key); if (iter == mTranslateKeyMap.end()) { //LL_WARNS() << "Unknown virtual key " << os_key << LL_ENDL; @@ -214,11 +212,9 @@ bool LLKeyboard::translateKey(const U16 os_key, KEY *out_key) } } - -U16 LLKeyboard::inverseTranslateKey(const KEY translated_key) +LLKeyboard::NATIVE_KEY_TYPE LLKeyboard::inverseTranslateKey(const KEY translated_key) { - std::map<KEY, U16>::iterator iter; - iter = mInvTranslateKeyMap.find(translated_key); + auto iter = mInvTranslateKeyMap.find(translated_key); if (iter == mInvTranslateKeyMap.end()) { return 0; diff --git a/indra/llwindow/llkeyboard.h b/indra/llwindow/llkeyboard.h index 713eb7aec2..a527227672 100644 --- a/indra/llwindow/llkeyboard.h +++ b/indra/llwindow/llkeyboard.h @@ -55,6 +55,11 @@ class LLWindowCallbacks; class LLKeyboard { public: +#ifndef LL_SDL + typedef U16 NATIVE_KEY_TYPE; +#else + typedef U32 NATIVE_KEY_TYPE; +#endif LLKeyboard(); virtual ~LLKeyboard(); @@ -67,16 +72,15 @@ public: bool getKeyDown(const KEY key) { return mKeyLevel[key]; } bool getKeyRepeated(const KEY key) { return mKeyRepeated[key]; } - bool translateKey(const U16 os_key, KEY *translated_key); - U16 inverseTranslateKey(const KEY translated_key); + bool translateKey(const NATIVE_KEY_TYPE os_key, KEY *translated_key); + NATIVE_KEY_TYPE inverseTranslateKey(const KEY translated_key); bool handleTranslatedKeyUp(KEY translated_key, U32 translated_mask); // Translated into "Linden" keycodes bool handleTranslatedKeyDown(KEY translated_key, U32 translated_mask); // Translated into "Linden" keycodes + virtual bool handleKeyUp(const NATIVE_KEY_TYPE key, MASK mask) = 0; + virtual bool handleKeyDown(const NATIVE_KEY_TYPE key, MASK mask) = 0; - virtual bool handleKeyUp(const U16 key, MASK mask) = 0; - virtual bool handleKeyDown(const U16 key, MASK mask) = 0; - -#ifdef LL_DARWIN +#if defined(LL_DARWIN) && !defined(LL_SDL) // We only actually use this for macOS. virtual void handleModifier(MASK mask) = 0; #endif // LL_DARWIN @@ -111,8 +115,8 @@ protected: void addKeyName(KEY key, const std::string& name); protected: - std::map<U16, KEY> mTranslateKeyMap; // Map of translations from OS keys to Linden KEYs - std::map<KEY, U16> mInvTranslateKeyMap; // Map of translations from Linden KEYs to OS keys + std::map<NATIVE_KEY_TYPE, KEY> mTranslateKeyMap; // Map of translations from OS keys to Linden KEYs + std::map<KEY, NATIVE_KEY_TYPE> mInvTranslateKeyMap; // Map of translations from Linden KEYs to OS keys LLWindowCallbacks *mCallbacks; LLTimer mKeyLevelTimer[KEY_COUNT]; // Time since level was set diff --git a/indra/llwindow/llkeyboardheadless.cpp b/indra/llwindow/llkeyboardheadless.cpp index 8669a5b41a..6f8c829dd5 100644 --- a/indra/llwindow/llkeyboardheadless.cpp +++ b/indra/llwindow/llkeyboardheadless.cpp @@ -35,12 +35,8 @@ void LLKeyboardHeadless::resetMaskKeys() { } -bool LLKeyboardHeadless::handleKeyDown(const U16 key, const U32 mask) -{ return false; } -bool LLKeyboardHeadless::handleKeyUp(const U16 key, const U32 mask) -{ return false; } MASK LLKeyboardHeadless::currentMask(bool for_mouse_event) { return MASK_NONE; } diff --git a/indra/llwindow/llkeyboardheadless.h b/indra/llwindow/llkeyboardheadless.h index 2528f0e3f1..439abaf25b 100644 --- a/indra/llwindow/llkeyboardheadless.h +++ b/indra/llwindow/llkeyboardheadless.h @@ -35,8 +35,13 @@ public: LLKeyboardHeadless(); /*virtual*/ ~LLKeyboardHeadless() {}; - /*virtual*/ bool handleKeyUp(const U16 key, MASK mask); - /*virtual*/ bool handleKeyDown(const U16 key, MASK mask); +#ifndef LL_SDL + /*virtual*/ bool handleKeyUp(const U16 key, MASK mask) { return false; } + /*virtual*/ bool handleKeyDown(const U16 key, MASK mask) { return false; } +#else + /*virtual*/ bool handleKeyUp(const U32 key, MASK mask) { return false; } + /*virtual*/ bool handleKeyDown(const U32 key, MASK mask) { return false; } +#endif /*virtual*/ void resetMaskKeys(); /*virtual*/ MASK currentMask(bool for_mouse_event); /*virtual*/ void scanKeyboard(); diff --git a/indra/llwindow/llkeyboardsdl.cpp b/indra/llwindow/llkeyboardsdl.cpp index 97198f0cc0..72b4577276 100644 --- a/indra/llwindow/llkeyboardsdl.cpp +++ b/indra/llwindow/llkeyboardsdl.cpp @@ -1,6 +1,5 @@ /** - * @file llkeyboardsdl.cpp - * @brief Handler for assignable key bindings + * @author This module has many fathers, and it shows. * * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code @@ -24,12 +23,11 @@ * $/LicenseInfo$ */ -#if LL_SDL - #include "linden_common.h" #include "llkeyboardsdl.h" #include "llwindowcallbacks.h" -#include "SDL/SDL.h" +#include "SDL2/SDL.h" +#include "SDL2/SDL_keycode.h" LLKeyboardSDL::LLKeyboardSDL() { @@ -40,6 +38,10 @@ LLKeyboardSDL::LLKeyboardSDL() // Virtual key mappings from SDL_keysym.h ... // SDL maps the letter keys to the ASCII you'd expect, but it's lowercase... + + // <FS:ND> Looks like we need to map those despite of SDL_TEXTINPUT handling most of this, but without + // the translation lower->upper here accelerators will not work. + U16 cur_char; for (cur_char = 'A'; cur_char <= 'Z'; cur_char++) { @@ -68,13 +70,12 @@ LLKeyboardSDL::LLKeyboardSDL() //mTranslateKeyMap[SDLK_KP3] = KEY_PAGE_DOWN; //mTranslateKeyMap[SDLK_KP0] = KEY_INSERT; - mTranslateKeyMap[SDLK_SPACE] = ' '; + mTranslateKeyMap[SDLK_SPACE] = ' '; // <FS:ND/> Those are handled by SDL2 via text input, do not map them mTranslateKeyMap[SDLK_RETURN] = KEY_RETURN; mTranslateKeyMap[SDLK_LEFT] = KEY_LEFT; mTranslateKeyMap[SDLK_RIGHT] = KEY_RIGHT; mTranslateKeyMap[SDLK_UP] = KEY_UP; mTranslateKeyMap[SDLK_DOWN] = KEY_DOWN; - mTranslateKeyMap[SDLK_ESCAPE] = KEY_ESCAPE; mTranslateKeyMap[SDLK_KP_ENTER] = KEY_RETURN; mTranslateKeyMap[SDLK_ESCAPE] = KEY_ESCAPE; mTranslateKeyMap[SDLK_BACKSPACE] = KEY_BACKSPACE; @@ -111,40 +112,39 @@ LLKeyboardSDL::LLKeyboardSDL() mTranslateKeyMap[SDLK_F10] = KEY_F10; mTranslateKeyMap[SDLK_F11] = KEY_F11; mTranslateKeyMap[SDLK_F12] = KEY_F12; - mTranslateKeyMap[SDLK_PLUS] = '='; - mTranslateKeyMap[SDLK_COMMA] = ','; - mTranslateKeyMap[SDLK_MINUS] = '-'; - mTranslateKeyMap[SDLK_PERIOD] = '.'; - mTranslateKeyMap[SDLK_BACKQUOTE] = '`'; - mTranslateKeyMap[SDLK_SLASH] = KEY_DIVIDE; - mTranslateKeyMap[SDLK_SEMICOLON] = ';'; - mTranslateKeyMap[SDLK_LEFTBRACKET] = '['; - mTranslateKeyMap[SDLK_BACKSLASH] = '\\'; - mTranslateKeyMap[SDLK_RIGHTBRACKET] = ']'; - mTranslateKeyMap[SDLK_QUOTE] = '\''; + mTranslateKeyMap[SDLK_PLUS] = '='; // <FS:ND/> Those are handled by SDL2 via text input, do not map them + mTranslateKeyMap[SDLK_COMMA] = ','; // <FS:ND/> Those are handled by SDL2 via text input, do not map them + mTranslateKeyMap[SDLK_MINUS] = '-'; // <FS:ND/> Those are handled by SDL2 via text input, do not map them + mTranslateKeyMap[SDLK_PERIOD] = '.'; // <FS:ND/> Those are handled by SDL2 via text input, do not map them + mTranslateKeyMap[SDLK_BACKQUOTE] = '`'; // <FS:ND/> Those are handled by SDL2 via text input, do not map them + mTranslateKeyMap[SDLK_SLASH] = KEY_DIVIDE; // <FS:ND/> Those are handled by SDL2 via text input, do not map them + mTranslateKeyMap[SDLK_SEMICOLON] = ';'; // <FS:ND/> Those are handled by SDL2 via text input, do not map them + mTranslateKeyMap[SDLK_LEFTBRACKET] = '['; // <FS:ND/> Those are handled by SDL2 via text input, do not map them + mTranslateKeyMap[SDLK_BACKSLASH] = '\\'; // <FS:ND/> Those are handled by SDL2 via text input, do not map them + mTranslateKeyMap[SDLK_RIGHTBRACKET] = ']'; // <FS:ND/> Those are handled by SDL2 via text input, do not map them + mTranslateKeyMap[SDLK_QUOTE] = '\''; // <FS:ND/> Those are handled by SDL2 via text input, do not map them // Build inverse map - std::map<U16, KEY>::iterator iter; - for (iter = mTranslateKeyMap.begin(); iter != mTranslateKeyMap.end(); iter++) + for (auto iter = mTranslateKeyMap.begin(); iter != mTranslateKeyMap.end(); iter++) { mInvTranslateKeyMap[iter->second] = iter->first; } // numpad map - mTranslateNumpadMap[SDLK_KP0] = KEY_PAD_INS; - mTranslateNumpadMap[SDLK_KP1] = KEY_PAD_END; - mTranslateNumpadMap[SDLK_KP2] = KEY_PAD_DOWN; - mTranslateNumpadMap[SDLK_KP3] = KEY_PAD_PGDN; - mTranslateNumpadMap[SDLK_KP4] = KEY_PAD_LEFT; - mTranslateNumpadMap[SDLK_KP5] = KEY_PAD_CENTER; - mTranslateNumpadMap[SDLK_KP6] = KEY_PAD_RIGHT; - mTranslateNumpadMap[SDLK_KP7] = KEY_PAD_HOME; - mTranslateNumpadMap[SDLK_KP8] = KEY_PAD_UP; - mTranslateNumpadMap[SDLK_KP9] = KEY_PAD_PGUP; + mTranslateNumpadMap[SDLK_KP_0] = KEY_PAD_INS; + mTranslateNumpadMap[SDLK_KP_1] = KEY_PAD_END; + mTranslateNumpadMap[SDLK_KP_2] = KEY_PAD_DOWN; + mTranslateNumpadMap[SDLK_KP_3] = KEY_PAD_PGDN; + mTranslateNumpadMap[SDLK_KP_4] = KEY_PAD_LEFT; + mTranslateNumpadMap[SDLK_KP_5] = KEY_PAD_CENTER; + mTranslateNumpadMap[SDLK_KP_6] = KEY_PAD_RIGHT; + mTranslateNumpadMap[SDLK_KP_7] = KEY_PAD_HOME; + mTranslateNumpadMap[SDLK_KP_8] = KEY_PAD_UP; + mTranslateNumpadMap[SDLK_KP_9] = KEY_PAD_PGUP; mTranslateNumpadMap[SDLK_KP_PERIOD] = KEY_PAD_DEL; // build inverse numpad map - for (iter = mTranslateNumpadMap.begin(); + for (auto iter = mTranslateNumpadMap.begin(); iter != mTranslateNumpadMap.end(); iter++) { @@ -154,7 +154,7 @@ LLKeyboardSDL::LLKeyboardSDL() void LLKeyboardSDL::resetMaskKeys() { - SDLMod mask = SDL_GetModState(); + SDL_Keymod mask = SDL_GetModState(); // MBW -- XXX -- This mirrors the operation of the Windows version of resetMaskKeys(). // It looks a bit suspicious, as it won't correct for keys that have been released. @@ -165,7 +165,11 @@ void LLKeyboardSDL::resetMaskKeys() mKeyLevel[KEY_SHIFT] = true; } - if(mask & KMOD_CTRL) + if(mask & (KMOD_CTRL +#ifdef LL_DARWIN + | KMOD_GUI +#endif + )) { mKeyLevel[KEY_CONTROL] = true; } @@ -187,7 +191,11 @@ MASK LLKeyboardSDL::updateModifiers(const U32 mask) out_mask |= MASK_SHIFT; } - if(mask & KMOD_CTRL) + if(mask & (KMOD_CTRL +#ifdef LL_DARWIN + | KMOD_GUI +#endif + )) { out_mask |= MASK_CONTROL; } @@ -201,34 +209,34 @@ MASK LLKeyboardSDL::updateModifiers(const U32 mask) } -static U16 adjustNativekeyFromUnhandledMask(const U16 key, const U32 mask) +static U32 adjustNativekeyFromUnhandledMask(const U32 key, const U32 mask) { // SDL doesn't automatically adjust the keysym according to // whether NUMLOCK is engaged, so we massage the keysym manually. - U16 rtn = key; + U32 rtn = key; if (!(mask & KMOD_NUM)) { switch (key) { - case SDLK_KP_PERIOD: rtn = SDLK_DELETE; break; - case SDLK_KP0: rtn = SDLK_INSERT; break; - case SDLK_KP1: rtn = SDLK_END; break; - case SDLK_KP2: rtn = SDLK_DOWN; break; - case SDLK_KP3: rtn = SDLK_PAGEDOWN; break; - case SDLK_KP4: rtn = SDLK_LEFT; break; - case SDLK_KP6: rtn = SDLK_RIGHT; break; - case SDLK_KP7: rtn = SDLK_HOME; break; - case SDLK_KP8: rtn = SDLK_UP; break; - case SDLK_KP9: rtn = SDLK_PAGEUP; break; + case SDLK_KP_PERIOD: rtn = SDLK_DELETE; break; + case SDLK_KP_0: rtn = SDLK_INSERT; break; + case SDLK_KP_1: rtn = SDLK_END; break; + case SDLK_KP_2: rtn = SDLK_DOWN; break; + case SDLK_KP_3: rtn = SDLK_PAGEDOWN; break; + case SDLK_KP_4: rtn = SDLK_LEFT; break; + case SDLK_KP_6: rtn = SDLK_RIGHT; break; + case SDLK_KP_7: rtn = SDLK_HOME; break; + case SDLK_KP_8: rtn = SDLK_UP; break; + case SDLK_KP_9: rtn = SDLK_PAGEUP; break; } } return rtn; } -bool LLKeyboardSDL::handleKeyDown(const U16 key, const U32 mask) +bool LLKeyboardSDL::handleKeyDown(const U32 key, const U32 mask) { - U16 adjusted_nativekey; + U32 adjusted_nativekey; KEY translated_key = 0; U32 translated_mask = MASK_NONE; bool handled = false; @@ -246,9 +254,9 @@ bool LLKeyboardSDL::handleKeyDown(const U16 key, const U32 mask) } -bool LLKeyboardSDL::handleKeyUp(const U16 key, const U32 mask) +bool LLKeyboardSDL::handleKeyUp(const U32 key, const U32 mask) { - U16 adjusted_nativekey; + U32 adjusted_nativekey; KEY translated_key = 0; U32 translated_mask = MASK_NONE; bool handled = false; @@ -268,16 +276,20 @@ bool LLKeyboardSDL::handleKeyUp(const U16 key, const U32 mask) MASK LLKeyboardSDL::currentMask(bool for_mouse_event) { MASK result = MASK_NONE; - SDLMod mask = SDL_GetModState(); + SDL_Keymod mask = SDL_GetModState(); - if (mask & KMOD_SHIFT) result |= MASK_SHIFT; - if (mask & KMOD_CTRL) result |= MASK_CONTROL; - if (mask & KMOD_ALT) result |= MASK_ALT; + if (mask & KMOD_SHIFT) + result |= MASK_SHIFT; + if (mask & KMOD_CTRL) + result |= MASK_CONTROL; + if (mask & KMOD_ALT) + result |= MASK_ALT; // For keyboard events, consider Meta keys equivalent to Control if (!for_mouse_event) { - if (mask & KMOD_META) result |= MASK_CONTROL; + if (mask & KMOD_GUI) + result |= MASK_CONTROL; } return result; @@ -310,7 +322,7 @@ void LLKeyboardSDL::scanKeyboard() } -bool LLKeyboardSDL::translateNumpadKey( const U16 os_key, KEY *translated_key) +bool LLKeyboardSDL::translateNumpadKey( const U32 os_key, KEY *translated_key) { return translateKey(os_key, translated_key); } @@ -320,5 +332,338 @@ U16 LLKeyboardSDL::inverseTranslateNumpadKey(const KEY translated_key) return inverseTranslateKey(translated_key); } -#endif +enum class WindowsVK : U32 +{ + VK_UNKNOWN = 0, + VK_CANCEL = 0x03, + VK_BACK = 0x08, + VK_TAB = 0x09, + VK_CLEAR = 0x0C, + VK_RETURN = 0x0D, + VK_SHIFT = 0x10, + VK_CONTROL = 0x11, + VK_MENU = 0x12, + VK_PAUSE = 0x13, + VK_CAPITAL = 0x14, + VK_KANA = 0x15, + VK_HANGUL = 0x15, + VK_JUNJA = 0x17, + VK_FINAL = 0x18, + VK_HANJA = 0x19, + VK_KANJI = 0x19, + VK_ESCAPE = 0x1B, + VK_CONVERT = 0x1C, + VK_NONCONVERT = 0x1D, + VK_ACCEPT = 0x1E, + VK_MODECHANGE = 0x1F, + VK_SPACE = 0x20, + VK_PRIOR = 0x21, + VK_NEXT = 0x22, + VK_END = 0x23, + VK_HOME = 0x24, + VK_LEFT = 0x25, + VK_UP = 0x26, + VK_RIGHT = 0x27, + VK_DOWN = 0x28, + VK_SELECT = 0x29, + VK_PRINT = 0x2A, + VK_EXECUTE = 0x2B, + VK_SNAPSHOT = 0x2C, + VK_INSERT = 0x2D, + VK_DELETE = 0x2E, + VK_HELP = 0x2F, + VK_0 = 0x30, + VK_1 = 0x31, + VK_2 = 0x32, + VK_3 = 0x33, + VK_4 = 0x34, + VK_5 = 0x35, + VK_6 = 0x36, + VK_7 = 0x37, + VK_8 = 0x38, + VK_9 = 0x39, + VK_A = 0x41, + VK_B = 0x42, + VK_C = 0x43, + VK_D = 0x44, + VK_E = 0x45, + VK_F = 0x46, + VK_G = 0x47, + VK_H = 0x48, + VK_I = 0x49, + VK_J = 0x4A, + VK_K = 0x4B, + VK_L = 0x4C, + VK_M = 0x4D, + VK_N = 0x4E, + VK_O = 0x4F, + VK_P = 0x50, + VK_Q = 0x51, + VK_R = 0x52, + VK_S = 0x53, + VK_T = 0x54, + VK_U = 0x55, + VK_V = 0x56, + VK_W = 0x57, + VK_X = 0x58, + VK_Y = 0x59, + VK_Z = 0x5A, + VK_LWIN = 0x5B, + VK_RWIN = 0x5C, + VK_APPS = 0x5D, + VK_SLEEP = 0x5F, + VK_NUMPAD0 = 0x60, + VK_NUMPAD1 = 0x61, + VK_NUMPAD2 = 0x62, + VK_NUMPAD3 = 0x63, + VK_NUMPAD4 = 0x64, + VK_NUMPAD5 = 0x65, + VK_NUMPAD6 = 0x66, + VK_NUMPAD7 = 0x67, + VK_NUMPAD8 = 0x68, + VK_NUMPAD9 = 0x69, + VK_MULTIPLY = 0x6A, + VK_ADD = 0x6B, + VK_SEPARATOR = 0x6C, + VK_SUBTRACT = 0x6D, + VK_DECIMAL = 0x6E, + VK_DIVIDE = 0x6F, + VK_F1 = 0x70, + VK_F2 = 0x71, + VK_F3 = 0x72, + VK_F4 = 0x73, + VK_F5 = 0x74, + VK_F6 = 0x75, + VK_F7 = 0x76, + VK_F8 = 0x77, + VK_F9 = 0x78, + VK_F10 = 0x79, + VK_F11 = 0x7A, + VK_F12 = 0x7B, + VK_F13 = 0x7C, + VK_F14 = 0x7D, + VK_F15 = 0x7E, + VK_F16 = 0x7F, + VK_F17 = 0x80, + VK_F18 = 0x81, + VK_F19 = 0x82, + VK_F20 = 0x83, + VK_F21 = 0x84, + VK_F22 = 0x85, + VK_F23 = 0x86, + VK_F24 = 0x87, + VK_NUMLOCK = 0x90, + VK_SCROLL = 0x91, + VK_LSHIFT = 0xA0, + VK_RSHIFT = 0xA1, + VK_LCONTROL = 0xA2, + VK_RCONTROL = 0xA3, + VK_LMENU = 0xA4, + VK_RMENU = 0xA5, + VK_BROWSER_BACK = 0xA6, + VK_BROWSER_FORWARD = 0xA7, + VK_BROWSER_REFRESH = 0xA8, + VK_BROWSER_STOP = 0xA9, + VK_BROWSER_SEARCH = 0xAA, + VK_BROWSER_FAVORITES = 0xAB, + VK_BROWSER_HOME = 0xAC, + VK_VOLUME_MUTE = 0xAD, + VK_VOLUME_DOWN = 0xAE, + VK_VOLUME_UP = 0xAF, + VK_MEDIA_NEXT_TRACK = 0xB0, + VK_MEDIA_PREV_TRACK = 0xB1, + VK_MEDIA_STOP = 0xB2, + VK_MEDIA_PLAY_PAUSE = 0xB3, + VK_MEDIA_LAUNCH_MAIL = 0xB4, + VK_MEDIA_LAUNCH_MEDIA_SELECT = 0xB5, + VK_MEDIA_LAUNCH_APP1 = 0xB6, + VK_MEDIA_LAUNCH_APP2 = 0xB7, + VK_OEM_1 = 0xBA, + VK_OEM_PLUS = 0xBB, + VK_OEM_COMMA = 0xBC, + VK_OEM_MINUS = 0xBD, + VK_OEM_PERIOD = 0xBE, + VK_OEM_2 = 0xBF, + VK_OEM_3 = 0xC0, + VK_OEM_4 = 0xDB, + VK_OEM_5 = 0xDC, + VK_OEM_6 = 0xDD, + VK_OEM_7 = 0xDE, + VK_OEM_8 = 0xDF, + VK_OEM_102 = 0xE2, + VK_PROCESSKEY = 0xE5, + VK_PACKET = 0xE7, + VK_ATTN = 0xF6, + VK_CRSEL = 0xF7, + VK_EXSEL = 0xF8, + VK_EREOF = 0xF9, + VK_PLAY = 0xFA, + VK_ZOOM = 0xFB, + VK_NONAME = 0xFC, + VK_PA1 = 0xFD, + VK_OEM_CLEAR = 0xFE, +}; + +std::map< U32, U32 > mSDL2_to_Win; +std::set< U32 > mIgnoreSDL2Keys; + +U32 LLKeyboardSDL::mapSDL2toWin( U32 aSymbol ) +{ + // <FS:ND> Map SDLK_ virtual keys to Windows VK_ virtual keys. + // Text is handled via unicode input (SDL_TEXTINPUT event) and does not need to be translated into VK_ values as those match already. + if( mSDL2_to_Win.empty() ) + { + mSDL2_to_Win[ SDLK_BACKSPACE ] = (U32)WindowsVK::VK_BACK; + mSDL2_to_Win[ SDLK_TAB ] = (U32)WindowsVK::VK_TAB; + mSDL2_to_Win[ 12 ] = (U32)WindowsVK::VK_CLEAR; + mSDL2_to_Win[ SDLK_RETURN ] = (U32)WindowsVK::VK_RETURN; + mSDL2_to_Win[ 19 ] = (U32)WindowsVK::VK_PAUSE; + mSDL2_to_Win[ SDLK_ESCAPE ] = (U32)WindowsVK::VK_ESCAPE; + mSDL2_to_Win[ SDLK_SPACE ] = (U32)WindowsVK::VK_SPACE; + mSDL2_to_Win[ SDLK_QUOTE ] = (U32)WindowsVK::VK_OEM_7; + mSDL2_to_Win[ SDLK_COMMA ] = (U32)WindowsVK::VK_OEM_COMMA; + mSDL2_to_Win[ SDLK_MINUS ] = (U32)WindowsVK::VK_OEM_MINUS; + mSDL2_to_Win[ SDLK_PERIOD ] = (U32)WindowsVK::VK_OEM_PERIOD; + mSDL2_to_Win[ SDLK_SLASH ] = (U32)WindowsVK::VK_OEM_2; + + mSDL2_to_Win[ SDLK_0 ] = (U32)WindowsVK::VK_0; + mSDL2_to_Win[ SDLK_1 ] = (U32)WindowsVK::VK_1; + mSDL2_to_Win[ SDLK_2 ] = (U32)WindowsVK::VK_2; + mSDL2_to_Win[ SDLK_3 ] = (U32)WindowsVK::VK_3; + mSDL2_to_Win[ SDLK_4 ] = (U32)WindowsVK::VK_4; + mSDL2_to_Win[ SDLK_5 ] = (U32)WindowsVK::VK_5; + mSDL2_to_Win[ SDLK_6 ] = (U32)WindowsVK::VK_6; + mSDL2_to_Win[ SDLK_7 ] = (U32)WindowsVK::VK_7; + mSDL2_to_Win[ SDLK_8 ] = (U32)WindowsVK::VK_8; + mSDL2_to_Win[ SDLK_9 ] = (U32)WindowsVK::VK_9; + + mSDL2_to_Win[ SDLK_SEMICOLON ] = (U32)WindowsVK::VK_OEM_1; + mSDL2_to_Win[ SDLK_LESS ] = (U32)WindowsVK::VK_OEM_102; + mSDL2_to_Win[ SDLK_EQUALS ] = (U32)WindowsVK::VK_OEM_PLUS; + mSDL2_to_Win[ SDLK_KP_EQUALS ] = (U32)WindowsVK::VK_OEM_PLUS; + + mSDL2_to_Win[ SDLK_LEFTBRACKET ] = (U32)WindowsVK::VK_OEM_4; + mSDL2_to_Win[ SDLK_BACKSLASH ] = (U32)WindowsVK::VK_OEM_5; + mSDL2_to_Win[ SDLK_RIGHTBRACKET ] = (U32)WindowsVK::VK_OEM_6; + mSDL2_to_Win[ SDLK_BACKQUOTE ] = (U32)WindowsVK::VK_OEM_8; + + mSDL2_to_Win[ SDLK_a ] = (U32)WindowsVK::VK_A; + mSDL2_to_Win[ SDLK_b ] = (U32)WindowsVK::VK_B; + mSDL2_to_Win[ SDLK_c ] = (U32)WindowsVK::VK_C; + mSDL2_to_Win[ SDLK_d ] = (U32)WindowsVK::VK_D; + mSDL2_to_Win[ SDLK_e ] = (U32)WindowsVK::VK_E; + mSDL2_to_Win[ SDLK_f ] = (U32)WindowsVK::VK_F; + mSDL2_to_Win[ SDLK_g ] = (U32)WindowsVK::VK_G; + mSDL2_to_Win[ SDLK_h ] = (U32)WindowsVK::VK_H; + mSDL2_to_Win[ SDLK_i ] = (U32)WindowsVK::VK_I; + mSDL2_to_Win[ SDLK_j ] = (U32)WindowsVK::VK_J; + mSDL2_to_Win[ SDLK_k ] = (U32)WindowsVK::VK_K; + mSDL2_to_Win[ SDLK_l ] = (U32)WindowsVK::VK_L; + mSDL2_to_Win[ SDLK_m ] = (U32)WindowsVK::VK_M; + mSDL2_to_Win[ SDLK_n ] = (U32)WindowsVK::VK_N; + mSDL2_to_Win[ SDLK_o ] = (U32)WindowsVK::VK_O; + mSDL2_to_Win[ SDLK_p ] = (U32)WindowsVK::VK_P; + mSDL2_to_Win[ SDLK_q ] = (U32)WindowsVK::VK_Q; + mSDL2_to_Win[ SDLK_r ] = (U32)WindowsVK::VK_R; + mSDL2_to_Win[ SDLK_s ] = (U32)WindowsVK::VK_S; + mSDL2_to_Win[ SDLK_t ] = (U32)WindowsVK::VK_T; + mSDL2_to_Win[ SDLK_u ] = (U32)WindowsVK::VK_U; + mSDL2_to_Win[ SDLK_v ] = (U32)WindowsVK::VK_V; + mSDL2_to_Win[ SDLK_w ] = (U32)WindowsVK::VK_W; + mSDL2_to_Win[ SDLK_x ] = (U32)WindowsVK::VK_X; + mSDL2_to_Win[ SDLK_y ] = (U32)WindowsVK::VK_Y; + mSDL2_to_Win[ SDLK_z ] = (U32)WindowsVK::VK_Z; + + mSDL2_to_Win[ SDLK_DELETE ] = (U32)WindowsVK::VK_DELETE; + + + mSDL2_to_Win[ SDLK_NUMLOCKCLEAR ] = (U32)WindowsVK::VK_NUMLOCK; + mSDL2_to_Win[ SDLK_SCROLLLOCK ] = (U32)WindowsVK::VK_SCROLL; + + mSDL2_to_Win[ SDLK_HELP ] = (U32)WindowsVK::VK_HELP; + mSDL2_to_Win[ SDLK_PRINTSCREEN ] = (U32)WindowsVK::VK_SNAPSHOT; + mSDL2_to_Win[ SDLK_CANCEL ] = (U32)WindowsVK::VK_CANCEL; + mSDL2_to_Win[ SDLK_APPLICATION ] = (U32)WindowsVK::VK_APPS; + + mSDL2_to_Win[ SDLK_UNKNOWN ] = (U32)WindowsVK::VK_UNKNOWN; + mSDL2_to_Win[ SDLK_BACKSPACE ] = (U32)WindowsVK::VK_BACK; + mSDL2_to_Win[ SDLK_TAB ] = (U32)WindowsVK::VK_TAB; + mSDL2_to_Win[ SDLK_CLEAR ] = (U32)WindowsVK::VK_CLEAR; + mSDL2_to_Win[ SDLK_RETURN ] = (U32)WindowsVK::VK_RETURN; + mSDL2_to_Win[ SDLK_PAUSE ] = (U32)WindowsVK::VK_PAUSE; + mSDL2_to_Win[ SDLK_ESCAPE ] = (U32)WindowsVK::VK_ESCAPE; + mSDL2_to_Win[ SDLK_DELETE ] = (U32)WindowsVK::VK_DELETE; + + mSDL2_to_Win[ SDLK_KP_PERIOD ] = (U32)WindowsVK::VK_OEM_PERIOD; // VK_DECIMAL? + mSDL2_to_Win[ SDLK_KP_DIVIDE ] = (U32)WindowsVK::VK_DIVIDE; + mSDL2_to_Win[ SDLK_KP_MULTIPLY] = (U32)WindowsVK::VK_MULTIPLY; + mSDL2_to_Win[ SDLK_KP_MINUS ] = (U32)WindowsVK::VK_OEM_MINUS; // VK_SUBSTRACT? + mSDL2_to_Win[ SDLK_KP_PLUS ] = (U32)WindowsVK::VK_OEM_PLUS; // VK_ADD? + mSDL2_to_Win[ SDLK_KP_ENTER ] = (U32)WindowsVK::VK_RETURN; + mSDL2_to_Win[ SDLK_KP_0 ] = (U32)WindowsVK::VK_NUMPAD0; + mSDL2_to_Win[ SDLK_KP_1 ] = (U32)WindowsVK::VK_NUMPAD1; + mSDL2_to_Win[ SDLK_KP_2 ] = (U32)WindowsVK::VK_NUMPAD2; + mSDL2_to_Win[ SDLK_KP_3 ] = (U32)WindowsVK::VK_NUMPAD3; + mSDL2_to_Win[ SDLK_KP_4 ] = (U32)WindowsVK::VK_NUMPAD4; + mSDL2_to_Win[ SDLK_KP_5 ] = (U32)WindowsVK::VK_NUMPAD5; + mSDL2_to_Win[ SDLK_KP_6 ] = (U32)WindowsVK::VK_NUMPAD6; + mSDL2_to_Win[ SDLK_KP_7 ] = (U32)WindowsVK::VK_NUMPAD7; + mSDL2_to_Win[ SDLK_KP_8 ] = (U32)WindowsVK::VK_NUMPAD8; + mSDL2_to_Win[ SDLK_KP_9 ] = (U32)WindowsVK::VK_NUMPAD9; + + // ? + + mSDL2_to_Win[ SDLK_UP ] = (U32)WindowsVK::VK_UP; + mSDL2_to_Win[ SDLK_DOWN ] = (U32)WindowsVK::VK_DOWN; + mSDL2_to_Win[ SDLK_RIGHT ] = (U32)WindowsVK::VK_RIGHT; + mSDL2_to_Win[ SDLK_LEFT ] = (U32)WindowsVK::VK_LEFT; + mSDL2_to_Win[ SDLK_INSERT ] = (U32)WindowsVK::VK_INSERT; + mSDL2_to_Win[ SDLK_HOME ] = (U32)WindowsVK::VK_HOME; + mSDL2_to_Win[ SDLK_END ] = (U32)WindowsVK::VK_END; + mSDL2_to_Win[ SDLK_PAGEUP ] = (U32)WindowsVK::VK_PRIOR; + mSDL2_to_Win[ SDLK_PAGEDOWN ] = (U32)WindowsVK::VK_NEXT; + mSDL2_to_Win[ SDLK_F1 ] = (U32)WindowsVK::VK_F1; + mSDL2_to_Win[ SDLK_F2 ] = (U32)WindowsVK::VK_F2; + mSDL2_to_Win[ SDLK_F3 ] = (U32)WindowsVK::VK_F3; + mSDL2_to_Win[ SDLK_F4 ] = (U32)WindowsVK::VK_F4; + mSDL2_to_Win[ SDLK_F5 ] = (U32)WindowsVK::VK_F5; + mSDL2_to_Win[ SDLK_F6 ] = (U32)WindowsVK::VK_F6; + mSDL2_to_Win[ SDLK_F7 ] = (U32)WindowsVK::VK_F7; + mSDL2_to_Win[ SDLK_F8 ] = (U32)WindowsVK::VK_F8; + mSDL2_to_Win[ SDLK_F9 ] = (U32)WindowsVK::VK_F9; + mSDL2_to_Win[ SDLK_F10 ] = (U32)WindowsVK::VK_F10; + mSDL2_to_Win[ SDLK_F11 ] = (U32)WindowsVK::VK_F11; + mSDL2_to_Win[ SDLK_F12 ] = (U32)WindowsVK::VK_F12; + mSDL2_to_Win[ SDLK_F13 ] = (U32)WindowsVK::VK_F13; + mSDL2_to_Win[ SDLK_F14 ] = (U32)WindowsVK::VK_F14; + mSDL2_to_Win[ SDLK_F15 ] = (U32)WindowsVK::VK_F15; + mSDL2_to_Win[ SDLK_CAPSLOCK ] = (U32)WindowsVK::VK_CAPITAL; + mSDL2_to_Win[ SDLK_RSHIFT ] = (U32)WindowsVK::VK_SHIFT; + mSDL2_to_Win[ SDLK_LSHIFT ] = (U32)WindowsVK::VK_SHIFT; + mSDL2_to_Win[ SDLK_RCTRL ] = (U32)WindowsVK::VK_CONTROL; + mSDL2_to_Win[ SDLK_LCTRL ] = (U32)WindowsVK::VK_CONTROL; + mSDL2_to_Win[ SDLK_RALT ] = (U32)WindowsVK::VK_MENU; + mSDL2_to_Win[ SDLK_LALT ] = (U32)WindowsVK::VK_MENU; + + mSDL2_to_Win[ SDLK_MENU ] = (U32)WindowsVK::VK_MENU; + + // VK_MODECHANGE ? + // mSDL2_to_Win[ SDLK_MODE ] = (U32)WindowsVK::VK_MODE; + + // ? + // mSDL2_to_Win[ SDLK_SYSREQ ] = (U32)WindowsVK::VK_SYSREQ; + // mSDL2_to_Win[ SDLK_POWER ] = (U32)WindowsVK::VK_POWER; + // mSDL2_to_Win[ SDLK_UNDO ] = (U32)WindowsVK::VK_UNDO; + // mSDL2_to_Win[ SDLK_KP_EQUALS ] = (U32)WindowsVK::VK_EQUALS; + // mSDL2_to_Win[ 311 ] = (U32)WindowsVK::VK_LWIN; + // mSDL2_to_Win[ 312 ] = (U32)WindowsVK::VK_RWIN; + // mSDL2_to_Win[ SDLK_COLON ] = ? + } + + auto itr = mSDL2_to_Win.find( aSymbol ); + if( itr != mSDL2_to_Win.end() ) + return itr->second; + + return aSymbol; +} diff --git a/indra/llwindow/llkeyboardsdl.h b/indra/llwindow/llkeyboardsdl.h index fd348b28f2..3af098c4d1 100644 --- a/indra/llwindow/llkeyboardsdl.h +++ b/indra/llwindow/llkeyboardsdl.h @@ -1,8 +1,7 @@ /** - * @file llkeyboardsdl.h - * @brief Handler for assignable key bindings + * @author This module has many fathers, and it shows. * - * $LicenseInfo:firstyear=2004&license=viewerlgpl$ + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. * @@ -24,11 +23,14 @@ * $/LicenseInfo$ */ -#ifndef LL_LLKEYBOARDSDL_H -#define LL_LLKEYBOARDSDL_H +#ifndef LL_LLKEYBOARDSDL2_H +#define LL_LLKEYBOARDSDL2_H #include "llkeyboard.h" -#include "SDL/SDL.h" +#if !defined(__i386__) && !defined(__x86_64__) +#define SDL_DISABLE_IMMINTRIN_H +#endif +#include "SDL2/SDL.h" class LLKeyboardSDL : public LLKeyboard { @@ -36,8 +38,8 @@ public: LLKeyboardSDL(); /*virtual*/ ~LLKeyboardSDL() {}; - /*virtual*/ bool handleKeyUp(const U16 key, MASK mask); - /*virtual*/ bool handleKeyDown(const U16 key, MASK mask); + /*virtual*/ bool handleKeyUp(const U32 key, MASK mask); + /*virtual*/ bool handleKeyDown(const U32 key, MASK mask); /*virtual*/ void resetMaskKeys(); /*virtual*/ MASK currentMask(bool for_mouse_event); /*virtual*/ void scanKeyboard(); @@ -45,11 +47,14 @@ public: protected: MASK updateModifiers(const U32 mask); void setModifierKeyLevel( KEY key, bool new_state ); - bool translateNumpadKey( const U16 os_key, KEY *translated_key ); + bool translateNumpadKey( const U32 os_key, KEY *translated_key ); U16 inverseTranslateNumpadKey(const KEY translated_key); private: - std::map<U16, KEY> mTranslateNumpadMap; // special map for translating OS keys to numpad keys - std::map<KEY, U16> mInvTranslateNumpadMap; // inverse of the above + std::map<U32, KEY> mTranslateNumpadMap; // special map for translating OS keys to numpad keys + std::map<KEY, U32> mInvTranslateNumpadMap; // inverse of the above + +public: + static U32 mapSDL2toWin( U32 ); }; #endif diff --git a/indra/llwindow/llopenglview-objc.mm b/indra/llwindow/llopenglview-objc.mm index 0bd4e506a2..6177eb4873 100644 --- a/indra/llwindow/llopenglview-objc.mm +++ b/indra/llwindow/llopenglview-objc.mm @@ -64,16 +64,16 @@ attributedStringInfo getSegments(NSAttributedString *str) segment_standouts seg_standouts; NSRange effectiveRange; NSRange limitRange = NSMakeRange(0, [str length]); - + while (limitRange.length > 0) { NSNumber *attr = [str attribute:NSUnderlineStyleAttributeName atIndex:limitRange.location longestEffectiveRange:&effectiveRange inRange:limitRange]; limitRange = NSMakeRange(NSMaxRange(effectiveRange), NSMaxRange(limitRange) - NSMaxRange(effectiveRange)); - + if (effectiveRange.length <= 0) { effectiveRange.length = 1; } - + if ([attr integerValue] == 2) { seg_lengths.push_back(effectiveRange.length); @@ -96,12 +96,12 @@ attributedStringInfo getSegments(NSAttributedString *str) + (NSScreen *)currentScreenForMouseLocation { NSPoint mouseLocation = [NSEvent mouseLocation]; - + NSEnumerator *screenEnumerator = [[NSScreen screens] objectEnumerator]; NSScreen *screen; while ((screen = [screenEnumerator nextObject]) && !NSMouseInRect(mouseLocation, screen.frame, NO)) ; - + return screen; } @@ -110,7 +110,7 @@ attributedStringInfo getSegments(NSAttributedString *str) { float normalizedX = fabs(fabs(self.frame.origin.x) - fabs(aPoint.x)); float normalizedY = aPoint.y - self.frame.origin.y; - + return NSMakePoint(normalizedX, normalizedY); } @@ -153,7 +153,7 @@ attributedStringInfo getSegments(NSAttributedString *str) { vram_megabytes = 256; } - + return (unsigned long)vram_megabytes; // return value is in megabytes. } @@ -162,15 +162,15 @@ attributedStringInfo getSegments(NSAttributedString *str) [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(windowResized:) name:NSWindowDidResizeNotification object:[self window]]; - + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(windowWillMiniaturize:) name:NSWindowWillMiniaturizeNotification object:[self window]]; - + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(windowDidDeminiaturize:) name:NSWindowDidDeminiaturizeNotification object:[self window]]; - + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(windowDidBecomeKey:) name:NSWindowDidBecomeKeyNotification object:[self window]]; @@ -246,7 +246,7 @@ attributedStringInfo getSegments(NSAttributedString *str) { [self registerForDraggedTypes:[NSArray arrayWithObject:NSURLPboardType]]; [self initWithFrame:frame]; - + // Initialize with a default "safe" pixel format that will work with versions dating back to OS X 10.6. // Any specialized pixel formats, i.e. a core profile pixel format, should be initialized through rebuildContextWithFormat. // 10.7 and 10.8 don't really care if we're defining a profile or not. If we don't explicitly request a core or legacy profile, it'll always assume a legacy profile (for compatibility reasons). @@ -255,8 +255,8 @@ attributedStringInfo getSegments(NSAttributedString *str) NSOpenGLPFADoubleBuffer, NSOpenGLPFAClosestPolicy, NSOpenGLPFAAccelerated, - NSOpenGLPFASampleBuffers, static_cast<NSOpenGLPixelFormatAttribute>(samples > 0 ? 1 : 0), - NSOpenGLPFASamples, static_cast<NSOpenGLPixelFormatAttribute>(samples), + NSOpenGLPFASampleBuffers, 0, + NSOpenGLPFASamples, 0, NSOpenGLPFAStencilSize, 8, NSOpenGLPFADepthSize, 24, NSOpenGLPFAAlphaSize, 8, @@ -264,34 +264,34 @@ attributedStringInfo getSegments(NSAttributedString *str) NSOpenGLPFAOpenGLProfile, NSOpenGLProfileVersion4_1Core, 0 }; - + NSOpenGLPixelFormat *pixelFormat = [[[NSOpenGLPixelFormat alloc] initWithAttributes:attrs] autorelease]; - + if (pixelFormat == nil) { NSLog(@"Failed to create pixel format!", nil); return nil; } - + NSOpenGLContext *glContext = [[NSOpenGLContext alloc] initWithFormat:pixelFormat shareContext:nil]; - + if (glContext == nil) { NSLog(@"Failed to create OpenGL context!", nil); return nil; } - + [self setPixelFormat:pixelFormat]; //for retina support [self setWantsBestResolutionOpenGLSurface:gHiDPISupport]; [self setOpenGLContext:glContext]; - + [glContext setView:self]; - + [glContext makeCurrentContext]; - + if (vsync) { GLint value = 1; @@ -303,9 +303,9 @@ attributedStringInfo getSegments(NSAttributedString *str) GLint swapInterval=0; [glContext setValues:&swapInterval forParameter:NSOpenGLCPSwapInterval]; } - + mOldResize = false; - + return self; } @@ -317,16 +317,16 @@ attributedStringInfo getSegments(NSAttributedString *str) - (BOOL) rebuildContextWithFormat:(NSOpenGLPixelFormat *)format { NSOpenGLContext *ctx = [self openGLContext]; - + [ctx clearDrawable]; [ctx initWithFormat:format shareContext:nil]; - + if (ctx == nil) { NSLog(@"Failed to create OpenGL context!", nil); return false; } - + [self setOpenGLContext:ctx]; [ctx setView:self]; [ctx makeCurrentContext]; @@ -413,9 +413,9 @@ attributedStringInfo getSegments(NSAttributedString *str) float(dev_delta.x), float(dev_delta.y) }; - + callDeltaUpdate(mouseDeltas, 0); - + NSPoint mPoint = gHiDPISupport ? [self convertPointToBacking:[theEvent locationInWindow]] : [theEvent locationInWindow]; mMousePos[0] = mPoint.x; mMousePos[1] = mPoint.y; @@ -437,9 +437,9 @@ attributedStringInfo getSegments(NSAttributedString *str) float(dev_delta.x), float(dev_delta.y) }; - + callDeltaUpdate(mouseDeltas, 0); - + NSPoint mPoint = gHiDPISupport ? [self convertPointToBacking:[theEvent locationInWindow]] : [theEvent locationInWindow]; mMousePos[0] = mPoint.x; mMousePos[1] = mPoint.y; @@ -469,7 +469,7 @@ attributedStringInfo getSegments(NSAttributedString *str) - (void) otherMouseDragged:(NSEvent *)theEvent { - [self mouseDragged:theEvent]; + [self mouseDragged:theEvent]; } - (void) scrollWheel:(NSEvent *)theEvent @@ -493,7 +493,7 @@ attributedStringInfo getSegments(NSAttributedString *str) { NativeKeyEventData eventData = extractKeyDataFromKeyEvent(theEvent); eventData.mKeyEvent = NativeKeyEventData::KEYDOWN; - + uint keycode = [theEvent keyCode]; // We must not depend on flagsChange event to detect modifier flags changed, // must depend on the modifire flags in the event parameter. @@ -527,13 +527,13 @@ attributedStringInfo getSegments(NSAttributedString *str) - (void)flagsChanged:(NSEvent *)theEvent { NativeKeyEventData eventData = extractKeyDataFromModifierEvent(theEvent); - + mModifiers = [theEvent modifierFlags]; callModifier([theEvent modifierFlags]); - + NSInteger mask = 0; switch([theEvent keyCode]) - { + { case 56: mask = NSShiftKeyMask; break; @@ -544,9 +544,9 @@ attributedStringInfo getSegments(NSAttributedString *str) mask = NSControlKeyMask; break; default: - return; + return; } - + if (mModifiers & mask) { eventData.mKeyEvent = NativeKeyEventData::KEYDOWN; @@ -565,7 +565,7 @@ attributedStringInfo getSegments(NSAttributedString *str) { eventData.mKeyEvent = NativeKeyEventData::KEYUP; callKeyUp(&eventData, [theEvent keyCode], 0); - } + } } - (BOOL) acceptsFirstResponder @@ -577,11 +577,11 @@ attributedStringInfo getSegments(NSAttributedString *str) { NSPasteboard *pboard; NSDragOperation sourceDragMask; - + sourceDragMask = [sender draggingSourceOperationMask]; - + pboard = [sender draggingPasteboard]; - + if ([[pboard types] containsObject:NSURLPboardType]) { if (sourceDragMask & NSDragOperationLink) { @@ -596,7 +596,7 @@ attributedStringInfo getSegments(NSAttributedString *str) - (NSDragOperation)draggingUpdated:(id <NSDraggingInfo>)sender { callHandleDragUpdated(mLastDraggedUrl); - + return NSDragOperationLink; } @@ -650,12 +650,12 @@ attributedStringInfo getSegments(NSAttributedString *str) unsigned(selectedRange.location), unsigned(selectedRange.length) }; - + unsigned int replacement[2] = { unsigned(replacementRange.location), unsigned(replacementRange.length) }; - + int string_length = [aString length]; unichar text[string_length]; attributedStringInfo segments; @@ -754,7 +754,7 @@ attributedStringInfo getSegments(NSAttributedString *str) return; } } - + @try { if (!mHasMarkedText) @@ -767,7 +767,7 @@ attributedStringInfo getSegments(NSAttributedString *str) resetPreedit(); // We may never get this point since unmarkText may be called before insertText ever gets called once we submit our text. // But just in case... - + for (NSInteger i = 0; i < [aString length]; i++) { handleUnicodeCharacter([aString characterAtIndex:i]); @@ -913,10 +913,10 @@ attributedStringInfo getSegments(NSAttributedString *str) NSPoint screenPoint = [[view window] convertBaseToScreen:windowPoint]; NSPoint flippedScreenPoint = [currentScreen flipPoint:screenPoint]; flippedScreenPoint.y += [currentScreen frame].origin.y; - + return flippedScreenPoint; } - + return NSZeroPoint; } diff --git a/indra/llwindow/llwindow.cpp b/indra/llwindow/llwindow.cpp index 378e633cd2..302d038a79 100644 --- a/indra/llwindow/llwindow.cpp +++ b/indra/llwindow/llwindow.cpp @@ -76,7 +76,7 @@ S32 OSMessageBox(const std::string& text, const std::string& caption, U32 type) return OSBTN_OK; #elif LL_WINDOWS result = OSMessageBoxWin32(text, caption, type); -#elif LL_DARWIN +#elif LL_DARWIN && !LL_SDL result = OSMessageBoxMacOSX(text, caption, type); #elif LL_SDL result = OSMessageBoxSDL(text, caption, type); @@ -261,7 +261,7 @@ std::vector<std::string> LLWindow::getDynamicFallbackFontList() { #if LL_WINDOWS return LLWindowWin32::getDynamicFallbackFontList(); -#elif LL_DARWIN +#elif LL_DARWIN && !LL_SDL return LLWindowMacOSX::getDynamicFallbackFontList(); #elif LL_SDL return LLWindowSDL::getDynamicFallbackFontList(); @@ -275,7 +275,7 @@ std::vector<std::string> LLWindow::getDisplaysResolutionList() { #if LL_WINDOWS return LLWindowWin32::getDisplaysResolutionList(); -#elif LL_DARWIN +#elif LL_DARWIN && !LL_SDL return LLWindowMacOSX::getDisplaysResolutionList(); #else return std::vector<std::string>(); @@ -346,7 +346,7 @@ LLSplashScreen *LLSplashScreen::create() return 0; #elif LL_WINDOWS return new LLSplashScreenWin32; -#elif LL_DARWIN +#elif LL_DARWIN && !LL_SDL return new LLSplashScreenMacOSX; #else #error("LLSplashScreen not implemented on this platform!") @@ -361,7 +361,7 @@ void LLSplashScreen::show() { #if LL_WINDOWS && !LL_MESA_HEADLESS gSplashScreenp = new LLSplashScreenWin32; -#elif LL_DARWIN +#elif LL_DARWIN && !LL_SDL gSplashScreenp = new LLSplashScreenMacOSX; #endif if (gSplashScreenp) @@ -411,7 +411,7 @@ LLWindow* LLWindowManager::createWindow( U32 max_cores, F32 max_gl_version) { - LLWindow* new_window; + LLWindow* new_window = nullptr; if (use_gl) { diff --git a/indra/llwindow/llwindowcallbacks.cpp b/indra/llwindow/llwindowcallbacks.cpp index c160382c17..195f68e08b 100644 --- a/indra/llwindow/llwindowcallbacks.cpp +++ b/indra/llwindow/llwindowcallbacks.cpp @@ -194,6 +194,11 @@ bool LLWindowCallbacks::handleDPIChanged(LLWindow *window, F32 ui_scale_factor, return false; } +bool LLWindowCallbacks::handleDisplayChanged() +{ + return false; +} + bool LLWindowCallbacks::handleWindowDidChangeScreen(LLWindow *window) { return false; diff --git a/indra/llwindow/llwindowcallbacks.h b/indra/llwindow/llwindowcallbacks.h index 63b585231f..d812f93524 100644 --- a/indra/llwindow/llwindowcallbacks.h +++ b/indra/llwindow/llwindowcallbacks.h @@ -69,6 +69,7 @@ public: virtual bool handleTimerEvent(LLWindow *window); virtual bool handleDeviceChange(LLWindow *window); virtual bool handleDPIChanged(LLWindow *window, F32 ui_scale_factor, S32 window_width, S32 window_height); + virtual bool handleDisplayChanged(); virtual bool handleWindowDidChangeScreen(LLWindow *window); enum DragNDropAction { diff --git a/indra/llwindow/llwindowmacosx.cpp b/indra/llwindow/llwindowmacosx.cpp index f26d692363..c97e014e46 100644 --- a/indra/llwindow/llwindowmacosx.cpp +++ b/indra/llwindow/llwindowmacosx.cpp @@ -38,6 +38,7 @@ #include "lldir.h" #include "indra_constants.h" + #include <OpenGL/OpenGL.h> #include <Carbon/Carbon.h> #include <CoreServices/CoreServices.h> @@ -279,6 +280,10 @@ void callResetKeys() bool callUnicodeCallback(wchar_t character, unsigned int mask) { + if (!gWindowImplementation) + { + return false; + } NativeKeyEventData eventData; memset(&eventData, 0, sizeof(NativeKeyEventData)); @@ -300,7 +305,7 @@ bool callUnicodeCallback(wchar_t character, unsigned int mask) void callFocus() { - if (gWindowImplementation) + if (gWindowImplementation && gWindowImplementation->getCallbacks()) { gWindowImplementation->getCallbacks()->handleFocus(gWindowImplementation); } @@ -308,7 +313,7 @@ void callFocus() void callFocusLost() { - if (gWindowImplementation) + if (gWindowImplementation && gWindowImplementation->getCallbacks()) { gWindowImplementation->getCallbacks()->handleFocusLost(gWindowImplementation); } @@ -316,6 +321,10 @@ void callFocusLost() void callRightMouseDown(float *pos, MASK mask) { + if (!gWindowImplementation) + { + return; + } if (gWindowImplementation->allowsLanguageInput()) { gWindowImplementation->interruptLanguageTextInput(); @@ -329,6 +338,10 @@ void callRightMouseDown(float *pos, MASK mask) void callRightMouseUp(float *pos, MASK mask) { + if (!gWindowImplementation) + { + return; + } if (gWindowImplementation->allowsLanguageInput()) { gWindowImplementation->interruptLanguageTextInput(); @@ -342,6 +355,10 @@ void callRightMouseUp(float *pos, MASK mask) void callLeftMouseDown(float *pos, MASK mask) { + if (!gWindowImplementation) + { + return; + } if (gWindowImplementation->allowsLanguageInput()) { gWindowImplementation->interruptLanguageTextInput(); @@ -355,6 +372,10 @@ void callLeftMouseDown(float *pos, MASK mask) void callLeftMouseUp(float *pos, MASK mask) { + if (!gWindowImplementation) + { + return; + } if (gWindowImplementation->allowsLanguageInput()) { gWindowImplementation->interruptLanguageTextInput(); @@ -369,6 +390,10 @@ void callLeftMouseUp(float *pos, MASK mask) void callDoubleClick(float *pos, MASK mask) { + if (!gWindowImplementation) + { + return; + } if (gWindowImplementation->allowsLanguageInput()) { gWindowImplementation->interruptLanguageTextInput(); @@ -382,7 +407,7 @@ void callDoubleClick(float *pos, MASK mask) void callResize(unsigned int width, unsigned int height) { - if (gWindowImplementation != NULL) + if (gWindowImplementation && gWindowImplementation->getCallbacks()) { gWindowImplementation->getCallbacks()->handleResize(gWindowImplementation, width, height); } @@ -390,6 +415,10 @@ void callResize(unsigned int width, unsigned int height) void callMouseMoved(float *pos, MASK mask) { + if (!gWindowImplementation) + { + return; + } LLCoordGL outCoords; outCoords.mX = ll_round(pos[0]); outCoords.mY = ll_round(pos[1]); @@ -403,6 +432,10 @@ void callMouseMoved(float *pos, MASK mask) void callMouseDragged(float *pos, MASK mask) { + if (!gWindowImplementation) + { + return; + } LLCoordGL outCoords; outCoords.mX = ll_round(pos[0]); outCoords.mY = ll_round(pos[1]); @@ -424,6 +457,10 @@ void callScrollMoved(float deltaX, float deltaY) void callMouseExit() { + if (!gWindowImplementation) + { + return; + } gWindowImplementation->getCallbacks()->handleMouseLeave(gWindowImplementation); } @@ -475,11 +512,19 @@ void callWindowDidChangeScreen() void callDeltaUpdate(float *delta, MASK mask) { + if (!gWindowImplementation) + { + return; + } gWindowImplementation->updateMouseDeltas(delta); } void callOtherMouseDown(float *pos, MASK mask, int button) { + if (!gWindowImplementation) + { + return; + } LLCoordGL outCoords; outCoords.mX = ll_round(pos[0]); outCoords.mY = ll_round(pos[1]); @@ -500,6 +545,10 @@ void callOtherMouseDown(float *pos, MASK mask, int button) void callOtherMouseUp(float *pos, MASK mask, int button) { + if (!gWindowImplementation) + { + return; + } LLCoordGL outCoords; outCoords.mX = ll_round(pos[0]); outCoords.mY = ll_round(pos[1]); @@ -524,27 +573,43 @@ void callModifier(MASK mask) void callHandleDragEntered(std::string url) { + if (!gWindowImplementation) + { + return; + } gWindowImplementation->handleDragNDrop(url, LLWindowCallbacks::DNDA_START_TRACKING); } void callHandleDragExited(std::string url) { + if (!gWindowImplementation) + { + return; + } gWindowImplementation->handleDragNDrop(url, LLWindowCallbacks::DNDA_STOP_TRACKING); } void callHandleDragUpdated(std::string url) { + if (!gWindowImplementation) + { + return; + } gWindowImplementation->handleDragNDrop(url, LLWindowCallbacks::DNDA_TRACK); } void callHandleDragDropped(std::string url) { + if (!gWindowImplementation) + { + return; + } gWindowImplementation->handleDragNDrop(url, LLWindowCallbacks::DNDA_DROPPED); } void callQuitHandler() { - if (gWindowImplementation) + if (gWindowImplementation && gWindowImplementation->getCallbacks()) { if(gWindowImplementation->getCallbacks()->handleCloseRequest(gWindowImplementation)) { @@ -555,7 +620,7 @@ void callQuitHandler() void getPreeditSelectionRange(int *position, int *length) { - if (gWindowImplementation->getPreeditor()) + if (gWindowImplementation && gWindowImplementation->getPreeditor()) { gWindowImplementation->getPreeditor()->getSelectionRange(position, length); } @@ -563,7 +628,7 @@ void getPreeditSelectionRange(int *position, int *length) void getPreeditMarkedRange(int *position, int *length) { - if (gWindowImplementation->getPreeditor()) + if (gWindowImplementation && gWindowImplementation->getPreeditor()) { gWindowImplementation->getPreeditor()->getPreeditRange(position, length); } @@ -571,7 +636,7 @@ void getPreeditMarkedRange(int *position, int *length) void setPreeditMarkedRange(int position, int length) { - if (gWindowImplementation->getPreeditor()) + if (gWindowImplementation && gWindowImplementation->getPreeditor()) { gWindowImplementation->getPreeditor()->markAsPreedit(position, length); } @@ -580,7 +645,7 @@ void setPreeditMarkedRange(int position, int length) bool handleUnicodeCharacter(wchar_t c) { bool success = false; - if (gWindowImplementation->getPreeditor()) + if (gWindowImplementation && gWindowImplementation->getPreeditor()) { success = gWindowImplementation->getPreeditor()->handleUnicodeCharHere(c); } @@ -590,7 +655,7 @@ bool handleUnicodeCharacter(wchar_t c) void resetPreedit() { - if (gWindowImplementation->getPreeditor()) + if (gWindowImplementation && gWindowImplementation->getPreeditor()) { gWindowImplementation->getPreeditor()->resetPreedit(); } @@ -600,7 +665,7 @@ void resetPreedit() // This largely mirrors the old implementation, only sans the carbon parameters. void setMarkedText(unsigned short *unitext, unsigned int *selectedRange, unsigned int *replacementRange, long text_len, attributedStringInfo segments) { - if (gWindowImplementation->getPreeditor()) + if (gWindowImplementation && gWindowImplementation->getPreeditor()) { LLPreeditor *preeditor = gWindowImplementation->getPreeditor(); preeditor->resetPreedit(); @@ -623,7 +688,7 @@ void setMarkedText(unsigned short *unitext, unsigned int *selectedRange, unsigne void getPreeditLocation(float *location, unsigned int length) { - if (gWindowImplementation->getPreeditor()) + if (gWindowImplementation && gWindowImplementation->getPreeditor()) { LLPreeditor *preeditor = gWindowImplementation->getPreeditor(); LLCoordGL coord; @@ -1060,7 +1125,7 @@ F32 LLWindowMacOSX::getGamma() &greenGamma, &blueMin, &blueMax, - &blueGamma) == noErr) + &blueGamma) == kCGErrorSuccess) { // So many choices... // Let's just return the green channel gamma for now. @@ -1111,7 +1176,7 @@ bool LLWindowMacOSX::setGamma(const F32 gamma) &greenGamma, &blueMin, &blueMax, - &blueGamma) != noErr) + &blueGamma) != kCGErrorSuccess) { return false; } @@ -1126,7 +1191,7 @@ bool LLWindowMacOSX::setGamma(const F32 gamma) gamma, blueMin, blueMax, - gamma) != noErr) + gamma) != kCGErrorSuccess) { return false; } @@ -1178,7 +1243,7 @@ bool LLWindowMacOSX::setCursorPosition(const LLCoordWindow position) newPosition.y = screen_pos.mY; CGSetLocalEventsSuppressionInterval(0.0); - if(CGWarpMouseCursorPosition(newPosition) == noErr) + if(CGWarpMouseCursorPosition(newPosition) == kCGErrorSuccess) { result = true; } diff --git a/indra/llwindow/llwindowsdl.cpp b/indra/llwindow/llwindowsdl.cpp index 7433ad6bd2..8c90f917b8 100644 --- a/indra/llwindow/llwindowsdl.cpp +++ b/indra/llwindow/llwindowsdl.cpp @@ -25,8 +25,6 @@ * $/LicenseInfo$ */ -#if LL_SDL - #include "linden_common.h" #include "llwindowsdl.h" @@ -40,23 +38,23 @@ #include "lldir.h" #include "llfindlocale.h" -#if LL_GTK -extern "C" { -# include "gtk/gtk.h" -} -#include <locale.h> -#endif // LL_GTK +#ifdef LL_GLIB +#include <glib.h> +#endif extern "C" { # include "fontconfig/fontconfig.h" } -#if LL_LINUX +#if LL_LINUX || __FreeBSD__ // not necessarily available on random SDL platforms, so #if LL_LINUX // for execv(), waitpid(), fork() # include <unistd.h> # include <sys/types.h> # include <sys/wait.h> +# define GLX_GLXEXT_PROTOTYPES 1 +# include <GL/glx.h> +# include <stdio.h> #endif // LL_LINUX extern bool gDebugWindowProc; @@ -66,6 +64,43 @@ const S32 MAX_NUM_RESOLUTIONS = 200; // static variable for ATI mouse cursor crash work-around: static bool ATIbug = false; +#if LL_DARWIN + +#include <OpenGL/OpenGL.h> +#include <CoreGraphics/CGDirectDisplay.h> +#include <CoreServices/CoreServices.h> + +bool gHiDPISupport = true; + +namespace +{ + struct NativeKeyEventData { + enum EventType { + KEYUNKNOWN, + KEYUP, + KEYDOWN, + KEYCHAR + }; + + EventType mKeyEvent = KEYUNKNOWN; + uint32_t mEventType = 0; + uint32_t mEventModifiers = 0; + uint32_t mEventKeyCode = 0; + uint32_t mEventChars = 0; + uint32_t mEventUnmodChars = 0; + bool mEventRepeat = false; + } *mRawKeyEvent = NULL; +} +// +// LLWindowMacOSX +// + +bool LLWindowSDL::sUseMultGL = false; + +#endif + +bool hasHIDPI = 0; + // // LLWindowSDL // @@ -97,108 +132,291 @@ void maybe_unlock_display(void) } -#if LL_GTK -// Lazily initialize and check the runtime GTK version for goodness. +#if LL_X11 // static -bool LLWindowSDL::ll_try_gtk_init(void) +Window LLWindowSDL::get_SDL_XWindowID(void) +{ + if (gWindowImplementation) { + return gWindowImplementation->mSDL_XWindowID; + } + return None; +} + +//static +Display* LLWindowSDL::get_SDL_Display(void) +{ + if (gWindowImplementation) { + return gWindowImplementation->mSDL_Display; + } + return NULL; +} +#endif // LL_X11 + +#if LL_X11 + +// Clipboard handing via native X11, base on the implementation in Cool VL by Henri Beauchamp + +namespace { - static bool done_gtk_diag = false; - static bool gtk_is_good = false; - static bool done_setlocale = false; - static bool tried_gtk_init = false; + std::array<Atom, 3> gSupportedAtoms; - if (!done_setlocale) + Atom XA_CLIPBOARD; + Atom XA_TARGETS; + Atom PVT_PASTE_BUFFER; + long const MAX_PASTE_BUFFER_SIZE = 16383; + + void filterSelectionRequest( XEvent aEvent ) { - LL_INFOS() << "Starting GTK Initialization." << LL_ENDL; - maybe_lock_display(); - gtk_disable_setlocale(); - maybe_unlock_display(); - done_setlocale = true; + auto *display = LLWindowSDL::getSDLDisplay(); + auto &request = aEvent.xselectionrequest; + + XSelectionEvent reply { SelectionNotify, aEvent.xany.serial, aEvent.xany.send_event, display, + request.requestor, request.selection, request.target, + request.property,request.time }; + + if (request.target == XA_TARGETS) + { + XChangeProperty(display, request.requestor, request.property, + XA_ATOM, 32, PropModeReplace, + (unsigned char *) &gSupportedAtoms.front(), gSupportedAtoms.size()); + } + else if (std::find(gSupportedAtoms.begin(), gSupportedAtoms.end(), request.target) != + gSupportedAtoms.end()) + { + std::string utf8; + if (request.selection == XA_PRIMARY) + utf8 = wstring_to_utf8str(gWindowImplementation->getPrimaryText()); + else + utf8 = wstring_to_utf8str(gWindowImplementation->getSecondaryText()); + + XChangeProperty(display, request.requestor, request.property, + request.target, 8, PropModeReplace, + (unsigned char *) utf8.c_str(), utf8.length()); + } + else if (request.selection == XA_CLIPBOARD) + { + // Did not have what they wanted, so no property set + reply.property = None; + } + else + return; + + XSendEvent(request.display, request.requestor, False, NoEventMask, (XEvent *) &reply); + XSync(display, False); } - if (!tried_gtk_init) + void filterSelectionClearRequest( XEvent aEvent ) { - tried_gtk_init = true; - if (!g_thread_supported ()) g_thread_init (NULL); - maybe_lock_display(); - gtk_is_good = gtk_init_check(NULL, NULL); - maybe_unlock_display(); - if (!gtk_is_good) - LL_WARNS() << "GTK Initialization failed." << LL_ENDL; + auto &request = aEvent.xselectionrequest; + if (request.selection == XA_PRIMARY) + gWindowImplementation->clearPrimaryText(); + else if (request.selection == XA_CLIPBOARD) + gWindowImplementation->clearSecondaryText(); } - if (gtk_is_good && !done_gtk_diag) + int x11_clipboard_filter(void*, SDL_Event *evt) { - LL_INFOS() << "GTK Initialized." << LL_ENDL; - LL_INFOS() << "- Compiled against GTK version " - << GTK_MAJOR_VERSION << "." - << GTK_MINOR_VERSION << "." - << GTK_MICRO_VERSION << LL_ENDL; - LL_INFOS() << "- Running against GTK version " - << gtk_major_version << "." - << gtk_minor_version << "." - << gtk_micro_version << LL_ENDL; + Display *display = LLWindowSDL::getSDLDisplay(); + if (!display) + return 1; + + if (evt->type != SDL_SYSWMEVENT) + return 1; + + auto xevent = evt->syswm.msg->msg.x11.event; + + if (xevent.type == SelectionRequest) + filterSelectionRequest( xevent ); + else if (xevent.type == SelectionClear) + filterSelectionClearRequest( xevent ); + return 1; + } + + bool grab_property(Display* display, Window window, Atom selection, Atom target) + { + if( !display ) + return false; + maybe_lock_display(); - const gchar* gtk_warning = gtk_check_version( - GTK_MAJOR_VERSION, - GTK_MINOR_VERSION, - GTK_MICRO_VERSION); + + XDeleteProperty(display, window, PVT_PASTE_BUFFER); + XFlush(display); + + XConvertSelection(display, selection, target, PVT_PASTE_BUFFER, window, CurrentTime); + + // Unlock the connection so that the SDL event loop may function maybe_unlock_display(); - if (gtk_warning) + + const auto start{ SDL_GetTicks() }; + const auto end{ start + 1000 }; + + XEvent xevent {}; + bool response = false; + + do { - LL_WARNS() << "- GTK COMPATIBILITY WARNING: " << - gtk_warning << LL_ENDL; - gtk_is_good = false; - } else { - LL_INFOS() << "- GTK version is good." << LL_ENDL; - } + SDL_Event event {}; + + // Wait for an event + SDL_WaitEvent(&event); + + // If the event is a window manager event + if (event.type == SDL_SYSWMEVENT) + { + xevent = event.syswm.msg->msg.x11.event; + + if (xevent.type == SelectionNotify && xevent.xselection.requestor == window) + response = true; + } + } while (!response && SDL_GetTicks() < end ); + + return response && xevent.xselection.property != None; + } +} + +void LLWindowSDL::initialiseX11Clipboard() +{ + if (!mSDL_Display) + return; + + SDL_EventState(SDL_SYSWMEVENT, SDL_ENABLE); + SDL_SetEventFilter(x11_clipboard_filter, nullptr); + + maybe_lock_display(); + + XA_CLIPBOARD = XInternAtom(mSDL_Display, "CLIPBOARD", False); + + gSupportedAtoms[0] = XInternAtom(mSDL_Display, "UTF8_STRING", False); + gSupportedAtoms[1] = XInternAtom(mSDL_Display, "COMPOUND_TEXT", False); + gSupportedAtoms[2] = XA_STRING; + + // TARGETS atom + XA_TARGETS = XInternAtom(mSDL_Display, "TARGETS", False); + + // SL_PASTE_BUFFER atom + PVT_PASTE_BUFFER = XInternAtom(mSDL_Display, "FS_PASTE_BUFFER", False); + + maybe_unlock_display(); +} + +bool LLWindowSDL::getSelectionText( Atom aSelection, Atom aType, LLWString &text ) +{ + if( !mSDL_Display ) + return false; + + if( !grab_property(mSDL_Display, mSDL_XWindowID, aSelection,aType ) ) + return false; - done_gtk_diag = true; + maybe_lock_display(); + + Atom type; + int format{}; + unsigned long len{},remaining {}; + unsigned char* data = nullptr; + int res = XGetWindowProperty(mSDL_Display, mSDL_XWindowID, + PVT_PASTE_BUFFER, 0, MAX_PASTE_BUFFER_SIZE, False, + AnyPropertyType, &type, &format, &len, + &remaining, &data); + if (data && len) + { + text = LLWString( + utf8str_to_wstring(reinterpret_cast< char const *>( data ) ) + ); + XFree(data); } - return gtk_is_good; + maybe_unlock_display(); + return res == Success; } -#endif // LL_GTK +bool LLWindowSDL::getSelectionText(Atom selection, LLWString& text) +{ + if (!mSDL_Display) + return false; -#if LL_X11 -// static -Window LLWindowSDL::get_SDL_XWindowID(void) + maybe_lock_display(); + + Window owner = XGetSelectionOwner(mSDL_Display, selection); + if (owner == None) + { + if (selection == XA_PRIMARY) + { + owner = DefaultRootWindow(mSDL_Display); + selection = XA_CUT_BUFFER0; + } + else + { + maybe_unlock_display(); + return false; + } + } + + maybe_unlock_display(); + + for( Atom atom : gSupportedAtoms ) + { + if(getSelectionText(selection, atom, text ) ) + return true; + } + + return false; +} + +bool LLWindowSDL::setSelectionText(Atom selection, const LLWString& text) { - if (gWindowImplementation) { - return gWindowImplementation->mSDL_XWindowID; + maybe_lock_display(); + + if (selection == XA_PRIMARY) + { + std::string utf8 = wstring_to_utf8str(text); + XStoreBytes(mSDL_Display, utf8.c_str(), utf8.length() + 1); + mPrimaryClipboard = text; } - return None; + else + mSecondaryClipboard = text; + + XSetSelectionOwner(mSDL_Display, selection, mSDL_XWindowID, CurrentTime); + + auto owner = XGetSelectionOwner(mSDL_Display, selection); + + maybe_unlock_display(); + + return owner == mSDL_XWindowID; } -//static -Display* LLWindowSDL::get_SDL_Display(void) +Display* LLWindowSDL::getSDLDisplay() { - if (gWindowImplementation) { + if (gWindowImplementation) return gWindowImplementation->mSDL_Display; - } - return NULL; + return nullptr; } -#endif // LL_X11 + +#endif LLWindowSDL::LLWindowSDL(LLWindowCallbacks* callbacks, - const std::string& title, S32 x, S32 y, S32 width, - S32 height, U32 flags, - bool fullscreen, bool clearBg, - bool disable_vsync, bool use_gl, - bool ignore_pixel_depth, U32 fsaa_samples) - : LLWindow(callbacks, fullscreen, flags), - Lock_Display(NULL), - Unlock_Display(NULL), mGamma(1.0f) + const std::string& title, S32 x, S32 y, S32 width, + S32 height, U32 flags, + bool fullscreen, bool clearBg, + bool disable_vsync, bool use_gl, + bool ignore_pixel_depth, U32 fsaa_samples) + : LLWindow(callbacks, fullscreen, flags), + Lock_Display(NULL), + //Unlock_Display(NULL), mGamma(1.0f) + Unlock_Display(NULL), mGamma(1.0f) { // Initialize the keyboard gKeyboard = new LLKeyboardSDL(); gKeyboard->setCallbacks(callbacks); // Note that we can't set up key-repeat until after SDL has init'd video +#if LL_DARWIN + hasHIDPI = gHiDPISupport; +#endif + // Ignore use_gl for now, only used for drones on PC mWindow = NULL; + mContext = {}; mNeedsResize = false; mOverrideAspectRatio = 0.f; mGrabbyKeyFlags = 0; @@ -212,13 +430,6 @@ LLWindowSDL::LLWindowSDL(LLWindowCallbacks* callbacks, mSDL_Display = NULL; #endif // LL_X11 -#if LL_GTK - // We MUST be the first to initialize GTK so that GTK doesn't get badly - // initialized with a non-C locale and cause lots of serious random - // weirdness. - ll_try_gtk_init(); -#endif // LL_GTK - // Assume 4:3 aspect ratio until we know better mOriginalAspectRatio = 1024.0 / 768.0; @@ -244,9 +455,9 @@ LLWindowSDL::LLWindowSDL(LLWindowCallbacks* callbacks, #if LL_X11 mFlashing = false; + initialiseX11Clipboard(); #endif // LL_X11 - mKeyScanCode = 0; mKeyVirtualKey = 0; mKeyModifiers = KMOD_NONE; } @@ -258,10 +469,10 @@ static SDL_Surface *Load_BMP_Resource(const char *basename) // Figure out where our BMP is living on the disk snprintf(path_buffer, PATH_BUFFER_SIZE-1, "%s%sres-sdl%s%s", - gDirUtilp->getAppRODataDir().c_str(), - gDirUtilp->getDirDelimiter().c_str(), - gDirUtilp->getDirDelimiter().c_str(), - basename); + gDirUtilp->getAppRODataDir().c_str(), + gDirUtilp->getDirDelimiter().c_str(), + gDirUtilp->getDirDelimiter().c_str(), + basename); path_buffer[PATH_BUFFER_SIZE-1] = '\0'; return SDL_LoadBMP(path_buffer); @@ -348,7 +559,7 @@ static int x11_detect_VRAM_kb() if (fp) { LL_INFOS() << "Looking in " << fname - << " for VRAM info..." << LL_ENDL; + << " for VRAM info..." << LL_ENDL; rtn = x11_detect_VRAM_kb_fp(fp, ": VideoRAM: "); fclose(fp); if (0 == rtn) @@ -373,7 +584,7 @@ static int x11_detect_VRAM_kb() else { LL_INFOS() << "Could not open " << fname - << " - skipped." << LL_ENDL; + << " - skipped." << LL_ENDL; // Try old XFree86 log otherwise fname = x_log_location; fname += "XFree86."; @@ -383,7 +594,7 @@ static int x11_detect_VRAM_kb() if (fp) { LL_INFOS() << "Looking in " << fname - << " for VRAM info..." << LL_ENDL; + << " for VRAM info..." << LL_ENDL; rtn = x11_detect_VRAM_kb_fp(fp, ": VideoRAM: "); fclose(fp); if (0 == rtn) @@ -399,95 +610,170 @@ static int x11_detect_VRAM_kb() else { LL_INFOS() << "Could not open " << fname - << " - skipped." << LL_ENDL; + << " - skipped." << LL_ENDL; } } return rtn; } #endif // LL_X11 +void LLWindowSDL::setTitle(const std::string title) +{ + SDL_SetWindowTitle( mWindow, title.c_str() ); +} + +void LLWindowSDL::tryFindFullscreenSize( int &width, int &height ) +{ + LL_INFOS() << "createContext: setting up fullscreen " << width << "x" << height << LL_ENDL; + + // If the requested width or height is 0, find the best default for the monitor. + if((width == 0) || (height == 0)) + { + // Scan through the list of modes, looking for one which has: + // height between 700 and 800 + // aspect ratio closest to the user's original mode + S32 resolutionCount = 0; + LLWindowResolution *resolutionList = getSupportedResolutions(resolutionCount); + + if(resolutionList != NULL) + { + F32 closestAspect = 0; + U32 closestHeight = 0; + U32 closestWidth = 0; + int i; + + LL_INFOS() << "createContext: searching for a display mode, original aspect is " << mOriginalAspectRatio << LL_ENDL; + + for(i=0; i < resolutionCount; i++) + { + F32 aspect = (F32)resolutionList[i].mWidth / (F32)resolutionList[i].mHeight; + + LL_INFOS() << "createContext: width " << resolutionList[i].mWidth << " height " << resolutionList[i].mHeight << " aspect " << aspect << LL_ENDL; + + if( (resolutionList[i].mHeight >= 700) && (resolutionList[i].mHeight <= 800) && + (fabs(aspect - mOriginalAspectRatio) < fabs(closestAspect - mOriginalAspectRatio))) + { + LL_INFOS() << " (new closest mode) " << LL_ENDL; + + // This is the closest mode we've seen yet. + closestWidth = resolutionList[i].mWidth; + closestHeight = resolutionList[i].mHeight; + closestAspect = aspect; + } + } + + width = closestWidth; + height = closestHeight; + } + } + + if((width == 0) || (height == 0)) + { + // Mode search failed for some reason. Use the old-school default. + width = 1024; + height = 768; + } +} + bool LLWindowSDL::createContext(int x, int y, int width, int height, int bits, bool fullscreen, bool disable_vsync) { //bool glneedsinit = false; LL_INFOS() << "createContext, fullscreen=" << fullscreen << - " size=" << width << "x" << height << LL_ENDL; + " size=" << width << "x" << height << LL_ENDL; // captures don't survive contexts mGrabbyKeyFlags = 0; mReallyCapturedCount = 0; - if (SDL_Init(SDL_INIT_VIDEO) < 0) + std::initializer_list<std::tuple< char const*, char const * > > hintList = + { + {SDL_HINT_VIDEO_X11_NET_WM_BYPASS_COMPOSITOR,"0"}, + {SDL_HINT_MOUSE_FOCUS_CLICKTHROUGH,"1"}, + {SDL_HINT_IME_INTERNAL_EDITING,"1"} + }; + + for( auto hint: hintList ) { - LL_INFOS() << "sdl_init() failed! " << SDL_GetError() << LL_ENDL; - setupFailure("sdl_init() failure, window creation error", "error", OSMB_OK); - return false; + SDL_SetHint( std::get<0>(hint), std::get<1>(hint)); + } + + std::initializer_list<std::tuple<uint32_t, char const*, bool>> initList= + { {SDL_INIT_VIDEO,"SDL_INIT_VIDEO", true}, + {SDL_INIT_AUDIO,"SDL_INIT_AUDIO", false}, + {SDL_INIT_GAMECONTROLLER,"SDL_INIT_GAMECONTROLLER", false}, + {SDL_INIT_SENSOR,"SDL_INIT_SENSOR", false} + }; + + for( auto subSystem : initList) + { + if( SDL_InitSubSystem( std::get<0>(subSystem) ) < 0 ) + { + LL_WARNS() << "SDL_InitSubSystem for " << std::get<1>(subSystem) << " failed " << SDL_GetError() << LL_ENDL; + + if( std::get<2>(subSystem)) + setupFailure("SDL_Init() failure", "error", OSMB_OK); + + } } SDL_version c_sdl_version; SDL_VERSION(&c_sdl_version); LL_INFOS() << "Compiled against SDL " - << int(c_sdl_version.major) << "." - << int(c_sdl_version.minor) << "." - << int(c_sdl_version.patch) << LL_ENDL; - const SDL_version *r_sdl_version; - r_sdl_version = SDL_Linked_Version(); + << int(c_sdl_version.major) << "." + << int(c_sdl_version.minor) << "." + << int(c_sdl_version.patch) << LL_ENDL; + SDL_version r_sdl_version; + SDL_GetVersion(&r_sdl_version); LL_INFOS() << " Running against SDL " - << int(r_sdl_version->major) << "." - << int(r_sdl_version->minor) << "." - << int(r_sdl_version->patch) << LL_ENDL; + << int(r_sdl_version.major) << "." + << int(r_sdl_version.minor) << "." + << int(r_sdl_version.patch) << LL_ENDL; - const SDL_VideoInfo *video_info = SDL_GetVideoInfo( ); - if (!video_info) - { - LL_INFOS() << "SDL_GetVideoInfo() failed! " << SDL_GetError() << LL_ENDL; - setupFailure("SDL_GetVideoInfo() failed, Window creation error", "Error", OSMB_OK); - return false; - } + if (width == 0) + width = 1024; + if (height == 0) + width = 768; - if (video_info->current_h > 0) - { - mOriginalAspectRatio = (float)video_info->current_w / (float)video_info->current_h; - LL_INFOS() << "Original aspect ratio was " << video_info->current_w << ":" << video_info->current_h << "=" << mOriginalAspectRatio << LL_ENDL; - } + mFullscreen = fullscreen; - SDL_EnableUNICODE(1); - SDL_WM_SetCaption(mWindowTitle.c_str(), mWindowTitle.c_str()); + int sdlflags = SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE; - // Set the application icon. - SDL_Surface *bmpsurface; - bmpsurface = Load_BMP_Resource("ll_icon.BMP"); - if (bmpsurface) + if( mFullscreen ) { - // This attempts to give a black-keyed mask to the icon. - SDL_SetColorKey(bmpsurface, - SDL_SRCCOLORKEY, - SDL_MapRGB(bmpsurface->format, 0,0,0) ); - SDL_WM_SetIcon(bmpsurface, NULL); - // The SDL examples cheerfully avoid freeing the icon - // surface, but I'm betting that's leaky. - SDL_FreeSurface(bmpsurface); - bmpsurface = NULL; + sdlflags |= SDL_WINDOW_FULLSCREEN; + tryFindFullscreenSize( width, height ); } - // note: these SetAttributes make Tom's 9600-on-AMD64 fail to - // get a visual, but it's broken anyway when it does, and without - // these SetAttributes we might easily get an avoidable substandard - // visual to work with on most other machines. - SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8); - SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE,8); - SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8); - SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, (bits <= 16) ? 16 : 24); - // We need stencil support for a few (minor) things. - if (!getenv("LL_GL_NO_STENCIL")) - SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8); - SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, (bits <= 16) ? 1 : 8); + if(hasHIDPI) sdlflags = sdlflags | SDL_WINDOW_ALLOW_HIGHDPI; - // *FIX: try to toggle vsync here? + mSDLFlags = sdlflags; - mFullscreen = fullscreen; + GLint redBits{8}, greenBits{8}, blueBits{8}, alphaBits{8}; + + GLint depthBits{(bits <= 16) ? 16 : 24}, stencilBits{8}; + + if (getenv("LL_GL_NO_STENCIL")) + stencilBits = 0; - int sdlflags = SDL_OPENGL | SDL_RESIZABLE | SDL_ANYFORMAT; + SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, alphaBits); + SDL_GL_SetAttribute(SDL_GL_RED_SIZE, redBits); + SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, greenBits); + SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, blueBits); + SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, depthBits ); + + // We need stencil support for a few (minor) things. + if (stencilBits) + SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, stencilBits); + // *FIX: try to toggle vsync here? + + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 4); +#if LL_DARWIN + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 1); +#else + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 6); +#endif + SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE); SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); @@ -497,80 +783,41 @@ bool LLWindowSDL::createContext(int x, int y, int width, int height, int bits, b SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, mFSAASamples); } - mSDLFlags = sdlflags; + SDL_GL_SetAttribute(SDL_GL_SHARE_WITH_CURRENT_CONTEXT, 1); + mWindow = SDL_CreateWindow( mWindowTitle.c_str(), SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, width, height, mSDLFlags ); - if (mFullscreen) + if( mWindow ) { - LL_INFOS() << "createContext: setting up fullscreen " << width << "x" << height << LL_ENDL; + mContext = SDL_GL_CreateContext( mWindow ); - // If the requested width or height is 0, find the best default for the monitor. - if((width == 0) || (height == 0)) + if( mContext == 0 ) { - // Scan through the list of modes, looking for one which has: - // height between 700 and 800 - // aspect ratio closest to the user's original mode - S32 resolutionCount = 0; - LLWindowResolution *resolutionList = getSupportedResolutions(resolutionCount); - - if(resolutionList != NULL) - { - F32 closestAspect = 0; - U32 closestHeight = 0; - U32 closestWidth = 0; - int i; - - LL_INFOS() << "createContext: searching for a display mode, original aspect is " << mOriginalAspectRatio << LL_ENDL; - - for(i=0; i < resolutionCount; i++) - { - F32 aspect = (F32)resolutionList[i].mWidth / (F32)resolutionList[i].mHeight; - - LL_INFOS() << "createContext: width " << resolutionList[i].mWidth << " height " << resolutionList[i].mHeight << " aspect " << aspect << LL_ENDL; - - if( (resolutionList[i].mHeight >= 700) && (resolutionList[i].mHeight <= 800) && - (fabs(aspect - mOriginalAspectRatio) < fabs(closestAspect - mOriginalAspectRatio))) - { - LL_INFOS() << " (new closest mode) " << LL_ENDL; - - // This is the closest mode we've seen yet. - closestWidth = resolutionList[i].mWidth; - closestHeight = resolutionList[i].mHeight; - closestAspect = aspect; - } - } - - width = closestWidth; - height = closestHeight; - } + LL_WARNS() << "Cannot create GL context " << SDL_GetError() << LL_ENDL; + setupFailure("GL Context creation error creation error", "Error", OSMB_OK); + return false; } + // SDL_GL_SetSwapInterval(1); + } - if((width == 0) || (height == 0)) - { - // Mode search failed for some reason. Use the old-school default. - width = 1024; - height = 768; - } - - mWindow = SDL_SetVideoMode(width, height, bits, sdlflags | SDL_FULLSCREEN); - if (!mWindow && bits > 16) - { - SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 16); - mWindow = SDL_SetVideoMode(width, height, bits, sdlflags | SDL_FULLSCREEN); - } + if( mFullscreen ) + { if (mWindow) { mFullscreen = true; - mFullscreenWidth = mWindow->w; - mFullscreenHeight = mWindow->h; - mFullscreenBits = mWindow->format->BitsPerPixel; + /* + mFullscreenWidth = mSurface->w; + mFullscreenHeight = mSurface->h; + mFullscreenBits = mSurface->format->BitsPerPixel; + */ + SDL_GetWindowSize(mWindow, &mFullscreenWidth, &mFullscreenHeight); mFullscreenRefresh = -1; LL_INFOS() << "Running at " << mFullscreenWidth - << "x" << mFullscreenHeight - << "x" << mFullscreenBits - << " @ " << mFullscreenRefresh - << LL_ENDL; + << "x" << mFullscreenHeight + << "x" << mFullscreenBits + << " @ " << mFullscreenRefresh + << LL_ENDL; } else { @@ -584,33 +831,27 @@ bool LLWindowSDL::createContext(int x, int y, int width, int height, int bits, b std::string error = llformat("Unable to run fullscreen at %d x %d.\nRunning in window.", width, height); OSMessageBox(error, "Error", OSMB_OK); + return false; } } - - if(!mFullscreen && (mWindow == NULL)) + else { - if (width == 0) - width = 1024; - if (height == 0) - width = 768; - - LL_INFOS() << "createContext: creating window " << width << "x" << height << "x" << bits << LL_ENDL; - mWindow = SDL_SetVideoMode(width, height, bits, sdlflags); - if (!mWindow && bits > 16) - { - SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 16); - mWindow = SDL_SetVideoMode(width, height, bits, sdlflags); - } - if (!mWindow) { LL_WARNS() << "createContext: window creation failure. SDL: " << SDL_GetError() << LL_ENDL; setupFailure("Window creation error", "Error", OSMB_OK); return false; } - } else if (!mFullscreen && (mWindow != NULL)) + } + + // Set the application icon. + SDL_Surface *bmpsurface; + bmpsurface = Load_BMP_Resource("ll_icon.BMP"); + if (bmpsurface) { - LL_INFOS() << "createContext: SKIPPING - !fullscreen, but +mWindow " << width << "x" << height << "x" << bits << LL_ENDL; + SDL_SetWindowIcon(mWindow, bmpsurface); + SDL_FreeSurface(bmpsurface); + bmpsurface = NULL; } // Detect video memory size. @@ -620,39 +861,67 @@ bool LLWindowSDL::createContext(int x, int y, int width, int height, int bits, b { LL_INFOS() << "X11 log-parser detected " << gGLManager.mVRAM << "MB VRAM." << LL_ENDL; } else + { + PFNGLXQUERYCURRENTRENDERERINTEGERMESAPROC queryInteger; + queryInteger = (PFNGLXQUERYCURRENTRENDERERINTEGERMESAPROC) + glXGetProcAddressARB((const GLubyte *)"glXQueryCurrentRendererIntegerMESA"); + unsigned int vram_megabytes = 0; + queryInteger(GLX_RENDERER_VIDEO_MEMORY_MESA, &vram_megabytes); + if (!vram_megabytes) { + glGetIntegerv(GL_GPU_MEMORY_INFO_DEDICATED_VIDMEM_NVX, (int *)&vram_megabytes); + vram_megabytes /= 1024; + } + if (!vram_megabytes) { + glGetIntegerv(GL_VBO_FREE_MEMORY_ATI, (int *)&vram_megabytes); + vram_megabytes /= 1024; + } + gGLManager.mVRAM = vram_megabytes; + } +#elif LL_DARWIN + CGLRendererInfoObj info = 0; + GLint vram_megabytes = 0; + int num_renderers = 0; + auto err = CGLQueryRendererInfo(CGDisplayIDToOpenGLDisplayMask(kCGDirectMainDisplay), + &info, &num_renderers); + if (!err) { + CGLDescribeRenderer(info, 0, kCGLRPVideoMemoryMegabytes, &vram_megabytes); + CGLDestroyRendererInfo(info); + } else + vram_megabytes = 256; + gGLManager.mVRAM = vram_megabytes; # endif // LL_X11 +/* { // fallback to letting SDL detect VRAM. // note: I've not seen SDL's detection ever actually find // VRAM != 0, but if SDL *does* detect it then that's a bonus. - gGLManager.mVRAM = video_info->video_mem / 1024; + gGLManager.mVRAM = 0; if (gGLManager.mVRAM != 0) { LL_INFOS() << "SDL detected " << gGLManager.mVRAM << "MB VRAM." << LL_ENDL; } } +*/ // If VRAM is not detected, that is handled later // *TODO: Now would be an appropriate time to check for some // explicitly unsupported cards. //const char* RENDERER = (const char*) glGetString(GL_RENDERER); - GLint depthBits, stencilBits, redBits, greenBits, blueBits, alphaBits; - - glGetIntegerv(GL_RED_BITS, &redBits); - glGetIntegerv(GL_GREEN_BITS, &greenBits); - glGetIntegerv(GL_BLUE_BITS, &blueBits); - glGetIntegerv(GL_ALPHA_BITS, &alphaBits); - glGetIntegerv(GL_DEPTH_BITS, &depthBits); - glGetIntegerv(GL_STENCIL_BITS, &stencilBits); + SDL_GL_GetAttribute(SDL_GL_RED_SIZE, &redBits); + SDL_GL_GetAttribute(SDL_GL_GREEN_SIZE, &greenBits); + SDL_GL_GetAttribute(SDL_GL_BLUE_SIZE, &blueBits); + SDL_GL_GetAttribute(SDL_GL_ALPHA_SIZE, &alphaBits); + SDL_GL_GetAttribute(SDL_GL_DEPTH_SIZE, &depthBits); + SDL_GL_GetAttribute(SDL_GL_STENCIL_SIZE, &stencilBits); LL_INFOS() << "GL buffer:" << LL_ENDL; - LL_INFOS() << " Red Bits " << S32(redBits) << LL_ENDL; - LL_INFOS() << " Green Bits " << S32(greenBits) << LL_ENDL; - LL_INFOS() << " Blue Bits " << S32(blueBits) << LL_ENDL; - LL_INFOS() << " Alpha Bits " << S32(alphaBits) << LL_ENDL; - LL_INFOS() << " Depth Bits " << S32(depthBits) << LL_ENDL; - LL_INFOS() << " Stencil Bits " << S32(stencilBits) << LL_ENDL; + LL_INFOS() << " Red Bits " << S32(redBits) << LL_ENDL; + LL_INFOS() << " Green Bits " << S32(greenBits) << LL_ENDL; + LL_INFOS() << " Blue Bits " << S32(blueBits) << LL_ENDL; + LL_INFOS() << " Alpha Bits " << S32(alphaBits) << LL_ENDL; + LL_INFOS() << " Depth Bits " << S32(depthBits) << LL_ENDL; + LL_INFOS() << " Stencil Bits " << S32(stencilBits) << LL_ENDL; GLint colorBits = redBits + greenBits + blueBits + alphaBits; // fixme: actually, it's REALLY important for picking that we get at @@ -660,70 +929,51 @@ bool LLWindowSDL::createContext(int x, int y, int width, int height, int bits, b // relaxed about if we have to. if (colorBits < 32) { +#if 0 close(); setupFailure( - "Second Life requires True Color (32-bit) to run in a window.\n" - "Please go to Control Panels -> Display -> Settings and\n" - "set the screen to 32-bit color.\n" - "Alternately, if you choose to run fullscreen, Second Life\n" - "will automatically adjust the screen each time it runs.", - "Error", - OSMB_OK); - return false; - } - -#if 0 // *FIX: we're going to brave it for now... - if (alphaBits < 8) - { - close(); - setupFailure( - "Second Life is unable to run because it can't get an 8 bit alpha\n" - "channel. Usually this is due to video card driver issues.\n" - "Please make sure you have the latest video card drivers installed.\n" - "Also be sure your monitor is set to True Color (32-bit) in\n" - "Control Panels -> Display -> Settings.\n" - "If you continue to receive this message, contact customer service.", - "Error", - OSMB_OK); + "Second Life requires True Color (32-bit) to run in a window.\n" + "Please go to Control Panels -> Display -> Settings and\n" + "set the screen to 32-bit color.\n" + "Alternately, if you choose to run fullscreen, Second Life\n" + "will automatically adjust the screen each time it runs.", + "Error", + OSMB_OK); return false; - } #endif + } #if LL_X11 /* Grab the window manager specific information */ SDL_SysWMinfo info; SDL_VERSION(&info.version); - if ( SDL_GetWMInfo(&info) ) + if ( SDL_GetWindowWMInfo(mWindow, &info) ) { /* Save the information for later use */ if ( info.subsystem == SDL_SYSWM_X11 ) { mSDL_Display = info.info.x11.display; - mSDL_XWindowID = info.info.x11.wmwindow; - Lock_Display = info.info.x11.lock_func; - Unlock_Display = info.info.x11.unlock_func; + mSDL_XWindowID = info.info.x11.window; } else { LL_WARNS() << "We're not running under X11? Wild." - << LL_ENDL; + << LL_ENDL; } } else { LL_WARNS() << "We're not running under any known WM. Wild." - << LL_ENDL; + << LL_ENDL; } #endif // LL_X11 + SDL_StartTextInput(); //make sure multisampling is disabled by default +#if GL_VERSION_1_3 glDisable(GL_MULTISAMPLE_ARB); - - // We need to do this here, once video is init'd - if (-1 == SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, - SDL_DEFAULT_REPEAT_INTERVAL)) - LL_WARNS() << "Couldn't enable key-repeat: " << SDL_GetError() <<LL_ENDL; +#endif // Don't need to get the current gamma, since there's a call that restores it to the system defaults. return true; @@ -761,6 +1011,7 @@ void LLWindowSDL::destroyContext() { LL_INFOS() << "destroyContext begins" << LL_ENDL; + SDL_StopTextInput(); #if LL_X11 mSDL_Display = NULL; mSDL_XWindowID = None; @@ -794,23 +1045,39 @@ LLWindowSDL::~LLWindowSDL() void LLWindowSDL::show() { // *FIX: What to do with SDL? + if (mWindow) + { + SDL_ShowWindow(mWindow); + } } void LLWindowSDL::hide() { // *FIX: What to do with SDL? + if (mWindow) + { + SDL_HideWindow(mWindow); + } } //virtual void LLWindowSDL::minimize() { // *FIX: What to do with SDL? + if (mWindow) + { + SDL_MinimizeWindow(mWindow); + } } //virtual void LLWindowSDL::restore() { // *FIX: What to do with SDL? + if (mWindow) + { + SDL_RestoreWindow(mWindow); + } } @@ -844,7 +1111,7 @@ bool LLWindowSDL::getVisible() // Then what is? if (mWindow) { - result = true; + if( SDL_GetWindowFlags(mWindow) & SDL_WINDOW_SHOWN ) result = true; } return(result); @@ -854,10 +1121,12 @@ bool LLWindowSDL::getMinimized() { bool result = false; - if (mWindow && (1 == mIsMinimized)) + if (mWindow/*&& (1 == mIsMinimized)*/) { - result = true; + if( SDL_GetWindowFlags(mWindow) & SDL_WINDOW_MINIMIZED ) result = true; } + + mIsMinimized = result; return(result); } @@ -868,6 +1137,8 @@ bool LLWindowSDL::getMaximized() if (mWindow) { // TODO + if( SDL_GetWindowFlags(mWindow) & SDL_WINDOW_MAXIMIZED ) result = true; + else result = false; } return(result); @@ -876,7 +1147,15 @@ bool LLWindowSDL::getMaximized() bool LLWindowSDL::maximize() { // TODO - return false; + bool result = false; + + if (mWindow) + { + SDL_MaximizeWindow(mWindow); + result = true; + } + + return result; } bool LLWindowSDL::getFullscreen() @@ -896,9 +1175,13 @@ bool LLWindowSDL::getSize(LLCoordScreen *size) { if (mWindow) { - size->mX = mWindow->w; - size->mY = mWindow->h; - return (true); + /* + if(hasHIDPI) + SDL_GL_GetDrawableSize(mWindow, &size->mX, &size->mY); + else + */ + SDL_GetWindowSize(mWindow, &size->mX, &size->mY); + return (true); } return (false); @@ -908,9 +1191,11 @@ bool LLWindowSDL::getSize(LLCoordWindow *size) { if (mWindow) { - size->mX = mWindow->w; - size->mY = mWindow->h; - return (true); + if(hasHIDPI) + SDL_GL_GetDrawableSize(mWindow, &size->mX, &size->mY); + else + SDL_GetWindowSize(mWindow, &size->mX, &size->mY); + return (true); } return (false); @@ -918,49 +1203,50 @@ bool LLWindowSDL::getSize(LLCoordWindow *size) bool LLWindowSDL::setPosition(const LLCoordScreen position) { + bool result = false; + if(mWindow) { // *FIX: (?) //MacMoveWindow(mWindow, position.mX, position.mY, false); + SDL_SetWindowPosition(mWindow, position.mX, position.mY); + result = true; } - return true; + return result; } -bool LLWindowSDL::setSizeImpl(const LLCoordScreen size) +template< typename T > bool setSizeImpl( const T& newSize, SDL_Window *pWin ) { - if(mWindow) - { - // Push a resize event onto SDL's queue - we'll handle it - // when it comes out again. - SDL_Event event; - event.type = SDL_VIDEORESIZE; - event.resize.w = size.mX; - event.resize.h = size.mY; - SDL_PushEvent(&event); // copied into queue + if( !pWin ) + return false; - return true; - } + auto nFlags = SDL_GetWindowFlags( pWin ); - return false; + if( nFlags & SDL_WINDOW_MAXIMIZED ) + SDL_RestoreWindow( pWin ); + + + SDL_SetWindowSize( pWin, newSize.mX, newSize.mY ); + SDL_Event event; + event.type = SDL_WINDOWEVENT; + event.window.event = SDL_WINDOWEVENT_RESIZED; + event.window.windowID = SDL_GetWindowID( pWin ); + event.window.data1 = newSize.mX; + event.window.data2 = newSize.mY; + SDL_PushEvent( &event ); + + return true; } -bool LLWindowSDL::setSizeImpl(const LLCoordWindow size) +bool LLWindowSDL::setSizeImpl(const LLCoordScreen size) { - if(mWindow) - { - // Push a resize event onto SDL's queue - we'll handle it - // when it comes out again. - SDL_Event event; - event.type = SDL_VIDEORESIZE; - event.resize.w = size.mX; - event.resize.h = size.mY; - SDL_PushEvent(&event); // copied into queue - - return true; - } + return ::setSizeImpl( size, mWindow ); +} - return false; +bool LLWindowSDL::setSizeImpl(const LLCoordWindow size) +{ + return ::setSizeImpl( size, mWindow ); } @@ -968,7 +1254,7 @@ void LLWindowSDL::swapBuffers() { if (mWindow) { - SDL_GL_SwapBuffers(); + SDL_GL_SwapWindow( mWindow ); } } @@ -990,7 +1276,10 @@ F32 LLWindowSDL::getGamma() bool LLWindowSDL::restoreGamma() { //CGDisplayRestoreColorSyncSettings(); - SDL_SetGamma(1.0f, 1.0f, 1.0f); + // SDL_SetGamma(1.0f, 1.0f, 1.0f); + Uint16 ramp; + SDL_CalculateGammaRamp(1.0f, &ramp); + SDL_SetWindowGammaRamp(mWindow, &ramp, &ramp, &ramp); return true; } @@ -999,7 +1288,10 @@ bool LLWindowSDL::setGamma(const F32 gamma) mGamma = gamma; if (mGamma == 0) mGamma = 0.1f; mGamma = 1/mGamma; - SDL_SetGamma(mGamma, mGamma, mGamma); + // SDL_SetGamma(mGamma, mGamma, mGamma); + Uint16 ramp; + SDL_CalculateGammaRamp(mGamma, &ramp); + SDL_SetWindowGammaRamp(mWindow, &ramp, &ramp, &ramp); return true; } @@ -1048,7 +1340,14 @@ bool LLWindowSDL::setCursorPosition(const LLCoordWindow position) //LL_INFOS() << "setCursorPosition(" << screen_pos.mX << ", " << screen_pos.mY << ")" << LL_ENDL; // do the actual forced cursor move. - SDL_WarpMouse(screen_pos.mX, screen_pos.mY); + + if (mFullscreen) + { + SDL_WarpMouseGlobal(screen_pos.mX, screen_pos.mY); + return result; + } + + SDL_WarpMouseInWindow(mWindow, screen_pos.mX, screen_pos.mY); //LL_INFOS() << llformat("llcw %d,%d -> scr %d,%d", position.mX, position.mY, screen_pos.mX, screen_pos.mY) << LL_ENDL; @@ -1070,21 +1369,14 @@ bool LLWindowSDL::getCursorPosition(LLCoordWindow *position) return convertCoords(screen_pos, position); } +F32 LLWindowSDL::getSystemUISize() +{ + if(hasHIDPI) return 2.0f; + else return 1.f; +} F32 LLWindowSDL::getNativeAspectRatio() { -#if 0 - // RN: this hack presumes that the largest supported resolution is monitor-limited - // and that pixels in that mode are square, therefore defining the native aspect ratio - // of the monitor...this seems to work to a close approximation for most CRTs/LCDs - S32 num_resolutions; - LLWindowResolution* resolutions = getSupportedResolutions(num_resolutions); - - - return ((F32)resolutions[num_resolutions - 1].mWidth / (F32)resolutions[num_resolutions - 1].mHeight); - //rn: AC -#endif - // MBW -- there are a couple of bad assumptions here. One is that the display list won't include // ridiculous resolutions nobody would ever use. The other is that the list is in order. @@ -1146,7 +1438,7 @@ void LLWindowSDL::beforeDialog() // it only works in X11 if (running_x11 && mWindow) { - SDL_WM_ToggleFullScreen(mWindow); + SDL_SetWindowFullscreen( mWindow, 0 ); } } } @@ -1162,12 +1454,6 @@ void LLWindowSDL::beforeDialog() } #endif // LL_X11 -#if LL_GTK - // this is a good time to grab some GTK version information for - // diagnostics, if not already done. - ll_try_gtk_init(); -#endif // LL_GTK - maybe_lock_display(); } @@ -1188,7 +1474,7 @@ void LLWindowSDL::afterDialog() // in X11 if (running_x11 && mWindow) { - SDL_WM_ToggleFullScreen(mWindow); + SDL_SetWindowFullscreen( mWindow, 0 ); } } } @@ -1224,143 +1510,87 @@ void LLWindowSDL::x11_set_urgent(bool urgent) void LLWindowSDL::flashIcon(F32 seconds) { + if (getMinimized()) + { #if !LL_X11 - LL_INFOS() << "Stub LLWindowSDL::flashIcon(" << seconds << ")" << LL_ENDL; + LL_INFOS() << "Stub LLWindowSDL::flashIcon(" << seconds << ")" << LL_ENDL; #else - LL_INFOS() << "X11 LLWindowSDL::flashIcon(" << seconds << ")" << LL_ENDL; + LL_INFOS() << "X11 LLWindowSDL::flashIcon(" << seconds << ")" << LL_ENDL; - F32 remaining_time = mFlashTimer.getRemainingTimeF32(); - if (remaining_time < seconds) - remaining_time = seconds; - mFlashTimer.reset(); - mFlashTimer.setTimerExpirySec(remaining_time); + F32 remaining_time = mFlashTimer.getRemainingTimeF32(); + if (remaining_time < seconds) + remaining_time = seconds; + mFlashTimer.reset(); + mFlashTimer.setTimerExpirySec(remaining_time); - x11_set_urgent(true); - mFlashing = true; + x11_set_urgent(true); + mFlashing = true; #endif // LL_X11 -} - - -#if LL_GTK -bool LLWindowSDL::isClipboardTextAvailable() -{ - if (ll_try_gtk_init()) - { - GtkClipboard * const clipboard = - gtk_clipboard_get(GDK_NONE); - return gtk_clipboard_wait_is_text_available(clipboard) ? - true : false; - } - return false; // failure -} - -bool LLWindowSDL::pasteTextFromClipboard(LLWString &text) -{ - if (ll_try_gtk_init()) - { - GtkClipboard * const clipboard = - gtk_clipboard_get(GDK_NONE); - gchar * const data = gtk_clipboard_wait_for_text(clipboard); - if (data) - { - text = LLWString(utf8str_to_wstring(data)); - g_free(data); - return true; - } - } - return false; // failure -} - -bool LLWindowSDL::copyTextToClipboard(const LLWString &text) -{ - if (ll_try_gtk_init()) - { - const std::string utf8 = wstring_to_utf8str(text); - GtkClipboard * const clipboard = - gtk_clipboard_get(GDK_NONE); - gtk_clipboard_set_text(clipboard, utf8.c_str(), utf8.length()); - return true; } - return false; // failure } - -bool LLWindowSDL::isPrimaryTextAvailable() -{ - if (ll_try_gtk_init()) - { - GtkClipboard * const clipboard = - gtk_clipboard_get(GDK_SELECTION_PRIMARY); - return gtk_clipboard_wait_is_text_available(clipboard) ? - true : false; - } - return false; // failure -} - -bool LLWindowSDL::pasteTextFromPrimary(LLWString &text) +bool LLWindowSDL::isClipboardTextAvailable() { - if (ll_try_gtk_init()) - { - GtkClipboard * const clipboard = - gtk_clipboard_get(GDK_SELECTION_PRIMARY); - gchar * const data = gtk_clipboard_wait_for_text(clipboard); - if (data) - { - text = LLWString(utf8str_to_wstring(data)); - g_free(data); - return true; - } - } - return false; // failure +#if LL_X11 + return mSDL_Display && XGetSelectionOwner(mSDL_Display, XA_CLIPBOARD) != None; +#else + return SDL_HasClipboardText(); +#endif } -bool LLWindowSDL::copyTextToPrimary(const LLWString &text) +bool LLWindowSDL::pasteTextFromClipboard(LLWString &dst) { - if (ll_try_gtk_init()) +#if LL_X11 + return getSelectionText(XA_CLIPBOARD, dst); +#else + auto data = SDL_GetClipboardText(); + if (data) { - const std::string utf8 = wstring_to_utf8str(text); - GtkClipboard * const clipboard = - gtk_clipboard_get(GDK_SELECTION_PRIMARY); - gtk_clipboard_set_text(clipboard, utf8.c_str(), utf8.length()); + dst = LLWString(utf8str_to_wstring(data)); + SDL_free(data); return true; } - return false; // failure -} - -#else - -bool LLWindowSDL::isClipboardTextAvailable() -{ - return false; // unsupported -} - -bool LLWindowSDL::pasteTextFromClipboard(LLWString &dst) -{ - return false; // unsupported + return false; +#endif } bool LLWindowSDL::copyTextToClipboard(const LLWString &s) { - return false; // unsupported +#if LL_X11 + return setSelectionText(XA_CLIPBOARD, s); +#else + return !SDL_SetClipboardText(wstring_to_utf8str(s).c_str()); +#endif } bool LLWindowSDL::isPrimaryTextAvailable() { +#if LL_X11 + LLWString text; + return getSelectionText(XA_PRIMARY, text) && !text.empty(); +#else return false; // unsupported +#endif } bool LLWindowSDL::pasteTextFromPrimary(LLWString &dst) { +#if LL_X11 + return getSelectionText(XA_PRIMARY, dst); +#else return false; // unsupported +#endif } bool LLWindowSDL::copyTextToPrimary(const LLWString &s) { - return false; // unsupported +#if LL_X11 + return setSelectionText(XA_PRIMARY, s); +#else + return false; // unsupported +#endif } -#endif // LL_GTK - LLWindow::LLWindowResolution* LLWindowSDL::getSupportedResolutions(S32 &num_resolutions) { if (!mSupportedResolutions) @@ -1368,33 +1598,30 @@ LLWindow::LLWindowResolution* LLWindowSDL::getSupportedResolutions(S32 &num_reso mSupportedResolutions = new LLWindowResolution[MAX_NUM_RESOLUTIONS]; mNumSupportedResolutions = 0; - SDL_Rect **modes = SDL_ListModes(NULL, SDL_OPENGL | SDL_FULLSCREEN); - if ( (modes != NULL) && (modes != ((SDL_Rect **) -1)) ) + // <FS:ND> Use display no from mWindow/mSurface here? + int max = SDL_GetNumDisplayModes(0); + max = llclamp( max, 0, MAX_NUM_RESOLUTIONS ); + + for( int i =0; i < max; ++i ) { - int count = 0; - while (*modes && count<MAX_NUM_RESOLUTIONS) // they're sorted biggest to smallest, so find end... + SDL_DisplayMode mode = { SDL_PIXELFORMAT_UNKNOWN, 0, 0, 0, 0 }; + if (SDL_GetDisplayMode( 0 , i, &mode) != 0) { - modes++; - count++; + continue; } - while (count--) + int w = mode.w; + int h = mode.h; + if ((w >= 800) && (h >= 600)) { - modes--; - SDL_Rect *r = *modes; - int w = r->w; - int h = r->h; - if ((w >= 800) && (h >= 600)) + // make sure we don't add the same resolution multiple times! + if ( (mNumSupportedResolutions == 0) || + ((mSupportedResolutions[mNumSupportedResolutions-1].mWidth != w) && + (mSupportedResolutions[mNumSupportedResolutions-1].mHeight != h)) ) { - // make sure we don't add the same resolution multiple times! - if ( (mNumSupportedResolutions == 0) || - ((mSupportedResolutions[mNumSupportedResolutions-1].mWidth != w) && - (mSupportedResolutions[mNumSupportedResolutions-1].mHeight != h)) ) - { - mSupportedResolutions[mNumSupportedResolutions].mWidth = w; - mSupportedResolutions[mNumSupportedResolutions].mHeight = h; - mNumSupportedResolutions++; - } + mSupportedResolutions[mNumSupportedResolutions].mWidth = w; + mSupportedResolutions[mNumSupportedResolutions].mHeight = h; + mNumSupportedResolutions++; } } } @@ -1410,7 +1637,9 @@ bool LLWindowSDL::convertCoords(LLCoordGL from, LLCoordWindow *to) return false; to->mX = from.mX; - to->mY = mWindow->h - from.mY - 1; + int h; + SDL_GetWindowSize(mWindow, nullptr, &h); + to->mY = h - from.mY - 1; return true; } @@ -1421,7 +1650,9 @@ bool LLWindowSDL::convertCoords(LLCoordWindow from, LLCoordGL* to) return false; to->mX = from.mX; - to->mY = mWindow->h - from.mY - 1; + int h; + SDL_GetWindowSize(mWindow, nullptr, &h); + to->mY = h - from.mY - 1; return true; } @@ -1482,13 +1713,13 @@ bool LLWindowSDL::SDLReallyCaptureInput(bool capture) else mReallyCapturedCount = 0; - SDL_GrabMode wantmode, newmode; + bool wantGrab; if (mReallyCapturedCount <= 0) // uncapture { - wantmode = SDL_GRAB_OFF; + wantGrab = false; } else // capture { - wantmode = SDL_GRAB_ON; + wantGrab = true; } if (mReallyCapturedCount < 0) // yuck, imbalance. @@ -1497,9 +1728,11 @@ bool LLWindowSDL::SDLReallyCaptureInput(bool capture) LL_WARNS() << "ReallyCapture count was < 0" << LL_ENDL; } + bool newGrab = wantGrab; + +#if LL_X11 if (!mFullscreen) /* only bother if we're windowed anyway */ { -#if LL_X11 if (mSDL_Display) { /* we dirtily mix raw X11 with SDL so that our pointer @@ -1512,49 +1745,37 @@ bool LLWindowSDL::SDLReallyCaptureInput(bool capture) *keyboard* input from the window manager, which was frustrating users. */ int result; - if (wantmode == SDL_GRAB_ON) + if (wantGrab == true) { - //LL_INFOS() << "X11 POINTER GRABBY" << LL_ENDL; - //newmode = SDL_WM_GrabInput(wantmode); maybe_lock_display(); result = XGrabPointer(mSDL_Display, mSDL_XWindowID, - True, 0, GrabModeAsync, - GrabModeAsync, - None, None, CurrentTime); + True, 0, GrabModeAsync, + GrabModeAsync, + None, None, CurrentTime); maybe_unlock_display(); if (GrabSuccess == result) - newmode = SDL_GRAB_ON; + newGrab = true; else - newmode = SDL_GRAB_OFF; - } else if (wantmode == SDL_GRAB_OFF) + newGrab = false; + } + else { - //LL_INFOS() << "X11 POINTER UNGRABBY" << LL_ENDL; - newmode = SDL_GRAB_OFF; - //newmode = SDL_WM_GrabInput(SDL_GRAB_OFF); + newGrab = false; maybe_lock_display(); XUngrabPointer(mSDL_Display, CurrentTime); // Make sure the ungrab happens RIGHT NOW. XSync(mSDL_Display, False); maybe_unlock_display(); - } else - { - newmode = SDL_GRAB_QUERY; // neutral } - } else // not actually running on X11, for some reason - newmode = wantmode; -#endif // LL_X11 - } else { - // pretend we got what we wanted, when really we don't care. - newmode = wantmode; + } } - +#endif // LL_X11 // return boolean success for whether we ended up in the desired state - return (capture && SDL_GRAB_ON==newmode) || - (!capture && SDL_GRAB_OFF==newmode); + return capture == newGrab; } -U32 LLWindowSDL::SDLCheckGrabbyKeys(SDLKey keysym, bool gain) +U32 LLWindowSDL::SDLCheckGrabbyKeys(U32 keysym, bool gain) { /* part of the fix for SL-13243: Some popular window managers like to totally eat alt-drag for the purposes of moving windows. We @@ -1572,16 +1793,16 @@ U32 LLWindowSDL::SDLCheckGrabbyKeys(SDLKey keysym, bool gain) U32 mask = 0; switch (keysym) { - case SDLK_LALT: - mask = 1U << 0; break; - case SDLK_RALT: - mask = 1U << 1; break; - case SDLK_LCTRL: - mask = 1U << 2; break; - case SDLK_RCTRL: - mask = 1U << 3; break; - default: - break; + case SDLK_LALT: + mask = 1U << 0; break; + case SDLK_RALT: + mask = 1U << 1; break; + case SDLK_LCTRL: + mask = 1U << 2; break; + case SDLK_RCTRL: + mask = 1U << 3; break; + default: + break; } if (gain) @@ -1679,7 +1900,7 @@ void check_vm_bloat() last_rss_size = this_rss_size; last_vm_size = this_vm_size; -finally: + finally: if (NULL != ptr) { free(ptr); @@ -1694,33 +1915,17 @@ finally: // virtual void LLWindowSDL::processMiscNativeEvents() { -#if LL_GTK - // Pump GTK events to avoid starvation for: - // * DBUS servicing - // * Anything else which quietly hooks into the default glib/GTK loop - if (ll_try_gtk_init()) - { - // Yuck, Mozilla's GTK callbacks play with the locale - push/pop - // the locale to protect it, as exotic/non-C locales - // causes our code lots of general critical weirdness - // and crashness. (SL-35450) - static std::string saved_locale; - saved_locale = ll_safe_string(setlocale(LC_ALL, NULL)); - - // Pump until we've nothing left to do or passed 1/15th of a - // second pumping for this frame. - static LLTimer pump_timer; - pump_timer.reset(); - pump_timer.setTimerExpirySec(1.0f / 15.0f); - do { - // Always do at least one non-blocking pump - gtk_main_iteration_do(false); - } while (gtk_events_pending() && - !pump_timer.hasExpired()); - - setlocale(LC_ALL, saved_locale.c_str() ); - } -#endif // LL_GTK +#if LL_GLIB + // Pump until we've nothing left to do or passed 1/15th of a + // second pumping for this frame. + static LLTimer pump_timer; + pump_timer.reset(); + pump_timer.setTimerExpirySec(1.0f / 15.0f); + do + { + g_main_context_iteration(g_main_context_default(), false); + } while( g_main_context_pending(g_main_context_default()) && !pump_timer.hasExpired()); +#endif // hack - doesn't belong here - but this is just for debugging if (getenv("LL_DEBUG_BLOAT")) @@ -1743,43 +1948,89 @@ void LLWindowSDL::gatherInput() { switch (event.type) { + case SDL_MOUSEWHEEL: + if( event.wheel.y != 0 ) + mCallbacks->handleScrollWheel(this, -event.wheel.y); + break; + case SDL_MOUSEMOTION: { LLCoordWindow winCoord(event.button.x, event.button.y); LLCoordGL openGlCoord; convertCoords(winCoord, &openGlCoord); + + openGlCoord.mX = openGlCoord.mX * getSystemUISize(); + openGlCoord.mY = openGlCoord.mY * getSystemUISize(); + + //LL_INFOS() << "SDL_MOUSEMOTION " << event.button.x << " " << event.button.y << " gl " << openGlCoord.mX << " " << openGlCoord.mY << LL_ENDL; + MASK mask = gKeyboard->currentMask(true); mCallbacks->handleMouseMove(this, openGlCoord, mask); break; } + case SDL_TEXTINPUT: + { + auto string = utf8str_to_utf16str( event.text.text ); + mKeyModifiers = gKeyboard->currentMask( false ); + mInputType = "textinput"; + for( auto key: string ) + { + mKeyVirtualKey = key; + + if( (MASK_CONTROL|MASK_ALT)&mKeyModifiers ) + gKeyboard->handleKeyDown(mKeyVirtualKey, mKeyModifiers ); + else + handleUnicodeUTF16( key, mKeyModifiers ); + } + break; + } + case SDL_KEYDOWN: - mKeyScanCode = event.key.keysym.scancode; - mKeyVirtualKey = event.key.keysym.unicode; - mKeyModifiers = event.key.keysym.mod; + mKeyVirtualKey = event.key.keysym.sym; + mKeyModifiers = event.key.keysym.mod; + mInputType = "keydown"; - gKeyboard->handleKeyDown(event.key.keysym.sym, event.key.keysym.mod); - // part of the fix for SL-13243 - if (SDLCheckGrabbyKeys(event.key.keysym.sym, true) != 0) - SDLReallyCaptureInput(true); + // treat all possible Enter/Return keys the same + if (mKeyVirtualKey == SDLK_RETURN2 || mKeyVirtualKey == SDLK_KP_ENTER) + { + mKeyVirtualKey = SDLK_RETURN; + } + + gKeyboard->handleKeyDown(mKeyVirtualKey, mKeyModifiers ); + + // <FS:ND> Slightly hacky :| To make the viewer honor enter (eg to accept form input) we've to not only send handleKeyDown but also send a + // invoke handleUnicodeUTF16 in case the user hits return. + // Note that we cannot blindly use handleUnicodeUTF16 for each SDL_KEYDOWN. Doing so will create bogus keyboard input (like % for cursor left). + if( mKeyVirtualKey == SDLK_RETURN ) + { + // fix return key not working when capslock, scrolllock or numlock are enabled + mKeyModifiers &= (~(KMOD_NUM | KMOD_CAPS | KMOD_MODE | KMOD_SCROLL)); + handleUnicodeUTF16( mKeyVirtualKey, mKeyModifiers ); + } + + // part of the fix for SL-13243 + if (SDLCheckGrabbyKeys(event.key.keysym.sym, true) != 0) + SDLReallyCaptureInput(true); - if (event.key.keysym.unicode) - { - handleUnicodeUTF16(event.key.keysym.unicode, - gKeyboard->currentMask(false)); - } break; case SDL_KEYUP: - mKeyScanCode = event.key.keysym.scancode; - mKeyVirtualKey = event.key.keysym.unicode; - mKeyModifiers = event.key.keysym.mod; + mKeyVirtualKey = event.key.keysym.sym; + mKeyModifiers = event.key.keysym.mod; + mInputType = "keyup"; - if (SDLCheckGrabbyKeys(event.key.keysym.sym, false) == 0) - SDLReallyCaptureInput(false); // part of the fix for SL-13243 + // treat all possible Enter/Return keys the same + if (mKeyVirtualKey == SDLK_RETURN2 || mKeyVirtualKey == SDLK_KP_ENTER) + { + mKeyVirtualKey = SDLK_RETURN; + } - gKeyboard->handleKeyUp(event.key.keysym.sym, event.key.keysym.mod); - break; + if (SDLCheckGrabbyKeys(mKeyVirtualKey, false) == 0) + SDLReallyCaptureInput(false); // part of the fix for SL-13243 + + gKeyboard->handleKeyUp(mKeyVirtualKey,mKeyModifiers); + break; case SDL_MOUSEBUTTONDOWN: { @@ -1787,7 +2038,11 @@ void LLWindowSDL::gatherInput() LLCoordWindow winCoord(event.button.x, event.button.y); LLCoordGL openGlCoord; convertCoords(winCoord, &openGlCoord); - MASK mask = gKeyboard->currentMask(true); + + openGlCoord.mX *= getSystemUISize(); + openGlCoord.mY *= getSystemUISize(); + + MASK mask = gKeyboard->currentMask(true); if (event.button.button == SDL_BUTTON_LEFT) // SDL doesn't manage double clicking... { @@ -1799,7 +2054,7 @@ void LLWindowSDL::gatherInput() if (++leftClick >= 2) { leftClick = 0; - isDoubleClick = true; + isDoubleClick = true; } } lastLeftDown = now; @@ -1830,7 +2085,7 @@ void LLWindowSDL::gatherInput() else if (event.button.button == SDL_BUTTON_RIGHT) // right { - mCallbacks->handleRightMouseDown(this, openGlCoord, mask); + mCallbacks->handleRightMouseDown(this, openGlCoord, mask); } else if (event.button.button == SDL_BUTTON_MIDDLE) // middle @@ -1850,86 +2105,108 @@ void LLWindowSDL::gatherInput() LLCoordWindow winCoord(event.button.x, event.button.y); LLCoordGL openGlCoord; convertCoords(winCoord, &openGlCoord); - MASK mask = gKeyboard->currentMask(true); + + openGlCoord.mX *= getSystemUISize(); + openGlCoord.mY *= getSystemUISize(); + + MASK mask = gKeyboard->currentMask(true); if (event.button.button == SDL_BUTTON_LEFT) // left - mCallbacks->handleMouseUp(this, openGlCoord, mask); + mCallbacks->handleMouseUp(this, openGlCoord, mask); else if (event.button.button == SDL_BUTTON_RIGHT) // right - mCallbacks->handleRightMouseUp(this, openGlCoord, mask); + mCallbacks->handleRightMouseUp(this, openGlCoord, mask); else if (event.button.button == SDL_BUTTON_MIDDLE) // middle - mCallbacks->handleMiddleMouseUp(this, openGlCoord, mask); + mCallbacks->handleMiddleMouseUp(this, openGlCoord, mask); // don't handle mousewheel here... break; } - case SDL_VIDEOEXPOSE: // VIDEOEXPOSE doesn't specify the damage, but hey, it's OpenGL...repaint the whole thing! - mCallbacks->handlePaint(this, 0, 0, mWindow->w, mWindow->h); - break; - - case SDL_VIDEORESIZE: // *FIX: handle this? + case SDL_WINDOWEVENT: // *FIX: handle this? { - LL_INFOS() << "Handling a resize event: " << event.resize.w << - "x" << event.resize.h << LL_ENDL; + if( event.window.event == SDL_WINDOWEVENT_RESIZED + /* || event.window.event == SDL_WINDOWEVENT_SIZE_CHANGED*/ ) // <FS:ND> SDL_WINDOWEVENT_SIZE_CHANGED is followed by SDL_WINDOWEVENT_RESIZED, so handling one shall be enough + { + LL_INFOS() << "Handling a resize event: " << event.window.data1 << "x" << event.window.data2 << LL_ENDL; - S32 width = llmax(event.resize.w, (S32)mMinWindowWidth); - S32 height = llmax(event.resize.h, (S32)mMinWindowHeight); + S32 width = llmax(event.window.data1, (S32)mMinWindowWidth); + S32 height = llmax(event.window.data2, (S32)mMinWindowHeight); - // *FIX: I'm not sure this is necessary! - mWindow = SDL_SetVideoMode(width, height, 32, mSDLFlags); - if (!mWindow) - { - // *FIX: More informative dialog? - LL_INFOS() << "Could not recreate context after resize! Quitting..." << LL_ENDL; - if(mCallbacks->handleCloseRequest(this)) + // *FIX: I'm not sure this is necessary! + // <FS:ND> I think is is not + // SDL_SetWindowSize(mWindow, width, height); + // + + mCallbacks->handleResize(this, width * getSystemUISize(), height * getSystemUISize()); + } + else if(event.window.event == SDL_WINDOWEVENT_ENTER) { - // Get the app to initiate cleanup. - mCallbacks->handleQuit(this); - // The app is responsible for calling destroyWindow when done with GL + LL_INFOS() << "SDL_WINDOWEVENT_ENTER" << LL_ENDL; + if(!mHaveInputFocus) mCallbacks->handleFocus(this); + mHaveInputFocus = true; } - break; - } - - mCallbacks->handleResize(this, width, height); - break; - } - case SDL_ACTIVEEVENT: - if (event.active.state & SDL_APPINPUTFOCUS) + else if(event.window.event == SDL_WINDOWEVENT_LEAVE) { - // Note that for SDL (particularly on X11), keyboard - // and mouse focus are independent things. Here we are - // tracking keyboard focus state changes. - - // We have to do our own state massaging because SDL - // can send us two unfocus events in a row for example, - // which confuses the focus code [SL-24071]. - if (event.active.gain != mHaveInputFocus) - { - mHaveInputFocus = !!event.active.gain; + LL_INFOS() << "SDL_WINDOWEVENT_LEAVE" << LL_ENDL; + if(mHaveInputFocus) mCallbacks->handleFocusLost(this); + mHaveInputFocus = false; + } + else if( event.window.event == SDL_WINDOWEVENT_FOCUS_GAINED ) // <FS:ND> What about SDL_WINDOWEVENT_ENTER (mouse focus) + { + // We have to do our own state massaging because SDL + // can send us two unfocus events in a row for example, + // which confuses the focus code [SL-24071]. + mHaveInputFocus = true; - if (mHaveInputFocus) mCallbacks->handleFocus(this); - else + } + else if( event.window.event == SDL_WINDOWEVENT_FOCUS_LOST ) // <FS:ND> What about SDL_WINDOWEVENT_LEAVE (mouse focus) + { + // We have to do our own state massaging because SDL + // can send us two unfocus events in a row for example, + // which confuses the focus code [SL-24071]. + mHaveInputFocus = false; + mCallbacks->handleFocusLost(this); - } } - if (event.active.state & SDL_APPACTIVE) + /* + + Bug : the app remains inactive when maximized .. + + else if(event.window.event == SDL_WINDOWEVENT_MINIMIZED) { - // Change in iconification/minimization state. - if ((!event.active.gain) != mIsMinimized) - { - mIsMinimized = (!event.active.gain); + LL_INFOS() << "SDL_WINDOWEVENT_MINIMIZED" << LL_ENDL; + if(!mIsMinimized) mCallbacks->handleActivate(this,false); + mIsMinimized = true; + } + else if(event.window.event == SDL_WINDOWEVENT_MAXIMIZED) + { + LL_INFOS() << "SDL_WINDOWEVENT_MAXIMIZED" << LL_ENDL; + if(mIsMinimized) mCallbacks->handleActivate(this,true); + mIsMinimized = false; + } + */ + else if (event.window.event == SDL_WINDOWEVENT_EXPOSED) + { + int w, h; + SDL_GL_GetDrawableSize(mWindow, &w, &h); - mCallbacks->handleActivate(this, !mIsMinimized); - LL_INFOS() << "SDL deiconification state switched to " << bool(event.active.gain) << LL_ENDL; - } - else - { - LL_INFOS() << "Ignored bogus redundant SDL deiconification state switch to " << bool(event.active.gain) << LL_ENDL; - } + mCallbacks->handlePaint(this, 0, 0, w, h); } - break; + else if( event.window.event == SDL_WINDOWEVENT_MINIMIZED || + event.window.event == SDL_WINDOWEVENT_MAXIMIZED || + event.window.event == SDL_WINDOWEVENT_RESTORED || + event.window.event == SDL_WINDOWEVENT_EXPOSED || + event.window.event == SDL_WINDOWEVENT_SHOWN ) + { + mIsMinimized = (event.window.event == SDL_WINDOWEVENT_MINIMIZED); + mCallbacks->handleActivate(this, !mIsMinimized); + LL_INFOS() << "SDL deiconification state switched to " << mIsMinimized << LL_ENDL; + } + + break; + } case SDL_QUIT: if(mCallbacks->handleCloseRequest(this)) { @@ -1938,9 +2215,9 @@ void LLWindowSDL::gatherInput() // The app is responsible for calling destroyWindow when done with GL } break; - default: - //LL_INFOS() << "Unhandled SDL event type " << event.type << LL_ENDL; - break; + default: + //LL_INFOS() << "Unhandled SDL event type " << event.type << LL_ENDL; + break; } } @@ -1968,21 +2245,21 @@ static SDL_Cursor *makeSDLCursorFromBMP(const char *filename, int hotx, int hoty { SDL_Surface *cursurface; LL_DEBUGS() << "Loaded cursor file " << filename << " " - << bmpsurface->w << "x" << bmpsurface->h << LL_ENDL; + << bmpsurface->w << "x" << bmpsurface->h << LL_ENDL; cursurface = SDL_CreateRGBSurface (SDL_SWSURFACE, - bmpsurface->w, - bmpsurface->h, - 32, - SDL_SwapLE32(0xFFU), - SDL_SwapLE32(0xFF00U), - SDL_SwapLE32(0xFF0000U), - SDL_SwapLE32(0xFF000000U)); + bmpsurface->w, + bmpsurface->h, + 32, + SDL_SwapLE32(0xFFU), + SDL_SwapLE32(0xFF00U), + SDL_SwapLE32(0xFF0000U), + SDL_SwapLE32(0xFF000000U)); SDL_FillRect(cursurface, NULL, SDL_SwapLE32(0x00000000U)); // Blit the cursor pixel data onto a 32-bit RGBA surface so we // only have to cope with processing one type of pixel format. if (0 == SDL_BlitSurface(bmpsurface, NULL, - cursurface, NULL)) + cursurface, NULL)) { // n.b. we already checked that width is a multiple of 8. const int bitmap_bytes = (cursurface->w * cursurface->h) / 8; @@ -1997,26 +2274,26 @@ static SDL_Cursor *makeSDLCursorFromBMP(const char *filename, int hotx, int hoty for (i=0; i<cursurface->h; ++i) { for (j=0; j<cursurface->w; ++j) { U8 *pixelp = - ((U8*)cursurface->pixels) - + cursurface->pitch * i - + j*cursurface->format->BytesPerPixel; + ((U8*)cursurface->pixels) + + cursurface->pitch * i + + j*cursurface->format->BytesPerPixel; U8 srcred = pixelp[0]; U8 srcgreen = pixelp[1]; U8 srcblue = pixelp[2]; bool mask_bit = (srcred != 200) - || (srcgreen != 200) - || (srcblue != 200); + || (srcgreen != 200) + || (srcblue != 200); bool data_bit = mask_bit && (srcgreen <= 80);//not 0x80 unsigned char bit_offset = (cursurface->w/8) * i - + j/8; + + j/8; cursor_data[bit_offset] |= (data_bit) << (7 - (j&7)); cursor_mask[bit_offset] |= (mask_bit) << (7 - (j&7)); } } sdlcursor = SDL_CreateCursor((Uint8*)cursor_data, - (Uint8*)cursor_mask, - cursurface->w, cursurface->h, - hotx, hoty); + (Uint8*)cursor_mask, + cursurface->w, cursurface->h, + hotx, hoty); delete[] cursor_data; delete[] cursor_mask; } else { @@ -2207,8 +2484,6 @@ void LLWindowSDL::hideCursorUntilMouseMove() } } - - // // LLSplashScreenSDL - I don't think we'll bother to implement this; it's // fairly obsolete at this point. @@ -2233,133 +2508,71 @@ void LLSplashScreenSDL::hideImpl() { } - - -#if LL_GTK -static void response_callback (GtkDialog *dialog, - gint arg1, - gpointer user_data) -{ - gint *response = (gint*)user_data; - *response = arg1; - gtk_widget_destroy(GTK_WIDGET(dialog)); - gtk_main_quit(); -} - S32 OSMessageBoxSDL(const std::string& text, const std::string& caption, U32 type) { - S32 rtn = OSBTN_CANCEL; - - if(gWindowImplementation != NULL) - gWindowImplementation->beforeDialog(); + SDL_MessageBoxData oData = { SDL_MESSAGEBOX_INFORMATION, nullptr, caption.c_str(), text.c_str(), 0, nullptr, nullptr }; + SDL_MessageBoxButtonData btnOk[] = {{SDL_MESSAGEBOX_BUTTON_RETURNKEY_DEFAULT, OSBTN_OK, "OK" }}; + SDL_MessageBoxButtonData btnOkCancel [] = {{SDL_MESSAGEBOX_BUTTON_RETURNKEY_DEFAULT, OSBTN_OK, "OK" }, {SDL_MESSAGEBOX_BUTTON_ESCAPEKEY_DEFAULT, OSBTN_CANCEL, "Cancel"} }; + SDL_MessageBoxButtonData btnYesNo[] = { {SDL_MESSAGEBOX_BUTTON_RETURNKEY_DEFAULT, OSBTN_YES, "Yes" }, {SDL_MESSAGEBOX_BUTTON_ESCAPEKEY_DEFAULT, OSBTN_NO, "No"} }; - if (LLWindowSDL::ll_try_gtk_init()) + switch (type) { - GtkWidget *win = NULL; - - LL_INFOS() << "Creating a dialog because we're in windowed mode and GTK is happy." << LL_ENDL; - - GtkDialogFlags flags = GTK_DIALOG_MODAL; - GtkMessageType messagetype; - GtkButtonsType buttons; - switch (type) - { default: case OSMB_OK: - messagetype = GTK_MESSAGE_WARNING; - buttons = GTK_BUTTONS_OK; + oData.flags = SDL_MESSAGEBOX_WARNING; + oData.buttons = btnOk; + oData.numbuttons = 1; break; case OSMB_OKCANCEL: - messagetype = GTK_MESSAGE_QUESTION; - buttons = GTK_BUTTONS_OK_CANCEL; + oData.flags = SDL_MESSAGEBOX_INFORMATION; + oData.buttons = btnOkCancel; + oData.numbuttons = 2; break; case OSMB_YESNO: - messagetype = GTK_MESSAGE_QUESTION; - buttons = GTK_BUTTONS_YES_NO; + oData.flags = SDL_MESSAGEBOX_INFORMATION; + oData.buttons = btnYesNo; + oData.numbuttons = 2; break; - } - win = gtk_message_dialog_new(NULL, flags, messagetype, buttons, "%s", - text.c_str()); - -# if LL_X11 - // Make GTK tell the window manager to associate this - // dialog with our non-GTK SDL window, which should try - // to keep it on top etc. - if (gWindowImplementation && - gWindowImplementation->mSDL_XWindowID != None) - { - gtk_widget_realize(GTK_WIDGET(win)); // so we can get its gdkwin - GdkWindow *gdkwin = gdk_window_foreign_new(gWindowImplementation->mSDL_XWindowID); - gdk_window_set_transient_for(GTK_WIDGET(win)->window, - gdkwin); - } -# endif //LL_X11 - - gtk_window_set_position(GTK_WINDOW(win), - GTK_WIN_POS_CENTER_ON_PARENT); - - gtk_window_set_type_hint(GTK_WINDOW(win), - GDK_WINDOW_TYPE_HINT_DIALOG); - - if (!caption.empty()) - gtk_window_set_title(GTK_WINDOW(win), caption.c_str()); - - gint response = GTK_RESPONSE_NONE; - g_signal_connect (win, - "response", - G_CALLBACK (response_callback), - &response); - - // we should be able to use a gtk_dialog_run(), but it's - // apparently not written to exist in a world without a higher - // gtk_main(), so we manage its signal/destruction outselves. - gtk_widget_show_all (win); - gtk_main(); - - //LL_INFOS() << "response: " << response << LL_ENDL; - switch (response) - { - case GTK_RESPONSE_OK: rtn = OSBTN_OK; break; - case GTK_RESPONSE_YES: rtn = OSBTN_YES; break; - case GTK_RESPONSE_NO: rtn = OSBTN_NO; break; - case GTK_RESPONSE_APPLY: rtn = OSBTN_OK; break; - case GTK_RESPONSE_NONE: - case GTK_RESPONSE_CANCEL: - case GTK_RESPONSE_CLOSE: - case GTK_RESPONSE_DELETE_EVENT: - default: rtn = OSBTN_CANCEL; - } - } - else - { - LL_INFOS() << "MSGBOX: " << caption << ": " << text << LL_ENDL; - LL_INFOS() << "Skipping dialog because we're in fullscreen mode or GTK is not happy." << LL_ENDL; - rtn = OSBTN_OK; } - if(gWindowImplementation != NULL) - gWindowImplementation->afterDialog(); + int btn{0}; + if( 0 == SDL_ShowMessageBox( &oData, &btn ) ) + return btn; + return OSBTN_CANCEL; +} - return rtn; +bool LLWindowSDL::dialogColorPicker( F32 *r, F32 *g, F32 *b) +{ + return (false); } -static void color_changed_callback(GtkWidget *widget, - gpointer user_data) +#if LL_DARWIN +LLSD LLWindowSDL::getNativeKeyData() { - GtkColorSelection *colorsel = GTK_COLOR_SELECTION(widget); - GdkColor *colorp = (GdkColor*)user_data; + LLSD result = LLSD::emptyMap(); - gtk_color_selection_get_current_color(colorsel, colorp); -} + if(mRawKeyEvent) + { + result["event_type"] = LLSD::Integer(mRawKeyEvent->mEventType); + result["event_modifiers"] = LLSD::Integer(mRawKeyEvent->mEventModifiers); + result["event_keycode"] = LLSD::Integer(mRawKeyEvent->mEventKeyCode); + result["event_chars"] = (mRawKeyEvent->mEventChars) ? LLSD(LLSD::Integer(mRawKeyEvent->mEventChars)) : LLSD(); + result["event_umodchars"] = (mRawKeyEvent->mEventUnmodChars) ? LLSD(LLSD::Integer(mRawKeyEvent->mEventUnmodChars)) : LLSD(); + result["event_isrepeat"] = LLSD::Boolean(mRawKeyEvent->mEventRepeat); + } + LL_DEBUGS() << "native key data is: " << result << LL_ENDL; + return result; +} +#else /* Make the raw keyboard data available - used to poke through to LLQtWebKit so that Qt/Webkit has access to the virtual keycodes etc. that it needs */ LLSD LLWindowSDL::getNativeKeyData() { - LLSD result = LLSD::emptyMap(); + LLSD result = LLSD::emptyMap(); U32 modifiers = 0; // pretend-native modifiers... oh what a tangled web we weave! @@ -2377,99 +2590,15 @@ LLSD LLWindowSDL::getNativeKeyData() // *todo: test ALTs - I don't have a case for testing these. Do you? // *todo: NUM? - I don't care enough right now (and it's not a GDK modifier). - result["scan_code"] = (S32)mKeyScanCode; - result["virtual_key"] = (S32)mKeyVirtualKey; + result["virtual_key"] = (S32)mKeyVirtualKey; + result["virtual_key_win"] = (S32)LLKeyboardSDL::mapSDL2toWin( mKeyVirtualKey ); result["modifiers"] = (S32)modifiers; - - return result; -} - - -bool LLWindowSDL::dialogColorPicker( F32 *r, F32 *g, F32 *b) -{ - bool rtn = false; - - beforeDialog(); - - if (ll_try_gtk_init()) - { - GtkWidget *win = NULL; - - win = gtk_color_selection_dialog_new(NULL); - -# if LL_X11 - // Get GTK to tell the window manager to associate this - // dialog with our non-GTK SDL window, which should try - // to keep it on top etc. - if (mSDL_XWindowID != None) - { - gtk_widget_realize(GTK_WIDGET(win)); // so we can get its gdkwin - GdkWindow *gdkwin = gdk_window_foreign_new(mSDL_XWindowID); - gdk_window_set_transient_for(GTK_WIDGET(win)->window, - gdkwin); - } -# endif //LL_X11 - - GtkColorSelection *colorsel = GTK_COLOR_SELECTION (GTK_COLOR_SELECTION_DIALOG(win)->colorsel); - - GdkColor color, orig_color; - orig_color.pixel = 0; - orig_color.red = guint16(65535 * *r); - orig_color.green= guint16(65535 * *g); - orig_color.blue = guint16(65535 * *b); - color = orig_color; - - gtk_color_selection_set_previous_color (colorsel, &color); - gtk_color_selection_set_current_color (colorsel, &color); - gtk_color_selection_set_has_palette (colorsel, true); - gtk_color_selection_set_has_opacity_control(colorsel, false); - - gint response = GTK_RESPONSE_NONE; - g_signal_connect (win, - "response", - G_CALLBACK (response_callback), - &response); - - g_signal_connect (G_OBJECT (colorsel), "color_changed", - G_CALLBACK (color_changed_callback), - &color); - - gtk_window_set_modal(GTK_WINDOW(win), true); - gtk_widget_show_all(win); - // hide the help button - we don't service it. - gtk_widget_hide(GTK_COLOR_SELECTION_DIALOG(win)->help_button); - gtk_main(); - - if (response == GTK_RESPONSE_OK && - (orig_color.red != color.red - || orig_color.green != color.green - || orig_color.blue != color.blue) ) - { - *r = color.red / 65535.0f; - *g = color.green / 65535.0f; - *b = color.blue / 65535.0f; - rtn = true; - } - } - - afterDialog(); - - return rtn; -} -#else -S32 OSMessageBoxSDL(const std::string& text, const std::string& caption, U32 type) -{ - LL_INFOS() << "MSGBOX: " << caption << ": " << text << LL_ENDL; - return 0; -} - -bool LLWindowSDL::dialogColorPicker( F32 *r, F32 *g, F32 *b) -{ - return (false); + result["input_type"] = mInputType; + return result; } -#endif // LL_GTK +#endif // LL_DARWIN -#if LL_LINUX +#if LL_LINUX || LL_SOLARIS || __FreeBSD__ // extracted from spawnWebBrowser for clarity and to eliminate // compiler confusion regarding close(int fd) vs. LLWindow::close() void exec_cmd(const std::string& cmd, const std::string& arg) @@ -2481,9 +2610,32 @@ void exec_cmd(const std::string& cmd, const std::string& arg) { // child // disconnect from stdin/stdout/stderr, or child will // keep our output pipe undesirably alive if it outlives us. - close(0); - close(1); - close(2); + // close(0); + // close(1); + // close(2); + // <FS:TS> Reopen stdin, stdout, and stderr to /dev/null. + // It's good practice to always have those file + // descriptors open to something, lest the exec'd + // program actually try to use them. + FILE *result; + result = freopen("/dev/null","r",stdin); + if (result == NULL) + { + LL_WARNS() << "Error reopening stdin for web browser: " + << strerror(errno) << LL_ENDL; + } + result = freopen("/dev/null","w",stdout); + if (result == NULL) + { + LL_WARNS() << "Error reopening stdout for web browser: " + << strerror(errno) << LL_ENDL; + } + result = freopen("/dev/null","w",stderr); + if (result == NULL) + { + LL_WARNS() << "Error reopening stderr for web browser: " + << strerror(errno) << LL_ENDL; + } // end ourself by running the command execv(cmd.c_str(), argv); /* Flawfinder: ignore */ // if execv returns at all, there was a problem. @@ -2525,7 +2677,7 @@ void LLWindowSDL::spawnWebBrowser(const std::string& escaped_url, bool async) LL_INFOS() << "spawn_web_browser: " << escaped_url << LL_ENDL; -#if LL_LINUX +#if LL_LINUX || __FreeBSD__ # if LL_X11 if (mSDL_Display) { @@ -2537,43 +2689,65 @@ void LLWindowSDL::spawnWebBrowser(const std::string& escaped_url, bool async) # endif // LL_X11 std::string cmd, arg; +#ifdef LL_USESYSTEMLIBS + cmd = gDirUtilp->getExecutableDir(); +#else cmd = gDirUtilp->getAppRODataDir(); cmd += gDirUtilp->getDirDelimiter(); cmd += "etc"; +#endif cmd += gDirUtilp->getDirDelimiter(); cmd += "launch_url.sh"; arg = escaped_url; exec_cmd(cmd, arg); -#endif // LL_LINUX - LL_INFOS() << "spawn_web_browser returning." << LL_ENDL; -} +#elif LL_DARWIN + S32 result = 0; + CFURLRef urlRef = NULL; -void *LLWindowSDL::getPlatformWindow() -{ -#if LL_GTK && LL_LLMOZLIB_ENABLED - if (LLWindowSDL::ll_try_gtk_init()) + LL_INFOS() << "Opening URL " << escaped_url << LL_ENDL; + + CFStringRef stringRef = CFStringCreateWithCString(NULL, escaped_url.c_str(), kCFStringEncodingUTF8); + if (stringRef) { - maybe_lock_display(); + // This will succeed if the string is a full URL, including the http:// + // Note that URLs specified this way need to be properly percent-escaped. + urlRef = CFURLCreateWithString(NULL, stringRef, NULL); - GtkWidget *owin = gtk_window_new(GTK_WINDOW_POPUP); - // Why a layout widget? A MozContainer would be ideal, but - // it involves exposing Mozilla headers to mozlib-using apps. - // A layout widget with a GtkWindow parent has the desired - // properties of being plain GTK, having a window, and being - // derived from a GtkContainer. - GtkWidget *rtnw = gtk_layout_new(NULL, NULL); - gtk_container_add(GTK_CONTAINER(owin), rtnw); - gtk_widget_realize(rtnw); - GTK_WIDGET_UNSET_FLAGS(GTK_WIDGET(rtnw), GTK_NO_WINDOW); + // Don't use CRURLCreateWithFileSystemPath -- only want valid URLs - maybe_unlock_display(); + CFRelease(stringRef); + } - return rtnw; + if (urlRef) + { + result = LSOpenCFURLRef(urlRef, NULL); + + if (result != noErr) + { + LL_INFOS() << "Error " << result << " on open." << LL_ENDL; + } + + CFRelease(urlRef); } -#endif // LL_GTK && LL_LLMOZLIB_ENABLED - // Unixoid mozilla really needs GTK. + else + { + LL_INFOS() << "Error: couldn't create URL." << LL_ENDL; + } + +#endif // LL_LINUX + + LL_INFOS() << "spawn_web_browser returning." << LL_ENDL; +} + +void LLWindowSDL::openFile(const std::string& file_name) +{ + spawnWebBrowser("file://"+file_name,true); +} + +void *LLWindowSDL::getPlatformWindow() +{ return NULL; } @@ -2634,10 +2808,10 @@ std::vector<std::string> LLWindowSDL::getDynamicFallbackFontList() LL_INFOS("AppInit") << "Variant " << locale->variant << LL_ENDL; LL_INFOS() << "Preferring fonts of language: " - << locale->lang - << LL_ENDL; + << locale->lang + << LL_ENDL; sort_order = "lang=" + std::string(locale->lang) + ":" - + sort_order; + + sort_order; } } FL_FreeLocale(&locale); @@ -2655,7 +2829,7 @@ std::vector<std::string> LLWindowSDL::getDynamicFallbackFontList() // Sort the list of system fonts from most-to-least-desirable. FcResult result; fs = FcFontSort(NULL, sortpat, elide_unicode_coverage, - NULL, &result); + NULL, &result); FcPatternDestroy(sortpat); } @@ -2669,8 +2843,8 @@ std::vector<std::string> LLWindowSDL::getDynamicFallbackFontList() { FcChar8 *filename; if (FcResultMatch == FcPatternGetString(fs->fonts[i], - FC_FILE, 0, - &filename) + FC_FILE, 0, + &filename) && filename) { rtns.push_back(std::string((const char*)filename)); @@ -2694,4 +2868,64 @@ std::vector<std::string> LLWindowSDL::getDynamicFallbackFontList() return rtns; } -#endif // LL_SDL + +void* LLWindowSDL::createSharedContext() +{ + auto *pContext = SDL_GL_CreateContext(mWindow); + if ( pContext) + { + SDL_GL_SetSwapInterval(0); + SDL_GL_MakeCurrent(mWindow, mContext); + + LLCoordScreen size; + if (getSize(&size)) + setSize(size); + + LL_DEBUGS() << "Creating shared OpenGL context successful!" << LL_ENDL; + + return (void*)pContext; + } + + LL_WARNS() << "Creating shared OpenGL context failed!" << LL_ENDL; + + return nullptr; +} + +void LLWindowSDL::makeContextCurrent(void* contextPtr) +{ + LL_PROFILER_GPU_CONTEXT; + SDL_GL_MakeCurrent( mWindow, contextPtr ); +} + +void LLWindowSDL::destroySharedContext(void* contextPtr) +{ + SDL_GL_DeleteContext( contextPtr ); +} + +void LLWindowSDL::toggleVSync(bool enable_vsync) +{ + if( !enable_vsync) + { + SDL_GL_SetSwapInterval(0); + SDL_SetHintWithPriority(SDL_HINT_RENDER_VSYNC,"0",SDL_HINT_OVERRIDE); + } + else + { + SDL_GL_SetSwapInterval(1); + SDL_SetHintWithPriority(SDL_HINT_RENDER_VSYNC,"1",SDL_HINT_OVERRIDE); + } +} + +void LLWindowSDL::setLanguageTextInput(const LLCoordGL& position) +{ + LLCoordWindow win_pos; + convertCoords( position, &win_pos ); + + SDL_Rect r; + r.x = win_pos.mX; + r.y = win_pos.mY; + r.w = 500; + r.h = 16; + + SDL_SetTextInputRect(&r); +} diff --git a/indra/llwindow/llwindowsdl.h b/indra/llwindow/llwindowsdl.h index 196ad2986d..3ed2811572 100644 --- a/indra/llwindow/llwindowsdl.h +++ b/indra/llwindow/llwindowsdl.h @@ -24,20 +24,24 @@ * $/LicenseInfo$ */ -#ifndef LL_LLWINDOWSDL_H -#define LL_LLWINDOWSDL_H +#ifndef LL_LLWINDOWSDL2_H +#define LL_LLWINDOWSDL2_H // Simple Directmedia Layer (http://libsdl.org/) implementation of LLWindow class #include "llwindow.h" #include "lltimer.h" -#include "SDL/SDL.h" -#include "SDL/SDL_endian.h" +#if !defined(__i386__) && !defined(__x86_64__) +#define SDL_DISABLE_IMMINTRIN_H +#endif +#include "SDL2/SDL.h" +#include "SDL2/SDL_video.h" +#include "SDL2/SDL_endian.h" #if LL_X11 // get X11-specific headers for use in low-level stuff like copy-and-paste support -#include "SDL/SDL_syswm.h" +#include "SDL2/SDL_syswm.h" #endif // AssertMacros.h does bad things. @@ -46,83 +50,141 @@ #undef require -class LLWindowSDL : public LLWindow -{ +class LLWindowSDL : public LLWindow { public: - /*virtual*/ void show(); - /*virtual*/ void hide(); - /*virtual*/ void close(); - /*virtual*/ bool getVisible(); - /*virtual*/ bool getMinimized(); - /*virtual*/ bool getMaximized(); - /*virtual*/ bool maximize(); - /*virtual*/ void minimize(); - /*virtual*/ void restore(); - /*virtual*/ bool getFullscreen(); - /*virtual*/ bool getPosition(LLCoordScreen *position); - /*virtual*/ bool getSize(LLCoordScreen *size); - /*virtual*/ bool getSize(LLCoordWindow *size); - /*virtual*/ bool setPosition(LLCoordScreen position); - /*virtual*/ bool setSizeImpl(LLCoordScreen size); - /*virtual*/ bool setSizeImpl(LLCoordWindow size); - /*virtual*/ bool switchContext(bool fullscreen, const LLCoordScreen &size, bool disable_vsync, const LLCoordScreen * const posp = NULL); - /*virtual*/ bool setCursorPosition(LLCoordWindow position); - /*virtual*/ bool getCursorPosition(LLCoordWindow *position); - /*virtual*/ void showCursor(); - /*virtual*/ void hideCursor(); - /*virtual*/ void showCursorFromMouseMove(); - /*virtual*/ void hideCursorUntilMouseMove(); - /*virtual*/ bool isCursorHidden(); - /*virtual*/ void updateCursor(); - /*virtual*/ void captureMouse(); - /*virtual*/ void releaseMouse(); - /*virtual*/ void setMouseClipping( bool b ); - /*virtual*/ void setMinSize(U32 min_width, U32 min_height, bool enforce_immediately = true); - - /*virtual*/ bool isClipboardTextAvailable(); - /*virtual*/ bool pasteTextFromClipboard(LLWString &dst); - /*virtual*/ bool copyTextToClipboard(const LLWString & src); - - /*virtual*/ bool isPrimaryTextAvailable(); - /*virtual*/ bool pasteTextFromPrimary(LLWString &dst); - /*virtual*/ bool copyTextToPrimary(const LLWString & src); - - /*virtual*/ void flashIcon(F32 seconds); - /*virtual*/ F32 getGamma(); - /*virtual*/ bool setGamma(const F32 gamma); // Set the gamma - /*virtual*/ U32 getFSAASamples(); - /*virtual*/ void setFSAASamples(const U32 samples); - /*virtual*/ bool restoreGamma(); // Restore original gamma table (before updating gamma) - /*virtual*/ ESwapMethod getSwapMethod() { return mSwapMethod; } - /*virtual*/ void processMiscNativeEvents(); - /*virtual*/ void gatherInput(); - /*virtual*/ void swapBuffers(); - /*virtual*/ void restoreGLContext() {}; - - /*virtual*/ void delayInputProcessing() { }; + void show() override; + + void hide() override; + + void close() override; + + bool getVisible() override; + + bool getMinimized() override; + + bool getMaximized() override; + + bool maximize() override; + + void minimize() override; + + void restore() override; + + bool getFullscreen(); + + bool getPosition(LLCoordScreen *position) override; + + bool getSize(LLCoordScreen *size) override; + + bool getSize(LLCoordWindow *size) override; + + bool setPosition(LLCoordScreen position) override; + + bool setSizeImpl(LLCoordScreen size) override; + + bool setSizeImpl(LLCoordWindow size) override; + + bool switchContext(bool fullscreen, const LLCoordScreen &size, bool disable_vsync, + const LLCoordScreen *const posp = NULL) override; + + bool setCursorPosition(LLCoordWindow position) override; + + bool getCursorPosition(LLCoordWindow *position) override; + + void showCursor() override; + + void hideCursor() override; + + void showCursorFromMouseMove() override; + + void hideCursorUntilMouseMove() override; + + bool isCursorHidden() override; + + void updateCursor() override; + + void captureMouse() override; + + void releaseMouse() override; + + void setMouseClipping(bool b) override; + + void setMinSize(U32 min_width, U32 min_height, bool enforce_immediately = true) override; + + bool isClipboardTextAvailable() override; + + bool pasteTextFromClipboard(LLWString &dst) override; + + bool copyTextToClipboard(const LLWString &src) override; + + bool isPrimaryTextAvailable() override; + + bool pasteTextFromPrimary(LLWString &dst) override; + + bool copyTextToPrimary(const LLWString &src) override; + + void flashIcon(F32 seconds) override; + + F32 getGamma() override; + + bool setGamma(const F32 gamma) override; // Set the gamma + U32 getFSAASamples() override; + + void setFSAASamples(const U32 samples) override; + + bool restoreGamma() override; // Restore original gamma table (before updating gamma) + ESwapMethod getSwapMethod() override { return mSwapMethod; } + + void processMiscNativeEvents() override; + + void gatherInput() override; + + void swapBuffers() override; + + void restoreGLContext() {}; + + void delayInputProcessing() override {}; // handy coordinate space conversion routines - /*virtual*/ bool convertCoords(LLCoordScreen from, LLCoordWindow *to); - /*virtual*/ bool convertCoords(LLCoordWindow from, LLCoordScreen *to); - /*virtual*/ bool convertCoords(LLCoordWindow from, LLCoordGL *to); - /*virtual*/ bool convertCoords(LLCoordGL from, LLCoordWindow *to); - /*virtual*/ bool convertCoords(LLCoordScreen from, LLCoordGL *to); - /*virtual*/ bool convertCoords(LLCoordGL from, LLCoordScreen *to); + bool convertCoords(LLCoordScreen from, LLCoordWindow *to) override; + + bool convertCoords(LLCoordWindow from, LLCoordScreen *to) override; + + bool convertCoords(LLCoordWindow from, LLCoordGL *to) override; + + bool convertCoords(LLCoordGL from, LLCoordWindow *to) override; + + bool convertCoords(LLCoordScreen from, LLCoordGL *to) override; + + bool convertCoords(LLCoordGL from, LLCoordScreen *to) override; - /*virtual*/ LLWindowResolution* getSupportedResolutions(S32 &num_resolutions); - /*virtual*/ F32 getNativeAspectRatio(); - /*virtual*/ F32 getPixelAspectRatio(); - /*virtual*/ void setNativeAspectRatio(F32 ratio) { mOverrideAspectRatio = ratio; } + LLWindowResolution *getSupportedResolutions(S32 &num_resolutions) override; - /*virtual*/ void beforeDialog(); - /*virtual*/ void afterDialog(); + F32 getNativeAspectRatio() override; - /*virtual*/ bool dialogColorPicker(F32 *r, F32 *g, F32 *b); + F32 getPixelAspectRatio() override; - /*virtual*/ void *getPlatformWindow(); - /*virtual*/ void bringToFront(); + void setNativeAspectRatio(F32 ratio) override { mOverrideAspectRatio = ratio; } - /*virtual*/ void spawnWebBrowser(const std::string& escaped_url, bool async); + F32 getSystemUISize() override; + + void beforeDialog() override; + + void afterDialog() override; + + bool dialogColorPicker(F32 *r, F32 *g, F32 *b) override; + + void *getPlatformWindow() override; + + void bringToFront() override; + + void setLanguageTextInput(const LLCoordGL& pos) override; + + void spawnWebBrowser(const std::string &escaped_url, bool async) override; + + void openFile(const std::string &file_name); + + void setTitle(const std::string title) override; static std::vector<std::string> getDynamicFallbackFontList(); @@ -132,40 +194,56 @@ public: Window mSDL_XWindowID; Display *mSDL_Display; #endif + void (*Lock_Display)(void); - void (*Unlock_Display)(void); -#if LL_GTK - // Lazily initialize and check the runtime GTK version for goodness. - static bool ll_try_gtk_init(void); -#endif // LL_GTK + void (*Unlock_Display)(void); #if LL_X11 + static Window get_SDL_XWindowID(void); - static Display* get_SDL_Display(void); + + static Display *get_SDL_Display(void); + #endif // LL_X11 +#if LL_DARWIN + static bool sUseMultGL; +#endif + + void *createSharedContext() override; + + void makeContextCurrent(void *context) override; + + void destroySharedContext(void *context) override; + + void toggleVSync(bool enable_vsync) override; + protected: - LLWindowSDL(LLWindowCallbacks* callbacks, - const std::string& title, int x, int y, int width, int height, U32 flags, - bool fullscreen, bool clearBg, bool disable_vsync, bool use_gl, - bool ignore_pixel_depth, U32 fsaa_samples); + LLWindowSDL(LLWindowCallbacks *callbacks, + const std::string &title, int x, int y, int width, int height, U32 flags, + bool fullscreen, bool clearBg, bool disable_vsync, bool use_gl, + bool ignore_pixel_depth, U32 fsaa_samples); + ~LLWindowSDL(); - /*virtual*/ bool isValid(); - /*virtual*/ LLSD getNativeKeyData(); + bool isValid() override; + + LLSD getNativeKeyData() override; - void initCursors(); - void quitCursors(); - void moveWindow(const LLCoordScreen& position,const LLCoordScreen& size); + void initCursors(); + + void quitCursors(); + + void moveWindow(const LLCoordScreen &position, const LLCoordScreen &size); // Changes display resolution. Returns true if successful - bool setDisplayResolution(S32 width, S32 height, S32 bits, S32 refresh); + bool setDisplayResolution(S32 width, S32 height, S32 bits, S32 refresh); // Go back to last fullscreen display resolution. - bool setFullscreenResolution(); + bool setFullscreenResolution(); - bool shouldPostQuit() { return mPostQuit; } + bool shouldPostQuit() { return mPostQuit; } protected: // @@ -174,46 +252,84 @@ protected: // create or re-create the GL context/window. Called from the constructor and switchContext(). bool createContext(int x, int y, int width, int height, int bits, bool fullscreen, bool disable_vsync); + void destroyContext(); - void setupFailure(const std::string& text, const std::string& caption, U32 type); + + void setupFailure(const std::string &text, const std::string &caption, U32 type); + void fixWindowSize(void); - U32 SDLCheckGrabbyKeys(SDLKey keysym, bool gain); + + U32 SDLCheckGrabbyKeys(U32 keysym, bool gain); + bool SDLReallyCaptureInput(bool capture); // // Platform specific variables // - U32 mGrabbyKeyFlags; - int mReallyCapturedCount; - SDL_Surface * mWindow; + U32 mGrabbyKeyFlags; + int mReallyCapturedCount; + + SDL_Window *mWindow; + SDL_GLContext mContext; + SDL_Cursor *mSDLCursors[UI_CURSOR_COUNT]; + std::string mWindowTitle; - double mOriginalAspectRatio; - bool mNeedsResize; // Constructor figured out the window is too big, it needs a resize. - LLCoordScreen mNeedsResizeSize; - F32 mOverrideAspectRatio; - F32 mGamma; - U32 mFSAASamples; + double mOriginalAspectRatio; + bool mNeedsResize; // Constructor figured out the window is too big, it needs a resize. + LLCoordScreen mNeedsResizeSize; + F32 mOverrideAspectRatio; + F32 mGamma; + U32 mFSAASamples; - int mSDLFlags; + int mSDLFlags; - SDL_Cursor* mSDLCursors[UI_CURSOR_COUNT]; - int mHaveInputFocus; /* 0=no, 1=yes, else unknown */ - int mIsMinimized; /* 0=no, 1=yes, else unknown */ + int mHaveInputFocus; /* 0=no, 1=yes, else unknown */ + int mIsMinimized; /* 0=no, 1=yes, else unknown */ + int mIsActive; /* 0=no, 1=yes, else unknown */ friend class LLWindowManager; private: #if LL_X11 + void x11_set_urgent(bool urgent); + bool mFlashing; LLTimer mFlashTimer; #endif //LL_X11 - U32 mKeyScanCode; - U32 mKeyVirtualKey; - SDLMod mKeyModifiers; -}; + U32 mKeyVirtualKey; + U32 mKeyModifiers; + std::string mInputType; + +public: +#if LL_X11 + + static Display *getSDLDisplay(); + LLWString const &getPrimaryText() const { return mPrimaryClipboard; } + + LLWString const &getSecondaryText() const { return mSecondaryClipboard; } + + void clearPrimaryText() { mPrimaryClipboard.clear(); } + + void clearSecondaryText() { mSecondaryClipboard.clear(); } + +private: + void initialiseX11Clipboard(); + + bool getSelectionText(Atom selection, LLWString &text); + + bool getSelectionText(Atom selection, Atom type, LLWString &text); + + bool setSelectionText(Atom selection, const LLWString &text); +#endif + + void tryFindFullscreenSize(int &aWidth, int &aHeight); + + LLWString mPrimaryClipboard; + LLWString mSecondaryClipboard; +}; class LLSplashScreenSDL : public LLSplashScreen { @@ -221,9 +337,9 @@ public: LLSplashScreenSDL(); virtual ~LLSplashScreenSDL(); - /*virtual*/ void showImpl(); - /*virtual*/ void updateImpl(const std::string& mesg); - /*virtual*/ void hideImpl(); + void showImpl(); + void updateImpl(const std::string& mesg); + void hideImpl(); }; S32 OSMessageBoxSDL(const std::string& text, const std::string& caption, U32 type); diff --git a/indra/llwindow/llwindowwin32.cpp b/indra/llwindow/llwindowwin32.cpp index 91437b98d1..730e658c6a 100644 --- a/indra/llwindow/llwindowwin32.cpp +++ b/indra/llwindow/llwindowwin32.cpp @@ -44,6 +44,7 @@ #include "llstring.h" #include "lldir.h" #include "llsdutil.h" +#include "llsys.h" #include "llglslshader.h" #include "llthreadsafequeue.h" #include "stringize.h" @@ -80,10 +81,6 @@ const S32 BITS_PER_PIXEL = 32; const S32 MAX_NUM_RESOLUTIONS = 32; const F32 ICON_FLASH_TIME = 0.5f; -#ifndef WM_DPICHANGED -#define WM_DPICHANGED 0x02E0 -#endif - #ifndef USER_DEFAULT_SCREEN_DPI #define USER_DEFAULT_SCREEN_DPI 96 // Win7 #endif @@ -163,18 +160,7 @@ HGLRC SafeCreateContext(HDC &hdc) GLuint SafeChoosePixelFormat(HDC &hdc, const PIXELFORMATDESCRIPTOR *ppfd) { - __try - { - return ChoosePixelFormat(hdc, ppfd); - } - __except (EXCEPTION_EXECUTE_HANDLER) - { - // convert to C++ styled exception - // C exception don't allow classes, so it's a regular char array - char integer_string[32]; - sprintf(integer_string, "SEH, code: %lu\n", GetExceptionCode()); - throw std::exception(integer_string); - } + return LL::seh::catcher([hdc, ppfd]{ return ChoosePixelFormat(hdc, ppfd); }); } //static @@ -1317,8 +1303,7 @@ bool LLWindowWin32::switchContext(bool fullscreen, const LLCoordScreen& size, bo catch (...) { LOG_UNHANDLED_EXCEPTION("ChoosePixelFormat"); - OSMessageBox(mCallbacks->translateString("MBPixelFmtErr"), - mCallbacks->translateString("MBError"), OSMB_OK); + LLError::LLUserWarningMsg::show(mCallbacks->translateString("MBPixelFmtErr"), 8/*LAST_EXEC_GRAPHICS_INIT*/); close(); return false; } @@ -1329,8 +1314,7 @@ bool LLWindowWin32::switchContext(bool fullscreen, const LLCoordScreen& size, bo if (!DescribePixelFormat(mhDC, pixel_format, sizeof(PIXELFORMATDESCRIPTOR), &pfd)) { - OSMessageBox(mCallbacks->translateString("MBPixelFmtDescErr"), - mCallbacks->translateString("MBError"), OSMB_OK); + LLError::LLUserWarningMsg::show(mCallbacks->translateString("MBPixelFmtDescErr"), 8/*LAST_EXEC_GRAPHICS_INIT*/); close(); return false; } @@ -1368,8 +1352,7 @@ bool LLWindowWin32::switchContext(bool fullscreen, const LLCoordScreen& size, bo if (!SetPixelFormat(mhDC, pixel_format, &pfd)) { - OSMessageBox(mCallbacks->translateString("MBPixelFmtSetErr"), - mCallbacks->translateString("MBError"), OSMB_OK); + LLError::LLUserWarningMsg::show(mCallbacks->translateString("MBPixelFmtSetErr"), 8/*LAST_EXEC_GRAPHICS_INIT*/); close(); return false; } @@ -1377,16 +1360,14 @@ bool LLWindowWin32::switchContext(bool fullscreen, const LLCoordScreen& size, bo if (!(mhRC = SafeCreateContext(mhDC))) { - OSMessageBox(mCallbacks->translateString("MBGLContextErr"), - mCallbacks->translateString("MBError"), OSMB_OK); + LLError::LLUserWarningMsg::show(mCallbacks->translateString("MBGLContextErr"), 8/*LAST_EXEC_GRAPHICS_INIT*/); close(); return false; } if (!wglMakeCurrent(mhDC, mhRC)) { - OSMessageBox(mCallbacks->translateString("MBGLContextActErr"), - mCallbacks->translateString("MBError"), OSMB_OK); + LLError::LLUserWarningMsg::show(mCallbacks->translateString("MBGLContextActErr"), 8/*LAST_EXEC_GRAPHICS_INIT*/); close(); return false; } @@ -1592,15 +1573,14 @@ const S32 max_format = (S32)num_formats - 1; if (!mhDC) { - OSMessageBox(mCallbacks->translateString("MBDevContextErr"), mCallbacks->translateString("MBError"), OSMB_OK); + LLError::LLUserWarningMsg::show(mCallbacks->translateString("MBDevContextErr"), 8/*LAST_EXEC_GRAPHICS_INIT*/); close(); return false; } if (!SetPixelFormat(mhDC, pixel_format, &pfd)) { - OSMessageBox(mCallbacks->translateString("MBPixelFmtSetErr"), - mCallbacks->translateString("MBError"), OSMB_OK); + LLError::LLUserWarningMsg::show(mCallbacks->translateString("MBPixelFmtSetErr"), 8/*LAST_EXEC_GRAPHICS_INIT*/); close(); return false; } @@ -1632,7 +1612,7 @@ const S32 max_format = (S32)num_formats - 1; { LL_WARNS("Window") << "No wgl_ARB_pixel_format extension!" << LL_ENDL; // cannot proceed without wgl_ARB_pixel_format extension, shutdown same as any other gGLManager.initGL() failure - OSMessageBox(mCallbacks->translateString("MBVideoDrvErr"), mCallbacks->translateString("MBError"), OSMB_OK); + LLError::LLUserWarningMsg::show(mCallbacks->translateString("MBVideoDrvErr"), 8/*LAST_EXEC_GRAPHICS_INIT*/); close(); return false; } @@ -1641,7 +1621,7 @@ const S32 max_format = (S32)num_formats - 1; if (!DescribePixelFormat(mhDC, pixel_format, sizeof(PIXELFORMATDESCRIPTOR), &pfd)) { - OSMessageBox(mCallbacks->translateString("MBPixelFmtDescErr"), mCallbacks->translateString("MBError"), OSMB_OK); + LLError::LLUserWarningMsg::show(mCallbacks->translateString("MBPixelFmtDescErr"), 8/*LAST_EXEC_GRAPHICS_INIT*/); close(); return false; } @@ -1663,14 +1643,14 @@ const S32 max_format = (S32)num_formats - 1; if (!wglMakeCurrent(mhDC, mhRC)) { - OSMessageBox(mCallbacks->translateString("MBGLContextActErr"), mCallbacks->translateString("MBError"), OSMB_OK); + LLError::LLUserWarningMsg::show(mCallbacks->translateString("MBGLContextActErr"), 8/*LAST_EXEC_GRAPHICS_INIT*/); close(); return false; } if (!gGLManager.initGL()) { - OSMessageBox(mCallbacks->translateString("MBVideoDrvErr"), mCallbacks->translateString("MBError"), OSMB_OK); + LLError::LLUserWarningMsg::show(mCallbacks->translateString("MBVideoDrvErr"), 8/*LAST_EXEC_GRAPHICS_INIT*/); close(); return false; } @@ -1875,7 +1855,7 @@ void* LLWindowWin32::createSharedContext() if (!rc && !(rc = wglCreateContext(mhDC))) { close(); - OSMessageBox(mCallbacks->translateString("MBGLContextErr"), mCallbacks->translateString("MBError"), OSMB_OK); + LLError::LLUserWarningMsg::show(mCallbacks->translateString("MBGLContextErr"), 8/*LAST_EXEC_GRAPHICS_INIT*/); } return rc; @@ -2974,6 +2954,11 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_ return 0; } + case WM_DISPLAYCHANGE: + { + WINDOW_IMP_POST(window_imp->mCallbacks->handleDisplayChanged()); + } + case WM_SETFOCUS: { LL_PROFILE_ZONE_NAMED_CATEGORY_WIN32("mwp - WM_SETFOCUS"); @@ -4044,7 +4029,15 @@ void LLWindowWin32::fillCompositionLogfont(LOGFONT *logfont) break; } - logfont->lfHeight = mPreeditor->getPreeditFontSize(); + if (mPreeditor) + { + logfont->lfHeight = mPreeditor->getPreeditFontSize(); + } + else + { + // todo: extract from some font * LLUI::getScaleFactor() intead + logfont->lfHeight = 10; + } logfont->lfWeight = FW_NORMAL; } @@ -4681,6 +4674,23 @@ void LLWindowWin32::LLWindowWin32Thread::checkDXMem() // Alternatively use GetDesc from below to get adapter's memory UINT64 budget_mb = info.Budget / (1024 * 1024); + if (gGLManager.mIsIntel) + { + U32Megabytes phys_mb = gSysMemory.getPhysicalMemoryKB(); + LL_WARNS() << "Physical memory: " << phys_mb << " MB" << LL_ENDL; + + if (phys_mb > 0) + { + // Intel uses 'shared' vram, cap it to 25% of total memory + // Todo: consider caping all adapters at least to 50% ram + budget_mb = llmin(budget_mb, (UINT64)(phys_mb * 0.25)); + } + else + { + // if no data available, cap to 2Gb + budget_mb = llmin(budget_mb, (UINT64)2048); + } + } if (gGLManager.mVRAM < (S32)budget_mb) { gGLManager.mVRAM = (S32)budget_mb; diff --git a/indra/llxml/CMakeLists.txt b/indra/llxml/CMakeLists.txt index 508c2b919b..03ac4bc9f2 100644 --- a/indra/llxml/CMakeLists.txt +++ b/indra/llxml/CMakeLists.txt @@ -4,6 +4,7 @@ project(llxml) include(00-Common) include(LLCommon) +include(LLWindow) set(llxml_SOURCE_FILES llcontrol.cpp @@ -31,9 +32,11 @@ target_link_libraries( llxml llmath llcommon ll::expat + ll::SDL ) target_include_directories( llxml INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}) +include(LibraryInstall) # tests diff --git a/indra/llxml/llxmlnode.cpp b/indra/llxml/llxmlnode.cpp index 92bcb1a2ae..8a2c36a307 100644 --- a/indra/llxml/llxmlnode.cpp +++ b/indra/llxml/llxmlnode.cpp @@ -29,6 +29,9 @@ #include <iostream> #include <map> +#if LL_SDL +#include <SDL_rwops.h> +#endif #include "llxmlnode.h" @@ -306,6 +309,7 @@ void LLXMLNode::addChild(LLXMLNodePtr& new_child) // virtual LLXMLNodePtr LLXMLNode::createChild(const char* name, bool is_attribute) { + // Todo: validate to make sure node name is valid? (no spaces, etc) return createChild(gStringTable.addStringEntry(name), is_attribute); } diff --git a/indra/llxml/llxmltree.cpp b/indra/llxml/llxmltree.cpp index 164b3156e1..d66544d0f8 100644 --- a/indra/llxml/llxmltree.cpp +++ b/indra/llxml/llxmltree.cpp @@ -108,12 +108,15 @@ LLXmlTreeNode::LLXmlTreeNode( const std::string& name, LLXmlTreeNode* parent, LL LLXmlTreeNode::~LLXmlTreeNode() { - attribute_map_t::iterator iter; - for (iter=mAttributes.begin(); iter != mAttributes.end(); iter++) - delete iter->second; - for(LLXmlTreeNode* node : mChildren) + for (auto& attr : mAttributes) + { + delete attr.second; + } + mAttributes.clear(); + + for (auto& child : mChildren) { - delete node; + delete child; } mChildren.clear(); } diff --git a/indra/media_plugins/CMakeLists.txt b/indra/media_plugins/CMakeLists.txt index 972bb7dd2d..78bdba8f18 100644 --- a/indra/media_plugins/CMakeLists.txt +++ b/indra/media_plugins/CMakeLists.txt @@ -2,9 +2,15 @@ add_subdirectory(base) +if (CMAKE_SYSTEM_NAME MATCHES "FreeBSD") + add_subdirectory(example) + add_subdirectory(libvlc) +endif (CMAKE_SYSTEM_NAME MATCHES "FreeBSD") + if (LINUX) - #add_subdirectory(gstreamer010) + add_subdirectory(cef) add_subdirectory(example) + add_subdirectory(libvlc) endif (LINUX) if (DARWIN) diff --git a/indra/media_plugins/base/CMakeLists.txt b/indra/media_plugins/base/CMakeLists.txt index 64b6a4228d..57e3782ada 100644 --- a/indra/media_plugins/base/CMakeLists.txt +++ b/indra/media_plugins/base/CMakeLists.txt @@ -12,13 +12,6 @@ include(PluginAPI) ### media_plugin_base -if(NOT ADDRESS_SIZE EQUAL 32) - if(WINDOWS) - ##add_definitions(/FIXED:NO) - else(WINDOWS) # not windows therefore gcc LINUX and DARWIN - add_definitions(-fPIC) - endif(WINDOWS) -endif(NOT ADDRESS_SIZE EQUAL 32) set(media_plugin_base_SOURCE_FILES media_plugin_base.cpp @@ -31,6 +24,7 @@ set(media_plugin_base_HEADER_FILES ) add_library(media_plugin_base + STATIC ${media_plugin_base_SOURCE_FILES} ) diff --git a/indra/media_plugins/base/media_plugin_base.cpp b/indra/media_plugins/base/media_plugin_base.cpp index 545eee25a9..d54e67c532 100644 --- a/indra/media_plugins/base/media_plugin_base.cpp +++ b/indra/media_plugins/base/media_plugin_base.cpp @@ -167,10 +167,60 @@ void MediaPluginBase::sendStatus() sendMessage(message); } +#if LL_LINUX || __FreeBSD__ + +size_t SymbolGrabber::registerSymbol( SymbolToGrab aSymbol ) +{ + gSymbolsToGrab.emplace_back(aSymbol); + return gSymbolsToGrab.size(); +} + +bool SymbolGrabber::grabSymbols(std::vector< std::string > const &aDSONames) +{ + std::cerr << "SYMBOLS: " << gSymbolsToGrab.size() << std::endl; + + if (sSymsGrabbed) + return true; + + //attempt to load the shared libraries + apr_pool_create(&sSymDSOMemoryPool, nullptr); + + for( std::vector< std::string >::const_iterator itr = aDSONames.begin(); itr != aDSONames.end(); ++itr ) + { + apr_dso_handle_t *pDSO(NULL); + std::string strDSO{ *itr }; + if( APR_SUCCESS == apr_dso_load( &pDSO, strDSO.c_str(), sSymDSOMemoryPool )) + sLoadedLibraries.push_back( pDSO ); + + for( auto i = 0; i < gSymbolsToGrab.size(); ++i ) + { + if( !*gSymbolsToGrab[i].mPPFunc ) + apr_dso_sym( gSymbolsToGrab[i].mPPFunc, pDSO, gSymbolsToGrab[i].mName ); + } + } + + bool sym_error = false; + + for( auto i = 0; i < gSymbolsToGrab.size(); ++i ) + { + if( gSymbolsToGrab[ i ].mRequired && ! *gSymbolsToGrab[ i ].mPPFunc ) + sym_error = true; + } + + sSymsGrabbed = !sym_error; + return sSymsGrabbed; +} + +void SymbolGrabber::ungrabSymbols() +{ + +} +#endif + #if LL_WINDOWS # define LLSYMEXPORT __declspec(dllexport) -#elif LL_LINUX +#elif LL_LINUX || __FreeBSD__ # define LLSYMEXPORT __attribute__ ((visibility("default"))) #else # define LLSYMEXPORT /**/ @@ -204,3 +254,50 @@ int WINAPI DllEntryPoint( HINSTANCE hInstance, unsigned long reason, void* param return 1; } #endif + +#if LL_LINUX +pid_t getParentPid( pid_t aPid ) +{ + std::stringstream strm; + strm << "/proc/" << aPid << "/status"; + std::ifstream in{ strm.str() }; + + if( !in.is_open() ) + return 0; + + pid_t res {0}; + while( !in.eof() && res == 0 ) + { + std::string line; + line.resize( 1024, 0 ); + in.getline( &line[0], line.length() ); + + auto i = line.find( "PPid:" ); + + if( i == std::string::npos ) + continue; + + char const *pIn = line.c_str() + 5; // Skip over pid; + while( *pIn != 0 && isspace( *pIn ) ) + ++pIn; + + if( *pIn ) + res = atoll( pIn ); + } + return res; +} + +bool isPluginPid( pid_t aPid ) +{ + auto myPid = getpid(); + + do + { + if( aPid == myPid ) + return true; + aPid = getParentPid( aPid ); + } while( aPid > 1 ); + + return false; +} +#endif diff --git a/indra/media_plugins/base/media_plugin_base.h b/indra/media_plugins/base/media_plugin_base.h index f65c712a66..a6f3bc7d71 100644 --- a/indra/media_plugins/base/media_plugin_base.h +++ b/indra/media_plugins/base/media_plugin_base.h @@ -32,6 +32,41 @@ #include "llpluginmessage.h" #include "llpluginmessageclasses.h" +#if LL_LINUX || __FreeBSD__ + +struct SymbolToGrab +{ + bool mRequired; + char const *mName; + apr_dso_handle_sym_t *mPPFunc; +}; + +class SymbolGrabber +{ +public: + size_t registerSymbol( SymbolToGrab aSymbol ); + bool grabSymbols(std::vector< std::string > const &aDSONames); + void ungrabSymbols(); + +private: + std::vector< SymbolToGrab > gSymbolsToGrab; + + bool sSymsGrabbed = false; + apr_pool_t *sSymDSOMemoryPool = nullptr; + std::vector<apr_dso_handle_t *> sLoadedLibraries; +}; + +extern SymbolGrabber gSymbolGrabber; + +// extern SymbolGrabber gSymbolGrabber; + +#define LL_GRAB_SYM(SYMBOL_GRABBER, REQUIRED, SYMBOL_NAME, RETURN, ...) \ + RETURN (*ll##SYMBOL_NAME)(__VA_ARGS__) = nullptr; \ + size_t gRegistered##SYMBOL_NAME = SYMBOL_GRABBER.registerSymbol( \ + { REQUIRED, #SYMBOL_NAME , (apr_dso_handle_sym_t*)&ll##SYMBOL_NAME} \ + ); + +#endif class MediaPluginBase { @@ -46,7 +81,6 @@ public: static void staticReceiveMessage(const char *message_string, void **user_data); protected: - /** Plugin status. */ typedef enum { @@ -126,4 +160,7 @@ int init_media_plugin( LLPluginInstance::sendMessageFunction *plugin_send_func, void **plugin_user_data); - +#if LL_LINUX +pid_t getParentPid(pid_t aPid); +bool isPluginPid(pid_t aPid); +#endif diff --git a/indra/media_plugins/cef/CMakeLists.txt b/indra/media_plugins/cef/CMakeLists.txt index 0d1a833936..bf1e990450 100644 --- a/indra/media_plugins/cef/CMakeLists.txt +++ b/indra/media_plugins/cef/CMakeLists.txt @@ -10,18 +10,10 @@ include(Linking) include(PluginAPI) include(CEFPlugin) - +include(GLIB) ### media_plugin_cef -if(NOT ADDRESS_SIZE EQUAL 32) - if(WINDOWS) - ##add_definitions(/FIXED:NO) - else(WINDOWS) # not windows therefore gcc LINUX and DARWIN - add_definitions(-fPIC) - endif(WINDOWS) -endif(NOT ADDRESS_SIZE EQUAL 32) - set(media_plugin_cef_SOURCE_FILES media_plugin_cef.cpp ) @@ -32,10 +24,41 @@ set(media_plugin_cef_HEADER_FILES # Select which VolumeCatcher implementation to use if (LINUX) - message(FATAL_ERROR "CEF plugin has been enabled for a Linux compile.\n" - " Please create a volume_catcher implementation for this platform.") + foreach( PULSE_FILE pulse/introspect.h pulse/context.h pulse/subscribe.h pulse/glib-mainloop.h ) + find_path( PULSE_FILE_${PULSE_FILE}_FOUND ${PULSE_FILE} NO_CACHE) + if( NOT PULSE_FILE_${PULSE_FILE}_FOUND ) + message( "Looking for ${PULSE_FILE} ... not found") + message( FATAL_ERROR "Pulse header not found" ) + else() + message( "Looking for ${PULSE_FILE} ... found") + endif() + endforeach() + + include(FindPipeWire) + include_directories(SYSTEM ${PIPEWIRE_INCLUDE_DIRS} ${SPA_INCLUDE_DIRS}) + + message( "Building with Linux volume catcher for PipeWire and PulseAudio" ) + + list(APPEND media_plugin_cef_HEADER_FILES + linux/volume_catcher_linux.h + ) + + set(LINUX_VOLUME_CATCHER + linux/volume_catcher_linux.cpp + linux/volume_catcher_pulseaudio.cpp + linux/volume_catcher_pipewire.cpp + ) + + if (NOT (${LINUX_DISTRO} MATCHES debian OR (${LINUX_DISTRO} MATCHES ubuntu))) + message( "Building with Linux volume catcher for PulseAudio only and cancelling PipeWire" ) + list(REMOVE_ITEM LINUX_VOLUME_CATCHER linux/volume_catcher_pipewire.cpp) + endif () + + list(APPEND media_plugin_cef_SOURCE_FILES ${LINUX_VOLUME_CATCHER}) + set(CMAKE_SHARED_LINKER_FLAGS "-Wl,--build-id -Wl,-rpath,'$ORIGIN:$ORIGIN/../../lib'") + list(APPEND media_plugin_cef_LINK_LIBRARIES llwindow ) elseif (DARWIN) - list(APPEND media_plugin_cef_SOURCE_FILES mac_volume_catcher_null.cpp) + list(APPEND media_plugin_cef_SOURCE_FILES volume_catcher_null.cpp) find_library(CORESERVICES_LIBRARY CoreServices) find_library(AUDIOUNIT_LIBRARY AudioUnit) set( media_plugin_cef_LINK_LIBRARIES @@ -53,6 +76,10 @@ add_library(media_plugin_cef ${media_plugin_cef_SOURCE_FILES} ) +if (${LINUX_DISTRO} MATCHES debian OR (${LINUX_DISTRO} MATCHES ubuntu)) + target_compile_definitions(media_plugin_cef PRIVATE USE_VOLUME_CATCHER_PW=1) +endif () + #add_dependencies(media_plugin_cef # ${MEDIA_PLUGIN_BASE_LIBRARIES} #) @@ -60,6 +87,7 @@ add_library(media_plugin_cef target_link_libraries(media_plugin_cef media_plugin_base ll::cef + ll::glib_headers ) if (WINDOWS) @@ -84,9 +112,87 @@ if (DARWIN) add_custom_command(TARGET media_plugin_cef POST_BUILD COMMAND ${CMAKE_INSTALL_NAME_TOOL} -change "@executable_path/Chromium Embedded Framework" "@executable_path/../../../../Frameworks/Chromium Embedded Framework.framework/Chromium Embedded Framework" + -change "/opt/local/lib/libpng16.16.dylib" "@loader_path/../../Frameworks/libpng16.16.dylib" + -change "/opt/local/lib/libjpeg.8.dylib" "@loader_path/../../Frameworks/libjpeg.8.dylib" + -change "/opt/local/lib/libfreetype.6.dylib" "@loader_path/../../Frameworks/libfreetype.6.dylib" + -change "/opt/local/lib/libaprutil-1.0.dylib" "@loader_path/../../Frameworks/libaprutil-1.0.dylib" + -change "/opt/local/lib/libiconv.2.dylib" "@loader_path/../../Frameworks/libiconv.2.dylib" + -change "/opt/local/lib/libapr-1.0.dylib" "@loader_path/../../Frameworks/libapr-1.0.dylib" + -change "/opt/local/lib/libexpat.1.dylib" "@loader_path/../../Frameworks/libexpat.1.dylib" + -change "/opt/local/libexec/boost/1.87/lib/libboost_context-mt.dylib" "@loader_path/../../Frameworks/libboost_context-mt.dylib" + -change "/opt/local/libexec/boost/1.87/lib/libboost_fiber-mt.dylib" "@loader_path/../../Frameworks/libboost_fiber-mt.dylib" + -change "/opt/local/libexec/boost/1.87/lib/libboost_filesystem-mt.dylib" "@loader_path/../../Frameworks/libboost_filesystem-mt.dylib" + -change "/opt/local/libexec/boost/1.87/lib/libboost_program_options-mt.dylib" "@loader_path/../../Frameworks/libboost_program_options-mt.dylib" + -change "/opt/local/libexec/boost/1.87/lib/libboost_regex-mt.dylib" "@loader_path/../../Frameworks/libboost_regex-mt.dylib" + -change "/opt/local/libexec/boost/1.87/lib/libboost_system-mt.dylib" "@loader_path/../../Frameworks/libboost_system-mt.dylib" + -change "/opt/local/libexec/boost/1.87/lib/libboost_thread-mt.dylib" "@loader_path/../../Frameworks/libboost_thread-mt.dylib" + -change "/opt/local/libexec/boost/1.87/lib/libboost_url-mt.dylib" "@loader_path/../../Frameworks/libboost_url-mt.dylib" + -change "/opt/local/lib/libz.1.dylib" "@loader_path/../../Frameworks/libz.1.dylib" + -change "/opt/local/lib/libnghttp2.14.dylib" "@loader_path/../../Frameworks/libnghttp2.14.dylib" "$<TARGET_FILE:media_plugin_cef>" VERBATIM COMMENT "Fixing path to CEF Framework" ) endif (DARWIN) + +if (INSTALL) + if (DARWIN) + set(_LIB llplugin) + install( + DIRECTORY "${AUTOBUILD_INSTALL_DIR}/lib/release/Chromium Embedded Framework.framework" + DESTINATION ../Frameworks + ) + install( + DIRECTORY + "${AUTOBUILD_INSTALL_DIR}/lib/release/DullahanHelper.app" + "${AUTOBUILD_INSTALL_DIR}/lib/release/DullahanHelper (GPU).app" + "${AUTOBUILD_INSTALL_DIR}/lib/release/DullahanHelper (Plugin).app" + "${AUTOBUILD_INSTALL_DIR}/lib/release/DullahanHelper (Renderer).app" + DESTINATION SLPlugin.app/Contents/Frameworks + ) + elseif (LINUX) + if (${LINUX_DISTRO} MATCHES debian OR (${LINUX_DISTRO} MATCHES ubuntu)) + set(_LIB lib/${ARCH}-linux-gnu) + elseif (${LINUX_DISTRO} MATCHES fedora OR (${LINUX_DISTRO} MATCHES opensuse-tumbleweed) OR (${LINUX_DISTRO} MATCHES gentoo)) + set(_LIB lib${ADDRESS_SIZE}) + else () + set(_LIB lib) + endif () + if (${LINUX_DISTRO} MATCHES arch) + install( + PROGRAMS + ${AUTOBUILD_INSTALL_DIR}/bin/release/chrome-sandbox + ${AUTOBUILD_INSTALL_DIR}/bin/release/dullahan_host + DESTINATION lib/${VIEWER_BINARY_NAME} + #PERMISSIONS SETUID OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE + ) + else (${LINUX_DISTRO} MATCHES arch) + install( + PROGRAMS + ${AUTOBUILD_INSTALL_DIR}/bin/release/chrome-sandbox + ${AUTOBUILD_INSTALL_DIR}/bin/release/dullahan_host + DESTINATION libexec/${VIEWER_BINARY_NAME} + #PERMISSIONS SETUID OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE + ) + endif (${LINUX_DISTRO} MATCHES arch) + install( + FILES + ${AUTOBUILD_INSTALL_DIR}/lib/release/libcef.so + ${AUTOBUILD_INSTALL_DIR}/bin/release/snapshot_blob.bin + ${AUTOBUILD_INSTALL_DIR}/bin/release/v8_context_snapshot.bin + ${AUTOBUILD_INSTALL_DIR}/resources/chrome_100_percent.pak + ${AUTOBUILD_INSTALL_DIR}/resources/chrome_200_percent.pak + ${AUTOBUILD_INSTALL_DIR}/resources/icudtl.dat + ${AUTOBUILD_INSTALL_DIR}/resources/resources.pak + DESTINATION ${_LIB} + ) + install( + DIRECTORY ${AUTOBUILD_INSTALL_DIR}/resources/locales + DESTINATION ${_LIB} + ) + else (DARWIN) + set(_LIB lib) + endif (DARWIN) + install(TARGETS ${PROJECT_NAME} DESTINATION ${_LIB}) +endif (INSTALL) diff --git a/indra/media_plugins/cef/linux/volume_catcher_linux.cpp b/indra/media_plugins/cef/linux/volume_catcher_linux.cpp new file mode 100644 index 0000000000..ba2ed1aa56 --- /dev/null +++ b/indra/media_plugins/cef/linux/volume_catcher_linux.cpp @@ -0,0 +1,80 @@ +/** + * @file volume_catcher.cpp + * @brief Linux volume catcher which will pick an implementation to use + * + * @cond + * $LicenseInfo:firstyear=2010&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + * @endcond + */ + +#include "volume_catcher_linux.h" + +VolumeCatcher::VolumeCatcher() +{ +} + +void VolumeCatcher::onEnablePipeWireVolumeCatcher(bool enable) +{ + if (pimpl != nullptr) + return; + +#if USE_VOLUME_CATCHER_PW + if (enable) + { + LL_DEBUGS() << "volume catcher using pipewire" << LL_ENDL; + pimpl = new VolumeCatcherPipeWire(); + } + else +#endif + { + LL_DEBUGS() << "volume catcher using pulseaudio" << LL_ENDL; + pimpl = new VolumeCatcherPulseAudio(); + } +} + +VolumeCatcher::~VolumeCatcher() +{ + if (pimpl != nullptr) + { + delete pimpl; + pimpl = nullptr; + } +} + +void VolumeCatcher::setVolume(F32 volume) +{ + if (pimpl != nullptr) { + pimpl->setVolume(volume); + } +} + +void VolumeCatcher::setPan(F32 pan) +{ + if (pimpl != nullptr) + pimpl->setPan(pan); +} + +void VolumeCatcher::pump() +{ + if (pimpl != nullptr) + pimpl->pump(); +} diff --git a/indra/media_plugins/cef/linux/volume_catcher_linux.h b/indra/media_plugins/cef/linux/volume_catcher_linux.h new file mode 100644 index 0000000000..505f9ffb31 --- /dev/null +++ b/indra/media_plugins/cef/linux/volume_catcher_linux.h @@ -0,0 +1,149 @@ +/** + * @file volume_catcher_impl.h + * @brief + * + * @cond + * $LicenseInfo:firstyear=2010&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + * @endcond + */ + +#ifndef VOLUME_CATCHER_LINUX_H +#define VOLUME_CATCHER_LINUX_H + +#include "linden_common.h" + +#include "../volume_catcher.h" + +#include <unordered_set> +#include <mutex> + +extern "C" { +// There's no special reason why we want the *glib* PA mainloop, but the generic polling implementation seems broken. +#include <pulse/glib-mainloop.h> +#include <pulse/context.h> + +#include <pipewire/pipewire.h> + +#include "apr_pools.h" +#include "apr_dso.h" +} + +#include "media_plugin_base.h" + +class VolumeCatcherImpl +{ +public: + virtual ~VolumeCatcherImpl() = default; + + virtual void setVolume(F32 volume) = 0; // 0.0 - 1.0 + + // Set the left-right pan of audio sources + // where -1.0 = left, 0 = center, and 1.0 = right + virtual void setPan(F32 pan) = 0; + + virtual void pump() = 0; // call this at least a few times a second if you can - it affects how quickly we can 'catch' a new audio source and adjust its volume +}; + +class VolumeCatcherPulseAudio : public VolumeCatcherImpl +{ +public: + VolumeCatcherPulseAudio(); + ~VolumeCatcherPulseAudio(); + + void setVolume(F32 volume); + void setPan(F32 pan); + void pump(); + + // for internal use - can't be private because used from our C callbacks + + bool loadsyms(std::string pa_dso_name); + void init(); + void cleanup(); + + void update_all_volumes(F32 volume); + void update_index_volume(U32 index, F32 volume); + void connected_okay(); + + std::set<U32> mSinkInputIndices; + std::map<U32,U32> mSinkInputNumChannels; + F32 mDesiredVolume; + pa_glib_mainloop *mMainloop; + pa_context *mPAContext; + bool mConnected; + bool mGotSyms; +}; + +class VolumeCatcherPipeWire : public VolumeCatcherImpl +{ +public: + VolumeCatcherPipeWire(); + ~VolumeCatcherPipeWire(); + + bool loadsyms(std::string pw_dso_name); + void init(); + void cleanup(); + + // some of these should be private + + void lock(); + void unlock(); + + void setVolume(F32 volume); + void setPan(F32 pan); + void pump(); + + void handleRegistryEventGlobal( + uint32_t id, uint32_t permissions, const char* type, + uint32_t version, const struct spa_dict* props + ); + + class ChildNode + { + public: + bool mActive = false; + + pw_proxy* mProxy = nullptr; + spa_hook mNodeListener {}; + spa_hook mProxyListener {}; + VolumeCatcherPipeWire* mImpl = nullptr; + + void updateVolume(); + void destroy(); + }; + + bool mGotSyms = false; + + F32 mVolume = 1.0f; // max by default + // F32 mPan = 0.0f; // center + + pw_thread_loop* mThreadLoop = nullptr; + pw_context* mContext = nullptr; + pw_core* mCore = nullptr; + pw_registry* mRegistry = nullptr; + spa_hook mRegistryListener; + + std::unordered_set<ChildNode*> mChildNodes; + std::mutex mChildNodesMutex; + std::mutex mCleanupMutex; +}; + +#endif // VOLUME_CATCHER_LINUX_H diff --git a/indra/media_plugins/cef/linux/volume_catcher_pipewire.cpp b/indra/media_plugins/cef/linux/volume_catcher_pipewire.cpp new file mode 100755 index 0000000000..27fea547c9 --- /dev/null +++ b/indra/media_plugins/cef/linux/volume_catcher_pipewire.cpp @@ -0,0 +1,333 @@ +/** + * @file volume_catcher_pipewire.cpp + * @brief A Linux-specific, PipeWire-specific hack to detect and volume-adjust new audio sources + * + * @cond + * $LicenseInfo:firstyear=2010&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + * @endcond + */ + +/* + The high-level design is as follows: + 1) Connect to the PipeWire daemon + 2) Find all existing and new audio nodes + 3) Examine PID and parent PID's to see if it belongs to our process + 4) If so, tell PipeWire to adjust the volume of that node + 5) Keep a list of all audio nodes and adjust when we setVolume() + */ + +#include "linden_common.h" + +#include "volume_catcher_linux.h" + +extern "C" { +#include <spa/pod/builder.h> +#include <spa/param/props.h> +} + +SymbolGrabber pwSymbolGrabber; + +#include "volume_catcher_pipewire_syms.inc" + +//////////////////////////////////////////////////// + +VolumeCatcherPipeWire::VolumeCatcherPipeWire() +{ + init(); +} + +VolumeCatcherPipeWire::~VolumeCatcherPipeWire() +{ + cleanup(); +} + +static void registryEventGlobal( + void *data, uint32_t id, uint32_t permissions, const char *type, + uint32_t version, const struct spa_dict *props) +{ + static_cast<VolumeCatcherPipeWire*>(data)->handleRegistryEventGlobal( + id, permissions, type, version, props + ); +} + +static const struct pw_registry_events REGISTRY_EVENTS = { + .version = PW_VERSION_REGISTRY_EVENTS, + .global = registryEventGlobal, +}; + +bool VolumeCatcherPipeWire::loadsyms(std::string pw_dso_name) +{ + return pwSymbolGrabber.grabSymbols({ pw_dso_name }); +} + +void VolumeCatcherPipeWire::init() +{ + LL_DEBUGS() << "init" << LL_ENDL; + + mGotSyms = loadsyms("libpipewire-0.3.so.0"); + + if (!mGotSyms) + return; + + LL_DEBUGS() << "successfully got symbols" << LL_ENDL; + + llpw_init(nullptr, nullptr); + + mThreadLoop = llpw_thread_loop_new("SL Plugin Volume Adjuster", nullptr); + + if (!mThreadLoop) + return; + + // i dont think we need to lock this early + // std::lock_guard pwLock(*this); + + mContext = llpw_context_new( + llpw_thread_loop_get_loop(mThreadLoop), nullptr, 0 + ); + + if (!mContext) + return; + + mCore = llpw_context_connect(mContext, nullptr, 0); + + if (!mCore) + return; + + mRegistry = pw_core_get_registry(mCore, PW_VERSION_REGISTRY, 0); + + LL_DEBUGS() << "pw_core_get_registry: " << (mRegistry?"success":"nullptr") << LL_ENDL; + + spa_zero(mRegistryListener); + + pw_registry_add_listener( + mRegistry, &mRegistryListener, ®ISTRY_EVENTS, this + ); + + llpw_thread_loop_start(mThreadLoop); + + LL_DEBUGS() << "thread loop started" << LL_ENDL; +} + +void VolumeCatcherPipeWire::cleanup() +{ + { + std::unique_lock childNodesLock(mChildNodesMutex); + for (auto *childNode: mChildNodes) + childNode->destroy(); + + mChildNodes.clear(); + } + + { + std::unique_lock pwLock(mCleanupMutex); + if (mRegistry) + llpw_proxy_destroy((struct pw_proxy *) mRegistry); + + spa_zero(mRegistryListener); + + if (mCore) + llpw_core_disconnect(mCore); + if (mContext) + llpw_context_destroy(mContext); + } + + if (!mThreadLoop) + return; + + llpw_thread_loop_stop(mThreadLoop); + llpw_thread_loop_destroy(mThreadLoop); + + LL_DEBUGS() << "cleanup done" << LL_ENDL; +} + +void VolumeCatcherPipeWire::lock() +{ + if (!mThreadLoop) + return; + + llpw_thread_loop_lock(mThreadLoop); +} + +void VolumeCatcherPipeWire::unlock() +{ + if (!mThreadLoop) + return; + + llpw_thread_loop_unlock(mThreadLoop); +} + +const uint32_t channels = 1; +const float resetVolumes[channels] = { 1.0f }; + +void VolumeCatcherPipeWire::ChildNode::updateVolume() +{ + if (!mActive) + return; + + F32 volume = std::clamp(mImpl->mVolume, 0.0f, 1.0f); + + const float volumes[channels] = { volume }; + + uint8_t buffer[512]; + + spa_pod_builder builder; + spa_pod_builder_init(&builder, buffer, sizeof(buffer)); + + spa_pod_frame frame; + spa_pod_builder_push_object(&builder, &frame, SPA_TYPE_OBJECT_Props, SPA_PARAM_Props); + + // resets system-wide memorized volume for chromium (not google chrome) to 100% + spa_pod_builder_prop(&builder, SPA_PROP_channelVolumes, 0); + spa_pod_builder_array(&builder, sizeof(float), SPA_TYPE_Float, channels, resetVolumes); + + // sets temporary volume + spa_pod_builder_prop(&builder, SPA_PROP_softVolumes, 0); + spa_pod_builder_array(&builder, sizeof(float), SPA_TYPE_Float, channels, volumes); + + spa_pod* pod = static_cast<spa_pod*>(spa_pod_builder_pop(&builder, &frame)); + + { + std::lock_guard pwLock(*mImpl); + pw_node_set_param(mProxy, SPA_PARAM_Props, 0, pod); + } +} + +void VolumeCatcherPipeWire::ChildNode::destroy() +{ + if (!mActive) + return; + + mActive = false; + + { + std::unique_lock childNodesLock(mImpl->mChildNodesMutex); + mImpl->mChildNodes.erase(this); + } + + spa_hook_remove(&mNodeListener); + spa_hook_remove(&mProxyListener); + + { + std::lock_guard pwLock(*mImpl); + llpw_proxy_destroy(mProxy); + } +} + +static void nodeEventInfo(void* data, const struct pw_node_info* info) +{ + const char* processId = spa_dict_lookup(info->props, PW_KEY_APP_PROCESS_ID); + + if (processId == nullptr) + return; + + pid_t pid = atoll(processId); + + if (!isPluginPid(pid)) + return; + + const char* appName = spa_dict_lookup(info->props, PW_KEY_APP_NAME); + LL_DEBUGS() << "got app: " << appName << LL_ENDL; + + auto* const childNode = static_cast<VolumeCatcherPipeWire::ChildNode*>(data); + LL_DEBUGS() << "init volume: " << childNode->mImpl->mVolume << LL_ENDL; + + childNode->updateVolume(); + + { + std::lock_guard childNodesLock(childNode->mImpl->mChildNodesMutex); + childNode->mImpl->mChildNodes.insert(childNode); + } +} + +static const struct pw_node_events NODE_EVENTS = { + .version = PW_VERSION_CLIENT_EVENTS, + .info = nodeEventInfo, +}; + +static void proxyEventDestroy(void* data) +{ + auto* const childNode = static_cast<VolumeCatcherPipeWire::ChildNode*>(data); + childNode->destroy(); +} + +static void proxyEventRemoved(void* data) +{ + auto* const childNode = static_cast<VolumeCatcherPipeWire::ChildNode*>(data); + childNode->destroy(); +} + +static const struct pw_proxy_events PROXY_EVENTS = { + .version = PW_VERSION_PROXY_EVENTS, + .destroy = proxyEventDestroy, + .removed = proxyEventRemoved, +}; + +void VolumeCatcherPipeWire::handleRegistryEventGlobal( + uint32_t id, uint32_t permissions, const char *type, uint32_t version, + const struct spa_dict *props) +{ + if (props == nullptr || type == nullptr || strcmp(type, PW_TYPE_INTERFACE_Node) != 0) + return; + + const char* mediaClass = spa_dict_lookup(props, PW_KEY_MEDIA_CLASS); + + if (mediaClass == nullptr || strcmp(mediaClass, "Stream/Output/Audio") != 0) + return; + + pw_proxy* proxy = static_cast<pw_proxy*>( + pw_registry_bind(mRegistry, id, type, PW_VERSION_CLIENT, sizeof(ChildNode)) + ); + + auto* const childNode = static_cast<ChildNode*>(llpw_proxy_get_user_data(proxy)); + + childNode->mActive = true; + childNode->mProxy = proxy; + childNode->mImpl = this; + + pw_node_add_listener(proxy, &childNode->mNodeListener, &NODE_EVENTS, childNode); + llpw_proxy_add_listener(proxy, &childNode->mProxyListener, &PROXY_EVENTS, childNode); +} + +void VolumeCatcherPipeWire::setVolume(F32 volume) +{ + LL_DEBUGS() << "setting volume to: " << volume << LL_ENDL; + + mVolume = volume; + + { + std::unique_lock childNodeslock(mChildNodesMutex); + std::unordered_set<ChildNode *> copyOfChildNodes(mChildNodes); + + LL_DEBUGS() << "found " << copyOfChildNodes.size() << " child nodes" << LL_ENDL; + + for (auto* childNode : copyOfChildNodes) + childNode->updateVolume(); + } +} + +void VolumeCatcherPipeWire::setPan(F32 pan) +{ +} + +void VolumeCatcherPipeWire::pump() +{ +} diff --git a/indra/media_plugins/cef/linux/volume_catcher_pipewire_syms.inc b/indra/media_plugins/cef/linux/volume_catcher_pipewire_syms.inc new file mode 100644 index 0000000000..dbc0f5f169 --- /dev/null +++ b/indra/media_plugins/cef/linux/volume_catcher_pipewire_syms.inc @@ -0,0 +1,26 @@ +#define G pwSymbolGrabber + +// required symbols to grab +LL_GRAB_SYM(G, true, pw_init, void, int *argc, char **argv[]); +// LL_GRAB_SYM(G, true, pw_main_loop_new, struct pw_main_loop *, const struct spa_dict *props); +// LL_GRAB_SYM(G, true, pw_main_loop_get_loop, struct pw_loop *, struct pw_main_loop *loop); +// LL_GRAB_SYM(G, true, pw_main_loop_destroy, void, struct pw_main_loop *loop); +// LL_GRAB_SYM(G, true, pw_main_loop_run, void, struct pw_main_loop *loop); +LL_GRAB_SYM(G, true, pw_context_new, struct pw_context *, struct pw_loop *main_loop, struct pw_properties *props, size_t user_data_size); +LL_GRAB_SYM(G, true, pw_context_destroy, void, struct pw_context *context); +LL_GRAB_SYM(G, true, pw_context_connect, struct pw_core *, struct pw_context *context, struct pw_properties *properties, size_t user_data_size); +LL_GRAB_SYM(G, true, pw_thread_loop_new, struct pw_thread_loop *, const char *name, const struct spa_dict *props); +LL_GRAB_SYM(G, true, pw_thread_loop_destroy, void, struct pw_thread_loop *loop); +LL_GRAB_SYM(G, true, pw_thread_loop_get_loop, struct pw_loop *, struct pw_thread_loop *loop); +LL_GRAB_SYM(G, true, pw_thread_loop_start, int, struct pw_thread_loop *loop); +LL_GRAB_SYM(G, true, pw_thread_loop_stop, void, struct pw_thread_loop *loop); +LL_GRAB_SYM(G, true, pw_thread_loop_lock, void, struct pw_thread_loop *loop); +LL_GRAB_SYM(G, true, pw_thread_loop_unlock, void, struct pw_thread_loop *loop); +LL_GRAB_SYM(G, true, pw_proxy_add_listener, void, struct pw_proxy *proxy, struct spa_hook *listener, const struct pw_proxy_events *events, void *data); +LL_GRAB_SYM(G, true, pw_proxy_destroy, void, struct pw_proxy *proxy); +LL_GRAB_SYM(G, true, pw_proxy_get_user_data, void *, struct pw_proxy *proxy); +LL_GRAB_SYM(G, true, pw_core_disconnect, int, struct pw_core *core); + +// optional symbols to grab + +#undef G diff --git a/indra/media_plugins/cef/linux/volume_catcher_pulseaudio.cpp b/indra/media_plugins/cef/linux/volume_catcher_pulseaudio.cpp new file mode 100755 index 0000000000..9417c49d38 --- /dev/null +++ b/indra/media_plugins/cef/linux/volume_catcher_pulseaudio.cpp @@ -0,0 +1,322 @@ +/** + * @file volume_catcher_pulseaudio.cpp + * @brief A Linux-specific, PulseAudio-specific hack to detect and volume-adjust new audio sources + * + * @cond + * $LicenseInfo:firstyear=2010&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + * @endcond + */ + +/* + The high-level design is as follows: + 1) Connect to the PulseAudio daemon + 2) Watch for the creation of new audio players connecting to the daemon (this includes ALSA clients running on the PulseAudio emulation layer, such as Flash plugins) + 3) Examine any new audio player's PID to see if it belongs to our own process + 4) If so, tell PA to adjust the volume of that audio player ('sink input' in PA parlance) + 5) Keep a list of all living audio players that we care about, adjust the volumes of all of them when we get a new setVolume() call + */ + +#include "linden_common.h" + +#include "volume_catcher_linux.h" + +extern "C" { +#include <glib.h> +#include <glib-object.h> + +#include <pulse/introspect.h> + +#include <pulse/subscribe.h> +} + +SymbolGrabber paSymbolGrabber; + +#include "volume_catcher_pulseaudio_syms.inc" +#include "volume_catcher_pulseaudio_glib_syms.inc" + +//////////////////////////////////////////////////// + +// PulseAudio requires a chain of callbacks with C linkage +extern "C" { + void callback_discovered_sinkinput(pa_context *context, const pa_sink_input_info *i, int eol, void *userdata); + void callback_subscription_alert(pa_context *context, pa_subscription_event_type_t t, uint32_t index, void *userdata); + void callback_context_state(pa_context *context, void *userdata); +} + +VolumeCatcherPulseAudio::VolumeCatcherPulseAudio() + : mDesiredVolume(0.0f), + mMainloop(nullptr), + mPAContext(nullptr), + mConnected(false), + mGotSyms(false) +{ + init(); +} + +VolumeCatcherPulseAudio::~VolumeCatcherPulseAudio() +{ + cleanup(); +} + +bool VolumeCatcherPulseAudio::loadsyms(std::string pulse_dso_name) +{ + return paSymbolGrabber.grabSymbols({ pulse_dso_name }); +} + +void VolumeCatcherPulseAudio::init() +{ + // try to be as defensive as possible because PA's interface is a + // bit fragile and (for our purposes) we'd rather simply not function + // than crash + + // we cheat and rely upon libpulse-mainloop-glib.so.0 to pull-in + // libpulse.so.0 - this isn't a great assumption, and the two DSOs should + // probably be loaded separately. Our Linux DSO framework needs refactoring, + // we do this sort of thing a lot with practically identical logic... + mGotSyms = loadsyms("libpulse-mainloop-glib.so.0"); + + if (!mGotSyms) + mGotSyms = loadsyms("libpulse.so.0"); + + if (!mGotSyms) + return; + + mMainloop = llpa_glib_mainloop_new(g_main_context_default()); + + if (mMainloop) + { + pa_mainloop_api *api = llpa_glib_mainloop_get_api(mMainloop); + + if (api) + { + pa_proplist *proplist = llpa_proplist_new(); + + if (proplist) + { + llpa_proplist_sets(proplist, PA_PROP_APPLICATION_ICON_NAME, "multimedia-player"); + llpa_proplist_sets(proplist, PA_PROP_APPLICATION_ID, "com.secondlife.viewer.mediaplugvoladjust"); + llpa_proplist_sets(proplist, PA_PROP_APPLICATION_NAME, "SL Plugin Volume Adjuster"); + llpa_proplist_sets(proplist, PA_PROP_APPLICATION_VERSION, "1"); + + // plain old pa_context_new() is broken! + mPAContext = llpa_context_new_with_proplist(api, nullptr, proplist); + + llpa_proplist_free(proplist); + } + } + } + + // Now we've set up a PA context and mainloop, try connecting the + // PA context to a PA daemon. + if (mPAContext) + { + llpa_context_set_state_callback(mPAContext, callback_context_state, this); + pa_context_flags_t cflags = (pa_context_flags)0; // maybe add PA_CONTEXT_NOAUTOSPAWN? + if (llpa_context_connect(mPAContext, nullptr, cflags, nullptr) >= 0) + { + // Okay! We haven't definitely connected, but we + // haven't definitely failed yet. + } + else + { + // Failed to connect to PA manager... we'll leave + // things like that. Perhaps we should try again later. + } + } +} + +void VolumeCatcherPulseAudio::cleanup() +{ + mConnected = false; + + if (mGotSyms && mPAContext) + { + llpa_context_disconnect(mPAContext); + llpa_context_unref(mPAContext); + } + + mPAContext = nullptr; + + if (mGotSyms && mMainloop) + llpa_glib_mainloop_free(mMainloop); + + mMainloop = nullptr; +} + +void VolumeCatcherPulseAudio::setVolume(F32 volume) +{ + mDesiredVolume = volume; + + if (!mGotSyms) + return; + + if (mConnected && mPAContext) + { + update_all_volumes(mDesiredVolume); + } + + pump(); +} + +void VolumeCatcherPulseAudio::setPan(F32 pan) +{ +} + +void VolumeCatcherPulseAudio::pump() +{ + gboolean may_block = FALSE; + g_main_context_iteration(g_main_context_default(), may_block); +} + +void VolumeCatcherPulseAudio::connected_okay() +{ + pa_operation *op; + + // fetch global list of existing sinkinputs + if ((op = llpa_context_get_sink_input_info_list(mPAContext, + callback_discovered_sinkinput, + this))) + { + llpa_operation_unref(op); + } + + // subscribe to future global sinkinput changes + llpa_context_set_subscribe_callback(mPAContext, + callback_subscription_alert, + this); + if ((op = llpa_context_subscribe(mPAContext, (pa_subscription_mask_t) + (PA_SUBSCRIPTION_MASK_SINK_INPUT), + nullptr, nullptr))) + { + llpa_operation_unref(op); + } +} + +void VolumeCatcherPulseAudio::update_all_volumes(F32 volume) +{ + for (std::set<U32>::iterator it = mSinkInputIndices.begin(); + it != mSinkInputIndices.end(); ++it) + { + update_index_volume(*it, volume); + } +} + +void VolumeCatcherPulseAudio::update_index_volume(U32 index, F32 volume) +{ + static pa_cvolume cvol; + llpa_cvolume_set(&cvol, mSinkInputNumChannels[index], + llpa_sw_volume_from_linear(volume)); + + pa_context *c = mPAContext; + uint32_t idx = index; + const pa_cvolume *cvolumep = &cvol; + pa_context_success_cb_t cb = nullptr; // okay as null + void *userdata = nullptr; // okay as null + + pa_operation *op; + if ((op = llpa_context_set_sink_input_volume(c, idx, cvolumep, cb, userdata))) + llpa_operation_unref(op); +} + +void callback_discovered_sinkinput(pa_context *context, const pa_sink_input_info *sii, int eol, void *userdata) +{ + VolumeCatcherPulseAudio *impl = dynamic_cast<VolumeCatcherPulseAudio*>((VolumeCatcherPulseAudio*)userdata); + llassert(impl); + + if (0 == eol) + { + pa_proplist *proplist = sii->proplist; + pid_t sinkpid = atoll(llpa_proplist_gets(proplist, PA_PROP_APPLICATION_PROCESS_ID)); + + if (isPluginPid( sinkpid )) // does the discovered sinkinput belong to this process? + { + bool is_new = (impl->mSinkInputIndices.find(sii->index) == impl->mSinkInputIndices.end()); + + impl->mSinkInputIndices.insert(sii->index); + impl->mSinkInputNumChannels[sii->index] = sii->channel_map.channels; + + if (is_new) + { + // new! + impl->update_index_volume(sii->index, impl->mDesiredVolume); + } + else + { + // seen it already, do nothing. + } + } + } +} + +void callback_subscription_alert(pa_context *context, pa_subscription_event_type_t t, uint32_t index, void *userdata) +{ + VolumeCatcherPulseAudio *impl = dynamic_cast<VolumeCatcherPulseAudio*>((VolumeCatcherPulseAudio*)userdata); + llassert(impl); + + switch (t & PA_SUBSCRIPTION_EVENT_FACILITY_MASK) + { + case PA_SUBSCRIPTION_EVENT_SINK_INPUT: + if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_REMOVE) + { + // forget this sinkinput, if we were caring about it + impl->mSinkInputIndices.erase(index); + impl->mSinkInputNumChannels.erase(index); + } + else if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_NEW) + { + // ask for more info about this new sinkinput + pa_operation *op; + if ((op = llpa_context_get_sink_input_info(impl->mPAContext, index, callback_discovered_sinkinput, impl))) + { + llpa_operation_unref(op); + } + } + else + { + // property change on this sinkinput - we don't care. + } + break; + + default:; + } +} + +void callback_context_state(pa_context *context, void *userdata) +{ + VolumeCatcherPulseAudio *impl = dynamic_cast<VolumeCatcherPulseAudio*>((VolumeCatcherPulseAudio*)userdata); + llassert(impl); + + switch (llpa_context_get_state(context)) + { + case PA_CONTEXT_READY: + impl->mConnected = true; + impl->connected_okay(); + break; + case PA_CONTEXT_TERMINATED: + impl->mConnected = false; + break; + case PA_CONTEXT_FAILED: + impl->mConnected = false; + break; + default:; + } +} diff --git a/indra/media_plugins/cef/linux/volume_catcher_pulseaudio_glib_syms.inc b/indra/media_plugins/cef/linux/volume_catcher_pulseaudio_glib_syms.inc new file mode 100755 index 0000000000..e9b7196e51 --- /dev/null +++ b/indra/media_plugins/cef/linux/volume_catcher_pulseaudio_glib_syms.inc @@ -0,0 +1,10 @@ +#define G paSymbolGrabber + +// required symbols to grab +LL_GRAB_SYM(G, true, pa_glib_mainloop_free, void, pa_glib_mainloop* g) +LL_GRAB_SYM(G, true, pa_glib_mainloop_get_api, pa_mainloop_api*, pa_glib_mainloop* g) +LL_GRAB_SYM(G, true, pa_glib_mainloop_new, pa_glib_mainloop *, GMainContext *c) + +// optional symbols to grab + +#undef G diff --git a/indra/media_plugins/cef/linux/volume_catcher_pulseaudio_syms.inc b/indra/media_plugins/cef/linux/volume_catcher_pulseaudio_syms.inc new file mode 100755 index 0000000000..4859a34405 --- /dev/null +++ b/indra/media_plugins/cef/linux/volume_catcher_pulseaudio_syms.inc @@ -0,0 +1,29 @@ +#define G paSymbolGrabber + +// required symbols to grab +LL_GRAB_SYM(G, true, pa_context_connect, int, pa_context *c, const char *server, pa_context_flags_t flags, const pa_spawn_api *api) +LL_GRAB_SYM(G, true, pa_context_disconnect, void, pa_context *c) +LL_GRAB_SYM(G, true, pa_context_get_sink_input_info, pa_operation*, pa_context *c, uint32_t idx, pa_sink_input_info_cb_t cb, void *userdata) +LL_GRAB_SYM(G, true, pa_context_get_sink_input_info_list, pa_operation*, pa_context *c, pa_sink_input_info_cb_t cb, void *userdata) +LL_GRAB_SYM(G, true, pa_context_get_state, pa_context_state_t, pa_context *c) +LL_GRAB_SYM(G, true, pa_context_new_with_proplist, pa_context*, pa_mainloop_api *mainloop, const char *name, pa_proplist *proplist) +LL_GRAB_SYM(G, true, pa_context_set_sink_input_volume, pa_operation*, pa_context *c, uint32_t idx, const pa_cvolume *volume, pa_context_success_cb_t cb, void *userdata) +LL_GRAB_SYM(G, true, pa_context_set_state_callback, void, pa_context *c, pa_context_notify_cb_t cb, void *userdata) +LL_GRAB_SYM(G, true, pa_context_set_subscribe_callback, void, pa_context *c, pa_context_subscribe_cb_t cb, void *userdata) +LL_GRAB_SYM(G, true, pa_context_subscribe, pa_operation*, pa_context *c, pa_subscription_mask_t m, pa_context_success_cb_t cb, void *userdata) +LL_GRAB_SYM(G, true, pa_context_unref, void, pa_context *c) +LL_GRAB_SYM(G, true, pa_cvolume_set, pa_cvolume*, pa_cvolume *a, unsigned channels, pa_volume_t v) +LL_GRAB_SYM(G, true, pa_operation_unref, void, pa_operation *o) +LL_GRAB_SYM(G, true, pa_proplist_free, void, pa_proplist* p) +LL_GRAB_SYM(G, true, pa_proplist_gets, const char*, pa_proplist *p, const char *key) +LL_GRAB_SYM(G, true, pa_proplist_new, pa_proplist*, void) +LL_GRAB_SYM(G, true, pa_proplist_sets, int, pa_proplist *p, const char *key, const char *value) +LL_GRAB_SYM(G, true, pa_sw_volume_from_linear, pa_volume_t, double v) +// LL_GRAB_SYM(G, true, pa_mainloop_free, void, pa_mainloop *m) +// LL_GRAB_SYM(G, true, pa_mainloop_get_api, pa_mainloop_api *, pa_mainloop *m) +// LL_GRAB_SYM(G, true, pa_mainloop_iterate, int, pa_mainloop *m, int block, int *retval) +// LL_GRAB_SYM(G, true, pa_mainloop_new, pa_mainloop *, void) + +// optional symbols to grab + +#undef G diff --git a/indra/media_plugins/cef/media_plugin_cef.cpp b/indra/media_plugins/cef/media_plugin_cef.cpp index 64fc7e452b..9c205b558c 100644 --- a/indra/media_plugins/cef/media_plugin_cef.cpp +++ b/indra/media_plugins/cef/media_plugin_cef.cpp @@ -886,7 +886,7 @@ void MediaPluginCEF::receiveMessage(const char* message_string) keyEvent(key_event, native_key_data); -#elif LL_WINDOWS +#else std::string event = message_in.getValue("event"); LLSD native_key_data = message_in.getValueLLSD("native_key_data"); @@ -908,6 +908,13 @@ void MediaPluginCEF::receiveMessage(const char* message_string) { mEnableMediaPluginDebugging = message_in.getValueBoolean("enable"); } +#if LL_LINUX + else if (message_name == "enable_pipewire_volume_catcher") + { + bool enable = message_in.getValueBoolean("enable"); + mVolumeCatcher.onEnablePipeWireVolumeCatcher(enable); + } +#endif if (message_name == "pick_file_response") { LLSD file_list_llsd = message_in.getValueLLSD("file_list"); @@ -1050,6 +1057,28 @@ void MediaPluginCEF::keyEvent(dullahan::EKeyEvent key_event, LLSD native_key_dat mCEFLib->nativeKeyboardEventWin(msg, wparam, lparam); #endif + +#if LL_LINUX + + uint32_t native_virtual_key = (uint32_t)(native_key_data["virtual_key"].asInteger()); // this is actually the SDL event.key.keysym.sym; + uint32_t native_virtual_key_win = (uint32_t)(native_key_data["virtual_key_win"].asInteger()); + uint32_t native_modifiers = (uint32_t)(native_key_data["modifiers"].asInteger()); + + // only for non-printable keysyms, the actual text input is done in unicodeInput() below + if (native_virtual_key <= 0x1b || native_virtual_key >= 0x7f) + { + // set keypad flag, not sure if this even does anything + bool keypad = false; + if (native_virtual_key_win >= 0x60 && native_virtual_key_win <= 0x6f) + { + keypad = true; + } + + // yes, we send native_virtual_key_win twice because native_virtual_key breaks it + mCEFLib->nativeKeyboardEventSDL2(key_event, native_virtual_key, native_modifiers, keypad); + } + +#endif // LL_LINUX }; void MediaPluginCEF::unicodeInput(std::string event, LLSD native_key_data = LLSD::emptyMap()) @@ -1080,6 +1109,16 @@ void MediaPluginCEF::unicodeInput(std::string event, LLSD native_key_data = LLSD U64 lparam = ll_U32_from_sd(native_key_data["l_param"]); mCEFLib->nativeKeyboardEventWin(msg, wparam, lparam); #endif + +#if LL_LINUX + + uint32_t native_scan_code = (uint32_t)(native_key_data["sdl_sym"].asInteger()); + uint32_t native_virtual_key = (uint32_t)(native_key_data["virtual_key"].asInteger()); + uint32_t native_modifiers = (uint32_t)(native_key_data["modifiers"].asInteger()); + + mCEFLib->nativeKeyboardEvent(dullahan::KE_KEY_DOWN, native_scan_code, native_virtual_key, native_modifiers); + +#endif // LL_LINUX }; //////////////////////////////////////////////////////////////////////////////// diff --git a/indra/media_plugins/cef/volume_catcher.h b/indra/media_plugins/cef/volume_catcher.h index ea97a24947..6933854e8e 100644 --- a/indra/media_plugins/cef/volume_catcher.h +++ b/indra/media_plugins/cef/volume_catcher.h @@ -35,19 +35,20 @@ class VolumeCatcherImpl; class VolumeCatcher { - public: +public: VolumeCatcher(); ~VolumeCatcher(); - void setVolume(F32 volume); // 0.0 - 1.0 - - // Set the left-right pan of audio sources - // where -1.0 = left, 0 = center, and 1.0 = right + void setVolume(F32 volume); void setPan(F32 pan); - void pump(); // call this at least a few times a second if you can - it affects how quickly we can 'catch' a new audio source and adjust its volume + void pump(); + +#if LL_LINUX + void onEnablePipeWireVolumeCatcher(bool enable); +#endif - private: +private: VolumeCatcherImpl *pimpl; }; diff --git a/indra/media_plugins/cef/mac_volume_catcher_null.cpp b/indra/media_plugins/cef/volume_catcher_null.cpp index c479e24a95..c6028da45b 100644 --- a/indra/media_plugins/cef/mac_volume_catcher_null.cpp +++ b/indra/media_plugins/cef/volume_catcher_null.cpp @@ -1,5 +1,5 @@ -/** - * @file windows_volume_catcher.cpp +/** + * @file volume_catcher_null.cpp * @brief A null implementation of volume level control of all audio channels opened by a process. * We are using this for the macOS version for now until we can understand how to make the * exitising mac_volume_catcher.cpp work without the (now, non-existant) QuickTime dependency @@ -29,67 +29,25 @@ */ #include "volume_catcher.h" -#include "llsingleton.h" -class VolumeCatcherImpl : public LLSingleton<VolumeCatcherImpl> -{ - LLSINGLETON(VolumeCatcherImpl); - // This is a singleton class -- both callers and the component implementation should use getInstance() to find the instance. - ~VolumeCatcherImpl(); - -public: - - void setVolume(F32 volume); - void setPan(F32 pan); - -private: - F32 mVolume; - F32 mPan; - bool mSystemIsVistaOrHigher; -}; - -VolumeCatcherImpl::VolumeCatcherImpl() -: mVolume(1.0f), // default volume is max - mPan(0.f) // default pan is centered -{ -} - -VolumeCatcherImpl::~VolumeCatcherImpl() -{ -} - -void VolumeCatcherImpl::setVolume(F32 volume) -{ - mVolume = volume; -} - -void VolumeCatcherImpl::setPan(F32 pan) -{ // remember pan for calculating individual channel levels later - mPan = pan; -} ///////////////////////////////////////////////////// VolumeCatcher::VolumeCatcher() { - pimpl = VolumeCatcherImpl::getInstance(); } VolumeCatcher::~VolumeCatcher() { - // Let the instance persist until exit. } void VolumeCatcher::setVolume(F32 volume) { - pimpl->setVolume(volume); } void VolumeCatcher::setPan(F32 pan) { - pimpl->setPan(pan); } void VolumeCatcher::pump() { - // No periodic tasks are necessary for this implementation. } diff --git a/indra/media_plugins/cef/windows_volume_catcher.cpp b/indra/media_plugins/cef/windows_volume_catcher.cpp index e7daeb5f74..1e52fee9de 100644 --- a/indra/media_plugins/cef/windows_volume_catcher.cpp +++ b/indra/media_plugins/cef/windows_volume_catcher.cpp @@ -44,7 +44,6 @@ public: private: F32 mVolume; F32 mPan; - bool mSystemIsVistaOrHigher; }; VolumeCatcherImpl::VolumeCatcherImpl() diff --git a/indra/media_plugins/example/CMakeLists.txt b/indra/media_plugins/example/CMakeLists.txt index 41e2353f31..71343d5f85 100644 --- a/indra/media_plugins/example/CMakeLists.txt +++ b/indra/media_plugins/example/CMakeLists.txt @@ -13,14 +13,6 @@ include(ExamplePlugin) ### media_plugin_example -if(NOT ADDRESS_SIZE EQUAL 32) - if(WINDOWS) - ##add_definitions(/FIXED:NO) - else(WINDOWS) # not windows therefore gcc LINUX and DARWIN - add_definitions(-fPIC) - endif(WINDOWS) -endif(NOT ADDRESS_SIZE EQUAL 32) - set(media_plugin_example_SOURCE_FILES media_plugin_example.cpp ) diff --git a/indra/media_plugins/gstreamer010/CMakeLists.txt b/indra/media_plugins/gstreamer010/CMakeLists.txt deleted file mode 100644 index 38fc8201bf..0000000000 --- a/indra/media_plugins/gstreamer010/CMakeLists.txt +++ /dev/null @@ -1,46 +0,0 @@ -# -*- cmake -*- - -project(media_plugin_gstreamer010) - -include(00-Common) -include(LLCommon) -include(LLImage) -include(LLMath) -include(LLWindow) -include(Linking) -include(PluginAPI) -include(OpenGL) - -include(GStreamer010Plugin) - -### media_plugin_gstreamer010 - -if(NOT ADDRESS_SIZE EQUAL 32) - if(WINDOWS) - ##add_definitions(/FIXED:NO) - else(WINDOWS) # not windows therefore gcc LINUX and DARWIN - add_definitions(-fPIC) - endif(WINDOWS) -endif(NOT ADDRESS_SIZE EQUAL 32) - -set(media_plugin_gstreamer010_SOURCE_FILES - media_plugin_gstreamer010.cpp - llmediaimplgstreamer_syms.cpp - llmediaimplgstreamervidplug.cpp - ) - -set(media_plugin_gstreamer010_HEADER_FILES - llmediaimplgstreamervidplug.h - llmediaimplgstreamer_syms.h - llmediaimplgstreamertriviallogging.h - ) - -add_library(media_plugin_gstreamer010 - SHARED - ${media_plugin_gstreamer010_SOURCE_FILES} - ) - -target_link_libraries(media_plugin_gstreamer010 - media_plugin_base - ll::gstreamer - ) diff --git a/indra/media_plugins/gstreamer010/llmediaimplgstreamer_syms.cpp b/indra/media_plugins/gstreamer010/llmediaimplgstreamer_syms.cpp deleted file mode 100644 index dcc04b37e4..0000000000 --- a/indra/media_plugins/gstreamer010/llmediaimplgstreamer_syms.cpp +++ /dev/null @@ -1,167 +0,0 @@ -/** - * @file llmediaimplgstreamer_syms.cpp - * @brief dynamic GStreamer symbol-grabbing code - * - * @cond - * $LicenseInfo:firstyear=2007&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 of the License only. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA - * $/LicenseInfo$ - * @endcond - */ - -#if LL_GSTREAMER010_ENABLED - -#include <string> - -extern "C" { -#include <gst/gst.h> - -#include "apr_pools.h" -#include "apr_dso.h" -} - -#include "llmediaimplgstreamertriviallogging.h" - -#define LL_GST_SYM(REQ, GSTSYM, RTN, ...) RTN (*ll##GSTSYM)(__VA_ARGS__) = NULL -#include "llmediaimplgstreamer_syms_raw.inc" -#include "llmediaimplgstreamer_syms_rawv.inc" -#undef LL_GST_SYM - -// a couple of stubs for disgusting reasons -GstDebugCategory* -ll_gst_debug_category_new(gchar *name, guint color, gchar *description) -{ - static GstDebugCategory dummy; - return &dummy; -} -void ll_gst_debug_register_funcptr(GstDebugFuncPtr func, gchar* ptrname) -{ -} - -static bool sSymsGrabbed = false; -static apr_pool_t *sSymGSTDSOMemoryPool = NULL; -static apr_dso_handle_t *sSymGSTDSOHandleG = NULL; -static apr_dso_handle_t *sSymGSTDSOHandleV = NULL; - - -bool grab_gst_syms(std::string gst_dso_name, - std::string gst_dso_name_vid) -{ - if (sSymsGrabbed) - { - // already have grabbed good syms - return TRUE; - } - - bool sym_error = false; - bool rtn = false; - apr_status_t rv; - apr_dso_handle_t *sSymGSTDSOHandle = NULL; - -#define LL_GST_SYM(REQ, GSTSYM, RTN, ...) do{rv = apr_dso_sym((apr_dso_handle_sym_t*)&ll##GSTSYM, sSymGSTDSOHandle, #GSTSYM); if (rv != APR_SUCCESS) {INFOMSG("Failed to grab symbol: %s", #GSTSYM); if (REQ) sym_error = true;} else DEBUGMSG("grabbed symbol: %s from %p", #GSTSYM, (void*)ll##GSTSYM);}while(0) - - //attempt to load the shared libraries - apr_pool_create(&sSymGSTDSOMemoryPool, NULL); - - if ( APR_SUCCESS == (rv = apr_dso_load(&sSymGSTDSOHandle, - gst_dso_name.c_str(), - sSymGSTDSOMemoryPool) )) - { - INFOMSG("Found DSO: %s", gst_dso_name.c_str()); -#include "llmediaimplgstreamer_syms_raw.inc" - - if ( sSymGSTDSOHandle ) - { - sSymGSTDSOHandleG = sSymGSTDSOHandle; - sSymGSTDSOHandle = NULL; - } - - if ( APR_SUCCESS == - (rv = apr_dso_load(&sSymGSTDSOHandle, - gst_dso_name_vid.c_str(), - sSymGSTDSOMemoryPool) )) - { - INFOMSG("Found DSO: %s", gst_dso_name_vid.c_str()); -#include "llmediaimplgstreamer_syms_rawv.inc" - rtn = !sym_error; - } - else - { - INFOMSG("Couldn't load DSO: %s", gst_dso_name_vid.c_str()); - rtn = false; // failure - } - } - else - { - INFOMSG("Couldn't load DSO: %s", gst_dso_name.c_str()); - rtn = false; // failure - } - - if (sym_error) - { - WARNMSG("Failed to find necessary symbols in GStreamer libraries."); - } - - if ( sSymGSTDSOHandle ) - { - sSymGSTDSOHandleV = sSymGSTDSOHandle; - sSymGSTDSOHandle = NULL; - } -#undef LL_GST_SYM - - sSymsGrabbed = !!rtn; - return rtn; -} - - -void ungrab_gst_syms() -{ - // should be safe to call regardless of whether we've - // actually grabbed syms. - - if ( sSymGSTDSOHandleG ) - { - apr_dso_unload(sSymGSTDSOHandleG); - sSymGSTDSOHandleG = NULL; - } - - if ( sSymGSTDSOHandleV ) - { - apr_dso_unload(sSymGSTDSOHandleV); - sSymGSTDSOHandleV = NULL; - } - - if ( sSymGSTDSOMemoryPool ) - { - apr_pool_destroy(sSymGSTDSOMemoryPool); - sSymGSTDSOMemoryPool = NULL; - } - - // NULL-out all of the symbols we'd grabbed -#define LL_GST_SYM(REQ, GSTSYM, RTN, ...) do{ll##GSTSYM = NULL;}while(0) -#include "llmediaimplgstreamer_syms_raw.inc" -#include "llmediaimplgstreamer_syms_rawv.inc" -#undef LL_GST_SYM - - sSymsGrabbed = false; -} - - -#endif // LL_GSTREAMER010_ENABLED diff --git a/indra/media_plugins/gstreamer010/llmediaimplgstreamer_syms.h b/indra/media_plugins/gstreamer010/llmediaimplgstreamer_syms.h deleted file mode 100644 index 57d446c7df..0000000000 --- a/indra/media_plugins/gstreamer010/llmediaimplgstreamer_syms.h +++ /dev/null @@ -1,74 +0,0 @@ -/** - * @file llmediaimplgstreamer_syms.h - * @brief dynamic GStreamer symbol-grabbing code - * - * @cond - * $LicenseInfo:firstyear=2007&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 of the License only. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA - * $/LicenseInfo$ - * @endcond - */ - -#include "linden_common.h" - -#if LL_GSTREAMER010_ENABLED - -extern "C" { -#include <gst/gst.h> -} - -bool grab_gst_syms(std::string gst_dso_name, - std::string gst_dso_name_vid); -void ungrab_gst_syms(); - -#define LL_GST_SYM(REQ, GSTSYM, RTN, ...) extern RTN (*ll##GSTSYM)(__VA_ARGS__) -#include "llmediaimplgstreamer_syms_raw.inc" -#include "llmediaimplgstreamer_syms_rawv.inc" -#undef LL_GST_SYM - -// regrettable hacks to give us better runtime compatibility with older systems -#define llg_return_if_fail(COND) do{if (!(COND)) return;}while(0) -#define llg_return_val_if_fail(COND,V) do{if (!(COND)) return V;}while(0) - -// regrettable hacks because GStreamer was not designed for runtime loading -#undef GST_TYPE_MESSAGE -#define GST_TYPE_MESSAGE (llgst_message_get_type()) -#undef GST_TYPE_OBJECT -#define GST_TYPE_OBJECT (llgst_object_get_type()) -#undef GST_TYPE_PIPELINE -#define GST_TYPE_PIPELINE (llgst_pipeline_get_type()) -#undef GST_TYPE_ELEMENT -#define GST_TYPE_ELEMENT (llgst_element_get_type()) -#undef GST_TYPE_VIDEO_SINK -#define GST_TYPE_VIDEO_SINK (llgst_video_sink_get_type()) -// more regrettable hacks to stub-out these .h-exposed GStreamer internals -void ll_gst_debug_register_funcptr(GstDebugFuncPtr func, gchar* ptrname); -#undef _gst_debug_register_funcptr -#define _gst_debug_register_funcptr ll_gst_debug_register_funcptr -GstDebugCategory* ll_gst_debug_category_new(gchar *name, guint color, gchar *description); -#undef _gst_debug_category_new -#define _gst_debug_category_new ll_gst_debug_category_new -#undef __gst_debug_enabled -#define __gst_debug_enabled (0) - -// more hacks -#define LLGST_MESSAGE_TYPE_NAME(M) (llgst_message_type_get_name(GST_MESSAGE_TYPE(M))) - -#endif // LL_GSTREAMER010_ENABLED diff --git a/indra/media_plugins/gstreamer010/llmediaimplgstreamer_syms_raw.inc b/indra/media_plugins/gstreamer010/llmediaimplgstreamer_syms_raw.inc deleted file mode 100644 index b33e59363d..0000000000 --- a/indra/media_plugins/gstreamer010/llmediaimplgstreamer_syms_raw.inc +++ /dev/null @@ -1,51 +0,0 @@ - -// required symbols to grab -LL_GST_SYM(true, gst_pad_peer_accept_caps, gboolean, GstPad *pad, GstCaps *caps); -LL_GST_SYM(true, gst_buffer_new, GstBuffer*, void); -LL_GST_SYM(true, gst_buffer_set_caps, void, GstBuffer*, GstCaps *); -LL_GST_SYM(true, gst_structure_set_value, void, GstStructure *, const gchar *, const GValue*); -LL_GST_SYM(true, gst_init_check, gboolean, int *argc, char **argv[], GError ** err); -LL_GST_SYM(true, gst_message_get_type, GType, void); -LL_GST_SYM(true, gst_message_type_get_name, const gchar*, GstMessageType type); -LL_GST_SYM(true, gst_message_parse_error, void, GstMessage *message, GError **gerror, gchar **debug); -LL_GST_SYM(true, gst_message_parse_warning, void, GstMessage *message, GError **gerror, gchar **debug); -LL_GST_SYM(true, gst_message_parse_state_changed, void, GstMessage *message, GstState *oldstate, GstState *newstate, GstState *pending); -LL_GST_SYM(true, gst_element_set_state, GstStateChangeReturn, GstElement *element, GstState state); -LL_GST_SYM(true, gst_object_unref, void, gpointer object); -LL_GST_SYM(true, gst_object_get_type, GType, void); -LL_GST_SYM(true, gst_pipeline_get_type, GType, void); -LL_GST_SYM(true, gst_pipeline_get_bus, GstBus*, GstPipeline *pipeline); -LL_GST_SYM(true, gst_bus_add_watch, guint, GstBus * bus, GstBusFunc func, gpointer user_data); -LL_GST_SYM(true, gst_element_factory_make, GstElement*, const gchar *factoryname, const gchar *name); -LL_GST_SYM(true, gst_element_get_type, GType, void); -LL_GST_SYM(true, gst_static_pad_template_get, GstPadTemplate*, GstStaticPadTemplate *pad_template); -LL_GST_SYM(true, gst_element_class_add_pad_template, void, GstElementClass *klass, GstPadTemplate *temp); -LL_GST_SYM(true, gst_element_class_set_details, void, GstElementClass *klass, const GstElementDetails *details); -LL_GST_SYM(true, gst_caps_unref, void, GstCaps* caps); -LL_GST_SYM(true, gst_caps_ref, GstCaps *, GstCaps* caps); -//LL_GST_SYM(true, gst_caps_is_empty, gboolean, const GstCaps *caps); -LL_GST_SYM(true, gst_caps_from_string, GstCaps *, const gchar *string); -LL_GST_SYM(true, gst_caps_replace, void, GstCaps **caps, GstCaps *newcaps); -LL_GST_SYM(true, gst_caps_get_structure, GstStructure *, const GstCaps *caps, guint index); -LL_GST_SYM(true, gst_caps_copy, GstCaps *, const GstCaps * caps); -//LL_GST_SYM(true, gst_caps_intersect, GstCaps *, const GstCaps *caps1, const GstCaps *caps2); -LL_GST_SYM(true, gst_element_register, gboolean, GstPlugin *plugin, const gchar *name, guint rank, GType type); -LL_GST_SYM(true, _gst_plugin_register_static, void, GstPluginDesc *desc); -LL_GST_SYM(true, gst_structure_get_int, gboolean, const GstStructure *structure, const gchar *fieldname, gint *value); -LL_GST_SYM(true, gst_structure_get_value, G_CONST_RETURN GValue *, const GstStructure *structure, const gchar *fieldname); -LL_GST_SYM(true, gst_value_get_fraction_numerator, gint, const GValue *value); -LL_GST_SYM(true, gst_value_get_fraction_denominator, gint, const GValue *value); -LL_GST_SYM(true, gst_structure_get_name, G_CONST_RETURN gchar *, const GstStructure *structure); -LL_GST_SYM(true, gst_element_seek, bool, GstElement *, gdouble, GstFormat, GstSeekFlags, GstSeekType, gint64, GstSeekType, gint64); - -// optional symbols to grab -LL_GST_SYM(false, gst_registry_fork_set_enabled, void, gboolean enabled); -LL_GST_SYM(false, gst_segtrap_set_enabled, void, gboolean enabled); -LL_GST_SYM(false, gst_message_parse_buffering, void, GstMessage *message, gint *percent); -LL_GST_SYM(false, gst_message_parse_info, void, GstMessage *message, GError **gerror, gchar **debug); -LL_GST_SYM(false, gst_element_query_position, gboolean, GstElement *element, GstFormat *format, gint64 *cur); -LL_GST_SYM(false, gst_version, void, guint *major, guint *minor, guint *micro, guint *nano); - -// GStreamer 'internal' symbols which may not be visible in some runtimes but are still used in expanded GStreamer header macros - yuck! We'll substitute our own stubs for these. -//LL_GST_SYM(true, _gst_debug_register_funcptr, void, GstDebugFuncPtr func, gchar* ptrname); -//LL_GST_SYM(true, _gst_debug_category_new, GstDebugCategory *, gchar *name, guint color, gchar *description); diff --git a/indra/media_plugins/gstreamer010/llmediaimplgstreamer_syms_rawv.inc b/indra/media_plugins/gstreamer010/llmediaimplgstreamer_syms_rawv.inc deleted file mode 100644 index 14fbcb48b9..0000000000 --- a/indra/media_plugins/gstreamer010/llmediaimplgstreamer_syms_rawv.inc +++ /dev/null @@ -1,5 +0,0 @@ - -// required symbols to grab -LL_GST_SYM(true, gst_video_sink_get_type, GType, void); - -// optional symbols to grab diff --git a/indra/media_plugins/gstreamer010/llmediaimplgstreamertriviallogging.h b/indra/media_plugins/gstreamer010/llmediaimplgstreamertriviallogging.h deleted file mode 100644 index 43ebad6744..0000000000 --- a/indra/media_plugins/gstreamer010/llmediaimplgstreamertriviallogging.h +++ /dev/null @@ -1,55 +0,0 @@ -/** - * @file llmediaimplgstreamertriviallogging.h - * @brief minimal logging utilities. - * - * @cond - * $LicenseInfo:firstyear=2009&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 of the License only. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA - * $/LicenseInfo$ - * @endcond - */ - -#ifndef __LLMEDIAIMPLGSTREAMERTRIVIALLOGGING_H__ -#define __LLMEDIAIMPLGSTREAMERTRIVIALLOGGING_H__ - -#include <cstdio> - -extern "C" { -#include <sys/types.h> -#include <unistd.h> -} - -///////////////////////////////////////////////////////////////////////// -// Debug/Info/Warning macros. -#define MSGMODULEFOO "(media plugin)" -#define STDERRMSG(...) do{\ - fprintf(stderr, " pid:%d: ", (int)getpid());\ - fprintf(stderr, MSGMODULEFOO " %s:%d: ", __FUNCTION__, __LINE__);\ - fprintf(stderr, __VA_ARGS__);\ - fputc('\n',stderr);\ - }while(0) -#define NULLMSG(...) do{}while(0) - -#define DEBUGMSG NULLMSG -#define INFOMSG STDERRMSG -#define WARNMSG STDERRMSG -///////////////////////////////////////////////////////////////////////// - -#endif /* __LLMEDIAIMPLGSTREAMERTRIVIALLOGGING_H__ */ diff --git a/indra/media_plugins/gstreamer010/llmediaimplgstreamervidplug.cpp b/indra/media_plugins/gstreamer010/llmediaimplgstreamervidplug.cpp deleted file mode 100644 index acec0f2399..0000000000 --- a/indra/media_plugins/gstreamer010/llmediaimplgstreamervidplug.cpp +++ /dev/null @@ -1,526 +0,0 @@ -/** - * @file llmediaimplgstreamervidplug.h - * @brief Video-consuming static GStreamer plugin for gst-to-LLMediaImpl - * - * @cond - * $LicenseInfo:firstyear=2007&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 of the License only. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA - * $/LicenseInfo$ - * @endcond - */ - -#if LL_GSTREAMER010_ENABLED - -#include "linden_common.h" - -#include <gst/gst.h> -#include <gst/video/video.h> -#include <gst/video/gstvideosink.h> - -#include "llmediaimplgstreamer_syms.h" -#include "llmediaimplgstreamertriviallogging.h" - -#include "llmediaimplgstreamervidplug.h" - - -GST_DEBUG_CATEGORY_STATIC (gst_slvideo_debug); -#define GST_CAT_DEFAULT gst_slvideo_debug - - -#define SLV_SIZECAPS ", width=(int)[1,2048], height=(int)[1,2048] " -#define SLV_ALLCAPS GST_VIDEO_CAPS_RGBx SLV_SIZECAPS - -static GstStaticPadTemplate sink_factory = GST_STATIC_PAD_TEMPLATE ( - (gchar*)"sink", - GST_PAD_SINK, - GST_PAD_ALWAYS, - GST_STATIC_CAPS (SLV_ALLCAPS) - ); - -GST_BOILERPLATE (GstSLVideo, gst_slvideo, GstVideoSink, - GST_TYPE_VIDEO_SINK); - -static void gst_slvideo_set_property (GObject * object, guint prop_id, - const GValue * value, - GParamSpec * pspec); -static void gst_slvideo_get_property (GObject * object, guint prop_id, - GValue * value, GParamSpec * pspec); - -static void -gst_slvideo_base_init (gpointer gclass) -{ - static GstElementDetails element_details = { - (gchar*)"PluginTemplate", - (gchar*)"Generic/PluginTemplate", - (gchar*)"Generic Template Element", - (gchar*)"Linden Lab" - }; - GstElementClass *element_class = GST_ELEMENT_CLASS (gclass); - - llgst_element_class_add_pad_template (element_class, - llgst_static_pad_template_get (&sink_factory)); - llgst_element_class_set_details (element_class, &element_details); -} - - -static void -gst_slvideo_finalize (GObject * object) -{ - GstSLVideo *slvideo; - slvideo = GST_SLVIDEO (object); - if (slvideo->caps) - { - llgst_caps_unref(slvideo->caps); - } - - G_OBJECT_CLASS(parent_class)->finalize (object); -} - - -static GstFlowReturn -gst_slvideo_show_frame (GstBaseSink * bsink, GstBuffer * buf) -{ - GstSLVideo *slvideo; - llg_return_val_if_fail (buf != NULL, GST_FLOW_ERROR); - - slvideo = GST_SLVIDEO(bsink); - - DEBUGMSG("transferring a frame of %dx%d <- %p (%d)", - slvideo->width, slvideo->height, GST_BUFFER_DATA(buf), - slvideo->format); - - if (GST_BUFFER_DATA(buf)) - { - // copy frame and frame info into neutral territory - GST_OBJECT_LOCK(slvideo); - slvideo->retained_frame_ready = TRUE; - slvideo->retained_frame_width = slvideo->width; - slvideo->retained_frame_height = slvideo->height; - slvideo->retained_frame_format = slvideo->format; - int rowbytes = - SLVPixelFormatBytes[slvideo->retained_frame_format] * - slvideo->retained_frame_width; - int needbytes = rowbytes * slvideo->retained_frame_width; - // resize retained frame hunk only if necessary - if (needbytes != slvideo->retained_frame_allocbytes) - { - delete[] slvideo->retained_frame_data; - slvideo->retained_frame_data = new unsigned char[needbytes]; - slvideo->retained_frame_allocbytes = needbytes; - - } - // copy the actual frame data to neutral territory - - // flipped, for GL reasons - for (int ypos=0; ypos<slvideo->height; ++ypos) - { - memcpy(&slvideo->retained_frame_data[(slvideo->height-1-ypos)*rowbytes], - &(((unsigned char*)GST_BUFFER_DATA(buf))[ypos*rowbytes]), - rowbytes); - } - // done with the shared data - GST_OBJECT_UNLOCK(slvideo); - } - - return GST_FLOW_OK; -} - - -static GstStateChangeReturn -gst_slvideo_change_state(GstElement * element, GstStateChange transition) -{ - GstSLVideo *slvideo; - GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS; - - slvideo = GST_SLVIDEO (element); - - switch (transition) { - case GST_STATE_CHANGE_NULL_TO_READY: - break; - case GST_STATE_CHANGE_READY_TO_PAUSED: - break; - case GST_STATE_CHANGE_PAUSED_TO_PLAYING: - break; - default: - break; - } - - ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition); - if (ret == GST_STATE_CHANGE_FAILURE) - return ret; - - switch (transition) { - case GST_STATE_CHANGE_PLAYING_TO_PAUSED: - break; - case GST_STATE_CHANGE_PAUSED_TO_READY: - slvideo->fps_n = 0; - slvideo->fps_d = 1; - GST_VIDEO_SINK_WIDTH(slvideo) = 0; - GST_VIDEO_SINK_HEIGHT(slvideo) = 0; - break; - case GST_STATE_CHANGE_READY_TO_NULL: - break; - default: - break; - } - - return ret; -} - - -static GstCaps * -gst_slvideo_get_caps (GstBaseSink * bsink) -{ - GstSLVideo *slvideo; - slvideo = GST_SLVIDEO(bsink); - - return llgst_caps_ref (slvideo->caps); -} - - -/* this function handles the link with other elements */ -static gboolean -gst_slvideo_set_caps (GstBaseSink * bsink, GstCaps * caps) -{ - GstSLVideo *filter; - GstStructure *structure; - - GST_DEBUG ("set caps with %" GST_PTR_FORMAT, caps); - - filter = GST_SLVIDEO(bsink); - - int width, height; - gboolean ret; - const GValue *fps; - const GValue *par; - structure = llgst_caps_get_structure (caps, 0); - ret = llgst_structure_get_int (structure, "width", &width); - ret = ret && llgst_structure_get_int (structure, "height", &height); - fps = llgst_structure_get_value (structure, "framerate"); - ret = ret && (fps != NULL); - par = llgst_structure_get_value (structure, "pixel-aspect-ratio"); - if (!ret) - return FALSE; - - INFOMSG("** filter caps set with width=%d, height=%d", width, height); - - GST_OBJECT_LOCK(filter); - - filter->width = width; - filter->height = height; - - filter->fps_n = llgst_value_get_fraction_numerator(fps); - filter->fps_d = llgst_value_get_fraction_denominator(fps); - if (par) - { - filter->par_n = llgst_value_get_fraction_numerator(par); - filter->par_d = llgst_value_get_fraction_denominator(par); - } - else - { - filter->par_n = 1; - filter->par_d = 1; - } - GST_VIDEO_SINK_WIDTH(filter) = width; - GST_VIDEO_SINK_HEIGHT(filter) = height; - - // crufty lump - we *always* accept *only* RGBX now. - /* - filter->format = SLV_PF_UNKNOWN; - if (0 == strcmp(llgst_structure_get_name(structure), - "video/x-raw-rgb")) - { - int red_mask; - int green_mask; - int blue_mask; - llgst_structure_get_int(structure, "red_mask", &red_mask); - llgst_structure_get_int(structure, "green_mask", &green_mask); - llgst_structure_get_int(structure, "blue_mask", &blue_mask); - if ((unsigned int)red_mask == 0xFF000000 && - (unsigned int)green_mask == 0x00FF0000 && - (unsigned int)blue_mask == 0x0000FF00) - { - filter->format = SLV_PF_RGBX; - //fprintf(stderr, "\n\nPIXEL FORMAT RGB\n\n"); - } else if ((unsigned int)red_mask == 0x0000FF00 && - (unsigned int)green_mask == 0x00FF0000 && - (unsigned int)blue_mask == 0xFF000000) - { - filter->format = SLV_PF_BGRX; - //fprintf(stderr, "\n\nPIXEL FORMAT BGR\n\n"); - } - }*/ - - filter->format = SLV_PF_RGBX; - - GST_OBJECT_UNLOCK(filter); - - return TRUE; -} - - -static gboolean -gst_slvideo_start (GstBaseSink * bsink) -{ - gboolean ret = TRUE; - - GST_SLVIDEO(bsink); - - return ret; -} - -static gboolean -gst_slvideo_stop (GstBaseSink * bsink) -{ - GstSLVideo *slvideo; - slvideo = GST_SLVIDEO(bsink); - - // free-up retained frame buffer - GST_OBJECT_LOCK(slvideo); - slvideo->retained_frame_ready = FALSE; - delete[] slvideo->retained_frame_data; - slvideo->retained_frame_data = NULL; - slvideo->retained_frame_allocbytes = 0; - GST_OBJECT_UNLOCK(slvideo); - - return TRUE; -} - - -static GstFlowReturn -gst_slvideo_buffer_alloc (GstBaseSink * bsink, guint64 offset, guint size, - GstCaps * caps, GstBuffer ** buf) -{ - gint width, height; - GstStructure *structure = NULL; - GstSLVideo *slvideo; - slvideo = GST_SLVIDEO(bsink); - - // caps == requested caps - // we can ignore these and reverse-negotiate our preferred dimensions with - // the peer if we like - we need to do this to obey dynamic resize requests - // flowing in from the app. - structure = llgst_caps_get_structure (caps, 0); - if (!llgst_structure_get_int(structure, "width", &width) || - !llgst_structure_get_int(structure, "height", &height)) - { - GST_WARNING_OBJECT (slvideo, "no width/height in caps %" GST_PTR_FORMAT, caps); - return GST_FLOW_NOT_NEGOTIATED; - } - - GstBuffer *newbuf = llgst_buffer_new(); - bool made_bufferdata_ptr = false; -#define MAXDEPTHHACK 4 - - GST_OBJECT_LOCK(slvideo); - if (slvideo->resize_forced_always) // app is giving us a fixed size to work with - { - gint slwantwidth, slwantheight; - slwantwidth = slvideo->resize_try_width; - slwantheight = slvideo->resize_try_height; - - if (slwantwidth != width || - slwantheight != height) - { - // don't like requested caps, we will issue our own suggestion - copy - // the requested caps but substitute our own width and height and see - // if our peer is happy with that. - - GstCaps *desired_caps; - GstStructure *desired_struct; - desired_caps = llgst_caps_copy (caps); - desired_struct = llgst_caps_get_structure (desired_caps, 0); - - GValue value = {0}; - g_value_init(&value, G_TYPE_INT); - g_value_set_int(&value, slwantwidth); - llgst_structure_set_value (desired_struct, "width", &value); - g_value_unset(&value); - g_value_init(&value, G_TYPE_INT); - g_value_set_int(&value, slwantheight); - llgst_structure_set_value (desired_struct, "height", &value); - - if (llgst_pad_peer_accept_caps (GST_VIDEO_SINK_PAD (slvideo), - desired_caps)) - { - // todo: re-use buffers from a pool? - // todo: set MALLOCDATA to null, set DATA to point straight to shm? - - // peer likes our cap suggestion - DEBUGMSG("peer loves us :)"); - GST_BUFFER_SIZE(newbuf) = slwantwidth * slwantheight * MAXDEPTHHACK; - GST_BUFFER_MALLOCDATA(newbuf) = (guint8*)g_malloc(GST_BUFFER_SIZE(newbuf)); - GST_BUFFER_DATA(newbuf) = GST_BUFFER_MALLOCDATA(newbuf); - llgst_buffer_set_caps (GST_BUFFER_CAST(newbuf), desired_caps); - - made_bufferdata_ptr = true; - } else { - // peer hates our cap suggestion - INFOMSG("peer hates us :("); - llgst_caps_unref(desired_caps); - } - } - } - - GST_OBJECT_UNLOCK(slvideo); - - if (!made_bufferdata_ptr) // need to fallback to malloc at original size - { - GST_BUFFER_SIZE(newbuf) = width * height * MAXDEPTHHACK; - GST_BUFFER_MALLOCDATA(newbuf) = (guint8*)g_malloc(GST_BUFFER_SIZE(newbuf)); - GST_BUFFER_DATA(newbuf) = GST_BUFFER_MALLOCDATA(newbuf); - llgst_buffer_set_caps (GST_BUFFER_CAST(newbuf), caps); - } - - *buf = GST_BUFFER_CAST(newbuf); - - return GST_FLOW_OK; -} - - -/* initialize the plugin's class */ -static void -gst_slvideo_class_init (GstSLVideoClass * klass) -{ - GObjectClass *gobject_class; - GstElementClass *gstelement_class; - GstBaseSinkClass *gstbasesink_class; - - gobject_class = (GObjectClass *) klass; - gstelement_class = (GstElementClass *) klass; - gstbasesink_class = (GstBaseSinkClass *) klass; - - gobject_class->finalize = gst_slvideo_finalize; - gobject_class->set_property = gst_slvideo_set_property; - gobject_class->get_property = gst_slvideo_get_property; - - gstelement_class->change_state = gst_slvideo_change_state; - -#define LLGST_DEBUG_FUNCPTR(p) (p) - gstbasesink_class->get_caps = LLGST_DEBUG_FUNCPTR (gst_slvideo_get_caps); - gstbasesink_class->set_caps = LLGST_DEBUG_FUNCPTR( gst_slvideo_set_caps); - gstbasesink_class->buffer_alloc=LLGST_DEBUG_FUNCPTR(gst_slvideo_buffer_alloc); - //gstbasesink_class->get_times = LLGST_DEBUG_FUNCPTR (gst_slvideo_get_times); - gstbasesink_class->preroll = LLGST_DEBUG_FUNCPTR (gst_slvideo_show_frame); - gstbasesink_class->render = LLGST_DEBUG_FUNCPTR (gst_slvideo_show_frame); - - gstbasesink_class->start = LLGST_DEBUG_FUNCPTR (gst_slvideo_start); - gstbasesink_class->stop = LLGST_DEBUG_FUNCPTR (gst_slvideo_stop); - - // gstbasesink_class->unlock = LLGST_DEBUG_FUNCPTR (gst_slvideo_unlock); -#undef LLGST_DEBUG_FUNCPTR -} - - -/* initialize the new element - * instantiate pads and add them to element - * set functions - * initialize structure - */ -static void -gst_slvideo_init (GstSLVideo * filter, - GstSLVideoClass * gclass) -{ - filter->caps = NULL; - filter->width = -1; - filter->height = -1; - - // this is the info we share with the client app - GST_OBJECT_LOCK(filter); - filter->retained_frame_ready = FALSE; - filter->retained_frame_data = NULL; - filter->retained_frame_allocbytes = 0; - filter->retained_frame_width = filter->width; - filter->retained_frame_height = filter->height; - filter->retained_frame_format = SLV_PF_UNKNOWN; - GstCaps *caps = llgst_caps_from_string (SLV_ALLCAPS); - llgst_caps_replace (&filter->caps, caps); - filter->resize_forced_always = false; - filter->resize_try_width = -1; - filter->resize_try_height = -1; - GST_OBJECT_UNLOCK(filter); -} - -static void -gst_slvideo_set_property (GObject * object, guint prop_id, - const GValue * value, GParamSpec * pspec) -{ - llg_return_if_fail (GST_IS_SLVIDEO (object)); - - switch (prop_id) { - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -gst_slvideo_get_property (GObject * object, guint prop_id, - GValue * value, GParamSpec * pspec) -{ - llg_return_if_fail (GST_IS_SLVIDEO (object)); - - switch (prop_id) { - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - - -/* entry point to initialize the plug-in - * initialize the plug-in itself - * register the element factories and pad templates - * register the features - */ -static gboolean -plugin_init (GstPlugin * plugin) -{ - DEBUGMSG("PLUGIN INIT"); - - GST_DEBUG_CATEGORY_INIT (gst_slvideo_debug, (gchar*)"private-slvideo-plugin", - 0, (gchar*)"Second Life Video Sink"); - - return llgst_element_register (plugin, "private-slvideo", - GST_RANK_NONE, GST_TYPE_SLVIDEO); -} - -/* this is the structure that gstreamer looks for to register plugins - */ -/* NOTE: Can't rely upon GST_PLUGIN_DEFINE_STATIC to self-register, since - some g++ versions buggily avoid __attribute__((constructor)) functions - - so we provide an explicit plugin init function. - */ -#define PACKAGE (gchar*)"packagehack" -// this macro quietly refers to PACKAGE internally -GST_PLUGIN_DEFINE (GST_VERSION_MAJOR, - GST_VERSION_MINOR, - (gchar*)"private-slvideoplugin", - (gchar*)"SL Video sink plugin", - plugin_init, (gchar*)"1.0", (gchar*)"LGPL", - (gchar*)"Second Life", - (gchar*)"http://www.secondlife.com/"); -#undef PACKAGE -void gst_slvideo_init_class (void) -{ - ll_gst_plugin_register_static (&gst_plugin_desc); - DEBUGMSG("CLASS INIT"); -} - -#endif // LL_GSTREAMER010_ENABLED diff --git a/indra/media_plugins/gstreamer010/llmediaimplgstreamervidplug.h b/indra/media_plugins/gstreamer010/llmediaimplgstreamervidplug.h deleted file mode 100644 index d4e07daf4f..0000000000 --- a/indra/media_plugins/gstreamer010/llmediaimplgstreamervidplug.h +++ /dev/null @@ -1,105 +0,0 @@ -/** - * @file llmediaimplgstreamervidplug.h - * @brief Video-consuming static GStreamer plugin for gst-to-LLMediaImpl - * - * @cond - * $LicenseInfo:firstyear=2007&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 of the License only. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA - * $/LicenseInfo$ - * @endcond - */ - -#ifndef __GST_SLVIDEO_H__ -#define __GST_SLVIDEO_H__ - -#if LL_GSTREAMER010_ENABLED - -extern "C" { -#include <gst/gst.h> -#include <gst/video/video.h> -#include <gst/video/gstvideosink.h> -} - -G_BEGIN_DECLS - -/* #defines don't like whitespacey bits */ -#define GST_TYPE_SLVIDEO \ - (gst_slvideo_get_type()) -#define GST_SLVIDEO(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_SLVIDEO,GstSLVideo)) -#define GST_SLVIDEO_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_SLVIDEO,GstSLVideoClass)) -#define GST_IS_SLVIDEO(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_SLVIDEO)) -#define GST_IS_SLVIDEO_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_SLVIDEO)) - -typedef struct _GstSLVideo GstSLVideo; -typedef struct _GstSLVideoClass GstSLVideoClass; - -typedef enum { - SLV_PF_UNKNOWN = 0, - SLV_PF_RGBX = 1, - SLV_PF_BGRX = 2, - SLV__END = 3 -} SLVPixelFormat; -const int SLVPixelFormatBytes[SLV__END] = {1, 4, 4}; - -struct _GstSLVideo -{ - GstVideoSink video_sink; - - GstCaps *caps; - - int fps_n, fps_d; - int par_n, par_d; - int height, width; - SLVPixelFormat format; - - // SHARED WITH APPLICATION: - // Access to the following should be protected by GST_OBJECT_LOCK() on - // the GstSLVideo object, and should be totally consistent upon UNLOCK - // (i.e. all written at once to reflect the current retained frame info - // when the retained frame is updated.) - bool retained_frame_ready; // new frame ready since flag last reset. (*TODO: could get the writer to wait on a semaphore instead of having the reader poll, potentially making dropped frames somewhat cheaper.) - unsigned char* retained_frame_data; - int retained_frame_allocbytes; - int retained_frame_width, retained_frame_height; - SLVPixelFormat retained_frame_format; - // sticky resize info - bool resize_forced_always; - int resize_try_width; - int resize_try_height; -}; - -struct _GstSLVideoClass -{ - GstVideoSinkClass parent_class; -}; - -GType gst_slvideo_get_type (void); - -void gst_slvideo_init_class (void); - -G_END_DECLS - -#endif // LL_GSTREAMER010_ENABLED - -#endif /* __GST_SLVIDEO_H__ */ diff --git a/indra/media_plugins/gstreamer010/media_plugin_gstreamer010.cpp b/indra/media_plugins/gstreamer010/media_plugin_gstreamer010.cpp deleted file mode 100644 index 97d1d7d7b5..0000000000 --- a/indra/media_plugins/gstreamer010/media_plugin_gstreamer010.cpp +++ /dev/null @@ -1,1266 +0,0 @@ -/** - * @file media_plugin_gstreamer010.cpp - * @brief GStreamer-0.10 plugin for LLMedia API plugin system - * - * @cond - * $LicenseInfo:firstyear=2007&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 of the License only. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA - * $/LicenseInfo$ - * @endcond - */ - -#include "linden_common.h" - -#include "llgl.h" - -#include "llplugininstance.h" -#include "llpluginmessage.h" -#include "llpluginmessageclasses.h" -#include "media_plugin_base.h" - -#if LL_GSTREAMER010_ENABLED - -extern "C" { -#include <gst/gst.h> -} - -#include "llmediaimplgstreamer.h" -#include "llmediaimplgstreamertriviallogging.h" - -#include "llmediaimplgstreamervidplug.h" - -#include "llmediaimplgstreamer_syms.h" - -////////////////////////////////////////////////////////////////////////////// -// -class MediaPluginGStreamer010 : public MediaPluginBase -{ -public: - MediaPluginGStreamer010(LLPluginInstance::sendMessageFunction host_send_func, void *host_user_data); - ~MediaPluginGStreamer010(); - - /* virtual */ void receiveMessage(const char *message_string); - - static bool startup(); - static bool closedown(); - - gboolean processGSTEvents(GstBus *bus, - GstMessage *message); - -private: - std::string getVersion(); - bool navigateTo( const std::string urlIn ); - bool seek( double time_sec ); - bool setVolume( float volume ); - - // misc - bool pause(); - bool stop(); - bool play(double rate); - bool getTimePos(double &sec_out); - - static const double MIN_LOOP_SEC = 1.0F; - - bool mIsLooping; - - enum ECommand { - COMMAND_NONE, - COMMAND_STOP, - COMMAND_PLAY, - COMMAND_FAST_FORWARD, - COMMAND_FAST_REWIND, - COMMAND_PAUSE, - COMMAND_SEEK, - }; - ECommand mCommand; - -private: - bool unload(); - bool load(); - - bool update(int milliseconds); - void mouseDown( int x, int y ); - void mouseUp( int x, int y ); - void mouseMove( int x, int y ); - - void sizeChanged(); - - static bool mDoneInit; - - guint mBusWatchID; - - float mVolume; - - int mDepth; - - // media NATURAL size - int mNaturalWidth; - int mNaturalHeight; - // media current size - int mCurrentWidth; - int mCurrentHeight; - int mCurrentRowbytes; - // previous media size so we can detect changes - int mPreviousWidth; - int mPreviousHeight; - // desired render size from host - int mWidth; - int mHeight; - // padded texture size we need to write into - int mTextureWidth; - int mTextureHeight; - - int mTextureFormatPrimary; - int mTextureFormatType; - - bool mSeekWanted; - double mSeekDestination; - - // Very GStreamer-specific - GMainLoop *mPump; // event pump for this media - GstElement *mPlaybin; - GstElement *mVisualizer; - GstSLVideo *mVideoSink; -}; - -//static -bool MediaPluginGStreamer010::mDoneInit = false; - -MediaPluginGStreamer010::MediaPluginGStreamer010( - LLPluginInstance::sendMessageFunction host_send_func, - void *host_user_data ) : - MediaPluginBase(host_send_func, host_user_data), - mBusWatchID ( 0 ), - mCurrentRowbytes ( 4 ), - mTextureFormatPrimary ( GL_RGBA ), - mTextureFormatType ( GL_UNSIGNED_INT_8_8_8_8_REV ), - mSeekWanted(false), - mSeekDestination(0.0), - mPump ( NULL ), - mPlaybin ( NULL ), - mVisualizer ( NULL ), - mVideoSink ( NULL ), - mCommand ( COMMAND_NONE ) -{ - std::ostringstream str; - INFOMSG("MediaPluginGStreamer010 constructor - my PID=%u", U32(getpid())); -} - -/////////////////////////////////////////////////////////////////////////////// -// -//#define LL_GST_REPORT_STATE_CHANGES -#ifdef LL_GST_REPORT_STATE_CHANGES -static char* get_gst_state_name(GstState state) -{ - switch (state) { - case GST_STATE_VOID_PENDING: return "VOID_PENDING"; - case GST_STATE_NULL: return "NULL"; - case GST_STATE_READY: return "READY"; - case GST_STATE_PAUSED: return "PAUSED"; - case GST_STATE_PLAYING: return "PLAYING"; - } - return "(unknown)"; -} -#endif // LL_GST_REPORT_STATE_CHANGES - -gboolean -MediaPluginGStreamer010::processGSTEvents(GstBus *bus, - GstMessage *message) -{ - if (!message) - return TRUE; // shield against GStreamer bug - - if (GST_MESSAGE_TYPE(message) != GST_MESSAGE_STATE_CHANGED && - GST_MESSAGE_TYPE(message) != GST_MESSAGE_BUFFERING) - { - DEBUGMSG("Got GST message type: %s", - LLGST_MESSAGE_TYPE_NAME (message)); - } - else - { - // TODO: grok 'duration' message type - DEBUGMSG("Got GST message type: %s", - LLGST_MESSAGE_TYPE_NAME (message)); - } - - switch (GST_MESSAGE_TYPE (message)) { - case GST_MESSAGE_BUFFERING: { - // NEEDS GST 0.10.11+ - if (llgst_message_parse_buffering) - { - gint percent = 0; - llgst_message_parse_buffering(message, &percent); - DEBUGMSG("GST buffering: %d%%", percent); - } - break; - } - case GST_MESSAGE_STATE_CHANGED: { - GstState old_state; - GstState new_state; - GstState pending_state; - llgst_message_parse_state_changed(message, - &old_state, - &new_state, - &pending_state); -#ifdef LL_GST_REPORT_STATE_CHANGES - // not generally very useful, and rather spammy. - DEBUGMSG("state change (old,<new>,pending): %s,<%s>,%s", - get_gst_state_name(old_state), - get_gst_state_name(new_state), - get_gst_state_name(pending_state)); -#endif // LL_GST_REPORT_STATE_CHANGES - - switch (new_state) { - case GST_STATE_VOID_PENDING: - break; - case GST_STATE_NULL: - break; - case GST_STATE_READY: - setStatus(STATUS_LOADED); - break; - case GST_STATE_PAUSED: - setStatus(STATUS_PAUSED); - break; - case GST_STATE_PLAYING: - setStatus(STATUS_PLAYING); - break; - } - break; - } - case GST_MESSAGE_ERROR: { - GError *err = NULL; - gchar *debug = NULL; - - llgst_message_parse_error (message, &err, &debug); - WARNMSG("GST error: %s", err?err->message:"(unknown)"); - if (err) - g_error_free (err); - g_free (debug); - - mCommand = COMMAND_STOP; - - setStatus(STATUS_ERROR); - - break; - } - case GST_MESSAGE_INFO: { - if (llgst_message_parse_info) - { - GError *err = NULL; - gchar *debug = NULL; - - llgst_message_parse_info (message, &err, &debug); - INFOMSG("GST info: %s", err?err->message:"(unknown)"); - if (err) - g_error_free (err); - g_free (debug); - } - break; - } - case GST_MESSAGE_WARNING: { - GError *err = NULL; - gchar *debug = NULL; - - llgst_message_parse_warning (message, &err, &debug); - WARNMSG("GST warning: %s", err?err->message:"(unknown)"); - if (err) - g_error_free (err); - g_free (debug); - - break; - } - case GST_MESSAGE_EOS: - /* end-of-stream */ - DEBUGMSG("GST end-of-stream."); - if (mIsLooping) - { - DEBUGMSG("looping media..."); - double eos_pos_sec = 0.0F; - bool got_eos_position = getTimePos(eos_pos_sec); - - if (got_eos_position && eos_pos_sec < MIN_LOOP_SEC) - { - // if we know that the movie is really short, don't - // loop it else it can easily become a time-hog - // because of GStreamer spin-up overhead - DEBUGMSG("really short movie (%0.3fsec) - not gonna loop this, pausing instead.", eos_pos_sec); - // inject a COMMAND_PAUSE - mCommand = COMMAND_PAUSE; - } - else - { -#undef LLGST_LOOP_BY_SEEKING -// loop with a stop-start instead of a seek, because it actually seems rather -// faster than seeking on remote streams. -#ifdef LLGST_LOOP_BY_SEEKING - // first, try looping by an explicit rewind - bool seeksuccess = seek(0.0); - if (seeksuccess) - { - play(1.0); - } - else -#endif // LLGST_LOOP_BY_SEEKING - { // use clumsy stop-start to loop - DEBUGMSG("didn't loop by rewinding - stopping and starting instead..."); - stop(); - play(1.0); - } - } - } - else // not a looping media - { - // inject a COMMAND_STOP - mCommand = COMMAND_STOP; - } - break; - default: - /* unhandled message */ - break; - } - - /* we want to be notified again the next time there is a message - * on the bus, so return true (false means we want to stop watching - * for messages on the bus and our callback should not be called again) - */ - return TRUE; -} - -extern "C" { -gboolean -llmediaimplgstreamer_bus_callback (GstBus *bus, - GstMessage *message, - gpointer data) -{ - MediaPluginGStreamer010 *impl = (MediaPluginGStreamer010*)data; - return impl->processGSTEvents(bus, message); -} -} // extern "C" - - - -bool -MediaPluginGStreamer010::navigateTo ( const std::string urlIn ) -{ - if (!mDoneInit) - return false; // error - - setStatus(STATUS_LOADING); - - DEBUGMSG("Setting media URI: %s", urlIn.c_str()); - - mSeekWanted = false; - - if (NULL == mPump || - NULL == mPlaybin) - { - setStatus(STATUS_ERROR); - return false; // error - } - - // set URI - g_object_set (G_OBJECT (mPlaybin), "uri", urlIn.c_str(), NULL); - //g_object_set (G_OBJECT (mPlaybin), "uri", "file:///tmp/movie", NULL); - - // navigateTo implicitly plays, too. - play(1.0); - - return true; -} - - -bool -MediaPluginGStreamer010::update(int milliseconds) -{ - if (!mDoneInit) - return false; // error - - DEBUGMSG("updating media..."); - - // sanity check - if (NULL == mPump || - NULL == mPlaybin) - { - DEBUGMSG("dead media..."); - return false; - } - - // see if there's an outstanding seek wanted - if (mSeekWanted && - // bleh, GST has to be happy that the movie is really truly playing - // or it may quietly ignore the seek (with rtsp:// at least). - (GST_STATE(mPlaybin) == GST_STATE_PLAYING)) - { - seek(mSeekDestination); - mSeekWanted = false; - } - - // *TODO: time-limit - but there isn't a lot we can do here, most - // time is spent in gstreamer's own opaque worker-threads. maybe - // we can do something sneaky like only unlock the video object - // for 'milliseconds' and otherwise hold the lock. - while (g_main_context_pending(g_main_loop_get_context(mPump))) - { - g_main_context_iteration(g_main_loop_get_context(mPump), FALSE); - } - - // check for availability of a new frame - - if (mVideoSink) - { - GST_OBJECT_LOCK(mVideoSink); - if (mVideoSink->retained_frame_ready) - { - DEBUGMSG("NEW FRAME READY"); - - if (mVideoSink->retained_frame_width != mCurrentWidth || - mVideoSink->retained_frame_height != mCurrentHeight) - // *TODO: also check for change in format - { - // just resize container, don't consume frame - int neww = mVideoSink->retained_frame_width; - int newh = mVideoSink->retained_frame_height; - - int newd = 4; - mTextureFormatPrimary = GL_RGBA; - mTextureFormatType = GL_UNSIGNED_INT_8_8_8_8_REV; - - /* - int newd = SLVPixelFormatBytes[mVideoSink->retained_frame_format]; - if (SLV_PF_BGRX == mVideoSink->retained_frame_format) - { - mTextureFormatPrimary = GL_BGRA; - mTextureFormatType = GL_UNSIGNED_INT_8_8_8_8_REV; - } - else - { - mTextureFormatPrimary = GL_RGBA; - mTextureFormatType = GL_UNSIGNED_INT_8_8_8_8_REV; - } - */ - - GST_OBJECT_UNLOCK(mVideoSink); - - mCurrentRowbytes = neww * newd; - DEBUGMSG("video container resized to %dx%d", - neww, newh); - - mDepth = newd; - mCurrentWidth = neww; - mCurrentHeight = newh; - sizeChanged(); - return true; - } - - if (mPixels && - mCurrentHeight <= mHeight && - mCurrentWidth <= mWidth && - !mTextureSegmentName.empty()) - { - // we're gonna totally consume this frame - reset 'ready' flag - mVideoSink->retained_frame_ready = FALSE; - int destination_rowbytes = mWidth * mDepth; - for (int row=0; row<mCurrentHeight; ++row) - { - memcpy(&mPixels - [destination_rowbytes * row], - &mVideoSink->retained_frame_data - [mCurrentRowbytes * row], - mCurrentRowbytes); - } - - GST_OBJECT_UNLOCK(mVideoSink); - DEBUGMSG("NEW FRAME REALLY TRULY CONSUMED, TELLING HOST"); - - setDirty(0,0,mCurrentWidth,mCurrentHeight); - } - else - { - // new frame ready, but we're not ready to - // consume it. - - GST_OBJECT_UNLOCK(mVideoSink); - - DEBUGMSG("NEW FRAME not consumed, still waiting for a shm segment and/or shm resize"); - } - - return true; - } - else - { - // nothing to do yet. - GST_OBJECT_UNLOCK(mVideoSink); - return true; - } - } - - return true; -} - - -void -MediaPluginGStreamer010::mouseDown( int x, int y ) -{ - // do nothing -} - -void -MediaPluginGStreamer010::mouseUp( int x, int y ) -{ - // do nothing -} - -void -MediaPluginGStreamer010::mouseMove( int x, int y ) -{ - // do nothing -} - - -bool -MediaPluginGStreamer010::pause() -{ - DEBUGMSG("pausing media..."); - // todo: error-check this? - if (mDoneInit && mPlaybin) - { - llgst_element_set_state(mPlaybin, GST_STATE_PAUSED); - return true; - } - return false; -} - -bool -MediaPluginGStreamer010::stop() -{ - DEBUGMSG("stopping media..."); - // todo: error-check this? - if (mDoneInit && mPlaybin) - { - llgst_element_set_state(mPlaybin, GST_STATE_READY); - return true; - } - return false; -} - -bool -MediaPluginGStreamer010::play(double rate) -{ - // NOTE: we don't actually support non-natural rate. - - DEBUGMSG("playing media... rate=%f", rate); - // todo: error-check this? - if (mDoneInit && mPlaybin) - { - llgst_element_set_state(mPlaybin, GST_STATE_PLAYING); - return true; - } - return false; -} - -bool -MediaPluginGStreamer010::setVolume( float volume ) -{ - // we try to only update volume as conservatively as - // possible, as many gst-plugins-base versions up to at least - // November 2008 have critical race-conditions in setting volume - sigh - if (mVolume == volume) - return true; // nothing to do, everything's fine - - mVolume = volume; - if (mDoneInit && mPlaybin) - { - g_object_set(mPlaybin, "volume", mVolume, NULL); - return true; - } - - return false; -} - -bool -MediaPluginGStreamer010::seek(double time_sec) -{ - bool success = false; - if (mDoneInit && mPlaybin) - { - success = llgst_element_seek(mPlaybin, 1.0F, GST_FORMAT_TIME, - GstSeekFlags(GST_SEEK_FLAG_FLUSH | - GST_SEEK_FLAG_KEY_UNIT), - GST_SEEK_TYPE_SET, gint64(time_sec*GST_SECOND), - GST_SEEK_TYPE_NONE, GST_CLOCK_TIME_NONE); - } - DEBUGMSG("MEDIA SEEK REQUEST to %fsec result was %d", - float(time_sec), int(success)); - return success; -} - -bool -MediaPluginGStreamer010::getTimePos(double &sec_out) -{ - bool got_position = false; - if (mDoneInit && mPlaybin) - { - gint64 pos; - GstFormat timefmt = GST_FORMAT_TIME; - got_position = - llgst_element_query_position && - llgst_element_query_position(mPlaybin, - &timefmt, - &pos); - got_position = got_position - && (timefmt == GST_FORMAT_TIME); - // GStreamer may have other ideas, but we consider the current position - // undefined if not PLAYING or PAUSED - got_position = got_position && - (GST_STATE(mPlaybin) == GST_STATE_PLAYING || - GST_STATE(mPlaybin) == GST_STATE_PAUSED); - if (got_position && !GST_CLOCK_TIME_IS_VALID(pos)) - { - if (GST_STATE(mPlaybin) == GST_STATE_PLAYING) - { - // if we're playing then we treat an invalid clock time - // as 0, for complicated reasons (insert reason here) - pos = 0; - } - else - { - got_position = false; - } - - } - // If all the preconditions succeeded... we can trust the result. - if (got_position) - { - sec_out = double(pos) / double(GST_SECOND); // gst to sec - } - } - return got_position; -} - -bool -MediaPluginGStreamer010::load() -{ - if (!mDoneInit) - return false; // error - - setStatus(STATUS_LOADING); - - DEBUGMSG("setting up media..."); - - mIsLooping = false; - mVolume = 0.1234567; // minor hack to force an initial volume update - - // Create a pumpable main-loop for this media - mPump = g_main_loop_new (NULL, FALSE); - if (!mPump) - { - setStatus(STATUS_ERROR); - return false; // error - } - - // instantiate a playbin element to do the hard work - mPlaybin = llgst_element_factory_make ("playbin", "play"); - if (!mPlaybin) - { - setStatus(STATUS_ERROR); - return false; // error - } - - // get playbin's bus - GstBus *bus = llgst_pipeline_get_bus (GST_PIPELINE (mPlaybin)); - if (!bus) - { - setStatus(STATUS_ERROR); - return false; // error - } - mBusWatchID = llgst_bus_add_watch (bus, - llmediaimplgstreamer_bus_callback, - this); - llgst_object_unref (bus); - -#if 0 // not quite stable/correct yet - // get a visualizer element (bonus feature!) - char* vis_name = getenv("LL_GST_VIS_NAME"); - if (!vis_name || - (vis_name && std::string(vis_name)!="none")) - { - if (vis_name) - { - mVisualizer = llgst_element_factory_make (vis_name, "vis"); - } - if (!mVisualizer) - { - mVisualizer = llgst_element_factory_make ("libvisual_jess", "vis"); - if (!mVisualizer) - { - mVisualizer = llgst_element_factory_make ("goom", "vis"); - if (!mVisualizer) - { - mVisualizer = llgst_element_factory_make ("libvisual_lv_scope", "vis"); - if (!mVisualizer) - { - // That's okay, we don't NEED this. - } - } - } - } - } -#endif - - if (NULL == getenv("LL_GSTREAMER_EXTERNAL")) { - // instantiate a custom video sink - mVideoSink = - GST_SLVIDEO(llgst_element_factory_make ("private-slvideo", "slvideo")); - if (!mVideoSink) - { - WARNMSG("Could not instantiate private-slvideo element."); - // todo: cleanup. - setStatus(STATUS_ERROR); - return false; // error - } - - // connect the pieces - g_object_set(mPlaybin, "video-sink", mVideoSink, NULL); - } - - if (mVisualizer) - { - g_object_set(mPlaybin, "vis-plugin", mVisualizer, NULL); - } - - return true; -} - -bool -MediaPluginGStreamer010::unload () -{ - if (!mDoneInit) - return false; // error - - DEBUGMSG("unloading media..."); - - // stop getting callbacks for this bus - g_source_remove(mBusWatchID); - mBusWatchID = 0; - - if (mPlaybin) - { - llgst_element_set_state (mPlaybin, GST_STATE_NULL); - llgst_object_unref (GST_OBJECT (mPlaybin)); - mPlaybin = NULL; - } - - if (mVisualizer) - { - llgst_object_unref (GST_OBJECT (mVisualizer)); - mVisualizer = NULL; - } - - if (mPump) - { - g_main_loop_quit(mPump); - mPump = NULL; - } - - mVideoSink = NULL; - - setStatus(STATUS_NONE); - - return true; -} - - -//static -bool -MediaPluginGStreamer010::startup() -{ - // first - check if GStreamer is explicitly disabled - if (NULL != getenv("LL_DISABLE_GSTREAMER")) - return false; - - // only do global GStreamer initialization once. - if (!mDoneInit) - { - g_thread_init(NULL); - - // Init the glib type system - we need it. - g_type_init(); - - // Get symbols! -#if LL_DARWIN - if (! grab_gst_syms("libgstreamer-0.10.dylib", - "libgstvideo-0.10.dylib") ) -#elseif LL_WINDOWS - if (! grab_gst_syms("libgstreamer-0.10.dll", - "libgstvideo-0.10.dll") ) -#else // linux or other ELFy unixoid - if (! grab_gst_syms("libgstreamer-0.10.so.0", - "libgstvideo-0.10.so.0") ) -#endif - { - WARNMSG("Couldn't find suitable GStreamer 0.10 support on this system - video playback disabled."); - return false; - } - - if (llgst_segtrap_set_enabled) - { - llgst_segtrap_set_enabled(FALSE); - } - else - { - WARNMSG("gst_segtrap_set_enabled() is not available; plugin crashes won't be caught."); - } - -#if LL_LINUX - // Gstreamer tries a fork during init, waitpid-ing on it, - // which conflicts with any installed SIGCHLD handler... - struct sigaction tmpact, oldact; - if (llgst_registry_fork_set_enabled) { - // if we can disable SIGCHLD-using forking behaviour, - // do it. - llgst_registry_fork_set_enabled(false); - } - else { - // else temporarily install default SIGCHLD handler - // while GStreamer initialises - tmpact.sa_handler = SIG_DFL; - sigemptyset( &tmpact.sa_mask ); - tmpact.sa_flags = SA_SIGINFO; - sigaction(SIGCHLD, &tmpact, &oldact); - } -#endif // LL_LINUX - - // Protect against GStreamer resetting the locale, yuck. - static std::string saved_locale; - saved_locale = setlocale(LC_ALL, NULL); - - // finally, try to initialize GStreamer! - GError *err = NULL; - gboolean init_gst_success = llgst_init_check(NULL, NULL, &err); - - // restore old locale - setlocale(LC_ALL, saved_locale.c_str() ); - -#if LL_LINUX - // restore old SIGCHLD handler - if (!llgst_registry_fork_set_enabled) - sigaction(SIGCHLD, &oldact, NULL); -#endif // LL_LINUX - - if (!init_gst_success) // fail - { - if (err) - { - WARNMSG("GST init failed: %s", err->message); - g_error_free(err); - } - else - { - WARNMSG("GST init failed for unspecified reason."); - } - return false; - } - - // Init our custom plugins - only really need do this once. - gst_slvideo_init_class(); - - mDoneInit = true; - } - - return true; -} - - -void -MediaPluginGStreamer010::sizeChanged() -{ - // the shared writing space has possibly changed size/location/whatever - - // Check to see whether the movie's NATURAL size has been set yet - if (1 == mNaturalWidth && - 1 == mNaturalHeight) - { - mNaturalWidth = mCurrentWidth; - mNaturalHeight = mCurrentHeight; - DEBUGMSG("Media NATURAL size better detected as %dx%d", - mNaturalWidth, mNaturalHeight); - } - - // if the size has changed then the shm has changed and the app needs telling - if (mCurrentWidth != mPreviousWidth || - mCurrentHeight != mPreviousHeight) - { - mPreviousWidth = mCurrentWidth; - mPreviousHeight = mCurrentHeight; - - LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "size_change_request"); - message.setValue("name", mTextureSegmentName); - message.setValueS32("width", mNaturalWidth); - message.setValueS32("height", mNaturalHeight); - DEBUGMSG("<--- Sending size change request to application with name: '%s' - natural size is %d x %d", mTextureSegmentName.c_str(), mNaturalWidth, mNaturalHeight); - sendMessage(message); - } -} - - - -//static -bool -MediaPluginGStreamer010::closedown() -{ - if (!mDoneInit) - return false; // error - - ungrab_gst_syms(); - - mDoneInit = false; - - return true; -} - -MediaPluginGStreamer010::~MediaPluginGStreamer010() -{ - DEBUGMSG("MediaPluginGStreamer010 destructor"); - - closedown(); - - DEBUGMSG("GStreamer010 closing down"); -} - - -std::string -MediaPluginGStreamer010::getVersion() -{ - std::string plugin_version = "GStreamer010 media plugin, GStreamer version "; - if (mDoneInit && - llgst_version) - { - guint major, minor, micro, nano; - llgst_version(&major, &minor, µ, &nano); - plugin_version += llformat("%u.%u.%u.%u (runtime), %u.%u.%u.%u (headers)", (unsigned int)major, (unsigned int)minor, (unsigned int)micro, (unsigned int)nano, (unsigned int)GST_VERSION_MAJOR, (unsigned int)GST_VERSION_MINOR, (unsigned int)GST_VERSION_MICRO, (unsigned int)GST_VERSION_NANO); - } - else - { - plugin_version += "(unknown)"; - } - return plugin_version; -} - -void MediaPluginGStreamer010::receiveMessage(const char *message_string) -{ - //std::cerr << "MediaPluginGStreamer010::receiveMessage: received message: \"" << message_string << "\"" << std::endl; - - LLPluginMessage message_in; - - if(message_in.parse(message_string) >= 0) - { - std::string message_class = message_in.getClass(); - std::string message_name = message_in.getName(); - if(message_class == LLPLUGIN_MESSAGE_CLASS_BASE) - { - if(message_name == "init") - { - LLPluginMessage message("base", "init_response"); - LLSD versions = LLSD::emptyMap(); - versions[LLPLUGIN_MESSAGE_CLASS_BASE] = LLPLUGIN_MESSAGE_CLASS_BASE_VERSION; - versions[LLPLUGIN_MESSAGE_CLASS_MEDIA] = LLPLUGIN_MESSAGE_CLASS_MEDIA_VERSION; - versions[LLPLUGIN_MESSAGE_CLASS_MEDIA_TIME] = LLPLUGIN_MESSAGE_CLASS_MEDIA_TIME_VERSION; - message.setValueLLSD("versions", versions); - - if ( load() ) - { - DEBUGMSG("GStreamer010 media instance set up"); - } - else - { - WARNMSG("GStreamer010 media instance failed to set up"); - } - - message.setValue("plugin_version", getVersion()); - sendMessage(message); - } - else if(message_name == "idle") - { - // no response is necessary here. - double time = message_in.getValueReal("time"); - - // Convert time to milliseconds for update() - update((int)(time * 1000.0f)); - } - else if(message_name == "cleanup") - { - unload(); - closedown(); - } - else if(message_name == "shm_added") - { - SharedSegmentInfo info; - info.mAddress = message_in.getValuePointer("address"); - info.mSize = (size_t)message_in.getValueS32("size"); - std::string name = message_in.getValue("name"); - - std::ostringstream str; - INFOMSG("MediaPluginGStreamer010::receiveMessage: shared memory added, name: %s, size: %d, address: %p", name.c_str(), int(info.mSize), info.mAddress); - - mSharedSegments.insert(SharedSegmentMap::value_type(name, info)); - } - else if(message_name == "shm_remove") - { - std::string name = message_in.getValue("name"); - - DEBUGMSG("MediaPluginGStreamer010::receiveMessage: shared memory remove, name = %s", name.c_str()); - - SharedSegmentMap::iterator iter = mSharedSegments.find(name); - if(iter != mSharedSegments.end()) - { - if(mPixels == iter->second.mAddress) - { - // This is the currently active pixel buffer. Make sure we stop drawing to it. - mPixels = NULL; - mTextureSegmentName.clear(); - - // Make sure the movie decoder is no longer pointed at the shared segment. - sizeChanged(); - } - mSharedSegments.erase(iter); - } - else - { - WARNMSG("MediaPluginGStreamer010::receiveMessage: unknown shared memory region!"); - } - - // Send the response so it can be cleaned up. - LLPluginMessage message("base", "shm_remove_response"); - message.setValue("name", name); - sendMessage(message); - } - else - { - std::ostringstream str; - INFOMSG("MediaPluginGStreamer010::receiveMessage: unknown base message: %s", message_name.c_str()); - } - } - else if(message_class == LLPLUGIN_MESSAGE_CLASS_MEDIA) - { - if(message_name == "init") - { - // Plugin gets to decide the texture parameters to use. - LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "texture_params"); - // lame to have to decide this now, it depends on the movie. Oh well. - mDepth = 4; - - mCurrentWidth = 1; - mCurrentHeight = 1; - mPreviousWidth = 1; - mPreviousHeight = 1; - mNaturalWidth = 1; - mNaturalHeight = 1; - mWidth = 1; - mHeight = 1; - mTextureWidth = 1; - mTextureHeight = 1; - - message.setValueU32("format", GL_RGBA); - message.setValueU32("type", GL_UNSIGNED_INT_8_8_8_8_REV); - - message.setValueS32("depth", mDepth); - message.setValueS32("default_width", mWidth); - message.setValueS32("default_height", mHeight); - message.setValueU32("internalformat", GL_RGBA8); - message.setValueBoolean("coords_opengl", true); // true == use OpenGL-style coordinates, false == (0,0) is upper left. - message.setValueBoolean("allow_downsample", true); // we respond with grace and performance if asked to downscale - sendMessage(message); - } - else if(message_name == "size_change") - { - std::string name = message_in.getValue("name"); - S32 width = message_in.getValueS32("width"); - S32 height = message_in.getValueS32("height"); - S32 texture_width = message_in.getValueS32("texture_width"); - S32 texture_height = message_in.getValueS32("texture_height"); - - std::ostringstream str; - INFOMSG("---->Got size change instruction from application with shm name: %s - size is %d x %d", name.c_str(), width, height); - - LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "size_change_response"); - message.setValue("name", name); - message.setValueS32("width", width); - message.setValueS32("height", height); - message.setValueS32("texture_width", texture_width); - message.setValueS32("texture_height", texture_height); - sendMessage(message); - - if(!name.empty()) - { - // Find the shared memory region with this name - SharedSegmentMap::iterator iter = mSharedSegments.find(name); - if(iter != mSharedSegments.end()) - { - INFOMSG("*** Got size change with matching shm, new size is %d x %d", width, height); - INFOMSG("*** Got size change with matching shm, texture size size is %d x %d", texture_width, texture_height); - - mPixels = (unsigned char*)iter->second.mAddress; - mTextureSegmentName = name; - mWidth = width; - mHeight = height; - - if (texture_width > 1 || - texture_height > 1) // not a dummy size from the app, a real explicit forced size - { - INFOMSG("**** = REAL RESIZE REQUEST FROM APP"); - - GST_OBJECT_LOCK(mVideoSink); - mVideoSink->resize_forced_always = true; - mVideoSink->resize_try_width = texture_width; - mVideoSink->resize_try_height = texture_height; - GST_OBJECT_UNLOCK(mVideoSink); - } - - mTextureWidth = texture_width; - mTextureHeight = texture_height; - } - } - } - else if(message_name == "load_uri") - { - std::string uri = message_in.getValue("uri"); - navigateTo( uri ); - sendStatus(); - } - else if(message_name == "mouse_event") - { - std::string event = message_in.getValue("event"); - S32 x = message_in.getValueS32("x"); - S32 y = message_in.getValueS32("y"); - - if(event == "down") - { - mouseDown(x, y); - } - else if(event == "up") - { - mouseUp(x, y); - } - else if(event == "move") - { - mouseMove(x, y); - }; - }; - } - else if(message_class == LLPLUGIN_MESSAGE_CLASS_MEDIA_TIME) - { - if(message_name == "stop") - { - stop(); - } - else if(message_name == "start") - { - double rate = 0.0; - if(message_in.hasValue("rate")) - { - rate = message_in.getValueReal("rate"); - } - // NOTE: we don't actually support rate. - play(rate); - } - else if(message_name == "pause") - { - pause(); - } - else if(message_name == "seek") - { - double time = message_in.getValueReal("time"); - // defer the actual seek in case we haven't - // really truly started yet in which case there - // is nothing to seek upon - mSeekWanted = true; - mSeekDestination = time; - } - else if(message_name == "set_loop") - { - bool loop = message_in.getValueBoolean("loop"); - mIsLooping = loop; - } - else if(message_name == "set_volume") - { - double volume = message_in.getValueReal("volume"); - setVolume(volume); - } - } - else - { - INFOMSG("MediaPluginGStreamer010::receiveMessage: unknown message class: %s", message_class.c_str()); - } - } -} - -int init_media_plugin(LLPluginInstance::sendMessageFunction host_send_func, void *host_user_data, LLPluginInstance::sendMessageFunction *plugin_send_func, void **plugin_user_data) -{ - if (MediaPluginGStreamer010::startup()) - { - MediaPluginGStreamer010 *self = new MediaPluginGStreamer010(host_send_func, host_user_data); - *plugin_send_func = MediaPluginGStreamer010::staticReceiveMessage; - *plugin_user_data = (void*)self; - - return 0; // okay - } - else - { - return -1; // failed to init - } -} - -#else // LL_GSTREAMER010_ENABLED - -// Stubbed-out class with constructor/destructor (necessary or windows linker -// will just think its dead code and optimize it all out) -class MediaPluginGStreamer010 : public MediaPluginBase -{ -public: - MediaPluginGStreamer010(LLPluginInstance::sendMessageFunction host_send_func, void *host_user_data); - ~MediaPluginGStreamer010(); - /* virtual */ void receiveMessage(const char *message_string); -}; - -MediaPluginGStreamer010::MediaPluginGStreamer010( - LLPluginInstance::sendMessageFunction host_send_func, - void *host_user_data ) : - MediaPluginBase(host_send_func, host_user_data) -{ - // no-op -} - -MediaPluginGStreamer010::~MediaPluginGStreamer010() -{ - // no-op -} - -void MediaPluginGStreamer010::receiveMessage(const char *message_string) -{ - // no-op -} - -// We're building without GStreamer enabled. Just refuse to initialize. -int init_media_plugin(LLPluginInstance::sendMessageFunction host_send_func, void *host_user_data, LLPluginInstance::sendMessageFunction *plugin_send_func, void **plugin_user_data) -{ - return -1; -} - -#endif // LL_GSTREAMER010_ENABLED diff --git a/indra/media_plugins/gstreamer10/CMakeLists.txt b/indra/media_plugins/gstreamer10/CMakeLists.txt new file mode 100644 index 0000000000..f9898368cc --- /dev/null +++ b/indra/media_plugins/gstreamer10/CMakeLists.txt @@ -0,0 +1,52 @@ +# -*- cmake -*- + +project(media_plugin_gstreamer) + +include(00-Common) +include(LLCommon) +include(LLImage) +include(LLMath) +include(LLWindow) +include(Linking) +include(PluginAPI) +include(OpenGL) +include(GLIB) + +include(GStreamer10Plugin) + +### media_plugin_gstreamer10 + +set(${PROJECT_NAME}_SOURCE_FILES + media_plugin_gstreamer10.cpp + ) + +set(media_plugin_gstreamer10_HEADER_FILES + llmediaimplgstreamer_syms.h + llmediaimplgstreamertriviallogging.h + ) + +add_library(${PROJECT_NAME} + SHARED + ${${PROJECT_NAME}_SOURCE_FILES} +) + +target_link_libraries(${PROJECT_NAME} media_plugin_base ll::gstreamer10 ) + +if (WINDOWS) + set_target_properties( + media_plugin_gstreamer10 + PROPERTIES + LINK_FLAGS "/MANIFEST:NO /SAFESEH:NO /NODEFAULTLIB:LIBCMT" + ) +endif (WINDOWS) + +if (INSTALL) + if (EXISTS ${CMAKE_SYSROOT}/usr/lib/${ARCH}-linux-gnu) + set(_LIB lib/${ARCH}-linux-gnu) + elseif (EXISTS /lib64) + set(_LIB lib64) + else () + set(_LIB lib) + endif () + install(TARGETS ${PROJECT_NAME} DESTINATION ${_LIB}) +endif () diff --git a/indra/media_plugins/gstreamer010/llmediaimplgstreamer.h b/indra/media_plugins/gstreamer10/llmediaimplgstreamer.h index cae11a5cb3..cae11a5cb3 100644 --- a/indra/media_plugins/gstreamer010/llmediaimplgstreamer.h +++ b/indra/media_plugins/gstreamer10/llmediaimplgstreamer.h diff --git a/indra/media_plugins/gstreamer10/llmediaimplgstreamer_syms_raw.inc b/indra/media_plugins/gstreamer10/llmediaimplgstreamer_syms_raw.inc new file mode 100644 index 0000000000..6f5bb04bdf --- /dev/null +++ b/indra/media_plugins/gstreamer10/llmediaimplgstreamer_syms_raw.inc @@ -0,0 +1,71 @@ +#define G gstSymbolGrabber + +LL_GRAB_SYM(G, true, gst_buffer_new, GstBuffer*, void) +LL_GRAB_SYM(G, true, gst_structure_set_value, void, GstStructure *, const gchar *, const GValue*) +LL_GRAB_SYM(G, true, gst_init_check, gboolean, int *argc, char **argv[], GError ** err) +LL_GRAB_SYM(G, true, gst_message_get_type, GType, void) +LL_GRAB_SYM(G, true, gst_message_type_get_name, const gchar*, GstMessageType type) +LL_GRAB_SYM(G, true, gst_message_parse_error, void, GstMessage *message, GError **gerror, gchar **debug) +LL_GRAB_SYM(G, true, gst_message_parse_warning, void, GstMessage *message, GError **gerror, gchar **debug) +LL_GRAB_SYM(G, true, gst_message_parse_state_changed, void, GstMessage *message, GstState *oldstate, GstState *newstate, GstState *pending) +LL_GRAB_SYM(G, true, gst_element_set_state, GstStateChangeReturn, GstElement *element, GstState state) +LL_GRAB_SYM(G, true, gst_object_unref, void, gpointer object) +LL_GRAB_SYM(G, true, gst_object_get_type, GType, void) +LL_GRAB_SYM(G, true, gst_pipeline_get_type, GType, void) +LL_GRAB_SYM(G, true, gst_pipeline_get_bus, GstBus*, GstPipeline *pipeline) +LL_GRAB_SYM(G, true, gst_bus_add_watch, guint, GstBus * bus, GstBusFunc func, gpointer user_data) +LL_GRAB_SYM(G, true, gst_element_factory_make, GstElement*, const gchar *factoryname, const gchar *name) +LL_GRAB_SYM(G, true, gst_element_get_type, GType, void) +LL_GRAB_SYM(G, true, gst_static_pad_template_get, GstPadTemplate*, GstStaticPadTemplate *pad_template) +LL_GRAB_SYM(G, true, gst_element_class_add_pad_template, void, GstElementClass *klass, GstPadTemplate *temp) +LL_GRAB_SYM(G, true, gst_caps_from_string, GstCaps *, const gchar *string) +LL_GRAB_SYM(G, true, gst_caps_get_structure, GstStructure *, const GstCaps *caps, guint index) +LL_GRAB_SYM(G, true, gst_element_register, gboolean, GstPlugin *plugin, const gchar *name, guint rank, GType type) +LL_GRAB_SYM(G, true, gst_structure_get_int, gboolean, const GstStructure *structure, const gchar *fieldname, gint *value) +LL_GRAB_SYM(G, true, gst_structure_get_value, const GValue *, const GstStructure *structure, const gchar *fieldname) +LL_GRAB_SYM(G, true, gst_value_get_fraction_numerator, gint, const GValue *value) +LL_GRAB_SYM(G, true, gst_value_get_fraction_denominator, gint, const GValue *value) +LL_GRAB_SYM(G, true, gst_structure_get_name, const gchar *, const GstStructure *structure) +LL_GRAB_SYM(G, true, gst_element_seek, bool, GstElement *, gdouble, GstFormat, GstSeekFlags, GstSeekType, gint64, GstSeekType, gint64) + +LL_GRAB_SYM(G, false, gst_registry_fork_set_enabled, void, gboolean enabled) +LL_GRAB_SYM(G, false, gst_segtrap_set_enabled, void, gboolean enabled) +LL_GRAB_SYM(G, false, gst_message_parse_buffering, void, GstMessage *message, gint *percent) +LL_GRAB_SYM(G, false, gst_message_parse_info, void, GstMessage *message, GError **gerror, gchar **debug) +LL_GRAB_SYM(G, false, gst_element_query_position, gboolean, GstElement *element, GstFormat *format, gint64 *cur) +LL_GRAB_SYM(G, false, gst_version, void, guint *major, guint *minor, guint *micro, guint *nano) + +LL_GRAB_SYM(G, true, gst_message_parse_tag, void, GstMessage *, GstTagList **) +LL_GRAB_SYM(G, true, gst_tag_list_foreach, void, const GstTagList *, GstTagForeachFunc, gpointer) +LL_GRAB_SYM(G, true, gst_tag_list_get_tag_size, guint, const GstTagList *, const gchar *) +LL_GRAB_SYM(G, true, gst_tag_list_get_value_index, const GValue *, const GstTagList *, const gchar *, guint) + +LL_GRAB_SYM(G, true, gst_caps_new_simple, GstCaps*, const char *, const char*, ... ) + +LL_GRAB_SYM(G, true, gst_sample_get_caps, GstCaps*, GstSample* ) +LL_GRAB_SYM(G, true, gst_sample_get_buffer, GstBuffer*, GstSample* ) +LL_GRAB_SYM(G, true, gst_buffer_map, gboolean, GstBuffer*, GstMapInfo*, GstMapFlags ) +LL_GRAB_SYM(G, true, gst_buffer_unmap, void, GstBuffer*, GstMapInfo* ) + +LL_GRAB_SYM(G, true, gst_app_sink_set_caps, void, GstAppSink*, GstCaps const* ) +LL_GRAB_SYM(G, true, gst_app_sink_pull_sample, GstSample*, GstAppSink* ) + +LL_GRAB_SYM(G, true, g_free, void, gpointer ) +LL_GRAB_SYM(G, true, g_error_free, void, GError* ) + +LL_GRAB_SYM(G, true, g_main_context_pending, gboolean, GMainContext* ) +LL_GRAB_SYM(G, true, g_main_loop_get_context, GMainContext*, GMainLoop* ) +LL_GRAB_SYM(G, true, g_main_context_iteration, gboolean, GMainContext*, gboolean ) +LL_GRAB_SYM(G, true, g_main_loop_new, GMainLoop*, GMainContext*, gboolean ) +LL_GRAB_SYM(G, true, g_main_loop_quit, void, GMainLoop* ) +LL_GRAB_SYM(G, true, gst_mini_object_unref, void, GstMiniObject* ) +LL_GRAB_SYM(G, true, g_object_set, void, gpointer, gchar const*, ... ) +LL_GRAB_SYM(G, true, g_source_remove, gboolean, guint ) +LL_GRAB_SYM(G, true, g_value_get_string, gchar const*, GValue const* ) + +LL_GRAB_SYM(G, true, gst_debug_set_active, void, gboolean ) +LL_GRAB_SYM(G, true, gst_debug_add_log_function, void, GstLogFunction, gpointer, GDestroyNotify ) +LL_GRAB_SYM(G, true, gst_debug_set_default_threshold, void, GstDebugLevel ) +LL_GRAB_SYM(G, true, gst_debug_message_get , gchar const*, GstDebugMessage * ) + +#undef G diff --git a/indra/media_plugins/gstreamer10/media_plugin_gstreamer10.cpp b/indra/media_plugins/gstreamer10/media_plugin_gstreamer10.cpp new file mode 100644 index 0000000000..3f636915ea --- /dev/null +++ b/indra/media_plugins/gstreamer10/media_plugin_gstreamer10.cpp @@ -0,0 +1,958 @@ +/** + * @file media_plugin_gstreamer10.cpp + * @brief GStreamer-1.0 plugin for LLMedia API plugin system + * + * @cond + * $LicenseInfo:firstyear=2016&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2016, Linden Research, Inc. / Nicky Dasmijn + * + * 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$ + * @endcond + */ + +#define FLIP_Y + +#include "linden_common.h" + +#include "llgl.h" + +#include "llplugininstance.h" +#include "llpluginmessage.h" +#include "llpluginmessageclasses.h" +#include "media_plugin_base.h" + +#define G_DISABLE_CAST_CHECKS +extern "C" { +#include <gst/gst.h> +#include <gst/app/gstappsink.h> +} + +SymbolGrabber gstSymbolGrabber; + +#include "llmediaimplgstreamer_syms_raw.inc" + +static inline void llgst_caps_unref( GstCaps * caps ) +{ + llgst_mini_object_unref( GST_MINI_OBJECT_CAST( caps ) ); +} + +static inline void llgst_sample_unref( GstSample *aSample ) +{ + llgst_mini_object_unref( GST_MINI_OBJECT_CAST( aSample ) ); +} + +////////////////////////////////////////////////////////////////////////////// +// +class MediaPluginGStreamer10 : public MediaPluginBase +{ +public: + MediaPluginGStreamer10(LLPluginInstance::sendMessageFunction host_send_func, void *host_user_data); + ~MediaPluginGStreamer10(); + + /* virtual */ void receiveMessage(const char *message_string); + + static bool startup(); + static bool closedown(); + + gboolean processGSTEvents(GstBus *bus, GstMessage *message); + +private: + std::string getVersion(); + bool navigateTo( const std::string urlIn ); + bool seek( double time_sec ); + bool setVolume( float volume ); + + // misc + bool pause(); + bool stop(); + bool play(double rate); + bool getTimePos(double &sec_out); + + double MIN_LOOP_SEC = 1.0F; + U32 INTERNAL_TEXTURE_SIZE = 1024; + + bool mIsLooping; + + enum ECommand { + COMMAND_NONE, + COMMAND_STOP, + COMMAND_PLAY, + COMMAND_FAST_FORWARD, + COMMAND_FAST_REWIND, + COMMAND_PAUSE, + COMMAND_SEEK, + }; + ECommand mCommand; + +private: + bool unload(); + bool load(); + + bool update(int milliseconds); + void mouseDown( int x, int y ); + void mouseUp( int x, int y ); + void mouseMove( int x, int y ); + + static bool mDoneInit; + + guint mBusWatchID; + + float mVolume; + + int mDepth; + + // padded texture size we need to write into + int mTextureWidth; + int mTextureHeight; + + bool mSeekWanted; + double mSeekDestination; + + // Very GStreamer-specific + GMainLoop *mPump; // event pump for this media + GstElement *mPlaybin; + GstAppSink *mAppSink; +}; + +//static +bool MediaPluginGStreamer10::mDoneInit = false; + +MediaPluginGStreamer10::MediaPluginGStreamer10( LLPluginInstance::sendMessageFunction host_send_func, + void *host_user_data ) + : MediaPluginBase(host_send_func, host_user_data) + , mBusWatchID ( 0 ) + , mSeekWanted(false) + , mSeekDestination(0.0) + , mPump ( nullptr ) + , mPlaybin ( nullptr ) + , mAppSink ( nullptr ) + , mCommand ( COMMAND_NONE ) +{ +} + +gboolean MediaPluginGStreamer10::processGSTEvents(GstBus *bus, GstMessage *message) +{ + if (!message) + return TRUE; // shield against GStreamer bug + + switch (GST_MESSAGE_TYPE (message)) + { + case GST_MESSAGE_BUFFERING: + { + // NEEDS GST 0.10.11+ + if (llgst_message_parse_buffering) + { + gint percent = 0; + llgst_message_parse_buffering(message, &percent); + } + break; + } + case GST_MESSAGE_STATE_CHANGED: + { + GstState old_state; + GstState new_state; + GstState pending_state; + llgst_message_parse_state_changed(message, + &old_state, + &new_state, + &pending_state); + + switch (new_state) + { + case GST_STATE_VOID_PENDING: + break; + case GST_STATE_NULL: + break; + case GST_STATE_READY: + setStatus(STATUS_LOADED); + break; + case GST_STATE_PAUSED: + setStatus(STATUS_PAUSED); + break; + case GST_STATE_PLAYING: + setStatus(STATUS_PLAYING); + break; + } + break; + } + case GST_MESSAGE_ERROR: + { + GError *err = nullptr; + gchar *debug = nullptr; + + llgst_message_parse_error (message, &err, &debug); + if (err) + llg_error_free (err); + llg_free (debug); + + mCommand = COMMAND_STOP; + + setStatus(STATUS_ERROR); + + break; + } + case GST_MESSAGE_INFO: + { + if (llgst_message_parse_info) + { + GError *err = nullptr; + gchar *debug = nullptr; + + llgst_message_parse_info (message, &err, &debug); + if (err) + llg_error_free (err); + llg_free (debug); + } + break; + } + case GST_MESSAGE_WARNING: + { + GError *err = nullptr; + gchar *debug = nullptr; + + llgst_message_parse_warning (message, &err, &debug); + if (err) + llg_error_free (err); + llg_free (debug); + + break; + } + case GST_MESSAGE_EOS: + /* end-of-stream */ + if (mIsLooping) + { + double eos_pos_sec = 0.0F; + bool got_eos_position = getTimePos(eos_pos_sec); + + if (got_eos_position && eos_pos_sec < MIN_LOOP_SEC) + { + // if we know that the movie is really short, don't + // loop it else it can easily become a time-hog + // because of GStreamer spin-up overhead + // inject a COMMAND_PAUSE + mCommand = COMMAND_PAUSE; + } + else + { + stop(); + play(1.0); + } + } + else // not a looping media + { + // inject a COMMAND_STOP + mCommand = COMMAND_STOP; + } + break; + default: + /* unhandled message */ + break; + } + + /* we want to be notified again the next time there is a message + * on the bus, so return true (false means we want to stop watching + * for messages on the bus and our callback should not be called again) + */ + return TRUE; +} + +extern "C" { + gboolean llmediaimplgstreamer_bus_callback (GstBus *bus, + GstMessage *message, + gpointer data) + { + MediaPluginGStreamer10 *impl = (MediaPluginGStreamer10*)data; + return impl->processGSTEvents(bus, message); + } +} // extern "C" + + + +bool MediaPluginGStreamer10::navigateTo ( const std::string urlIn ) +{ + if (!mDoneInit) + return false; // error + + setStatus(STATUS_LOADING); + + mSeekWanted = false; + + if (nullptr == mPump || nullptr == mPlaybin) + { + setStatus(STATUS_ERROR); + return false; // error + } + + llg_object_set (G_OBJECT (mPlaybin), "uri", urlIn.c_str(), nullptr); + + // navigateTo implicitly plays, too. + play(1.0); + + return true; +} + + +class GstSampleUnref +{ + GstSample *mT; +public: + GstSampleUnref( GstSample *aT ) + : mT( aT ) + { llassert_always( mT ); } + + ~GstSampleUnref( ) + { llgst_sample_unref( mT ); } +}; + +bool MediaPluginGStreamer10::update(int milliseconds) +{ + if (!mDoneInit) + return false; // error + + // DEBUGMSG("updating media..."); + + // sanity check + if (nullptr == mPump || nullptr == mPlaybin) + { + return false; + } + + // see if there's an outstanding seek wanted + if (mSeekWanted && + // bleh, GST has to be happy that the movie is really truly playing + // or it may quietly ignore the seek (with rtsp:// at least). + (GST_STATE(mPlaybin) == GST_STATE_PLAYING)) + { + seek(mSeekDestination); + mSeekWanted = false; + } + + // *TODO: time-limit - but there isn't a lot we can do here, most + // time is spent in gstreamer's own opaque worker-threads. maybe + // we can do something sneaky like only unlock the video object + // for 'milliseconds' and otherwise hold the lock. + while (llg_main_context_pending(llg_main_loop_get_context(mPump))) + { + llg_main_context_iteration(llg_main_loop_get_context(mPump), FALSE); + } + + // check for availability of a new frame + + if( !mAppSink ) + return true; + + if( GST_STATE(mPlaybin) != GST_STATE_PLAYING) // Do not try to pull a sample if not in playing state + return true; + + GstSample *pSample = llgst_app_sink_pull_sample( mAppSink ); + if(!pSample) + return false; // Done playing + + GstSampleUnref oSampleUnref( pSample ); + GstCaps *pCaps = llgst_sample_get_caps ( pSample ); + if (!pCaps) + return false; + + gint width = 0, height = 0; + GstStructure *pStruct = llgst_caps_get_structure ( pCaps, 0); + + if(!llgst_structure_get_int ( pStruct, "width", &width) ) + width = 0; + if(!llgst_structure_get_int ( pStruct, "height", &height) ) + height = 0; + + if( !mPixels || width == 0 || height == 0) + return true; + + GstBuffer *pBuffer = llgst_sample_get_buffer ( pSample ); + GstMapInfo map; + llgst_buffer_map ( pBuffer, &map, GST_MAP_READ); + + // Our render buffer is always 1kx1k + + U32 rowSkip = INTERNAL_TEXTURE_SIZE / mTextureHeight; + U32 colSkip = INTERNAL_TEXTURE_SIZE / mTextureWidth; + + for (int row = 0; row < mTextureHeight; ++row) + { + U8 const *pTexelIn = map.data + (row*rowSkip * width *3); +#ifndef FLIP_Y + U8 *pTexelOut = mPixels + (row * mTextureWidth * mDepth ); +#else + U8 *pTexelOut = mPixels + ((mTextureHeight-row-1) * mTextureWidth * mDepth ); +#endif + for( int col = 0; col < mTextureWidth; ++col ) + { + pTexelOut[ 0 ] = pTexelIn[0]; + pTexelOut[ 1 ] = pTexelIn[1]; + pTexelOut[ 2 ] = pTexelIn[2]; + pTexelOut += mDepth; + pTexelIn += colSkip*3; + } + } + + llgst_buffer_unmap( pBuffer, &map ); + setDirty(0,0,mTextureWidth,mTextureHeight); + + return true; +} + +void MediaPluginGStreamer10::mouseDown( int x, int y ) +{ + // do nothing +} + +void MediaPluginGStreamer10::mouseUp( int x, int y ) +{ + // do nothing +} + +void MediaPluginGStreamer10::mouseMove( int x, int y ) +{ + // do nothing +} + + +bool MediaPluginGStreamer10::pause() +{ + // todo: error-check this? + if (mDoneInit && mPlaybin) + { + llgst_element_set_state(mPlaybin, GST_STATE_PAUSED); + return true; + } + return false; +} + +bool MediaPluginGStreamer10::stop() +{ + // todo: error-check this? + if (mDoneInit && mPlaybin) + { + llgst_element_set_state(mPlaybin, GST_STATE_READY); + return true; + } + return false; +} + +bool MediaPluginGStreamer10::play(double rate) +{ + // NOTE: we don't actually support non-natural rate. + + // todo: error-check this? + if (mDoneInit && mPlaybin) + { + llgst_element_set_state(mPlaybin, GST_STATE_PLAYING); + return true; + } + return false; +} + +bool MediaPluginGStreamer10::setVolume( float volume ) +{ + // we try to only update volume as conservatively as + // possible, as many gst-plugins-base versions up to at least + // November 2008 have critical race-conditions in setting volume - sigh + if (mVolume == volume) + return true; // nothing to do, everything's fine + + mVolume = volume; + if (mDoneInit && mPlaybin) + { + llg_object_set(mPlaybin, "volume", mVolume, nullptr); + return true; + } + + return false; +} + +bool MediaPluginGStreamer10::seek(double time_sec) +{ + bool success = false; + if (mDoneInit && mPlaybin) + { + success = llgst_element_seek(mPlaybin, 1.0F, GST_FORMAT_TIME, + GstSeekFlags(GST_SEEK_FLAG_FLUSH | + GST_SEEK_FLAG_KEY_UNIT), + GST_SEEK_TYPE_SET, gint64(time_sec*GST_SECOND), + GST_SEEK_TYPE_NONE, GST_CLOCK_TIME_NONE); + } + return success; +} + +bool MediaPluginGStreamer10::getTimePos(double &sec_out) +{ + bool got_position = false; + if (mDoneInit && mPlaybin) + { + gint64 pos(0); + GstFormat timefmt = GST_FORMAT_TIME; + got_position = + llgst_element_query_position && + llgst_element_query_position(mPlaybin, + &timefmt, + &pos); + got_position = got_position + && (timefmt == GST_FORMAT_TIME); + // GStreamer may have other ideas, but we consider the current position + // undefined if not PLAYING or PAUSED + got_position = got_position && + (GST_STATE(mPlaybin) == GST_STATE_PLAYING || + GST_STATE(mPlaybin) == GST_STATE_PAUSED); + if (got_position && !GST_CLOCK_TIME_IS_VALID(pos)) + { + if (GST_STATE(mPlaybin) == GST_STATE_PLAYING) + { + // if we're playing then we treat an invalid clock time + // as 0, for complicated reasons (insert reason here) + pos = 0; + } + else + { + got_position = false; + } + + } + // If all the preconditions succeeded... we can trust the result. + if (got_position) + { + sec_out = double(pos) / double(GST_SECOND); // gst to sec + } + } + return got_position; +} + +bool MediaPluginGStreamer10::load() +{ + if (!mDoneInit) + return false; // error + + setStatus(STATUS_LOADING); + + mIsLooping = false; + mVolume = 0.1234567f; // minor hack to force an initial volume update + + // Create a pumpable main-loop for this media + mPump = llg_main_loop_new (nullptr, FALSE); + if (!mPump) + { + setStatus(STATUS_ERROR); + return false; // error + } + + // instantiate a playbin element to do the hard work + mPlaybin = llgst_element_factory_make ("playbin", ""); + if (!mPlaybin) + { + setStatus(STATUS_ERROR); + return false; // error + } + + // get playbin's bus + GstBus *bus = llgst_pipeline_get_bus (GST_PIPELINE (mPlaybin)); + if (!bus) + { + setStatus(STATUS_ERROR); + return false; // error + } + mBusWatchID = llgst_bus_add_watch (bus, + llmediaimplgstreamer_bus_callback, + this); + llgst_object_unref (bus); + + mAppSink = (GstAppSink*)(llgst_element_factory_make ("appsink", "")); + + GstCaps* pCaps = llgst_caps_new_simple( "video/x-raw", + "format", G_TYPE_STRING, "RGB", + "width", G_TYPE_INT, INTERNAL_TEXTURE_SIZE, + "height", G_TYPE_INT, INTERNAL_TEXTURE_SIZE, + nullptr ); + + llgst_app_sink_set_caps( mAppSink, pCaps ); + llgst_caps_unref( pCaps ); + + if (!mAppSink) + { + setStatus(STATUS_ERROR); + return false; + } + + llg_object_set(mPlaybin, "video-sink", mAppSink, nullptr); + + return true; +} + +bool MediaPluginGStreamer10::unload () +{ + if (!mDoneInit) + return false; // error + + // stop getting callbacks for this bus + llg_source_remove(mBusWatchID); + mBusWatchID = 0; + + if (mPlaybin) + { + llgst_element_set_state (mPlaybin, GST_STATE_NULL); + llgst_object_unref (GST_OBJECT (mPlaybin)); + mPlaybin = nullptr; + } + + if (mPump) + { + llg_main_loop_quit(mPump); + mPump = nullptr; + } + + mAppSink = nullptr; + + setStatus(STATUS_NONE); + + return true; +} + +void LogFunction(GstDebugCategory *category, GstDebugLevel level, const gchar *file, const gchar *function, gint line, GObject *object, GstDebugMessage *message, gpointer user_data ) +{ + std::cerr << file << ":" << line << "(" << function << "): " << llgst_debug_message_get( message ) << std::endl; +} + +//static +bool MediaPluginGStreamer10::startup() +{ + // first - check if GStreamer is explicitly disabled + if (nullptr != getenv("LL_DISABLE_GSTREAMER")) + return false; + + // only do global GStreamer initialization once. + if (!mDoneInit) + { + ll_init_apr(); + + // Get symbols! + std::vector< std::string > vctDSONames; + vctDSONames.push_back( "libgstreamer-1.0.so.0" ); + vctDSONames.push_back( "libgstapp-1.0.so.0" ); + vctDSONames.push_back( "libglib-2.0.so.0" ); + vctDSONames.push_back( "libgobject-2.0.so" ); + if( !gstSymbolGrabber.grabSymbols( vctDSONames ) ) + return false; + + if (llgst_segtrap_set_enabled) + { + llgst_segtrap_set_enabled(FALSE); + } + + // Gstreamer tries a fork during init, waitpid-ing on it, + // which conflicts with any installed SIGCHLD handler... + struct sigaction tmpact, oldact; + if (llgst_registry_fork_set_enabled ) { + // if we can disable SIGCHLD-using forking behaviour, + // do it. + llgst_registry_fork_set_enabled(false); + } + else { + // else temporarily install default SIGCHLD handler + // while GStreamer initialises + tmpact.sa_handler = SIG_DFL; + sigemptyset( &tmpact.sa_mask ); + tmpact.sa_flags = SA_SIGINFO; + sigaction(SIGCHLD, &tmpact, &oldact); + } + // Protect against GStreamer resetting the locale, yuck. + static std::string saved_locale; + saved_locale = setlocale(LC_ALL, nullptr); + + llgst_debug_set_default_threshold( GST_LEVEL_WARNING ); + llgst_debug_add_log_function( LogFunction, nullptr, nullptr ); + llgst_debug_set_active( false ); + + // finally, try to initialize GStreamer! + GError *err = nullptr; + gboolean init_gst_success = llgst_init_check(nullptr, nullptr, &err); + + // restore old locale + setlocale(LC_ALL, saved_locale.c_str() ); + + // restore old SIGCHLD handler + if (!llgst_registry_fork_set_enabled) + sigaction(SIGCHLD, &oldact, nullptr); + + if (!init_gst_success) // fail + { + if (err) + llg_error_free(err); + return false; + } + + mDoneInit = true; + } + + return true; +} + +//static +bool MediaPluginGStreamer10::closedown() +{ + if (!mDoneInit) + return false; // error + + gstSymbolGrabber.ungrabSymbols(); + mDoneInit = false; + + return true; +} + +MediaPluginGStreamer10::~MediaPluginGStreamer10() +{ + closedown(); +} + +std::string MediaPluginGStreamer10::getVersion() +{ + std::string plugin_version = "GStreamer10 media plugin, GStreamer version "; + if (mDoneInit && + llgst_version) + { + guint major, minor, micro, nano; + llgst_version(&major, &minor, µ, &nano); + plugin_version += llformat("%u.%u.%u.%u (runtime), %u.%u.%u.%u (headers)", (unsigned int)major, (unsigned int)minor, + (unsigned int)micro, (unsigned int)nano, (unsigned int)GST_VERSION_MAJOR, (unsigned int)GST_VERSION_MINOR, + (unsigned int)GST_VERSION_MICRO, (unsigned int)GST_VERSION_NANO); + } + else + { + plugin_version += "(unknown)"; + } + return plugin_version; +} + +void MediaPluginGStreamer10::receiveMessage(const char *message_string) +{ + LLPluginMessage message_in; + + if(message_in.parse(message_string) >= 0) + { + std::string message_class = message_in.getClass(); + std::string message_name = message_in.getName(); + + if(message_class == LLPLUGIN_MESSAGE_CLASS_BASE) + { + if(message_name == "init") + { + LLPluginMessage message("base", "init_response"); + LLSD versions = LLSD::emptyMap(); + versions[LLPLUGIN_MESSAGE_CLASS_BASE] = LLPLUGIN_MESSAGE_CLASS_BASE_VERSION; + versions[LLPLUGIN_MESSAGE_CLASS_MEDIA] = LLPLUGIN_MESSAGE_CLASS_MEDIA_VERSION; + versions[LLPLUGIN_MESSAGE_CLASS_MEDIA_TIME] = LLPLUGIN_MESSAGE_CLASS_MEDIA_TIME_VERSION; + message.setValueLLSD("versions", versions); + + load(); + + message.setValue("plugin_version", getVersion()); + sendMessage(message); + } + else if(message_name == "idle") + { + // no response is necessary here. + double time = message_in.getValueReal("time"); + + // Convert time to milliseconds for update() + update((int)(time * 1000.0f)); + } + else if(message_name == "cleanup") + { + unload(); + closedown(); + } + else if(message_name == "shm_added") + { + SharedSegmentInfo info; + info.mAddress = message_in.getValuePointer("address"); + info.mSize = (size_t)message_in.getValueS32("size"); + std::string name = message_in.getValue("name"); + + mSharedSegments.insert(SharedSegmentMap::value_type(name, info)); + } + else if(message_name == "shm_remove") + { + std::string name = message_in.getValue("name"); + + SharedSegmentMap::iterator iter = mSharedSegments.find(name); + if(iter != mSharedSegments.end()) + { + if(mPixels == iter->second.mAddress) + { + // This is the currently active pixel buffer. Make sure we stop drawing to it. + mPixels = nullptr; + mTextureSegmentName.clear(); + } + mSharedSegments.erase(iter); + } + + // Send the response so it can be cleaned up. + LLPluginMessage message("base", "shm_remove_response"); + message.setValue("name", name); + sendMessage(message); + } + } + else if(message_class == LLPLUGIN_MESSAGE_CLASS_MEDIA) + { + if(message_name == "init") + { + // Plugin gets to decide the texture parameters to use. + LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "texture_params"); + // lame to have to decide this now, it depends on the movie. Oh well. + mDepth = 4; + + mTextureWidth = 1; + mTextureHeight = 1; + + message.setValueU32("format", GL_RGBA); + message.setValueU32("type", GL_UNSIGNED_INT_8_8_8_8_REV); + + message.setValueS32("depth", mDepth); + message.setValueS32("default_width", INTERNAL_TEXTURE_SIZE ); + message.setValueS32("default_height", INTERNAL_TEXTURE_SIZE ); + message.setValueU32("internalformat", GL_RGBA8); + message.setValueBoolean("coords_opengl", true); // true == use OpenGL-style coordinates, false == (0,0) is upper left. + message.setValueBoolean("allow_downsample", true); // we respond with grace and performance if asked to downscale + sendMessage(message); + } + else if(message_name == "size_change") + { + std::string name = message_in.getValue("name"); + S32 width = message_in.getValueS32("width"); + S32 height = message_in.getValueS32("height"); + S32 texture_width = message_in.getValueS32("texture_width"); + S32 texture_height = message_in.getValueS32("texture_height"); + + LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "size_change_response"); + message.setValue("name", name); + message.setValueS32("width", width); + message.setValueS32("height", height); + message.setValueS32("texture_width", texture_width); + message.setValueS32("texture_height", texture_height); + sendMessage(message); + + if(!name.empty()) + { + // Find the shared memory region with this name + SharedSegmentMap::iterator iter = mSharedSegments.find(name); + if(iter != mSharedSegments.end()) + { + mPixels = (unsigned char*)iter->second.mAddress; + mTextureSegmentName = name; + + mTextureWidth = texture_width; + mTextureHeight = texture_height; + memset( mPixels, 0, mTextureWidth*mTextureHeight*mDepth ); + } + + LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "size_change_request"); + message.setValue("name", mTextureSegmentName); + message.setValueS32("width", INTERNAL_TEXTURE_SIZE ); + message.setValueS32("height", INTERNAL_TEXTURE_SIZE ); + sendMessage(message); + + } + } + else if(message_name == "load_uri") + { + std::string uri = message_in.getValue("uri"); + navigateTo( uri ); + sendStatus(); + } + else if(message_name == "mouse_event") + { + std::string event = message_in.getValue("event"); + S32 x = message_in.getValueS32("x"); + S32 y = message_in.getValueS32("y"); + + if(event == "down") + { + mouseDown(x, y); + } + else if(event == "up") + { + mouseUp(x, y); + } + else if(event == "move") + { + mouseMove(x, y); + }; + }; + } + else if(message_class == LLPLUGIN_MESSAGE_CLASS_MEDIA_TIME) + { + if(message_name == "stop") + { + stop(); + } + else if(message_name == "start") + { + double rate = 0.0; + if(message_in.hasValue("rate")) + { + rate = message_in.getValueReal("rate"); + } + // NOTE: we don't actually support rate. + play(rate); + } + else if(message_name == "pause") + { + pause(); + } + else if(message_name == "seek") + { + double time = message_in.getValueReal("time"); + // defer the actual seek in case we haven't + // really truly started yet in which case there + // is nothing to seek upon + mSeekWanted = true; + mSeekDestination = time; + } + else if(message_name == "set_loop") + { + bool loop = message_in.getValueBoolean("loop"); + mIsLooping = loop; + } + else if(message_name == "set_volume") + { + double volume = message_in.getValueReal("volume"); + setVolume(volume); + } + } + } +} + +int init_media_plugin(LLPluginInstance::sendMessageFunction host_send_func, void *host_user_data, LLPluginInstance::sendMessageFunction *plugin_send_func, void **plugin_user_data) +{ + if( MediaPluginGStreamer10::startup() ) + { + MediaPluginGStreamer10 *self = new MediaPluginGStreamer10(host_send_func, host_user_data); + *plugin_send_func = MediaPluginGStreamer10::staticReceiveMessage; + *plugin_user_data = (void*)self; + + return 0; // okay + } + else + { + return -1; // failed to init + } +} diff --git a/indra/media_plugins/libvlc/CMakeLists.txt b/indra/media_plugins/libvlc/CMakeLists.txt index 202cbed96e..547733496f 100644 --- a/indra/media_plugins/libvlc/CMakeLists.txt +++ b/indra/media_plugins/libvlc/CMakeLists.txt @@ -13,13 +13,6 @@ include(LibVLCPlugin) ### media_plugin_libvlc -if(NOT ADDRESS_SIZE EQUAL 32) - if(WINDOWS) - ##add_definitions(/FIXED:NO) - else(WINDOWS) # not windows therefore gcc LINUX and DARWIN - add_definitions(-fPIC) - endif(WINDOWS) -endif(NOT ADDRESS_SIZE EQUAL 32) set(media_plugin_libvlc_SOURCE_FILES media_plugin_libvlc.cpp @@ -54,4 +47,55 @@ if (DARWIN) LINK_FLAGS "-exported_symbols_list ${CMAKE_CURRENT_SOURCE_DIR}/../base/media_plugin_base.exp" ) + add_custom_command(TARGET ${PROJECT_NAME} + POST_BUILD COMMAND ${CMAKE_INSTALL_NAME_TOOL} + -change "/opt/local/lib/libpng16.16.dylib" "@loader_path/../../Frameworks/libpng16.16.dylib" + -change "/opt/local/lib/libjpeg.8.dylib" "@loader_path/../../Frameworks/libjpeg.8.dylib" + -change "/opt/local/lib/libfreetype.6.dylib" "@loader_path/../../Frameworks/libfreetype.6.dylib" + -change "/opt/local/lib/libaprutil-1.0.dylib" "@loader_path/../../Frameworks/libaprutil-1.0.dylib" + -change "/opt/local/lib/libiconv.2.dylib" "@loader_path/../../Frameworks/libiconv.2.dylib" + -change "/opt/local/lib/libapr-1.0.dylib" "@loader_path/../../Frameworks/libapr-1.0.dylib" + -change "/opt/local/lib/libexpat.1.dylib" "@loader_path/../../Frameworks/libexpat.1.dylib" + -change "/opt/local/libexec/boost/1.87/lib/libboost_context-mt.dylib" "@loader_path/../../Frameworks/libboost_context-mt.dylib" + -change "/opt/local/libexec/boost/1.87/lib/libboost_fiber-mt.dylib" "@loader_path/../../Frameworks/libboost_fiber-mt.dylib" + -change "/opt/local/libexec/boost/1.87/lib/libboost_filesystem-mt.dylib" "@loader_path/../../Frameworks/libboost_filesystem-mt.dylib" + -change "/opt/local/libexec/boost/1.87/lib/libboost_program_options-mt.dylib" "@loader_path/../../Frameworks/libboost_program_options-mt.dylib" + -change "/opt/local/libexec/boost/1.87/lib/libboost_regex-mt.dylib" "@loader_path/../../Frameworks/libboost_regex-mt.dylib" + -change "/opt/local/libexec/boost/1.87/lib/libboost_system-mt.dylib" "@loader_path/../../Frameworks/libboost_system-mt.dylib" + -change "/opt/local/libexec/boost/1.87/lib/libboost_thread-mt.dylib" "@loader_path/../../Frameworks/libboost_thread-mt.dylib" + -change "/opt/local/libexec/boost/1.87/lib/libboost_url-mt.dylib" "@loader_path/../../Frameworks/libboost_url-mt.dylib" + -change "/opt/local/lib/libz.1.dylib" "@loader_path/../../Frameworks/libz.1.dylib" + -change "/opt/local/lib/libnghttp2.14.dylib" "@loader_path/../../Frameworks/libnghttp2.14.dylib" + -change "@rpath/libvlc.dylib" "@loader_path/plugins/libvlc.dylib" + -change "@rpath/libvlccore.dylib" "@loader_path/plugins/libvlccore.dylib" + "$<TARGET_FILE:media_plugin_libvlc>" + VERBATIM + COMMENT "Fixing paths to LibVLC media plugin dependencies" + ) + endif (DARWIN) + +if (INSTALL) + if (DARWIN) + set(_LIB llplugin) + install( + DIRECTORY /Volumes/VLC\ media\ player/VLC.app/Contents/MacOS/plugins + DESTINATION ${_LIB} + ) + install( + FILES + /Volumes/VLC\ media\ player/VLC.app/Contents/MacOS/lib/libvlc.5.dylib + /Volumes/VLC\ media\ player/VLC.app/Contents/MacOS/lib/libvlc.dylib + /Volumes/VLC\ media\ player/VLC.app/Contents/MacOS/lib/libvlccore.9.dylib + /Volumes/VLC\ media\ player/VLC.app/Contents/MacOS/lib/libvlccore.dylib + DESTINATION ${_LIB}/plugins + ) + elseif (${LINUX_DISTRO} MATCHES debian OR (${LINUX_DISTRO} MATCHES ubuntu)) + set(_LIB lib/${ARCH}-linux-gnu) + elseif (${LINUX_DISTRO} MATCHES fedora OR (${LINUX_DISTRO} MATCHES opensuse-tumbleweed) OR (${LINUX_DISTRO} MATCHES gentoo)) + set(_LIB lib${ADDRESS_SIZE}) + else (DARWIN) + set(_LIB lib) + endif (DARWIN) + install(TARGETS ${PROJECT_NAME} DESTINATION ${_LIB}) +endif (INSTALL) diff --git a/indra/media_plugins/libvlc/media_plugin_libvlc.cpp b/indra/media_plugins/libvlc/media_plugin_libvlc.cpp index 4240613a0c..e79d474325 100644 --- a/indra/media_plugins/libvlc/media_plugin_libvlc.cpp +++ b/indra/media_plugins/libvlc/media_plugin_libvlc.cpp @@ -294,6 +294,22 @@ void MediaPluginLibVLC::eventCallbacks(const libvlc_event_t* event, void* ptr) } } break; + case libvlc_MediaMetaChanged: + auto title = libvlc_media_get_meta(parent->mLibVLCMedia, libvlc_meta_Title); + if (title) + { + LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "title_text"); + message.setValue("title", title); + parent->sendMessage(message); + } + auto now_playing = libvlc_media_get_meta(parent->mLibVLCMedia, libvlc_meta_NowPlaying); + if (now_playing) + { + LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "nowplaying_text"); + message.setValue("nowplaying", now_playing); + parent->sendMessage(message); + } + break; } } @@ -348,6 +364,11 @@ void MediaPluginLibVLC::playMedia() libvlc_event_attach(em, libvlc_MediaPlayerLengthChanged, eventCallbacks, this); libvlc_event_attach(em, libvlc_MediaPlayerTitleChanged, eventCallbacks, this); } + auto event_manager = libvlc_media_event_manager(mLibVLCMedia); + if (event_manager) + { + libvlc_event_attach(event_manager, libvlc_MediaMetaChanged, eventCallbacks, this); + } libvlc_video_set_callbacks(mLibVLCMediaPlayer, lock, unlock, display, &mLibVLCCallbackContext); libvlc_video_set_format(mLibVLCMediaPlayer, "RV32", mWidth, mHeight, mWidth * mDepth); diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index 5bcfddfe25..8d7f37142f 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -9,11 +9,15 @@ include(Linking) include(Boost) include(bugsplat) +if (NOT USESYSTEMLIBS) include(BuildPackagesInfo) +endif () include(BuildVersion) include(CMakeCopyIfDifferent) include(CubemapToEquirectangularJS) +if (NOT USESYSTEMLIBS) include(DBusGlib) +endif () include(DragDrop) include(EXPAT) include(Hunspell) @@ -41,12 +45,19 @@ include(ThreeJS) include(Tracy) include(UI) include(ViewerMiscLibs) +if (NOT USESYSTEMLIBS) include(ViewerManager) +endif () include(VisualLeakDetector) include(VulkanGltf) include(ZLIBNG) include(LLPrimitive) +if (ENABLE_MEDIA_PLUGINS) + include(LibVLCPlugin) + include(CEFPlugin) +endif (ENABLE_MEDIA_PLUGINS) + if (NOT HAVOK_TPV) # When using HAVOK_TPV, the library is precompiled, so no need for this @@ -156,6 +167,7 @@ set(viewer_SOURCE_FILES lldrawpooltree.cpp lldrawpoolwater.cpp lldrawpoolwlsky.cpp + lldrawpoolwaterexclusion.cpp lldynamictexture.cpp llemote.cpp llenvironment.cpp @@ -230,6 +242,8 @@ set(viewer_SOURCE_FILES llfloaterhandler.cpp llfloaterhelpbrowser.cpp llfloaterhoverheight.cpp + mpfloatertuning.cpp + fsfloatersearch.cpp llfloaterhowto.cpp llfloaterhud.cpp llfloaterimagepreview.cpp @@ -290,6 +304,7 @@ set(viewer_SOURCE_FILES llfloatersettingscolor.cpp llfloatersettingsdebug.cpp llfloatersidepanelcontainer.cpp + llfloaterslapptest.cpp llfloatersnapshot.cpp llfloatersounddevices.cpp llfloaterspellchecksettings.cpp @@ -729,6 +744,10 @@ set(viewer_SOURCE_FILES pipeline.cpp ) +if (CMAKE_SYSTEM_NAME MATCHES FreeBSD) + list(REMOVE_ITEM viewer_SOURCE_FILES llvoicewebrtc.cpp) +endif (CMAKE_SYSTEM_NAME MATCHES FreeBSD) + set(VIEWER_BINARY_NAME "secondlife-bin" CACHE STRING "The name of the viewer executable to create.") @@ -823,6 +842,7 @@ set(viewer_HEADER_FILES lldrawpooltree.h lldrawpoolwater.h lldrawpoolwlsky.h + lldrawpoolwaterexclusion.h lldynamictexture.h llemote.h llenvironment.h @@ -897,6 +917,8 @@ set(viewer_HEADER_FILES llfloaterhandler.h llfloaterhelpbrowser.h llfloaterhoverheight.h + mpfloatertuning.h + fsfloatersearch.h llfloaterhowto.h llfloaterhud.h llfloaterimagepreview.h @@ -960,6 +982,7 @@ set(viewer_HEADER_FILES llfloatersettingscolor.h llfloatersettingsdebug.h llfloatersidepanelcontainer.h + llfloaterslapptest.h llfloatersnapshot.h llfloatersounddevices.h llfloaterspellchecksettings.h @@ -1415,11 +1438,24 @@ if (DARWIN) LIST(APPEND viewer_SOURCE_FILES llfilepicker_mac.mm) LIST(APPEND viewer_HEADER_FILES llfilepicker_mac.h) + set_source_files_properties( + llappviewermacosx-objc.mm + PROPERTIES + SKIP_PRECOMPILE_HEADERS TRUE + ) + + set_source_files_properties( + llfilepicker_mac.mm + PROPERTIES + SKIP_PRECOMPILE_HEADERS TRUE + ) + # This should be compiled with the viewer. LIST(APPEND viewer_SOURCE_FILES llappdelegate-objc.mm) set_source_files_properties( llappdelegate-objc.mm PROPERTIES + SKIP_PRECOMPILE_HEADERS TRUE COMPILE_DEFINITIONS "${VIEWER_CHANNEL_VERSION_DEFINES}" # BugsplatMac is a module, imported with @import. That language feature # demands these -f switches. @@ -1447,17 +1483,18 @@ if (DARWIN) list(APPEND viewer_SOURCE_FILES ${viewer_RESOURCE_FILES}) endif (DARWIN) -if (LINUX) +if (USESYSTEMLIBS AND NOT DARWIN) LIST(APPEND viewer_SOURCE_FILES llappviewerlinux.cpp) set_source_files_properties( llappviewerlinux.cpp PROPERTIES COMPILE_DEFINITIONS "${VIEWER_CHANNEL_VERSION_DEFINES}" ) - LIST(APPEND viewer_SOURCE_FILES llappviewerlinux_api_dbus.cpp) + if (NOT CMAKE_CXX_COMPILER_ID MATCHES "AppleClang") SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--as-needed") + endif () -endif (LINUX) +endif (USESYSTEMLIBS AND NOT DARWIN) if (WINDOWS) @@ -1644,6 +1681,10 @@ set(viewer_APPSETTINGS_FILES featuretable_mac.txt ) +if (USESYSTEMLIBS) + list(REMOVE_ITEM viewer_APPSETTINGS_FILES packages-info.txt) +endif () + source_group("App Settings" FILES ${viewer_APPSETTINGS_FILES}) set_source_files_properties(${viewer_APPSETTINGS_FILES} @@ -1703,6 +1744,10 @@ list(APPEND EVENT_HOST_SCRIPTS ${EVENT_HOST_SCRIPT_GLOB_LIST}) set(PACKAGE ON CACHE BOOL "Add a package target that builds an installer package.") +if(USE_PRECOMPILED_HEADERS) + target_precompile_headers( ${VIEWER_BINARY_NAME} PRIVATE llviewerprecompiledheaders.h ) +endif(USE_PRECOMPILED_HEADERS) + if (WINDOWS) set_target_properties(${VIEWER_BINARY_NAME} PROPERTIES @@ -1713,10 +1758,6 @@ if (WINDOWS) ) target_compile_options(${VIEWER_BINARY_NAME} PRIVATE /bigobj) - if(USE_PRECOMPILED_HEADERS) - target_precompile_headers( ${VIEWER_BINARY_NAME} PRIVATE llviewerprecompiledheaders.h ) - endif(USE_PRECOMPILED_HEADERS) - # If adding a file to viewer_manifest.py in the WindowsManifest.construct() method, be sure to add the dependency # here. # *NOTE:Mani - This is a crappy hack to have important dependencies for the viewer_manifest copy action @@ -1962,7 +2003,6 @@ target_link_libraries(${VIEWER_BINARY_NAME} llcorehttp llcommon llmeshoptimizer - llwebrtc ll::ndof lllogin llprimitive @@ -1973,6 +2013,17 @@ target_link_libraries(${VIEWER_BINARY_NAME} ll::openxr ) +if (NOT CMAKE_SYSTEM_NAME MATCHES FreeBSD) + target_link_libraries(${VIEWER_BINARY_NAME} llwebrtc ) +endif (NOT CMAKE_SYSTEM_NAME MATCHES FreeBSD) + +if (ENABLE_MEDIA_PLUGINS) + target_link_libraries(${VIEWER_BINARY_NAME} ll::libvlc ) + if (DARWIN OR LINUX) + target_link_libraries(${VIEWER_BINARY_NAME} ll::cef ) + endif (DARWIN OR LINUX) +endif (ENABLE_MEDIA_PLUGINS) + if( TARGET ll::intel_memops ) target_link_libraries(${VIEWER_BINARY_NAME} ll::intel_memops ) endif() @@ -1984,6 +2035,62 @@ endif() set(ARTWORK_DIR ${CMAKE_CURRENT_SOURCE_DIR} CACHE PATH "Path to artwork files.") +set_source_files_properties(llinventorygallery.cpp PROPERTIES COMPILE_FLAGS + -Wno-unused-but-set-variable) +if (CMAKE_CXX_COMPILER_ID MATCHES "Clang") + set_source_files_properties(llappviewerlinux.cpp PROPERTIES + COMPILE_FLAGS -Wno-dangling-gsl + ) + set_source_files_properties(llviewerstats.cpp PROPERTIES + COMPILE_FLAGS -Wno-unused-value) +elseif (CMAKE_CXX_COMPILER_ID MATCHES "GNU") + set_source_files_properties( + llface.cpp + llhttpretrypolicy.cpp + llmodelpreview.cpp + llpanelface.cpp + lltexturefetch.cpp + PROPERTIES COMPILE_FLAGS -Wno-maybe-uninitialized) + set_source_files_properties(llfasttimerview.cpp PROPERTIES + COMPILE_FLAGS -Wno-nonnull) + set_source_files_properties(llinventorygallerymenu.cpp PROPERTIES + COMPILE_FLAGS -Wno-uninitialized) + set_source_files_properties(llviewerstats.cpp PROPERTIES + COMPILE_FLAGS -Wno-unused-value) + set_source_files_properties( + llaisapi.cpp + llconversationlog.cpp + llconversationmodel.cpp + lleventnotifier.cpp + llfloateravatarrendersettings.cpp + llfloatereditextdaycycle.cpp + llfloaternewfeaturenotification.cpp + llinventoryfunctions.cpp + llnotificationlistitem.cpp + llpanelenvironment.cpp + llpanelgroupnotices.cpp + llpanelteleporthistory.cpp + lltoastgroupnotifypanel.cpp + llvoavatar.cpp + PROPERTIES COMPILE_FLAGS -Wno-stringop-overflow) + set_source_files_properties(llurl.cpp PROPERTIES COMPILE_FLAGS + -Wno-stringop-truncation) + set_source_files_properties( + llfloaterimsessiontab.cpp + llfloatersimplesnapshot.cpp + llfloatersidepanelcontainer.cpp + llinventorypanel.cpp + llpanelmaininventory.cpp + llpathfindingnavmesh.cpp + llsidepanelinventory.cpp + PROPERTIES COMPILE_FLAGS -Wno-dangling-reference + ) + set_source_files_properties( + gltf/animation.cpp + gltf/primitive.cpp + PROPERTIES COMPILE_FLAGS -Wno-unused-function) +endif () + message("Copying fonts") file(GLOB FONT_FILE_GLOB_LIST "${AUTOBUILD_INSTALL_DIR}/fonts/*" @@ -2006,7 +2113,100 @@ foreach(elem ${country_codes}) configure_file(${emoji_mapping_src_file} ${emoji_mapping_dst_file} COPYONLY) endforeach() +if (PACKAGE AND USESYSTEMLIBS) + set(CPACK_PACKAGE_NAME ${VIEWER_BINARY_NAME} + CACHE STRING "Viewer binary name.") + set(CPACK_PACKAGE_VERSION ${VIEWER_VERSION_MAJOR}.${VIEWER_VERSION_MINOR}.${VIEWER_VERSION_PATCH}.${VIEWER_VERSION_REVISION} + CACHE STRING "Viewer major.minor.patch.revision versions.") + set(VIEWER_PACKAGE_COMMENT + "A fork of the Second Life viewer" + ) + set(VIEWER_PACKAGE_DESCRIPTION + "An entrance to virtual empires in only megabytes. A shelter for the metaverse refugees, especially those from less supported operating systems." + ) + set(VIEWER_PACKAGE_DOMAIN_NAME + ${VIEWER_BINARY_NAME}.net + ) +endif (PACKAGE AND USESYSTEMLIBS) + if (LINUX) + if (USESYSTEMLIBS) + add_custom_command( + TARGET ${VIEWER_BINARY_NAME} POST_BUILD + COMMAND ${CMAKE_SYSROOT}/usr/bin/sed + ARGS -e '/Linden Lab.*/d' ${CMAKE_HOME_DIRECTORY}/../doc/contributions.txt > ${CMAKE_CURRENT_BINARY_DIR}/contributions.txt + COMMAND ${CMAKE_SYSROOT}/usr/bin/sed + ARGS -i ${CMAKE_CURRENT_BINARY_DIR}/contributions.txt -e '/following residents.*/d' ${CMAKE_CURRENT_BINARY_DIR}/contributions.txt + COMMAND ${CMAKE_SYSROOT}/usr/bin/sed + ARGS -i ${CMAKE_CURRENT_BINARY_DIR}/contributions.txt -e '/along with.*/d' ${CMAKE_CURRENT_BINARY_DIR}/contributions.txt + COMMAND ${CMAKE_SYSROOT}/usr/bin/sed + ARGS -i ${CMAKE_CURRENT_BINARY_DIR}/contributions.txt -e '/^$$/d' ${CMAKE_CURRENT_BINARY_DIR}/contributions.txt + COMMAND ${CMAKE_SYSROOT}/usr/bin/sed + ARGS -i ${CMAKE_CURRENT_BINARY_DIR}/contributions.txt -e '/\t.*/d' ${CMAKE_CURRENT_BINARY_DIR}/contributions.txt + COMMAND ${CMAKE_SYSROOT}/usr/bin/sed + ARGS -i ${CMAKE_CURRENT_BINARY_DIR}/contributions.txt -e '/^ .*/d' ${CMAKE_CURRENT_BINARY_DIR}/contributions.txt + COMMAND sort + ARGS -R contributions.txt -o ${CMAKE_CURRENT_BINARY_DIR}/contributions.txt + COMMAND paste + ARGS -s -d, ${CMAKE_CURRENT_BINARY_DIR}/contributions.txt > ${CMAKE_CURRENT_BINARY_DIR}/contributors.txt + COMMAND ${CMAKE_SYSROOT}/usr/bin/sed + ARGS -i ${CMAKE_CURRENT_BINARY_DIR}/contributions.txt -e 's/,/, /g' ${CMAKE_CURRENT_BINARY_DIR}/contributors.txt + ) + if (PACKAGE) + if (${LINUX_DISTRO} MATCHES debian OR ${LINUX_DISTRO} MATCHES ubuntu) + set(CPACK_BINARY_DEB ON CACHE BOOL "Able to package Debian DEB.") + set(CPACK_DEBIAN_PACKAGE_ARCHITECTURE + amd64 + CACHE STRING "Debian package architecture.") + set(CPACK_DEBIAN_PACKAGE_DESCRIPTION ${VIEWER_PACKAGE_COMMENT} + CACHE STRING "Debian package description.") + set(CPACK_DEBIAN_PACKAGE_MAINTAINER + $ENV{USER}@${VIEWER_PACKAGE_DOMAIN_NAME} + CACHE STRING "Debian package maintainer.") + set(CPACK_DEBIAN_PACKAGE_SECTION net + CACHE STRING "Debian package section.") + if (${LINUX_DISTRO} MATCHES debian) + set(CPACK_DEBIAN_PACKAGE_DEPENDS + "libalut0, libaprutil1, libboost-fiber1.81.0, libboost-filesystem1.81.0, libboost-program-options1.81.0, libboost-regex1.81.0, libboost-thread1.81.0, libboost-url1.81.0, libexpat1, libfltk1.3, libglu1-mesa, libhunspell-1.7-0, libmeshoptimizer2d, libminizip1, libnghttp2-14, libsdl2-2.0-0, libvlc5, libvorbisenc2, libvorbisfile3, vlc-plugin-base" + CACHE STRING "Debian package dependencies.") + elseif (${LINUX_DISTRO} MATCHES ubuntu) + set(CPACK_DEBIAN_PACKAGE_DEPENDS + "libaprutil1t64, libboost-fiber1.83.0, libboost-filesystem1.83.0, libboost-program-options1.83.0, libboost-regex1.83.0, libboost-thread1.83.0, libboost-url1.83.0, libexpat1, libfltk1.3t64, libglu1-mesa, libhunspell-1.7-0, libmeshoptimizer2d, libminizip1, libnghttp2-14, libsdl2-2.0-0, libvlc5, libvorbisenc2, libvorbisfile3, vlc-plugin-base" + CACHE STRING "Debian package dependencies.") + endif (${LINUX_DISTRO} MATCHES debian) + elseif (${LINUX_DISTRO} MATCHES fedora OR (${LINUX_DISTRO} MATCHES opensuse-tumbleweed)) + set(CPACK_BINARY_RPM ON CACHE BOOL "Able to package Fedora RPM.") + set(CPACK_RPM_PACKAGE_SUMMARY ${VIEWER_PACKAGE_COMMENT} + CACHE STRING "RPM package summary.") + set(CPACK_RPM_PACKAGE_ARCHITECTURE + ${CMAKE_SYSTEM_PROCESSOR} + CACHE STRING "RPM package architecture.") + set(CPACK_RPM_PACKAGE_LICENSE LGPL-2.1-only + CACHE STRING "RPM package license.") + set(CPACK_RPM_PACKAGE_VENDOR ${VIEWER_CHANNEL} + CACHE STRING "RPM package vendor.") + set(CPACK_RPM_PACKAGE_URL + https://${VIEWER_PACKAGE_DOMAIN_NAME} + CACHE STRING "RPM package URL.") + set(CPACK_RPM_PACKAGE_DESCRIPTION ${VIEWER_PACKAGE_DESCRIPTION} + CACHE STRING "RPM package description.") + if (${LINUX_DISTRO} MATCHES fedora) + set(CPACK_RPM_PACKAGE_REQUIRES + "apr-util, boost-fiber, boost-program-options, boost-regex, boost-thread, boost-url, expat, fltk, mesa-libGLU, hunspell, libnghttp2, SDL2, vlc-libs, vlc-plugins-base, libvorbis" + CACHE STRING "RPM package requirements.") + elseif (${LINUX_DISTRO} MATCHES opensuse-tumbleweed) + set(CPACK_RPM_PACKAGE_REQUIRES + "libapr-util1-0, libboost_fiber1_87_0, libboost_program_options1_87_0, libboost_regex1_87_0, libboost_thread1_87_0, libboost_url1_87_0, libboost_url1_87_0-x86-64-v3, expat, libfltk1_3, libGLU1, libhunspell-1_7-0, libnghttp2-14, libSDL2-2_0-0, libvlc5, vlc-codecs, libvorbis0" + CACHE STRING "RPM package requirements.") + endif (${LINUX_DISTRO} MATCHES fedora) + elseif (${LINUX_DISTRO} MATCHES arch) + configure_file( + ${CMAKE_CURRENT_SOURCE_DIR}/PKGBUILD.in + ${CMAKE_BINARY_DIR}/PKGBUILD + ) + endif (${LINUX_DISTRO} MATCHES debian OR ${LINUX_DISTRO} MATCHES ubuntu) + endif (PACKAGE) + else (USESYSTEMLIBS) set(product SecondLife-${ARCH}-${VIEWER_SHORT_VERSION}.${VIEWER_VERSION_REVISION}) # These are the generated targets that are copied to package/ @@ -2081,6 +2281,49 @@ if (LINUX) add_dependencies(llpackage copy_l_viewer_manifest) check_message_template(llpackage) endif (PACKAGE) + endif (USESYSTEMLIBS) +elseif (USESYSTEMLIBS) + add_custom_command( + TARGET ${VIEWER_BINARY_NAME} POST_BUILD + COMMAND sed + ARGS -e '/Linden Lab.*/d' ${CMAKE_HOME_DIRECTORY}/../doc/contributions.txt > ${CMAKE_CURRENT_BINARY_DIR}/contributions.txt + COMMAND sed + ARGS -i '' -e '/following residents.*/d' ${CMAKE_CURRENT_BINARY_DIR}/contributions.txt + COMMAND sed + ARGS -i '' -e '/along with.*/d' ${CMAKE_CURRENT_BINARY_DIR}/contributions.txt + COMMAND sed + ARGS -i '' -e '/^$$/d' ${CMAKE_CURRENT_BINARY_DIR}/contributions.txt + COMMAND sed + ARGS -i '' -e '/\t.*/d' ${CMAKE_CURRENT_BINARY_DIR}/contributions.txt + COMMAND sed + ARGS -i '' -e '/^ .*/d' ${CMAKE_CURRENT_BINARY_DIR}/contributions.txt + COMMAND sort + ARGS -R contributions.txt -o ${CMAKE_CURRENT_BINARY_DIR}/contributions.txt + COMMAND paste + ARGS -s -d, ${CMAKE_CURRENT_BINARY_DIR}/contributions.txt > ${CMAKE_CURRENT_BINARY_DIR}/contributors.txt + COMMAND sed + ARGS -i '' -e 's/,/, /g' ${CMAKE_CURRENT_BINARY_DIR}/contributors.txt + ) + if (CMAKE_SYSTEM_NAME MATCHES FreeBSD AND PACKAGE) + set(CPACK_BINARY_FREEBSD ON CACHE BOOL "Able to package FreeBSD PKG.") + set(CPACK_FREEBSD_PACKAGE_COMMENT ${VIEWER_PACKAGE_COMMENT} + CACHE STRING "FreeBSD package comment.") + set(CPACK_FREEBSD_PACKAGE_DESCRIPTION ${VIEWER_PACKAGE_DESCRIPTION} + CACHE STRING "FreeBSD package description.") + set(CPACK_FREEBSD_PACKAGE_WWW + https://${VIEWER_PACKAGE_DOMAIN_NAME} + CACHE STRING "FreeBSD package WWW.") + set(CPACK_FREEBSD_PACKAGE_LICENSE LGPL21 + CACHE STRING "FreeBSD package license.") + set(CPACK_FREEBSD_PACKAGE_MAINTAINER + $ENV{USER}@${VIEWER_PACKAGE_DOMAIN_NAME} + CACHE STRING "FreeBSD package maintainer.") + set(CPACK_FREEBSD_PACKAGE_ORIGIN net/${VIEWER_BINARY_NAME} + CACHE STRING "FreeBSD package origin.") + set(CPACK_FREEBSD_PACKAGE_DEPS + "audio/freealut;graphics/libGLU;textproc/hunspell;misc/meshoptimizer;archivers/minizip;www/libnghttp2;multimedia/vlc;audio/libvorbis" + CACHE STRING "FreeBSD package dependencies.") + endif (CMAKE_SYSTEM_NAME MATCHES FreeBSD AND PACKAGE) endif (LINUX) if (DARWIN) @@ -2090,13 +2333,13 @@ if (DARWIN) set(product "${VIEWER_CHANNEL}") set(MACOSX_EXECUTABLE_NAME "${VIEWER_CHANNEL}") set(MACOSX_BUNDLE_INFO_STRING "${VIEWER_CHANNEL}") - set(MACOSX_BUNDLE_ICON_FILE "secondlife.icns") - set(MACOSX_BUNDLE_GUI_IDENTIFIER "com.secondlife.indra.viewer") + set(MACOSX_BUNDLE_ICON_FILE "${VIEWER_CHANNEL}.icns") + set(MACOSX_BUNDLE_GUI_IDENTIFIER "net.megapahit.viewer") set(MACOSX_BUNDLE_LONG_VERSION_STRING "${VIEWER_CHANNEL} ${VIEWER_SHORT_VERSION}.${VIEWER_VERSION_REVISION}") - set(MACOSX_BUNDLE_BUNDLE_NAME "SecondLife") + set(MACOSX_BUNDLE_BUNDLE_NAME "Megapahit") set(MACOSX_BUNDLE_SHORT_VERSION_STRING "${VIEWER_SHORT_VERSION}.${VIEWER_VERSION_REVISION}") set(MACOSX_BUNDLE_BUNDLE_VERSION "${VIEWER_SHORT_VERSION}${VIEWER_MACOSX_PHASE}${VIEWER_REVISION}") - set(MACOSX_BUNDLE_COPYRIGHT "Copyright © Linden Research, Inc. 2020") + set(MACOSX_BUNDLE_COPYRIGHT "Copyright © Megapahit 2025") set(MACOSX_BUNDLE_NSMAIN_NIB_FILE "SecondLife.nib") set(MACOSX_BUNDLE_NSPRINCIPAL_CLASS "LLApplication") @@ -2114,6 +2357,7 @@ if (DARWIN) LINK_FLAGS "-rpath @loader_path/../Frameworks" MACOSX_BUNDLE_INFO_PLIST "${CMAKE_CURRENT_SOURCE_DIR}/Info-SecondLife.plist" XCODE_ATTRIBUTE_PRODUCT_BUNDLE_IDENTIFIER "${MACOSX_BUNDLE_GUI_IDENTIFIER}" + MACOSX_BUNDLE TRUE ) set(VIEWER_APP_BUNDLE "${CMAKE_CURRENT_BINARY_DIR}/$<IF:$<BOOL:${LL_GENERATOR_IS_MULTI_CONFIG}>,$<CONFIG>,>/${product}.app") @@ -2124,6 +2368,12 @@ if (DARWIN) "${VIEWER_APP_BUNDLE}/Contents/Info.plist" ) + if (USESYSTEMLIBS) + configure_file( + ${CMAKE_CURRENT_SOURCE_DIR}/English.lproj/InfoPlist.strings + ${CMAKE_CURRENT_BINARY_DIR}/InfoPlist.strings + ) + else (USESYSTEMLIBS) add_custom_command( TARGET ${VIEWER_BINARY_NAME} POST_BUILD COMMAND ${PYTHON_EXECUTABLE} @@ -2148,8 +2398,11 @@ if (DARWIN) ${VIEWER_BINARY_NAME} ${CMAKE_CURRENT_SOURCE_DIR}/viewer_manifest.py ) + endif (USESYSTEMLIBS) + if (ENABLE_MEDIA_PLUGINS) add_dependencies(${VIEWER_BINARY_NAME} SLPlugin media_plugin_libvlc media_plugin_cef) + endif () if (ENABLE_SIGNING) set(SIGNING_SETTING "--signature=${SIGNING_IDENTITY}") @@ -2158,6 +2411,26 @@ if (DARWIN) endif (ENABLE_SIGNING) if (PACKAGE) + if (USESYSTEMLIBS) + set(CPACK_DMG_VOLUME_NAME "${product} Installer" + CACHE STRING "Disk image volume name.") + set(CPACK_DMG_FORMAT UDRW CACHE STRING "Disk image format.") + set(CPACK_DMG_DS_STORE + ${CMAKE_CURRENT_SOURCE_DIR}/installers/darwin/release-dmg/_DS_Store + CACHE STRING "Disk image .DS_Store file.") + set(CPACK_DMG_DS_STORE_SETUP_SCRIPT + ${CMAKE_CURRENT_SOURCE_DIR}/installers/darwin/dmg-cleanup.applescript + CACHE STRING "Disk image AppleScript file.") + set(CPACK_DMG_BACKGROUND_IMAGE + ${CMAKE_CURRENT_SOURCE_DIR}/installers/darwin/release-dmg/background.jpg + CACHE STRING "Disk image background image.") + set(CPACK_BUNDLE_NAME ${product} CACHE STRING "Bundle name.") + set(CPACK_BUNDLE_PLIST ${VIEWER_APP_BUNDLE}/Contents/Info.plist + CACHE STRING "Bundle Property List file.") + set(CPACK_BUNDLE_ICON ${CMAKE_CURRENT_SOURCE_DIR}/secondlife.icns + CACHE STRING "Bundle icon file.") + + else (USESYSTEMLIBS) add_custom_target(llpackage ALL DEPENDS ${VIEWER_BINARY_NAME}) add_custom_command( @@ -2183,12 +2456,16 @@ if (DARWIN) DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/viewer_manifest.py ) + endif (USESYSTEMLIBS) endif (PACKAGE) endif (DARWIN) if (INSTALL) include(${CMAKE_CURRENT_SOURCE_DIR}/ViewerInstall.cmake) endif (INSTALL) +if (PACKAGE AND USESYSTEMLIBS) + include(CPack) +endif (PACKAGE AND USESYSTEMLIBS) if (PACKAGE AND (RELEASE_CRASH_REPORTING OR NON_RELEASE_CRASH_REPORTING) AND VIEWER_SYMBOL_FILE) if (USE_BUGSPLAT) @@ -2399,4 +2676,3 @@ if (LL_TESTS) endif (LL_TESTS) check_message_template(${VIEWER_BINARY_NAME}) - diff --git a/indra/newview/English.lproj/InfoPlist.strings b/indra/newview/English.lproj/InfoPlist.strings index 041b8cea0b..25f517d364 100644 --- a/indra/newview/English.lproj/InfoPlist.strings +++ b/indra/newview/English.lproj/InfoPlist.strings @@ -1,7 +1,7 @@ /* Localized versions of Info.plist keys */ -CFBundleName = "Second Life"; +CFBundleName = "Megapahit"; -CFBundleShortVersionString = "Second Life version %%VERSION%%"; -CFBundleGetInfoString = "Second Life version %%VERSION%%, Copyright 2004 Linden Research, Inc."; +CFBundleShortVersionString = "Megapahit version ${MACOSX_BUNDLE_SHORT_VERSION_STRING}"; +CFBundleGetInfoString = "Megapahit version ${MACOSX_BUNDLE_SHORT_VERSION_STRING}, Copyright 2025 Megapahit."; diff --git a/indra/newview/FixBundle.cmake.in b/indra/newview/FixBundle.cmake.in new file mode 100644 index 0000000000..7f06249224 --- /dev/null +++ b/indra/newview/FixBundle.cmake.in @@ -0,0 +1,703 @@ +include(BundleUtilities) + +set(dirs + /opt/local/lib + ) + +file(CREATE_LINK + "../../../../Frameworks/libnghttp2.14.dylib" + "${viewer_BINARY_DIR}/${VIEWER_CHANNEL}.app/Contents/Resources/SLPlugin.app/Contents/Frameworks/libnghttp2.14.dylib" + SYMBOLIC + ) +file(CREATE_LINK + "../../../../Frameworks/libpng16.16.dylib" + "${viewer_BINARY_DIR}/${VIEWER_CHANNEL}.app/Contents/Resources/SLPlugin.app/Contents/Frameworks/libpng16.16.dylib" + SYMBOLIC + ) +file(CREATE_LINK + "../../../../Frameworks/libjpeg.8.dylib" + "${viewer_BINARY_DIR}/${VIEWER_CHANNEL}.app/Contents/Resources/SLPlugin.app/Contents/Frameworks/libjpeg.8.dylib" + SYMBOLIC + ) +file(CREATE_LINK + "../../../../Frameworks/libaprutil-1.0.dylib" + "${viewer_BINARY_DIR}/${VIEWER_CHANNEL}.app/Contents/Resources/SLPlugin.app/Contents/Frameworks/libaprutil-1.0.dylib" + SYMBOLIC + ) +file(CREATE_LINK + "../../../../Frameworks/libiconv.2.dylib" + "${viewer_BINARY_DIR}/${VIEWER_CHANNEL}.app/Contents/Resources/SLPlugin.app/Contents/Frameworks/libiconv.2.dylib" + SYMBOLIC + ) +file(CREATE_LINK + "../../../../Frameworks/libapr-1.0.dylib" + "${viewer_BINARY_DIR}/${VIEWER_CHANNEL}.app/Contents/Resources/SLPlugin.app/Contents/Frameworks/libapr-1.0.dylib" + SYMBOLIC + ) +file(CREATE_LINK + "../../../../Frameworks/libz.1.dylib" + "${viewer_BINARY_DIR}/${VIEWER_CHANNEL}.app/Contents/Resources/SLPlugin.app/Contents/Frameworks/libz.1.dylib" + SYMBOLIC + ) +file(CREATE_LINK + "../../../../Frameworks/libboost_atomic-mt.dylib" + "${viewer_BINARY_DIR}/${VIEWER_CHANNEL}.app/Contents/Resources/SLPlugin.app/Contents/Frameworks/libboost_atomic-mt.dylib" + SYMBOLIC + ) +file(CREATE_LINK + "../../../../Frameworks/libboost_context-mt.dylib" + "${viewer_BINARY_DIR}/${VIEWER_CHANNEL}.app/Contents/Resources/SLPlugin.app/Contents/Frameworks/libboost_context-mt.dylib" + SYMBOLIC + ) +file(CREATE_LINK + "../../../../Frameworks/libboost_fiber-mt.dylib" + "${viewer_BINARY_DIR}/${VIEWER_CHANNEL}.app/Contents/Resources/SLPlugin.app/Contents/Frameworks/libboost_fiber-mt.dylib" + SYMBOLIC + ) +file(CREATE_LINK + "../../../../Frameworks/libboost_filesystem-mt.dylib" + "${viewer_BINARY_DIR}/${VIEWER_CHANNEL}.app/Contents/Resources/SLPlugin.app/Contents/Frameworks/libboost_filesystem-mt.dylib" + SYMBOLIC + ) +file(CREATE_LINK + "../../../../Frameworks/libboost_program_options-mt.dylib" + "${viewer_BINARY_DIR}/${VIEWER_CHANNEL}.app/Contents/Resources/SLPlugin.app/Contents/Frameworks/libboost_program_options-mt.dylib" + SYMBOLIC + ) +file(CREATE_LINK + "../../../../Frameworks/libboost_regex-mt.dylib" + "${viewer_BINARY_DIR}/${VIEWER_CHANNEL}.app/Contents/Resources/SLPlugin.app/Contents/Frameworks/libboost_regex-mt.dylib" + SYMBOLIC + ) +file(CREATE_LINK + "../../../../Frameworks/libboost_system-mt.dylib" + "${viewer_BINARY_DIR}/${VIEWER_CHANNEL}.app/Contents/Resources/SLPlugin.app/Contents/Frameworks/libboost_system-mt.dylib" + SYMBOLIC + ) +file(CREATE_LINK + "../../../../Frameworks/libboost_thread-mt.dylib" + "${viewer_BINARY_DIR}/${VIEWER_CHANNEL}.app/Contents/Resources/SLPlugin.app/Contents/Frameworks/libboost_thread-mt.dylib" + SYMBOLIC + ) +file(CREATE_LINK + "../../../../Frameworks/libboost_url-mt.dylib" + "${viewer_BINARY_DIR}/${VIEWER_CHANNEL}.app/Contents/Resources/SLPlugin.app/Contents/Frameworks/libboost_url-mt.dylib" + SYMBOLIC + ) +file(CREATE_LINK + "../../../../Frameworks/libexpat.1.dylib" + "${viewer_BINARY_DIR}/${VIEWER_CHANNEL}.app/Contents/Resources/SLPlugin.app/Contents/Frameworks/libexpat.1.dylib" + SYMBOLIC + ) +file(CREATE_LINK + "../../../../Frameworks/libfreetype.6.dylib" + "${viewer_BINARY_DIR}/${VIEWER_CHANNEL}.app/Contents/Resources/SLPlugin.app/Contents/Frameworks/libfreetype.6.dylib" + SYMBOLIC + ) +file(CREATE_LINK + "../../../../Frameworks/libbz2.1.0.dylib" + "${viewer_BINARY_DIR}/${VIEWER_CHANNEL}.app/Contents/Resources/SLPlugin.app/Contents/Frameworks/libbz2.1.0.dylib" + SYMBOLIC + ) +file(CREATE_LINK + "../../../../Frameworks/libbrotlidec.1.dylib" + "${viewer_BINARY_DIR}/${VIEWER_CHANNEL}.app/Contents/Resources/SLPlugin.app/Contents/Frameworks/libbrotlidec.1.dylib" + SYMBOLIC + ) +file(CREATE_LINK + "../../../../Frameworks/libbrotlicommon.1.dylib" + "${viewer_BINARY_DIR}/${VIEWER_CHANNEL}.app/Contents/Resources/SLPlugin.app/Contents/Frameworks/libbrotlicommon.1.dylib" + SYMBOLIC + ) +file(CREATE_LINK + "../../../../Frameworks/libicudata.76.dylib" + "${viewer_BINARY_DIR}/${VIEWER_CHANNEL}.app/Contents/Resources/SLPlugin.app/Contents/Frameworks/libicudata.76.dylib" + SYMBOLIC + ) +file(CREATE_LINK + "../../../../Frameworks/libicui18n.76.dylib" + "${viewer_BINARY_DIR}/${VIEWER_CHANNEL}.app/Contents/Resources/SLPlugin.app/Contents/Frameworks/libicui18n.76.dylib" + SYMBOLIC + ) +file(CREATE_LINK + "../../../../Frameworks/libicuuc.76.dylib" + "${viewer_BINARY_DIR}/${VIEWER_CHANNEL}.app/Contents/Resources/SLPlugin.app/Contents/Frameworks/libicuuc.76.dylib" + SYMBOLIC + ) +file(CREATE_LINK + "../../../../Frameworks/Chromium Embedded Framework.framework" + "${viewer_BINARY_DIR}/${VIEWER_CHANNEL}.app/Contents/Resources/SLPlugin.app/Contents/Frameworks/Chromium Embedded Framework.framework" + SYMBOLIC + ) + +fixup_bundle(${viewer_BINARY_DIR}/${VIEWER_CHANNEL}.app/Contents/MacOS/${VIEWER_CHANNEL} "" "${dirs}") + +file(CHMOD + "${viewer_BINARY_DIR}/${VIEWER_CHANNEL}.app/Contents/Resources/SLPlugin.app/Contents/Frameworks/DullahanHelper.app/Contents/MacOS/DullahanHelper" + "${viewer_BINARY_DIR}/${VIEWER_CHANNEL}.app/Contents/Resources/SLPlugin.app/Contents/Frameworks/DullahanHelper (GPU).app/Contents/MacOS/DullahanHelper (GPU)" + "${viewer_BINARY_DIR}/${VIEWER_CHANNEL}.app/Contents/Resources/SLPlugin.app/Contents/Frameworks/DullahanHelper (Plugin).app/Contents/MacOS/DullahanHelper (Plugin)" + "${viewer_BINARY_DIR}/${VIEWER_CHANNEL}.app/Contents/Resources/SLPlugin.app/Contents/Frameworks/DullahanHelper (Renderer).app/Contents/MacOS/DullahanHelper (Renderer)" + PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE + ) + +execute_process( + COMMAND hdiutil detach /Volumes/VLC\ media\ player + COMMAND lipo libalut.0.dylib + -thin ${CMAKE_OSX_ARCHITECTURES} + -output libalut.0.dylib + COMMAND lipo libapr-1.0.dylib + -thin ${CMAKE_OSX_ARCHITECTURES} + -output libapr-1.0.dylib + COMMAND lipo libaprutil-1.0.dylib + -thin ${CMAKE_OSX_ARCHITECTURES} + -output libaprutil-1.0.dylib + COMMAND lipo libboost_atomic-mt.dylib + -thin ${CMAKE_OSX_ARCHITECTURES} + -output libboost_atomic-mt.dylib + COMMAND lipo libboost_context-mt.dylib + -thin ${CMAKE_OSX_ARCHITECTURES} + -output libboost_context-mt.dylib + COMMAND lipo libboost_fiber-mt.dylib + -thin ${CMAKE_OSX_ARCHITECTURES} + -output libboost_fiber-mt.dylib + COMMAND lipo libboost_filesystem-mt.dylib + -thin ${CMAKE_OSX_ARCHITECTURES} + -output libboost_filesystem-mt.dylib + COMMAND lipo libboost_program_options-mt.dylib + -thin ${CMAKE_OSX_ARCHITECTURES} + -output libboost_program_options-mt.dylib + COMMAND lipo libboost_regex-mt.dylib + -thin ${CMAKE_OSX_ARCHITECTURES} + -output libboost_regex-mt.dylib + COMMAND lipo libboost_system-mt.dylib + -thin ${CMAKE_OSX_ARCHITECTURES} + -output libboost_system-mt.dylib + COMMAND lipo libboost_thread-mt.dylib + -thin ${CMAKE_OSX_ARCHITECTURES} + -output libboost_thread-mt.dylib + COMMAND lipo libboost_url-mt.dylib + -thin ${CMAKE_OSX_ARCHITECTURES} + -output libboost_url-mt.dylib + COMMAND lipo libbrotlicommon.1.1.0.dylib + -thin ${CMAKE_OSX_ARCHITECTURES} + -output libbrotlicommon.1.1.0.dylib + COMMAND lipo libbrotlidec.1.1.0.dylib + -thin ${CMAKE_OSX_ARCHITECTURES} + -output libbrotlidec.1.1.0.dylib + COMMAND lipo libbz2.1.0.8.dylib + -thin ${CMAKE_OSX_ARCHITECTURES} + -output libbz2.1.0.8.dylib + COMMAND lipo libcollada14dom.2.3-r8.dylib + -thin ${CMAKE_OSX_ARCHITECTURES} + -output libcollada14dom.2.3-r8.dylib + COMMAND lipo libexpat.1.10.0.dylib + -thin ${CMAKE_OSX_ARCHITECTURES} + -output libexpat.1.10.0.dylib + COMMAND lipo libfreetype.6.dylib + -thin ${CMAKE_OSX_ARCHITECTURES} + -output libfreetype.6.dylib + COMMAND lipo libhunspell-1.7.0.dylib + -thin ${CMAKE_OSX_ARCHITECTURES} + -output libhunspell-1.7.0.dylib + COMMAND lipo libiconv.2.dylib + -thin ${CMAKE_OSX_ARCHITECTURES} + -output libiconv.2.dylib + COMMAND lipo libicudata.76.1.dylib + -thin ${CMAKE_OSX_ARCHITECTURES} + -output libicudata.76.1.dylib + COMMAND lipo libicui18n.76.1.dylib + -thin ${CMAKE_OSX_ARCHITECTURES} + -output libicui18n.76.1.dylib + COMMAND lipo libicuuc.76.1.dylib + -thin ${CMAKE_OSX_ARCHITECTURES} + -output libicuuc.76.1.dylib + COMMAND lipo libjpeg.8.3.2.dylib + -thin ${CMAKE_OSX_ARCHITECTURES} + -output libjpeg.8.3.2.dylib + COMMAND lipo libllwebrtc.dylib + -thin ${CMAKE_OSX_ARCHITECTURES} + -output libllwebrtc.dylib + COMMAND lipo liblzma.5.dylib + -thin ${CMAKE_OSX_ARCHITECTURES} + -output liblzma.5.dylib + COMMAND lipo libminizip.1.dylib + -thin ${CMAKE_OSX_ARCHITECTURES} + -output libminizip.1.dylib + COMMAND lipo libncurses.6.dylib + -thin ${CMAKE_OSX_ARCHITECTURES} + -output libncurses.6.dylib + COMMAND lipo libndofdev.dylib + -thin ${CMAKE_OSX_ARCHITECTURES} + -output libndofdev.dylib + COMMAND lipo libnghttp2.14.dylib + -thin ${CMAKE_OSX_ARCHITECTURES} + -output libnghttp2.14.dylib + COMMAND lipo libogg.0.dylib + -thin ${CMAKE_OSX_ARCHITECTURES} + -output libogg.0.dylib + COMMAND lipo libopenal.1.24.2.dylib + -thin ${CMAKE_OSX_ARCHITECTURES} + -output libopenal.1.24.2.dylib + COMMAND lipo libpng16.16.dylib + -thin ${CMAKE_OSX_ARCHITECTURES} + -output libpng16.16.dylib + COMMAND lipo libvlc.5.dylib + -thin ${CMAKE_OSX_ARCHITECTURES} + -output libvlc.5.dylib + COMMAND lipo libvlccore.9.dylib + -thin ${CMAKE_OSX_ARCHITECTURES} + -output libvlccore.9.dylib + COMMAND lipo libvorbis.0.dylib + -thin ${CMAKE_OSX_ARCHITECTURES} + -output libvorbis.0.dylib + COMMAND lipo libvorbisenc.2.dylib + -thin ${CMAKE_OSX_ARCHITECTURES} + -output libvorbisenc.2.dylib + COMMAND lipo libvorbisfile.3.dylib + -thin ${CMAKE_OSX_ARCHITECTURES} + -output libvorbisfile.3.dylib + COMMAND lipo libxml2.2.dylib + -thin ${CMAKE_OSX_ARCHITECTURES} + -output libxml2.2.dylib + COMMAND lipo libz.1.3.1.dylib + -thin ${CMAKE_OSX_ARCHITECTURES} + -output libz.1.3.1.dylib + WORKING_DIRECTORY ${viewer_BINARY_DIR}/${VIEWER_CHANNEL}.app/Contents/Frameworks + ERROR_QUIET + ) + +message("By default, the situation is assumed to be the strictest, an Apple Silicon Mac with the default security settings. Running a native self-built viewer on it without correct codesigning would lead to a crash. Also, codesigning requires administrative access. If you believe you're not in such a situation, you can remove the sudos in this file.") +execute_process( + COMMAND sudo codesign -f -s ${SIGNING_IDENTITY} --timestamp -o runtime --runtime-version ${CMAKE_OSX_DEPLOYMENT_TARGET} + Frameworks/Chromium\ Embedded\ Framework.framework/Libraries/libEGL.dylib + Frameworks/Chromium\ Embedded\ Framework.framework/Libraries/libGLESv2.dylib + Frameworks/Chromium\ Embedded\ Framework.framework/Libraries/libvk_swiftshader.dylib + Frameworks/Chromium\ Embedded\ Framework.framework + Frameworks/libalut.0.dylib + Frameworks/libapr-1.0.dylib + Frameworks/libaprutil-1.0.dylib + Frameworks/libboost_atomic-mt.dylib + Frameworks/libboost_context-mt.dylib + Frameworks/libboost_fiber-mt.dylib + Frameworks/libboost_filesystem-mt.dylib + Frameworks/libboost_program_options-mt.dylib + Frameworks/libboost_regex-mt.dylib + Frameworks/libboost_system-mt.dylib + Frameworks/libboost_thread-mt.dylib + Frameworks/libboost_url-mt.dylib + Frameworks/libbrotlicommon.1.1.0.dylib + Frameworks/libbrotlidec.1.1.0.dylib + Frameworks/libbz2.1.0.8.dylib + Frameworks/libcollada14dom.2.3-r8.dylib + Frameworks/libexpat.1.10.0.dylib + Frameworks/libfreetype.6.dylib + Frameworks/libhunspell-1.7.0.dylib + Frameworks/libiconv.2.dylib + Frameworks/libicudata.76.1.dylib + Frameworks/libicui18n.76.1.dylib + Frameworks/libicuuc.76.1.dylib + Frameworks/libjpeg.8.3.2.dylib + Frameworks/libllwebrtc.dylib + Frameworks/liblzma.5.dylib + Frameworks/libminizip.1.dylib + Frameworks/libncurses.6.dylib + Frameworks/libndofdev.dylib + Frameworks/libnghttp2.14.dylib + Frameworks/libogg.0.dylib + Frameworks/libopenal.1.24.2.dylib + Frameworks/libpng16.16.dylib + Frameworks/libvlc.5.dylib + Frameworks/libvlccore.9.dylib + Frameworks/libvorbis.0.dylib + Frameworks/libvorbisenc.2.dylib + Frameworks/libvorbisfile.3.dylib + Frameworks/libxml2.2.dylib + Frameworks/libz.1.3.1.dylib + Resources/libndofdev.dylib + Resources/llplugin/media_plugin_cef.dylib + Resources/llplugin/media_plugin_libvlc.dylib + Resources/llplugin/plugins/liba52_plugin.dylib + Resources/llplugin/plugins/libaccess_concat_plugin.dylib + Resources/llplugin/plugins/libaccess_imem_plugin.dylib + Resources/llplugin/plugins/libaccess_mms_plugin.dylib + Resources/llplugin/plugins/libaccess_output_dummy_plugin.dylib + Resources/llplugin/plugins/libaccess_output_file_plugin.dylib + Resources/llplugin/plugins/libaccess_output_http_plugin.dylib + Resources/llplugin/plugins/libaccess_output_livehttp_plugin.dylib + Resources/llplugin/plugins/libaccess_output_rist_plugin.dylib + Resources/llplugin/plugins/libaccess_output_shout_plugin.dylib + Resources/llplugin/plugins/libaccess_output_srt_plugin.dylib + Resources/llplugin/plugins/libaccess_output_udp_plugin.dylib + Resources/llplugin/plugins/libaccess_realrtsp_plugin.dylib + Resources/llplugin/plugins/libaccess_srt_plugin.dylib + Resources/llplugin/plugins/libadaptive_plugin.dylib + Resources/llplugin/plugins/libaddonsfsstorage_plugin.dylib + Resources/llplugin/plugins/libaddonsvorepository_plugin.dylib + Resources/llplugin/plugins/libadf_plugin.dylib + Resources/llplugin/plugins/libadjust_plugin.dylib + Resources/llplugin/plugins/libadpcm_plugin.dylib + Resources/llplugin/plugins/libadummy_plugin.dylib + Resources/llplugin/plugins/libaes3_plugin.dylib + Resources/llplugin/plugins/libafile_plugin.dylib + Resources/llplugin/plugins/libaiff_plugin.dylib + Resources/llplugin/plugins/libalphamask_plugin.dylib + Resources/llplugin/plugins/libamem_plugin.dylib + Resources/llplugin/plugins/libanaglyph_plugin.dylib + Resources/llplugin/plugins/libantiflicker_plugin.dylib + Resources/llplugin/plugins/libaom_plugin.dylib + Resources/llplugin/plugins/libaraw_plugin.dylib + Resources/llplugin/plugins/libarchive_plugin.dylib + Resources/llplugin/plugins/libaribsub_plugin.dylib + Resources/llplugin/plugins/libasf_plugin.dylib + Resources/llplugin/plugins/libattachment_plugin.dylib + Resources/llplugin/plugins/libau_plugin.dylib + Resources/llplugin/plugins/libaudio_format_plugin.dylib + Resources/llplugin/plugins/libaudiobargraph_a_plugin.dylib + Resources/llplugin/plugins/libaudiobargraph_v_plugin.dylib + Resources/llplugin/plugins/libaudioscrobbler_plugin.dylib + Resources/llplugin/plugins/libaudiotoolboxmidi_plugin.dylib + Resources/llplugin/plugins/libauhal_plugin.dylib + Resources/llplugin/plugins/libavaudiocapture_plugin.dylib + Resources/llplugin/plugins/libavcapture_plugin.dylib + Resources/llplugin/plugins/libavcodec_plugin.dylib + Resources/llplugin/plugins/libavi_plugin.dylib + Resources/llplugin/plugins/libball_plugin.dylib + Resources/llplugin/plugins/libblend_plugin.dylib + Resources/llplugin/plugins/libblendbench_plugin.dylib + Resources/llplugin/plugins/libbluescreen_plugin.dylib + Resources/llplugin/plugins/libbluray-awt-j2se-1.3.2.jar + Resources/llplugin/plugins/libbluray-j2se-1.3.2.jar + Resources/llplugin/plugins/libbonjour_plugin.dylib + Resources/llplugin/plugins/libcache_block_plugin.dylib + Resources/llplugin/plugins/libcache_read_plugin.dylib + Resources/llplugin/plugins/libcaf_plugin.dylib + Resources/llplugin/plugins/libcanvas_plugin.dylib + Resources/llplugin/plugins/libcaopengllayer_plugin.dylib + Resources/llplugin/plugins/libcc_plugin.dylib + Resources/llplugin/plugins/libcdda_plugin.dylib + Resources/llplugin/plugins/libcdg_plugin.dylib + Resources/llplugin/plugins/libchain_plugin.dylib + Resources/llplugin/plugins/libchorus_flanger_plugin.dylib + Resources/llplugin/plugins/libci_filters_plugin.dylib + Resources/llplugin/plugins/libclone_plugin.dylib + Resources/llplugin/plugins/libcolorthres_plugin.dylib + Resources/llplugin/plugins/libcompressor_plugin.dylib + Resources/llplugin/plugins/libconsole_logger_plugin.dylib + Resources/llplugin/plugins/libcroppadd_plugin.dylib + Resources/llplugin/plugins/libcvdsub_plugin.dylib + Resources/llplugin/plugins/libcvpx_plugin.dylib + Resources/llplugin/plugins/libdav1d_plugin.dylib + Resources/llplugin/plugins/libdca_plugin.dylib + Resources/llplugin/plugins/libdcp_plugin.dylib + Resources/llplugin/plugins/libddummy_plugin.dylib + Resources/llplugin/plugins/libdecomp_plugin.dylib + Resources/llplugin/plugins/libdeinterlace_plugin.dylib + Resources/llplugin/plugins/libdemux_cdg_plugin.dylib + Resources/llplugin/plugins/libdemux_chromecast_plugin.dylib + Resources/llplugin/plugins/libdemux_stl_plugin.dylib + Resources/llplugin/plugins/libdemuxdump_plugin.dylib + Resources/llplugin/plugins/libdiracsys_plugin.dylib + Resources/llplugin/plugins/libdirectory_demux_plugin.dylib + Resources/llplugin/plugins/libdolby_surround_decoder_plugin.dylib + Resources/llplugin/plugins/libdummy_plugin.dylib + Resources/llplugin/plugins/libdvbsub_plugin.dylib + Resources/llplugin/plugins/libdvdnav_plugin.dylib + Resources/llplugin/plugins/libdvdread_plugin.dylib + Resources/llplugin/plugins/libdynamicoverlay_plugin.dylib + Resources/llplugin/plugins/libedgedetection_plugin.dylib + Resources/llplugin/plugins/libedummy_plugin.dylib + Resources/llplugin/plugins/libequalizer_plugin.dylib + Resources/llplugin/plugins/liberase_plugin.dylib + Resources/llplugin/plugins/libes_plugin.dylib + Resources/llplugin/plugins/libexport_plugin.dylib + Resources/llplugin/plugins/libextract_plugin.dylib + Resources/llplugin/plugins/libfaad_plugin.dylib + Resources/llplugin/plugins/libfile_keystore_plugin.dylib + Resources/llplugin/plugins/libfile_logger_plugin.dylib + Resources/llplugin/plugins/libfilesystem_plugin.dylib + Resources/llplugin/plugins/libfingerprinter_plugin.dylib + Resources/llplugin/plugins/libflac_plugin.dylib + Resources/llplugin/plugins/libflacsys_plugin.dylib + Resources/llplugin/plugins/libflaschen_plugin.dylib + Resources/llplugin/plugins/libfloat_mixer_plugin.dylib + Resources/llplugin/plugins/libfolder_plugin.dylib + Resources/llplugin/plugins/libfps_plugin.dylib + Resources/llplugin/plugins/libfreetype_plugin.dylib + Resources/llplugin/plugins/libfreeze_plugin.dylib + Resources/llplugin/plugins/libftp_plugin.dylib + Resources/llplugin/plugins/libg711_plugin.dylib + Resources/llplugin/plugins/libgain_plugin.dylib + Resources/llplugin/plugins/libgaussianblur_plugin.dylib + Resources/llplugin/plugins/libgestures_plugin.dylib + Resources/llplugin/plugins/libglconv_cvpx_plugin.dylib + Resources/llplugin/plugins/libgme_plugin.dylib + Resources/llplugin/plugins/libgnutls_plugin.dylib + Resources/llplugin/plugins/libgoom_plugin.dylib + Resources/llplugin/plugins/libgradfun_plugin.dylib + Resources/llplugin/plugins/libgradient_plugin.dylib + Resources/llplugin/plugins/libgrain_plugin.dylib + Resources/llplugin/plugins/libgrey_yuv_plugin.dylib + Resources/llplugin/plugins/libh26x_plugin.dylib + Resources/llplugin/plugins/libhds_plugin.dylib + Resources/llplugin/plugins/libheadphone_channel_mixer_plugin.dylib + Resources/llplugin/plugins/libhotkeys_plugin.dylib + Resources/llplugin/plugins/libhqdn3d_plugin.dylib + Resources/llplugin/plugins/libhttp_plugin.dylib + Resources/llplugin/plugins/libhttps_plugin.dylib + Resources/llplugin/plugins/libi420_10_p010_plugin.dylib + Resources/llplugin/plugins/libi420_nv12_plugin.dylib + Resources/llplugin/plugins/libi420_rgb_mmx_plugin.dylib + Resources/llplugin/plugins/libi420_rgb_plugin.dylib + Resources/llplugin/plugins/libi420_rgb_sse2_plugin.dylib + Resources/llplugin/plugins/libi420_yuy2_mmx_plugin.dylib + Resources/llplugin/plugins/libi420_yuy2_plugin.dylib + Resources/llplugin/plugins/libi420_yuy2_sse2_plugin.dylib + Resources/llplugin/plugins/libi422_i420_plugin.dylib + Resources/llplugin/plugins/libi422_yuy2_mmx_plugin.dylib + Resources/llplugin/plugins/libi422_yuy2_plugin.dylib + Resources/llplugin/plugins/libi422_yuy2_sse2_plugin.dylib + Resources/llplugin/plugins/libidummy_plugin.dylib + Resources/llplugin/plugins/libimage_plugin.dylib + Resources/llplugin/plugins/libimem_plugin.dylib + Resources/llplugin/plugins/libinflate_plugin.dylib + Resources/llplugin/plugins/libinteger_mixer_plugin.dylib + Resources/llplugin/plugins/libinvert_plugin.dylib + Resources/llplugin/plugins/libjpeg_plugin.dylib + Resources/llplugin/plugins/libkaraoke_plugin.dylib + Resources/llplugin/plugins/libkate_plugin.dylib + Resources/llplugin/plugins/libkeychain_plugin.dylib + Resources/llplugin/plugins/liblibass_plugin.dylib + Resources/llplugin/plugins/liblibbluray_plugin.dylib + Resources/llplugin/plugins/liblibmpeg2_plugin.dylib + Resources/llplugin/plugins/liblive555_plugin.dylib + Resources/llplugin/plugins/liblogger_plugin.dylib + Resources/llplugin/plugins/liblogo_plugin.dylib + Resources/llplugin/plugins/liblpcm_plugin.dylib + Resources/llplugin/plugins/liblua_plugin.dylib + Resources/llplugin/plugins/libmacosx_plugin.dylib + Resources/llplugin/plugins/libmad_plugin.dylib + Resources/llplugin/plugins/libmagnify_plugin.dylib + Resources/llplugin/plugins/libmarq_plugin.dylib + Resources/llplugin/plugins/libmediadirs_plugin.dylib + Resources/llplugin/plugins/libmemory_keystore_plugin.dylib + Resources/llplugin/plugins/libmirror_plugin.dylib + Resources/llplugin/plugins/libmjpeg_plugin.dylib + Resources/llplugin/plugins/libmkv_plugin.dylib + Resources/llplugin/plugins/libmod_plugin.dylib + Resources/llplugin/plugins/libmono_plugin.dylib + Resources/llplugin/plugins/libmosaic_plugin.dylib + Resources/llplugin/plugins/libmotion_plugin.dylib + Resources/llplugin/plugins/libmotionblur_plugin.dylib + Resources/llplugin/plugins/libmotiondetect_plugin.dylib + Resources/llplugin/plugins/libmp4_plugin.dylib + Resources/llplugin/plugins/libmpc_plugin.dylib + Resources/llplugin/plugins/libmpg123_plugin.dylib + Resources/llplugin/plugins/libmpgv_plugin.dylib + Resources/llplugin/plugins/libmux_asf_plugin.dylib + Resources/llplugin/plugins/libmux_avi_plugin.dylib + Resources/llplugin/plugins/libmux_dummy_plugin.dylib + Resources/llplugin/plugins/libmux_mp4_plugin.dylib + Resources/llplugin/plugins/libmux_mpjpeg_plugin.dylib + Resources/llplugin/plugins/libmux_ogg_plugin.dylib + Resources/llplugin/plugins/libmux_ps_plugin.dylib + Resources/llplugin/plugins/libmux_ts_plugin.dylib + Resources/llplugin/plugins/libmux_wav_plugin.dylib + Resources/llplugin/plugins/libncurses_plugin.dylib + Resources/llplugin/plugins/libnetsync_plugin.dylib + Resources/llplugin/plugins/libnfs_plugin.dylib + Resources/llplugin/plugins/libnormvol_plugin.dylib + Resources/llplugin/plugins/libnoseek_plugin.dylib + Resources/llplugin/plugins/libnsc_plugin.dylib + Resources/llplugin/plugins/libnsspeechsynthesizer_plugin.dylib + Resources/llplugin/plugins/libnsv_plugin.dylib + Resources/llplugin/plugins/libnuv_plugin.dylib + Resources/llplugin/plugins/libogg_plugin.dylib + Resources/llplugin/plugins/liboggspots_plugin.dylib + Resources/llplugin/plugins/liboldmovie_plugin.dylib + Resources/llplugin/plugins/liboldrc_plugin.dylib + Resources/llplugin/plugins/libopus_plugin.dylib + Resources/llplugin/plugins/libosx_notifications_plugin.dylib + Resources/llplugin/plugins/libpacketizer_a52_plugin.dylib + Resources/llplugin/plugins/libpacketizer_av1_plugin.dylib + Resources/llplugin/plugins/libpacketizer_copy_plugin.dylib + Resources/llplugin/plugins/libpacketizer_dirac_plugin.dylib + Resources/llplugin/plugins/libpacketizer_dts_plugin.dylib + Resources/llplugin/plugins/libpacketizer_flac_plugin.dylib + Resources/llplugin/plugins/libpacketizer_h264_plugin.dylib + Resources/llplugin/plugins/libpacketizer_hevc_plugin.dylib + Resources/llplugin/plugins/libpacketizer_mlp_plugin.dylib + Resources/llplugin/plugins/libpacketizer_mpeg4audio_plugin.dylib + Resources/llplugin/plugins/libpacketizer_mpeg4video_plugin.dylib + Resources/llplugin/plugins/libpacketizer_mpegaudio_plugin.dylib + Resources/llplugin/plugins/libpacketizer_mpegvideo_plugin.dylib + Resources/llplugin/plugins/libpacketizer_vc1_plugin.dylib + Resources/llplugin/plugins/libparam_eq_plugin.dylib + Resources/llplugin/plugins/libplaylist_plugin.dylib + Resources/llplugin/plugins/libpng_plugin.dylib + Resources/llplugin/plugins/libpodcast_plugin.dylib + Resources/llplugin/plugins/libposterize_plugin.dylib + Resources/llplugin/plugins/libpostproc_plugin.dylib + Resources/llplugin/plugins/libprefetch_plugin.dylib + Resources/llplugin/plugins/libps_plugin.dylib + Resources/llplugin/plugins/libpsychedelic_plugin.dylib + Resources/llplugin/plugins/libpuzzle_plugin.dylib + Resources/llplugin/plugins/libpva_plugin.dylib + Resources/llplugin/plugins/librawaud_plugin.dylib + Resources/llplugin/plugins/librawdv_plugin.dylib + Resources/llplugin/plugins/librawvid_plugin.dylib + Resources/llplugin/plugins/librawvideo_plugin.dylib + Resources/llplugin/plugins/libreal_plugin.dylib + Resources/llplugin/plugins/librecord_plugin.dylib + Resources/llplugin/plugins/libremap_plugin.dylib + Resources/llplugin/plugins/libremoteosd_plugin.dylib + Resources/llplugin/plugins/libripple_plugin.dylib + Resources/llplugin/plugins/librist_plugin.dylib + Resources/llplugin/plugins/librotate_plugin.dylib + Resources/llplugin/plugins/librss_plugin.dylib + Resources/llplugin/plugins/librtp_plugin.dylib + Resources/llplugin/plugins/librtpvideo_plugin.dylib + Resources/llplugin/plugins/librv32_plugin.dylib + Resources/llplugin/plugins/libsamplerate_plugin.dylib + Resources/llplugin/plugins/libsap_plugin.dylib + Resources/llplugin/plugins/libsatip_plugin.dylib + Resources/llplugin/plugins/libscale_plugin.dylib + Resources/llplugin/plugins/libscaletempo_pitch_plugin.dylib + Resources/llplugin/plugins/libscaletempo_plugin.dylib + Resources/llplugin/plugins/libscene_plugin.dylib + Resources/llplugin/plugins/libschroedinger_plugin.dylib + Resources/llplugin/plugins/libscreen_plugin.dylib + Resources/llplugin/plugins/libscte18_plugin.dylib + Resources/llplugin/plugins/libscte27_plugin.dylib + Resources/llplugin/plugins/libsdp_plugin.dylib + Resources/llplugin/plugins/libsecuretransport_plugin.dylib + Resources/llplugin/plugins/libsepia_plugin.dylib + Resources/llplugin/plugins/libsftp_plugin.dylib + Resources/llplugin/plugins/libsharpen_plugin.dylib + Resources/llplugin/plugins/libshm_plugin.dylib + Resources/llplugin/plugins/libsid_plugin.dylib + Resources/llplugin/plugins/libsimple_channel_mixer_plugin.dylib + Resources/llplugin/plugins/libskiptags_plugin.dylib + Resources/llplugin/plugins/libsmf_plugin.dylib + Resources/llplugin/plugins/libspatialaudio_plugin.dylib + Resources/llplugin/plugins/libspatializer_plugin.dylib + Resources/llplugin/plugins/libspdif_plugin.dylib + Resources/llplugin/plugins/libspeex_plugin.dylib + Resources/llplugin/plugins/libspeex_resampler_plugin.dylib + Resources/llplugin/plugins/libspudec_plugin.dylib + Resources/llplugin/plugins/libstats_plugin.dylib + Resources/llplugin/plugins/libstereo_widen_plugin.dylib + Resources/llplugin/plugins/libstl_plugin.dylib + Resources/llplugin/plugins/libstream_out_autodel_plugin.dylib + Resources/llplugin/plugins/libstream_out_bridge_plugin.dylib + Resources/llplugin/plugins/libstream_out_chromaprint_plugin.dylib + Resources/llplugin/plugins/libstream_out_chromecast_plugin.dylib + Resources/llplugin/plugins/libstream_out_cycle_plugin.dylib + Resources/llplugin/plugins/libstream_out_delay_plugin.dylib + Resources/llplugin/plugins/libstream_out_description_plugin.dylib + Resources/llplugin/plugins/libstream_out_display_plugin.dylib + Resources/llplugin/plugins/libstream_out_dummy_plugin.dylib + Resources/llplugin/plugins/libstream_out_duplicate_plugin.dylib + Resources/llplugin/plugins/libstream_out_es_plugin.dylib + Resources/llplugin/plugins/libstream_out_gather_plugin.dylib + Resources/llplugin/plugins/libstream_out_mosaic_bridge_plugin.dylib + Resources/llplugin/plugins/libstream_out_record_plugin.dylib + Resources/llplugin/plugins/libstream_out_rtp_plugin.dylib + Resources/llplugin/plugins/libstream_out_setid_plugin.dylib + Resources/llplugin/plugins/libstream_out_smem_plugin.dylib + Resources/llplugin/plugins/libstream_out_standard_plugin.dylib + Resources/llplugin/plugins/libstream_out_stats_plugin.dylib + Resources/llplugin/plugins/libstream_out_transcode_plugin.dylib + Resources/llplugin/plugins/libsubsdec_plugin.dylib + Resources/llplugin/plugins/libsubsdelay_plugin.dylib + Resources/llplugin/plugins/libsubstx3g_plugin.dylib + Resources/llplugin/plugins/libsubsusf_plugin.dylib + Resources/llplugin/plugins/libsubtitle_plugin.dylib + Resources/llplugin/plugins/libsvcdsub_plugin.dylib + Resources/llplugin/plugins/libswscale_plugin.dylib + Resources/llplugin/plugins/libsyslog_plugin.dylib + Resources/llplugin/plugins/libt140_plugin.dylib + Resources/llplugin/plugins/libtaglib_plugin.dylib + Resources/llplugin/plugins/libtcp_plugin.dylib + Resources/llplugin/plugins/libtdummy_plugin.dylib + Resources/llplugin/plugins/libtelx_plugin.dylib + Resources/llplugin/plugins/libtextst_plugin.dylib + Resources/llplugin/plugins/libtheora_plugin.dylib + Resources/llplugin/plugins/libtimecode_plugin.dylib + Resources/llplugin/plugins/libtospdif_plugin.dylib + Resources/llplugin/plugins/libtransform_plugin.dylib + Resources/llplugin/plugins/libtrivial_channel_mixer_plugin.dylib + Resources/llplugin/plugins/libts_plugin.dylib + Resources/llplugin/plugins/libtta_plugin.dylib + Resources/llplugin/plugins/libttml_plugin.dylib + Resources/llplugin/plugins/libtwolame_plugin.dylib + Resources/llplugin/plugins/libty_plugin.dylib + Resources/llplugin/plugins/libudp_plugin.dylib + Resources/llplugin/plugins/libugly_resampler_plugin.dylib + Resources/llplugin/plugins/libuleaddvaudio_plugin.dylib + Resources/llplugin/plugins/libupnp_plugin.dylib + Resources/llplugin/plugins/libvc1_plugin.dylib + Resources/llplugin/plugins/libvcd_plugin.dylib + Resources/llplugin/plugins/libvdr_plugin.dylib + Resources/llplugin/plugins/libvdummy_plugin.dylib + Resources/llplugin/plugins/libvhs_plugin.dylib + Resources/llplugin/plugins/libvideotoolbox_plugin.dylib + Resources/llplugin/plugins/libvisual_plugin.dylib + Resources/llplugin/plugins/libvlc.5.dylib + Resources/llplugin/plugins/libvlccore.9.dylib + Resources/llplugin/plugins/libvmem_plugin.dylib + Resources/llplugin/plugins/libvobsub_plugin.dylib + Resources/llplugin/plugins/libvoc_plugin.dylib + Resources/llplugin/plugins/libvod_rtsp_plugin.dylib + Resources/llplugin/plugins/libvorbis_plugin.dylib + Resources/llplugin/plugins/libvout_macosx_plugin.dylib + Resources/llplugin/plugins/libvpx_plugin.dylib + Resources/llplugin/plugins/libwall_plugin.dylib + Resources/llplugin/plugins/libwav_plugin.dylib + Resources/llplugin/plugins/libwave_plugin.dylib + Resources/llplugin/plugins/libwebvtt_plugin.dylib + Resources/llplugin/plugins/libx26410b_plugin.dylib + Resources/llplugin/plugins/libx264_plugin.dylib + Resources/llplugin/plugins/libx265_plugin.dylib + Resources/llplugin/plugins/libxa_plugin.dylib + Resources/llplugin/plugins/libxml_plugin.dylib + Resources/llplugin/plugins/libyuv_plugin.dylib + Resources/llplugin/plugins/libyuvp_plugin.dylib + Resources/llplugin/plugins/libyuy2_i420_plugin.dylib + Resources/llplugin/plugins/libyuy2_i422_plugin.dylib + Resources/llplugin/plugins/libzvbi_plugin.dylib + Resources/SLPlugin.app/Contents/Frameworks/DullahanHelper\ \(GPU\).app/Contents/MacOS/DullahanHelper\ \(GPU\) + Resources/SLPlugin.app/Contents/Frameworks/DullahanHelper\ \(Plugin\).app/Contents/MacOS/DullahanHelper\ \(Plugin\) + WORKING_DIRECTORY ${viewer_BINARY_DIR}/${VIEWER_CHANNEL}.app/Contents + ) +execute_process( + COMMAND sudo codesign -f -s ${SIGNING_IDENTITY} --timestamp -o runtime --runtime-version ${CMAKE_OSX_DEPLOYMENT_TARGET} + DullahanHelper.app + COMMAND sudo codesign -f -s ${SIGNING_IDENTITY} --timestamp -o runtime --runtime-version ${CMAKE_OSX_DEPLOYMENT_TARGET} + --entitlements ${CMAKE_SOURCE_DIR}/newview/slplugin.entitlements + DullahanHelper\ \(Renderer\).app/Contents/MacOS/DullahanHelper\ \(Renderer\) + COMMAND sudo codesign -f -s ${SIGNING_IDENTITY} --timestamp -o runtime --runtime-version ${CMAKE_OSX_DEPLOYMENT_TARGET} + --deep + DullahanHelper\ \(GPU\).app + DullahanHelper\ \(Plugin\).app + WORKING_DIRECTORY ${viewer_BINARY_DIR}/${VIEWER_CHANNEL}.app/Contents/Resources/SLPlugin.app/Contents/Frameworks + ) +execute_process( + COMMAND sudo codesign -f -s ${SIGNING_IDENTITY} --timestamp -o runtime --runtime-version ${CMAKE_OSX_DEPLOYMENT_TARGET} + --entitlements ${CMAKE_SOURCE_DIR}/newview/slplugin.entitlements + --deep + DullahanHelper\ \(Renderer\).app + WORKING_DIRECTORY ${viewer_BINARY_DIR}/${VIEWER_CHANNEL}.app/Contents/Resources/SLPlugin.app/Contents/Frameworks + ) +execute_process( + COMMAND sudo codesign -f -s ${SIGNING_IDENTITY} --timestamp -o runtime --runtime-version ${CMAKE_OSX_DEPLOYMENT_TARGET} + --entitlements ${CMAKE_SOURCE_DIR}/newview/slplugin.entitlements + SLPlugin.app + WORKING_DIRECTORY ${viewer_BINARY_DIR}/${VIEWER_CHANNEL}.app/Contents/Resources + ) +execute_process( + COMMAND sudo codesign -f -s ${SIGNING_IDENTITY} --timestamp -o runtime --runtime-version ${CMAKE_OSX_DEPLOYMENT_TARGET} + --entitlements ${CMAKE_SOURCE_DIR}/newview/slplugin.entitlements + -i net.${VIEWER_BINARY_NAME}.viewer + ${VIEWER_CHANNEL}.app + WORKING_DIRECTORY ${viewer_BINARY_DIR} + ) diff --git a/indra/newview/FixPackage.cmake.in b/indra/newview/FixPackage.cmake.in new file mode 100644 index 0000000000..074a6e5815 --- /dev/null +++ b/indra/newview/FixPackage.cmake.in @@ -0,0 +1,702 @@ +include(BundleUtilities) + +set(dirs + /opt/local/lib + ) + +file(CREATE_LINK + "../../../../Frameworks/libnghttp2.14.dylib" + "${CMAKE_CACHEFILE_DIR}/_CPack_Packages/${CMAKE_SYSTEM_NAME}/Bundle/${CPACK_BUNDLE_NAME}-${CPACK_PACKAGE_VERSION}-${CMAKE_SYSTEM_NAME}/${CPACK_BUNDLE_NAME}.app/Contents/Resources/SLPlugin.app/Contents/Frameworks/libnghttp2.14.dylib" + SYMBOLIC + ) +file(CREATE_LINK + "../../../../Frameworks/libpng16.16.dylib" + "${CMAKE_CACHEFILE_DIR}/_CPack_Packages/${CMAKE_SYSTEM_NAME}/Bundle/${CPACK_BUNDLE_NAME}-${CPACK_PACKAGE_VERSION}-${CMAKE_SYSTEM_NAME}/${CPACK_BUNDLE_NAME}.app/Contents/Resources/SLPlugin.app/Contents/Frameworks/libpng16.16.dylib" + SYMBOLIC + ) +file(CREATE_LINK + "../../../../Frameworks/libjpeg.8.dylib" + "${CMAKE_CACHEFILE_DIR}/_CPack_Packages/${CMAKE_SYSTEM_NAME}/Bundle/${CPACK_BUNDLE_NAME}-${CPACK_PACKAGE_VERSION}-${CMAKE_SYSTEM_NAME}/${CPACK_BUNDLE_NAME}.app/Contents/Resources/SLPlugin.app/Contents/Frameworks/libjpeg.8.dylib" + SYMBOLIC + ) +file(CREATE_LINK + "../../../../Frameworks/libaprutil-1.0.dylib" + "${CMAKE_CACHEFILE_DIR}/_CPack_Packages/${CMAKE_SYSTEM_NAME}/Bundle/${CPACK_BUNDLE_NAME}-${CPACK_PACKAGE_VERSION}-${CMAKE_SYSTEM_NAME}/${CPACK_BUNDLE_NAME}.app/Contents/Resources/SLPlugin.app/Contents/Frameworks/libaprutil-1.0.dylib" + SYMBOLIC + ) +file(CREATE_LINK + "../../../../Frameworks/libiconv.2.dylib" + "${CMAKE_CACHEFILE_DIR}/_CPack_Packages/${CMAKE_SYSTEM_NAME}/Bundle/${CPACK_BUNDLE_NAME}-${CPACK_PACKAGE_VERSION}-${CMAKE_SYSTEM_NAME}/${CPACK_BUNDLE_NAME}.app/Contents/Resources/SLPlugin.app/Contents/Frameworks/libiconv.2.dylib" + SYMBOLIC + ) +file(CREATE_LINK + "../../../../Frameworks/libapr-1.0.dylib" + "${CMAKE_CACHEFILE_DIR}/_CPack_Packages/${CMAKE_SYSTEM_NAME}/Bundle/${CPACK_BUNDLE_NAME}-${CPACK_PACKAGE_VERSION}-${CMAKE_SYSTEM_NAME}/${CPACK_BUNDLE_NAME}.app/Contents/Resources/SLPlugin.app/Contents/Frameworks/libapr-1.0.dylib" + SYMBOLIC + ) +file(CREATE_LINK + "../../../../Frameworks/libz.1.dylib" + "${CMAKE_CACHEFILE_DIR}/_CPack_Packages/${CMAKE_SYSTEM_NAME}/Bundle/${CPACK_BUNDLE_NAME}-${CPACK_PACKAGE_VERSION}-${CMAKE_SYSTEM_NAME}/${CPACK_BUNDLE_NAME}.app/Contents/Resources/SLPlugin.app/Contents/Frameworks/libz.1.dylib" + SYMBOLIC + ) +file(CREATE_LINK + "../../../../Frameworks/libboost_atomic-mt.dylib" + "${CMAKE_CACHEFILE_DIR}/_CPack_Packages/${CMAKE_SYSTEM_NAME}/Bundle/${CPACK_BUNDLE_NAME}-${CPACK_PACKAGE_VERSION}-${CMAKE_SYSTEM_NAME}/${CPACK_BUNDLE_NAME}.app/Contents/Resources/SLPlugin.app/Contents/Frameworks/libboost_atomic-mt.dylib" + SYMBOLIC + ) +file(CREATE_LINK + "../../../../Frameworks/libboost_context-mt.dylib" + "${CMAKE_CACHEFILE_DIR}/_CPack_Packages/${CMAKE_SYSTEM_NAME}/Bundle/${CPACK_BUNDLE_NAME}-${CPACK_PACKAGE_VERSION}-${CMAKE_SYSTEM_NAME}/${CPACK_BUNDLE_NAME}.app/Contents/Resources/SLPlugin.app/Contents/Frameworks/libboost_context-mt.dylib" + SYMBOLIC + ) +file(CREATE_LINK + "../../../../Frameworks/libboost_fiber-mt.dylib" + "${CMAKE_CACHEFILE_DIR}/_CPack_Packages/${CMAKE_SYSTEM_NAME}/Bundle/${CPACK_BUNDLE_NAME}-${CPACK_PACKAGE_VERSION}-${CMAKE_SYSTEM_NAME}/${CPACK_BUNDLE_NAME}.app/Contents/Resources/SLPlugin.app/Contents/Frameworks/libboost_fiber-mt.dylib" + SYMBOLIC + ) +file(CREATE_LINK + "../../../../Frameworks/libboost_filesystem-mt.dylib" + "${CMAKE_CACHEFILE_DIR}/_CPack_Packages/${CMAKE_SYSTEM_NAME}/Bundle/${CPACK_BUNDLE_NAME}-${CPACK_PACKAGE_VERSION}-${CMAKE_SYSTEM_NAME}/${CPACK_BUNDLE_NAME}.app/Contents/Resources/SLPlugin.app/Contents/Frameworks/libboost_filesystem-mt.dylib" + SYMBOLIC + ) +file(CREATE_LINK + "../../../../Frameworks/libboost_program_options-mt.dylib" + "${CMAKE_CACHEFILE_DIR}/_CPack_Packages/${CMAKE_SYSTEM_NAME}/Bundle/${CPACK_BUNDLE_NAME}-${CPACK_PACKAGE_VERSION}-${CMAKE_SYSTEM_NAME}/${CPACK_BUNDLE_NAME}.app/Contents/Resources/SLPlugin.app/Contents/Frameworks/libboost_program_options-mt.dylib" + SYMBOLIC + ) +file(CREATE_LINK + "../../../../Frameworks/libboost_regex-mt.dylib" + "${CMAKE_CACHEFILE_DIR}/_CPack_Packages/${CMAKE_SYSTEM_NAME}/Bundle/${CPACK_BUNDLE_NAME}-${CPACK_PACKAGE_VERSION}-${CMAKE_SYSTEM_NAME}/${CPACK_BUNDLE_NAME}.app/Contents/Resources/SLPlugin.app/Contents/Frameworks/libboost_regex-mt.dylib" + SYMBOLIC + ) +file(CREATE_LINK + "../../../../Frameworks/libboost_system-mt.dylib" + "${CMAKE_CACHEFILE_DIR}/_CPack_Packages/${CMAKE_SYSTEM_NAME}/Bundle/${CPACK_BUNDLE_NAME}-${CPACK_PACKAGE_VERSION}-${CMAKE_SYSTEM_NAME}/${CPACK_BUNDLE_NAME}.app/Contents/Resources/SLPlugin.app/Contents/Frameworks/libboost_system-mt.dylib" + SYMBOLIC + ) +file(CREATE_LINK + "../../../../Frameworks/libboost_thread-mt.dylib" + "${CMAKE_CACHEFILE_DIR}/_CPack_Packages/${CMAKE_SYSTEM_NAME}/Bundle/${CPACK_BUNDLE_NAME}-${CPACK_PACKAGE_VERSION}-${CMAKE_SYSTEM_NAME}/${CPACK_BUNDLE_NAME}.app/Contents/Resources/SLPlugin.app/Contents/Frameworks/libboost_thread-mt.dylib" + SYMBOLIC + ) +file(CREATE_LINK + "../../../../Frameworks/libboost_url-mt.dylib" + "${CMAKE_CACHEFILE_DIR}/_CPack_Packages/${CMAKE_SYSTEM_NAME}/Bundle/${CPACK_BUNDLE_NAME}-${CPACK_PACKAGE_VERSION}-${CMAKE_SYSTEM_NAME}/${CPACK_BUNDLE_NAME}.app/Contents/Resources/SLPlugin.app/Contents/Frameworks/libboost_url-mt.dylib" + SYMBOLIC + ) +file(CREATE_LINK + "../../../../Frameworks/libexpat.1.dylib" + "${CMAKE_CACHEFILE_DIR}/_CPack_Packages/${CMAKE_SYSTEM_NAME}/Bundle/${CPACK_BUNDLE_NAME}-${CPACK_PACKAGE_VERSION}-${CMAKE_SYSTEM_NAME}/${CPACK_BUNDLE_NAME}.app/Contents/Resources/SLPlugin.app/Contents/Frameworks/libexpat.1.dylib" + SYMBOLIC + ) +file(CREATE_LINK + "../../../../Frameworks/libfreetype.6.dylib" + "${CMAKE_CACHEFILE_DIR}/_CPack_Packages/${CMAKE_SYSTEM_NAME}/Bundle/${CPACK_BUNDLE_NAME}-${CPACK_PACKAGE_VERSION}-${CMAKE_SYSTEM_NAME}/${CPACK_BUNDLE_NAME}.app/Contents/Resources/SLPlugin.app/Contents/Frameworks/libfreetype.6.dylib" + SYMBOLIC + ) +file(CREATE_LINK + "../../../../Frameworks/libbz2.1.0.dylib" + "${CMAKE_CACHEFILE_DIR}/_CPack_Packages/${CMAKE_SYSTEM_NAME}/Bundle/${CPACK_BUNDLE_NAME}-${CPACK_PACKAGE_VERSION}-${CMAKE_SYSTEM_NAME}/${CPACK_BUNDLE_NAME}.app/Contents/Resources/SLPlugin.app/Contents/Frameworks/libbz2.1.0.dylib" + SYMBOLIC + ) +file(CREATE_LINK + "../../../../Frameworks/libbrotlidec.1.dylib" + "${CMAKE_CACHEFILE_DIR}/_CPack_Packages/${CMAKE_SYSTEM_NAME}/Bundle/${CPACK_BUNDLE_NAME}-${CPACK_PACKAGE_VERSION}-${CMAKE_SYSTEM_NAME}/${CPACK_BUNDLE_NAME}.app/Contents/Resources/SLPlugin.app/Contents/Frameworks/libbrotlidec.1.dylib" + SYMBOLIC + ) +file(CREATE_LINK + "../../../../Frameworks/libbrotlicommon.1.dylib" + "${CMAKE_CACHEFILE_DIR}/_CPack_Packages/${CMAKE_SYSTEM_NAME}/Bundle/${CPACK_BUNDLE_NAME}-${CPACK_PACKAGE_VERSION}-${CMAKE_SYSTEM_NAME}/${CPACK_BUNDLE_NAME}.app/Contents/Resources/SLPlugin.app/Contents/Frameworks/libbrotlicommon.1.dylib" + SYMBOLIC + ) +file(CREATE_LINK + "../../../../Frameworks/libicudata.76.dylib" + "${CMAKE_CACHEFILE_DIR}/_CPack_Packages/${CMAKE_SYSTEM_NAME}/Bundle/${CPACK_BUNDLE_NAME}-${CPACK_PACKAGE_VERSION}-${CMAKE_SYSTEM_NAME}/${CPACK_BUNDLE_NAME}.app/Contents/Resources/SLPlugin.app/Contents/Frameworks/libicudata.76.dylib" + SYMBOLIC + ) +file(CREATE_LINK + "../../../../Frameworks/libicui18n.76.dylib" + "${CMAKE_CACHEFILE_DIR}/_CPack_Packages/${CMAKE_SYSTEM_NAME}/Bundle/${CPACK_BUNDLE_NAME}-${CPACK_PACKAGE_VERSION}-${CMAKE_SYSTEM_NAME}/${CPACK_BUNDLE_NAME}.app/Contents/Resources/SLPlugin.app/Contents/Frameworks/libicui18n.76.dylib" + SYMBOLIC + ) +file(CREATE_LINK + "../../../../Frameworks/libicuuc.76.dylib" + "${CMAKE_CACHEFILE_DIR}/_CPack_Packages/${CMAKE_SYSTEM_NAME}/Bundle/${CPACK_BUNDLE_NAME}-${CPACK_PACKAGE_VERSION}-${CMAKE_SYSTEM_NAME}/${CPACK_BUNDLE_NAME}.app/Contents/Resources/SLPlugin.app/Contents/Frameworks/libicuuc.76.dylib" + SYMBOLIC + ) +file(CREATE_LINK + "../../../../Frameworks/Chromium Embedded Framework.framework" + "${CMAKE_CACHEFILE_DIR}/_CPack_Packages/${CMAKE_SYSTEM_NAME}/Bundle/${CPACK_BUNDLE_NAME}-${CPACK_PACKAGE_VERSION}-${CMAKE_SYSTEM_NAME}/${CPACK_BUNDLE_NAME}.app/Contents/Resources/SLPlugin.app/Contents/Frameworks/Chromium Embedded Framework.framework" + SYMBOLIC + ) + +fixup_bundle(${CMAKE_CACHEFILE_DIR}/_CPack_Packages/${CMAKE_SYSTEM_NAME}/Bundle/${CPACK_BUNDLE_NAME}-${CPACK_PACKAGE_VERSION}-${CMAKE_SYSTEM_NAME}/${CPACK_BUNDLE_NAME}.app/Contents/MacOS/${CPACK_BUNDLE_NAME} "" "${dirs}") + +file(CHMOD + "${CMAKE_CACHEFILE_DIR}/_CPack_Packages/${CMAKE_SYSTEM_NAME}/Bundle/${CPACK_BUNDLE_NAME}-${CPACK_PACKAGE_VERSION}-${CMAKE_SYSTEM_NAME}/${CPACK_BUNDLE_NAME}.app/Contents/Resources/SLPlugin.app/Contents/Frameworks/DullahanHelper.app/Contents/MacOS/DullahanHelper" + "${CMAKE_CACHEFILE_DIR}/_CPack_Packages/${CMAKE_SYSTEM_NAME}/Bundle/${CPACK_BUNDLE_NAME}-${CPACK_PACKAGE_VERSION}-${CMAKE_SYSTEM_NAME}/${CPACK_BUNDLE_NAME}.app/Contents/Resources/SLPlugin.app/Contents/Frameworks/DullahanHelper (GPU).app/Contents/MacOS/DullahanHelper (GPU)" + "${CMAKE_CACHEFILE_DIR}/_CPack_Packages/${CMAKE_SYSTEM_NAME}/Bundle/${CPACK_BUNDLE_NAME}-${CPACK_PACKAGE_VERSION}-${CMAKE_SYSTEM_NAME}/${CPACK_BUNDLE_NAME}.app/Contents/Resources/SLPlugin.app/Contents/Frameworks/DullahanHelper (Plugin).app/Contents/MacOS/DullahanHelper (Plugin)" + "${CMAKE_CACHEFILE_DIR}/_CPack_Packages/${CMAKE_SYSTEM_NAME}/Bundle/${CPACK_BUNDLE_NAME}-${CPACK_PACKAGE_VERSION}-${CMAKE_SYSTEM_NAME}/${CPACK_BUNDLE_NAME}.app/Contents/Resources/SLPlugin.app/Contents/Frameworks/DullahanHelper (Renderer).app/Contents/MacOS/DullahanHelper (Renderer)" + PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE + ) + +execute_process( + COMMAND hdiutil detach /Volumes/VLC\ media\ player + COMMAND lipo libalut.0.dylib + -thin ${CMAKE_OSX_ARCHITECTURES} + -output libalut.0.dylib + COMMAND lipo libapr-1.0.dylib + -thin ${CMAKE_OSX_ARCHITECTURES} + -output libapr-1.0.dylib + COMMAND lipo libaprutil-1.0.dylib + -thin ${CMAKE_OSX_ARCHITECTURES} + -output libaprutil-1.0.dylib + COMMAND lipo libboost_atomic-mt.dylib + -thin ${CMAKE_OSX_ARCHITECTURES} + -output libboost_atomic-mt.dylib + COMMAND lipo libboost_context-mt.dylib + -thin ${CMAKE_OSX_ARCHITECTURES} + -output libboost_context-mt.dylib + COMMAND lipo libboost_fiber-mt.dylib + -thin ${CMAKE_OSX_ARCHITECTURES} + -output libboost_fiber-mt.dylib + COMMAND lipo libboost_filesystem-mt.dylib + -thin ${CMAKE_OSX_ARCHITECTURES} + -output libboost_filesystem-mt.dylib + COMMAND lipo libboost_program_options-mt.dylib + -thin ${CMAKE_OSX_ARCHITECTURES} + -output libboost_program_options-mt.dylib + COMMAND lipo libboost_regex-mt.dylib + -thin ${CMAKE_OSX_ARCHITECTURES} + -output libboost_regex-mt.dylib + COMMAND lipo libboost_system-mt.dylib + -thin ${CMAKE_OSX_ARCHITECTURES} + -output libboost_system-mt.dylib + COMMAND lipo libboost_thread-mt.dylib + -thin ${CMAKE_OSX_ARCHITECTURES} + -output libboost_thread-mt.dylib + COMMAND lipo libboost_url-mt.dylib + -thin ${CMAKE_OSX_ARCHITECTURES} + -output libboost_url-mt.dylib + COMMAND lipo libbrotlicommon.1.1.0.dylib + -thin ${CMAKE_OSX_ARCHITECTURES} + -output libbrotlicommon.1.1.0.dylib + COMMAND lipo libbrotlidec.1.1.0.dylib + -thin ${CMAKE_OSX_ARCHITECTURES} + -output libbrotlidec.1.1.0.dylib + COMMAND lipo libbz2.1.0.8.dylib + -thin ${CMAKE_OSX_ARCHITECTURES} + -output libbz2.1.0.8.dylib + COMMAND lipo libcollada14dom.2.3-r8.dylib + -thin ${CMAKE_OSX_ARCHITECTURES} + -output libcollada14dom.2.3-r8.dylib + COMMAND lipo libexpat.1.10.0.dylib + -thin ${CMAKE_OSX_ARCHITECTURES} + -output libexpat.1.10.0.dylib + COMMAND lipo libfreetype.6.dylib + -thin ${CMAKE_OSX_ARCHITECTURES} + -output libfreetype.6.dylib + COMMAND lipo libhunspell-1.7.0.dylib + -thin ${CMAKE_OSX_ARCHITECTURES} + -output libhunspell-1.7.0.dylib + COMMAND lipo libiconv.2.dylib + -thin ${CMAKE_OSX_ARCHITECTURES} + -output libiconv.2.dylib + COMMAND lipo libicudata.76.1.dylib + -thin ${CMAKE_OSX_ARCHITECTURES} + -output libicudata.76.1.dylib + COMMAND lipo libicui18n.76.1.dylib + -thin ${CMAKE_OSX_ARCHITECTURES} + -output libicui18n.76.1.dylib + COMMAND lipo libicuuc.76.1.dylib + -thin ${CMAKE_OSX_ARCHITECTURES} + -output libicuuc.76.1.dylib + COMMAND lipo libjpeg.8.3.2.dylib + -thin ${CMAKE_OSX_ARCHITECTURES} + -output libjpeg.8.3.2.dylib + COMMAND lipo libllwebrtc.dylib + -thin ${CMAKE_OSX_ARCHITECTURES} + -output libllwebrtc.dylib + COMMAND lipo liblzma.5.dylib + -thin ${CMAKE_OSX_ARCHITECTURES} + -output liblzma.5.dylib + COMMAND lipo libminizip.1.dylib + -thin ${CMAKE_OSX_ARCHITECTURES} + -output libminizip.1.dylib + COMMAND lipo libncurses.6.dylib + -thin ${CMAKE_OSX_ARCHITECTURES} + -output libncurses.6.dylib + COMMAND lipo libndofdev.dylib + -thin ${CMAKE_OSX_ARCHITECTURES} + -output libndofdev.dylib + COMMAND lipo libnghttp2.14.dylib + -thin ${CMAKE_OSX_ARCHITECTURES} + -output libnghttp2.14.dylib + COMMAND lipo libogg.0.dylib + -thin ${CMAKE_OSX_ARCHITECTURES} + -output libogg.0.dylib + COMMAND lipo libopenal.1.24.2.dylib + -thin ${CMAKE_OSX_ARCHITECTURES} + -output libopenal.1.24.2.dylib + COMMAND lipo libpng16.16.dylib + -thin ${CMAKE_OSX_ARCHITECTURES} + -output libpng16.16.dylib + COMMAND lipo libvlc.5.dylib + -thin ${CMAKE_OSX_ARCHITECTURES} + -output libvlc.5.dylib + COMMAND lipo libvlccore.9.dylib + -thin ${CMAKE_OSX_ARCHITECTURES} + -output libvlccore.9.dylib + COMMAND lipo libvorbis.0.dylib + -thin ${CMAKE_OSX_ARCHITECTURES} + -output libvorbis.0.dylib + COMMAND lipo libvorbisenc.2.dylib + -thin ${CMAKE_OSX_ARCHITECTURES} + -output libvorbisenc.2.dylib + COMMAND lipo libvorbisfile.3.dylib + -thin ${CMAKE_OSX_ARCHITECTURES} + -output libvorbisfile.3.dylib + COMMAND lipo libxml2.2.dylib + -thin ${CMAKE_OSX_ARCHITECTURES} + -output libxml2.2.dylib + COMMAND lipo libz.1.3.1.dylib + -thin ${CMAKE_OSX_ARCHITECTURES} + -output libz.1.3.1.dylib + WORKING_DIRECTORY ${CMAKE_CACHEFILE_DIR}/_CPack_Packages/${CMAKE_SYSTEM_NAME}/Bundle/${CPACK_BUNDLE_NAME}-${CPACK_PACKAGE_VERSION}-${CMAKE_SYSTEM_NAME}/${CPACK_BUNDLE_NAME}.app/Contents/Frameworks + ERROR_QUIET + ) + +message("By default, the situation is assumed to be the strictest, an Apple Silicon Mac with the default security settings. Running a native self-built viewer on it without correct codesigning would lead to a crash. Also, codesigning requires administrative access. If you believe you're not in such a situation, you can remove the sudos in this file.") +execute_process( + COMMAND sudo codesign -f -s ${SIGNING_IDENTITY} --timestamp -o runtime --runtime-version ${CMAKE_OSX_DEPLOYMENT_TARGET} + Frameworks/Chromium\ Embedded\ Framework.framework/Libraries/libEGL.dylib + Frameworks/Chromium\ Embedded\ Framework.framework/Libraries/libGLESv2.dylib + Frameworks/Chromium\ Embedded\ Framework.framework/Libraries/libvk_swiftshader.dylib + Frameworks/Chromium\ Embedded\ Framework.framework + Frameworks/libalut.0.dylib + Frameworks/libapr-1.0.dylib + Frameworks/libaprutil-1.0.dylib + Frameworks/libboost_atomic-mt.dylib + Frameworks/libboost_context-mt.dylib + Frameworks/libboost_fiber-mt.dylib + Frameworks/libboost_filesystem-mt.dylib + Frameworks/libboost_program_options-mt.dylib + Frameworks/libboost_regex-mt.dylib + Frameworks/libboost_system-mt.dylib + Frameworks/libboost_thread-mt.dylib + Frameworks/libboost_url-mt.dylib + Frameworks/libbrotlicommon.1.1.0.dylib + Frameworks/libbrotlidec.1.1.0.dylib + Frameworks/libbz2.1.0.8.dylib + Frameworks/libcollada14dom.2.3-r8.dylib + Frameworks/libexpat.1.10.0.dylib + Frameworks/libfreetype.6.dylib + Frameworks/libhunspell-1.7.0.dylib + Frameworks/libiconv.2.dylib + Frameworks/libicudata.76.1.dylib + Frameworks/libicui18n.76.1.dylib + Frameworks/libicuuc.76.1.dylib + Frameworks/libjpeg.8.3.2.dylib + Frameworks/libllwebrtc.dylib + Frameworks/liblzma.5.dylib + Frameworks/libminizip.1.dylib + Frameworks/libncurses.6.dylib + Frameworks/libndofdev.dylib + Frameworks/libnghttp2.14.dylib + Frameworks/libogg.0.dylib + Frameworks/libopenal.1.24.2.dylib + Frameworks/libpng16.16.dylib + Frameworks/libvlc.5.dylib + Frameworks/libvlccore.9.dylib + Frameworks/libvorbis.0.dylib + Frameworks/libvorbisenc.2.dylib + Frameworks/libvorbisfile.3.dylib + Frameworks/libxml2.2.dylib + Frameworks/libz.1.3.1.dylib + Resources/libndofdev.dylib + Resources/llplugin/media_plugin_cef.dylib + Resources/llplugin/media_plugin_libvlc.dylib + Resources/llplugin/plugins/liba52_plugin.dylib + Resources/llplugin/plugins/libaccess_concat_plugin.dylib + Resources/llplugin/plugins/libaccess_imem_plugin.dylib + Resources/llplugin/plugins/libaccess_mms_plugin.dylib + Resources/llplugin/plugins/libaccess_output_dummy_plugin.dylib + Resources/llplugin/plugins/libaccess_output_file_plugin.dylib + Resources/llplugin/plugins/libaccess_output_http_plugin.dylib + Resources/llplugin/plugins/libaccess_output_livehttp_plugin.dylib + Resources/llplugin/plugins/libaccess_output_rist_plugin.dylib + Resources/llplugin/plugins/libaccess_output_shout_plugin.dylib + Resources/llplugin/plugins/libaccess_output_srt_plugin.dylib + Resources/llplugin/plugins/libaccess_output_udp_plugin.dylib + Resources/llplugin/plugins/libaccess_realrtsp_plugin.dylib + Resources/llplugin/plugins/libaccess_srt_plugin.dylib + Resources/llplugin/plugins/libadaptive_plugin.dylib + Resources/llplugin/plugins/libaddonsfsstorage_plugin.dylib + Resources/llplugin/plugins/libaddonsvorepository_plugin.dylib + Resources/llplugin/plugins/libadf_plugin.dylib + Resources/llplugin/plugins/libadjust_plugin.dylib + Resources/llplugin/plugins/libadpcm_plugin.dylib + Resources/llplugin/plugins/libadummy_plugin.dylib + Resources/llplugin/plugins/libaes3_plugin.dylib + Resources/llplugin/plugins/libafile_plugin.dylib + Resources/llplugin/plugins/libaiff_plugin.dylib + Resources/llplugin/plugins/libalphamask_plugin.dylib + Resources/llplugin/plugins/libamem_plugin.dylib + Resources/llplugin/plugins/libanaglyph_plugin.dylib + Resources/llplugin/plugins/libantiflicker_plugin.dylib + Resources/llplugin/plugins/libaom_plugin.dylib + Resources/llplugin/plugins/libaraw_plugin.dylib + Resources/llplugin/plugins/libarchive_plugin.dylib + Resources/llplugin/plugins/libaribsub_plugin.dylib + Resources/llplugin/plugins/libasf_plugin.dylib + Resources/llplugin/plugins/libattachment_plugin.dylib + Resources/llplugin/plugins/libau_plugin.dylib + Resources/llplugin/plugins/libaudio_format_plugin.dylib + Resources/llplugin/plugins/libaudiobargraph_a_plugin.dylib + Resources/llplugin/plugins/libaudiobargraph_v_plugin.dylib + Resources/llplugin/plugins/libaudioscrobbler_plugin.dylib + Resources/llplugin/plugins/libaudiotoolboxmidi_plugin.dylib + Resources/llplugin/plugins/libauhal_plugin.dylib + Resources/llplugin/plugins/libavaudiocapture_plugin.dylib + Resources/llplugin/plugins/libavcapture_plugin.dylib + Resources/llplugin/plugins/libavcodec_plugin.dylib + Resources/llplugin/plugins/libavi_plugin.dylib + Resources/llplugin/plugins/libball_plugin.dylib + Resources/llplugin/plugins/libblend_plugin.dylib + Resources/llplugin/plugins/libblendbench_plugin.dylib + Resources/llplugin/plugins/libbluescreen_plugin.dylib + Resources/llplugin/plugins/libbluray-awt-j2se-1.3.2.jar + Resources/llplugin/plugins/libbluray-j2se-1.3.2.jar + Resources/llplugin/plugins/libbonjour_plugin.dylib + Resources/llplugin/plugins/libcache_block_plugin.dylib + Resources/llplugin/plugins/libcache_read_plugin.dylib + Resources/llplugin/plugins/libcaf_plugin.dylib + Resources/llplugin/plugins/libcanvas_plugin.dylib + Resources/llplugin/plugins/libcaopengllayer_plugin.dylib + Resources/llplugin/plugins/libcc_plugin.dylib + Resources/llplugin/plugins/libcdda_plugin.dylib + Resources/llplugin/plugins/libcdg_plugin.dylib + Resources/llplugin/plugins/libchain_plugin.dylib + Resources/llplugin/plugins/libchorus_flanger_plugin.dylib + Resources/llplugin/plugins/libci_filters_plugin.dylib + Resources/llplugin/plugins/libclone_plugin.dylib + Resources/llplugin/plugins/libcolorthres_plugin.dylib + Resources/llplugin/plugins/libcompressor_plugin.dylib + Resources/llplugin/plugins/libconsole_logger_plugin.dylib + Resources/llplugin/plugins/libcroppadd_plugin.dylib + Resources/llplugin/plugins/libcvdsub_plugin.dylib + Resources/llplugin/plugins/libcvpx_plugin.dylib + Resources/llplugin/plugins/libdav1d_plugin.dylib + Resources/llplugin/plugins/libdca_plugin.dylib + Resources/llplugin/plugins/libdcp_plugin.dylib + Resources/llplugin/plugins/libddummy_plugin.dylib + Resources/llplugin/plugins/libdecomp_plugin.dylib + Resources/llplugin/plugins/libdeinterlace_plugin.dylib + Resources/llplugin/plugins/libdemux_cdg_plugin.dylib + Resources/llplugin/plugins/libdemux_chromecast_plugin.dylib + Resources/llplugin/plugins/libdemux_stl_plugin.dylib + Resources/llplugin/plugins/libdemuxdump_plugin.dylib + Resources/llplugin/plugins/libdiracsys_plugin.dylib + Resources/llplugin/plugins/libdirectory_demux_plugin.dylib + Resources/llplugin/plugins/libdolby_surround_decoder_plugin.dylib + Resources/llplugin/plugins/libdummy_plugin.dylib + Resources/llplugin/plugins/libdvbsub_plugin.dylib + Resources/llplugin/plugins/libdvdnav_plugin.dylib + Resources/llplugin/plugins/libdvdread_plugin.dylib + Resources/llplugin/plugins/libdynamicoverlay_plugin.dylib + Resources/llplugin/plugins/libedgedetection_plugin.dylib + Resources/llplugin/plugins/libedummy_plugin.dylib + Resources/llplugin/plugins/libequalizer_plugin.dylib + Resources/llplugin/plugins/liberase_plugin.dylib + Resources/llplugin/plugins/libes_plugin.dylib + Resources/llplugin/plugins/libexport_plugin.dylib + Resources/llplugin/plugins/libextract_plugin.dylib + Resources/llplugin/plugins/libfaad_plugin.dylib + Resources/llplugin/plugins/libfile_keystore_plugin.dylib + Resources/llplugin/plugins/libfile_logger_plugin.dylib + Resources/llplugin/plugins/libfilesystem_plugin.dylib + Resources/llplugin/plugins/libfingerprinter_plugin.dylib + Resources/llplugin/plugins/libflac_plugin.dylib + Resources/llplugin/plugins/libflacsys_plugin.dylib + Resources/llplugin/plugins/libflaschen_plugin.dylib + Resources/llplugin/plugins/libfloat_mixer_plugin.dylib + Resources/llplugin/plugins/libfolder_plugin.dylib + Resources/llplugin/plugins/libfps_plugin.dylib + Resources/llplugin/plugins/libfreetype_plugin.dylib + Resources/llplugin/plugins/libfreeze_plugin.dylib + Resources/llplugin/plugins/libftp_plugin.dylib + Resources/llplugin/plugins/libg711_plugin.dylib + Resources/llplugin/plugins/libgain_plugin.dylib + Resources/llplugin/plugins/libgaussianblur_plugin.dylib + Resources/llplugin/plugins/libgestures_plugin.dylib + Resources/llplugin/plugins/libglconv_cvpx_plugin.dylib + Resources/llplugin/plugins/libgme_plugin.dylib + Resources/llplugin/plugins/libgnutls_plugin.dylib + Resources/llplugin/plugins/libgoom_plugin.dylib + Resources/llplugin/plugins/libgradfun_plugin.dylib + Resources/llplugin/plugins/libgradient_plugin.dylib + Resources/llplugin/plugins/libgrain_plugin.dylib + Resources/llplugin/plugins/libgrey_yuv_plugin.dylib + Resources/llplugin/plugins/libh26x_plugin.dylib + Resources/llplugin/plugins/libhds_plugin.dylib + Resources/llplugin/plugins/libheadphone_channel_mixer_plugin.dylib + Resources/llplugin/plugins/libhotkeys_plugin.dylib + Resources/llplugin/plugins/libhqdn3d_plugin.dylib + Resources/llplugin/plugins/libhttp_plugin.dylib + Resources/llplugin/plugins/libhttps_plugin.dylib + Resources/llplugin/plugins/libi420_10_p010_plugin.dylib + Resources/llplugin/plugins/libi420_nv12_plugin.dylib + Resources/llplugin/plugins/libi420_rgb_mmx_plugin.dylib + Resources/llplugin/plugins/libi420_rgb_plugin.dylib + Resources/llplugin/plugins/libi420_rgb_sse2_plugin.dylib + Resources/llplugin/plugins/libi420_yuy2_mmx_plugin.dylib + Resources/llplugin/plugins/libi420_yuy2_plugin.dylib + Resources/llplugin/plugins/libi420_yuy2_sse2_plugin.dylib + Resources/llplugin/plugins/libi422_i420_plugin.dylib + Resources/llplugin/plugins/libi422_yuy2_mmx_plugin.dylib + Resources/llplugin/plugins/libi422_yuy2_plugin.dylib + Resources/llplugin/plugins/libi422_yuy2_sse2_plugin.dylib + Resources/llplugin/plugins/libidummy_plugin.dylib + Resources/llplugin/plugins/libimage_plugin.dylib + Resources/llplugin/plugins/libimem_plugin.dylib + Resources/llplugin/plugins/libinflate_plugin.dylib + Resources/llplugin/plugins/libinteger_mixer_plugin.dylib + Resources/llplugin/plugins/libinvert_plugin.dylib + Resources/llplugin/plugins/libjpeg_plugin.dylib + Resources/llplugin/plugins/libkaraoke_plugin.dylib + Resources/llplugin/plugins/libkate_plugin.dylib + Resources/llplugin/plugins/libkeychain_plugin.dylib + Resources/llplugin/plugins/liblibass_plugin.dylib + Resources/llplugin/plugins/liblibbluray_plugin.dylib + Resources/llplugin/plugins/liblibmpeg2_plugin.dylib + Resources/llplugin/plugins/liblive555_plugin.dylib + Resources/llplugin/plugins/liblogger_plugin.dylib + Resources/llplugin/plugins/liblogo_plugin.dylib + Resources/llplugin/plugins/liblpcm_plugin.dylib + Resources/llplugin/plugins/liblua_plugin.dylib + Resources/llplugin/plugins/libmacosx_plugin.dylib + Resources/llplugin/plugins/libmad_plugin.dylib + Resources/llplugin/plugins/libmagnify_plugin.dylib + Resources/llplugin/plugins/libmarq_plugin.dylib + Resources/llplugin/plugins/libmediadirs_plugin.dylib + Resources/llplugin/plugins/libmemory_keystore_plugin.dylib + Resources/llplugin/plugins/libmirror_plugin.dylib + Resources/llplugin/plugins/libmjpeg_plugin.dylib + Resources/llplugin/plugins/libmkv_plugin.dylib + Resources/llplugin/plugins/libmod_plugin.dylib + Resources/llplugin/plugins/libmono_plugin.dylib + Resources/llplugin/plugins/libmosaic_plugin.dylib + Resources/llplugin/plugins/libmotion_plugin.dylib + Resources/llplugin/plugins/libmotionblur_plugin.dylib + Resources/llplugin/plugins/libmotiondetect_plugin.dylib + Resources/llplugin/plugins/libmp4_plugin.dylib + Resources/llplugin/plugins/libmpc_plugin.dylib + Resources/llplugin/plugins/libmpg123_plugin.dylib + Resources/llplugin/plugins/libmpgv_plugin.dylib + Resources/llplugin/plugins/libmux_asf_plugin.dylib + Resources/llplugin/plugins/libmux_avi_plugin.dylib + Resources/llplugin/plugins/libmux_dummy_plugin.dylib + Resources/llplugin/plugins/libmux_mp4_plugin.dylib + Resources/llplugin/plugins/libmux_mpjpeg_plugin.dylib + Resources/llplugin/plugins/libmux_ogg_plugin.dylib + Resources/llplugin/plugins/libmux_ps_plugin.dylib + Resources/llplugin/plugins/libmux_ts_plugin.dylib + Resources/llplugin/plugins/libmux_wav_plugin.dylib + Resources/llplugin/plugins/libncurses_plugin.dylib + Resources/llplugin/plugins/libnetsync_plugin.dylib + Resources/llplugin/plugins/libnfs_plugin.dylib + Resources/llplugin/plugins/libnormvol_plugin.dylib + Resources/llplugin/plugins/libnoseek_plugin.dylib + Resources/llplugin/plugins/libnsc_plugin.dylib + Resources/llplugin/plugins/libnsspeechsynthesizer_plugin.dylib + Resources/llplugin/plugins/libnsv_plugin.dylib + Resources/llplugin/plugins/libnuv_plugin.dylib + Resources/llplugin/plugins/libogg_plugin.dylib + Resources/llplugin/plugins/liboggspots_plugin.dylib + Resources/llplugin/plugins/liboldmovie_plugin.dylib + Resources/llplugin/plugins/liboldrc_plugin.dylib + Resources/llplugin/plugins/libopus_plugin.dylib + Resources/llplugin/plugins/libosx_notifications_plugin.dylib + Resources/llplugin/plugins/libpacketizer_a52_plugin.dylib + Resources/llplugin/plugins/libpacketizer_av1_plugin.dylib + Resources/llplugin/plugins/libpacketizer_copy_plugin.dylib + Resources/llplugin/plugins/libpacketizer_dirac_plugin.dylib + Resources/llplugin/plugins/libpacketizer_dts_plugin.dylib + Resources/llplugin/plugins/libpacketizer_flac_plugin.dylib + Resources/llplugin/plugins/libpacketizer_h264_plugin.dylib + Resources/llplugin/plugins/libpacketizer_hevc_plugin.dylib + Resources/llplugin/plugins/libpacketizer_mlp_plugin.dylib + Resources/llplugin/plugins/libpacketizer_mpeg4audio_plugin.dylib + Resources/llplugin/plugins/libpacketizer_mpeg4video_plugin.dylib + Resources/llplugin/plugins/libpacketizer_mpegaudio_plugin.dylib + Resources/llplugin/plugins/libpacketizer_mpegvideo_plugin.dylib + Resources/llplugin/plugins/libpacketizer_vc1_plugin.dylib + Resources/llplugin/plugins/libparam_eq_plugin.dylib + Resources/llplugin/plugins/libplaylist_plugin.dylib + Resources/llplugin/plugins/libpng_plugin.dylib + Resources/llplugin/plugins/libpodcast_plugin.dylib + Resources/llplugin/plugins/libposterize_plugin.dylib + Resources/llplugin/plugins/libpostproc_plugin.dylib + Resources/llplugin/plugins/libprefetch_plugin.dylib + Resources/llplugin/plugins/libps_plugin.dylib + Resources/llplugin/plugins/libpsychedelic_plugin.dylib + Resources/llplugin/plugins/libpuzzle_plugin.dylib + Resources/llplugin/plugins/libpva_plugin.dylib + Resources/llplugin/plugins/librawaud_plugin.dylib + Resources/llplugin/plugins/librawdv_plugin.dylib + Resources/llplugin/plugins/librawvid_plugin.dylib + Resources/llplugin/plugins/librawvideo_plugin.dylib + Resources/llplugin/plugins/libreal_plugin.dylib + Resources/llplugin/plugins/librecord_plugin.dylib + Resources/llplugin/plugins/libremap_plugin.dylib + Resources/llplugin/plugins/libremoteosd_plugin.dylib + Resources/llplugin/plugins/libripple_plugin.dylib + Resources/llplugin/plugins/librist_plugin.dylib + Resources/llplugin/plugins/librotate_plugin.dylib + Resources/llplugin/plugins/librss_plugin.dylib + Resources/llplugin/plugins/librtp_plugin.dylib + Resources/llplugin/plugins/librtpvideo_plugin.dylib + Resources/llplugin/plugins/librv32_plugin.dylib + Resources/llplugin/plugins/libsamplerate_plugin.dylib + Resources/llplugin/plugins/libsap_plugin.dylib + Resources/llplugin/plugins/libsatip_plugin.dylib + Resources/llplugin/plugins/libscale_plugin.dylib + Resources/llplugin/plugins/libscaletempo_pitch_plugin.dylib + Resources/llplugin/plugins/libscaletempo_plugin.dylib + Resources/llplugin/plugins/libscene_plugin.dylib + Resources/llplugin/plugins/libschroedinger_plugin.dylib + Resources/llplugin/plugins/libscreen_plugin.dylib + Resources/llplugin/plugins/libscte18_plugin.dylib + Resources/llplugin/plugins/libscte27_plugin.dylib + Resources/llplugin/plugins/libsdp_plugin.dylib + Resources/llplugin/plugins/libsecuretransport_plugin.dylib + Resources/llplugin/plugins/libsepia_plugin.dylib + Resources/llplugin/plugins/libsftp_plugin.dylib + Resources/llplugin/plugins/libsharpen_plugin.dylib + Resources/llplugin/plugins/libshm_plugin.dylib + Resources/llplugin/plugins/libsid_plugin.dylib + Resources/llplugin/plugins/libsimple_channel_mixer_plugin.dylib + Resources/llplugin/plugins/libskiptags_plugin.dylib + Resources/llplugin/plugins/libsmf_plugin.dylib + Resources/llplugin/plugins/libspatialaudio_plugin.dylib + Resources/llplugin/plugins/libspatializer_plugin.dylib + Resources/llplugin/plugins/libspdif_plugin.dylib + Resources/llplugin/plugins/libspeex_plugin.dylib + Resources/llplugin/plugins/libspeex_resampler_plugin.dylib + Resources/llplugin/plugins/libspudec_plugin.dylib + Resources/llplugin/plugins/libstats_plugin.dylib + Resources/llplugin/plugins/libstereo_widen_plugin.dylib + Resources/llplugin/plugins/libstl_plugin.dylib + Resources/llplugin/plugins/libstream_out_autodel_plugin.dylib + Resources/llplugin/plugins/libstream_out_bridge_plugin.dylib + Resources/llplugin/plugins/libstream_out_chromaprint_plugin.dylib + Resources/llplugin/plugins/libstream_out_chromecast_plugin.dylib + Resources/llplugin/plugins/libstream_out_cycle_plugin.dylib + Resources/llplugin/plugins/libstream_out_delay_plugin.dylib + Resources/llplugin/plugins/libstream_out_description_plugin.dylib + Resources/llplugin/plugins/libstream_out_display_plugin.dylib + Resources/llplugin/plugins/libstream_out_dummy_plugin.dylib + Resources/llplugin/plugins/libstream_out_duplicate_plugin.dylib + Resources/llplugin/plugins/libstream_out_es_plugin.dylib + Resources/llplugin/plugins/libstream_out_gather_plugin.dylib + Resources/llplugin/plugins/libstream_out_mosaic_bridge_plugin.dylib + Resources/llplugin/plugins/libstream_out_record_plugin.dylib + Resources/llplugin/plugins/libstream_out_rtp_plugin.dylib + Resources/llplugin/plugins/libstream_out_setid_plugin.dylib + Resources/llplugin/plugins/libstream_out_smem_plugin.dylib + Resources/llplugin/plugins/libstream_out_standard_plugin.dylib + Resources/llplugin/plugins/libstream_out_stats_plugin.dylib + Resources/llplugin/plugins/libstream_out_transcode_plugin.dylib + Resources/llplugin/plugins/libsubsdec_plugin.dylib + Resources/llplugin/plugins/libsubsdelay_plugin.dylib + Resources/llplugin/plugins/libsubstx3g_plugin.dylib + Resources/llplugin/plugins/libsubsusf_plugin.dylib + Resources/llplugin/plugins/libsubtitle_plugin.dylib + Resources/llplugin/plugins/libsvcdsub_plugin.dylib + Resources/llplugin/plugins/libswscale_plugin.dylib + Resources/llplugin/plugins/libsyslog_plugin.dylib + Resources/llplugin/plugins/libt140_plugin.dylib + Resources/llplugin/plugins/libtaglib_plugin.dylib + Resources/llplugin/plugins/libtcp_plugin.dylib + Resources/llplugin/plugins/libtdummy_plugin.dylib + Resources/llplugin/plugins/libtelx_plugin.dylib + Resources/llplugin/plugins/libtextst_plugin.dylib + Resources/llplugin/plugins/libtheora_plugin.dylib + Resources/llplugin/plugins/libtimecode_plugin.dylib + Resources/llplugin/plugins/libtospdif_plugin.dylib + Resources/llplugin/plugins/libtransform_plugin.dylib + Resources/llplugin/plugins/libtrivial_channel_mixer_plugin.dylib + Resources/llplugin/plugins/libts_plugin.dylib + Resources/llplugin/plugins/libtta_plugin.dylib + Resources/llplugin/plugins/libttml_plugin.dylib + Resources/llplugin/plugins/libtwolame_plugin.dylib + Resources/llplugin/plugins/libty_plugin.dylib + Resources/llplugin/plugins/libudp_plugin.dylib + Resources/llplugin/plugins/libugly_resampler_plugin.dylib + Resources/llplugin/plugins/libuleaddvaudio_plugin.dylib + Resources/llplugin/plugins/libupnp_plugin.dylib + Resources/llplugin/plugins/libvc1_plugin.dylib + Resources/llplugin/plugins/libvcd_plugin.dylib + Resources/llplugin/plugins/libvdr_plugin.dylib + Resources/llplugin/plugins/libvdummy_plugin.dylib + Resources/llplugin/plugins/libvhs_plugin.dylib + Resources/llplugin/plugins/libvideotoolbox_plugin.dylib + Resources/llplugin/plugins/libvisual_plugin.dylib + Resources/llplugin/plugins/libvlc.5.dylib + Resources/llplugin/plugins/libvlccore.9.dylib + Resources/llplugin/plugins/libvmem_plugin.dylib + Resources/llplugin/plugins/libvobsub_plugin.dylib + Resources/llplugin/plugins/libvoc_plugin.dylib + Resources/llplugin/plugins/libvod_rtsp_plugin.dylib + Resources/llplugin/plugins/libvorbis_plugin.dylib + Resources/llplugin/plugins/libvout_macosx_plugin.dylib + Resources/llplugin/plugins/libvpx_plugin.dylib + Resources/llplugin/plugins/libwall_plugin.dylib + Resources/llplugin/plugins/libwav_plugin.dylib + Resources/llplugin/plugins/libwave_plugin.dylib + Resources/llplugin/plugins/libwebvtt_plugin.dylib + Resources/llplugin/plugins/libx26410b_plugin.dylib + Resources/llplugin/plugins/libx264_plugin.dylib + Resources/llplugin/plugins/libx265_plugin.dylib + Resources/llplugin/plugins/libxa_plugin.dylib + Resources/llplugin/plugins/libxml_plugin.dylib + Resources/llplugin/plugins/libyuv_plugin.dylib + Resources/llplugin/plugins/libyuvp_plugin.dylib + Resources/llplugin/plugins/libyuy2_i420_plugin.dylib + Resources/llplugin/plugins/libyuy2_i422_plugin.dylib + Resources/llplugin/plugins/libzvbi_plugin.dylib + Resources/SLPlugin.app/Contents/Frameworks/DullahanHelper.app + Resources/SLPlugin.app/Contents/Frameworks/DullahanHelper\ \(GPU\).app/Contents/MacOS/DullahanHelper\ \(GPU\) + Resources/SLPlugin.app/Contents/Frameworks/DullahanHelper\ \(Plugin\).app/Contents/MacOS/DullahanHelper\ \(Plugin\) + WORKING_DIRECTORY ${CMAKE_CACHEFILE_DIR}/_CPack_Packages/${CMAKE_SYSTEM_NAME}/Bundle/${CPACK_BUNDLE_NAME}-${CPACK_PACKAGE_VERSION}-${CMAKE_SYSTEM_NAME}/${CPACK_BUNDLE_NAME}.app/Contents + ) +execute_process( + COMMAND sudo codesign -f -s ${SIGNING_IDENTITY} --timestamp -o runtime --runtime-version ${CMAKE_OSX_DEPLOYMENT_TARGET} + --entitlements ${CMAKE_SOURCE_DIR}/newview/slplugin.entitlements + DullahanHelper\ \(Renderer\).app/Contents/MacOS/DullahanHelper\ \(Renderer\) + COMMAND sudo codesign -f -s ${SIGNING_IDENTITY} --timestamp -o runtime --runtime-version ${CMAKE_OSX_DEPLOYMENT_TARGET} + --deep + DullahanHelper\ \(GPU\).app + DullahanHelper\ \(Plugin\).app + WORKING_DIRECTORY ${CMAKE_CACHEFILE_DIR}/_CPack_Packages/${CMAKE_SYSTEM_NAME}/Bundle/${CPACK_BUNDLE_NAME}-${CPACK_PACKAGE_VERSION}-${CMAKE_SYSTEM_NAME}/${CPACK_BUNDLE_NAME}.app/Contents/Resources/SLPlugin.app/Contents/Frameworks + ) +execute_process( + COMMAND sudo codesign -f -s ${SIGNING_IDENTITY} --timestamp -o runtime --runtime-version ${CMAKE_OSX_DEPLOYMENT_TARGET} + --entitlements ${CMAKE_SOURCE_DIR}/newview/slplugin.entitlements + --deep + DullahanHelper\ \(Renderer\).app + WORKING_DIRECTORY ${CMAKE_CACHEFILE_DIR}/_CPack_Packages/${CMAKE_SYSTEM_NAME}/Bundle/${CPACK_BUNDLE_NAME}-${CPACK_PACKAGE_VERSION}-${CMAKE_SYSTEM_NAME}/${CPACK_BUNDLE_NAME}.app/Contents/Resources/SLPlugin.app/Contents/Frameworks + ) +execute_process( + COMMAND sudo codesign -f -s ${SIGNING_IDENTITY} --timestamp -o runtime --runtime-version ${CMAKE_OSX_DEPLOYMENT_TARGET} + --entitlements ${CMAKE_SOURCE_DIR}/newview/slplugin.entitlements + SLPlugin.app + WORKING_DIRECTORY ${CMAKE_CACHEFILE_DIR}/_CPack_Packages/${CMAKE_SYSTEM_NAME}/Bundle/${CPACK_BUNDLE_NAME}-${CPACK_PACKAGE_VERSION}-${CMAKE_SYSTEM_NAME}/${CPACK_BUNDLE_NAME}.app/Contents/Resources + ) +execute_process( + COMMAND sudo codesign -f -s ${SIGNING_IDENTITY} --timestamp -o runtime --runtime-version ${CMAKE_OSX_DEPLOYMENT_TARGET} + --entitlements ${CMAKE_SOURCE_DIR}/newview/slplugin.entitlements + -i net.${VIEWER_BINARY_NAME}.viewer + ${CPACK_BUNDLE_NAME}.app + WORKING_DIRECTORY ${CMAKE_CACHEFILE_DIR}/_CPack_Packages/${CMAKE_SYSTEM_NAME}/Bundle/${CPACK_BUNDLE_NAME}-${CPACK_PACKAGE_VERSION}-${CMAKE_SYSTEM_NAME} + ) diff --git a/indra/newview/Info-SecondLife.plist b/indra/newview/Info-SecondLife.plist index 09b0e1ec1b..82f63519db 100644 --- a/indra/newview/Info-SecondLife.plist +++ b/indra/newview/Info-SecondLife.plist @@ -11,7 +11,7 @@ <key>CFBundleIconFile</key> <string>${MACOSX_BUNDLE_ICON_FILE}</string> <key>CFBundleIdentifier</key> - <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string> + <string>${MACOSX_BUNDLE_GUI_IDENTIFIER}</string> <key>CFBundleInfoDictionaryVersion</key> <string>6.0</string> <key>CFBundleLongVersionString</key> @@ -34,6 +34,10 @@ <string>${MACOSX_BUNDLE_COPYRIGHT}</string> <key>NSMicrophoneUsageDescription</key> <string>For voice chat, you must grant permission for Second Life to use the microphone.</string> + <key>LSApplicationCategoryType</key> + <string>public.app-category.games</string> + <key>NSHighResolutionCapable</key> + <true/> <key>CFBundleDocumentTypes</key> <array> <dict> diff --git a/indra/newview/PKGBUILD.in b/indra/newview/PKGBUILD.in new file mode 100644 index 0000000000..4d617c132c --- /dev/null +++ b/indra/newview/PKGBUILD.in @@ -0,0 +1,14 @@ +# Maintainer: $ENV{USER}@${VIEWER_PACKAGE_DOMAIN_NAME} +pkgname=${VIEWER_BINARY_NAME} +pkgver=${VIEWER_VERSION_MAJOR}.${VIEWER_VERSION_MINOR}.${VIEWER_VERSION_PATCH} +pkgrel=${VIEWER_VERSION_REVISION} +pkgdesc="${VIEWER_PACKAGE_COMMENT}" +arch=('${CMAKE_SYSTEM_PROCESSOR}') +url="https://${VIEWER_PACKAGE_DOMAIN_NAME}" +license=('LGPL-2.1') +depends=(apr-util boost-libs fltk glu hunspell libnghttp2 sdl2 vlc libvorbis) + +package() { + cd "$startdir" + make DESTDIR="$pkgdir/" install +} diff --git a/indra/newview/SecondLife.nib b/indra/newview/SecondLife.nib Binary files differindex c4ddca50dc..ef0fa80b12 100644 --- a/indra/newview/SecondLife.nib +++ b/indra/newview/SecondLife.nib diff --git a/indra/newview/SecondLife.xib b/indra/newview/SecondLife.xib index fbff8fe307..8302392f5d 100644 --- a/indra/newview/SecondLife.xib +++ b/indra/newview/SecondLife.xib @@ -42,7 +42,7 @@ <array class="NSMutableArray" key="NSMenuItems"> <object class="NSMenuItem" id="694149608"> <reference key="NSMenu" ref="649796088"/> - <string key="NSTitle">Second Life</string> + <string key="NSTitle">Megapahit</string> <string key="NSKeyEquiv"/> <int key="NSMnemonicLoc">2147483647</int> <object class="NSCustomResource" key="NSOnImage" id="353210768"> @@ -55,11 +55,11 @@ </object> <string key="NSAction">submenuAction:</string> <object class="NSMenu" key="NSSubmenu" id="110575045"> - <string key="NSTitle">Second Life</string> + <string key="NSTitle">Megapahit</string> <array class="NSMutableArray" key="NSMenuItems"> <object class="NSMenuItem" id="238522557"> <reference key="NSMenu" ref="110575045"/> - <string key="NSTitle">About Second Life</string> + <string key="NSTitle">About Megapahit</string> <string key="NSKeyEquiv"/> <int key="NSMnemonicLoc">2147483647</int> <reference key="NSOnImage" ref="353210768"/> @@ -120,7 +120,7 @@ </object> <object class="NSMenuItem" id="755159360"> <reference key="NSMenu" ref="110575045"/> - <string key="NSTitle">Hide Second Life</string> + <string key="NSTitle">Hide Megapahit</string> <string key="NSKeyEquiv">h</string> <int key="NSKeyEquivModMask">1048576</int> <int key="NSMnemonicLoc">2147483647</int> @@ -156,7 +156,7 @@ </object> <object class="NSMenuItem" id="632727374"> <reference key="NSMenu" ref="110575045"/> - <string key="NSTitle">Quit Second Life</string> + <string key="NSTitle">Quit Megapahit</string> <string key="NSKeyEquiv">q</string> <int key="NSKeyEquivModMask">1048576</int> <int key="NSMnemonicLoc">2147483647</int> @@ -323,7 +323,7 @@ <int key="NSWindowBacking">2</int> <string key="NSWindowRect">{{196, 240}, {1024, 600}}</string> <int key="NSWTFlags">74974208</int> - <string key="NSWindowTitle">Second Life</string> + <string key="NSWindowTitle">Megapahit</string> <string key="NSWindowClass">LLNSWindow</string> <nil key="NSViewClass"/> <nil key="NSUserInterfaceItemIdentifier"/> @@ -338,7 +338,7 @@ </object> <string key="NSScreenRect">{{0, 0}, {2560, 1418}}</string> <string key="NSMaxSize">{10000000000000, 10000000000000}</string> - <string key="NSFrameAutosaveName">Second Life</string> + <string key="NSFrameAutosaveName">Megapahit</string> <int key="NSWindowCollectionBehavior">128</int> <bool key="NSWindowIsRestorable">NO</bool> </object> diff --git a/indra/newview/VIEWER_VERSION.txt b/indra/newview/VIEWER_VERSION.txt index e0eaaa0bbc..991d8e5c5f 100644 --- a/indra/newview/VIEWER_VERSION.txt +++ b/indra/newview/VIEWER_VERSION.txt @@ -1 +1 @@ -7.1.11 +7.1.13 diff --git a/indra/newview/ViewerInstall.cmake b/indra/newview/ViewerInstall.cmake index ac2247c815..4716cdde36 100644 --- a/indra/newview/ViewerInstall.cmake +++ b/indra/newview/ViewerInstall.cmake @@ -1,28 +1,169 @@ +if (DARWIN) + + install(FILES + ${CMAKE_CURRENT_BINARY_DIR}/InfoPlist.strings + ${CMAKE_CURRENT_SOURCE_DIR}/English.lproj/language.txt + DESTINATION English.lproj + ) + + install(DIRECTORY + German.lproj + Japanese.lproj + Korean.lproj + app_settings + character + cursors_mac + da.lproj + es.lproj + fonts + fr.lproj + uk.lproj + hu.lproj + it.lproj + nl.lproj + pl.lproj + pt.lproj + ru.lproj + skins + tr.lproj + zh-Hans.lproj + DESTINATION . + ) + + install(FILES + SecondLife.nib + ${AUTOBUILD_INSTALL_DIR}/ca-bundle.crt + cube.dae + featuretable_mac.txt + DESTINATION . + ) + + if (NOT PACKAGE) + install(FILES + secondlife.icns + RENAME ${VIEWER_CHANNEL}.icns + DESTINATION . + ) + endif (NOT PACKAGE) + + install(FILES + licenses-mac.txt + RENAME licenses.txt + DESTINATION . + ) + + install(FILES + ${SCRIPTS_DIR}/messages/message_template.msg + ${SCRIPTS_DIR}/../etc/message.xml + ${CMAKE_CURRENT_BINARY_DIR}/contributors.txt + DESTINATION app_settings + ) + + install(DIRECTORY + ${AUTOBUILD_INSTALL_DIR}/dictionaries + DESTINATION app_settings + ) + + if (NDOF) + install(FILES + "${AUTOBUILD_INSTALL_DIR}/lib/release/libndofdev.dylib" + DESTINATION . + ) + endif () + + if (PACKAGE) + configure_file( + ${CMAKE_CURRENT_SOURCE_DIR}/FixPackage.cmake.in + ${CMAKE_CURRENT_BINARY_DIR}/FixBundle.cmake + ) + else (PACKAGE) + configure_file( + ${CMAKE_CURRENT_SOURCE_DIR}/FixBundle.cmake.in + ${CMAKE_CURRENT_BINARY_DIR}/FixBundle.cmake + ) + endif (PACKAGE) + install(SCRIPT ${CMAKE_CURRENT_BINARY_DIR}/FixBundle.cmake) + +else (DARWIN) + install(PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/${VIEWER_BINARY_NAME} - DESTINATION ${APP_BINARY_DIR} + DESTINATION bin ) -install(DIRECTORY skins app_settings linux_tools - DESTINATION ${APP_SHARE_DIR} +if (${LINUX_DISTRO} MATCHES arch) + install(PROGRAMS linux_tools/launch_url.sh + DESTINATION lib/${VIEWER_BINARY_NAME} + ) +else (${LINUX_DISTRO} MATCHES arch) + install(PROGRAMS linux_tools/launch_url.sh + DESTINATION libexec/${VIEWER_BINARY_NAME} + ) +endif (${LINUX_DISTRO} MATCHES arch) + +if (LINUX) + if (${LINUX_DISTRO} MATCHES debian OR (${LINUX_DISTRO} MATCHES ubuntu)) + set(_LIB lib/${ARCH}-linux-gnu) + elseif (${LINUX_DISTRO} MATCHES fedora OR (${LINUX_DISTRO} MATCHES opensuse-tumbleweed) OR (${LINUX_DISTRO} MATCHES gentoo)) + set(_LIB lib${ADDRESS_SIZE}) + else () + set(_LIB lib) + endif () + if (USE_FMODSTUDIO) + install(FILES + ${AUTOBUILD_INSTALL_DIR}/lib/release/libfmod.so + ${AUTOBUILD_INSTALL_DIR}/lib/release/libfmod.so.13 + ${AUTOBUILD_INSTALL_DIR}/lib/release/libfmod.so.13.28 + DESTINATION ${_LIB}) + endif (USE_FMODSTUDIO) +endif (LINUX) + +install(DIRECTORY skins app_settings fonts + DESTINATION share/${VIEWER_BINARY_NAME} PATTERN ".svn" EXCLUDE ) +install(DIRECTORY icons/hicolor + DESTINATION share/icons + ) + find_file(IS_ARTWORK_PRESENT NAMES have_artwork_bundle.marker PATHS ${VIEWER_DIR}/newview/res) if (IS_ARTWORK_PRESENT) install(DIRECTORY res res-sdl character - DESTINATION ${APP_SHARE_DIR} + DESTINATION share/${VIEWER_BINARY_NAME} PATTERN ".svn" EXCLUDE ) else (IS_ARTWORK_PRESENT) message(STATUS "WARNING: Artwork is not present, and will not be installed") endif (IS_ARTWORK_PRESENT) -install(FILES featuretable_linux.txt featuretable_solaris.txt - DESTINATION ${APP_SHARE_DIR} + install(FILES + ${AUTOBUILD_INSTALL_DIR}/ca-bundle.crt + featuretable_linux.txt + #featuretable_solaris.txt + DESTINATION share/${VIEWER_BINARY_NAME} + ) + + install(FILES + licenses-linux.txt + RENAME licenses.txt + DESTINATION share/${VIEWER_BINARY_NAME} ) install(FILES ${SCRIPTS_DIR}/messages/message_template.msg - DESTINATION ${APP_SHARE_DIR}/app_settings + ${SCRIPTS_DIR}/../etc/message.xml + ${CMAKE_CURRENT_BINARY_DIR}/contributors.txt + DESTINATION share/${VIEWER_BINARY_NAME}/app_settings + ) + + install(DIRECTORY + ${AUTOBUILD_INSTALL_DIR}/dictionaries + DESTINATION share/${VIEWER_BINARY_NAME}/app_settings ) + + install(FILES linux_tools/${VIEWER_BINARY_NAME}.desktop + DESTINATION share/applications + ) + +endif (DARWIN) diff --git a/indra/newview/app_settings/camera/Rear.xml b/indra/newview/app_settings/camera/Rear.xml index 7eda566e48..db02001b9c 100644 --- a/indra/newview/app_settings/camera/Rear.xml +++ b/indra/newview/app_settings/camera/Rear.xml @@ -53,8 +53,8 @@ <key>Value</key> <array> <real>-3</real> - <real>0</real> - <real>0.75</real> + <real>0.5</real> + <real>0.2</real> </array> </map> <key>CameraOffsetScale</key> @@ -89,9 +89,9 @@ <string>Vector3D</string> <key>Value</key> <array> - <real>1.0</real> - <real>0.0</real> - <real>1.0</real> + <real>0.9</real> + <real>0.5</real> + <real>0.2</real> </array> </map> <key>PresetCameraActive</key> diff --git a/indra/newview/app_settings/commands.xml b/indra/newview/app_settings/commands.xml index 4a3dfffde1..635e5e40f5 100644 --- a/indra/newview/app_settings/commands.xml +++ b/indra/newview/app_settings/commands.xml @@ -46,7 +46,7 @@ available_in_toybox="true" is_flashing_allowed="true" icon="Command_Chat_Icon" - label_ref="Command_Chat_Label" + label_ref="Command_Conversations_Label" tooltip_ref="Command_Conversations_Tooltip" execute_function="Floater.ToggleOrBringToFront" execute_parameters="im_container" @@ -295,4 +295,19 @@ is_running_function="Floater.IsOpen" is_running_parameters="performance" /> + <command name="favoritefolder" + available_in_toybox="true" + icon="Command_FavoriteFolder_Icon" + label_ref="Command_FavoriteFolder_Label" + tooltip_ref="Command_FavoriteFolder_Tooltip" + execute_function="Inventory.OpenFavoriteFolder" + is_running_function="Inventory.IsFavoriteFolderOpen" + /> + <command name="resync_animations" + available_in_toybox="true" + icon="Command_Resync_Animations" + label_ref="Command_ResyncAnimations_Label" + tooltip_ref="Command_ResyncAnimations_Tooltip" + execute_function="Tools.ResyncAnimations" + /> </commands> diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 07298fa921..f8487c020e 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -46,6 +46,17 @@ <key>Value</key> <integer>1</integer> </map> + <key>IMNearbySessionFirst</key> + <map> + <key>Comment</key> + <string>Put nearby session always first(last).</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>0</integer> + </map> <key>IMShowTime</key> <map> <key>Comment</key> @@ -68,6 +79,17 @@ <key>Value</key> <integer>1</integer> </map> + <key>IMShowArrivalsDepartures</key> + <map> + <key>Comment</key> + <string>Enable(disable) showing of arrivals and departures in the chat.</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>0</integer> + </map> <key>CrashHostUrl</key> <map> <key>Comment</key> @@ -1264,8 +1286,8 @@ <key>Value</key> <array> <real>-3.0</real> - <real>0.0</real> - <real>0.75</real> + <real>0.5</real> + <real>0.2</real> </array> </map> <key>CameraOffsetScale</key> @@ -2524,7 +2546,7 @@ <key>Value</key> <integer>0</integer> </map> - <key>DoubleClickTeleport</key> + <key>DoubleClickTeleport</key> <map> <key>Comment</key> <string>Enable double-click to teleport where allowed (afects minimap and people panel)</string> @@ -2546,6 +2568,17 @@ <key>Value</key> <integer>1</integer> </map> + <key>DoubleClickZoomIn</key> + <map> + <key>Comment</key> + <string>Set double-click to zoom in on instead of IM avatar</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>0</integer> + </map> <key>DynamicCameraStrength</key> <map> <key>Comment</key> @@ -3112,9 +3145,9 @@ <string>Vector3D</string> <key>Value</key> <array> - <real>1.0</real> - <real>0.0</real> - <real>1.0</real> + <real>0.9</real> + <real>0.5</real> + <real>0.2</real> </array> </map> <key>AvatarSitRotation</key> @@ -3676,6 +3709,17 @@ <key>Value</key> <integer>5000</integer> </map> + <key>InventoryExposeFolderID</key> + <map> + <key>Comment</key> + <string>Allows copying folder id from context menu</string> + <key>Persist</key> + <integer>0</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>0</integer> + </map> <key>MarketplaceListingsSortOrder</key> <map> <key>Comment</key> @@ -4976,6 +5020,17 @@ <key>Value</key> <integer>0</integer> </map> + <key>MediaPluginPipeWireVolumeCatcher</key> + <map> + <key>Comment</key> + <string>Use PipeWire instead of PulseAudio for controlling web media volume.</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>0</integer> + </map> <key>MediaControlFadeTime</key> <map> <key>Comment</key> @@ -6097,6 +6152,28 @@ <key>Value</key> <integer>1</integer> </map> + <key>StreamNotificationChannel</key> + <map> + <key>Comment</key> + <string>Custom stream notification channel</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>S32</string> + <key>Value</key> + <integer>751751</integer> + </map> + <key>StreamNotificationChannelEnabled</key> + <map> + <key>Comment</key> + <string>Use the stream notification channel?</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>0</integer> + </map> <key>ParticipantListShowIcons</key> <map> <key>Comment</key> @@ -7794,6 +7871,17 @@ <key>Value</key> <integer>0</integer> </map> + <key>RenderTextureVRAMDivisor</key> + <map> + <key>Comment</key> + <string>Divisor for maximum amount of VRAM the viewer will use for textures. 1 = all the VRAM. Used in conjunction with RenderMaxVRAMBudget.</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>U32</string> + <key>Value</key> + <integer>1</integer> + </map> <key>RenderMinFreeMainMemoryThreshold</key> <map> <key>Comment</key> @@ -8376,7 +8464,7 @@ <key>Type</key> <string>F32</string> <key>Value</key> - <real>0.8</real> + <real>0.7</real> </map> <key>RenderShadowGaussian</key> @@ -8831,7 +8919,7 @@ <key>Type</key> <string>Boolean</string> <key>Value</key> - <integer>0</integer> + <integer>1</integer> </map> <key>NameTagShowUsernames</key> <map> @@ -9020,7 +9108,7 @@ <key>Value</key> <integer>1</integer> </map> - + <key>RenderReflectionDetail</key> <map> <key>Comment</key> @@ -9065,6 +9153,28 @@ <key>Value</key> <integer>1</integer> </map> + <key>RenderReflectionProbeDynamicAllocation</key> + <map> + <key>Comment</key> + <string>Enable dynamic allocation of reflection probes. -1 means no dynamic allocation. Sets a buffer to allocate when a dynamic allocation occurs otherwise.</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>S32</string> + <key>Value</key> + <integer>-1</integer> + </map> + <key>RenderReflectionProbeCount</key> + <map> + <key>Comment</key> + <string>Number of probes to render. Maximum of 256. Clamps to the nearest power of 2.</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>U32</string> + <key>Value</key> + <integer>256</integer> + </map> <key>RenderReflectionProbeResolution</key> <map> <key>Comment</key> @@ -9087,7 +9197,7 @@ <key>Value</key> <real>1.0</real> </map> - + <key>RenderReflectionProbeDrawDistance</key> <map> <key>Comment</key> @@ -9286,7 +9396,7 @@ <key>Value</key> <real>1.0</real> </map> - + <key>RenderReflectionProbeMaxLocalLightAmbiance</key> <map> <key>Comment</key> @@ -9951,7 +10061,7 @@ <key>Type</key> <string>String</string> <key>Value</key> - <string>https://feedback.secondlife.com/</string> + <string>https://megapahit.com/enter_bug.cgi?product=Viewer</string> </map> <key>RevokePermsOnStopAnimation</key> <map> @@ -10501,7 +10611,7 @@ <key>Type</key> <string>Boolean</string> <key>Value</key> - <integer>0</integer> + <integer>1</integer> </map> <key>NavBarShowParcelProperties</key> <map> @@ -10788,7 +10898,7 @@ <string>Boolean</string> <key>Value</key> <integer>0</integer> - </map> + </map> <key>NearbyListShowMap</key> <map> <key>Comment</key> @@ -11618,7 +11728,7 @@ <key>Type</key> <string>F32</string> <key>Value</key> - <real>0.04</real> + <real>0.0095</real> </map> <key>TextureScaleMaxAreaFactor</key> <map> @@ -12717,7 +12827,7 @@ <key>UpdaterWillingToTest</key> <map> <key>Comment</key> - <string>Whether or not the updater should offer test candidate upgrades.</string> + <string>Whether or not the updater should offer Beta upgrades.</string> <key>Persist</key> <integer>1</integer> <key>Type</key> @@ -13764,13 +13874,24 @@ <key>MaxFPS</key> <map> <key>Comment</key> - <string>OBSOLETE UNUSED setting.</string> + <string>FPS Limiter.</string> <key>Persist</key> <integer>1</integer> <key>Type</key> - <string>F32</string> + <string>U32</string> <key>Value</key> - <real>-1.0</real> + <real>0</real> + </map> + <key>MaxFPS</key> + <map> + <key>Comment</key> + <string>FPS Limiter.</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>U32</string> + <key>Value</key> + <real>0</real> </map> <key>ZoomDirect</key> <map> @@ -14031,6 +14152,345 @@ <real>12</real> </map> + + <!-- megapahit settings --> + <key>MPVBufferOptiMode</key> + <map> + <key>Comment</key> + <string> + OpenGL buffer mapping mode: + 0:auto + 1:normal + 2:MP optimised + 3:LL optimized.</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>U32</string> + <key>Value</key> + <integer>0</integer> + </map> + <key>MPRenderShadowOpti</key> + <map> + <key>Comment</key> + <string>Shadows Optimisations</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>S32</string> + <key>Value</key> + <integer>0</integer> + </map> + <key>MPVCameraCollapsed</key> + <map> + <key>Comment</key> + <string> + Camera floater collapsed</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>0</integer> + </map> + <key>MPVNearMeRange</key> + <map> + <key>Comment</key> + <string>Search radius in the people panel</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>F32</string> + <key>Value</key> + <integer>4096</integer> + </map> + <key>RenderVSyncEnabled</key> + <map> + <key>Comment</key> + <string>VSync</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>0</integer> + </map> + <key>MemProfiling</key> + <map> + <key>Comment</key> + <string>VSync</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>0</integer> + </map> + <key>FSLastSearchTab</key> + <map> + <key>Comment</key> + <string>Last selected tab in search window</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>S32</string> + <key>Value</key> + <integer>0</integer> + </map> + <key>FSLegacySearchActionOnTeleport</key> + <map> + <key>Comment</key> + <string>Controls what action Legacy Search should take when teleporting: 0 = No effect, + 1 = Close floater, 2 Minimise floater</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>U32</string> + <key>Value</key> + <integer>1</integer> + </map> + <key>ShowPGGroups</key> + <map> + <key>Comment</key> + <string>Controls what action Legacy Search should take when teleporting: 0 = No effect, + 1 = Close floater, 2 Minimise floater</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>U32</string> + <key>Value</key> + <integer>1</integer> + </map> + <key>ShowPGGroups</key> + <map> + <key>Comment</key> + <string>Display results of find groups that are flagged as general</string> + <key>Persist</key> + <integer>1</integer> + <key>HideFromEditor</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>1</integer> + </map> + <key>ShowMatureGroups</key> + <map> + <key>Comment</key> + <string>Display results of find groups that are flagged as moderate</string> + <key>Persist</key> + <integer>1</integer> + <key>HideFromEditor</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>1</integer> + </map> + <key>ShowAdultGroups</key> + <map> + <key>Comment</key> + <string>Display results of find groups that are flagged as adult</string> + <key>Persist</key> + <integer>1</integer> + <key>HideFromEditor</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>0</integer> + </map> + <key>ShowPGClassifieds</key> + <map> + <key>Comment</key> + <string>Display results of find classifieds that are flagged as general</string> + <key>Persist</key> + <integer>1</integer> + <key>HideFromEditor</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>1</integer> + </map> + <key>ShowMatureClassifieds</key> + <map> + <key>Comment</key> + <string>Display results of find classifieds that are flagged as moderate</string> + <key>Persist</key> + <integer>1</integer> + <key>HideFromEditor</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>1</integer> + </map> + <key>ShowAdultClassifieds</key> + <map> + <key>Comment</key> + <string>Display results of find classifieds that are flagged as adult</string> + <key>Persist</key> + <integer>1</integer> + <key>HideFromEditor</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>0</integer> + </map> + <key>ShowPGEvents</key> + <map> + <key>Comment</key> + <string>Display results of find events that are flagged as general</string> + <key>Persist</key> + <integer>1</integer> + <key>HideFromEditor</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>1</integer> + </map> + <key>ShowMatureEvents</key> + <map> + <key>Comment</key> + <string>Display results of find events that are flagged as moderate</string> + <key>Persist</key> + <integer>1</integer> + <key>HideFromEditor</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>1</integer> + </map> + <key>ShowAdultEvents</key> + <map> + <key>Comment</key> + <string>Display results of find events that are flagged as adult</string> + <key>Persist</key> + <integer>1</integer> + <key>HideFromEditor</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>0</integer> + </map> + <key>ShowPGLand</key> + <map> + <key>Comment</key> + <string>Display results of find land sales that are flagged as general</string> + <key>Persist</key> + <integer>1</integer> + <key>HideFromEditor</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>1</integer> + </map> + <key>ShowMatureLand</key> + <map> + <key>Comment</key> + <string>Display results of find land sales that are flagged as moderate</string> + <key>Persist</key> + <integer>1</integer> + <key>HideFromEditor</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>1</integer> + </map> + <key>ShowAdultLand</key> + <map> + <key>Comment</key> + <string>Display results of find land sales that are flagged as adult</string> + <key>Persist</key> + <integer>1</integer> + <key>HideFromEditor</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>0</integer> + </map> + <key>ShowPGSims</key> + <map> + <key>Comment</key> + <string>Display results of find places or find popular that are in general sims</string> + <key>Persist</key> + <integer>1</integer> + <key>HideFromEditor</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>1</integer> + </map> + <key>ShowMatureSims</key> + <map> + <key>Comment</key> + <string>Display results of find places or find popular that are in moderate sims</string> + <key>Persist</key> + <integer>1</integer> + <key>HideFromEditor</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>1</integer> + </map> + <key>ShowAdultSims</key> + <map> + <key>Comment</key> + <string>Display results of find places or find popular that are in adult sims</string> + <key>Persist</key> + <integer>1</integer> + <key>HideFromEditor</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>0</integer> + </map> + <key>FindLandArea</key> + <map> + <key>Comment</key> + <string>Enables filtering of land search results by area</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>0</integer> + </map> + <key>FindLandPrice</key> + <map> + <key>Comment</key> + <string>Enables filtering of land search results by price</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>1</integer> + </map> + <key>FindLandType</key> + <map> + <key>Comment</key> + <string>Controls which type of land you are searching for in Find Land interface ("All", + "Auction", "For Sale")</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>String</string> + <key>Value</key> + <string>All</string> + </map> + <!-- Settings below are for back compatibility only. They are not used in current viewer anymore. But they can't be removed to avoid influence on previous versions of the viewer in case of settings are not used or default value @@ -15935,7 +16395,7 @@ <key>Type</key> <string>Boolean</string> <key>Value</key> - <integer>1</integer> + <integer>1</integer> </map> <key>UpdateAppWindowTitleBar</key> <map> diff --git a/indra/newview/app_settings/settings_per_account.xml b/indra/newview/app_settings/settings_per_account.xml index 6b788dd78f..80a4bec57f 100644 --- a/indra/newview/app_settings/settings_per_account.xml +++ b/indra/newview/app_settings/settings_per_account.xml @@ -458,5 +458,16 @@ <key>Value</key> <integer>2</integer> </map> + <key>FavoriteFolder</key> + <map> + <key>Comment</key> + <string>Favorite inventory folder (UUID)</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>String</string> + <key>Value</key> + <string></string> + </map> </map> </llsd> diff --git a/indra/newview/app_settings/shaders/class1/deferred/aoUtil.glsl b/indra/newview/app_settings/shaders/class1/deferred/aoUtil.glsl index ce018623a8..1a065daf89 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/aoUtil.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/aoUtil.glsl @@ -78,10 +78,10 @@ float calcAmbientOcclusion(vec4 pos, vec3 norm, vec2 pos_screen) { float ret = 1.0; vec3 pos_world = pos.xyz; - vec2 noise_reflect = texture(noiseMap, pos_screen.xy * (screen_res / 128)).xy; + vec2 noise_reflect = texture(noiseMap, pos_screen.xy * (screen_res / 128.0)).xy; float angle_hidden = 0.0; - float points = 0; + float points = 0.0; float scale = min(ssao_radius / -pos_world.z, ssao_max_radius); diff --git a/indra/newview/app_settings/shaders/class1/deferred/deferredUtil.glsl b/indra/newview/app_settings/shaders/class1/deferred/deferredUtil.glsl index 94711be473..63ab0b9b38 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/deferredUtil.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/deferredUtil.glsl @@ -80,6 +80,18 @@ vec3 atmosFragLightingLinear(vec3 light, vec3 additive, vec3 atten); vec4 decodeNormal(vec4 norm); +vec3 clampHDRRange(vec3 color) +{ + // Why do this? + // There are situations where the color range will go to something insane - potentially producing infs and NaNs even. + // This is a safety measure to prevent that. + // As to the specific number there - allegedly some HDR displays expect values to be in the 0-11.2 range. Citation needed. + // -Geenz 2025-03-05 + color = mix(color, vec3(1), isinf(color)); + color = mix(color, vec3(0.0), isnan(color)); + return clamp(color, vec3(0.0), vec3(11.2)); +} + float calcLegacyDistanceAttenuation(float distance, float falloff) { float dist_atten = 1.0 - clamp((distance + falloff)/(1.0 + falloff), 0.0, 1.0); @@ -253,7 +265,7 @@ vec4 texture2DLodSpecular(vec2 tc, float lod) vec2 dist = vec2(0.5) - abs(tc-vec2(0.5)); float det = min(lod/(proj_lod*0.5), 1.0); float d = min(dist.x, dist.y); - d *= min(1, d * (proj_lod - lod)); // BUG? extra factor compared to diffuse causes N repeats + d *= min(1.0, d * (proj_lod - lod)); // BUG? extra factor compared to diffuse causes N repeats float edge = 0.25*det; ret *= clamp(d/edge, 0.0, 1.0); @@ -371,7 +383,7 @@ void pbrIbl(vec3 diffuseColor, out vec3 specularOut) { // retrieve a scale and bias to F0. See [1], Figure 3 - vec2 brdf = BRDF(clamp(nv, 0, 1), 1.0-perceptualRough); + vec2 brdf = BRDF(clamp(nv, 0.0, 1.0), 1.0-perceptualRough); vec3 diffuseLight = irradiance; vec3 specularLight = radiance; @@ -426,9 +438,10 @@ float geometricOcclusion(PBRInfo pbrInputs) float NdotL = pbrInputs.NdotL; float NdotV = pbrInputs.NdotV; float r = pbrInputs.alphaRoughness; + float r2 = r * r; - float attenuationL = 2.0 * NdotL / (NdotL + sqrt(r * r + (1.0 - r * r) * (NdotL * NdotL))); - float attenuationV = 2.0 * NdotV / (NdotV + sqrt(r * r + (1.0 - r * r) * (NdotV * NdotV))); + float attenuationL = 2.0 * NdotL / (NdotL + sqrt(r2 + (1.0 - r2) * (NdotL * NdotL))); + float attenuationV = 2.0 * NdotV / (NdotV + sqrt(r2 + (1.0 - r2) * (NdotV * NdotV))); return attenuationL * attenuationV; } @@ -613,24 +626,11 @@ vec3 pbrBaseLight(vec3 diffuseColor, vec3 specularColor, float metallic, vec3 v, uniform vec4 waterPlane; uniform float waterSign; -// discard if given position in eye space is on the wrong side of the waterPlane according to waterSign void waterClip(vec3 pos) { - // TODO: make this less branchy - if (waterSign > 0) + if (((dot(pos.xyz, waterPlane.xyz) + waterPlane.w) * waterSign) < 0.0) { - if ((dot(pos.xyz, waterPlane.xyz) + waterPlane.w) < 0.0) - { - discard; - } + discard; } - else - { - if ((dot(pos.xyz, waterPlane.xyz) + waterPlane.w) > 0.0) - { - discard; - } - } - } diff --git a/indra/newview/app_settings/shaders/class1/deferred/globalF.glsl b/indra/newview/app_settings/shaders/class1/deferred/globalF.glsl index 2ed4ba3163..9060d358cf 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/globalF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/globalF.glsl @@ -34,7 +34,7 @@ uniform float clipSign; void mirrorClip(vec3 pos) { - if (mirror_flag > 0) + if (mirror_flag > 0.0) { if ((dot(pos.xyz, clipPlane.xyz) + clipPlane.w) < 0.0) { diff --git a/indra/newview/app_settings/shaders/class1/deferred/luminanceF.glsl b/indra/newview/app_settings/shaders/class1/deferred/luminanceF.glsl index 4acab159cb..4331418b33 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/luminanceF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/luminanceF.glsl @@ -37,14 +37,10 @@ uniform sampler2D emissiveRect; uniform sampler2D normalMap; uniform float diffuse_luminance_scale; -float lum(vec3 col) -{ - vec3 l = vec3(0.2126, 0.7152, 0.0722); - return dot(l, col); -} void main() { + const vec3 l = vec3(0.2126, 0.7152, 0.0722); vec2 tc = vary_fragcoord*0.6+0.2; tc.y -= 0.1; // HACK - nudge exposure sample down a little bit to favor ground over sky vec3 c = texture(diffuseRect, tc).rgb; @@ -62,7 +58,7 @@ void main() c += texture(emissiveRect, tc).rgb; - float L = lum(c); + float L = dot(l, c); frag_color = vec4(max(L, 0.0)); } diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl index dc43007dca..fb4b139662 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl @@ -297,7 +297,7 @@ vec3 _t_normal_post_1(vec3 vNt0, float sign_or_zero) sign = (2.0*sign) + 1.0; sign /= abs(sign); // If the sign is negative, rotate normal by 180 degrees - vNt1.xy = (min(0, sign) * vNt1.xy) + (min(0, -sign) * -vNt1.xy); + vNt1.xy = (min(0.0, sign) * vNt1.xy) + (min(0.0, -sign) * -vNt1.xy); return vNt1; } diff --git a/indra/newview/app_settings/shaders/class1/deferred/postDeferredF.glsl b/indra/newview/app_settings/shaders/class1/deferred/postDeferredF.glsl index 9797bcd2ce..4e737492a7 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/postDeferredF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/postDeferredF.glsl @@ -69,6 +69,8 @@ void dofSampleNear(inout vec4 diff, inout float w, float min_sc, vec2 tc) w += wg; } +vec3 clampHDRRange(vec3 color); + void main() { vec2 tc = vary_fragcoord.xy; @@ -120,5 +122,6 @@ void main() diff /= w; } + diff.rgb = clampHDRRange(diff.rgb); frag_color = diff; } diff --git a/indra/newview/app_settings/shaders/class1/deferred/postDeferredGammaCorrect.glsl b/indra/newview/app_settings/shaders/class1/deferred/postDeferredGammaCorrect.glsl index befd2ae6da..4ccc6f54a8 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/postDeferredGammaCorrect.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/postDeferredGammaCorrect.glsl @@ -43,6 +43,8 @@ vec3 legacyGamma(vec3 color) return c; } +vec3 clampHDRRange(vec3 color); + void main() { //this is the one of the rare spots where diffuseRect contains linear color values (not sRGB) @@ -53,6 +55,7 @@ void main() diff.rgb = legacyGamma(diff.rgb); #endif - frag_color = max(diff, vec4(0)); + diff.rgb = clampHDRRange(diff.rgb); + frag_color = diff; } diff --git a/indra/newview/app_settings/shaders/class1/deferred/postDeferredNoDoFF.glsl b/indra/newview/app_settings/shaders/class1/deferred/postDeferredNoDoFF.glsl index 32b0a1ac8e..c05b4eed7a 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/postDeferredNoDoFF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/postDeferredNoDoFF.glsl @@ -71,6 +71,7 @@ float noise(vec2 x) { //============================= +vec3 clampHDRRange(vec3 color); void main() @@ -84,6 +85,7 @@ void main() diff.rgb += nz*0.003; #endif + diff.rgb = clampHDRRange(diff.rgb); frag_color = diff; gl_FragDepth = texture(depthMap, vary_fragcoord.xy).r; diff --git a/indra/newview/app_settings/shaders/class1/deferred/postDeferredTonemap.glsl b/indra/newview/app_settings/shaders/class1/deferred/postDeferredTonemap.glsl index fc6d4d7727..1f01c7f16a 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/postDeferredTonemap.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/postDeferredTonemap.glsl @@ -28,138 +28,13 @@ out vec4 frag_color; uniform sampler2D diffuseRect; -uniform sampler2D exposureMap; -uniform vec2 screen_res; in vec2 vary_fragcoord; vec3 linear_to_srgb(vec3 cl); +vec3 toneMap(vec3 color); -//=============================================================== -// tone mapping taken from Khronos sample implementation -//=============================================================== - -// sRGB => XYZ => D65_2_D60 => AP1 => RRT_SAT -const mat3 ACESInputMat = mat3 -( - 0.59719, 0.07600, 0.02840, - 0.35458, 0.90834, 0.13383, - 0.04823, 0.01566, 0.83777 -); - - -// ODT_SAT => XYZ => D60_2_D65 => sRGB -const mat3 ACESOutputMat = mat3 -( - 1.60475, -0.10208, -0.00327, - -0.53108, 1.10813, -0.07276, - -0.07367, -0.00605, 1.07602 -); - -// ACES tone map (faster approximation) -// see: https://knarkowicz.wordpress.com/2016/01/06/aces-filmic-tone-mapping-curve/ -vec3 toneMapACES_Narkowicz(vec3 color) -{ - const float A = 2.51; - const float B = 0.03; - const float C = 2.43; - const float D = 0.59; - const float E = 0.14; - return clamp((color * (A * color + B)) / (color * (C * color + D) + E), 0.0, 1.0); -} - - -// ACES filmic tone map approximation -// see https://github.com/TheRealMJP/BakingLab/blob/master/BakingLab/ACES.hlsl -vec3 RRTAndODTFit(vec3 color) -{ - vec3 a = color * (color + 0.0245786) - 0.000090537; - vec3 b = color * (0.983729 * color + 0.4329510) + 0.238081; - return a / b; -} - - -// tone mapping -vec3 toneMapACES_Hill(vec3 color) -{ - color = ACESInputMat * color; - - // Apply RRT and ODT - color = RRTAndODTFit(color); - - color = ACESOutputMat * color; - - // Clamp to [0, 1] - color = clamp(color, 0.0, 1.0); - - return color; -} - -// Khronos Neutral tonemapping -// https://github.com/KhronosGroup/ToneMapping/tree/main -// Input color is non-negative and resides in the Linear Rec. 709 color space. -// Output color is also Linear Rec. 709, but in the [0, 1] range. -vec3 PBRNeutralToneMapping( vec3 color ) -{ - const float startCompression = 0.8 - 0.04; - const float desaturation = 0.15; - - float x = min(color.r, min(color.g, color.b)); - float offset = x < 0.08 ? x - 6.25 * x * x : 0.04; - color -= offset; - - float peak = max(color.r, max(color.g, color.b)); - if (peak < startCompression) return color; - - const float d = 1. - startCompression; - float newPeak = 1. - d * d / (peak + d - startCompression); - color *= newPeak / peak; - - float g = 1. - 1. / (desaturation * (peak - newPeak) + 1.); - return mix(color, newPeak * vec3(1, 1, 1), g); -} - -uniform float exposure; -uniform float tonemap_mix; -uniform int tonemap_type; - -vec3 toneMap(vec3 color) -{ -#ifndef NO_POST - float exp_scale = texture(exposureMap, vec2(0.5,0.5)).r; - - color *= exposure * exp_scale; - - vec3 clamped_color = clamp(color.rgb, vec3(0.0), vec3(1.0)); - - switch(tonemap_type) - { - case 0: - color = PBRNeutralToneMapping(color); - break; - case 1: - color = toneMapACES_Hill(color); - break; - } - - // mix tonemapped and linear here to provide adjustment - color = mix(clamped_color, color, tonemap_mix); -#endif - - return color; -} - -//=============================================================== - -void debugExposure(inout vec3 color) -{ - float exp_scale = texture(exposureMap, vec2(0.5,0.5)).r; - exp_scale *= 0.5; - if (abs(vary_fragcoord.y-exp_scale) < 0.01 && vary_fragcoord.x < 0.1) - { - color = vec3(1,0,0); - } -} +vec3 clampHDRRange(vec3 color); void main() { @@ -172,6 +47,7 @@ void main() diff.rgb = clamp(diff.rgb, vec3(0.0), vec3(1.0)); #endif + diff.rgb = clampHDRRange(diff.rgb); //debugExposure(diff.rgb); frag_color = max(diff, vec4(0)); } diff --git a/indra/newview/app_settings/shaders/class1/deferred/tonemapUtilF.glsl b/indra/newview/app_settings/shaders/class1/deferred/tonemapUtilF.glsl new file mode 100644 index 0000000000..a63b8d7c2b --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/deferred/tonemapUtilF.glsl @@ -0,0 +1,180 @@ +/** + * @file postDeferredTonemap.glsl + * + * $LicenseInfo:firstyear=2024&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2024, 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$ + */ + +/*[EXTRA_CODE_HERE]*/ + +uniform sampler2D exposureMap; +uniform vec2 screen_res; +in vec2 vary_fragcoord; + +//=============================================================== +// tone mapping taken from Khronos sample implementation +//=============================================================== + +// sRGB => XYZ => D65_2_D60 => AP1 => RRT_SAT +const mat3 ACESInputMat = mat3 +( + 0.59719, 0.07600, 0.02840, + 0.35458, 0.90834, 0.13383, + 0.04823, 0.01566, 0.83777 +); + + +// ODT_SAT => XYZ => D60_2_D65 => sRGB +const mat3 ACESOutputMat = mat3 +( + 1.60475, -0.10208, -0.00327, + -0.53108, 1.10813, -0.07276, + -0.07367, -0.00605, 1.07602 +); + +// ACES tone map (faster approximation) +// see: https://knarkowicz.wordpress.com/2016/01/06/aces-filmic-tone-mapping-curve/ +vec3 toneMapACES_Narkowicz(vec3 color) +{ + const float A = 2.51; + const float B = 0.03; + const float C = 2.43; + const float D = 0.59; + const float E = 0.14; + return clamp((color * (A * color + B)) / (color * (C * color + D) + E), 0.0, 1.0); +} + + +// ACES filmic tone map approximation +// see https://github.com/TheRealMJP/BakingLab/blob/master/BakingLab/ACES.hlsl +vec3 RRTAndODTFit(vec3 color) +{ + vec3 a = color * (color + 0.0245786) - 0.000090537; + vec3 b = color * (0.983729 * color + 0.4329510) + 0.238081; + return a / b; +} + + +// tone mapping +vec3 toneMapACES_Hill(vec3 color) +{ + color = ACESInputMat * color; + + // Apply RRT and ODT + color = RRTAndODTFit(color); + + color = ACESOutputMat * color; + + // Clamp to [0, 1] + color = clamp(color, 0.0, 1.0); + + return color; +} + +// Khronos Neutral tonemapping +// https://github.com/KhronosGroup/ToneMapping/tree/main +// Input color is non-negative and resides in the Linear Rec. 709 color space. +// Output color is also Linear Rec. 709, but in the [0, 1] range. +vec3 PBRNeutralToneMapping( vec3 color ) +{ + const float startCompression = 0.8 - 0.04; + const float desaturation = 0.15; + + float x = min(color.r, min(color.g, color.b)); + float offset = x < 0.08 ? x - 6.25 * x * x : 0.04; + color -= offset; + + float peak = max(color.r, max(color.g, color.b)); + if (peak < startCompression) return color; + + const float d = 1. - startCompression; + float newPeak = 1. - d * d / (peak + d - startCompression); + color *= newPeak / peak; + + float g = 1. - 1. / (desaturation * (peak - newPeak) + 1.); + return mix(color, newPeak * vec3(1, 1, 1), g); +} + +uniform float exposure; +uniform float tonemap_mix; +uniform int tonemap_type; + +vec3 toneMap(vec3 color) +{ +#ifndef NO_POST + float exp_scale = texture(exposureMap, vec2(0.5,0.5)).r; + + color *= exposure * exp_scale; + + vec3 clamped_color = clamp(color.rgb, vec3(0.0), vec3(1.0)); + + switch(tonemap_type) + { + case 0: + color = PBRNeutralToneMapping(color); + break; + case 1: + color = toneMapACES_Hill(color); + break; + } + + // mix tonemapped and linear here to provide adjustment + color = mix(clamped_color, color, tonemap_mix); +#endif + + return color; +} + + +vec3 toneMapNoExposure(vec3 color) +{ +#ifndef NO_POST + vec3 clamped_color = clamp(color.rgb, vec3(0.0), vec3(1.0)); + + switch(tonemap_type) + { + case 0: + color = PBRNeutralToneMapping(color); + break; + case 1: + color = toneMapACES_Hill(color); + break; + } + + // mix tonemapped and linear here to provide adjustment + color = mix(clamped_color, color, tonemap_mix); +#endif + + return color; +} + + +//=============================================================== + +void debugExposure(inout vec3 color) +{ + float exp_scale = texture(exposureMap, vec2(0.5,0.5)).r; + exp_scale *= 0.5; + if (abs(vary_fragcoord.y-exp_scale) < 0.01 && vary_fragcoord.x < 0.1) + { + color = vec3(1,0,0); + } +} diff --git a/indra/newview/app_settings/shaders/class1/effects/glowExtractF.glsl b/indra/newview/app_settings/shaders/class1/effects/glowExtractF.glsl index 72eda80716..bfb592be9b 100644 --- a/indra/newview/app_settings/shaders/class1/effects/glowExtractF.glsl +++ b/indra/newview/app_settings/shaders/class1/effects/glowExtractF.glsl @@ -49,7 +49,7 @@ void main() float warmth = smoothstep(minLuminance, minLuminance+1.0, max(col.r * warmthWeights.r, max(col.g * warmthWeights.g, col.b * warmthWeights.b)) ); #if HAS_NOISE - float TRUE_NOISE_RES = 128; // See mTrueNoiseMap + float TRUE_NOISE_RES = 128.0; // See mTrueNoiseMap // *NOTE: Usually this is vary_fragcoord not vary_texcoord0, but glow extraction is in screen space vec3 glow_noise = texture(glowNoiseMap, vary_texcoord0.xy * (screen_res / TRUE_NOISE_RES)).xyz; // Dithering. Reduces banding effects in the reduced precision glow buffer. diff --git a/indra/newview/app_settings/shaders/class1/environment/srgbF.glsl b/indra/newview/app_settings/shaders/class1/environment/srgbF.glsl index d7f6d20547..bf8737615f 100644 --- a/indra/newview/app_settings/shaders/class1/environment/srgbF.glsl +++ b/indra/newview/app_settings/shaders/class1/environment/srgbF.glsl @@ -41,6 +41,26 @@ vec3 srgb_to_linear(vec3 cs) } + +vec4 srgb_to_linear4(vec4 cs) +{ + vec4 low_range = cs / vec4(12.92); + vec4 high_range = pow((cs+vec4(0.055))/vec4(1.055), vec4(2.4)); + bvec4 lte = lessThanEqual(cs,vec4(0.04045)); + +#ifdef OLD_SELECT + vec4 result; + result.r = lte.r ? low_range.r : high_range.r; + result.g = lte.g ? low_range.g : high_range.g; + result.b = lte.b ? low_range.b : high_range.b; + result.a = lte.a ? low_range.a : high_range.a; + return result; +#else + return mix(high_range, low_range, lte); +#endif + +} + vec3 linear_to_srgb(vec3 cl) { cl = clamp(cl, vec3(0), vec3(1)); diff --git a/indra/newview/app_settings/shaders/class1/environment/waterFogF.glsl b/indra/newview/app_settings/shaders/class1/environment/waterFogF.glsl index 20b61e9302..44a979e565 100644 --- a/indra/newview/app_settings/shaders/class1/environment/waterFogF.glsl +++ b/indra/newview/app_settings/shaders/class1/environment/waterFogF.glsl @@ -66,11 +66,11 @@ vec4 getWaterFogViewNoClip(vec3 pos) float t2 = kd + ks * es; float t3 = pow(F, t2*l) - 1.0; - float L = min(t1/t2*t3, 1.0); + float L = pow(min(t1/t2*t3, 1.0), 1.0/1.7); float D = pow(0.98, l*kd); - return vec4(srgb_to_linear(kc.rgb*L), D); + return vec4(srgb_to_linear(kc.rgb)*L, D); } vec4 getWaterFogView(vec3 pos) diff --git a/indra/newview/app_settings/shaders/class1/interface/gaussianF.glsl b/indra/newview/app_settings/shaders/class1/interface/gaussianF.glsl index 09eb7a6a6a..82f32da048 100644 --- a/indra/newview/app_settings/shaders/class1/interface/gaussianF.glsl +++ b/indra/newview/app_settings/shaders/class1/interface/gaussianF.glsl @@ -45,7 +45,7 @@ void main() for (int i = 0; i < 9; ++i) { - vec2 tc = vary_texcoord0 + (i-4)*direction*resScale; + vec2 tc = vary_texcoord0 + float(i-4)*direction*resScale; col += texture(diffuseRect, tc).rgb * w[i]; } diff --git a/indra/newview/llappviewerlinux_api_dbus.h b/indra/newview/app_settings/shaders/class1/objects/simpleColorF.glsl index 2f4492bd7a..30d70122cb 100644 --- a/indra/newview/llappviewerlinux_api_dbus.h +++ b/indra/newview/app_settings/shaders/class1/objects/simpleColorF.glsl @@ -1,10 +1,9 @@ /** - * @file llappviewerlinux_api_dbus.h - * @brief DBus-glib symbol handling + * @file simpleColorF.glsl * - * $LicenseInfo:firstyear=2008&license=viewerlgpl$ + * $LicenseInfo:firstyear=2025&license=viewerlgpl$ * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. + * Copyright (C) 2007, 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 @@ -24,21 +23,24 @@ * $/LicenseInfo$ */ -#include "linden_common.h" +out vec4 frag_color; -#if LL_DBUS_ENABLED +in vec4 vertex_color; +in vec4 vertex_position; -extern "C" { -#include <dbus/dbus-glib.h> -} - -#define DBUSGLIB_DYLIB_DEFAULT_NAME "libdbus-glib-1.so.2" +uniform vec4 waterPlane; +uniform float waterSign; -bool grab_dbus_syms(std::string dbus_dso_name); -void ungrab_dbus_syms(); +void waterClip(vec3 pos) +{ + if (((dot(pos.xyz, waterPlane.xyz) + waterPlane.w) * waterSign) < 0.0) + { + discard; + } +} -#define LL_DBUS_SYM(REQUIRED, DBUSSYM, RTN, ...) extern RTN (*ll##DBUSSYM)(__VA_ARGS__) -#include "llappviewerlinux_api_dbus_syms_raw.inc" -#undef LL_DBUS_SYM +void main() +{ -#endif // LL_DBUS_ENABLED + frag_color = vertex_color; +} diff --git a/indra/newview/app_settings/shaders/class1/objects/simpleNoAtmosV.glsl b/indra/newview/app_settings/shaders/class1/objects/simpleNoAtmosV.glsl new file mode 100644 index 0000000000..4564e56313 --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/objects/simpleNoAtmosV.glsl @@ -0,0 +1,43 @@ +/** + * @file simpleNoAtmosV.glsl + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2007, 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$ + */ + +uniform mat4 modelview_matrix; +uniform mat4 modelview_projection_matrix; + +uniform vec4 color; + +in vec3 position; + +out vec4 vertex_color; +out vec4 vertex_position; + +void main() +{ + //transform vertex + vec4 pos = (modelview_matrix * vec4(position.xyz, 1.0)); + vertex_position = modelview_projection_matrix * vec4(position.xyz, 1.0); + gl_Position = vertex_position; + vertex_color = color; +} diff --git a/indra/newview/app_settings/shaders/class1/windlight/atmosphericsFuncs.glsl b/indra/newview/app_settings/shaders/class1/windlight/atmosphericsFuncs.glsl index 205d4bff6d..9101fc0222 100644 --- a/indra/newview/app_settings/shaders/class1/windlight/atmosphericsFuncs.glsl +++ b/indra/newview/app_settings/shaders/class1/windlight/atmosphericsFuncs.glsl @@ -99,7 +99,7 @@ void calcAtmosphericVars(vec3 inPositionEye, vec3 light_dir, float ambFactor, ou haze_glow = max(haze_glow, .001); // set a minimum "angle" (smaller glow.y allows tighter, brighter hotspot) haze_glow *= glow.x; // higher glow.x gives dimmer glow (because next step is 1 / "angle") - haze_glow = clamp(pow(haze_glow, glow.z), -100000, 100000); + haze_glow = clamp(pow(haze_glow, glow.z), -100000.0, 100000.0); // glow.z should be negative, so we're doing a sort of (1 / "angle") function // add "minimum anti-solar illumination" @@ -154,6 +154,7 @@ void calcAtmosphericVarsLinear(vec3 inPositionEye, vec3 norm, vec3 light_dir, ou if (classic_mode < 1) { amblit = srgb_to_linear(amblit); + amblit = vec3(dot(amblit, vec3(0.2126, 0.7152, 0.0722))); sunlit = srgb_to_linear(sunlit); } diff --git a/indra/newview/app_settings/shaders/class1/windlight/atmosphericsV.glsl b/indra/newview/app_settings/shaders/class1/windlight/atmosphericsV.glsl index 1372ddbcfa..bdc5b58060 100644 --- a/indra/newview/app_settings/shaders/class1/windlight/atmosphericsV.glsl +++ b/indra/newview/app_settings/shaders/class1/windlight/atmosphericsV.glsl @@ -47,7 +47,7 @@ void calcAtmospherics(vec3 inPositionEye) { vec3 tmpaddlit = vec3(1); vec3 tmpattenlit = vec3(1); vec3 light_dir = (sun_up_factor == 1) ? sun_dir : moon_dir; - calcAtmosphericVars(inPositionEye, light_dir, 1, tmpsunlit, tmpamblit, tmpaddlit, tmpattenlit); + calcAtmosphericVars(inPositionEye, light_dir, 1.0, tmpsunlit, tmpamblit, tmpaddlit, tmpattenlit); setSunlitColor(tmpsunlit); setAmblitColor(tmpamblit); setAdditiveColor(tmpaddlit); diff --git a/indra/newview/app_settings/shaders/class2/deferred/alphaF.glsl b/indra/newview/app_settings/shaders/class2/deferred/alphaF.glsl index 3e702f26be..50b40e9c20 100644 --- a/indra/newview/app_settings/shaders/class2/deferred/alphaF.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/alphaF.glsl @@ -80,7 +80,7 @@ float getAmbientClamp(); void mirrorClip(vec3 pos); -void sampleReflectionProbesLegacy(inout vec3 ambenv, inout vec3 glossenv, inout vec3 legacyenv, +void sampleReflectionProbesLegacy(out vec3 ambenv, out vec3 glossenv, out vec3 legacyenv, vec2 tc, vec3 pos, vec3 norm, float glossiness, float envIntensity, bool transparent, vec3 amblit_linear); vec3 calcPointLightOrSpotLight(vec3 light_col, vec3 diffuse, vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float fa, float is_pointlight, float ambiance) @@ -148,9 +148,9 @@ vec3 calcPointLightOrSpotLight(vec3 light_col, vec3 diffuse, vec3 v, vec3 n, vec float lit = 0.0f; float amb_da = 0.0;//ambiance; - if (da > 0) + if (da > 0.0) { - lit = max(da * dist_atten,0.0); + lit = clamp(da * dist_atten, 0.0, 1.0); col = lit * light_col * diffuse; amb_da += (da*0.5+0.5) * ambiance; } diff --git a/indra/newview/app_settings/shaders/class2/deferred/reflectionProbeF.glsl b/indra/newview/app_settings/shaders/class2/deferred/reflectionProbeF.glsl index c43582e185..2657b2b54e 100644 --- a/indra/newview/app_settings/shaders/class2/deferred/reflectionProbeF.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/reflectionProbeF.glsl @@ -56,7 +56,7 @@ vec4 sampleReflectionProbesDebug(vec3 pos) return vec4(0, 0, 0, 0); } -void sampleReflectionProbesLegacy(inout vec3 ambenv, inout vec3 glossenv, inout vec3 legacyenv, +void sampleReflectionProbesLegacy(out vec3 ambenv, out vec3 glossenv, out vec3 legacyenv, vec2 tc, vec3 pos, vec3 norm, float glossiness, float envIntensity, bool transparent, vec3 amblit_linear) { ambenv = mix(ambenv, vec3(reflection_probe_ambiance * 0.25), reflection_probe_ambiance); diff --git a/indra/newview/app_settings/shaders/class3/deferred/fullbrightShinyF.glsl b/indra/newview/app_settings/shaders/class3/deferred/fullbrightShinyF.glsl index 03dc3d7113..5e38864d38 100644 --- a/indra/newview/app_settings/shaders/class3/deferred/fullbrightShinyF.glsl +++ b/indra/newview/app_settings/shaders/class3/deferred/fullbrightShinyF.glsl @@ -48,7 +48,7 @@ vec3 linear_to_srgb(vec3 c); vec3 srgb_to_linear(vec3 c); // reflection probe interface -void sampleReflectionProbesLegacy(inout vec3 ambenv, inout vec3 glossenv, inout vec3 legacyenv, +void sampleReflectionProbesLegacy(out vec3 ambenv, out vec3 glossenv, out vec3 legacyenv, vec2 tc, vec3 pos, vec3 norm, float glossiness, float envIntensity, bool transparent, vec3 amblit_linear); void applyLegacyEnv(inout vec3 color, vec3 legacyenv, vec4 spec, vec3 pos, vec3 norm, float envIntensity); diff --git a/indra/newview/app_settings/shaders/class3/deferred/materialF.glsl b/indra/newview/app_settings/shaders/class3/deferred/materialF.glsl index 7f871c0d5e..f8803f1a29 100644 --- a/indra/newview/app_settings/shaders/class3/deferred/materialF.glsl +++ b/indra/newview/app_settings/shaders/class3/deferred/materialF.glsl @@ -62,7 +62,7 @@ out vec4 frag_color; float sampleDirectionalShadow(vec3 pos, vec3 norm, vec2 pos_screen); #endif -void sampleReflectionProbesLegacy(inout vec3 ambenv, inout vec3 glossenv, inout vec3 legacyenv, +void sampleReflectionProbesLegacy(out vec3 ambenv, out vec3 glossenv, out vec3 legacyenv, vec2 tc, vec3 pos, vec3 norm, float glossiness, float envIntensity, bool transparent, vec3 amblit_linear); void applyGlossEnv(inout vec3 color, vec3 glossenv, vec4 spec, vec3 pos, vec3 norm); void applyLegacyEnv(inout vec3 color, vec3 legacyenv, vec4 spec, vec3 pos, vec3 norm, float envIntensity); @@ -138,9 +138,9 @@ vec3 calcPointLightOrSpotLight(vec3 light_col, vec3 npos, vec3 diffuse, vec4 spe float lit = 0.0f; float amb_da = ambiance; - if (da >= 0) + if (da >= 0.0) { - lit = max(da * dist_atten, 0.0); + lit = clamp(da * dist_atten, 0.0, 1.0); col = lit * light_col * diffuse; amb_da += (da*0.5 + 0.5) * ambiance; } @@ -159,10 +159,10 @@ vec3 calcPointLightOrSpotLight(vec3 light_col, vec3 npos, vec3 diffuse, vec4 spe float nv = dot(n, npos); float vh = dot(npos, h); float sa = nh; - float fres = pow(1 - dot(h, npos), 5)*0.4 + 0.5; + float fres = pow(1.0 - dot(h, npos), 5.0)*0.4 + 0.5; - float gtdenom = 2 * nh; - float gt = max(0, min(gtdenom * nv / vh, gtdenom * da / vh)); + float gtdenom = 2.0 * nh; + float gt = max(0.0, min(gtdenom * nv / vh, gtdenom * da / vh)); if (nh > 0.0) { @@ -225,7 +225,7 @@ vec3 getNormal(inout float glossiness) #ifdef HAS_NORMAL_MAP vec4 vNt = texture(bumpMap, vary_texcoord1.xy); glossiness *= vNt.a; - vNt.xyz = vNt.xyz * 2 - 1; + vNt.xyz = vNt.xyz * 2.0 - 1.0; float sign = vary_sign; vec3 vN = vary_normal; vec3 vT = vary_tangent.xyz; @@ -284,10 +284,10 @@ float getShadow(vec3 pos, vec3 norm) #if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_BLEND) return sampleDirectionalShadow(pos, norm, vary_texcoord0.xy); #else - return 1; + return 1.; #endif #else - return 1; + return 1.; #endif } @@ -377,9 +377,9 @@ void main() float lit = min(nl*6.0, 1.0); float sa = nh; - float fres = pow(1 - vh, 5) * 0.4+0.5; - float gtdenom = 2 * nh; - float gt = max(0,(min(gtdenom * nv / vh, gtdenom * nl / vh))); + float fres = pow(1.0 - vh, 5.0) * 0.4+0.5; + float gtdenom = 2.0 * nh; + float gt = max(0.0,(min(gtdenom * nv / vh, gtdenom * nl / vh))); float scol = shadow*fres*texture(lightFunc, vec2(nh, glossiness)).r*gt/(nh*nl); color.rgb += lit*scol*sunlit_linear.rgb*spec.rgb; @@ -396,7 +396,7 @@ void main() applyLegacyEnv(color, legacyenv, spec, pos.xyz, norm.xyz, env); float cur_glare = max(max(legacyenv.r, legacyenv.g), legacyenv.b); - cur_glare = clamp(cur_glare, 0, 1); + cur_glare = clamp(cur_glare, 0.0, 1.0); cur_glare *= env; glare += cur_glare; } diff --git a/indra/newview/app_settings/shaders/class3/deferred/multiPointLightF.glsl b/indra/newview/app_settings/shaders/class3/deferred/multiPointLightF.glsl index 96cda1ef49..b11c2644aa 100644 --- a/indra/newview/app_settings/shaders/class3/deferred/multiPointLightF.glsl +++ b/indra/newview/app_settings/shaders/class3/deferred/multiPointLightF.glsl @@ -153,10 +153,10 @@ void main() if (spec.a > 0.0) { lit = min(nl * 6.0, 1.0) * dist_atten; - float fres = pow(1 - vh, 5) * 0.4 + 0.5; + float fres = pow(1.0 - vh, 5.0) * 0.4 + 0.5; - float gtdenom = 2 * nh; - float gt = max(0, min(gtdenom * nv / vh, gtdenom * nl / vh)); + float gtdenom = 2.0 * nh; + float gt = max(0.0, min(gtdenom * nv / vh, gtdenom * nl / vh)); if (nh > 0.0) { diff --git a/indra/newview/app_settings/shaders/class3/deferred/pointLightF.glsl b/indra/newview/app_settings/shaders/class3/deferred/pointLightF.glsl index ceb37f36a5..6a248f25bc 100644 --- a/indra/newview/app_settings/shaders/class3/deferred/pointLightF.glsl +++ b/indra/newview/app_settings/shaders/class3/deferred/pointLightF.glsl @@ -134,9 +134,9 @@ void main() lit = min(nl*6.0, 1.0) * dist_atten; float sa = nh; - float fres = pow(1 - vh, 5) * 0.4+0.5; - float gtdenom = 2 * nh; - float gt = max(0,(min(gtdenom * nv / vh, gtdenom * nl / vh))); + float fres = pow(1.0 - vh, 5.0) * 0.4+0.5; + float gtdenom = 2.0 * nh; + float gt = max(0.0,(min(gtdenom * nv / vh, gtdenom * nl / vh))); if (nh > 0.0) { diff --git a/indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl b/indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl index 5dfa196cf6..2f577f8459 100644 --- a/indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl +++ b/indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl @@ -38,6 +38,8 @@ uniform float max_probe_lod; uniform bool transparent_surface; +uniform int classic_mode; + #define MAX_REFMAP_COUNT 256 // must match LL_MAX_REFLECTION_PROBE_COUNT layout (std140) uniform ReflectionProbes @@ -739,7 +741,10 @@ void doProbeSample(inout vec3 ambenv, inout vec3 glossenv, vec3 refnormpersp = reflect(pos.xyz, norm.xyz); - ambenv = sampleProbeAmbient(pos, norm, amblit); + ambenv = amblit; + + if (classic_mode == 0) + ambenv = sampleProbeAmbient(pos, norm, amblit); float lod = (1.0-glossiness)*reflection_lods; glossenv = sampleProbes(pos, normalize(refnormpersp), lod); @@ -784,9 +789,6 @@ void sampleReflectionProbesWater(inout vec3 ambenv, inout vec3 glossenv, probeIndex[probeInfluences++] = 0; doProbeSample(ambenv, glossenv, tc, pos, norm, glossiness, false, amblit); - - // fudge factor to get PBR water at a similar luminance ot legacy water - glossenv *= 0.4; } void debugTapRefMap(vec3 pos, vec3 dir, float depth, int i, inout vec4 col) @@ -837,7 +839,7 @@ vec4 sampleReflectionProbesDebug(vec3 pos) return col; } -void sampleReflectionProbesLegacy(inout vec3 ambenv, inout vec3 glossenv, inout vec3 legacyenv, +void sampleReflectionProbesLegacy(out vec3 ambenv, out vec3 glossenv, out vec3 legacyenv, vec2 tc, vec3 pos, vec3 norm, float glossiness, float envIntensity, bool transparent, vec3 amblit) { float reflection_lods = max_probe_lod; @@ -845,7 +847,10 @@ void sampleReflectionProbesLegacy(inout vec3 ambenv, inout vec3 glossenv, inout vec3 refnormpersp = reflect(pos.xyz, norm.xyz); - ambenv = sampleProbeAmbient(pos, norm, amblit); + ambenv = amblit; + + if (classic_mode == 0) + ambenv = sampleProbeAmbient(pos, norm, amblit); if (glossiness > 0.0) { diff --git a/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl b/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl index aac75a0739..6cec65ad83 100644 --- a/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl +++ b/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl @@ -69,7 +69,7 @@ vec3 scaleSoftClipFragLinear(vec3 l); // reflection probe interface void sampleReflectionProbes(inout vec3 ambenv, inout vec3 glossenv, vec2 tc, vec3 pos, vec3 norm, float glossiness, bool transparent, vec3 amblit_linear); -void sampleReflectionProbesLegacy(inout vec3 ambenv, inout vec3 glossenv, inout vec3 legacyenv, +void sampleReflectionProbesLegacy(out vec3 ambenv, out vec3 glossenv, out vec3 legacyenv, vec2 tc, vec3 pos, vec3 norm, float glossiness, float envIntensity, bool transparent, vec3 amblit_linear); void applyGlossEnv(inout vec3 color, vec3 glossenv, vec4 spec, vec3 pos, vec3 norm); void applyLegacyEnv(inout vec3 color, vec3 legacyenv, vec4 spec, vec3 pos, vec3 norm, float envIntensity); @@ -104,6 +104,7 @@ vec3 pbrBaseLight(vec3 diffuseColor, vec3 atten); GBufferInfo getGBuffer(vec2 screenpos); +vec3 clampHDRRange(vec3 color); void adjustIrradiance(inout vec3 irradiance, float ambocc) { @@ -278,6 +279,7 @@ void main() float final_scale = 1; if (classic_mode > 0) final_scale = 1.1; - frag_color.rgb = max(color.rgb * final_scale, vec3(0)); //output linear since local lights will be added to this shader's results + + frag_color.rgb = clampHDRRange(color.rgb * final_scale); //output linear since local lights will be added to this shader's results frag_color.a = 0.0; } diff --git a/indra/newview/app_settings/shaders/class3/deferred/spotLightF.glsl b/indra/newview/app_settings/shaders/class3/deferred/spotLightF.glsl index a46e3688dc..017f8bc844 100644 --- a/indra/newview/app_settings/shaders/class3/deferred/spotLightF.glsl +++ b/indra/newview/app_settings/shaders/class3/deferred/spotLightF.glsl @@ -199,7 +199,7 @@ void main() proj_tc.x > 0.0 && proj_tc.y > 0.0) { - float amb_da = 0; + float amb_da = 0.0; float lit = 0.0; if (nl > 0.0) @@ -222,10 +222,10 @@ void main() { dlit *= min(nl*6.0, 1.0) * dist_atten; - float fres = pow(1 - vh, 5)*0.4+0.5; + float fres = pow(1.0 - vh, 5.0)*0.4+0.5; - float gtdenom = 2 * nh; - float gt = max(0, min(gtdenom * nv / vh, gtdenom * nl / vh)); + float gtdenom = 2.0 * nh; + float gt = max(0.0, min(gtdenom * nv / vh, gtdenom * nl / vh)); if (nh > 0.0) { @@ -259,7 +259,7 @@ void main() stc.x > 0.0 && stc.y > 0.0) { - final_color += color.rgb * texture2DLodSpecular(stc.xy, (1 - spec.a) * (proj_lod * 0.6)).rgb * shadow * envIntensity; + final_color += color.rgb * texture2DLodSpecular(stc.xy, (1.0 - spec.a) * (proj_lod * 0.6)).rgb * shadow * envIntensity; } } } diff --git a/indra/newview/app_settings/shaders/class3/deferred/waterHazeF.glsl b/indra/newview/app_settings/shaders/class3/deferred/waterHazeF.glsl index 2bf785e773..091c25d15e 100644 --- a/indra/newview/app_settings/shaders/class3/deferred/waterHazeF.glsl +++ b/indra/newview/app_settings/shaders/class3/deferred/waterHazeF.glsl @@ -35,13 +35,25 @@ vec4 getWaterFogView(vec3 pos); uniform int above_water; +uniform sampler2D exclusionTex; + void main() { vec2 tc = vary_fragcoord.xy/vary_fragcoord.w*0.5+0.5; float depth = getDepth(tc.xy); + float mask = texture(exclusionTex, tc.xy).r; if (above_water > 0) { + // Just discard if we're in the exclusion mask. + // The previous invisiprim hack we're replacing would also crank up water fog desntiy. + // But doing that makes exclusion surfaces very slow as we'd need to render even more into the mask. + // - Geenz 2025-02-06 + if (mask < 1) + { + discard; + } + // we want to depth test when the camera is above water, but some GPUs have a hard time // with depth testing against render targets that are bound for sampling in the same shader // so we do it manually here @@ -51,11 +63,13 @@ void main() { discard; } + } vec4 pos = getPositionWithDepth(tc, depth); vec4 fogged = getWaterFogView(pos.xyz); + fogged.a = max(pow(fogged.a, 1.7), 0); frag_color = max(fogged, vec4(0)); //output linear since local lights will be added to this shader's results diff --git a/indra/newview/app_settings/shaders/class3/environment/underWaterF.glsl b/indra/newview/app_settings/shaders/class3/environment/underWaterF.glsl index 1c02dc764d..fa410e9f11 100644 --- a/indra/newview/app_settings/shaders/class3/environment/underWaterF.glsl +++ b/indra/newview/app_settings/shaders/class3/environment/underWaterF.glsl @@ -26,6 +26,7 @@ out vec4 frag_color; uniform sampler2D bumpMap; +uniform sampler2D exclusionTex; #ifdef TRANSPARENT_WATER uniform sampler2D screenTex; @@ -59,6 +60,9 @@ void mirrorClip(vec3 position); void main() { mirrorClip(vary_position); + vec2 screen_tc = (refCoord.xy/refCoord.z) * 0.5 + 0.5; + float water_mask = texture(exclusionTex, screen_tc).r; + vec4 color; //get detail normals @@ -68,8 +72,8 @@ void main() vec3 wavef = normalize(wave1+wave2+wave3); //figure out distortion vector (ripply) - vec2 distort = (refCoord.xy/refCoord.z) * 0.5 + 0.5; - distort = distort+wavef.xy*refScale; + vec2 distort = screen_tc; + distort = mix(distort, distort+wavef.xy*refScale, water_mask); #ifdef TRANSPARENT_WATER vec4 fb = texture(screenTex, distort); diff --git a/indra/newview/app_settings/shaders/class3/environment/waterF.glsl b/indra/newview/app_settings/shaders/class3/environment/waterF.glsl index 8bf4ec0a7e..b9de4edc67 100644 --- a/indra/newview/app_settings/shaders/class3/environment/waterF.glsl +++ b/indra/newview/app_settings/shaders/class3/environment/waterF.glsl @@ -25,6 +25,8 @@ // class3/environment/waterF.glsl +#define WATER_MINIMAL 1 + out vec4 frag_color; #ifdef HAS_SUN_SHADOW @@ -86,23 +88,17 @@ uniform sampler2D screenTex; uniform sampler2D depthMap; #endif -uniform sampler2D refTex; +uniform sampler2D exclusionTex; -uniform float sunAngle; -uniform float sunAngle2; +uniform int classic_mode; uniform vec3 lightDir; uniform vec3 specular; -uniform float lightExp; +uniform float blurMultiplier; uniform float refScale; uniform float kd; -uniform vec2 screenRes; uniform vec3 normScale; uniform float fresnelScale; uniform float fresnelOffset; -uniform float blurMultiplier; -uniform vec4 waterFogColor; -uniform vec3 waterFogColorLinear; - //bigWave is (refCoord.w, view.w); in vec4 refCoord; @@ -122,6 +118,10 @@ vec3 BlendNormal(vec3 bump1, vec3 bump2) vec3 srgb_to_linear(vec3 col); vec3 linear_to_srgb(vec3 col); +vec3 atmosLighting(vec3 light); +vec3 scaleSoftClip(vec3 light); +vec3 toneMapNoExposure(vec3 color); + vec3 vN, vT, vB; vec3 transform_normal(vec3 vNt) @@ -132,59 +132,109 @@ vec3 transform_normal(vec3 vNt) void sampleReflectionProbesWater(inout vec3 ambenv, inout vec3 glossenv, vec2 tc, vec3 pos, vec3 norm, float glossiness, vec3 amblit_linear); +void sampleReflectionProbes(inout vec3 ambenv, inout vec3 glossenv, + vec2 tc, vec3 pos, vec3 norm, float glossiness, bool transparent, vec3 amblit_linear); + +/* +void sampleReflectionProbesLegacy(inout vec3 ambenv, inout vec3 glossenv, inout vec3 legacyenv, + vec2 tc, vec3 pos, vec3 norm, float glossiness, float envIntensity, bool transparent, vec3 amblit); +*/ + + vec3 getPositionWithNDC(vec3 ndc); +void generateWaveNormals(out vec3 wave1, out vec3 wave2, out vec3 wave3) +{ + // Generate all of our wave normals. + // We layer these back and forth. + + vec2 bigwave = vec2(refCoord.w, view.w); + + vec3 wave1_a = texture(bumpMap, bigwave).xyz * 2.0 - 1.0; + vec3 wave2_a = texture(bumpMap, littleWave.xy).xyz * 2.0 - 1.0; + vec3 wave3_a = texture(bumpMap, littleWave.zw).xyz * 2.0 - 1.0; + + vec3 wave1_b = texture(bumpMap2, bigwave).xyz * 2.0 - 1.0; + vec3 wave2_b = texture(bumpMap2, littleWave.xy).xyz * 2.0 - 1.0; + vec3 wave3_b = texture(bumpMap2, littleWave.zw).xyz * 2.0 - 1.0; + + wave1 = BlendNormal(wave1_a, wave1_b); + wave2 = BlendNormal(wave2_a, wave2_b); + wave3 = BlendNormal(wave3_a, wave3_b); +} + +void calculateFresnelFactors(out vec3 df3, out vec2 df2, vec3 viewVec, vec3 wave1, vec3 wave2, vec3 wave3, vec3 wavef) +{ + // We calculate the fresnel here. + // We do this by getting the dot product for each sets of waves, and applying scale and offset. + + df3 = max(vec3(0), vec3( + dot(viewVec, wave1), + dot(viewVec, (wave2 + wave3) * 0.5), + dot(viewVec, wave3) + ) * fresnelScale + fresnelOffset); + + df3 *= df3; + + df2 = max(vec2(0), vec2( + df3.x + df3.y + df3.z, + dot(viewVec, wavef) * fresnelScale + fresnelOffset + )); +} + void main() { mirrorClip(vary_position); + vN = vary_normal; vT = vary_tangent; vB = cross(vN, vT); vec3 pos = vary_position.xyz; + float linear_depth = 1.0 / -pos.z; float dist = length(pos.xyz); //normalize view vector vec3 viewVec = normalize(pos.xyz); - //get wave normals - vec2 bigwave = vec2(refCoord.w, view.w); - vec3 wave1_a = texture(bumpMap, bigwave, -2 ).xyz*2.0-1.0; - vec3 wave2_a = texture(bumpMap, littleWave.xy).xyz*2.0-1.0; - vec3 wave3_a = texture(bumpMap, littleWave.zw).xyz*2.0-1.0; + // Setup our waves. - vec3 wave1_b = texture(bumpMap2, bigwave ).xyz*2.0-1.0; - vec3 wave2_b = texture(bumpMap2, littleWave.xy).xyz*2.0-1.0; - vec3 wave3_b = texture(bumpMap2, littleWave.zw).xyz*2.0-1.0; + vec3 wave1 = vec3(0, 0, 1); + vec3 wave2 = vec3(0, 0, 1); + vec3 wave3 = vec3(0, 0, 1); - //wave1_a = wave2_a = wave3_a = wave1_b = wave2_b = wave3_b = vec3(0,0,1); - - vec3 wave1 = BlendNormal(wave1_a, wave1_b); - vec3 wave2 = BlendNormal(wave2_a, wave2_b); - vec3 wave3 = BlendNormal(wave3_a, wave3_b); + generateWaveNormals(wave1, wave2, wave3); + float dmod = sqrt(dist); vec2 distort = (refCoord.xy/refCoord.z) * 0.5 + 0.5; - //wave1 = transform_normal(wave1); - //wave2 = transform_normal(wave2); - //wave3 = transform_normal(wave3); - vec3 wavef = (wave1 + wave2 * 0.4 + wave3 * 0.6) * 0.5; - vec3 waver = wavef*3; + vec3 df3 = vec3(0); + vec2 df2 = vec2(0); + + vec3 sunlit; + vec3 amblit; + vec3 additive; + vec3 atten; + calcAtmosphericVarsLinear(pos.xyz, wavef, vary_light_dir, sunlit, amblit, additive, atten); + + calculateFresnelFactors(df3, df2, normalize(view.xyz), wave1, wave2, wave3, wavef); + + vec3 waver = wavef*3.0; vec3 up = transform_normal(vec3(0,0,1)); - float vdu = -dot(viewVec, up)*2; + float vdu = -dot(viewVec, up)*2.0; - vec3 wave_ibl = wavef; + vec3 wave_ibl = wavef * normScale; wave_ibl.z *= 2.0; wave_ibl = transform_normal(normalize(wave_ibl)); vec3 norm = transform_normal(normalize(wavef)); - vdu = clamp(vdu, 0, 1); - wavef.z *= max(vdu*vdu*vdu, 0.1); + vdu = clamp(vdu, 0.0, 1.0); + //wavef.z *= max(vdu*vdu*vdu, 0.1); wavef = normalize(wavef); @@ -194,62 +244,71 @@ void main() float dist2 = dist; dist = max(dist, 5.0); - float dmod = sqrt(dist); - //figure out distortion vector (ripply) - vec2 distort2 = distort + waver.xy * refScale / max(dmod, 1.0); + vec2 distort2 = distort + waver.xy * refScale / max(dmod, 1.0) * 2.0; distort2 = clamp(distort2, vec2(0), vec2(0.999)); - vec3 sunlit; - vec3 amblit; - vec3 additive; - vec3 atten; - float shadow = 1.0f; + float water_mask = texture(exclusionTex, distort).r; + #ifdef HAS_SUN_SHADOW shadow = sampleDirectionalShadow(pos.xyz, norm.xyz, distort); #endif - calcAtmosphericVarsLinear(pos.xyz, wavef, vary_light_dir, sunlit, amblit, additive, atten); + vec3 sunlit_linear = sunlit; + float fade = 1.0; +#ifdef TRANSPARENT_WATER + float depth = texture(depthMap, distort).r; - vec3 sunlit_linear = srgb_to_linear(sunlit); + vec3 refPos = getPositionWithNDC(vec3(distort*2.0-vec2(1.0), depth*2.0-1.0)); -#ifdef TRANSPARENT_WATER - vec4 fb = texture(screenTex, distort2); - float depth = texture(depthMap, distort2).r; - vec3 refPos = getPositionWithNDC(vec3(distort2*2.0-vec2(1.0), depth*2.0-1.0)); + // Calculate some distance fade in the water to better assist with refraction blending and reducing the refraction texture's "disconnect". +#ifdef SHORELINE_FADE + fade = max(0.0,min(1.0, (pos.z - refPos.z) / 10.0)); +#else + fade = 1.0; +#endif + fade *= water_mask; + distort2 = mix(distort, distort2, min(1.0, fade * 10.0)); + depth = texture(depthMap, distort2).r; + + refPos = getPositionWithNDC(vec3(distort2 * 2.0 - vec2(1.0), depth * 2.0 - 1.0)); - if (refPos.z > pos.z-0.05) + if (pos.z < refPos.z - 0.05) { - //we sampled an above water sample, don't distort distort2 = distort; - fb = texture(screenTex, distort2); - depth = texture(depthMap, distort2).r; - refPos = getPositionWithNDC(vec3(distort2 * 2.0 - vec2(1.0), depth * 2.0 - 1.0)); } + vec4 fb = texture(screenTex, distort2); + #else vec4 fb = applyWaterFogViewLinear(viewVec*2048.0, vec4(1.0)); -#endif - // fudge sample on other side of water to be a tad darker - fb.rgb *= 0.75; + if (water_mask < 1.0) + discard; +#endif - float metallic = 0.0; - float perceptualRoughness = 0.05; + float metallic = 1.0; + float perceptualRoughness = blurMultiplier; float gloss = 1.0 - perceptualRoughness; vec3 irradiance = vec3(0); vec3 radiance = vec3(0); - sampleReflectionProbesWater(irradiance, radiance, distort2, pos.xyz, wave_ibl.xyz, gloss, amblit); + vec3 legacyenv = vec3(0); - irradiance = vec3(0); + // TODO: Make this an option. +#ifdef WATER_MINIMAL + sampleReflectionProbesWater(irradiance, radiance, distort2, pos.xyz, wave_ibl.xyz, gloss, amblit); +#elif WATER_MINIMAL_PLUS + sampleReflectionProbes(irradiance, radiance, distort2, pos.xyz, wave_ibl.xyz, gloss, false, amblit); +#endif vec3 diffuseColor = vec3(0); vec3 specularColor = vec3(0); - calcDiffuseSpecular(vec3(1), metallic, diffuseColor, specularColor); + vec3 specular_linear = srgb_to_linear(specular); + calcDiffuseSpecular(specular_linear, metallic, diffuseColor, specularColor); vec3 v = -normalize(pos.xyz); @@ -257,46 +316,36 @@ void main() float ao = 1.0; vec3 light_dir = transform_normal(lightDir); - perceptualRoughness = 0.0; - metallic = 1.0; - float NdotV = clamp(abs(dot(norm, v)), 0.001, 1.0); - float nl = 0; + float nl = 0.0; vec3 diffPunc = vec3(0); vec3 specPunc = vec3(0); - pbrPunctual(vec3(0), specularColor, 0.1, metallic, normalize(wavef+up*max(dist, 32.0)/32.0*(1.0-vdu)), v, normalize(light_dir), nl, diffPunc, specPunc); - - vec3 punctual = clamp(nl * (diffPunc + specPunc), vec3(0), vec3(10)); - - vec3 color = punctual * sunlit_linear * 2.75 * shadow; - vec3 iblDiff; - vec3 iblSpec; - pbrIbl(vec3(0), vec3(1), radiance, vec3(0), ao, NdotV, 0.0, iblDiff, iblSpec); - - color += iblDiff + iblSpec; + pbrPunctual(diffuseColor, specularColor, perceptualRoughness, metallic, normalize(wavef+up*max(dist, 32.0)/32.0*(1.0-vdu)), v, normalize(light_dir), nl, diffPunc, specPunc); - float nv = clamp(abs(dot(norm.xyz, v)), 0.001, 1.0); - vec2 brdf = BRDF(clamp(nv, 0, 1), 1.0); - float f = 1.0-brdf.y; //1.0 - (brdf.x+brdf.y); - f *= 0.9; - f *= f; + vec3 punctual = clamp(nl * (diffPunc + specPunc), vec3(0), vec3(10)) * sunlit_linear * shadow * atten; + radiance *= df2.y; + //radiance = toneMapNoExposure(radiance); + vec3 color = vec3(0); + color = mix(fb.rgb, radiance, min(1.0, df2.x)) + punctual.rgb; - // incoming scale is [0, 1] with 0.5 being default - // shift to 0.5 to 1.5 - f *= (fresnelScale - 0.5)+1.0; + float water_haze_scale = 4.0; - // incoming offset is [0, 1] with 0.5 being default - // shift from -1 to 1 - f += (fresnelOffset - 0.5) * 2.0; + if (classic_mode > 0) + water_haze_scale = 1.0; - f = clamp(f, 0, 1); + // This looks super janky, but we do this to restore water haze in the distance. + // These values were finagled in to try and bring back some of the distant brightening on legacy water. Also works reasonably well on PBR skies such as PBR midday. + // color = mix(color, additive * water_haze_scale, (1 - atten)); - color = ((1.0 - f) * color) + fb.rgb; + // We shorten the fade here at the shoreline so it doesn't appear too soft from a distance. + fade *= 60.0; + fade = min(1.0, fade); + color = mix(fb.rgb, color, fade); - float spec = min(max(max(punctual.r, punctual.g), punctual.b), 0.05); + float spec = min(max(max(punctual.r, punctual.g), punctual.b), 0.0); - frag_color = max(vec4(color, spec), vec4(0)); + frag_color = min(vec4(1),max(vec4(color.rgb, spec * water_mask), vec4(0))); } diff --git a/indra/newview/app_settings/toolbars.xml b/indra/newview/app_settings/toolbars.xml index a1c9d6d9ee..cd900b6c60 100644 --- a/indra/newview/app_settings/toolbars.xml +++ b/indra/newview/app_settings/toolbars.xml @@ -4,27 +4,24 @@ button_display_mode="icons_with_text"> <command name="chat"/> <command name="speak"/> - <command name="destinations"/> <command name="people"/> <command name="profile"/> - <command name="map"/> - <command name="move"/> <command name="view"/> - <command name="howto"/> + <command name="appearance"/> + <command name="inventory"/> </bottom_toolbar> <left_toolbar button_display_mode="icons_only"> - <command name="avatar"/> - <command name="appearance"/> - <command name="inventory"/> <command name="search"/> - <command name="places"/> - <command name="voice"/> + <command name="map"/> + <command name="build"/> <command name="minimap"/> <command name="snapshot"/> - <command name="performance"/> + <command name="aboutland"/> </left_toolbar> <right_toolbar button_display_mode="icons_only"> + <command name="performance"/> + <command name="howto"/> </right_toolbar> </toolbars> diff --git a/indra/newview/character/attentions.xml b/indra/newview/character/attentions.xml index be9a2b28fc..9bda3309ac 100644 --- a/indra/newview/character/attentions.xml +++ b/indra/newview/character/attentions.xml @@ -33,7 +33,7 @@ MOUSELOOK: Tracks center of view when in mouselook view mode. <param attention="hover" priority="4.0" timeout="1.0" /> <param attention="conversation" priority="0.0" timeout="-1" /> <param attention="select" priority="6.0" timeout="-1" /> - <param attention="focus" priority="6.0" timeout="-1" /> + <param attention="focus" priority="0.0" timeout="-1" /> <param attention="mouselook" priority="7.0" timeout="-1" /> </gender> <gender name="Feminine"> @@ -44,7 +44,7 @@ MOUSELOOK: Tracks center of view when in mouselook view mode. <param attention="hover" priority="4.0" timeout="1.0" /> <param attention="conversation" priority="0.0" timeout="-1" /> <param attention="select" priority="6.0" timeout="-1" /> - <param attention="focus" priority="6.0" timeout="-1" /> + <param attention="focus" priority="0.0" timeout="-1" /> <param attention="mouselook" priority="7.0" timeout="-1" /> </gender> </linden_attentions> diff --git a/indra/newview/featuretable.txt b/indra/newview/featuretable.txt index d894e1b24e..1090dd8ffb 100644 --- a/indra/newview/featuretable.txt +++ b/indra/newview/featuretable.txt @@ -1,4 +1,4 @@ -version 73 +version 74 // The version number above should be incremented IF AND ONLY IF some // change has been made that is sufficiently important to justify // resetting the graphics preferences of all users to the recommended @@ -85,6 +85,8 @@ RenderExposure 1 4 RenderTonemapType 1 1 RenderTonemapMix 1 1 RenderDisableVintageMode 1 1 +RenderMaxTextureResolution 1 2048 +RenderReflectionProbeCount 1 256 // // Low Graphics Settings @@ -126,6 +128,8 @@ RenderExposure 1 1 RenderTonemapType 1 1 RenderTonemapMix 1 0.7 RenderDisableVintageMode 1 0 +RenderMaxTextureResolution 1 512 +RenderReflectionProbeCount 1 1 // // Medium Low Graphics Settings @@ -167,6 +171,8 @@ RenderExposure 1 1 RenderTonemapType 1 1 RenderTonemapMix 1 0.7 RenderDisableVintageMode 1 0 +RenderMaxTextureResolution 1 1024 +RenderReflectionProbeCount 1 32 // // Medium Graphics Settings (standard) @@ -207,6 +213,8 @@ RenderCASSharpness 1 0 RenderExposure 1 1 RenderTonemapType 1 1 RenderTonemapMix 1 0.7 +RenderMaxTextureResolution 1 2048 +RenderReflectionProbeCount 1 64 // // Medium High Graphics Settings @@ -237,7 +245,7 @@ RenderFSAASamples 1 1 RenderReflectionsEnabled 1 1 RenderReflectionProbeDetail 1 1 RenderScreenSpaceReflections 1 0 -RenderReflectionProbeLevel 1 2 +RenderReflectionProbeLevel 1 1 RenderMirrors 1 0 RenderHeroProbeResolution 1 512 RenderHeroProbeDistance 1 6 @@ -247,6 +255,8 @@ RenderCASSharpness 1 0 RenderExposure 1 1 RenderTonemapType 1 1 RenderTonemapMix 1 0.7 +RenderMaxTextureResolution 1 2048 +RenderReflectionProbeCount 1 64 // // High Graphics Settings (SSAO + sun shadows) @@ -277,7 +287,7 @@ RenderFSAASamples 1 2 RenderReflectionsEnabled 1 1 RenderReflectionProbeDetail 1 1 RenderScreenSpaceReflections 1 0 -RenderReflectionProbeLevel 1 3 +RenderReflectionProbeLevel 1 2 RenderMirrors 1 0 RenderHeroProbeResolution 1 512 RenderHeroProbeDistance 1 8 @@ -287,6 +297,8 @@ RenderCASSharpness 1 0.4 RenderExposure 1 1 RenderTonemapType 1 1 RenderTonemapMix 1 0.7 +RenderMaxTextureResolution 1 2048 +RenderReflectionProbeCount 1 128 // // High Ultra Graphics Settings (deferred + SSAO + all shadows) @@ -327,6 +339,8 @@ RenderCASSharpness 1 0.4 RenderExposure 1 1 RenderTonemapType 1 1 RenderTonemapMix 1 0.7 +RenderMaxTextureResolution 1 2048 +RenderReflectionProbeCount 1 256 // // Ultra graphics (REALLY PURTY!) @@ -367,6 +381,8 @@ RenderCASSharpness 1 0.4 RenderExposure 1 1 RenderTonemapType 1 1 RenderTonemapMix 1 0.7 +RenderMaxTextureResolution 1 2048 +RenderReflectionProbeCount 1 256 // // Class Unknown Hardware (unknown) @@ -399,6 +415,8 @@ RenderShadowDetail 0 0 RenderReflectionProbeDetail 0 -1 RenderMirrors 0 0 RenderDisableVintageMode 1 0 +RenderMaxTextureResolution 1 2048 +RenderReflectionProbeCount 0 0 list Intel RenderAnisotropic 1 0 @@ -420,6 +438,7 @@ RenderMirrors 0 0 RenderGLMultiThreadedTextures 0 0 RenderGLMultiThreadedMedia 0 0 RenderDisableVintageMode 1 0 +RenderReflectionProbeCount 0 0 list TexUnit16orLess RenderTerrainPBRDetail 1 -1 diff --git a/indra/newview/featuretable_mac.txt b/indra/newview/featuretable_mac.txt index cfcd96d650..3233afc28d 100644 --- a/indra/newview/featuretable_mac.txt +++ b/indra/newview/featuretable_mac.txt @@ -1,4 +1,4 @@ -version 72 +version 73 // The version number above should be incremented IF AND ONLY IF some // change has been made that is sufficiently important to justify // resetting the graphics preferences of all users to the recommended @@ -85,39 +85,41 @@ RenderTonemapType 1 1 RenderTonemapMix 1 1 RenderDisableVintageMode 1 1 RenderDownScaleMethod 1 0 +RenderMaxTextureResolution 1 2048 +RenderReflectionProbeCount 1 256 // // Low Graphics Settings // list Low RenderAnisotropic 1 0 -RenderAvatarLODFactor 1 0 -RenderAvatarPhysicsLODFactor 1 0 +RenderAvatarLODFactor 1 0.5 +RenderAvatarMaxComplexity 1 35000 +RenderAvatarPhysicsLODFactor 1 0.5 RenderAvatarMaxNonImpostors 1 3 -RenderAvatarMaxComplexity 1 35000 RenderFarClip 1 64 -RenderFlexTimeFactor 1 0 +RenderFlexTimeFactor 1 1.0 RenderGlowResolutionPow 1 8 -RenderLocalLightCount 1 8 -RenderMaxPartCount 1 0 -RenderTerrainDetail 1 0 -RenderTerrainLODFactor 1 1 -RenderTerrainPBRDetail 1 -4 +RenderMaxPartCount 1 512 +RenderLocalLightCount 1 256 +RenderTerrainDetail 1 1 +RenderTerrainLODFactor 1 1.0 +RenderTerrainPBRDetail 1 -1 RenderTerrainPBRPlanarSampleCount 1 1 RenderTransparentWater 1 0 -RenderTreeLODFactor 1 0 +RenderTreeLODFactor 1 0.5 RenderVolumeLODFactor 1 1.125 RenderDeferredSSAO 1 0 RenderShadowDetail 1 0 WLSkyDetail 1 96 RenderFSAAType 1 0 RenderFSAASamples 1 0 -RenderReflectionsEnabled 1 0 +RenderReflectionsEnabled 1 1 RenderReflectionProbeDetail 1 0 RenderScreenSpaceReflections 1 0 RenderReflectionProbeLevel 1 0 RenderMirrors 1 0 -RenderHeroProbeResolution 1 256 +RenderHeroProbeResolution 1 64 RenderHeroProbeDistance 1 4 RenderHeroProbeUpdateRate 1 6 RenderHeroProbeConservativeUpdateMultiplier 1 16 @@ -126,6 +128,9 @@ RenderExposure 1 1 RenderTonemapType 1 1 RenderTonemapMix 1 0.7 RenderDisableVintageMode 1 0 +RenderMaxTextureResolution 1 512 +RenderReflectionProbeCount 1 8 + // // Medium Low Graphics Settings @@ -167,6 +172,8 @@ RenderExposure 1 1 RenderTonemapType 1 1 RenderTonemapMix 1 0.7 RenderDisableVintageMode 1 0 +RenderMaxTextureResolution 1 1024 +RenderReflectionProbeCount 1 32 // // Medium Graphics Settings (standard) @@ -207,6 +214,8 @@ RenderCASSharpness 1 0 RenderExposure 1 1 RenderTonemapType 1 1 RenderTonemapMix 1 0.7 +RenderMaxTextureResolution 1 2048 +RenderReflectionProbeCount 1 64 // // Medium High Graphics Settings @@ -247,6 +256,8 @@ RenderCASSharpness 1 0 RenderExposure 1 1 RenderTonemapType 1 1 RenderTonemapMix 1 0.7 +RenderMaxTextureResolution 1 2048 +RenderReflectionProbeCount 1 64 // // High Graphics Settings (SSAO + sun shadows) @@ -287,6 +298,8 @@ RenderCASSharpness 1 0 RenderExposure 1 1 RenderTonemapType 1 1 RenderTonemapMix 1 0.7 +RenderMaxTextureResolution 1 2048 +RenderReflectionProbeCount 1 128 // // High Ultra Graphics Settings (SSAO + all shadows) @@ -327,6 +340,8 @@ RenderCASSharpness 1 0.4 RenderExposure 1 1 RenderTonemapType 1 1 RenderTonemapMix 1 0.7 +RenderMaxTextureResolution 1 2048 +RenderReflectionProbeCount 1 256 // // Ultra graphics (REALLY PURTY!) @@ -367,6 +382,8 @@ RenderCASSharpness 1 0.4 RenderExposure 1 1 RenderTonemapType 1 1 RenderTonemapMix 1 0.7 +RenderMaxTextureResolution 1 2048 +RenderReflectionProbeCount 1 256 // // Class Unknown Hardware (unknown) @@ -398,6 +415,8 @@ RenderDeferredSSAO 0 0 RenderShadowDetail 0 0 RenderMirrors 0 0 RenderDisableVintageMode 1 0 +RenderMaxTextureResolution 1 2048 +RenderReflectionProbeCount 0 0 list TexUnit8orLess RenderDeferredSSAO 0 0 @@ -438,6 +457,7 @@ RenderReflectionProbeDetail 0 0 RenderReflectionsEnabled 0 0 RenderMirrors 0 0 RenderDisableVintageMode 1 0 +RenderReflectionProbeCount 0 0 list VaryingVectors16orLess RenderTerrainPBRPlanarSampleCount 1 1 diff --git a/indra/newview/fsfloatersearch.cpp b/indra/newview/fsfloatersearch.cpp new file mode 100644 index 0000000000..7e0a873452 --- /dev/null +++ b/indra/newview/fsfloatersearch.cpp @@ -0,0 +1,3212 @@ +/** + * @file fsfloatersearch.cpp + * @brief Firestorm Search Floater + * + * $LicenseInfo:firstyear=2012&license=fsviewerlgpl$ + * Phoenix Firestorm Viewer Source Code + * Copyright (C) 2012, Cinder Roxley <cinder.roxley@phoenixviewer.com> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * The Phoenix Firestorm Project, Inc., 1831 Oakwood Drive, Fairmont, Minnesota 56031-3225 USA + * http://www.firestormviewer.org + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" + +#include "fsfloatersearch.h" + +#include "lldispatcher.h" +#include "llagent.h" +#include "llavataractions.h" +#include "llavatarname.h" +#include "llavatarnamecache.h" +#include "llavatarpropertiesprocessor.h" +#include "llclassifiedflags.h" +#include "llclassifiedinfo.h" +#include "llcombobox.h" +#include "lldateutil.h" +#include "lleventflags.h" +#include "lleventnotifier.h" +#include "llfloaterreg.h" +#include "llfloaterworldmap.h" +#include "llgroupactions.h" +#include "llgroupmgr.h" +#include "llloadingindicator.h" +#include "lllogininstance.h" +#include "llnotificationsutil.h" +#include "llpanelprofile.h" +#include "llpanelprofileclassifieds.h" +#include "llparcel.h" +#include "llproductinforequest.h" +#include "llqueryflags.h" +#include "llregionhandle.h" +#include "llremoteparcelrequest.h" +#include "lltimer.h" +#include "lltrans.h" +#include "llviewercontrol.h" +#include "llviewergenericmessage.h" +#include "llviewernetwork.h" +#include "llviewerregion.h" +#include "llworldmapmessage.h" +#include "message.h" +#include <boost/tokenizer.hpp> +#include <boost/algorithm/string.hpp> +#include <string> + +#include <chrono> + +static const S32 MIN_SEARCH_STRING_SIZE = 2; +static const S32 RESULT_PAGE_SIZE = 100; + +// (observeur) Hack to avoid Find to be called several times (due to a bug in llsearchcombobox) +static std::chrono::time_point<std::chrono::system_clock> lastRequestTime; +static const S32 REQUEST_MIN_ELAPSED_TIME = 500; + +std::string filterShortWords(std::string query_string); +void fillSearchComboBox(LLSearchComboBox* search_combo); + +//////////////////////////////////////// +// Observer Classes // +//////////////////////////////////////// + +class FSSearchRemoteParcelInfoObserver : public LLRemoteParcelInfoObserver +{ +public: + FSSearchRemoteParcelInfoObserver(FSFloaterSearch* floater, bool for_events) : LLRemoteParcelInfoObserver(), + mParent(floater), + mForEvents(for_events) + {} + + ~FSSearchRemoteParcelInfoObserver() + { + // remove any in-flight observers + std::set<LLUUID>::iterator it; + for (it = mParcelIDs.begin(); it != mParcelIDs.end(); ++it) + { + const LLUUID &id = *it; + LLRemoteParcelInfoProcessor::getInstance()->removeObserver(id, this); + } + mParcelIDs.clear(); + } + + /*virtual*/ void processParcelInfo(const LLParcelData& parcel_data) + { + if (mParent) + { + if (mForEvents) + { + mParent->displayEventParcelImage(parcel_data); + } + else + { + mParent->displayParcelDetails(parcel_data); + } + } + mParcelIDs.erase(parcel_data.parcel_id); + LLRemoteParcelInfoProcessor::getInstance()->removeObserver(parcel_data.parcel_id, this); + } + + /*virtual*/ void setParcelID(const LLUUID& parcel_id) + { + if (!parcel_id.isNull()) + { + mParcelIDs.insert(parcel_id); + LLRemoteParcelInfoProcessor::getInstance()->addObserver(parcel_id, this); + LLRemoteParcelInfoProcessor::getInstance()->sendParcelInfoRequest(parcel_id); + } + } + + /*virtual*/ void setErrorStatus(S32 status, const std::string& reason) + { + LL_WARNS("Search") << "Can't complete remote parcel request. Http Status: " << status << ". Reason : " << reason << LL_ENDL; + } +private: + std::set<LLUUID> mParcelIDs; + FSFloaterSearch* mParent; + bool mForEvents; +}; + +///// Avatar Properties Observer ///// + +class FSSearchAvatarPropertiesObserver : public LLAvatarPropertiesObserver +{ +public: + FSSearchAvatarPropertiesObserver(FSFloaterSearch* floater) : LLAvatarPropertiesObserver(), + mParent(floater) + {} + + ~FSSearchAvatarPropertiesObserver() + { + // remove any in-flight observers + std::set<LLUUID>::iterator it; + for (it = mAvatarIDs.begin(); it != mAvatarIDs.end(); ++it) + { + const LLUUID &id = *it; + LLAvatarPropertiesProcessor::getInstance()->removeObserver(id, this); + } + mAvatarIDs.clear(); + } + + void processProperties(void* data, EAvatarProcessorType type) + { + if (!data) + return; + + if (APT_PROPERTIES == type) + { + LLAvatarData* avatar_data = static_cast<LLAvatarData*>(data); + if (avatar_data) + { + mParent->displayAvatarDetails(avatar_data); + LLAvatarPropertiesProcessor::getInstance()->removeObserver(avatar_data->avatar_id, this); + } + } + else if (APT_PROPERTIES_LEGACY == type) + { + LLAvatarData avatar_data(*static_cast<LLAvatarLegacyData*>(data)); + mParent->displayAvatarDetails(&avatar_data); + LLAvatarPropertiesProcessor::getInstance()->removeObserver(avatar_data.avatar_id, this); + } + if (APT_CLASSIFIED_INFO == type) + { + LLAvatarClassifiedInfo* c_info = static_cast<LLAvatarClassifiedInfo*>(data); + if (c_info) + { + mParent->displayClassifiedDetails(c_info); + LLAvatarPropertiesProcessor::getInstance()->removeObserver(c_info->classified_id, this); + std::string url = gAgent.getRegionCapability("SearchStatRequest"); + if (!url.empty()) + { + LL_INFOS("Search") << "Classified stat request via capability" << LL_ENDL; + LLSD body; + body["classified_id"] = c_info->classified_id; + LLCoreHttpUtil::HttpCoroutineAdapter::callbackHttpPost(url, body, boost::bind(&LLPanelProfileClassified::handleSearchStatResponse, c_info->classified_id, _1)); + } + } + } + } +private: + std::set<LLUUID> mAvatarIDs; + FSFloaterSearch* mParent; +}; + +///// Group Info Observer ///// + +class FSSearchGroupInfoObserver : public LLGroupMgrObserver +{ +public: + FSSearchGroupInfoObserver(const LLUUID& group_id, FSFloaterSearch* parent) : + LLGroupMgrObserver(group_id), + mParent(parent) + { + LLGroupMgr* groupmgr = LLGroupMgr::getInstance(); + if (!group_id.isNull() && groupmgr) + { + groupmgr->addObserver(this); + mID = group_id; + groupmgr->sendGroupPropertiesRequest(group_id); + } + } + + ~FSSearchGroupInfoObserver() + { + LLGroupMgr::getInstance()->removeObserver(this); + } + + void changed(LLGroupChange gc) + { + if (gc == GC_PROPERTIES) + { + LLGroupMgrGroupData* group_data = LLGroupMgr::getInstance()->getGroupData(mID); + mParent->displayGroupDetails(group_data); + LLGroupMgr::getInstance()->removeObserver(this); + } + } +private: + FSFloaterSearch* mParent; + LLUUID mID; +}; + +///// Silly Classified Clickthrough Class ///// +class FSDispatchClassifiedClickThrough : public LLDispatchHandler +{ +public: + virtual bool operator()( + const LLDispatcher* dispatcher, + const std::string& key, + const LLUUID& invoice, + const sparam_t& strings) + { + if (strings.size() != 4) return false; + LLUUID classified_id(strings[0]); + S32 teleport_clicks = atoi(strings[1].c_str()); + S32 map_clicks = atoi(strings[2].c_str()); + S32 profile_clicks = atoi(strings[3].c_str()); + + LLPanelProfileClassified::setClickThrough( + classified_id, teleport_clicks, map_clicks, profile_clicks, false); + + return true; + } +}; +static FSDispatchClassifiedClickThrough sClassifiedClickThrough; + +SearchQuery::SearchQuery() +: category("category", "") +, query("query") +{} + +//////////////////////////////////////// +// The floater itself // +//////////////////////////////////////// + +FSFloaterSearch::FSFloaterSearch(const Params& key) +: LLFloater(key) +{ + mRemoteParcelObserver = new FSSearchRemoteParcelInfoObserver(this, false); + mRemoteParcelEventLocationObserver = new FSSearchRemoteParcelInfoObserver(this, true); + mAvatarPropertiesObserver = new FSSearchAvatarPropertiesObserver(this); + mEventNotifierConnection = gEventNotifier.setNewEventCallback(boost::bind(&FSFloaterSearch::displayEventDetails, this, boost::placeholders::_1)); +} + +FSFloaterSearch::~FSFloaterSearch() +{ + mEventNotifierConnection.disconnect(); + delete mRemoteParcelObserver; + delete mRemoteParcelEventLocationObserver; + delete mAvatarPropertiesObserver; + gGenericDispatcher.addHandler("classifiedclickthrough", nullptr); +} + +// virtual +void FSFloaterSearch::onOpen(const LLSD& key) +{ + Params p(key); + mPanelWeb->loadURL(p.search); + if (key.has("query")) + { + mTabContainer->selectTabPanel(mPanelWeb); + } + else if (key.has("tab") && key["tab"].asString() == "groups") + { + mTabContainer->selectTabPanel(mPanelGroups); + } + + FSSearchPanelBase* current_panel = dynamic_cast<FSSearchPanelBase*>(mTabContainer->getCurrentPanel()); + if (current_panel) + { + current_panel->focusDefaultElement(); + } +} + +//virtual +void FSFloaterSearch::onClose(bool app_quitting) +{ + if (mTabContainer) + { + gSavedSettings.setS32("FSLastSearchTab", mTabContainer->getCurrentPanelIndex()); + } +} + +bool FSFloaterSearch::postBuild() +{ + childSetAction("people_profile_btn", boost::bind(&FSFloaterSearch::onBtnPeopleProfile, this)); + childSetAction("people_message_btn", boost::bind(&FSFloaterSearch::onBtnPeopleIM, this)); + childSetAction("people_friend_btn", boost::bind(&FSFloaterSearch::onBtnPeopleFriend, this)); + childSetAction("group_profile_btn", boost::bind(&FSFloaterSearch::onBtnGroupProfile, this)); + childSetAction("group_message_btn", boost::bind(&FSFloaterSearch::onBtnGroupChat, this)); + childSetAction("group_join_btn", boost::bind(&FSFloaterSearch::onBtnGroupJoin, this)); + childSetAction("event_reminder_btn", boost::bind(&FSFloaterSearch::onBtnEventReminder, this)); + childSetAction("teleport_btn", boost::bind(&FSFloaterSearch::onBtnTeleport, this)); + childSetAction("map_btn", boost::bind(&FSFloaterSearch::onBtnMap, this)); + resetVerbs(); + + mPanelPeople = findChild<FSPanelSearchPeople>("panel_ls_people"); + mPanelGroups = findChild<FSPanelSearchGroups>("panel_ls_groups"); + mPanelPlaces = findChild<FSPanelSearchPlaces>("panel_ls_places"); + mPanelEvents = findChild<FSPanelSearchEvents>("panel_ls_events"); + mPanelLand = findChild<FSPanelSearchLand>("panel_ls_land"); + mPanelClassifieds = findChild<FSPanelSearchClassifieds>("panel_ls_classifieds"); + mPanelWeb = findChild<FSPanelSearchWeb>("panel_ls_web"); + + mDetailsPanel = getChild<LLPanel>("panel_ls_details"); + mDetailTitle = getChild<LLTextEditor>("title"); + mDetailDesc = getChild<LLTextEditor>("desc"); + mDetailAux1 = getChild<LLTextEditor>("aux1"); + mDetailAux2 = getChild<LLTextEditor>("aux2"); + mDetailLocation = getChild<LLTextEditor>("location"); + mDetailSnapshot = getChild<LLTextureCtrl>("snapshot"); + mDetailSnapshotParcel = getChild<LLTextureCtrl>("snapshot_parcel"); + mDetailMaturity = getChild<LLIconCtrl>("maturity_icon"); + mTabContainer = getChild<LLTabContainer>("ls_tabs"); + + mTabContainer->setCommitCallback(boost::bind(&FSFloaterSearch::onTabChange, this)); + + flushDetails(); + + mDetailsPanel->setVisible(false); + + mHasSelection = false; + + if (!mTabContainer->selectTab(gSavedSettings.getS32("FSLastSearchTab"))) + { + mTabContainer->selectFirstTab(); + } + + return TRUE; +} + +void FSFloaterSearch::onTabChange() +{ + LL_INFOS() << "onTabChange()()" << LL_ENDL; + + flushDetails(); + + LLPanel* active_panel = mTabContainer->getCurrentPanel(); + + if (active_panel == mPanelWeb) + { + mDetailsPanel->setVisible(false); + mPanelWeb->resetFocusOnLoad(); + } + else if (active_panel == mPanelPeople) + { + mDetailsPanel->setVisible(mHasSelection); + } + + if (active_panel == mPanelPeople || active_panel == mPanelGroups) + { + mDetailSnapshotParcel->setVisible(FALSE); + mDetailSnapshot->setVisible(TRUE); + } + else if (active_panel == mPanelPlaces || active_panel == mPanelLand || + active_panel == mPanelEvents || active_panel == mPanelClassifieds) + { + mDetailSnapshot->setVisible(FALSE); + mDetailSnapshotParcel->setVisible(TRUE); + } +} + +//static +template <class T> +T* FSFloaterSearch::getSearchPanel(const std::string& panel_name) +{ + FSFloaterSearch* search_instance = LLFloaterReg::findTypedInstance<FSFloaterSearch>("search"); + if (search_instance && search_instance->mTabContainer) + { + return dynamic_cast<T*>(search_instance->mTabContainer->getPanelByName(panel_name)); + } + else + { + return nullptr; + } +} + +void FSFloaterSearch::onSelectedItem(const LLUUID& selected_item, ESearchCategory type) +{ + LL_INFOS() << "onSelectedItem()" << LL_ENDL; + + if (!selected_item.isNull()) + { + mSelectedID = selected_item; + resetVerbs(); + flushDetails(); + switch (type) + { + case SC_AVATAR: + { + LLAvatarPropertiesProcessor::getInstance()->addObserver(selected_item, mAvatarPropertiesObserver); + LLAvatarPropertiesProcessor::getInstance()->sendAvatarPropertiesRequest(selected_item); + } + break; + case SC_GROUP: + mGroupPropertiesRequest = new FSSearchGroupInfoObserver(selected_item, this); + break; + case SC_PLACE: + mRemoteParcelObserver->setParcelID(selected_item); + break; + case SC_CLASSIFIED: + LLAvatarPropertiesProcessor::getInstance()->addObserver(selected_item, mAvatarPropertiesObserver); + LLAvatarPropertiesProcessor::getInstance()->sendClassifiedInfoRequest(selected_item); + gGenericDispatcher.addHandler("classifiedclickthrough", &sClassifiedClickThrough); + break; + } + setLoadingProgress(true); + } +} + +void FSFloaterSearch::onSelectedEvent(const S32 selected_event) +{ + LL_INFOS() << "onSelectedEvent()()" << LL_ENDL; + + resetVerbs(); + flushDetails(); + + gMessageSystem->newMessageFast(_PREHASH_EventInfoRequest); + gMessageSystem->nextBlockFast(_PREHASH_AgentData); + gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgentID); + gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgentSessionID); + gMessageSystem->nextBlockFast(_PREHASH_EventData); + gMessageSystem->addU32Fast(_PREHASH_EventID, selected_event); + gAgent.sendReliableMessage(); +} + +void FSFloaterSearch::displayParcelDetails(const LLParcelData& parcel_data) +{ + S32 region_x; + S32 region_y; + S32 region_z; + region_x = ll_round(parcel_data.global_x) % REGION_WIDTH_UNITS; + region_y = ll_round(parcel_data.global_y) % REGION_WIDTH_UNITS; + region_z = ll_round(parcel_data.global_z); + // HACK: Flag 0x2 == adult region, + // Flag 0x1 == mature region, otherwise assume PG + if (parcel_data.flags & 0x2) + { + mDetailMaturity->setValue("Parcel_R_Dark"); + } + else if (parcel_data.flags & 0x1) + { + mDetailMaturity->setValue("Parcel_M_Dark"); + } + else + { + mDetailMaturity->setValue("Parcel_PG_Dark"); + } + + LLStringUtil::format_map_t map; + map["DWELL"] = llformat("%.0f", (F64)parcel_data.dwell); + map["AREA"] = llformat("%d m²", parcel_data.actual_area); + map["LOCATION"] = llformat("%s (%d, %d, %d)", parcel_data.sim_name.c_str(), region_x, region_y, region_z); + + mParcelGlobal = LLVector3d(parcel_data.global_x, parcel_data.global_y, parcel_data.global_z); + mDetailsPanel->setVisible(mTabContainer->getCurrentPanel()->getName() == "panel_ls_places" || mTabContainer->getCurrentPanel()->getName() == "panel_ls_land"); + mHasSelection = true; + mDetailMaturity->setVisible(true); + mDetailTitle->setValue(parcel_data.name); + mDetailDesc->setValue(parcel_data.desc); + mDetailAux1->setValue(getString("string.traffic", map)); + mDetailAux2->setValue(getString("string.area", map)); + mDetailLocation->setValue(getString("string.location", map)); + mDetailSnapshotParcel->setValue(parcel_data.snapshot_id); + childSetVisible("teleport_btn", true); + childSetVisible("map_btn", true); + setLoadingProgress(false); +} + +void FSFloaterSearch::displayAvatarDetails(LLAvatarData* avatar_data) +{ + if (avatar_data) + { + LLStringUtil::format_map_t map; + map["AGE"] = LLDateUtil::ageFromDate(avatar_data->born_on, LLDate::now()); + if (avatar_data->partner_id.notNull()) + { + map["PARTNER"] = LLSLURL("agent", avatar_data->partner_id, "inspect").getSLURLString(); + mDetailAux2->setValue(getString("string.partner", map)); + } + + mDetailsPanel->setVisible(mTabContainer->getCurrentPanel()->getName() == "panel_ls_people"); + mHasSelection = true; + mDetailTitle->setValue(LLTrans::getString("LoadingData")); + mDetailDesc->setValue(avatar_data->about_text); + mDetailSnapshot->setValue(avatar_data->image_id); + mDetailAux1->setValue(avatar_data->hide_age ? "" : getString("string.age", map)); + LLAvatarNameCache::get(avatar_data->avatar_id, boost::bind(&FSFloaterSearch::avatarNameUpdatedCallback,this, _1, _2)); + childSetVisible("people_profile_btn", true); + childSetVisible("people_message_btn", true); + childSetVisible("people_friend_btn", true); + getChildView("people_friend_btn")->setEnabled(!LLAvatarActions::isFriend(avatar_data->avatar_id)); + } +} + +void FSFloaterSearch::displayGroupDetails(LLGroupMgrGroupData*& group_data) +{ + if (group_data) + { + LLStringUtil::format_map_t map; + map["MEMBER_COUNT"] = llformat("%d",group_data->mMemberCount); + map["FOUNDER"] = LLSLURL("agent", group_data->mFounderID, "inspect").getSLURLString(); + + mDetailsPanel->setVisible(mTabContainer->getCurrentPanel()->getName() == "panel_ls_groups"); + mHasSelection = true; + mDetailTitle->setValue(LLTrans::getString("LoadingData")); + mDetailDesc->setValue(group_data->mCharter); + mDetailSnapshot->setValue(group_data->mInsigniaID); + mDetailAux1->setValue(getString("string.members", map)); + mDetailAux2->setValue(getString("string.founder", map)); + LLGroupData agent_gdatap; + bool is_member = gAgent.getGroupData(getSelectedID(),agent_gdatap) || gAgent.isGodlike(); + bool join_btn_enabled = !is_member && group_data->mOpenEnrollment; + childSetVisible("group_profile_btn", true); + childSetVisible("group_message_btn", true); + childSetVisible("group_join_btn", true); + getChildView("group_join_btn")->setEnabled(join_btn_enabled); + getChildView("group_message_btn")->setEnabled(is_member); + gCacheName->getGroup(getSelectedID(), boost::bind(&FSFloaterSearch::groupNameUpdatedCallback, this, _1, _2, _3)); + } +} + +void FSFloaterSearch::displayClassifiedDetails(LLAvatarClassifiedInfo*& c_info) +{ + if (c_info) + { + if (c_info->flags & CLASSIFIED_FLAG_MATURE) + { + mDetailMaturity->setValue("Parcel_M_Dark"); + } + else + { + mDetailMaturity->setValue("Parcel_PG_Dark"); + } + + LLStringUtil::format_map_t map; + map["LISTING_PRICE"] = llformat("L$%d", c_info->price_for_listing); + map["SLURL"] = LLSLURL("parcel", c_info->parcel_id, "about").getSLURLString(); + + mDetailsPanel->setVisible(mTabContainer->getCurrentPanel()->getName() == "panel_ls_classifieds"); + mHasSelection = true; + mDetailMaturity->setVisible(true); + mParcelGlobal = c_info->pos_global; + mDetailTitle->setValue(c_info->name); + mDetailDesc->setValue(c_info->description); + mDetailSnapshotParcel->setValue(c_info->snapshot_id); + mDetailAux1->setValue(getString("string.listing_price", map)); + mDetailLocation->setValue(getString("string.slurl", map)); + childSetVisible("teleport_btn", true); + childSetVisible("map_btn", true); + setLoadingProgress(false); + } +} + +bool FSFloaterSearch::displayEventDetails(LLEventStruct event) +{ + if (event.flags == EVENT_FLAG_ADULT) + { + mDetailMaturity->setValue("Parcel_R_Dark"); + } + else if (event.flags == EVENT_FLAG_MATURE) + { + mDetailMaturity->setValue("Parcel_M_Dark"); + } + else + { + mDetailMaturity->setValue("Parcel_PG_Dark"); + } + + S32 region_x; + S32 region_y; + S32 region_z; + region_x = (S64)ll_round(event.globalPos.mdV[VX]) % REGION_WIDTH_UNITS; + region_y = (S64)ll_round(event.globalPos.mdV[VY]) % REGION_WIDTH_UNITS; + region_z = (S32)ll_round(event.globalPos.mdV[VZ]); + LLStringUtil::format_map_t map; + map["DURATION"] = llformat("%d:%.2d", event.duration / 60, event.duration % 60); + map["LOCATION"] = llformat("%s (%d, %d, %d)", event.simName.c_str(), region_x, region_y, region_z); + if (event.cover > 0) + { + map["COVERCHARGE"] = llformat("L$%d", event.cover); + mDetailAux2->setValue(getString("string.covercharge", map)); + } + + mParcelGlobal = event.globalPos; + mEventID = event.eventId; + mDetailsPanel->setVisible(mTabContainer->getCurrentPanel()->getName() == "panel_ls_events"); + mHasSelection = true; + mDetailMaturity->setVisible(true); + mDetailTitle->setValue(event.eventName); + mDetailDesc->setValue(event.desc); + mDetailAux1->setValue(getString("string.duration", map)); + mDetailLocation->setValue(getString("string.location", map)); + mDetailSnapshotParcel->setValue(LLUUID::null); + childSetVisible("teleport_btn", true); + childSetVisible("map_btn", true); + childSetVisible("event_reminder_btn", true); + + LLWorldMapMessage::getInstance()->sendNamedRegionRequest(event.simName, boost::bind(&FSFloaterSearch::regionHandleCallback, this, _1, event.globalPos), "", false); + return true; +} + +void FSFloaterSearch::regionHandleCallback(U64 region_handle, LLVector3d pos_global) +{ + std::string url = gAgent.getRegionCapability("RemoteParcelRequest"); + if (!url.empty()) + { + auto region_origin = from_region_handle(region_handle); + LLVector3 pos_region(LLVector3(pos_global - region_origin)); + + LLRemoteParcelInfoProcessor::getInstance()->requestRegionParcelInfo(url, + LLUUID::null, pos_region, pos_global, mRemoteParcelEventLocationObserver->getObserverHandle()); + } + else + { + setLoadingProgress(false); + } +} + +void FSFloaterSearch::displayEventParcelImage(const LLParcelData& parcel_data) +{ + mDetailSnapshotParcel->setValue(parcel_data.snapshot_id); + setLoadingProgress(false); +} + +void FSFloaterSearch::avatarNameUpdatedCallback(const LLUUID& id, const LLAvatarName& av_name) +{ + if (id == getSelectedID()) + { + mDetailTitle->setValue(av_name.getCompleteName()); + setLoadingProgress(false); + } + // Otherwise possibly a request for an older selection, ignore it. +} + +void FSFloaterSearch::groupNameUpdatedCallback(const LLUUID& id, const std::string& name, bool is_group) +{ + if (id == getSelectedID()) + { + mDetailTitle->setValue( LLSD(name) ); + setLoadingProgress(false); + } + // Otherwise possibly a request for an older selection, ignore it. +} + +void FSFloaterSearch::setLoadingProgress(bool started) +{ + LLLoadingIndicator* indicator = getChild<LLLoadingIndicator>("loading"); + + indicator->setVisible(started); + + if (started) + { + indicator->start(); + } + else + { + indicator->stop(); + } +} + +void FSFloaterSearch::resetVerbs() +{ + childSetVisible("people_profile_btn", false); + childSetVisible("people_message_btn", false); + childSetVisible("people_friend_btn", false); + childSetVisible("group_profile_btn", false); + childSetVisible("group_message_btn", false); + childSetVisible("group_join_btn", false); + childSetVisible("event_reminder_btn", false); + childSetVisible("teleport_btn", false); + childSetVisible("map_btn", false); +} + +void FSFloaterSearch::flushDetails() +{ + LL_INFOS() << "flushDetails()" << LL_ENDL; + mDetailTitle->setValue(""); + mDetailDesc->setValue(""); + mDetailAux1->setValue(""); + mDetailAux2->setValue(""); + mDetailLocation->setValue(""); + mDetailSnapshot->setValue(LLSD()); + mDetailMaturity->setVisible(false); + mParcelGlobal.setZero(); +} + +void FSFloaterSearch::onBtnPeopleProfile() +{ + LLAvatarActions::showProfile(getSelectedID()); +} + +void FSFloaterSearch::onBtnPeopleIM() +{ + LLAvatarActions::startIM(getSelectedID()); +} + +void FSFloaterSearch::onBtnPeopleFriend() +{ + LLAvatarActions::requestFriendshipDialog(getSelectedID()); +} + +void FSFloaterSearch::onBtnGroupProfile() +{ + LLGroupActions::show(getSelectedID()); +} + +void FSFloaterSearch::onBtnGroupChat() +{ + LLGroupActions::startIM(getSelectedID()); +} + +void FSFloaterSearch::onBtnGroupJoin() +{ + LLGroupActions::join(getSelectedID()); +} + +void FSFloaterSearch::onBtnTeleport() +{ + if (!mParcelGlobal.isExactlyZero()) + { + gAgent.teleportViaLocationLookAt(mParcelGlobal); + LLFloaterWorldMap::getInstance()->trackLocation(mParcelGlobal); + /// <FS:CR> What should we do when when we teleport? The default (1) is to close the floater, + /// the user may elect to minimize the floater (2), or to do nothing (any other setting) + static LLCachedControl<U32> teleport_action(gSavedSettings, "FSLegacySearchActionOnTeleport"); + if (teleport_action == 1) + { + closeFloater(); + } + else if (teleport_action == 2) + { + setMinimized(TRUE); + } + } +} + +void FSFloaterSearch::onBtnMap() +{ + if (!mParcelGlobal.isExactlyZero()) + { + LLFloaterWorldMap::getInstance()->trackLocation(mParcelGlobal); + LLFloaterReg::showInstance("world_map", "center"); + } +} + +void FSFloaterSearch::onBtnEventReminder() +{ + gEventNotifier.add(mEventID); +} + +//////////////////////////////////////// +// People Search Panel // +//////////////////////////////////////// + +static LLPanelInjector<FSPanelSearchPeople> t_panel_fs_search_people("panel_ls_people"); + +FSPanelSearchPeople::FSPanelSearchPeople() : FSSearchPanelBase() +, mQueryID(nullptr) +, mStartSearch(0) +, mResultsReceived(0) +, mResultsContent() +, mAvatarNameCallbackConnection() +{ +} + +FSPanelSearchPeople::~FSPanelSearchPeople() +{ + if (mAvatarNameCallbackConnection.connected()) + { + mAvatarNameCallbackConnection.disconnect(); + } +} + +bool FSPanelSearchPeople::postBuild() +{ + mSearchComboBox = findChild<LLSearchComboBox>("people_edit"); + mSearchResults = findChild<LLScrollListCtrl>("search_results_people"); + if (mSearchComboBox) + { + mSearchComboBox->setCommitCallback(boost::bind(&FSPanelSearchPeople::onBtnFind, this)); + fillSearchComboBox(mSearchComboBox); + } + if (mSearchResults) + { + mSearchResults->setCommitCallback(boost::bind(&FSPanelSearchPeople::onSelectItem, this)); + mSearchResults->setEnabled(FALSE); + mSearchResults->setCommentText(LLTrans::getString("no_results")); + mSearchResults->setContextMenu(LLScrollListCtrl::MENU_AVATAR); + } + + childSetAction("people_next", boost::bind(&FSPanelSearchPeople::onBtnNext, this)); + childSetAction("people_back", boost::bind(&FSPanelSearchPeople::onBtnBack, this)); + getChildView("people_next")->setEnabled(FALSE); + getChildView("people_back")->setEnabled(FALSE); + + return TRUE; +} + +void FSPanelSearchPeople::focusDefaultElement() +{ + mSearchComboBox->focusTextEntry(); +} + +void FSPanelSearchPeople::find() +{ + std::string text = mSearchComboBox->getSimple(); + boost::trim(text); + + if (text.size() <= MIN_SEARCH_STRING_SIZE) + { + mSearchResults->setCommentText(LLTrans::getString("search_short")); + return; + } + + if (LLUUID::validate(text)) + { + LLUUID id(text); + + mSearchResults->deleteAllItems(); + mSearchResults->setCommentText(LLTrans::getString("searching")); + mResultsReceived = 0; + mNumResultsReturned = 0; + + if (mAvatarNameCallbackConnection.connected()) + { + mAvatarNameCallbackConnection.disconnect(); + } + mAvatarNameCallbackConnection = LLAvatarNameCache::get(id, boost::bind(&FSPanelSearchPeople::onAvatarNameCallback, this, _1, _2)); + + return; + } + + LLStringUtil::replaceChar(text, '.', ' '); + + mResultsReceived = 0; + if (mQueryID.notNull()) + { + mQueryID.setNull(); + } + mQueryID.generate(); + + if (mStartSearch < 0) + { + mStartSearch = 0; + } + + gMessageSystem->newMessage("DirFindQuery"); + gMessageSystem->nextBlock("AgentData"); + gMessageSystem->addUUID("AgentID", gAgentID); + gMessageSystem->addUUID("SessionID", gAgentSessionID); + gMessageSystem->nextBlock("QueryData"); + gMessageSystem->addUUID("QueryID", getQueryID()); + gMessageSystem->addString("QueryText", text); + gMessageSystem->addU32("QueryFlags", DFQ_PEOPLE); + gMessageSystem->addS32("QueryStart", mStartSearch); + gAgent.sendReliableMessage(); + LL_INFOS("Search") << "Firing off search request: " << getQueryID() << LL_ENDL; + + mSearchResults->deleteAllItems(); + mSearchResults->setCommentText(LLTrans::getString("searching")); + mNumResultsReturned = 0; +} + +void FSPanelSearchPeople::onBtnFind() +{ + std::chrono::time_point<std::chrono::system_clock> now = std::chrono::system_clock::now(); + auto elapsed = now - lastRequestTime; + U64 elapsedMS = std::chrono::duration_cast<std::chrono::milliseconds>(elapsed).count(); + if(elapsedMS < REQUEST_MIN_ELAPSED_TIME) return; + lastRequestTime = now; + + std::string text = mSearchComboBox->getSimple(); + + if (!text.empty()) + { + LLSearchHistory::getInstance()->addEntry(text); + } + + resetSearch(); + + find(); +} + +void FSPanelSearchPeople::onBtnNext() +{ + mStartSearch += RESULT_PAGE_SIZE; + getChildView("people_back")->setEnabled(TRUE); + + find(); +} + +void FSPanelSearchPeople::onBtnBack() +{ + mStartSearch -= RESULT_PAGE_SIZE; + getChildView("people_back")->setEnabled(mStartSearch > 0); + + find(); +} + +void FSPanelSearchPeople::resetSearch() +{ + mStartSearch = 0; + getChildView("people_back")->setEnabled(FALSE); + getChildView("people_next")->setEnabled(FALSE); +} + +S32 FSPanelSearchPeople::showNextButton(S32 rows) +{ + bool show_next_button = (mResultsReceived > RESULT_PAGE_SIZE); + getChildView("people_next")->setEnabled(show_next_button); + if (show_next_button) + { + rows -= (mResultsReceived - RESULT_PAGE_SIZE); + } + return rows; +} + +void FSPanelSearchPeople::onSelectItem() +{ + if (!mSearchResults) + { + return; + } + FSFloaterSearch* search_instance = LLFloaterReg::findTypedInstance<FSFloaterSearch>("search"); + if (search_instance) + { + search_instance->FSFloaterSearch::onSelectedItem(mSearchResults->getSelectedValue(), FSFloaterSearch::SC_AVATAR); + } +} + +// static +void FSPanelSearchPeople::processSearchReply(LLMessageSystem* msg, void**) +{ + LLUUID query_id; + std::string first_name; + std::string last_name; + LLUUID agent_id; + + msg->getUUIDFast(_PREHASH_QueryData, _PREHASH_QueryID, query_id); + msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_AgentID, agent_id); + + // This result is not for us. + if (agent_id != gAgentID) + { + return; + } + LL_INFOS("Search") << "received search results - QueryID: " << query_id << " AgentID: " << agent_id << LL_ENDL; + + FSPanelSearchPeople* self = FSFloaterSearch::getSearchPanel<FSPanelSearchPeople>("panel_ls_people"); + + // floater is closed or these are not results from our last request + if (!self || query_id != self->getQueryID()) + { + return; + } + + LLScrollListCtrl* search_results = self->getChild<LLScrollListCtrl>("search_results_people"); + + if (self->mNumResultsReturned++ == 0) + { + search_results->deleteAllItems(); + } + + // Check for status messages + if (msg->getNumberOfBlocks("StatusData")) + { + U32 status; + msg->getU32("StatusData", "Status", status); + if (status & STATUS_SEARCH_PLACES_FOUNDNONE) + { + LLStringUtil::format_map_t map; + map["[TEXT]"] = self->getChild<LLUICtrl>("people_edit")->getValue().asString(); + search_results->setEnabled(FALSE); + search_results->setCommentText(LLTrans::getString("not_found", map)); + return; + } + else if (status & STATUS_SEARCH_PLACES_SHORTSTRING) + { + search_results->setEnabled(FALSE); + search_results->setCommentText(LLTrans::getString("search_short")); + return; + } + else if (status & STATUS_SEARCH_PLACES_BANNEDWORD) + { + search_results->setEnabled(FALSE); + search_results->setCommentText(LLTrans::getString("search_banned")); + return; + } + else if (status & STATUS_SEARCH_PLACES_SEARCHDISABLED) + { + search_results->setEnabled(FALSE); + search_results->setCommentText(LLTrans::getString("search_disabled")); + return; + } + } + + bool found_one = false; + S32 num_new_rows = msg->getNumberOfBlocksFast(_PREHASH_QueryReplies); + if (num_new_rows == 0 && self->mResultsReceived == 0) + { + LLStringUtil::format_map_t map; + map["[TEXT]"] = self->getChild<LLUICtrl>("people_edit")->getValue().asString(); + search_results->setEnabled(FALSE); + search_results->setCommentText(LLTrans::getString("not_found", map)); + } + + self->mResultsReceived += num_new_rows; + num_new_rows = self->showNextButton(num_new_rows); + + for (S32 i = 0; i < num_new_rows; i++) + { + msg->getStringFast( _PREHASH_QueryReplies, _PREHASH_FirstName, first_name, i); + msg->getStringFast( _PREHASH_QueryReplies, _PREHASH_LastName, last_name, i); + msg->getUUIDFast( _PREHASH_QueryReplies, _PREHASH_AgentID, agent_id, i); + //msg->getU8Fast( _PREHASH_QueryReplies, _PREHASH_Online, online, i); + + if (agent_id.isNull()) + { + LL_INFOS("Search") << "Null result returned for QueryID: " << query_id << LL_ENDL; + LLStringUtil::format_map_t map; + map["[TEXT]"] = self->getChild<LLUICtrl>("people_edit")->getValue().asString(); + search_results->setEnabled(FALSE); + search_results->setCommentText(LLTrans::getString("not_found", map)); + } + else + { + LL_DEBUGS("Search") << "Got: " << first_name << " " << last_name << " AgentID: " << agent_id << LL_ENDL; + search_results->setEnabled(TRUE); + found_one = true; + + std::string avatar_name; + avatar_name = LLCacheName::buildFullName(first_name, last_name); + + LLSD content; + LLSD element; + + element["id"] = agent_id; + + element["columns"][0]["column"] = "icon"; + element["columns"][0]["type"] = "icon"; + element["columns"][0]["value"] = "icon_avatar_offline.tga"; + + element["columns"][1]["column"] = "username"; + element["columns"][1]["value"] = avatar_name; + + content["name"] = avatar_name; + + search_results->addElement(element, ADD_BOTTOM); + self->mResultsContent[agent_id.asString()] = content; + } + } + if (found_one) + { + search_results->selectFirstItem(); + search_results->setFocus(TRUE); + self->onSelectItem(); + } +} + +void FSPanelSearchPeople::onAvatarNameCallback(const LLUUID& id, const LLAvatarName& av_name) +{ + if (mAvatarNameCallbackConnection.connected()) + { + mAvatarNameCallbackConnection.disconnect(); + } + + LLScrollListCtrl* search_results = getChild<LLScrollListCtrl>("search_results_people"); + + if (av_name.getAccountName() != "(?\?\?).(?\?\?)") + { + LLSD content; + LLSD data; + data["id"] = id; + + data["columns"][0]["column"] = "icon"; + data["columns"][0]["type"] = "icon"; + data["columns"][0]["value"] = "icon_avatar_offline.tga"; + + data["columns"][1]["name"] = "username"; + data["columns"][1]["value"] = av_name.getUserName(); + + content["name"] = av_name.getUserName(); + + search_results->addElement(data); + + mResultsContent[id.asString()] = content; + mResultsReceived = 1; + mNumResultsReturned = 1; + + search_results->setEnabled(TRUE); + search_results->selectFirstItem(); + search_results->setFocus(TRUE); + onSelectItem(); + } + else + { + LLStringUtil::format_map_t map; + map["[TEXT]"] = getChild<LLUICtrl>("people_edit")->getValue().asString(); + search_results->setEnabled(FALSE); + search_results->setCommentText(LLTrans::getString("not_found", map)); + } +} + +//////////////////////////////////////// +// Groups Search Panel // +//////////////////////////////////////// + +static LLPanelInjector<FSPanelSearchGroups> t_panel_fs_search_groups("panel_ls_groups"); + +FSPanelSearchGroups::FSPanelSearchGroups() : FSSearchPanelBase() +, mQueryID(nullptr) +, mStartSearch(0) +, mResultsReceived(0) +, mResultsContent() +{ +} + +FSPanelSearchGroups::~FSPanelSearchGroups() +{ +} + +bool FSPanelSearchGroups::postBuild() +{ + mSearchComboBox = findChild<LLSearchComboBox>("groups_edit"); + mSearchResults = findChild<LLScrollListCtrl>("search_results_groups"); + if (mSearchComboBox) + { + mSearchComboBox->setCommitCallback(boost::bind(&FSPanelSearchGroups::onBtnFind, this)); + fillSearchComboBox(mSearchComboBox); + } + if (mSearchResults) + { + mSearchResults->setCommitCallback(boost::bind(&FSPanelSearchGroups::onSelectItem, this)); + mSearchResults->setEnabled(FALSE); + mSearchResults->setCommentText(LLTrans::getString("no_results")); + } + + childSetAction("groups_next", boost::bind(&FSPanelSearchGroups::onBtnNext, this)); + childSetAction("groups_back", boost::bind(&FSPanelSearchGroups::onBtnBack, this)); + getChildView("groups_next")->setEnabled(FALSE); + getChildView("groups_back")->setEnabled(FALSE); + + lastRequestTime = std::chrono::system_clock::now(); + + return TRUE; +} + +void FSPanelSearchGroups::focusDefaultElement() +{ + mSearchComboBox->focusTextEntry(); +} + +void FSPanelSearchGroups::find() +{ + std::string text = filterShortWords(mSearchComboBox->getSimple()); + if (text.size() == 0) + { + mSearchResults->setCommentText(LLTrans::getString("search_short")); + return; + } + + static LLUICachedControl<bool> inc_pg("ShowPGSims", 1); + static LLUICachedControl<bool> inc_mature("ShowMatureSims", 0); + static LLUICachedControl<bool> inc_adult("ShowAdultSims", 0); + if (!(inc_pg || inc_mature || inc_adult)) + { + LLNotificationsUtil::add("NoContentToSearch"); + return; + } + U32 scope = 0; + if (gAgent.wantsPGOnly()) + { + scope |= DFQ_PG_SIMS_ONLY; + } + bool adult_enabled = gAgent.canAccessAdult(); + bool mature_enabled = gAgent.canAccessMature(); + if (inc_pg) + { + scope |= DFQ_INC_PG; + } + if (inc_mature && mature_enabled) + { + scope |= DFQ_INC_MATURE; + } + if (inc_adult && adult_enabled) + { + scope |= DFQ_INC_ADULT; + } + scope |= DFQ_GROUPS; + + mResultsReceived = 0; + if (mQueryID.notNull()) + { + mQueryID.setNull(); + } + mQueryID.generate(); + + if (mStartSearch < 0) + { + mStartSearch = 0; + } + + gMessageSystem->newMessage("DirFindQuery"); + gMessageSystem->nextBlock("AgentData"); + gMessageSystem->addUUID("AgentID", gAgentID); + gMessageSystem->addUUID("SessionID", gAgentSessionID); + gMessageSystem->nextBlock("QueryData"); + gMessageSystem->addUUID("QueryID", getQueryID()); + gMessageSystem->addString("QueryText", text); + gMessageSystem->addU32("QueryFlags", scope); + gMessageSystem->addS32("QueryStart", mStartSearch); + gAgent.sendReliableMessage(); + LL_DEBUGS("Search") << "Firing off search request: " << getQueryID() << LL_ENDL; + + mSearchResults->deleteAllItems(); + mSearchResults->setCommentText(LLTrans::getString("searching")); + mNumResultsReturned = 0; +} + +void FSPanelSearchGroups::onBtnFind() +{ + std::chrono::time_point<std::chrono::system_clock> now = std::chrono::system_clock::now(); + auto elapsed = now - lastRequestTime; + U64 elapsedMS = std::chrono::duration_cast<std::chrono::milliseconds>(elapsed).count(); + if(elapsedMS < REQUEST_MIN_ELAPSED_TIME) return; + lastRequestTime = now; + + std::string text = mSearchComboBox->getSimple(); + if (!text.empty()) + { + LLSearchHistory::getInstance()->addEntry(text); + } + + resetSearch(); + + find(); +} + +void FSPanelSearchGroups::onBtnNext() +{ + mStartSearch += RESULT_PAGE_SIZE; + getChildView("groups_back")->setEnabled(TRUE); + + find(); +} + +void FSPanelSearchGroups::onBtnBack() +{ + mStartSearch -= RESULT_PAGE_SIZE; + getChildView("groups_back")->setEnabled(mStartSearch > 0); + + find(); +} + +void FSPanelSearchGroups::resetSearch() +{ + mStartSearch = 0; + getChildView("groups_back")->setEnabled(FALSE); + getChildView("groups_next")->setEnabled(FALSE); +} + +S32 FSPanelSearchGroups::showNextButton(S32 rows) +{ + bool show_next_button = (mResultsReceived > RESULT_PAGE_SIZE); + getChildView("groups_next")->setEnabled(show_next_button); + if (show_next_button) + { + rows -= (mResultsReceived - RESULT_PAGE_SIZE); + } + return rows; +} + +void FSPanelSearchGroups::onSelectItem() +{ + if (!mSearchResults) + { + return; + } + FSFloaterSearch* search_instance = LLFloaterReg::findTypedInstance<FSFloaterSearch>("search"); + if (search_instance) + { + search_instance->FSFloaterSearch::onSelectedItem(mSearchResults->getSelectedValue(), FSFloaterSearch::SC_GROUP); + } +} + +// static +void FSPanelSearchGroups::processSearchReply(LLMessageSystem* msg, void**) +{ + LLUUID query_id; + LLUUID group_id; + LLUUID agent_id; + std::string group_name; + S32 members; + F32 search_order; + + msg->getUUIDFast( _PREHASH_QueryData, _PREHASH_QueryID, query_id); + msg->getUUIDFast( _PREHASH_AgentData, _PREHASH_AgentID, agent_id); + + // Not for us + if (agent_id != gAgentID) + { + return; + } + LL_DEBUGS("Search") << "received directory request - QueryID: " << query_id << " AgentID: " << agent_id << LL_ENDL; + + FSPanelSearchGroups* self = FSFloaterSearch::getSearchPanel<FSPanelSearchGroups>("panel_ls_groups"); + + // floater is closed or these are not results from our last request + if (!self || query_id != self->mQueryID) + { + return; + } + + LLScrollListCtrl* search_results = self->getChild<LLScrollListCtrl>("search_results_groups"); + + // Clear "Searching" label on first results + if (self->mNumResultsReturned++ == 0) + { + search_results->deleteAllItems(); + } + + // Check for status messages + if (msg->getNumberOfBlocks("StatusData")) + { + U32 status; + msg->getU32("StatusData", "Status", status); + if (status & STATUS_SEARCH_PLACES_FOUNDNONE) + { + LLStringUtil::format_map_t map; + map["[TEXT]"] = self->getChild<LLUICtrl>("groups_edit")->getValue().asString(); + search_results->setEnabled(FALSE); + search_results->setCommentText(LLTrans::getString("not_found", map)); + return; + } + else if(status & STATUS_SEARCH_PLACES_SHORTSTRING) + { + search_results->setEnabled(FALSE); + search_results->setCommentText(LLTrans::getString("search_short")); + return; + } + else if (status & STATUS_SEARCH_PLACES_BANNEDWORD) + { + search_results->setEnabled(FALSE); + search_results->setCommentText(LLTrans::getString("search_banned")); + return; + } + else if (status & STATUS_SEARCH_PLACES_SEARCHDISABLED) + { + search_results->setEnabled(FALSE); + search_results->setCommentText(LLTrans::getString("search_disabled")); + return; + } + } + + bool found_one = false; + S32 num_new_rows = msg->getNumberOfBlocksFast(_PREHASH_QueryReplies); + if (num_new_rows == 0 && self->mResultsReceived == 0) + { + LLStringUtil::format_map_t map; + map["[TEXT]"] = self->getChild<LLUICtrl>("groups_edit")->getValue().asString(); + search_results->setEnabled(FALSE); + search_results->setCommentText(LLTrans::getString("not_found", map)); + } + + self->mResultsReceived += num_new_rows; + num_new_rows = self->showNextButton(num_new_rows); + + for (S32 i = 0; i < num_new_rows; i++) + { + msg->getUUIDFast( _PREHASH_QueryReplies, _PREHASH_GroupID, group_id, i); + msg->getStringFast( _PREHASH_QueryReplies, _PREHASH_GroupName, group_name, i); + msg->getS32Fast( _PREHASH_QueryReplies, _PREHASH_Members, members, i); + msg->getF32Fast( _PREHASH_QueryReplies, _PREHASH_SearchOrder, search_order,i); + if (group_id.isNull()) + { + LL_DEBUGS("Search") << "No results returned for QueryID: " << query_id << LL_ENDL; + LLStringUtil::format_map_t map; + map["[TEXT]"] = self->getChild<LLUICtrl>("groups_edit")->getValue().asString(); + search_results->setEnabled(FALSE); + search_results->setCommentText(LLTrans::getString("not_found", map)); + } + else + { + LL_DEBUGS("Search") << "Got: " << group_name << " GroupID: " << group_id << LL_ENDL; + search_results->setEnabled(TRUE); + found_one = true; + + LLSD content; + LLSD element; + + element["id"] = group_id; + + element["columns"][0]["column"] = "icon"; + element["columns"][0]["type"] = "icon"; + element["columns"][0]["value"] = "Icon_Group"; + + element["columns"][1]["column"] = "group_name"; + element["columns"][1]["value"] = group_name; + + element["columns"][2]["column"] = "members"; + element["columns"][2]["value"] = members; + + element["columns"][3]["column"] = "score"; + element["columns"][3]["value"] = search_order; + + content["name"] = group_name; + + search_results->addElement(element, ADD_BOTTOM); + self->mResultsContent[group_id.asString()] = content; + } + } + if (found_one) + { + search_results->selectFirstItem(); + search_results->setFocus(TRUE); + self->onSelectItem(); + } +} + +//////////////////////////////////////// +// Places Search Panel // +//////////////////////////////////////// + +static LLPanelInjector<FSPanelSearchPlaces> t_panel_fs_search_places("panel_ls_places"); + +FSPanelSearchPlaces::FSPanelSearchPlaces() : FSSearchPanelBase() +, mQueryID(nullptr) +, mStartSearch(0) +, mResultsReceived(0) +, mResultsContent() +{ + mCommitCallbackRegistrar.add("CommitSearch", boost::bind(&FSPanelSearchPlaces::find, this)); +} + +FSPanelSearchPlaces::~FSPanelSearchPlaces() +{ +} + +bool FSPanelSearchPlaces::postBuild() +{ + mSearchComboBox = findChild<LLSearchComboBox>("places_edit"); + mSearchResults = findChild<LLScrollListCtrl>("search_results_places"); + mPlacesCategory = findChild<LLComboBox>("places_category"); + if (mSearchComboBox) + { + mSearchComboBox->setCommitCallback(boost::bind(&FSPanelSearchPlaces::onBtnFind, this)); + fillSearchComboBox(mSearchComboBox); + } + if (mSearchResults) + { + mSearchResults->setCommitCallback(boost::bind(&FSPanelSearchPlaces::onSelectItem, this)); + mSearchResults->setEnabled(FALSE); + mSearchResults->setCommentText(LLTrans::getString("no_results")); + } + if (mPlacesCategory) + { + mPlacesCategory->add(LLTrans::getString("all_categories"), LLSD("any")); + mPlacesCategory->addSeparator(); + for (int category = LLParcel::C_LINDEN; category < LLParcel::C_COUNT; category++) + { + LLParcel::ECategory eCategory = (LLParcel::ECategory)category; + mPlacesCategory->add(LLTrans::getString(LLParcel::getCategoryUIString(eCategory)), LLParcel::getCategoryString(eCategory)); + } + } + childSetAction("places_next", boost::bind(&FSPanelSearchPlaces::onBtnNext, this)); + childSetAction("places_back", boost::bind(&FSPanelSearchPlaces::onBtnBack, this)); + getChildView("places_next")->setEnabled(FALSE); + getChildView("places_back")->setEnabled(FALSE); + + return TRUE; +} + +void FSPanelSearchPlaces::focusDefaultElement() +{ + mSearchComboBox->focusTextEntry(); +} + +void FSPanelSearchPlaces::find() +{ + std::string text = filterShortWords(mSearchComboBox->getSimple()); + if (text.empty()) + { + mSearchResults->setCommentText(LLTrans::getString("search_short")); + return; + } + + static LLUICachedControl<bool> inc_pg("ShowPGSims", 1); + static LLUICachedControl<bool> inc_mature("ShowMatureSims", 0); + static LLUICachedControl<bool> inc_adult("ShowAdultSims", 0); + if (!(inc_pg || inc_mature || inc_adult)) + { + LLNotificationsUtil::add("NoContentToSearch"); + return; + } + S8 category; + std::string category_string = mPlacesCategory->getSelectedValue(); + if (category_string == "any") + { + category = LLParcel::C_ANY; + } + else + { + category = LLParcel::getCategoryFromString(category_string); + } + U32 scope = 0; + if (gAgent.wantsPGOnly()) + { + scope |= DFQ_PG_SIMS_ONLY; + } + bool adult_enabled = gAgent.canAccessAdult(); + bool mature_enabled = gAgent.canAccessMature(); + if (inc_pg) + { + scope |= DFQ_INC_PG; + } + if (inc_mature && mature_enabled) + { + scope |= DFQ_INC_MATURE; + } + if (inc_adult && adult_enabled) + { + scope |= DFQ_INC_ADULT; + } + scope |= DFQ_DWELL_SORT; + + mResultsReceived = 0; + if (mQueryID.notNull()) + { + mQueryID.setNull(); + } + mQueryID.generate(); + + if (mStartSearch < 0) + { + mStartSearch = 0; + } + + gMessageSystem->newMessage("DirPlacesQuery"); + gMessageSystem->nextBlock("AgentData"); + gMessageSystem->addUUID("AgentID", gAgentID); + gMessageSystem->addUUID("SessionID", gAgentSessionID); + gMessageSystem->nextBlock("QueryData"); + gMessageSystem->addUUID("QueryID", getQueryID()); + gMessageSystem->addString("QueryText", text); + gMessageSystem->addU32("QueryFlags", scope); + gMessageSystem->addS8("Category", category); + // TODO: Search filter by region name. + gMessageSystem->addString("SimName", ""); + gMessageSystem->addS32("QueryStart", mStartSearch); + gAgent.sendReliableMessage(); + LL_INFOS("Search") << "Firing off places search request: " << getQueryID() << LL_ENDL; + + mSearchResults->deleteAllItems(); + mSearchResults->setCommentText(LLTrans::getString("searching")); + mNumResultsReturned = 0; +} + +void FSPanelSearchPlaces::onBtnFind() +{ + std::chrono::time_point<std::chrono::system_clock> now = std::chrono::system_clock::now(); + auto elapsed = now - lastRequestTime; + U64 elapsedMS = std::chrono::duration_cast<std::chrono::milliseconds>(elapsed).count(); + if(elapsedMS < REQUEST_MIN_ELAPSED_TIME) return; + lastRequestTime = now; + + std::string text = mSearchComboBox->getSimple(); + if (!text.empty()) + { + LLSearchHistory::getInstance()->addEntry(text); + } + + resetSearch(); + + find(); +} + +void FSPanelSearchPlaces::onBtnNext() +{ + mStartSearch += RESULT_PAGE_SIZE; + getChildView("places_back")->setEnabled(TRUE); + + find(); +} + +void FSPanelSearchPlaces::onBtnBack() +{ + mStartSearch -= RESULT_PAGE_SIZE; + getChildView("places_back")->setEnabled(mStartSearch > 0); + + find(); +} + +void FSPanelSearchPlaces::resetSearch() +{ + mStartSearch = 0; + getChildView("places_back")->setEnabled(FALSE); + getChildView("places_next")->setEnabled(FALSE); +} + +S32 FSPanelSearchPlaces::showNextButton(S32 rows) +{ + bool show_next_button = (mResultsReceived > RESULT_PAGE_SIZE); + getChildView("places_next")->setEnabled(show_next_button); + if (show_next_button) + { + rows -= (mResultsReceived - RESULT_PAGE_SIZE); + } + return rows; +} + +void FSPanelSearchPlaces::onSelectItem() +{ + if (!mSearchResults) + { + return; + } + FSFloaterSearch* search_instance = LLFloaterReg::findTypedInstance<FSFloaterSearch>("search"); + if (search_instance) + { + search_instance->FSFloaterSearch::onSelectedItem(mSearchResults->getSelectedValue(), FSFloaterSearch::SC_PLACE); + } +} + +// static +void FSPanelSearchPlaces::processSearchReply(LLMessageSystem* msg, void**) +{ + LLUUID agent_id; + LLUUID query_id; + LLUUID parcel_id; + std::string name; + bool for_sale; + bool auction; + F32 dwell; + + msg->getUUID("AgentData", "AgentID", agent_id); + msg->getUUID("QueryData", "QueryID", query_id); + + // Not for us + if (agent_id != gAgentID) + { + return; + } + LL_DEBUGS("Search") << "received directory request - QueryID: " << query_id << " AgentID: " << agent_id << LL_ENDL; + + FSPanelSearchPlaces* self = FSFloaterSearch::getSearchPanel<FSPanelSearchPlaces>("panel_ls_places"); + + // floater is closed or these are not results from our last request + if (!self || query_id != self->getQueryID()) + { + return; + } + + LLScrollListCtrl* search_results = self->getChild<LLScrollListCtrl>("search_results_places"); + + // Clear "Searching" label on first results + if (self->mNumResultsReturned++ == 0) + { + search_results->deleteAllItems(); + } + + // Check for status messages + if (msg->getNumberOfBlocks("StatusData")) + { + U32 status; + msg->getU32("StatusData", "Status", status); + if (status & STATUS_SEARCH_PLACES_FOUNDNONE) + { + LLStringUtil::format_map_t map; + map["[TEXT]"] = self->getChild<LLUICtrl>("places_edit")->getValue().asString(); + search_results->setEnabled(FALSE); + search_results->setCommentText(LLTrans::getString("not_found", map)); + return; + } + else if(status & STATUS_SEARCH_PLACES_SHORTSTRING) + { + search_results->setEnabled(FALSE); + search_results->setCommentText(LLTrans::getString("search_short")); + return; + } + else if (status & STATUS_SEARCH_PLACES_BANNEDWORD) + { + search_results->setEnabled(FALSE); + search_results->setCommentText(LLTrans::getString("search_banned")); + return; + } + else if (status & STATUS_SEARCH_PLACES_SEARCHDISABLED) + { + search_results->setEnabled(FALSE); + search_results->setCommentText(LLTrans::getString("search_disabled")); + return; + } + else if (status & STATUS_SEARCH_PLACES_ESTATEEMPTY) + { + search_results->setEnabled(FALSE); + search_results->setCommentText(LLTrans::getString("search_disabled")); + return; + } + } + + bool found_one = false; + S32 num_new_rows = msg->getNumberOfBlocks("QueryReplies"); + if (num_new_rows == 0 && self->mResultsReceived == 0) + { + LLStringUtil::format_map_t map; + map["[TEXT]"] = self->getChild<LLUICtrl>("places_edit")->getValue().asString(); + search_results->setEnabled(FALSE); + search_results->setCommentText(LLTrans::getString("not_found", map)); + } + + self->mResultsReceived += num_new_rows; + num_new_rows = self->showNextButton(num_new_rows); + + for (S32 i = 0; i < num_new_rows; i++) + { + msg->getUUID( "QueryReplies", "ParcelID", parcel_id, i); + msg->getString( "QueryReplies", "Name", name, i); + msg->getBOOL( "QueryReplies", "ForSale", for_sale,i); + msg->getBOOL( "QueryReplies", "Auction", auction, i); + msg->getF32( "QueryReplies", "Dwell", dwell, i); + if (parcel_id.isNull()) + { + LL_DEBUGS("Search") << "Null result returned for QueryID: " << query_id << LL_ENDL; + LLStringUtil::format_map_t map; + map["[TEXT]"] = self->getChild<LLUICtrl>("places_edit")->getValue().asString(); + search_results->setEnabled(FALSE); + search_results->setCommentText(LLTrans::getString("not_found", map)); + } + else + { + LL_DEBUGS("Search") << "Got: " << name << " ParcelID: " << parcel_id << LL_ENDL; + search_results->setEnabled(TRUE); + found_one = true; + + LLSD content; + LLSD element; + + element["id"] = parcel_id; + + if (auction) + { + element["columns"][0]["column"] = "icon"; + element["columns"][0]["type"] = "icon"; + element["columns"][0]["value"] = "Icon_Auction"; + } + else if (for_sale) + { + element["columns"][0]["column"] = "icon"; + element["columns"][0]["type"] = "icon"; + element["columns"][0]["value"] = "Icon_For_Sale"; + } + else + { + element["columns"][0]["column"] = "icon"; + element["columns"][0]["type"] = "icon"; + element["columns"][0]["value"] = "Icon_Place"; + } + + element["columns"][1]["column"] = "place_name"; + element["columns"][1]["value"] = name; + + content["name"] = name; + + std::string buffer = llformat("%.0f", (F64)dwell); + element["columns"][2]["column"] = "dwell"; + element["columns"][2]["value"] = buffer; + + search_results->addElement(element, ADD_BOTTOM); + self->mResultsContent[parcel_id.asString()] = content; + } + } + if (found_one) + { + search_results->selectFirstItem(); + search_results->setFocus(TRUE); + self->onSelectItem(); + } +} + +//////////////////////////////////////// +// Land Search Panel // +//////////////////////////////////////// + +static LLPanelInjector<FSPanelSearchLand> t_panel_fs_search_land("panel_ls_land"); + +FSPanelSearchLand::FSPanelSearchLand() : FSSearchPanelBase() +, mQueryID(nullptr) +, mStartSearch(0) +, mResultsReceived(0) +, mResultsContent() +{ + mCommitCallbackRegistrar.add("CommitSearch", boost::bind(&FSPanelSearchLand::find, this)); +} + +FSPanelSearchLand::~FSPanelSearchLand() +{ +} + +bool FSPanelSearchLand::postBuild() +{ + mSearchResults = getChild<LLScrollListCtrl>("search_results_land"); + mPriceEditor = findChild<LLLineEditor>("price_edit"); + mAreaEditor = findChild<LLLineEditor>("area_edit"); + if (mSearchResults) + { + mSearchResults->setCommitCallback(boost::bind(&FSPanelSearchLand::onSelectItem, this)); + mSearchResults->setEnabled(FALSE); + mSearchResults->setCommentText(LLTrans::getString("no_results")); + } + if (mPriceEditor) + { + mPriceEditor->setCommitOnFocusLost(false); + mPriceEditor->setCommitCallback(boost::bind(&FSPanelSearchLand::onBtnFind, this)); + } + if (mAreaEditor) + { + mAreaEditor->setCommitOnFocusLost(false); + mAreaEditor->setCommitCallback(boost::bind(&FSPanelSearchLand::find, this)); + } + childSetAction("land_find", boost::bind(&FSPanelSearchLand::onBtnFind, this)); + childSetAction("land_next", boost::bind(&FSPanelSearchLand::onBtnNext, this)); + childSetAction("land_back", boost::bind(&FSPanelSearchLand::onBtnBack, this)); + + getChildView("land_next")->setEnabled(FALSE); + getChildView("land_back")->setEnabled(FALSE); + + return TRUE; +} + +void FSPanelSearchLand::find() +{ + static LLUICachedControl<bool> inc_pg("ShowPGLand", 1); + static LLUICachedControl<bool> inc_mature("ShowMatureLand", 0); + static LLUICachedControl<bool> inc_adult("ShowAdultLand", 0); + static LLUICachedControl<bool> limit_price("FindLandPrice", 1); + static LLUICachedControl<bool> limit_area("FindLandArea", 1); + if (!(inc_pg || inc_mature || inc_adult)) + { + LLNotificationsUtil::add("NoContentToSearch"); + return; + } + + U32 category = ST_ALL; + const std::string& selection = findChild<LLComboBox>("land_category")->getSelectedValue().asString(); + if (!selection.empty()) + { + if (selection == "Auction") + { + category = ST_AUCTION; + } + else if (selection == "Mainland") + { + category = ST_MAINLAND; + } + else if (selection == "Estate") + { + category = ST_ESTATE; + } + } + + U32 scope = 0; + if (gAgent.wantsPGOnly()) + { + scope |= DFQ_PG_SIMS_ONLY; + } + bool mature_enabled = gAgent.canAccessMature(); + bool adult_enabled = gAgent.canAccessAdult(); + if (inc_pg) + { + scope |= DFQ_INC_PG; + } + if (inc_mature && mature_enabled) + { + scope |= DFQ_INC_MATURE; + } + if (inc_adult && adult_enabled) + { + scope |= DFQ_INC_ADULT; + } + const std::string& sort = findChild<LLComboBox>("land_sort_combo")->getSelectedValue().asString(); + if (!sort.empty()) + { + if (sort == "Name") + { + scope |= DFQ_NAME_SORT; + } + else if (sort == "Price") + { + scope |= DFQ_PRICE_SORT; + } + else if (sort == "PPM") + { + scope |= DFQ_PER_METER_SORT; + } + else if (sort == "Area") + { + scope |= DFQ_AREA_SORT; + } + } + else + { + scope |= DFQ_PRICE_SORT; + } + if (childGetValue("ascending_check").asBoolean()) + { + scope |= DFQ_SORT_ASC; + } + if (limit_price) + { + scope |= DFQ_LIMIT_BY_PRICE; + } + if (limit_area) + { + scope |= DFQ_LIMIT_BY_AREA; + } + S32 price = childGetValue("edit_price").asInteger(); + S32 area = childGetValue("edit_area").asInteger(); + + mResultsReceived = 0; + if (mQueryID.notNull()) + { + mQueryID.setNull(); + } + mQueryID.generate(); + + if (mStartSearch < 0) + { + mStartSearch = 0; + } + + gMessageSystem->newMessage("DirLandQuery"); + gMessageSystem->nextBlock("AgentData"); + gMessageSystem->addUUID("AgentID", gAgentID); + gMessageSystem->addUUID("SessionID", gAgentSessionID); + gMessageSystem->nextBlock("QueryData"); + gMessageSystem->addUUID("QueryID", getQueryID()); + gMessageSystem->addU32("QueryFlags", scope); + gMessageSystem->addU32("SearchType", category); + gMessageSystem->addS32("Price", price); + gMessageSystem->addS32("Area", area); + gMessageSystem->addS32("QueryStart", mStartSearch); + gAgent.sendReliableMessage(); + LL_DEBUGS("Search") << "Firing off places search request: " << getQueryID() << category << LL_ENDL; + + mSearchResults->deleteAllItems(); + mSearchResults->setCommentText(LLTrans::getString("searching")); + mNumResultsReturned = 0; +} + +void FSPanelSearchLand::onBtnFind() +{ + std::chrono::time_point<std::chrono::system_clock> now = std::chrono::system_clock::now(); + auto elapsed = now - lastRequestTime; + U64 elapsedMS = std::chrono::duration_cast<std::chrono::milliseconds>(elapsed).count(); + if(elapsedMS < REQUEST_MIN_ELAPSED_TIME) return; + lastRequestTime = now; + + resetSearch(); + + find(); +} + +void FSPanelSearchLand::onBtnNext() +{ + mStartSearch += RESULT_PAGE_SIZE; + getChildView("land_back")->setEnabled(TRUE); + + find(); +} + +void FSPanelSearchLand::onBtnBack() +{ + mStartSearch -= RESULT_PAGE_SIZE; + getChildView("land_back")->setEnabled(mStartSearch > 0); + + find(); +} + +void FSPanelSearchLand::resetSearch() +{ + mStartSearch = 0; + getChildView("land_back")->setEnabled(FALSE); + getChildView("land_next")->setEnabled(FALSE); +} + +S32 FSPanelSearchLand::showNextButton(S32 rows) +{ + bool show_next_button = (mResultsReceived > RESULT_PAGE_SIZE); + getChildView("land_next")->setEnabled(show_next_button); + if (show_next_button) + { + rows -= (mResultsReceived - RESULT_PAGE_SIZE); + } + return rows; +} + +void FSPanelSearchLand::onSelectItem() +{ + if (!mSearchResults) + { + return; + } + FSFloaterSearch* search_instance = LLFloaterReg::findTypedInstance<FSFloaterSearch>("search"); + if (search_instance) + { + search_instance->FSFloaterSearch::onSelectedItem(mSearchResults->getSelectedValue(), FSFloaterSearch::SC_PLACE); + } +} + +// static +void FSPanelSearchLand::processSearchReply(LLMessageSystem* msg, void**) +{ + LLUUID agent_id; + LLUUID query_id; + LLUUID parcel_id; + std::string name; + std::string land_sku; + std::string land_type; + bool auction; + bool for_sale; + S32 price; + S32 area; + + msg->getUUID("AgentData", "AgentID", agent_id); + msg->getUUID("QueryData", "QueryID", query_id); + + // Not for us + if (agent_id != gAgentID) + { + return; + } + LL_DEBUGS("Search") << "received directory request - QueryID: " << query_id << " AgentID: " << agent_id << LL_ENDL; + + FSPanelSearchLand* self = FSFloaterSearch::getSearchPanel<FSPanelSearchLand>("panel_ls_land"); + + // floater is closed or these are not results from our last request + if (!self || query_id != self->mQueryID) + { + return; + } + + LLScrollListCtrl* search_results = self->getChild<LLScrollListCtrl>("search_results_land"); + // clear "Searching" label on first results + if (self->mNumResultsReturned++ == 0) + { + search_results->deleteAllItems(); + } + + static LLUICachedControl<bool> use_price("FindLandPrice", 1); + static LLUICachedControl<bool> use_area("FindLandArea", 1); + S32 limit_price = self->childGetValue("edit_price").asInteger(); + S32 limit_area = self->childGetValue("edit_area").asInteger(); + + bool found_one = false; + S32 num_new_rows = msg->getNumberOfBlocks("QueryReplies"); + if (num_new_rows == 0 && self->mResultsReceived == 0) + { + LLStringUtil::format_map_t map; + map["[TEXT]"] = self->getChild<LLUICtrl>("events_edit")->getValue().asString(); + search_results->setEnabled(FALSE); + search_results->setCommentText(LLTrans::getString("not_found", map)); + } + self->mResultsReceived += num_new_rows; + + S32 not_auction = 0; + for (S32 i = 0; i < num_new_rows; i++) + { + msg->getUUID( "QueryReplies", "ParcelID", parcel_id, i); + msg->getString( "QueryReplies", "Name", name, i); + msg->getBOOL( "QueryReplies", "Auction", auction, i); + msg->getBOOL( "QueryReplies", "ForSale", for_sale, i); + msg->getS32( "QueryReplies", "SalePrice", price, i); + msg->getS32( "QueryReplies", "ActualArea", area, i); + if (parcel_id.isNull()) + { + LL_DEBUGS("Search") << "Null result returned for QueryID: " << query_id << LL_ENDL; + search_results->setEnabled(FALSE); + search_results->setCommentText(LLTrans::getString("no_results")); + } + else + { + LL_DEBUGS("Search") << "Got: " << name << " ClassifiedID: " << parcel_id << LL_ENDL; + search_results->setEnabled(TRUE); + found_one = true; + if (msg->getSizeFast(_PREHASH_QueryReplies, i, _PREHASH_ProductSKU) > 0) + { + msg->getStringFast( _PREHASH_QueryReplies, _PREHASH_ProductSKU, land_sku, i); + land_type = LLProductInfoRequestManager::instance().getDescriptionForSku(land_sku); + } + else + { + land_sku.clear(); + land_type = LLTrans::getString("land_type_unknown"); + } + if (parcel_id.isNull()) + { + continue; + } + if (use_price && (price > limit_price)) + { + continue; + } + if (use_area && (area < limit_area)) + { + continue; + } + + LLSD content; + LLSD element; + + element["id"] = parcel_id; + if (auction) + { + element["columns"][0]["column"] = "icon"; + element["columns"][0]["type"] = "icon"; + element["columns"][0]["value"] = "Icon_Auction"; + } + else if (for_sale) + { + element["columns"][0]["column"] = "icon"; + element["columns"][0]["type"] = "icon"; + element["columns"][0]["value"] = "Icon_For_Sale"; + } + else + { + element["columns"][0]["column"] = "icon"; + element["columns"][0]["type"] = "icon"; + element["columns"][0]["value"] = "Icon_Place"; + } + + element["columns"][1]["column"] = "land_name"; + element["columns"][1]["value"] = name; + + content["place_name"] = name; + + std::string buffer = "Auction"; + if (!auction) + { + buffer = llformat("%d", price); + not_auction++; + } + element["columns"][2]["column"] = "price"; + element["columns"][2]["value"] = price; + + element["columns"][3]["column"] = "area"; + element["columns"][3]["value"] = area; + if (!auction) + { + F32 ppm; + if (area > 0) + { + ppm = (F32)price / (F32)area; + } + else + { + ppm = 0.f; + } + std::string ppm_buffer = llformat("%.1f", ppm); + element["columns"][4]["column"] = "ppm"; + element["columns"][4]["value"] = ppm_buffer; + } + else + { + element["columns"][4]["column"] = "ppm"; + element["columns"][4]["value"] = "1.0"; + } + + element["columns"][5]["column"] = "land_type"; + element["columns"][5]["value"] = land_type; + + search_results->addElement(element, ADD_BOTTOM); + self->mResultsContent[parcel_id.asString()] = content; + } + // We test against non-auction properties because they don't count towards the page limit. + self->showNextButton(not_auction); + } + if (found_one) + { + search_results->selectFirstItem(); + search_results->setFocus(TRUE); + self->onSelectItem(); + } +} + +//////////////////////////////////////// +// Classifieds Search Panel // +//////////////////////////////////////// + +static LLPanelInjector<FSPanelSearchClassifieds> t_panel_fs_search_classifieds("panel_ls_classifieds"); + +FSPanelSearchClassifieds::FSPanelSearchClassifieds() : FSSearchPanelBase() +, mQueryID(nullptr) +, mStartSearch(0) +, mResultsReceived(0) +, mResultsContent() +{ + mCommitCallbackRegistrar.add("CommitSearch", boost::bind(&FSPanelSearchClassifieds::find, this)); +} + +FSPanelSearchClassifieds::~FSPanelSearchClassifieds() +{ +} + +bool FSPanelSearchClassifieds::postBuild() +{ + mSearchComboBox = findChild<LLSearchComboBox>("classifieds_edit"); + mSearchResults = getChild<LLScrollListCtrl>("search_results_classifieds"); + if (mSearchComboBox) + { + mSearchComboBox->setCommitCallback(boost::bind(&FSPanelSearchClassifieds::onBtnFind, this)); + fillSearchComboBox(mSearchComboBox); + } + if (mSearchResults) + { + mSearchResults->setCommitCallback(boost::bind(&FSPanelSearchClassifieds::onSelectItem, this)); + mSearchResults->setEnabled(FALSE); + mSearchResults->setCommentText(LLTrans::getString("no_results")); + } + + mClassifiedsCategory = getChild<LLComboBox>("classifieds_category"); + if (mClassifiedsCategory) + { + LLClassifiedInfo::cat_map::iterator iter; + mClassifiedsCategory->add(LLTrans::getString("all_categories"), LLSD(0)); + mClassifiedsCategory->addSeparator(); + for (iter = LLClassifiedInfo::sCategories.begin(); + iter != LLClassifiedInfo::sCategories.end(); + iter++) + { + mClassifiedsCategory->add(LLTrans::getString(iter->second), LLSD((S32)iter->first)); + } + } + childSetAction("classifieds_next", boost::bind(&FSPanelSearchClassifieds::onBtnNext, this)); + childSetAction("classifieds_back", boost::bind(&FSPanelSearchClassifieds::onBtnBack, this)); + + getChildView("classifieds_next")->setEnabled(FALSE); + getChildView("classifieds_back")->setEnabled(FALSE); + + return TRUE; +} + +void FSPanelSearchClassifieds::focusDefaultElement() +{ + mSearchComboBox->focusTextEntry(); +} + +void FSPanelSearchClassifieds::find() +{ + std::string text = filterShortWords(mSearchComboBox->getSimple()); + if (text.size() == 0) + { + mSearchResults->setCommentText(LLTrans::getString("search_short")); + return; + } + + static LLUICachedControl<bool> inc_pg("ShowPGClassifieds", 1); + static LLUICachedControl<bool> inc_mature("ShowMatureClassifieds", 0); + static LLUICachedControl<bool> inc_adult("ShowAdultClassifieds", 0); + if (!(inc_pg || inc_mature || inc_adult)) + { + LLNotificationsUtil::add("NoContentToSearch"); + return; + } + U32 category = mClassifiedsCategory->getValue().asInteger(); + bool auto_renew = FALSE; + U32 flags = pack_classified_flags_request(auto_renew, inc_pg, inc_mature, inc_adult); + + mResultsReceived = 0; + if (mQueryID.notNull()) + { + mQueryID.setNull(); + } + mQueryID.generate(); + + if (mStartSearch < 0) + { + mStartSearch = 0; + } + + gMessageSystem->newMessageFast(_PREHASH_DirClassifiedQuery); + gMessageSystem->nextBlockFast(_PREHASH_AgentData); + gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgentID); + gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgentSessionID); + gMessageSystem->nextBlockFast(_PREHASH_QueryData); + gMessageSystem->addUUIDFast(_PREHASH_QueryID, getQueryID()); + gMessageSystem->addStringFast(_PREHASH_QueryText, text); + gMessageSystem->addU32Fast(_PREHASH_QueryFlags, flags); + gMessageSystem->addU32Fast(_PREHASH_Category, category); + gMessageSystem->addS32Fast(_PREHASH_QueryStart, mStartSearch); + gAgent.sendReliableMessage(); + LL_DEBUGS("Search") << "Firing off classified ad search request: " << getQueryID() << LL_ENDL; + + mSearchResults->deleteAllItems(); + mSearchResults->setCommentText(LLTrans::getString("searching")); + mNumResultsReturned = 0; +} + +void FSPanelSearchClassifieds::onBtnFind() +{ + std::chrono::time_point<std::chrono::system_clock> now = std::chrono::system_clock::now(); + auto elapsed = now - lastRequestTime; + U64 elapsedMS = std::chrono::duration_cast<std::chrono::milliseconds>(elapsed).count(); + if(elapsedMS < REQUEST_MIN_ELAPSED_TIME) return; + lastRequestTime = now; + + std::string text = mSearchComboBox->getSimple(); + if (!text.empty()) + { + LLSearchHistory::getInstance()->addEntry(text); + } + + resetSearch(); + + find(); +} + +void FSPanelSearchClassifieds::onBtnNext() +{ + mStartSearch += RESULT_PAGE_SIZE; + getChildView("classifieds_back")->setEnabled(TRUE); + + find(); +} + +void FSPanelSearchClassifieds::onBtnBack() +{ + mStartSearch -= RESULT_PAGE_SIZE; + getChildView("classifieds_back")->setEnabled(mStartSearch > 0); + + find(); +} + +void FSPanelSearchClassifieds::resetSearch() +{ + mStartSearch = 0; + getChildView("classifieds_back")->setEnabled(FALSE); + getChildView("classifieds_next")->setEnabled(FALSE); +} + +S32 FSPanelSearchClassifieds::showNextButton(S32 rows) +{ + bool show_next_button = (mResultsReceived > RESULT_PAGE_SIZE); + getChildView("classifieds_next")->setEnabled(show_next_button); + if (show_next_button) + { + rows -= (mResultsReceived - RESULT_PAGE_SIZE); + } + return rows; +} + +void FSPanelSearchClassifieds::onSelectItem() +{ + if (!mSearchResults) + { + return; + } + FSFloaterSearch* search_instance = LLFloaterReg::findTypedInstance<FSFloaterSearch>("search"); + if (search_instance) + { + search_instance->FSFloaterSearch::onSelectedItem(mSearchResults->getSelectedValue(), FSFloaterSearch::SC_CLASSIFIED); + } +} + +// static +void FSPanelSearchClassifieds::processSearchReply(LLMessageSystem* msg, void**) +{ + LLUUID agent_id; + LLUUID query_id; + LLUUID classified_id; + std::string name; + U32 creation_date; + U32 expiration_date; + S32 price_for_listing; + + msg->getUUID("AgentData", "AgentID", agent_id); + msg->getUUID("QueryData", "QueryID", query_id); + + // Not for us + if (agent_id != gAgentID) + { + return; + } + LL_DEBUGS("Search") << "received directory request - QueryID: " << query_id << " AgentID: " << agent_id << LL_ENDL; + + FSPanelSearchClassifieds* self = FSFloaterSearch::getSearchPanel<FSPanelSearchClassifieds>("panel_ls_classifieds"); + + if (msg->getNumberOfBlocks("StatusData")) + { + U32 status; + msg->getU32("StatusData", "Status", status); + if (status & STATUS_SEARCH_CLASSIFIEDS_BANNEDWORD) + { + LLNotificationsUtil::add("SearchWordBanned"); + } + } + + // floater is closed or these are not results from our last request + if (!self || query_id != self->mQueryID) + { + return; + } + + LLScrollListCtrl* search_results = self->getChild<LLScrollListCtrl>("search_results_classifieds"); + + // Clear "Searching" label on first results + if (self->mNumResultsReturned++ == 0) + { + search_results->deleteAllItems(); + } + + // Check for status messages + if (msg->getNumberOfBlocks("StatusData")) + { + U32 status; + msg->getU32("StatusData", "Status", status); + if (status & STATUS_SEARCH_PLACES_FOUNDNONE) + { + LLStringUtil::format_map_t map; + map["[TEXT]"] = self->getChild<LLUICtrl>("classifieds_edit")->getValue().asString(); + search_results->setEnabled(FALSE); + search_results->setCommentText(LLTrans::getString("not_found", map)); + return; + } + else if(status & STATUS_SEARCH_PLACES_SHORTSTRING) + { + search_results->setEnabled(FALSE); + search_results->setCommentText(LLTrans::getString("search_short")); + return; + } + else if (status & STATUS_SEARCH_CLASSIFIEDS_BANNEDWORD) + { + search_results->setEnabled(FALSE); + search_results->setCommentText(LLTrans::getString("search_banned")); + return; + } + else if (status & STATUS_SEARCH_PLACES_SEARCHDISABLED) + { + search_results->setEnabled(FALSE); + search_results->setCommentText(LLTrans::getString("search_disabled")); + return; + } + } + + bool found_one = false; + S32 num_new_rows = msg->getNumberOfBlocks("QueryReplies"); + if (num_new_rows == 0 && self->mResultsReceived == 0) + { + LLStringUtil::format_map_t map; + map["[TEXT]"] = self->getChild<LLUICtrl>("classifieds_edit")->getValue().asString(); + search_results->setEnabled(FALSE); + search_results->setCommentText(LLTrans::getString("not_found", map)); + } + self->mResultsReceived += num_new_rows; + num_new_rows = self->showNextButton(num_new_rows); + + for (S32 i = 0; i < num_new_rows; i++) + { + msg->getUUID( "QueryReplies", "ClassifiedID", classified_id, i); + msg->getString( "QueryReplies", "Name", name, i); + msg->getU32( "QueryReplies", "CreationDate", creation_date, i); + msg->getU32( "QueryReplies", "ExpirationDate", expiration_date,i); + msg->getS32( "QueryReplies", "PriceForListing", price_for_listing,i); + if (classified_id.isNull()) + { + LL_DEBUGS("Search") << "Null result returned for QueryID: " << query_id << LL_ENDL; + LLStringUtil::format_map_t map; + map["[TEXT]"] = self->getChild<LLUICtrl>("classifieds_edit")->getValue().asString(); + search_results->setEnabled(FALSE); + search_results->setCommentText(LLTrans::getString("not_found", map)); + } + else + { + LL_DEBUGS("Search") << "Got: " << name << " ClassifiedID: " << classified_id << LL_ENDL; + search_results->setEnabled(TRUE); + found_one = true; + + LLSD content; + LLSD element; + + element["id"] = classified_id; + + element["columns"][0]["column"] = "icon"; + element["columns"][0]["type"] = "icon"; + element["columns"][0]["value"] = "icon_top_pick.tga"; + + element["columns"][1]["column"] = "classified_name"; + element["columns"][1]["value"] = name; + + element["columns"][2]["column"] = "price"; + element["columns"][2]["value"] = price_for_listing; + + content["name"] = name; + + search_results->addElement(element, ADD_BOTTOM); + self->mResultsContent[classified_id.asString()] = content; + } + } + if (found_one) + { + search_results->selectFirstItem(); + search_results->setFocus(TRUE); + self->onSelectItem(); + } +} + +//////////////////////////////////////// +// Events Search Panel // +//////////////////////////////////////// + +static LLPanelInjector<FSPanelSearchEvents> t_panel_fs_search_events("panel_ls_events"); + +FSPanelSearchEvents::FSPanelSearchEvents() : FSSearchPanelBase() +, mQueryID(nullptr) +, mResultsReceived(0) +, mStartSearch(0) +, mDay(0) +, mResultsContent() +{ + mCommitCallbackRegistrar.add("CommitSearch", boost::bind(&FSPanelSearchEvents::find, this)); +} + +FSPanelSearchEvents::~FSPanelSearchEvents() +{ +} + +bool FSPanelSearchEvents::postBuild() +{ + mSearchComboBox = findChild<LLSearchComboBox>("events_edit"); + mSearchResults = getChild<LLScrollListCtrl>("search_results_events"); + mEventsMode = findChild<LLRadioGroup>("events_search_mode"); + if (mSearchComboBox) + { + mSearchComboBox->setCommitCallback(boost::bind(&FSPanelSearchEvents::onBtnFind, this)); + fillSearchComboBox(mSearchComboBox); + } + if (mSearchResults) + { + mSearchResults->setCommitCallback(boost::bind(&FSPanelSearchEvents::onSelectItem, this)); + mSearchResults->setEnabled(FALSE); + mSearchResults->setCommentText(LLTrans::getString("no_results")); + } + if (mEventsMode) + { + mEventsMode->setCommitCallback(boost::bind(&FSPanelSearchEvents::onSearchModeChanged, this)); + mEventsMode->selectFirstItem(); + } + + childSetAction("events_next", boost::bind(&FSPanelSearchEvents::onBtnNext, this)); + childSetAction("events_back", boost::bind(&FSPanelSearchEvents::onBtnBack, this)); + childSetAction("events_tomorrow", boost::bind(&FSPanelSearchEvents::onBtnTomorrow, this)); + childSetAction("events_yesterday", boost::bind(&FSPanelSearchEvents::onBtnYesterday, this)); + childSetAction("events_today", boost::bind(&FSPanelSearchEvents::onBtnToday, this)); + + getChildView("events_next")->setEnabled(FALSE); + getChildView("events_back")->setEnabled(FALSE); + getChildView("events_tomorrow")->setEnabled(FALSE); + getChildView("events_yesterday")->setEnabled(FALSE); + getChildView("events_today")->setEnabled(FALSE); + setDay(0); + + return TRUE; +} + +void FSPanelSearchEvents::focusDefaultElement() +{ + mSearchComboBox->focusTextEntry(); +} + +void FSPanelSearchEvents::find() +{ + std::string text = filterShortWords(mSearchComboBox->getSimple()); + + static LLUICachedControl<bool> inc_pg("ShowPGEvents", 1); + static LLUICachedControl<bool> inc_mature("ShowMatureEvents", 0); + static LLUICachedControl<bool> inc_adult("ShowAdultEvents", 0); + if (!(inc_pg || inc_mature || inc_adult)) + { + LLNotificationsUtil::add("NoContentToSearch"); + return; + } + + U32 category = findChild<LLComboBox>("events_category")->getSelectedValue().asInteger(); + U32 scope = DFQ_DATE_EVENTS; + if (gAgent.wantsPGOnly()) + { + scope |= DFQ_PG_SIMS_ONLY; + } + bool mature_enabled = gAgent.canAccessMature(); + bool adult_enabled = gAgent.canAccessAdult(); + if (inc_pg) + { + scope |= DFQ_INC_PG; + } + if (inc_mature && mature_enabled) + { + scope |= DFQ_INC_MATURE; + } + if (inc_adult && adult_enabled) + { + scope |= DFQ_INC_ADULT; + } + + std::ostringstream string; + + if ("current" == childGetValue("events_search_mode").asString()) + { + string << "u|"; + } + else + { + string << mDay << "|"; + } + string << category << "|"; + string << text; + + mResultsReceived = 0; + if (mQueryID.notNull()) + { + mQueryID.setNull(); + } + mQueryID.generate(); + + if (mStartSearch < 0) + { + mStartSearch = 0; + } + + gMessageSystem->newMessage("DirFindQuery"); + gMessageSystem->nextBlock("AgentData"); + gMessageSystem->addUUID("AgentID", gAgentID); + gMessageSystem->addUUID("SessionID", gAgentSessionID); + gMessageSystem->nextBlock("QueryData"); + gMessageSystem->addUUID("QueryID", getQueryID()); + gMessageSystem->addString("QueryText", string.str()); + gMessageSystem->addU32("QueryFlags", scope); + gMessageSystem->addS32("QueryStart", mStartSearch); + gAgent.sendReliableMessage(); + LL_INFOS("Search") << "Firing off search request: " << getQueryID() << " Search Text: " << string.str() << LL_ENDL; + + mSearchResults->deleteAllItems(); + mSearchResults->setCommentText(LLTrans::getString("searching")); + mNumResultsReturned = 0; +} + +void FSPanelSearchEvents::onBtnFind() +{ + std::chrono::time_point<std::chrono::system_clock> now = std::chrono::system_clock::now(); + auto elapsed = now - lastRequestTime; + U64 elapsedMS = std::chrono::duration_cast<std::chrono::milliseconds>(elapsed).count(); + if(elapsedMS < REQUEST_MIN_ELAPSED_TIME) return; + lastRequestTime = now; + + std::string text = mSearchComboBox->getSimple(); + if (!text.empty()) + { + LLSearchHistory::getInstance()->addEntry(text); + } + + resetSearch(); + + find(); +} + +void FSPanelSearchEvents::onBtnNext() +{ + mStartSearch += RESULT_PAGE_SIZE; + getChildView("events_back")->setEnabled(TRUE); + + find(); +} + +void FSPanelSearchEvents::onBtnBack() +{ + mStartSearch -= RESULT_PAGE_SIZE; + getChildView("events_back")->setEnabled(mStartSearch > 0); + + find(); +} + +void FSPanelSearchEvents::onBtnTomorrow() +{ + resetSearch(); + setDay(mDay + 1); + + find(); +} + +void FSPanelSearchEvents::onBtnYesterday() +{ + resetSearch(); + setDay(mDay - 1); + + find(); +} + +void FSPanelSearchEvents::onBtnToday() +{ + resetSearch(); + setDay(0); + + find(); +} + +void FSPanelSearchEvents::resetSearch() +{ + mStartSearch = 0; + getChildView("events_back")->setEnabled(FALSE); + getChildView("events_next")->setEnabled(FALSE); +} + +void FSPanelSearchEvents::onSearchModeChanged() +{ + if (mEventsMode->getValue().asString() == "current") + { + getChildView("events_yesterday")->setEnabled(FALSE); + getChildView("events_tomorrow")->setEnabled(FALSE); + getChildView("events_today")->setEnabled(FALSE); + } + else + { + getChildView("events_yesterday")->setEnabled(TRUE); + getChildView("events_tomorrow")->setEnabled(TRUE); + getChildView("events_today")->setEnabled(TRUE); + } +} + +void FSPanelSearchEvents::setDay(S32 day) +{ + mDay = day; + struct tm* internal_time; + + time_t utc = time_corrected(); + utc += day * 24 * 60 * 60; + internal_time = utc_to_pacific_time(utc, is_daylight_savings()); + std::string buffer = llformat("%d/%d", 1 + internal_time->tm_mon, internal_time->tm_mday); + childSetValue("events_date", buffer); +} + +S32 FSPanelSearchEvents::showNextButton(S32 rows) +{ + bool show_next_button = (mResultsReceived > RESULT_PAGE_SIZE); + getChildView("events_next")->setEnabled(show_next_button); + if (show_next_button) + { + rows -= (mResultsReceived - RESULT_PAGE_SIZE); + } + return rows; +} + +void FSPanelSearchEvents::onSelectItem() +{ + if (!mSearchResults) + { + return; + } + S32 event_id = mSearchResults->getSelectedValue(); + FSFloaterSearch* search_instance = LLFloaterReg::findTypedInstance<FSFloaterSearch>("search"); + if (search_instance) + { + search_instance->FSFloaterSearch::onSelectedEvent(event_id); + } +} + +// static +void FSPanelSearchEvents::processSearchReply(LLMessageSystem* msg, void**) +{ + LLUUID agent_id; + LLUUID query_id; + LLUUID owner_id; + std::string name; + std::string date; + + msg->getUUID("AgentData", "AgentID", agent_id); + msg->getUUID("QueryData", "QueryID", query_id); + + // Not for us + if (agent_id != gAgentID) + { + return; + } + LL_DEBUGS("Search") << "received directory request - QueryID: " << query_id << " AgentID: " << agent_id << LL_ENDL; + + FSPanelSearchEvents* self = FSFloaterSearch::getSearchPanel<FSPanelSearchEvents>("panel_ls_events"); + + // floater is closed or these are not results from our last request + if (!self || query_id != self->mQueryID) + { + return; + } + + LLScrollListCtrl* search_results = self->getChild<LLScrollListCtrl>("search_results_events"); + + // Clear "Searching" label on first results + if (self->mNumResultsReturned++ == 0) + { + search_results->deleteAllItems(); + } + // Check for status messages + if (msg->getNumberOfBlocks("StatusData")) + { + U32 status; + msg->getU32("StatusData", "Status", status); + if (status & STATUS_SEARCH_EVENTS_FOUNDNONE) + { + LLStringUtil::format_map_t map; + map["[TEXT]"] = self->getChild<LLUICtrl>("events_edit")->getValue().asString(); + search_results->setEnabled(FALSE); + search_results->setCommentText(LLTrans::getString("not_found", map)); + return; + } + else if(status & STATUS_SEARCH_EVENTS_SHORTSTRING) + { + search_results->setEnabled(FALSE); + search_results->setCommentText(LLTrans::getString("search_short")); + return; + } + else if (status & STATUS_SEARCH_EVENTS_BANNEDWORD) + { + search_results->setEnabled(FALSE); + search_results->setCommentText(LLTrans::getString("search_banned")); + return; + } + else if (status & STATUS_SEARCH_EVENTS_SEARCHDISABLED) + { + search_results->setEnabled(FALSE); + search_results->setCommentText(LLTrans::getString("search_disabled")); + return; + } + else if (status & STATUS_SEARCH_EVENTS_NODATEOFFSET) + { + search_results->setEnabled(FALSE); + search_results->setCommentText(LLTrans::getString("search_no_date_offset")); + return; + } + else if (status & STATUS_SEARCH_EVENTS_NOCATEGORY) + { + search_results->setEnabled(FALSE); + search_results->setCommentText(LLTrans::getString("search_no_events_category")); + return; + } + else if (status & STATUS_SEARCH_EVENTS_NOQUERY) + { + search_results->setEnabled(FALSE); + search_results->setCommentText(LLTrans::getString("search_no_query")); + return; + } + } + + S32 num_new_rows = msg->getNumberOfBlocks("QueryReplies"); + if (num_new_rows == 0 && self->mResultsReceived == 0) + { + LLStringUtil::format_map_t map; + map["[TEXT]"] = self->getChild<LLUICtrl>("events_edit")->getValue().asString(); + search_results->setEnabled(FALSE); + search_results->setCommentText(LLTrans::getString("not_found", map)); + } + + self->mResultsReceived += num_new_rows; + num_new_rows = self->showNextButton(num_new_rows); + static LLUICachedControl<bool> inc_pg("ShowPGEvents", 1); + static LLUICachedControl<bool> inc_mature("ShowMatureEvents", 0); + static LLUICachedControl<bool> inc_adult("ShowAdultEvents", 0); + bool found_one = false; + + for (S32 i = 0; i < num_new_rows; i++) + { + U32 event_id; + U32 unix_time; + U32 event_flags; + + msg->getUUID( "QueryReplies", "OwnerID", owner_id, i); + msg->getString( "QueryReplies", "Name", name, i); + msg->getU32( "QueryReplies", "EventID", event_id, i); + msg->getString( "QueryReplies", "Date", date, i); + msg->getU32( "QueryReplies", "UnixTime", unix_time, i); + msg->getU32( "QueryReplies", "EventFlags", event_flags,i); + + // Skip empty events... + if (owner_id.isNull()) + { + LL_INFOS("Search") << "Skipped " << event_id << " because of a nullptr owner result" << LL_ENDL; + continue; + } + // Skips events that don't match our scope... + if (((event_flags & (EVENT_FLAG_ADULT | EVENT_FLAG_MATURE)) == EVENT_FLAG_NONE) && !inc_pg) + { + LL_INFOS("Search") << "Skipped " << event_id << " because it was out of scope" << LL_ENDL; + continue; + } + if ((event_flags & EVENT_FLAG_MATURE) && !inc_mature) + { + LL_INFOS("Search") << "Skipped " << event_id << " because it was out of scope" << LL_ENDL; + continue; + } + if ((event_flags & EVENT_FLAG_ADULT) && !inc_adult) + { + LL_INFOS("Search") << "Skipped " << event_id << " because it was out of scope" << LL_ENDL; + continue; + } + search_results->setEnabled(TRUE); + found_one = true; + + LLSD content; + LLSD element; + + element["id"] = llformat("%u", event_id); + + if (event_flags == EVENT_FLAG_ADULT) + { + element["columns"][0]["column"] = "icon"; + element["columns"][0]["type"] = "icon"; + element["columns"][0]["value"] = "Icon_Legacy_Event_Adult"; + } + else if (event_flags == EVENT_FLAG_MATURE) + { + element["columns"][0]["column"] = "icon"; + element["columns"][0]["type"] = "icon"; + element["columns"][0]["value"] = "Icon_Legacy_Event_Mature"; + } + else + { + element["columns"][0]["column"] = "icon"; + element["columns"][0]["type"] = "icon"; + element["columns"][0]["value"] = "Icon_Legacy_Event_PG"; + } + element["columns"][1]["column"] = "name"; + element["columns"][1]["value"] = name; + + element["columns"][2]["column"] = "date"; + element["columns"][2]["value"] = date; + + element["columns"][3]["column"] = "time"; + element["columns"][3]["value"] = llformat("%u", unix_time); + + content["name"] = name; + content["event_id"] = (S32)event_id; + + search_results->addElement(element, ADD_BOTTOM); + std::string event = llformat("%u", event_id); + self->mResultsContent[event] = content; + } + if (found_one) + { + search_results->selectFirstItem(); + search_results->setFocus(TRUE); + self->onSelectItem(); + } +} + +//////////////////////////////////////// +// WebSearch Panel // +//////////////////////////////////////// + +static LLPanelInjector<FSPanelSearchWeb> t_panel_fs_search_web("panel_ls_web"); + +FSPanelSearchWeb::FSPanelSearchWeb() : FSSearchPanelBase() +, mWebBrowser(nullptr) +, mResetFocusOnLoad(false) +{ + // Second Life grids use a different URL format now + mCategoryPaths = LLSD::emptyMap(); + if (LLGridManager::getInstance()->isInSecondlife()) + { + // declare a map that transforms a category name into + // the parameter list that is used to search that category + mCategoryPaths["people"] = "collection_chosen=people"; + mCategoryPaths["places"] = "collection_chosen=places"; + mCategoryPaths["events"] = "collection_chosen=events"; + mCategoryPaths["groups"] = "collection_chosen=groups"; + mCategoryPaths["destinations"] = "collection_chosen=destinations"; + + mCategoryPaths["classifieds"] = "search_type=classified"; + mCategoryPaths["wiki"] = "search/wiki"; // not sure if this is still a thing in the new search + + mCategoryPaths["all"] = mCategoryPaths["people"].asString() + "&" + + mCategoryPaths["places"].asString() + "&" + + mCategoryPaths["events"].asString() + "&" + + mCategoryPaths["groups"].asString() + "&" + + mCategoryPaths["destinations"].asString(); + } + // OpenSim currently still uses the old URL format + else + { + // declare a map that transforms a category name into + // the URL suffix that is used to search that category + mCategoryPaths["all"] = "search"; + mCategoryPaths["people"] = "search/people"; + mCategoryPaths["places"] = "search/places"; + mCategoryPaths["events"] = "search/events"; + mCategoryPaths["groups"] = "search/groups"; + mCategoryPaths["wiki"] = "search/wiki"; + mCategoryPaths["destinations"] = "destinations"; + mCategoryPaths["classifieds"] = "classifieds"; + } +} + +bool FSPanelSearchWeb::postBuild() +{ + mWebBrowser = getChild<LLMediaCtrl>("search_browser"); + return TRUE; +} + +void FSPanelSearchWeb::loadURL(const SearchQuery &p) +{ + if (!mWebBrowser || !p.validateBlock()) + { + return; + } + + // CATEGORY is no longer used as part of the path on Second Life grids + LLSD subs = LLSD().with("CATEGORY", ""); + + // on OpenSim grids it probably is currently still being used, so keep the old behavior + if (!LLGridManager::getInstance()->isInSecondlife()) + { + // work out the subdir to use based on the requested category + LLSD subs = LLSD().with("CATEGORY", (mCategoryPaths.has(p.category.getValue()) ? mCategoryPaths[p.category.getValue()].asString() : mCategoryPaths["all"].asString())); + } + + // add the search query string + subs["QUERY"] = LLURI::escape(p.query.getValue()); + + // add the permissions token that login.cgi gave us + // We use "search_token", and fallback to "auth_token" if not present. + LLSD search_token = LLLoginInstance::getInstance()->getResponse("search_token"); + if (search_token.asString().empty()) + { + search_token = LLLoginInstance::getInstance()->getResponse("auth_token"); + } + subs["AUTH_TOKEN"] = search_token.asString(); + + // add the user's preferred maturity (can be changed via prefs) + std::string maturity; + + // on Second Life grids, the maturity level is now a "&maturity" parameter that's not in the provided search URL + if (LLGridManager::getInstance()->isInSecondlife()) + { + if (gAgent.prefersAdult()) + { + maturity = "gma"; // PG,Mature,Adult + } + else if (gAgent.prefersMature()) + { + maturity = "gm"; // PG,Mature + } + else + { + maturity = "g"; // PG + } + + // not used on the SL search anymore, so clear out the respective parameter + subs["MATURITY"] = ""; + } + // OpenSim probably still uses the old maturity variant, so keep the old behavior here + else + { + if (gAgent.prefersAdult()) + { + maturity = "42"; // PG,Mature,Adult + } + else if (gAgent.prefersMature()) + { + maturity = "21"; // PG,Mature + } + else + { + maturity = "13"; // PG + } + subs["MATURITY"] = maturity; + } + + // add the user's god status + subs["GODLIKE"] = gAgent.isGodlike() ? "1" : "0"; + + // Get the search URL and expand all of the substitutions + // (also adds things like [LANGUAGE], [VERSION], [OS], etc.) + + // add the maturity and category variables to the new Second Life search URL + //std::string url = gAgent.getRegion() != nullptr ? gAgent.getRegion()->getSearchServerURL() : gSavedSettings.getString(LLGridManager::getInstance()->isInOpenSim() ? "OpenSimSearchURL" : "SearchURL"); + + std::string url = gSavedSettings.getString("SearchURL"); + + if (LLGridManager::getInstance()->isInSecondlife()) + { + url.append("&maturity=" + maturity + "&" + mCategoryPaths[p.category.getValue()].asString()); + } + + url = LLWeb::expandURLSubstitutions(url, subs); + + // Finally, load the URL in the webpanel + mWebBrowser->navigateTo(url, HTTP_CONTENT_TEXT_HTML); +} + +void FSPanelSearchWeb::focusDefaultElement() +{ + mWebBrowser->setFocus(TRUE); +} + +void FSPanelSearchWeb::draw() +{ + if (mResetFocusOnLoad) + { + focusDefaultElement(); + mResetFocusOnLoad = false; + } + + FSSearchPanelBase::draw(); +} + +//////////////////////////////////////// +// Local functions // +//////////////////////////////////////// + +std::string filterShortWords(std::string query_string) +{ + if (query_string.length() < 1) + { + return ""; + } + + std::string final_query; + bool filtered = false; + boost::char_separator<char> sep(" "); + boost::tokenizer<boost::char_separator<char> > tokens(query_string, sep); + boost::tokenizer<boost::char_separator<char> >::iterator iter = tokens.begin(); + boost::tokenizer<boost::char_separator<char> >::iterator last = tokens.end(); + boost::tokenizer<boost::char_separator<char> >::iterator temp; + for (; iter != last; ++iter) + { + if ((*iter).length() > MIN_SEARCH_STRING_SIZE) + { + final_query.append((*iter)); + temp = iter; ++temp; + if (temp != last) + { + final_query.append(" "); + } + } + else + { + filtered = true; + } + } + + if (filtered) + { + LLSD args = LLSD().with("FINALQUERY", final_query); + LLNotificationsUtil::add("SeachFilteredOnShortWords", args); + } + + return final_query; +} + +void fillSearchComboBox(LLSearchComboBox* search_combo) +{ + if (search_combo == nullptr) + { + return; + } + + LLSearchHistory::getInstance()->load(); + + LLSearchHistory::search_history_list_t search_list = + LLSearchHistory::getInstance()->getSearchHistoryList(); + LLSearchHistory::search_history_list_t::const_iterator it = search_list.begin(); + for ( ; search_list.end() != it; ++it) + { + LLSearchHistory::LLSearchHistoryItem item = *it; + search_combo->add(item.search_query); + } +} diff --git a/indra/newview/fsfloatersearch.h b/indra/newview/fsfloatersearch.h new file mode 100644 index 0000000000..90e2a8cb89 --- /dev/null +++ b/indra/newview/fsfloatersearch.h @@ -0,0 +1,404 @@ +/** + * @file fsfloatersearch.h + * @brief Firestorm search definitions + * + * $LicenseInfo:firstyear=2012&license=fsviewerlgpl$ + * Phoenix Firestorm Viewer Source Code + * Copyright (C) 2012, Cinder Roxley <cinder.roxley@phoenixviewer.com> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * The Phoenix Firestorm Project, Inc., 1831 Oakwood Drive, Fairmont, Minnesota 56031-3225 USA + * http://www.firestormviewer.org + * $/LicenseInfo$ + */ + +#ifndef FS_FLOATERSEARCH_H +#define FS_FLOATERSEARCH_H + +#include "llfloater.h" +#include "lliconctrl.h" +#include "lltexteditor.h" +#include "lltexturectrl.h" +#include "llremoteparcelrequest.h" +#include "llavatarpropertiesprocessor.h" +#include "llgroupmgr.h" +#include "llavatarnamecache.h" +#include "llmediactrl.h" +#include "llradiogroup.h" +#include "llsearchcombobox.h" +#include "llscrolllistctrl.h" +#include "lltabcontainer.h" +#include "lleventnotifier.h" + +class FSSearchRemoteParcelInfoObserver; +class LLAvatarPropertiesObserver; +class LLGroupMgrObserver; +class LLSearchEditor; +class LLSearchComboBox; +class FSFloaterSearch; +class LLPanelProfile; +class FSScrollListCtrl; + +struct SearchQuery : public LLInitParam::Block<SearchQuery> +{ + Optional<std::string> category; + Optional<std::string> query; + + SearchQuery(); +}; + +/////////////////////////////// +// Search Panels // +/////////////////////////////// + +class FSSearchPanelBase : public LLPanel +{ +public: + FSSearchPanelBase() : LLPanel() { } + virtual ~FSSearchPanelBase() = default; + virtual void focusDefaultElement() { } +}; + +class FSPanelSearchPeople : public FSSearchPanelBase +{ + LOG_CLASS(FSFloaterSearch); +public: + FSPanelSearchPeople(); + static void processSearchReply(LLMessageSystem* msg, void**); + + /*virtual*/ void focusDefaultElement(); + +protected: + const S32& getNumResultsReturned() const { return mNumResultsReturned; }; + const S32& getNumResultsReceived() const { return mResultsReceived; }; + +private: + /*virtual*/ bool postBuild(); + virtual ~FSPanelSearchPeople(); + + void onBtnFind(); + void onSelectItem(); + void onBtnNext(); + void onBtnBack(); + + void find(); + void resetSearch(); + S32 showNextButton(S32); + + const LLUUID& getQueryID() const { return mQueryID; } + + void onAvatarNameCallback(const LLUUID& id, const LLAvatarName& av_name); + + typedef boost::signals2::connection avatar_name_callback_connection_t; + avatar_name_callback_connection_t mAvatarNameCallbackConnection; + + S32 mNumResultsReturned; + S32 mStartSearch; + S32 mResultsReceived; + LLSD mResultsContent; + LLUUID mQueryID; + + LLSearchComboBox* mSearchComboBox; + LLScrollListCtrl* mSearchResults; +}; + +class FSPanelSearchGroups : public FSSearchPanelBase +{ + LOG_CLASS(FSFloaterSearch); +public: + FSPanelSearchGroups(); + static void processSearchReply(LLMessageSystem* msg, void**); + + /*virtual*/ void focusDefaultElement(); + +private: + /*virtual*/ bool postBuild(); + virtual ~FSPanelSearchGroups(); + + void onBtnFind(); + void onSelectItem(); + void onBtnNext(); + void onBtnBack(); + + void find(); + void resetSearch(); + S32 showNextButton(S32); + + const LLUUID& getQueryID() const { return mQueryID; } + + S32 mNumResultsReturned; + S32 mStartSearch; + S32 mResultsReceived; + LLSD mResultsContent; + LLUUID mQueryID; + + LLSearchComboBox* mSearchComboBox; + LLScrollListCtrl* mSearchResults; +}; + +class FSPanelSearchPlaces : public FSSearchPanelBase +{ + LOG_CLASS(FSFloaterSearch); +public: + FSPanelSearchPlaces(); + static void processSearchReply(LLMessageSystem* msg, void**); + + /*virtual*/ void focusDefaultElement(); + +private: + /*virtual*/ bool postBuild(); + virtual ~FSPanelSearchPlaces(); + + void onBtnFind(); + void onSelectItem(); + void onBtnNext(); + void onBtnBack(); + + void find(); + void resetSearch(); + S32 showNextButton(S32); + + const LLUUID& getQueryID() const { return mQueryID; } + + S32 mNumResultsReturned; + S32 mStartSearch; + S32 mResultsReceived; + LLSD mResultsContent; + LLUUID mQueryID; + + LLSearchComboBox* mSearchComboBox; + LLScrollListCtrl* mSearchResults; + LLComboBox* mPlacesCategory; +}; + +class FSPanelSearchLand : public FSSearchPanelBase +{ + LOG_CLASS(FSFloaterSearch); +public: + FSPanelSearchLand(); + static void processSearchReply(LLMessageSystem* msg, void**); + +private: + /*virtual*/ bool postBuild(); + virtual ~FSPanelSearchLand(); + + void onBtnFind(); + void onSelectItem(); + void onBtnNext(); + void onBtnBack(); + + void find(); + void resetSearch(); + S32 showNextButton(S32); + + const LLUUID& getQueryID() const { return mQueryID; } + + S32 mNumResultsReturned; + S32 mStartSearch; + S32 mResultsReceived; + LLSD mResultsContent; + LLUUID mQueryID; + + LLLineEditor* mPriceEditor; + LLLineEditor* mAreaEditor; + LLScrollListCtrl* mSearchResults; +}; + +class FSPanelSearchClassifieds : public FSSearchPanelBase +{ + LOG_CLASS(FSFloaterSearch); +public: + FSPanelSearchClassifieds(); + static void processSearchReply(LLMessageSystem* msg, void**); + + /*virtual*/ void focusDefaultElement(); + +private: + /*virtual*/ bool postBuild(); + virtual ~FSPanelSearchClassifieds(); + + void onBtnFind(); + void onSelectItem(); + void onBtnNext(); + void onBtnBack(); + + void find(); + void resetSearch(); + S32 showNextButton(S32); + + const LLUUID& getQueryID() const { return mQueryID; } + + S32 mNumResultsReturned; + S32 mStartSearch; + S32 mResultsReceived; + LLSD mResultsContent; + LLUUID mQueryID; + + LLSearchComboBox* mSearchComboBox; + LLScrollListCtrl* mSearchResults; + LLComboBox* mClassifiedsCategory; +}; + +class FSPanelSearchEvents : public FSSearchPanelBase +{ + LOG_CLASS(FSFloaterSearch); +public: + FSPanelSearchEvents(); + static void processSearchReply(LLMessageSystem* msg, void**); + + /*virtual*/ void focusDefaultElement(); + +private: + /*virtual*/ bool postBuild(); + virtual ~FSPanelSearchEvents(); + + void onBtnFind(); + void onSelectItem(); + void onBtnNext(); + void onBtnBack(); + void onBtnTomorrow(); + void onBtnYesterday(); + void onBtnToday(); + + void find(); + void setDay(S32 day); + void onSearchModeChanged(); + void resetSearch(); + S32 showNextButton(S32); + + const LLUUID& getQueryID() const { return mQueryID; } + + S32 mNumResultsReturned; + S32 mResultsReceived; + S32 mStartSearch; + S32 mDay; + LLSD mResultsContent; + LLUUID mQueryID; + + LLSearchComboBox* mSearchComboBox; + LLScrollListCtrl* mSearchResults; + LLRadioGroup* mEventsMode; +}; + +class FSPanelSearchWeb : public FSSearchPanelBase +{ + LOG_CLASS(FSFloaterSearch); +public: + FSPanelSearchWeb(); + /*virtual*/ bool postBuild(); + void loadURL(const SearchQuery &query); + /*virtual*/ void focusDefaultElement(); + /*virtual*/ void draw(); + void resetFocusOnLoad() { mResetFocusOnLoad = true; } + +private: + virtual ~FSPanelSearchWeb() {}; + + LLMediaCtrl* mWebBrowser; + LLSD mCategoryPaths; + + bool mResetFocusOnLoad; +}; + +class FSFloaterSearch : public LLFloater +{ + LOG_CLASS(FSFloaterSearch); +public: + typedef enum e_search_category + { + SC_AVATAR, + SC_GROUP, + SC_PLACE, + SC_CLASSIFIED + } ESearchCategory; + + struct _Params : public LLInitParam::Block<_Params, LLFloater::Params> + { + Optional<SearchQuery> search; + }; + + typedef LLSDParamAdapter<_Params> Params; + + FSFloaterSearch(const Params& key); + ~FSFloaterSearch(); + void onOpen(const LLSD& key); + bool postBuild(); + + void avatarNameUpdatedCallback(const LLUUID& id, const LLAvatarName& av_name); + void groupNameUpdatedCallback(const LLUUID& id, const std::string& name, bool is_group); + void onSelectedItem(const LLUUID& selected_item, ESearchCategory type); + void onSelectedEvent(const S32 selected_event); + void displayParcelDetails(const LLParcelData& parcel_data); + void displayClassifiedDetails(LLAvatarClassifiedInfo*& c_info); + void displayAvatarDetails(LLAvatarData* avatar_data); + void displayGroupDetails(LLGroupMgrGroupData*& group_data); + bool displayEventDetails(LLEventStruct event); + void displayEventParcelImage(const LLParcelData& parcel_data); + void setLoadingProgress(bool started); + + template <class T> + static T* getSearchPanel(const std::string& panel_name); + +private: + virtual void onClose(bool app_quitting); + const LLUUID& getSelectedID() { return mSelectedID; } + LLVector3d mParcelGlobal; + LLUUID mSelectedID; + U32 mEventID; + bool mHasSelection; + + void resetVerbs(); + void flushDetails(); + void onTabChange(); + void onBtnPeopleProfile(); + void onBtnPeopleIM(); + void onBtnPeopleFriend(); + void onBtnGroupProfile(); + void onBtnGroupChat(); + void onBtnGroupJoin(); + void onBtnEventReminder(); + void onBtnTeleport(); + void onBtnMap(); + + void regionHandleCallback(U64 region_handle, LLVector3d pos_global); + + FSSearchRemoteParcelInfoObserver* mRemoteParcelObserver; + FSSearchRemoteParcelInfoObserver* mRemoteParcelEventLocationObserver; + LLAvatarPropertiesObserver* mAvatarPropertiesObserver; + LLGroupMgrObserver* mGroupPropertiesRequest; + boost::signals2::connection mEventNotifierConnection; + + FSPanelSearchPeople* mPanelPeople; + FSPanelSearchGroups* mPanelGroups; + FSPanelSearchPlaces* mPanelPlaces; + FSPanelSearchEvents* mPanelEvents; + FSPanelSearchLand* mPanelLand; + FSPanelSearchClassifieds* mPanelClassifieds; + FSPanelSearchWeb* mPanelWeb; + + LLPanel* mDetailsPanel; + LLTextEditor* mDetailTitle; + LLTextEditor* mDetailDesc; + LLTextEditor* mDetailAux1; + LLTextEditor* mDetailAux2; + LLTextEditor* mDetailLocation; + LLTextureCtrl* mDetailSnapshot; + LLTextureCtrl* mDetailSnapshotParcel; + LLIconCtrl* mDetailMaturity; + LLTabContainer* mTabContainer; +}; + +#endif // FS_FLOATERSEARCH_H diff --git a/indra/newview/gltf/asset.cpp b/indra/newview/gltf/asset.cpp index c210b9c61d..a399a59f40 100644 --- a/indra/newview/gltf/asset.cpp +++ b/indra/newview/gltf/asset.cpp @@ -904,7 +904,7 @@ bool Asset::save(const std::string& filename) // save .gltf object obj; serialize(obj); - std::string buffer = boost::json::serialize(obj, {}); + std::string buffer = boost::json::serialize(obj); std::ofstream file(filename, std::ios::binary); file.write(buffer.c_str(), buffer.size()); diff --git a/indra/newview/gltf/common.h b/indra/newview/gltf/common.h index 742daff715..8cf3f1dff7 100644 --- a/indra/newview/gltf/common.h +++ b/indra/newview/gltf/common.h @@ -26,8 +26,6 @@ * $/LicenseInfo$ */ -#define GLM_ENABLE_EXPERIMENTAL 1 - #include "glm/vec2.hpp" #include "glm/vec3.hpp" #include "glm/vec4.hpp" diff --git a/indra/newview/gltf/primitive.cpp b/indra/newview/gltf/primitive.cpp index 81caff8ab2..5de45119fc 100644 --- a/indra/newview/gltf/primitive.cpp +++ b/indra/newview/gltf/primitive.cpp @@ -32,7 +32,11 @@ #include "mikktspace/mikktspace.hh" +#if LL_USESYSTEMLIBS +#include <meshoptimizer.h> +#else #include "meshoptimizer/meshoptimizer.h" +#endif using namespace LL::GLTF; diff --git a/indra/newview/gltfscenemanager.cpp b/indra/newview/gltfscenemanager.cpp index ed66753267..bf3fada3bd 100644 --- a/indra/newview/gltfscenemanager.cpp +++ b/indra/newview/gltfscenemanager.cpp @@ -69,9 +69,16 @@ void GLTFSceneManager::load() { return; } - if (filenames.size() > 0) + try + { + if (filenames.size() > 0) + { + GLTFSceneManager::instance().load(filenames[0]); + } + } + catch (std::bad_alloc&) { - GLTFSceneManager::instance().load(filenames[0]); + LLNotificationsUtil::add("CannotOpenFileTooBig"); } }, LLFilePicker::FFLOAD_GLTF, @@ -356,8 +363,9 @@ void GLTFSceneManager::addGLTFObject(LLViewerObject* obj, LLUUID gltf_id) llassert(obj->getVolume()->getParams().getSculptID() == gltf_id); llassert(obj->getVolume()->getParams().getSculptType() == LL_SCULPT_TYPE_GLTF); - if (obj->mGLTFAsset) - { // object already has a GLTF asset, don't reload it + if (obj->mGLTFAsset || obj->mIsGLTFAssetMissing ) + { + // object already has a GLTF asset or load failed, don't reload it // TODO: below assertion fails on dupliate requests for assets -- possibly need to touch up asset loading state machine // llassert(std::find(mObjects.begin(), mObjects.end(), obj) != mObjects.end()); @@ -398,16 +406,19 @@ void GLTFSceneManager::onGLTFBinLoadComplete(const LLUUID& id, LLAssetType::ETyp } else { - LL_WARNS("GLTF") << "Failed to prepare GLTF asset: " << id << LL_ENDL; + LL_WARNS("GLTF") << "Failed to prepare GLTF asset: " << id << ". Marking as missing." << LL_ENDL; + obj->mIsGLTFAssetMissing = true; obj->mGLTFAsset = nullptr; } } } + obj->unref(); // todo: use LLPointer } } else { - LL_WARNS("GLTF") << "Failed to load GLTF asset: " << id << LL_ENDL; + LL_WARNS("GLTF") << "Failed to load GLTF asset: " << id << ". Marking as missing." << LL_ENDL; + obj->mIsGLTFAssetMissing = true; obj->unref(); } }); @@ -446,7 +457,8 @@ void GLTFSceneManager::onGLTFLoadComplete(const LLUUID& id, LLAssetType::EType a } else { - LL_WARNS("GLTF") << "Buffer URI is not a valid UUID: " << buffer.mUri << LL_ENDL; + LL_WARNS("GLTF") << "Buffer URI is not a valid UUID: " << buffer.mUri << " for asset id: " << id << ". Marking as missing." << LL_ENDL; + obj->mIsGLTFAssetMissing = true; obj->unref(); return; } @@ -455,7 +467,8 @@ void GLTFSceneManager::onGLTFLoadComplete(const LLUUID& id, LLAssetType::EType a } else { - LL_WARNS("GLTF") << "Failed to load GLTF asset: " << id << LL_ENDL; + LL_WARNS("GLTF") << "Failed to load GLTF asset: " << id << ". Marking as missing." << LL_ENDL; + obj->mIsGLTFAssetMissing = true; obj->unref(); } } @@ -483,7 +496,7 @@ void GLTFSceneManager::update() { boost::json::object obj; mUploadingAsset->serialize(obj); - std::string buffer = boost::json::serialize(obj, {}); + std::string buffer = boost::json::serialize(obj); LLNewBufferedResourceUploadInfo::uploadFailure_f failure = [this](LLUUID assetId, LLSD response, std::string reason) { @@ -500,7 +513,7 @@ void GLTFSceneManager::update() LLNewBufferedResourceUploadInfo::uploadFinish_f finish = [this, buffer](LLUUID assetId, LLSD response) { LLAppViewer::instance()->postToMainCoro( - [=]() + [=, this]() { if (mUploadingAsset) { @@ -517,6 +530,7 @@ void GLTFSceneManager::update() if (mUploadingObject) { mUploadingObject->mGLTFAsset = nullptr; + mUploadingObject->mIsGLTFAssetMissing = false; mUploadingObject->setGLTFAsset(assetId); mUploadingObject->markForUpdate(); mUploadingObject = nullptr; @@ -975,9 +989,9 @@ void renderAssetDebug(LLViewerObject* obj, Asset* asset) LLVector4a t; agent_to_asset.affineTransform(gDebugRaycastStart, t); - start = glm::make_vec4(t.getF32ptr()); + start = vec4(t); agent_to_asset.affineTransform(gDebugRaycastEnd, t); - end = glm::make_vec4(t.getF32ptr()); + end = vec4(t); start.w = end.w = 1.0; diff --git a/indra/newview/icons/hicolor/128x128/apps/megapahit.png b/indra/newview/icons/hicolor/128x128/apps/megapahit.png Binary files differnew file mode 100644 index 0000000000..5ed63802d3 --- /dev/null +++ b/indra/newview/icons/hicolor/128x128/apps/megapahit.png diff --git a/indra/newview/icons/hicolor/256x256/apps/megapahit.png b/indra/newview/icons/hicolor/256x256/apps/megapahit.png Binary files differnew file mode 100644 index 0000000000..07deb76090 --- /dev/null +++ b/indra/newview/icons/hicolor/256x256/apps/megapahit.png diff --git a/indra/newview/icons/hicolor/48x48/apps/megapahit.png b/indra/newview/icons/hicolor/48x48/apps/megapahit.png Binary files differnew file mode 100644 index 0000000000..3189bb2c3d --- /dev/null +++ b/indra/newview/icons/hicolor/48x48/apps/megapahit.png diff --git a/indra/newview/icons/hicolor/512x512/apps/megapahit.png b/indra/newview/icons/hicolor/512x512/apps/megapahit.png Binary files differnew file mode 100644 index 0000000000..fdbec7e739 --- /dev/null +++ b/indra/newview/icons/hicolor/512x512/apps/megapahit.png diff --git a/indra/newview/icons/hicolor/64x64/apps/megapahit.png b/indra/newview/icons/hicolor/64x64/apps/megapahit.png Binary files differnew file mode 100644 index 0000000000..4917b1a825 --- /dev/null +++ b/indra/newview/icons/hicolor/64x64/apps/megapahit.png diff --git a/indra/newview/icons/hicolor/96x96/apps/megapahit.png b/indra/newview/icons/hicolor/96x96/apps/megapahit.png Binary files differnew file mode 100644 index 0000000000..ffe9066f4a --- /dev/null +++ b/indra/newview/icons/hicolor/96x96/apps/megapahit.png diff --git a/indra/newview/installers/darwin/dmg-cleanup.applescript b/indra/newview/installers/darwin/dmg-cleanup.applescript index 8a71b392f9..866bf31e8f 100755 --- a/indra/newview/installers/darwin/dmg-cleanup.applescript +++ b/indra/newview/installers/darwin/dmg-cleanup.applescript @@ -4,25 +4,43 @@ tell application "Finder" - set foo to every item in front window - repeat with i in foo - if the name of i is "Applications" then - set the position of i to {391, 165} - else if the name of i ends with ".app" then - set the position of i to {121, 166} - end if - end repeat + -- set foo to every item in front window + -- repeat with i in foo + -- if the name of i is "Applications" then + -- set the position of i to {391, 165} + -- else if the name of i ends with ".app" then + -- set the position of i to {121, 166} + -- end if + -- end repeat -- There doesn't seem to be a way to set the background picture with applescript, but all the saved .DS_Store files should already have that set correctly. - set foo to front window - set current view of foo to icon view - set toolbar visible of foo to false - set statusbar visible of foo to false - set the bounds of foo to {100, 100, 600, 449} + -- set foo to front window + -- set current view of foo to icon view + -- set toolbar visible of foo to false + -- set statusbar visible of foo to false + -- set the bounds of foo to {100, 100, 600, 449} -- set the position of front window to {100, 100} -- get {name, position} of every item of front window - get properties of front window + -- get properties of front window + + tell disk "Megapahit Installer" + open + set current view of container window to icon view + set toolbar visible of container window to false + set statusbar visible of container window to false + set the bounds of container window to {400, 100, 900, 500} + set theViewOptions to the icon view options of container window + set arrangement of theViewOptions to not arranged + set icon size of theViewOptions to 128 + set background picture of theViewOptions to file ".background:background.jpg" + make new alias file at container window to POSIX file "/Applications" with properties {name:"Applications"} + set position of item "Megapahit" of container window to {125, 160} + set position of item "Applications" of container window to {375, 160} + update without registering applications + delay 5 + close + end tell end tell diff --git a/indra/newview/installers/darwin/release-dmg/_VolumeIcon.icns b/indra/newview/installers/darwin/release-dmg/_VolumeIcon.icns Binary files differindex 272b496e7d..1be2300130 100644 --- a/indra/newview/installers/darwin/release-dmg/_VolumeIcon.icns +++ b/indra/newview/installers/darwin/release-dmg/_VolumeIcon.icns diff --git a/indra/newview/installers/darwin/release-dmg/background.jpg b/indra/newview/installers/darwin/release-dmg/background.jpg Binary files differindex e7064d9545..41c2bc320b 100644 --- a/indra/newview/installers/darwin/release-dmg/background.jpg +++ b/indra/newview/installers/darwin/release-dmg/background.jpg diff --git a/indra/newview/licenses-linux.txt b/indra/newview/licenses-linux.txt index e53ba94a36..23dace4de0 100644 --- a/indra/newview/licenses-linux.txt +++ b/indra/newview/licenses-linux.txt @@ -1,21 +1,3 @@ -=========== -APR License -=========== - -Copyright 2000-2004 The Apache Software Foundation - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - ============== Base32 License ============== @@ -69,43 +51,65 @@ NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +=========== +CEF License +=========== -Except as contained in this notice, the name of a copyright holder shall not -be used in advertising or otherwise to promote the sale, use or other dealings -in this Software without prior written authorization of the copyright holder. - +// Copyright (c) 2008-2020 Marshall A. Greenblatt. Portions Copyright (c) +// 2006-2009 Google Inc. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the name Chromium Embedded +// Framework nor the names of its contributors may be used to endorse +// or promote products derived from this software without specific prior +// written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -============= -expat License -============= -Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd +================ +Dullahan License +================ -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: +Copyright (c) 2016, Linden Research, Inc. -The above copyright notice and this permission notice shall be included -in all copies or substantial portions of the Software. +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. -================ -FreeType License -================ +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. -Portions of this software are copyright (c) 2003 The FreeType -Project (www.freetype.org). All rights reserved. ========================== FSI FontShop International @@ -126,10 +130,10 @@ obtain a license from FSI FontShop International at www.fontfont.com. GL License ========== -Mesa 3-D graphics library -Version: 6.2 +Mesa 3-D graphics library and Mesa Demos +Version: 6.2 and 8.5.0 -Copyright (C) 1999-2004 Brian Paul All Rights Reserved. +Copyright (C) 1999-2014 Brian Paul All Rights Reserved. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), @@ -191,122 +195,50 @@ Redistribution and use in source and binary forms, with or Cass Everitt - cass@r3.nu -======================= -JPEG Library 6b License -======================= - -This software is based in part on the work of the Independent JPEG Group - ================ -JPEG2000 License +OpenJPEG License ================ -Copyright 2001, David Taubman, The University of New South Wales (UNSW) -The copyright owner is Unisearch Ltd, Australia (commercial arm of UNSW) -Neither this copyright statement, nor the licensing details below -may be removed from this file or dissociated from its contents. - -Licensee: Linden Research, Inc. -License number: 00024 -The licensee has been granted a COMMERCIAL license to the contents of -this source file. A brief summary of this license appears below. This -summary is not to be relied upon in preference to the full text of the -license agreement, accepted at purchase of the license. -1. The Licensee has the right to Commercial Use of the Kakadu software, - including distribution of one or more Applications built using the - software. -2. The Licensee has the right to Internal Use of the Kakadu software, - including use by employees of the Licensee or an Affiliate for the - purpose of performing services on behalf of the Licensee or Affiliate, - or in the performance of services for Third Parties who engage Licensee - or an Affiliate for such services. -3. The Licensee has the right to distribute Reusable Code (including - source code and dynamically or statically linked libraries) to a Third - Party, provided the Third Party possesses a license to use the Kakadu - software. - -================== -ogg/vorbis License -================== - -Copyright (c) 2001, Xiphophorus - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: - -- Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. - -- Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. - -- Neither the name of the Xiphophorus nor the names of its contributors -may be used to endorse or promote products derived from this software -without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR -CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR -PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - -=========== -SDL License -=========== - -SDL - Simple DirectMedia Layer -Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 Sam Lantinga - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Library General Public -License as published by the Free Software Foundation; either -version 2 of the License, or (at your option) any later version. - -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 -Library General Public License for more details. - -You should have received a copy of the GNU Library General Public -License along with this library; if not, write to the Free -Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -Sam Lantinga -slouken@libsdl.org - -The GNU Library GPL is available at http://www.gnu.org/copyleft/lesser.html - -============= -ELFIO License -============= - -ELFIO.h - ELF reader and producer. -Copyright (C) 2001 Serge Lamikhov-Center <to_serge@users.sourceforge.net> - -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; either -version 2.1 of the License, or (at your option) any later version. - -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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +/* + * The copyright in this software is being made available under the 2-clauses + * BSD License, included below. This software may be subject to other third + * party and contributor rights, including patent rights, and no such rights + * are granted under this license. + * + * Copyright (c) 2002-2014, Universite catholique de Louvain (UCL), Belgium + * Copyright (c) 2002-2014, Professor Benoit Macq + * Copyright (c) 2003-2014, Antonin Descampe + * Copyright (c) 2003-2009, Francois-Olivier Devaux + * Copyright (c) 2005, Herve Drolon, FreeImage Team + * Copyright (c) 2002-2003, Yannick Verschueren + * Copyright (c) 2001-2003, David Janssens + * Copyright (c) 2011-2012, Centre National d'Etudes Spatiales (CNES), France + * Copyright (c) 2012, CS Systemes d'Information, France + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ -The GNU Library GPL is available at http://www.gnu.org/copyleft/lesser.html =============== OpenSSL License @@ -426,321 +358,6 @@ copied and put under another distribution licence [including the GNU Public Licence.] -================== -xmlrpc-epi License -================== - -Copyright 2000 Epinions, Inc. - -Subject to the following 3 conditions, Epinions, Inc. permits you, free of charge, to (a) use, copy, distribute, modify, perform and display this software and associated documentation files (the "Software"), and (b) permit others to whom the Software is furnished to do so as well. - -1) The above copyright notice and this permission notice shall be included without modification in all copies or substantial portions of the Software. - -2) THE SOFTWARE IS PROVIDED "AS IS", WITHOUT ANY WARRANTY OR CONDITION OF ANY KIND, EXPRESS, IMPLIED OR STATUTORY, INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES OF ACCURACY, MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT. - -3) IN NO EVENT SHALL EPINIONS, INC. BE LIABLE FOR ANY DIRECT, INDIRECT, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES OR LOST PROFITS ARISING OUT OF OR IN CONNECTION WITH THE SOFTWARE (HOWEVER ARISING, INCLUDING NEGLIGENCE), EVEN IF EPINIONS, INC. IS AWARE OF THE POSSIBILITY OF SUCH DAMAGES. - - -=============== -libuuid License -=============== - -Copyright (C) 1999, 2000, 2003, 2004 by Theodore Ts'o - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -1. Redistributions of source code must retain the above copyright - notice, and the entire permission notice in its entirety, - including the disclaimer of warranties. -2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. -3. The name of the author may not be used to endorse or promote - products derived from this software without specific prior - written permission. - -THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED -WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ALL OF -WHICH ARE HEREBY DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT -OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR -BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE -USE OF THIS SOFTWARE, EVEN IF NOT ADVISED OF THE POSSIBILITY OF SUCH -DAMAGE. - - -============ -zlib License -============ - -'zlib' general purpose compression library version 1.1.4, March 11th, 2002 - -Copyright (C) 1995-2002 Jean-loup Gailly and Mark Adler - -This software is provided 'as-is', without any express or implied warranty. -In no event will the authors be held liable for any damages arising from the -use of this software. - -Permission is granted to anyone to use this software for any purpose, -including commercial applications, and to alter it and redistribute it -freely, subject to the following restrictions: - -The origin of this software must not be misrepresented; you must not claim -that you wrote the original software. If you use this software in a product, -an acknowledgment in the product documentation would be appreciated but is -not required. - -Altered source versions must be plainly marked as such, and must not be -misrepresented as being the original software. - -This notice may not be removed or altered from any source distribution. - -Jean-loup Gailly -jloup@gzip.org - -Mark Adler -madler@alumni.caltech.edu - -================================= -tcmalloc/Google perftools license -================================= - -Copyright (c) 2005, Google Inc. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - - * Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above -copyright notice, this list of conditions and the following disclaimer -in the documentation and/or other materials provided with the -distribution. - * Neither the name of Google Inc. nor the names of its -contributors may be used to endorse or promote products derived from -this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -============== -libpng license -============== - -COPYRIGHT NOTICE, DISCLAIMER, and LICENSE: - -If you modify libpng you may insert additional notices immediately following -this sentence. - -libpng versions 1.2.6, August 15, 2004, through 1.2.18, May 15, 2007, are -Copyright (c) 2004, 2006-2007 Glenn Randers-Pehrson, and are -distributed according to the same disclaimer and license as libpng-1.2.5 -with the following individual added to the list of Contributing Authors: - - Cosmin Truta - -libpng versions 1.0.7, July 1, 2000, through 1.2.5, October 3, 2002, are -Copyright (c) 2000-2002 Glenn Randers-Pehrson, and are -distributed according to the same disclaimer and license as libpng-1.0.6 -with the following individuals added to the list of Contributing Authors: - - Simon-Pierre Cadieux - Eric S. Raymond - Gilles Vollant - -and with the following additions to the disclaimer: - - There is no warranty against interference with your enjoyment of the - library or against infringement. There is no warranty that our - efforts or the library will fulfill any of your particular purposes - or needs. This library is provided with all faults, and the entire - risk of satisfactory quality, performance, accuracy, and effort is with - the user. - -libpng versions 0.97, January 1998, through 1.0.6, March 20, 2000, are -Copyright (c) 1998, 1999, 2000 Glenn Randers-Pehrson, and are -distributed according to the same disclaimer and license as libpng-0.96, -with the following individuals added to the list of Contributing Authors: - - Tom Lane - Glenn Randers-Pehrson - Willem van Schaik - -libpng versions 0.89, June 1996, through 0.96, May 1997, are -Copyright (c) 1996, 1997 Andreas Dilger -Distributed according to the same disclaimer and license as libpng-0.88, -with the following individuals added to the list of Contributing Authors: - - John Bowler - Kevin Bracey - Sam Bushell - Magnus Holmgren - Greg Roelofs - Tom Tanner - -libpng versions 0.5, May 1995, through 0.88, January 1996, are -Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc. - -For the purposes of this copyright and license, "Contributing Authors" -is defined as the following set of individuals: - - Andreas Dilger - Dave Martindale - Guy Eric Schalnat - Paul Schmidt - Tim Wegner - -The PNG Reference Library is supplied "AS IS". The Contributing Authors -and Group 42, Inc. disclaim all warranties, expressed or implied, -including, without limitation, the warranties of merchantability and of -fitness for any purpose. The Contributing Authors and Group 42, Inc. -assume no liability for direct, indirect, incidental, special, exemplary, -or consequential damages, which may result from the use of the PNG -Reference Library, even if advised of the possibility of such damage. - -Permission is hereby granted to use, copy, modify, and distribute this -source code, or portions hereof, for any purpose, without fee, subject -to the following restrictions: - -1. The origin of this source code must not be misrepresented. - -2. Altered versions must be plainly marked as such and -must not be misrepresented as being the original source. - -3. This Copyright notice may not be removed or altered from - any source or altered source distribution. - -The Contributing Authors and Group 42, Inc. specifically permit, without -fee, and encourage the use of this source code as a component to -supporting the PNG file format in commercial products. If you use this -source code in a product, acknowledgment is not required but would be -appreciated. - -================= -Vivox SDK License -================= - -RSA Data Security, Inc. MD5 Message-Digest Algorithm - -Audio coding: Polycom(R) Siren14TM (ITU-T Rec. G.722.1 Annex C) - -Open Source Software Licensing -Each open source software component utilized by this product is subject to its own copyright and licensing terms, as listed below. - - -************************************************************* -************************************************************* - -/** - * OpenAL cross platform audio library - * Copyright (C) 1999-2000 by authors. - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * 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 - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - * Or go to http://www.gnu.org/copyleft/lgpl.html - */ - -************************************************************* -************************************************************* -RTP code under Lesser General Public License - -/* - The oRTP library is an RTP (Realtime Transport Protocol - rfc3550) stack. - Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org - - 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; either - version 2.1 of the License, or (at your option) any later version. - - 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ - -************************************************************ -************************************************************* - -/* - * The Vovida Software License, Version 1.0 - * - * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The names "VOCAL", "Vovida Open Communication Application Library", - * and "Vovida Open Communication Application Library (VOCAL)" must - * not be used to endorse or promote products derived from this - * software without prior written permission. For written - * permission, please contact vocal@vovida.org. - * - * 4. Products derived from this software may not be called "VOCAL", nor - * may "VOCAL" appear in their name, without prior written - * permission of Vovida Networks, Inc. - * - * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND - * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA - * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES - * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE - * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - * DAMAGE. - * - * - * This software consists of voluntary contributions made by Vovida - * Networks, Inc. and many individuals on behalf of Vovida Networks, - * Inc. For more information on Vovida Networks, Inc., please see - * - * - */ ************************************************************* ************************************************************* @@ -763,49 +380,54 @@ Internet Software Consortium code * SOFTWARE. */ -************************************************************* - -************************************************************* - -************************************************************ - -http://tinyxpath.sourceforge.net/ - -TinyXPath is covered by the zlib license : - - www.sourceforge.net/projects/tinyxpath - Copyright (c) 2002-2006 Yves Berquin (yvesb@users.sourceforge.net) +============= +meshoptimizer +============= +MIT License - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any - damages arising from the use of this software. +Copyright (c) 2016-2021 Arseny Kapoulkine - Permission is granted to anyone to use this software for any - purpose, including commercial applications, and to alter it and - redistribute it freely, subject to the following restrictions: +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: - 1. The origin of this software must not be misrepresented; you must - not claim that you wrote the original software. If you use this - software in a product, an acknowledgment in the product documentation - would be appreciated but is not required. +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. - 2. Altered source versions must be plainly marked as such, and - must not be misrepresented as being the original software. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. - 3. This notice may not be removed or altered from any source distribution. +============ +tinygltf +============ +MIT License -************************************************************ -************************************************************ +Copyright (c) 2017 Syoyo Fujita, Aurélien Chatelain and many contributors -THE FREE SOFTWARE FOUNDATION +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: -Any customer may request the source code for all open source portions of this product which are covered by the Free Software Foundation's General Public License (GPL), for a period of three years from purchase. Please contact the vendor from whom you obtained this product for instructions. A fee equivalent to the cost of making the code available may be charged. Alternatively, customers may choose to download desired GPL components directly from their original vendors. Specifically, this product contains the following GPL-licensed components: +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. -From Vivox: - - Assorted software components. To request source, contact Vivox at: - Vivox, Inc. - Attn: customer support - 40 Speen Street Suite 402 - Framingham, MA 01701 diff --git a/indra/newview/licenses-mac.txt b/indra/newview/licenses-mac.txt index 29b5a919bd..a3792f0b6b 100644 --- a/indra/newview/licenses-mac.txt +++ b/indra/newview/licenses-mac.txt @@ -48,6 +48,42 @@ Base32 License * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. + +=========== +CEF License +=========== + +// Copyright (c) 2008-2020 Marshall A. Greenblatt. Portions Copyright (c) +// 2006-2009 Google Inc. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the name Chromium Embedded +// Framework nor the names of its contributors may be used to endorse +// or promote products derived from this software without specific prior +// written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ============ cURL License ============ @@ -75,6 +111,31 @@ be used in advertising or otherwise to promote the sale, use or other dealings in this Software without prior written authorization of the copyright holder. +================ +Dullahan License +================ + +Copyright (c) 2016, Linden Research, Inc. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + + ============= expat License ============= @@ -198,32 +259,48 @@ JPEG Library 6b License This software is based in part on the work of the Independent JPEG Group ================ -JPEG2000 License +OpenJPEG License ================ -Copyright 2001, David Taubman, The University of New South Wales (UNSW) -The copyright owner is Unisearch Ltd, Australia (commercial arm of UNSW) -Neither this copyright statement, nor the licensing details below -may be removed from this file or dissociated from its contents. - -Licensee: Linden Research, Inc. -License number: 00024 -The licensee has been granted a COMMERCIAL license to the contents of -this source file. A brief summary of this license appears below. This -summary is not to be relied upon in preference to the full text of the -license agreement, accepted at purchase of the license. -1. The Licensee has the right to Commercial Use of the Kakadu software, - including distribution of one or more Applications built using the - software. -2. The Licensee has the right to Internal Use of the Kakadu software, - including use by employees of the Licensee or an Affiliate for the - purpose of performing services on behalf of the Licensee or Affiliate, - or in the performance of services for Third Parties who engage Licensee - or an Affiliate for such services. -3. The Licensee has the right to distribute Reusable Code (including - source code and dynamically or statically linked libraries) to a Third - Party, provided the Third Party possesses a license to use the Kakadu - software. +/* + * The copyright in this software is being made available under the 2-clauses + * BSD License, included below. This software may be subject to other third + * party and contributor rights, including patent rights, and no such rights + * are granted under this license. + * + * Copyright (c) 2002-2014, Universite catholique de Louvain (UCL), Belgium + * Copyright (c) 2002-2014, Professor Benoit Macq + * Copyright (c) 2003-2014, Antonin Descampe + * Copyright (c) 2003-2009, Francois-Olivier Devaux + * Copyright (c) 2005, Herve Drolon, FreeImage Team + * Copyright (c) 2002-2003, Yannick Verschueren + * Copyright (c) 2001-2003, David Janssens + * Copyright (c) 2011-2012, Centre National d'Etudes Spatiales (CNES), France + * Copyright (c) 2012, CS Systemes d'Information, France + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ ================== ogg/vorbis License @@ -259,6 +336,30 @@ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +=========== +SDL License +=========== + +SDL - Simple DirectMedia Layer +Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org> + +This software is provided 'as-is', without any express or implied +warranty. In no event will the authors be held liable for any damages +arising from the use of this software. + +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it +freely, subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. + + =============== OpenSSL License =============== @@ -516,18 +617,6 @@ supporting the PNG file format in commercial products. If you use this source code in a product, acknowledgment is not required but would be appreciated. -================= -Vivox SDK License -================= - -RSA Data Security, Inc. MD5 Message-Digest Algorithm - -Audio coding: Polycom(R) Siren14TM (ITU-T Rec. G.722.1 Annex C) - -Open Source Software Licensing -Each open source software component utilized by this product is subject to its own copyright and licensing terms, as listed below. - - ************************************************************* ************************************************************* @@ -553,80 +642,6 @@ Each open source software component utilized by this product is subject to its o ************************************************************* ************************************************************* -RTP code under Lesser General Public License - -/* - The oRTP library is an RTP (Realtime Transport Protocol - rfc3550) stack. - Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org - - 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; either - version 2.1 of the License, or (at your option) any later version. - - 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ - -************************************************************ -************************************************************* - -/* - * The Vovida Software License, Version 1.0 - * - * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The names "VOCAL", "Vovida Open Communication Application Library", - * and "Vovida Open Communication Application Library (VOCAL)" must - * not be used to endorse or promote products derived from this - * software without prior written permission. For written - * permission, please contact vocal@vovida.org. - * - * 4. Products derived from this software may not be called "VOCAL", nor - * may "VOCAL" appear in their name, without prior written - * permission of Vovida Networks, Inc. - * - * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND - * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA - * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES - * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE - * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - * DAMAGE. - * - * - * This software consists of voluntary contributions made by Vovida - * Networks, Inc. and many individuals on behalf of Vovida Networks, - * Inc. For more information on Vovida Networks, Inc., please see - * - * - */ -************************************************************* -************************************************************* Internet Software Consortium code @@ -647,54 +662,6 @@ Internet Software Consortium code * SOFTWARE. */ -************************************************************* - -************************************************************* - -************************************************************ - -http://tinyxpath.sourceforge.net/ - -TinyXPath is covered by the zlib license : - - www.sourceforge.net/projects/tinyxpath - Copyright (c) 2002-2006 Yves Berquin (yvesb@users.sourceforge.net) - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any - damages arising from the use of this software. - - Permission is granted to anyone to use this software for any - purpose, including commercial applications, and to alter it and - redistribute it freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must - not claim that you wrote the original software. If you use this - software in a product, an acknowledgment in the product documentation - would be appreciated but is not required. - - 2. Altered source versions must be plainly marked as such, and - must not be misrepresented as being the original software. - - 3. This notice may not be removed or altered from any source distribution. - - -************************************************************ -************************************************************ - -THE FREE SOFTWARE FOUNDATION - -Any customer may request the source code for all open source portions of this product which are covered by the Free Software Foundation's General Public License (GPL), for a period of three years from purchase. Please contact the vendor from whom you obtained this product for instructions. A fee equivalent to the cost of making the code available may be charged. Alternatively, customers may choose to download desired GPL components directly from their original vendors. Specifically, this product contains the following GPL-licensed components: - - -From Vivox: - - Assorted software components. To request source, contact Vivox at: - Vivox, Inc. - Attn: customer support - 40 Speen Street Suite 402 - Framingham, MA 01701 - - ============= meshoptimizer ============= @@ -771,3 +738,47 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +======== +sse2neon +======== +/* + * sse2neon is freely redistributable under the MIT License. + * + * Copyright (c) 2015-2024 SSE2NEON Contributors. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +=============================== +libwebrtc binaries (unofficial) +=============================== + +Copyright 2019 Zenichi Amano + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. diff --git a/indra/newview/linux_tools/launch_url.sh b/indra/newview/linux_tools/launch_url.sh index 404ea36f26..7c4ebf2291 100755 --- a/indra/newview/linux_tools/launch_url.sh +++ b/indra/newview/linux_tools/launch_url.sh @@ -61,6 +61,7 @@ fi # will be tried first, which is a debian alternative. BROWSER_COMMANDS=" \ x-www-browser \ + chrome \ firefox \ mozilla-firefox \ iceweasel \ diff --git a/indra/newview/linux_tools/megapahit.desktop b/indra/newview/linux_tools/megapahit.desktop new file mode 100755 index 0000000000..091df71e11 --- /dev/null +++ b/indra/newview/linux_tools/megapahit.desktop @@ -0,0 +1,10 @@ +[Desktop Entry] +Name=Megapahit +Comment=A fork of the Second Life viewer +Exec=megapahit +Icon=megapahit +Terminal=false +Type=Application +Categories=Network; +StartupNotify=true +X-Desktop-File-Install-Version=3.0" diff --git a/indra/newview/linux_tools/wrapper.sh b/indra/newview/linux_tools/wrapper.sh index eb3ead433b..a027aaf6d1 100755 --- a/indra/newview/linux_tools/wrapper.sh +++ b/indra/newview/linux_tools/wrapper.sh @@ -58,21 +58,14 @@ fi ## - Avoids an often-buggy X feature that doesn't really benefit us anyway. export SDL_VIDEO_X11_DGAMOUSE=0 -## - Works around a problem with misconfigured 64-bit systems not finding GL -I386_MULTIARCH="$(dpkg-architecture -ai386 -qDEB_HOST_MULTIARCH 2>/dev/null)" -MULTIARCH_ERR=$? -if [ $MULTIARCH_ERR -eq 0 ]; then - echo 'Multi-arch support detected.' - MULTIARCH_GL_DRIVERS="/usr/lib/${I386_MULTIARCH}/dri" - export LIBGL_DRIVERS_PATH="${LIBGL_DRIVERS_PATH}:${MULTIARCH_GL_DRIVERS}:/usr/lib64/dri:/usr/lib32/dri:/usr/lib/dri" -else - export LIBGL_DRIVERS_PATH="${LIBGL_DRIVERS_PATH}:/usr/lib64/dri:/usr/lib32/dri:/usr/lib/dri" -fi - ## - The 'scim' GTK IM module widely crashes the viewer. Avoid it. if [ "$GTK_IM_MODULE" = "scim" ]; then export GTK_IM_MODULE=xim fi +if [ "$XMODIFIERS" = "" ]; then + ## IME is valid only for fcitx, not when using ibus + export XMODIFIERS="@im=fcitx" +fi ## - Automatically work around the ATI mouse cursor crash bug: ## (this workaround is disabled as most fglrx users do not see the bug) @@ -98,25 +91,6 @@ cd "${RUN_PATH}" ## Before we mess with LD_LIBRARY_PATH, save the old one to restore for ## subprocesses that care. export SAVED_LD_LIBRARY_PATH="${LD_LIBRARY_PATH}" - -# if [ -n "$LL_TCMALLOC" ]; then -# tcmalloc_libs='/usr/lib/libtcmalloc.so.0 /usr/lib/libstacktrace.so.0 /lib/libpthread.so.0' -# all=1 -# for f in $tcmalloc_libs; do -# if [ ! -f $f ]; then -# all=0 -# fi -# done -# if [ $all != 1 ]; then -# echo 'Cannot use tcmalloc libraries: components missing' 1>&2 -# else -# export LD_PRELOAD=$(echo $tcmalloc_libs | tr ' ' :) -# if [ -z "$HEAPCHECK" -a -z "$HEAPPROFILE" ]; then -# export HEAPCHECK=${HEAPCHECK:-normal} -# fi -# fi -#fi - export LD_LIBRARY_PATH="$PWD/lib:${LD_LIBRARY_PATH}" # Copy "$@" to ARGS array specifically to delete the --skip-gridargs switch. @@ -140,18 +114,6 @@ LL_RUN_ERR=$? if [ $LL_RUN_ERR -ne 0 ]; then # generic error running the binary echo '*** Bad shutdown ($LL_RUN_ERR). ***' - if [ "$(uname -m)" = "x86_64" ]; then - echo - cat << EOFMARKER -You are running the Second Life Viewer on a x86_64 platform. The -most common problems when launching the Viewer (particularly -'bin/do-not-directly-run-secondlife-bin: not found' and 'error while -loading shared libraries') may be solved by installing your Linux -distribution's 32-bit compatibility packages. -For example, on Ubuntu and other Debian-based Linuxes you might run: -$ sudo apt-get install ia32-libs ia32-libs-gtk ia32-libs-kde ia32-libs-sdl -EOFMARKER - fi fi echo diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp index 26c080bf89..2161dbe19e 100644 --- a/indra/newview/llagent.cpp +++ b/indra/newview/llagent.cpp @@ -56,6 +56,7 @@ #include "llgroupmgr.h" #include "llhudmanager.h" #include "lljoystickbutton.h" +#include "lllandmarkactions.h" #include "llmorphview.h" #include "llmoveview.h" #include "llnavigationbar.h" // to show/hide navigation bar when changing mouse look state @@ -2501,7 +2502,10 @@ void LLAgent::endAnimationUpdateUI() gAgentAvatarp->updateAttachmentVisibility(gAgentCamera.getCameraMode()); } - gFloaterTools->dirty(); + if (gFloaterTools) + { + gFloaterTools->dirty(); + } // Don't let this be called more than once if the camera // mode hasn't changed. --JC @@ -4317,8 +4321,22 @@ void LLAgent::teleportViaLandmark(const LLUUID& landmark_asset_id) void LLAgent::doTeleportViaLandmark(const LLUUID& landmark_asset_id) { - LLViewerRegion *regionp = getRegion(); - if(regionp && teleportCore()) + LLViewerRegion* regionp = getRegion(); + if (!regionp) + { + LL_WARNS("Teleport") << "called when agent region is null" << LL_ENDL; + return; + } + + bool is_local(false); + if (LLLandmark* landmark = gLandmarkList.getAsset(landmark_asset_id, NULL)) + { + LLVector3d pos_global; + landmark->getGlobalPos(pos_global); + is_local = (regionp->getHandle() == to_region_handle_global((F32)pos_global.mdV[VX], (F32)pos_global.mdV[VY])); + } + + if(regionp && teleportCore(is_local)) { LL_INFOS("Teleport") << "Sending TeleportLandmarkRequest. Current region handle " << regionp->getHandle() << " region id " << regionp->getRegionID() @@ -4879,10 +4897,19 @@ void LLAgent::parseTeleportMessages(const std::string& xml_filename) LLXMLNodePtr root; bool success = LLUICtrlFactory::getLayeredXMLNode(xml_filename, root); - if (!success || !root || !root->hasName( "teleport_messages" )) + if (!success) { + LLError::LLUserWarningMsg::showMissingFiles(); LL_ERRS() << "Problem reading teleport string XML file: " - << xml_filename << LL_ENDL; + << xml_filename << LL_ENDL; + return; + } + + if (!root || !root->hasName("teleport_messages")) + { + LLError::LLUserWarningMsg::showMissingFiles(); + LL_ERRS() << "Invalid teleport string XML file: " + << xml_filename << LL_ENDL; return; } diff --git a/indra/newview/llagentcamera.cpp b/indra/newview/llagentcamera.cpp index 81e79a2ed9..40cb6f6265 100644 --- a/indra/newview/llagentcamera.cpp +++ b/indra/newview/llagentcamera.cpp @@ -2658,9 +2658,9 @@ void LLAgentCamera::setCameraPosAndFocusGlobal(const LLVector3d& camera_pos, con if (mCameraAnimating) { - const F64 ANIM_METERS_PER_SECOND = 10.0; + const F64 ANIM_METERS_PER_SECOND = 15.0; const F64 MIN_ANIM_SECONDS = 0.5; - const F64 MAX_ANIM_SECONDS = 10.0; + const F64 MAX_ANIM_SECONDS = 3.0; F64 anim_duration = llmax( MIN_ANIM_SECONDS, sqrt(focus_delta_squared) / ANIM_METERS_PER_SECOND ); anim_duration = llmin( anim_duration, MAX_ANIM_SECONDS ); setAnimationDuration( (F32)anim_duration ); diff --git a/indra/newview/llagentpicksinfo.cpp b/indra/newview/llagentpicksinfo.cpp index e2a2d2d8a9..265e4060ff 100644 --- a/indra/newview/llagentpicksinfo.cpp +++ b/indra/newview/llagentpicksinfo.cpp @@ -28,6 +28,7 @@ #include "llagentpicksinfo.h" #include "llagent.h" +#include "llagentbenefits.h" #include "llavatarpropertiesprocessor.h" const S32 MAX_AVATAR_PICKS = 10; @@ -85,10 +86,9 @@ private: LLAgentPicksInfo::LLAgentPicksInfo() : mAgentPicksObserver(NULL) - , mMaxNumberOfPicks(MAX_AVATAR_PICKS) // Disable Pick creation until we get number of Picks from server - in case // avatar has maximum number of Picks. - , mNumberOfPicks(mMaxNumberOfPicks) + , mNumberOfPicks(S32_MAX) { } @@ -110,7 +110,13 @@ void LLAgentPicksInfo::requestNumberOfPicks() mAgentPicksObserver->sendAgentPicksRequest(); } -bool LLAgentPicksInfo::isPickLimitReached() +// static +S32 LLAgentPicksInfo::getMaxNumberOfPicks() +{ + return LLAgentBenefitsMgr::current().getPicksLimit(); +} + +bool LLAgentPicksInfo::isPickLimitReached() const { return getNumberOfPicks() >= getMaxNumberOfPicks(); } diff --git a/indra/newview/llagentpicksinfo.h b/indra/newview/llagentpicksinfo.h index 9bc105a655..3514ade65d 100644 --- a/indra/newview/llagentpicksinfo.h +++ b/indra/newview/llagentpicksinfo.h @@ -52,17 +52,17 @@ public: /** * Returns number of Picks. */ - S32 getNumberOfPicks() { return mNumberOfPicks; } + S32 getNumberOfPicks() const { return mNumberOfPicks; } /** * Returns maximum number of Picks. */ - S32 getMaxNumberOfPicks() { return mMaxNumberOfPicks; } + static S32 getMaxNumberOfPicks(); /** * Returns true if Agent has maximum allowed number of Picks. */ - bool isPickLimitReached(); + bool isPickLimitReached() const; /** * After creating or deleting a Pick we can assume operation on server will be @@ -83,15 +83,9 @@ private: */ void setNumberOfPicks(S32 number) { mNumberOfPicks = number; } - /** - * Sets maximum number of Picks. - */ - void setMaxNumberOfPicks(S32 max_picks) { mMaxNumberOfPicks = max_picks; } - private: LLAgentPicksObserver* mAgentPicksObserver; - S32 mMaxNumberOfPicks; S32 mNumberOfPicks; }; diff --git a/indra/newview/llaisapi.cpp b/indra/newview/llaisapi.cpp index ce4e8e9392..11c5ffecb6 100644 --- a/indra/newview/llaisapi.cpp +++ b/indra/newview/llaisapi.cpp @@ -1385,8 +1385,6 @@ void AISUpdate::parseCategory(const LLSD& category_map, S32 depth) && curr_cat->getVersion() > LLViewerInventoryCategory::VERSION_UNKNOWN && version > curr_cat->getVersion()) { - // Potentially should new_cat->setVersion(unknown) here, - // but might be waiting for a callback that would increment LL_DEBUGS("Inventory") << "Category " << category_id << " is stale. Known version: " << curr_cat->getVersion() << " server version: " << version << LL_ENDL; diff --git a/indra/newview/llappdelegate-objc.mm b/indra/newview/llappdelegate-objc.mm index 1090888c1c..d4b05dde72 100644 --- a/indra/newview/llappdelegate-objc.mm +++ b/indra/newview/llappdelegate-objc.mm @@ -301,7 +301,8 @@ struct AttachmentInfo AttachmentInfo(metadata.logFilePathname, "text/plain"), AttachmentInfo(metadata.userSettingsPathname, "text/xml"), AttachmentInfo(metadata.accountSettingsPathname, "text/xml"), - AttachmentInfo(metadata.staticDebugPathname, "text/xml") + AttachmentInfo(metadata.staticDebugPathname, "text/xml"), + AttachmentInfo(metadata.attributesPathname, "text/xml") }; secondLogPath = metadata.secondLogFilePathname; diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp index 946d674e8b..101aca3823 100644 --- a/indra/newview/llappearancemgr.cpp +++ b/indra/newview/llappearancemgr.cpp @@ -537,9 +537,14 @@ LLUpdateAppearanceOnDestroy::~LLUpdateAppearanceOnDestroy() selfStopPhase("update_appearance_on_destroy"); - LLAppearanceMgr::instance().updateAppearanceFromCOF(mEnforceItemRestrictions, - mEnforceOrdering, - mPostUpdateFunc); + //avoid calling an update inside coroutine + bool force_restrictions(mEnforceItemRestrictions); + bool enforce_ordering(mEnforceOrdering); + nullary_func_t post_update_func(mPostUpdateFunc); + doOnIdleOneTime([force_restrictions,enforce_ordering,post_update_func]() + { + LLAppearanceMgr::instance().updateAppearanceFromCOF(force_restrictions, enforce_ordering, post_update_func); + }); } } @@ -4717,48 +4722,64 @@ void wear_multiple(const uuid_vec_t& ids, bool replace) LLAppearanceMgr::instance().wearItemsOnAvatar(ids, true, replace, cb); } -// SLapp for easy-wearing of a stock (library) avatar -// +bool wear_category(const LLSD& query_map, bool append) +{ + LLUUID folder_uuid; + + if (query_map.has("folder_name")) + { + std::string outfit_folder_name = query_map["folder_name"]; + folder_uuid = findDescendentCategoryIDByName(gInventory.getLibraryRootFolderID(), outfit_folder_name); + if (folder_uuid.isNull()) + LL_WARNS() << "Couldn't find " << std::quoted(outfit_folder_name) << " in the Library" << LL_ENDL; + } + if (folder_uuid.isNull() && query_map.has("folder_id")) + { + folder_uuid = query_map["folder_id"].asUUID(); + } + + if (folder_uuid.notNull()) + { + if (LLViewerInventoryCategory* cat = gInventory.getCategory(folder_uuid)) + { + if (bool is_library = gInventory.isObjectDescendentOf(folder_uuid, gInventory.getRootFolderID())) + { + LLPointer<LLInventoryCategory> new_category = new LLInventoryCategory(folder_uuid, LLUUID::null, LLFolderType::FT_CLOTHING, "Quick Appearance"); + LLAppearanceMgr::getInstance()->wearInventoryCategory(new_category, true, append); + } + else + { + LLAppearanceMgr::getInstance()->wearInventoryCategory(cat, true, append); + } + return true; + } + else + { + LL_WARNS() << "Couldn't find folder id" << folder_uuid << " in Inventory" << LL_ENDL; + } + } + + return false; +} + class LLWearFolderHandler : public LLCommandHandler { public: // not allowed from outside the app - LLWearFolderHandler() : LLCommandHandler("wear_folder", UNTRUSTED_BLOCK) { } + LLWearFolderHandler() : LLCommandHandler("wear_folder", UNTRUSTED_BLOCK) {} bool handle(const LLSD& tokens, const LLSD& query_map, const std::string& grid, LLMediaCtrl* web) { - LLSD::UUID folder_uuid; - - if (folder_uuid.isNull() && query_map.has("folder_name")) + if (wear_category(query_map, false)) { - std::string outfit_folder_name = query_map["folder_name"]; - folder_uuid = findDescendentCategoryIDByName( - gInventory.getLibraryRootFolderID(), - outfit_folder_name); - } - if (folder_uuid.isNull() && query_map.has("folder_id")) - { - folder_uuid = query_map["folder_id"].asUUID(); - } + // Assume this is coming from the predefined avatars web floater + LLUIUsage::instance().logCommand("Avatar.WearPredefinedAppearance"); - if (folder_uuid.notNull()) - { - LLPointer<LLInventoryCategory> category = new LLInventoryCategory(folder_uuid, - LLUUID::null, - LLFolderType::FT_CLOTHING, - "Quick Appearance"); - if ( gInventory.getCategory( folder_uuid ) != NULL ) - { - // Assume this is coming from the predefined avatars web floater - LLUIUsage::instance().logCommand("Avatar.WearPredefinedAppearance"); - LLAppearanceMgr::getInstance()->wearInventoryCategory(category, true, false); - - // *TODOw: This may not be necessary if initial outfit is chosen already -- josh - gAgent.setOutfitChosen(true); - } + // *TODOw: This may not be necessary if initial outfit is chosen already -- josh + gAgent.setOutfitChosen(true); } // release avatar picker keyboard focus @@ -4768,4 +4789,46 @@ public: } }; +class LLAddFolderHandler : public LLCommandHandler +{ +public: + // not allowed from outside the app + LLAddFolderHandler() : LLCommandHandler("add_folder", UNTRUSTED_BLOCK) {} + + bool handle(const LLSD& tokens, const LLSD& query_map, const std::string& grid, LLMediaCtrl* web) + { + wear_category(query_map, true); + + return true; + } +}; + +class LLRemoveFolderHandler : public LLCommandHandler +{ +public: + LLRemoveFolderHandler() : LLCommandHandler("remove_folder", UNTRUSTED_BLOCK) {} + + bool handle(const LLSD& tokens, const LLSD& query_map, const std::string& grid, LLMediaCtrl* web) + { + if (query_map.has("folder_id")) + { + LLUUID folder_id = query_map["folder_id"].asUUID(); + if (folder_id.notNull()) + { + if (LLViewerInventoryCategory* cat = gInventory.getCategory(folder_id)) + { + LLAppearanceMgr::instance().takeOffOutfit(cat->getLinkedUUID()); + } + else + { + LL_WARNS() << "Couldn't find folder id" << folder_id << " in Inventory" << LL_ENDL; + } + } + } + return true; + } +}; + LLWearFolderHandler gWearFolderHandler; +LLAddFolderHandler gAddFolderHandler; +LLRemoveFolderHandler gRemoveFolderHandler; diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index c770b7c917..c5190fe486 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -131,13 +131,17 @@ #include "stringize.h" #include "llcoros.h" #include "llexception.h" -#if !LL_LINUX +#if LL_DARWIN || LL_LINUX || __FreeBSD__ #include "cef/dullahan_version.h" +#endif #include "vlc/libvlc_version.h" -#endif // LL_LINUX #if LL_DARWIN +#if LL_SDL +#include "llwindowsdl.h" +#else #include "llwindowmacosx.h" +#endif // LL_SDL #endif // Third party library includes @@ -250,6 +254,8 @@ using namespace LL; #include "llcoproceduremanager.h" #include "llviewereventrecorder.h" +#include <chrono> + // *FIX: These extern globals should be cleaned up. // The globals either represent state/config/resource-storage of either // this app, or another 'component' of the viewer. App globals should be @@ -264,9 +270,10 @@ using namespace LL; // define a self-registering event API object #include "llappviewerlistener.h" -#if LL_LINUX && LL_GTK -#include "glib.h" -#endif // (LL_LINUX) && LL_GTK +#if LL_MSVC +// disable boost::lexical_cast warning +#pragma warning (disable:4702) +#endif static LLAppViewerListener sAppViewerListener(LLAppViewer::instance); @@ -298,6 +305,7 @@ bool gUseQuickTime = true; eLastExecEvent gLastExecEvent = LAST_EXEC_NORMAL; S32 gLastExecDuration = -1; // (<0 indicates unknown) +LLUUID gLastAgentSessionId; #if LL_WINDOWS # define LL_PLATFORM_KEY "win" @@ -305,6 +313,8 @@ S32 gLastExecDuration = -1; // (<0 indicates unknown) # define LL_PLATFORM_KEY "mac" #elif LL_LINUX # define LL_PLATFORM_KEY "lnx" +#elif __FreeBSD__ +# define LL_PLATFORM_KEY "bsd" #else # error "Unknown Platform" #endif @@ -348,10 +358,6 @@ std::string gLastVersionChannel; LLVector3 gWindVec(3.0, 3.0, 0.0); LLVector3 gRelativeWindVec(0.0, 0.0, 0.0); -U32 gPacketsIn = 0; - -bool gPrintMessagesThisFrame = false; - bool gRandomizeFramerate = false; bool gPeriodicSlowFrame = false; @@ -360,6 +366,7 @@ bool gLLErrorActivated = false; bool gLogoutInProgress = false; bool gSimulateMemLeak = false; +bool gDoDisconnect = false; // We don't want anyone, especially threads working on the graphics pipeline, // to have to block due to this WorkQueue being full. @@ -372,14 +379,13 @@ const int MAX_MARKER_LENGTH = 1024; const std::string MARKER_FILE_NAME("SecondLife.exec_marker"); const std::string START_MARKER_FILE_NAME("SecondLife.start_marker"); const std::string ERROR_MARKER_FILE_NAME("SecondLife.error_marker"); -const std::string LLERROR_MARKER_FILE_NAME("SecondLife.llerror_marker"); const std::string LOGOUT_MARKER_FILE_NAME("SecondLife.logout_marker"); -static bool gDoDisconnect = false; static std::string gLaunchFileOnQuit; // Used on Win32 for other apps to identify our window (eg, win_setup) const char* const VIEWER_WINDOW_CLASSNAME = "Second Life"; + //---------------------------------------------------------------------------- // List of entries from strings.xml to always replace @@ -449,8 +455,8 @@ void idle_afk_check() { // check idle timers F32 current_idle = gAwayTriggerTimer.getElapsedTimeF32(); - F32 afk_timeout = (F32)gSavedSettings.getS32("AFKTimeout"); - if (afk_timeout && (current_idle > afk_timeout) && ! gAgent.getAFK()) + static LLCachedControl<S32> afk_timeout(gSavedSettings, "AFKTimeout", 300); + if (afk_timeout() && (current_idle > (F32)afk_timeout()) && !gAgent.getAFK()) { LL_INFOS("IdleAway") << "Idle more than " << afk_timeout << " seconds: automatically changing to Away status" << LL_ENDL; gAgent.setAFK(); @@ -523,11 +529,13 @@ static void settings_to_globals() { LLSurface::setTextureSize(gSavedSettings.getU32("RegionTextureSize")); -#if LL_DARWIN +//#if LL_DARWIN LLRender::sGLCoreProfile = true; +/* #else LLRender::sGLCoreProfile = gSavedSettings.getBOOL("RenderGLContextCoreProfile"); #endif +*/ LLRender::sNsightDebugSupport = gSavedSettings.getBOOL("RenderNsightDebugSupport"); LLImageGL::sGlobalUseAnisotropic = gSavedSettings.getBOOL("RenderAnisotropic"); LLImageGL::sCompressTextures = gSavedSettings.getBOOL("RenderCompressTextures"); @@ -554,7 +562,11 @@ static void settings_to_globals() LLWorldMapView::setScaleSetting(gSavedSettings.getF32("MapScale")); #if LL_DARWIN +#if LL_SDL + LLWindowSDL::sUseMultGL = gSavedSettings.getBOOL("RenderAppleUseMultGL"); +#else LLWindowMacOSX::sUseMultGL = gSavedSettings.getBOOL("RenderAppleUseMultGL"); +#endif // LL_SDL gHiDPISupport = gSavedSettings.getBOOL("RenderHiDPI"); #endif } @@ -659,7 +671,7 @@ LLAppViewer::LLAppViewer() // Need to do this initialization before we do anything else, since anything // that touches files should really go through the lldir API - gDirUtilp->initAppDirs("SecondLife"); + gDirUtilp->initAppDirs("Megapahit"); // // IMPORTANT! Do NOT put anything that will write // into the log files during normal startup until AFTER @@ -891,7 +903,7 @@ bool LLAppViewer::init() std::string mime_types_name; #if LL_DARWIN mime_types_name = "mime_types_mac.xml"; -#elif LL_LINUX +#elif LL_LINUX || __FreeBSD__ mime_types_name = "mime_types_linux.xml"; #else mime_types_name = "mime_types.xml"; @@ -972,6 +984,7 @@ bool LLAppViewer::init() return false; } +#if defined(__i386__) || defined(__x86_64__) || defined(__amd64__) // Without SSE2 support we will crash almost immediately, warn here. if (!gSysCPU.hasSSE2()) { @@ -983,6 +996,7 @@ bool LLAppViewer::init() // quit immediately return false; } +#endif // alert the user if they are using unsupported hardware if (!gSavedSettings.getBOOL("AlertedUnsupportedHardware")) @@ -1090,7 +1104,7 @@ bool LLAppViewer::init() gGLActive = false; -#if LL_RELEASE_FOR_DOWNLOAD +#if 0 // LL_RELEASE_FOR_DOWNLOAD && !LL_LINUX // Skip updater if this is a non-interactive instance if (!gSavedSettings.getBOOL("CmdLineSkipUpdater") && !gNonInteractive) { @@ -1323,6 +1337,14 @@ bool LLAppViewer::frame() bool LLAppViewer::doFrame() { + U32 fpsLimitMaxFps = (U32)gSavedSettings.getU32("MaxFPS"); + if(fpsLimitMaxFps>120) fpsLimitMaxFps=0; + + using TimePoint = std::chrono::steady_clock::time_point; + + U64 fpsLimitSleepFor = 0; + TimePoint fpsLimitFrameStartTime = std::chrono::steady_clock::now(); + LL_RECORD_BLOCK_TIME(FTM_FRAME); { // and now adjust the visuals from previous frame. @@ -1493,11 +1515,23 @@ bool LLAppViewer::doFrame() } } + if(fpsLimitMaxFps > 0) + { + auto elapsed = std::chrono::steady_clock::now() - fpsLimitFrameStartTime; + + long long fpsLimitFrameTime = std::chrono::duration_cast<std::chrono::microseconds>(elapsed).count(); + U64 desired_time_us = (U32)(1000000.f / fpsLimitMaxFps); + if((fpsLimitFrameTime+1000) < desired_time_us) + { + fpsLimitSleepFor = (desired_time_us - fpsLimitFrameTime - 1000) * 1.0; + } + } + { LL_PROFILE_ZONE_NAMED_CATEGORY_APP("df pauseMainloopTimeout"); - pingMainloopTimeout("Main:Sleep"); + pingMainloopTimeout("Main:Sleep"); - pauseMainloopTimeout(); + pauseMainloopTimeout(); } // Sleep and run background threads @@ -1505,6 +1539,11 @@ bool LLAppViewer::doFrame() //LL_RECORD_BLOCK_TIME(SLEEP2); LL_PROFILE_ZONE_WARN("Sleep2"); + if(fpsLimitSleepFor) + { + usleep(fpsLimitSleepFor); + } + // yield some time to the os based on command line option static LLCachedControl<S32> yield_time(gSavedSettings, "YieldTime", -1); if(yield_time >= 0) @@ -1694,7 +1733,7 @@ bool LLAppViewer::cleanup() // one because it happens just after mFastTimerLogThread is deleted. This // comment is in case we guessed wrong, so we can move it here instead. -#if LL_LINUX +#if LL_LINUX || __FreeBSD__ // remove any old breakpad minidump files from the log directory if (! isError()) { @@ -2219,6 +2258,7 @@ bool LLAppViewer::initThreads() return true; } +// Callback for all LL_ERROR calls void errorCallback(LLError::ELevel level, const std::string &error_string) { if (level == LLError::LEVEL_ERROR) @@ -2234,15 +2274,38 @@ void errorCallback(LLError::ELevel level, const std::string &error_string) // haven't actually trashed anything yet, we can afford to write the whole // static info file. LLAppViewer::instance()->writeDebugInfo(); + + std::string error_marker_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, ERROR_MARKER_FILE_NAME); + if (!LLAPRFile::isExist(error_marker_file, NULL, LL_APR_RB)) + { + // If marker doesn't exist, create a marker with llerror code for next launch + // otherwise don't override existing file + LLAppViewer::instance()->createErrorMarker(LAST_EXEC_LLERROR_CRASH); + } } } -void errorMSG(const std::string& title_string, const std::string& message_string) +// Callback for LLError::LLUserWarningMsg +void errorHandler(const std::string& title_string, const std::string& message_string, S32 code) { if (!message_string.empty()) { OSMessageBox(message_string, title_string.empty() ? LLTrans::getString("MBFatalError") : title_string, OSMB_OK); } + switch (code) + { + case LLError::LLUserWarningMsg::ERROR_OTHER: + LLAppViewer::instance()->createErrorMarker(LAST_EXEC_OTHER_CRASH); + break; + case LLError::LLUserWarningMsg::ERROR_BAD_ALLOC: + LLAppViewer::instance()->createErrorMarker(LAST_EXEC_BAD_ALLOC); + break; + case LLError::LLUserWarningMsg::ERROR_MISSING_FILES: + LLAppViewer::instance()->createErrorMarker(LAST_EXEC_MISSING_FILES); + break; + default: + break; + } } void LLAppViewer::initLoggingAndGetLastDuration() @@ -2256,7 +2319,7 @@ void LLAppViewer::initLoggingAndGetLastDuration() LLError::addGenericRecorder(&errorCallback); //LLError::setTimeFunction(getRuntime); - LLError::LLUserWarningMsg::setHandler(errorMSG); + LLError::LLUserWarningMsg::setHandler(errorHandler); if (mSecondInstance) @@ -2330,6 +2393,14 @@ void LLAppViewer::initLoggingAndGetLastDuration() { LL_WARNS("MarkerFile") << duration_log_msg << LL_ENDL; } + + std::string user_data_path_cef_log = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "cef.log"); + if (gDirUtilp->fileExists(user_data_path_cef_log)) + { + std::string user_data_path_cef_old = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "cef.old"); + LLFile::remove(user_data_path_cef_old, ENOENT); + LLFile::rename(user_data_path_cef_log, user_data_path_cef_old); + } } } @@ -2540,6 +2611,7 @@ bool LLAppViewer::initConfiguration() OSMessageBox( "Unable to load default settings file. The installation may be corrupted.", LLStringUtil::null,OSMB_OK); + LLAppViewer::instance()->createErrorMarker(LAST_EXEC_MISSING_FILES); return false; } @@ -2956,9 +3028,10 @@ void LLAppViewer::initStrings() std::string strings_path_full = gDirUtilp->findSkinnedFilenameBaseLang(LLDir::XUI, strings_file); if (strings_path_full.empty() || !LLFile::isfile(strings_path_full)) { + std::string crash_reason; if (strings_path_full.empty()) { - LL_WARNS() << "The file '" << strings_file << "' is not found" << LL_ENDL; + crash_reason = "The file '" + strings_file + "' is not found"; } else { @@ -2966,24 +3039,23 @@ void LLAppViewer::initStrings() int rc = LLFile::stat(strings_path_full, &st); if (rc != 0) { - LL_WARNS() << "The file '" << strings_path_full << "' failed to get status. Error code: " << rc << LL_ENDL; + crash_reason = "The file '" + strings_path_full + "' failed to get status. Error code: " + std::to_string(rc); } else if (S_ISDIR(st.st_mode)) { - LL_WARNS() << "The filename '" << strings_path_full << "' is a directory name" << LL_ENDL; + crash_reason = "The filename '" + strings_path_full + "' is a directory name"; } else { - LL_WARNS() << "The filename '" << strings_path_full << "' doesn't seem to be a regular file name" << LL_ENDL; + crash_reason = "The filename '" + strings_path_full + "' doesn't seem to be a regular file name"; } } // initial check to make sure files are there failed gDirUtilp->dumpCurrentDirectories(LLError::LEVEL_WARN); LLError::LLUserWarningMsg::showMissingFiles(); - LL_ERRS() << "Viewer failed to find localization and UI files." - << " Please reinstall viewer from https://secondlife.com/support/downloads" - << " and contact https://support.secondlife.com if issue persists after reinstall." << LL_ENDL; + LL_ERRS() << "Viewer failed to open some of localization and UI files." + << " " << crash_reason << "." << LL_ENDL; } LLTransUtil::parseStrings(strings_file, default_trans_args); LLTransUtil::parseLanguageStrings("language_settings.xml"); @@ -3344,7 +3416,7 @@ LLSD LLAppViewer::getViewerInfo() const info["VOICE_VERSION"] = LLTrans::getString("NotConnected"); } -#if !LL_LINUX +#if LL_DARWIN || LL_LINUX || __FreeBSD__ std::ostringstream cef_ver_codec; cef_ver_codec << "Dullahan: "; cef_ver_codec << DULLAHAN_VERSION_MAJOR; @@ -3374,7 +3446,7 @@ LLSD LLAppViewer::getViewerInfo() const info["LIBCEF_VERSION"] = "Undefined"; #endif -#if !LL_LINUX +//#if !LL_LINUX std::ostringstream vlc_ver_codec; vlc_ver_codec << LIBVLC_VERSION_MAJOR; vlc_ver_codec << "."; @@ -3382,9 +3454,11 @@ LLSD LLAppViewer::getViewerInfo() const vlc_ver_codec << "."; vlc_ver_codec << LIBVLC_VERSION_REVISION; info["LIBVLC_VERSION"] = vlc_ver_codec.str(); +/* #else info["LIBVLC_VERSION"] = "Undefined"; #endif +*/ S32 packets_in = (S32)LLViewerStats::instance().getRecording().getSum(LLStatViewer::PACKETS_IN); if (packets_in > 0) @@ -3702,16 +3776,21 @@ bool LLAppViewer::markerIsSameVersion(const std::string& marker_name) const bool sameVersion = false; std::string my_version(LLVersionInfo::instance().getChannelAndVersion()); - char marker_version[MAX_MARKER_LENGTH]; + char marker_data[MAX_MARKER_LENGTH]; S32 marker_version_length; LLAPRFile marker_file; marker_file.open(marker_name, LL_APR_RB); if (marker_file.getFileHandle()) { - marker_version_length = marker_file.read(marker_version, sizeof(marker_version)); - std::string marker_string(marker_version, marker_version_length); - if ( 0 == my_version.compare( 0, my_version.length(), marker_version, 0, marker_version_length ) ) + marker_version_length = marker_file.read(marker_data, sizeof(marker_data)); + std::string marker_string(marker_data, marker_version_length); + size_t pos = marker_string.find('\n'); + if (pos != std::string::npos) + { + marker_string = marker_string.substr(0, pos); + } + if ( 0 == my_version.compare( 0, my_version.length(), marker_string, 0, marker_string.length()) ) { sameVersion = true; } @@ -3725,6 +3804,88 @@ bool LLAppViewer::markerIsSameVersion(const std::string& marker_name) const return sameVersion; } +void LLAppViewer::recordSessionToMarker() +{ + std::string marker_version(LLVersionInfo::instance().getChannelAndVersion()); + std::string uuid_str = "\n" + gAgentSessionID.asString(); + if (marker_version.length() + uuid_str.length() > MAX_MARKER_LENGTH) + { + LL_WARNS_ONCE("MarkerFile") << "Version length (" << marker_version.length() << ")" + << " greater than maximum (" << MAX_MARKER_LENGTH << ")" + << ": marker matching may be incorrect" + << LL_ENDL; + } + + mMarkerFile.seek(APR_SET, (S32)marker_version.length()); + mMarkerFile.write(uuid_str.data(), (S32)uuid_str.length()); +} + +LLUUID LLAppViewer::getMarkerSessionId(const std::string& marker_name) const +{ + std::string data; + if (getMarkerData(marker_name, data)) + { + return LLUUID(data); + } + return LLUUID(); +} + +S32 LLAppViewer::getMarkerErrorCode(const std::string& marker_name) const +{ + std::string data; + if (getMarkerData(marker_name, data)) + { + if (data.empty()) + { + return 0; + } + else + { + return std::stoi(data); + } + } + return -1; +} + +bool LLAppViewer::getMarkerData(const std::string& marker_name, std::string& data) const +{ + bool sameVersion = false; + + std::string my_version(LLVersionInfo::instance().getChannelAndVersion()); + char marker_data[MAX_MARKER_LENGTH]; + S32 marker_version_length; + + LLAPRFile marker_file; + marker_file.open(marker_name, LL_APR_RB); + if (marker_file.getFileHandle()) + { + marker_version_length = marker_file.read(marker_data, sizeof(marker_data)); + marker_file.close(); + std::string marker_string(marker_data, marker_version_length); + size_t pos = marker_string.find('\n'); + if (pos != std::string::npos) + { + data = marker_string.substr(pos + 1, marker_version_length - pos - 1); + marker_string = marker_string.substr(0, pos); + } + if (0 == my_version.compare(0, my_version.length(), marker_string, 0, marker_string.length())) + { + sameVersion = true; + } + else + { + return false; + } + LL_DEBUGS("MarkerFile") << "Compare markers for '" << marker_name << "': " + << "\n mine '" << my_version << "'" + << "\n marker '" << marker_string << "'" + << "\n " << (sameVersion ? "same" : "different") << " version" + << LL_ENDL; + return true; + } + return false; +} + void LLAppViewer::processMarkerFiles() { //We've got 4 things to test for here @@ -3743,6 +3904,10 @@ void LLAppViewer::processMarkerFiles() // File exists... // first, read it to see if it was created by the same version (we need this later) marker_is_same_version = markerIsSameVersion(mMarkerFileName); + if (marker_is_same_version) + { + gLastAgentSessionId = getMarkerSessionId(mMarkerFileName); + } // now test to see if this file is locked by a running process (try to open for write) marker_log_stream << "Checking exec marker file for lock..."; @@ -3832,44 +3997,27 @@ void LLAppViewer::processMarkerFiles() } LLAPRFile::remove(logout_marker_file); } - // further refine based on whether or not a marker created during an llerr crash is found - std::string llerror_marker_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, LLERROR_MARKER_FILE_NAME); - if(LLAPRFile::isExist(llerror_marker_file, NULL, LL_APR_RB)) - { - if (markerIsSameVersion(llerror_marker_file)) - { - if ( gLastExecEvent == LAST_EXEC_LOGOUT_FROZE ) - { - gLastExecEvent = LAST_EXEC_LOGOUT_CRASH; - LL_INFOS("MarkerFile") << "LLError marker '"<< llerror_marker_file << "' crashed, setting LastExecEvent to LOGOUT_CRASH" << LL_ENDL; - } - else - { - gLastExecEvent = LAST_EXEC_LLERROR_CRASH; - LL_INFOS("MarkerFile") << "LLError marker '"<< llerror_marker_file << "' crashed, setting LastExecEvent to LLERROR_CRASH" << LL_ENDL; - } - } - else - { - LL_INFOS("MarkerFile") << "LLError marker '"<< llerror_marker_file << "' found, but versions did not match" << LL_ENDL; - } - LLAPRFile::remove(llerror_marker_file); - } // and last refine based on whether or not a marker created during a non-llerr crash is found std::string error_marker_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, ERROR_MARKER_FILE_NAME); if(LLAPRFile::isExist(error_marker_file, NULL, LL_APR_RB)) { - if (markerIsSameVersion(error_marker_file)) + S32 marker_code = getMarkerErrorCode(error_marker_file); + if (marker_code >= 0) { if (gLastExecEvent == LAST_EXEC_LOGOUT_FROZE) { gLastExecEvent = LAST_EXEC_LOGOUT_CRASH; LL_INFOS("MarkerFile") << "Error marker '"<< error_marker_file << "' crashed, setting LastExecEvent to LOGOUT_CRASH" << LL_ENDL; } + else if (marker_code > 0 && marker_code < (S32)LAST_EXEC_COUNT) + { + gLastExecEvent = (eLastExecEvent)marker_code; + LL_INFOS("MarkerFile") << "Error marker '"<< error_marker_file << "' crashed, setting LastExecEvent to " << gLastExecEvent << LL_ENDL; + } else { gLastExecEvent = LAST_EXEC_OTHER_CRASH; - LL_INFOS("MarkerFile") << "Error marker '"<< error_marker_file << "' crashed, setting LastExecEvent to " << gLastExecEvent << LL_ENDL; + LL_INFOS("MarkerFile") << "Error marker '" << error_marker_file << "' crashed, setting LastExecEvent to " << gLastExecEvent << LL_ENDL; } } else @@ -4145,7 +4293,7 @@ U32 LLAppViewer::getTextureCacheVersion() U32 LLAppViewer::getDiskCacheVersion() { // Viewer disk cache version intorduced in Simple Cache Viewer, change if the cache format changes. - const U32 DISK_CACHE_VERSION = 1; + const U32 DISK_CACHE_VERSION = 2; return DISK_CACHE_VERSION ; } @@ -4464,11 +4612,32 @@ void LLAppViewer::saveFinalSnapshot() } } +static const char PRODUCTION_CACHE_FORMAT_STRING[] = "%s.%s"; +static const char GRID_CACHE_FORMAT_STRING[] = "%s.%s.%s"; +std::string get_name_cache_filename(const std::string &base_file, const std::string& extention) +{ + std::string filename; + std::string path(gDirUtilp->getExpandedFilename(LL_PATH_CACHE, base_file)); + if (LLGridManager::getInstance()->isInProductionGrid()) + { + filename = llformat(PRODUCTION_CACHE_FORMAT_STRING, path.c_str(), extention.c_str()); + } + else + { + // NOTE: The inventory cache filenames now include the grid name. + // Add controls against directory traversal or problematic pathname lengths + // if your viewer uses grid names from an untrusted source. + const std::string& grid_id_str = LLGridManager::getInstance()->getGridId(); + const std::string& grid_id_lower = utf8str_tolower(grid_id_str); + filename = llformat(GRID_CACHE_FORMAT_STRING, path.c_str(), grid_id_lower.c_str(), extention.c_str()); + } + return filename; +} + void LLAppViewer::loadNameCache() { // display names cache - std::string filename = - gDirUtilp->getExpandedFilename(LL_PATH_CACHE, "avatar_name_cache.xml"); + std::string filename = get_name_cache_filename("avatar_name_cache", "xml"); LL_INFOS("AvNameCache") << filename << LL_ENDL; llifstream name_cache_stream(filename.c_str()); if(name_cache_stream.is_open()) @@ -4483,8 +4652,8 @@ void LLAppViewer::loadNameCache() if (!gCacheName) return; - std::string name_cache; - name_cache = gDirUtilp->getExpandedFilename(LL_PATH_CACHE, "name.cache"); + // is there a reason for the "cache" extention? + std::string name_cache = get_name_cache_filename("name", "cache"); llifstream cache_file(name_cache.c_str()); if(cache_file.is_open()) { @@ -4495,8 +4664,7 @@ void LLAppViewer::loadNameCache() void LLAppViewer::saveNameCache() { // display names cache - std::string filename = - gDirUtilp->getExpandedFilename(LL_PATH_CACHE, "avatar_name_cache.xml"); + std::string filename = get_name_cache_filename("avatar_name_cache", "xml"); llofstream name_cache_stream(filename.c_str()); if(name_cache_stream.is_open()) { @@ -4506,8 +4674,7 @@ void LLAppViewer::saveNameCache() // real names cache if (gCacheName) { - std::string name_cache; - name_cache = gDirUtilp->getExpandedFilename(LL_PATH_CACHE, "name.cache"); + std::string name_cache = get_name_cache_filename("name", "cache"); llofstream cache_file(name_cache.c_str()); if(cache_file.is_open()) { @@ -4785,6 +4952,20 @@ void LLAppViewer::idle() if (gTeleportDisplay) { + if (gAgent.getTeleportState() == LLAgent::TELEPORT_ARRIVING) + { + // Teleported, but waiting for things to load, start processing surface data + { + LL_RECORD_BLOCK_TIME(FTM_NETWORK); + gVLManager.unpackData(); + } + { + LL_RECORD_BLOCK_TIME(FTM_REGION_UPDATE); + const F32 max_region_update_time = .001f; // 1ms + LLWorld::getInstance()->updateRegions(max_region_update_time); + } + } + return; } @@ -5080,15 +5261,28 @@ void LLAppViewer::sendLogoutRequest() gLogoutInProgress = true; if (!mSecondInstance) { - mLogoutMarkerFileName = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,LOGOUT_MARKER_FILE_NAME); - - mLogoutMarkerFile.open(mLogoutMarkerFileName, LL_APR_WB); - if (mLogoutMarkerFile.getFileHandle()) + mLogoutMarkerFileName = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, LOGOUT_MARKER_FILE_NAME); + try { - LL_INFOS("MarkerFile") << "Created logout marker file '"<< mLogoutMarkerFileName << "' " << LL_ENDL; - recordMarkerVersion(mLogoutMarkerFile); + if (!mLogoutMarkerFile.getFileHandle()) + { + mLogoutMarkerFile.open(mLogoutMarkerFileName, LL_APR_WB); + if (mLogoutMarkerFile.getFileHandle()) + { + LL_INFOS("MarkerFile") << "Created logout marker file '" << mLogoutMarkerFileName << "' " << LL_ENDL; + recordMarkerVersion(mLogoutMarkerFile); + } + else + { + LL_WARNS("MarkerFile") << "Cannot create logout marker file " << mLogoutMarkerFileName << LL_ENDL; + } + } + else + { + LL_WARNS("MarkerFile") << "Atempted to reopen file '" << mLogoutMarkerFileName << "' " << LL_ENDL; + } } - else + catch (...) { LL_WARNS("MarkerFile") << "Cannot create logout marker file " << mLogoutMarkerFileName << LL_ENDL; } @@ -5159,6 +5353,24 @@ void LLAppViewer::postToMainCoro(const LL::WorkQueue::Work& work) gMainloopWork.post(work); } +void LLAppViewer::createErrorMarker(eLastExecEvent error_code) const +{ + if (!mSecondInstance) + { + std::string error_marker = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, ERROR_MARKER_FILE_NAME); + + LLAPRFile file; + file.open(error_marker, LL_APR_WB); + if (file.getFileHandle()) + { + recordMarkerVersion(file); + std::string data = "\n" + std::to_string((S32)error_code); + file.write(data.data(), static_cast<S32>(data.length())); + file.close(); + } + } +} + void LLAppViewer::outOfMemorySoftQuit() { if (!mQuitRequested) @@ -5203,12 +5415,9 @@ void LLAppViewer::idleNameCache() // Handle messages, and all message related stuff // -#define TIME_THROTTLE_MESSAGES -#ifdef TIME_THROTTLE_MESSAGES -#define CHECK_MESSAGES_DEFAULT_MAX_TIME .020f // 50 ms = 50 fps (just for messages!) +constexpr F32 CHECK_MESSAGES_DEFAULT_MAX_TIME = 0.020f; // 50 ms = 50 fps (just for messages!) static F32 CheckMessagesMaxTime = CHECK_MESSAGES_DEFAULT_MAX_TIME; -#endif static LLTrace::BlockTimerStatHandle FTM_IDLE_NETWORK("Idle Network"); static LLTrace::BlockTimerStatHandle FTM_MESSAGE_ACKS("Message Acks"); @@ -5225,7 +5434,8 @@ void LLAppViewer::idleNetwork() gObjectList.mNumNewObjects = 0; S32 total_decoded = 0; - if (!gSavedSettings.getBOOL("SpeedTest")) + static LLCachedControl<bool> speed_test(gSavedSettings, "SpeedTest", false); + if (!speed_test()) { LL_PROFILE_ZONE_NAMED_CATEGORY_NETWORK("idle network"); //LL_RECORD_BLOCK_TIME(FTM_IDLE_NETWORK); // decode @@ -5235,6 +5445,7 @@ void LLAppViewer::idleNetwork() F32 total_time = 0.0f; { + bool needs_drain = false; LockMessageChecker lmc(gMessageSystem); while (lmc.checkAllMessages(frame_count, gServicePump)) { @@ -5247,53 +5458,45 @@ void LLAppViewer::idleNetwork() } total_decoded++; - gPacketsIn++; if (total_decoded > MESSAGE_MAX_PER_FRAME) { + needs_drain = true; break; } -#ifdef TIME_THROTTLE_MESSAGES // Prevent slow packets from completely destroying the frame rate. // This usually happens due to clumps of avatars taking huge amount // of network processing time (which needs to be fixed, but this is // a good limit anyway). total_time = check_message_timer.getElapsedTimeF32(); if (total_time >= CheckMessagesMaxTime) + { + needs_drain = true; break; -#endif + } + } + if (needs_drain || gMessageSystem->mPacketRing.getNumBufferedPackets() > 0) + { + // Rather than allow packets to silently backup on the socket + // we drain them into our own buffer so we know how many exist. + S32 num_buffered_packets = gMessageSystem->drainUdpSocket(); + if (num_buffered_packets > 0) + { + // Increase CheckMessagesMaxTime so that we will eventually catch up + CheckMessagesMaxTime *= 1.035f; // 3.5% ~= 2x in 20 frames, ~8x in 60 frames + } + } + else + { + // Reset CheckMessagesMaxTime to default value + CheckMessagesMaxTime = CHECK_MESSAGES_DEFAULT_MAX_TIME; } // Handle per-frame message system processing. - lmc.processAcks(gSavedSettings.getF32("AckCollectTime")); - } - -#ifdef TIME_THROTTLE_MESSAGES - if (total_time >= CheckMessagesMaxTime) - { - // Increase CheckMessagesMaxTime so that we will eventually catch up - CheckMessagesMaxTime *= 1.035f; // 3.5% ~= x2 in 20 frames, ~8x in 60 frames - } - else - { - // Reset CheckMessagesMaxTime to default value - CheckMessagesMaxTime = CHECK_MESSAGES_DEFAULT_MAX_TIME; - } -#endif - // Decode enqueued messages... - S32 remaining_possible_decodes = MESSAGE_MAX_PER_FRAME - total_decoded; - - if( remaining_possible_decodes <= 0 ) - { - LL_INFOS() << "Maxed out number of messages per frame at " << MESSAGE_MAX_PER_FRAME << LL_ENDL; - } - - if (gPrintMessagesThisFrame) - { - LL_INFOS() << "Decoded " << total_decoded << " msgs this frame!" << LL_ENDL; - gPrintMessagesThisFrame = false; + static LLCachedControl<F32> ack_collection_time(gSavedSettings, "AckCollectTime", 0.1f); + lmc.processAcks(ack_collection_time()); } } add(LLStatViewer::NUM_NEW_OBJECTS, gObjectList.mNumNewObjects); @@ -5301,6 +5504,7 @@ void LLAppViewer::idleNetwork() // Retransmit unacknowledged packets. gXferManager->retransmitUnackedPackets(); gAssetStorage->checkForTimeouts(); + gViewerThrottle.setBufferLoadRate(gMessageSystem->getBufferLoadRate()); gViewerThrottle.updateDynamicThrottle(); // Check that the circuit between the viewer and the agent's current @@ -5417,7 +5621,7 @@ void LLAppViewer::forceErrorBreakpoint() LL_WARNS() << "Forcing a deliberate breakpoint" << LL_ENDL; #ifdef LL_WINDOWS DebugBreak(); -#else +#elif __i386__ || __x86_64__ asm ("int $3"); #endif return; @@ -5475,6 +5679,27 @@ void LLAppViewer::forceErrorCoroutineCrash() LLCoros::instance().launch("LLAppViewer::crashyCoro", [] {throw LLException("A deliberate crash from LLCoros"); }); } +void LLAppViewer::forceErrorCoroprocedureCrash() +{ + LL_WARNS() << "Forcing a crash in LLCoprocedureManager" << LL_ENDL; + LLCoprocedureManager::instance().enqueueCoprocedure("Upload", "DeliberateCrash", + [](LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t&, const LLUUID&) + { + LL_WARNS() << "Forcing a deliberate bad memory access from LLCoprocedureManager" << LL_ENDL; + S32* crash = NULL; + *crash = 0xDEADBEEF; + }); +} + +void LLAppViewer::forceErrorWorkQueueCrash() +{ + LL::WorkQueue::ptr_t workqueue = LL::WorkQueue::getInstance("General"); + if (workqueue) + { + workqueue->post([]() { throw LLException("This is a deliberate crash from General Queue"); }); + } +} + void LLAppViewer::forceErrorThreadCrash() { class LLCrashTestThread : public LLThread @@ -5670,4 +5895,3 @@ void LLAppViewer::metricsSend(bool enable_reporting) // resolution in time. gViewerAssetStats->restart(); } - diff --git a/indra/newview/llappviewer.h b/indra/newview/llappviewer.h index 4ce4259ed8..3da0246ccf 100644 --- a/indra/newview/llappviewer.h +++ b/indra/newview/llappviewer.h @@ -66,6 +66,20 @@ class LLViewerRegion; extern LLTrace::BlockTimerStatHandle FTM_FRAME; +typedef enum +{ + LAST_EXEC_NORMAL = 0, + LAST_EXEC_FROZE, + LAST_EXEC_LLERROR_CRASH, + LAST_EXEC_OTHER_CRASH, + LAST_EXEC_LOGOUT_FROZE, + LAST_EXEC_LOGOUT_CRASH, + LAST_EXEC_BAD_ALLOC, + LAST_EXEC_MISSING_FILES, + LAST_EXEC_GRAPHICS_INIT, + LAST_EXEC_COUNT +} eLastExecEvent; + class LLAppViewer : public LLApp { public: @@ -143,10 +157,8 @@ public: void loadNameCache(); void saveNameCache(); - void loadExperienceCache(); - void saveExperienceCache(); - void removeMarkerFiles(); + void recordSessionToMarker(); void removeDumpDir(); // LLAppViewer testing helpers. @@ -160,6 +172,8 @@ public: virtual void forceErrorOSSpecificException(); virtual void forceErrorDriverCrash(); virtual void forceErrorCoroutineCrash(); + virtual void forceErrorCoroprocedureCrash(); + virtual void forceErrorWorkQueueCrash(); virtual void forceErrorThreadCrash(); // The list is found in app_settings/settings_files.xml @@ -227,6 +241,9 @@ public: // post given work to the "mainloop" work queue for handling on the main thread void postToMainCoro(const LL::WorkQueue::Work& work); + // Writes an error code into the error_marker file for use on next startup. + void createErrorMarker(eLastExecEvent error_code) const; + // Attempt a 'soft' quit with disconnect and saving of settings/cache. // Intended to be thread safe. // Good chance of viewer crashing either way, but better than alternatives. @@ -272,6 +289,9 @@ private: void processMarkerFiles(); static void recordMarkerVersion(LLAPRFile& marker_file); bool markerIsSameVersion(const std::string& marker_name) const; + LLUUID getMarkerSessionId(const std::string& marker_name) const; + S32 getMarkerErrorCode(const std::string& marker_name) const; + bool getMarkerData(const std::string& marker_name, std::string &data) const; void idle(); void idleShutdown(); @@ -347,18 +367,9 @@ private: extern LLSD gDebugInfo; extern bool gShowObjectUpdates; -typedef enum -{ - LAST_EXEC_NORMAL = 0, - LAST_EXEC_FROZE, - LAST_EXEC_LLERROR_CRASH, - LAST_EXEC_OTHER_CRASH, - LAST_EXEC_LOGOUT_FROZE, - LAST_EXEC_LOGOUT_CRASH -} eLastExecEvent; - extern eLastExecEvent gLastExecEvent; // llstartup extern S32 gLastExecDuration; ///< the duration of the previous run in seconds (<0 indicates unknown) +extern LLUUID gLastAgentSessionId; // will be set if agent logged in extern const char* gPlatform; @@ -399,11 +410,10 @@ extern std::string gLastVersionChannel; extern LLVector3 gWindVec; extern LLVector3 gRelativeWindVec; -extern U32 gPacketsIn; -extern bool gPrintMessagesThisFrame; extern bool gRandomizeFramerate; extern bool gPeriodicSlowFrame; +extern bool gDoDisconnect; extern bool gSimulateMemLeak; diff --git a/indra/newview/llappviewerlinux.cpp b/indra/newview/llappviewerlinux.cpp index 1709970156..c1e8f38c51 100644 --- a/indra/newview/llappviewerlinux.cpp +++ b/indra/newview/llappviewerlinux.cpp @@ -40,15 +40,60 @@ #include <exception> -#if LL_DBUS_ENABLED -# include "llappviewerlinux_api_dbus.h" - -// regrettable hacks to give us better runtime compatibility with older systems inside llappviewerlinux_api.h: -#define llg_return_if_fail(COND) do{if (!(COND)) return;}while(0) -#undef g_return_if_fail -#define g_return_if_fail(COND) llg_return_if_fail(COND) -// The generated API -# include "llappviewerlinux_api.h" +#if LL_GLIB +#include <gio/gio.h> +#endif +#include <netinet/in.h> +#include <resolv.h> + +#if (__GLIBC__*1000 + __GLIBC_MINOR__) >= 2034 +extern "C" +{ + int __res_nquery(res_state statep, + const char *dname, int qclass, int type, + unsigned char *answer, int anslen) + { + return res_nquery( statep, dname, qclass, type, answer, anslen ); + } + + int __dn_expand(const unsigned char *msg, + const unsigned char *eomorig, + const unsigned char *comp_dn, char *exp_dn, + int length) + { + return dn_expand( msg,eomorig,comp_dn,exp_dn,length); + } +} +#endif + +#if LL_SEND_CRASH_REPORTS +#include "breakpad/client/linux/handler/exception_handler.h" +#include "breakpad/common/linux/http_upload.h" +#include "lldir.h" +#include "../llcrashlogger/llcrashlogger.h" +#include "jsoncpp/reader.h" // JSON + +#endif + +#define VIEWERAPI_SERVICE "com.secondlife.ViewerAppAPIService" +#define VIEWERAPI_PATH "/com/secondlife/ViewerAppAPI" +#define VIEWERAPI_INTERFACE "com.secondlife.ViewerAppAPI" + +#if LL_GLIB +static const char * DBUS_SERVER = "<node name=\"/com/secondlife/ViewerAppAPI\">\n" + " <interface name=\"com.secondlife.ViewerAppAPI\">\n" + " <annotation name=\"org.freedesktop.DBus.GLib.CSymbol\" value=\"viewer_app_api\"/>\n" + " <method name=\"GoSLURL\">\n" + " <annotation name=\"org.freedesktop.DBus.GLib.CSymbol\" value=\"dispatchSLURL\"/>\n" + " <arg type=\"s\" name=\"slurl\" direction=\"in\" />\n" + " </method>\n" + " </interface>\n" + "</node>"; + +typedef struct +{ + GObject parent; +} ViewerAppAPI; #endif namespace @@ -81,6 +126,8 @@ int main( int argc, char **argv ) // install unexpected exception handler gOldTerminateHandler = std::set_terminate(exceptionTerminateHandler); + unsetenv( "LD_PRELOAD" ); // <FS:ND/> Get rid of any preloading, we do not want this to happen during startup of plugins. + bool ok = viewer_app_ptr->init(); if(!ok) { @@ -114,21 +161,74 @@ LLAppViewerLinux::~LLAppViewerLinux() { } -bool LLAppViewerLinux::init() +#if LL_SEND_CRASH_REPORTS +std::string gCrashLogger; +std::string gVersion; +std::string gBugsplatDB; +std::string gCrashBehavior; + +static bool dumpCallback(const google_breakpad::MinidumpDescriptor& descriptor, void* context, bool succeeded) +{ + if( fork() == 0 ) + execl( gCrashLogger.c_str(), gCrashLogger.c_str(), descriptor.path(), gVersion.c_str(), gBugsplatDB.c_str(), gCrashBehavior.c_str(), nullptr ); + return succeeded; +} + +void setupBreadpad() { - // g_thread_init() must be called before *any* use of glib, *and* - // before any mutexes are held, *and* some of our third-party - // libraries likes to use glib functions; in short, do this here - // really early in app startup! - if (!g_thread_supported ()) g_thread_init (NULL); + std::string build_data_fname(gDirUtilp->getExpandedFilename(LL_PATH_EXECUTABLE, "build_data.json")); + gCrashLogger = gDirUtilp->getExpandedFilename(LL_PATH_EXECUTABLE, "linux-crash-logger.bin"); + + llifstream inf(build_data_fname.c_str()); + if(!inf.is_open()) + { + LL_WARNS("BUGSPLAT") << "Can't initialize BugSplat, can't read '" << build_data_fname << "'" << LL_ENDL; + return; + } + + Json::Reader reader; + Json::Value build_data; + if(!reader.parse(inf, build_data, false)) + { + LL_WARNS("BUGSPLAT") << "Can't initialize BugSplat, can't parse '" << build_data_fname << "': " + << reader.getFormatedErrorMessages() << LL_ENDL; + return; + } + Json::Value BugSplat_DB = build_data["BugSplat DB"]; + if(!BugSplat_DB) + { + LL_WARNS("BUGSPLAT") << "Can't initialize BugSplat, no 'BugSplat DB' entry in '" << build_data_fname + << "'" << LL_ENDL; + return; + } + gVersion = STRINGIZE( + LL_VIEWER_VERSION_MAJOR << '.' << LL_VIEWER_VERSION_MINOR << '.' << LL_VIEWER_VERSION_PATCH + << '.' << LL_VIEWER_VERSION_BUILD); + gBugsplatDB = BugSplat_DB.asString(); + + LL_INFOS("BUGSPLAT") << "Initializing with crash logger: " << gCrashLogger << " database: " << gBugsplatDB << " version: " << gVersion << LL_ENDL; + + google_breakpad::MinidumpDescriptor *descriptor = new google_breakpad::MinidumpDescriptor(gDirUtilp->getExpandedFilename(LL_PATH_DUMP, "")); + google_breakpad::ExceptionHandler *eh = new google_breakpad::ExceptionHandler(*descriptor, NULL, dumpCallback, NULL, true, -1); +} +#endif + +bool LLAppViewerLinux::init() +{ bool success = LLAppViewer::init(); #if LL_SEND_CRASH_REPORTS - if (success) + S32 nCrashSubmitBehavior = gCrashSettings.getS32("CrashSubmitBehavior"); + + // For the first version we just consider always send and create a nice dialog for CRASH_BEHAVIOR_ASK later. + if (success && nCrashSubmitBehavior != CRASH_BEHAVIOR_NEVER_SEND ) { - LLAppViewer* pApp = LLAppViewer::instance(); - pApp->initCrashReporting(); + if( nCrashSubmitBehavior == CRASH_BEHAVIOR_ASK ) + gCrashBehavior = "ask"; + else + gCrashBehavior = "send"; + setupBreadpad(); } #endif @@ -143,7 +243,7 @@ bool LLAppViewerLinux::restoreErrorTrap() } ///////////////////////////////////////// -#if LL_DBUS_ENABLED +#if LL_GLIB typedef struct { @@ -153,101 +253,77 @@ typedef struct static void viewerappapi_init(ViewerAppAPI *server); static void viewerappapi_class_init(ViewerAppAPIClass *klass); -/// - -// regrettable hacks to give us better runtime compatibility with older systems in general -static GType llg_type_register_static_simple_ONCE(GType parent_type, - const gchar *type_name, - guint class_size, - GClassInitFunc class_init, - guint instance_size, - GInstanceInitFunc instance_init, - GTypeFlags flags) -{ - static GTypeInfo type_info; - memset(&type_info, 0, sizeof(type_info)); - - type_info.class_size = class_size; - type_info.class_init = class_init; - type_info.instance_size = instance_size; - type_info.instance_init = instance_init; - - return g_type_register_static(parent_type, type_name, &type_info, flags); -} -#define llg_intern_static_string(S) (S) -#define g_intern_static_string(S) llg_intern_static_string(S) -#define g_type_register_static_simple(parent_type, type_name, class_size, class_init, instance_size, instance_init, flags) llg_type_register_static_simple_ONCE(parent_type, type_name, class_size, class_init, instance_size, instance_init, flags) - G_DEFINE_TYPE(ViewerAppAPI, viewerappapi, G_TYPE_OBJECT); void viewerappapi_class_init(ViewerAppAPIClass *klass) { } -static bool dbus_server_init = false; - -void viewerappapi_init(ViewerAppAPI *server) +static void dispatchSLURL(gchar const *slurl) { - // Connect to the default DBUS, register our service/API. - - if (!dbus_server_init) - { - GError *error = NULL; - - server->connection = lldbus_g_bus_get(DBUS_BUS_SESSION, &error); - if (server->connection) - { - lldbus_g_object_type_install_info(viewerappapi_get_type(), &dbus_glib_viewerapp_object_info); + LL_INFOS() << "Was asked to go to slurl: " << slurl << LL_ENDL; - lldbus_g_connection_register_g_object(server->connection, VIEWERAPI_PATH, G_OBJECT(server)); + std::string url = slurl; + LLMediaCtrl* web = NULL; + const bool trusted_browser = false; + LLURLDispatcher::dispatch(url, "", web, trusted_browser); +} - DBusGProxy *serverproxy = lldbus_g_proxy_new_for_name(server->connection, DBUS_SERVICE_DBUS, DBUS_PATH_DBUS, DBUS_INTERFACE_DBUS); +static void DoMethodeCall (GDBusConnection *connection, + const gchar *sender, + const gchar *object_path, + const gchar *interface_name, + const gchar *method_name, + GVariant *parameters, + GDBusMethodInvocation *invocation, + gpointer user_data) +{ + LL_INFOS() << "DBUS message " << method_name << " from: " << sender << " interface: " << interface_name << LL_ENDL; + const gchar *slurl; - guint request_name_ret_unused; - // akin to org_freedesktop_DBus_request_name - if (lldbus_g_proxy_call(serverproxy, "RequestName", &error, G_TYPE_STRING, VIEWERAPI_SERVICE, G_TYPE_UINT, 0, G_TYPE_INVALID, G_TYPE_UINT, &request_name_ret_unused, G_TYPE_INVALID)) - { - // total success. - dbus_server_init = true; - } - else - { - LL_WARNS() << "Unable to register service name: " << error->message << LL_ENDL; - } + g_variant_get (parameters, "(&s)", &slurl); + dispatchSLURL(slurl); +} - g_object_unref(serverproxy); - } - else +GDBusNodeInfo *gBusNodeInfo = nullptr; +static const GDBusInterfaceVTable interface_vtable = { - g_warning("Unable to connect to dbus: %s", error->message); - } - - if (error) - g_error_free(error); - } + DoMethodeCall + }; +static void busAcquired(GDBusConnection *connection, const gchar *name, gpointer user_data) +{ + auto id = g_dbus_connection_register_object(connection, + VIEWERAPI_PATH, + gBusNodeInfo->interfaces[0], + &interface_vtable, + NULL, /* user_data */ + NULL, /* user_data_free_func */ + NULL); /* GError** */ + g_assert (id > 0); } -gboolean viewer_app_api_GoSLURL(ViewerAppAPI *obj, gchar *slurl, gboolean **success_rtn, GError **error) +static void nameAcquired(GDBusConnection *connection, const gchar *name, gpointer user_data) { - bool success = false; - - LL_INFOS() << "Was asked to go to slurl: " << slurl << LL_ENDL; +} - std::string url = slurl; - LLMediaCtrl* web = NULL; - const bool trusted_browser = false; - if (LLURLDispatcher::dispatch(url, "", web, trusted_browser)) - { - // bring window to foreground, as it has just been "launched" from a URL - // todo: hmm, how to get there from here? - //xxx->mWindow->bringToFront(); - success = true; - } +static void nameLost(GDBusConnection *connection, const gchar *name, gpointer user_data) +{ - *success_rtn = g_new (gboolean, 1); - (*success_rtn)[0] = (gboolean)success; +} +void viewerappapi_init(ViewerAppAPI *server) +{ + gBusNodeInfo = g_dbus_node_info_new_for_xml (DBUS_SERVER, NULL); + g_assert (gBusNodeInfo != NULL); + + g_bus_own_name(G_BUS_TYPE_SESSION, + VIEWERAPI_SERVICE, + G_BUS_NAME_OWNER_FLAGS_NONE, + busAcquired, + nameAcquired, + nameLost, + NULL, + NULL); - return TRUE; // the invokation succeeded, even if the actual dispatch didn't. } /// @@ -255,13 +331,6 @@ gboolean viewer_app_api_GoSLURL(ViewerAppAPI *obj, gchar *slurl, gboolean **succ //virtual bool LLAppViewerLinux::initSLURLHandler() { - if (!grab_dbus_syms(DBUSGLIB_DYLIB_DEFAULT_NAME)) - { - return false; // failed - } - - g_type_init(); - //ViewerAppAPI *api_server = (ViewerAppAPI*) g_object_new(viewerappapi_get_type(), NULL); @@ -271,49 +340,49 @@ bool LLAppViewerLinux::initSLURLHandler() //virtual bool LLAppViewerLinux::sendURLToOtherInstance(const std::string& url) { - if (!grab_dbus_syms(DBUSGLIB_DYLIB_DEFAULT_NAME)) + auto *pBus = g_bus_get_sync(G_BUS_TYPE_SESSION, NULL, nullptr); + + if( !pBus ) { - return false; // failed + LL_WARNS() << "Getting dbus failed." << LL_ENDL; + return false; } - bool success = false; - DBusGConnection *bus; - GError *error = NULL; - - g_type_init(); + auto pProxy = g_dbus_proxy_new_sync(pBus, G_DBUS_PROXY_FLAGS_NONE, nullptr, + VIEWERAPI_SERVICE, VIEWERAPI_PATH, + VIEWERAPI_INTERFACE, nullptr, nullptr); - bus = lldbus_g_bus_get (DBUS_BUS_SESSION, &error); - if (bus) + if( !pProxy ) { - gboolean rtn = FALSE; - DBusGProxy *remote_object = - lldbus_g_proxy_new_for_name(bus, VIEWERAPI_SERVICE, VIEWERAPI_PATH, VIEWERAPI_INTERFACE); - - if (lldbus_g_proxy_call(remote_object, "GoSLURL", &error, - G_TYPE_STRING, url.c_str(), G_TYPE_INVALID, - G_TYPE_BOOLEAN, &rtn, G_TYPE_INVALID)) - { - success = rtn; - } - else - { - LL_INFOS() << "Call-out to other instance failed (perhaps not running): " << error->message << LL_ENDL; - } - - g_object_unref(G_OBJECT(remote_object)); + LL_WARNS() << "Cannot create new dbus proxy." << LL_ENDL; + g_object_unref( pBus ); + return false; } - else + + auto *pArgs = g_variant_new( "(s)", url.c_str() ); + if( !pArgs ) { - LL_WARNS() << "Couldn't connect to session bus: " << error->message << LL_ENDL; + LL_WARNS() << "Cannot create new variant." << LL_ENDL; + g_object_unref( pBus ); + return false; } - if (error) - g_error_free(error); + auto pRes = g_dbus_proxy_call_sync(pProxy, + "GoSLURL", + pArgs, + G_DBUS_CALL_FLAGS_NONE, + -1, nullptr, nullptr); - return success; + + + if( pRes ) + g_variant_unref( pRes ); + g_object_unref( pProxy ); + g_object_unref( pBus ); + return true; } -#else // LL_DBUS_ENABLED +#else // LL_GLIB bool LLAppViewerLinux::initSLURLHandler() { return false; // not implemented without dbus @@ -322,31 +391,36 @@ bool LLAppViewerLinux::sendURLToOtherInstance(const std::string& url) { return false; // not implemented without dbus } -#endif // LL_DBUS_ENABLED +#endif // LL_GLIB void LLAppViewerLinux::initCrashReporting(bool reportFreeze) { std::string cmd =gDirUtilp->getExecutableDir(); cmd += gDirUtilp->getDirDelimiter(); -#if LL_LINUX +//#if LL_LINUX cmd += "linux-crash-logger.bin"; +/* #else # error Unknown platform #endif +*/ std::stringstream pid_str; pid_str << LLApp::getPid(); std::string logdir = gDirUtilp->getExpandedFilename(LL_PATH_DUMP, ""); std::string appname = gDirUtilp->getExecutableFilename(); + std::string grid{ LLGridManager::getInstance()->getGridId() }; + std::string title{ LLAppViewer::instance()->getSecondLifeTitle() }; + std::string pidstr{ pid_str.str() }; // launch the actual crash logger const char * cmdargv[] = {cmd.c_str(), "-user", - (char*)LLGridManager::getInstance()->getGridId().c_str(), + grid.c_str(), "-name", - LLAppViewer::instance()->getSecondLifeTitle().c_str(), + title.c_str(), "-pid", - pid_str.str().c_str(), + pidstr.c_str(), "-dumpdir", logdir.c_str(), "-procname", diff --git a/indra/newview/llappviewerlinux.h b/indra/newview/llappviewerlinux.h index dde223878d..460ca721f1 100644 --- a/indra/newview/llappviewerlinux.h +++ b/indra/newview/llappviewerlinux.h @@ -27,17 +27,6 @@ #ifndef LL_LLAPPVIEWERLINUX_H #define LL_LLAPPVIEWERLINUX_H -extern "C" { -# include <glib.h> -} - -#if LL_DBUS_ENABLED -extern "C" { -# include <glib-object.h> -# include <dbus/dbus-glib.h> -} -#endif - #ifndef LL_LLAPPVIEWER_H #include "llappviewer.h" #endif @@ -70,21 +59,4 @@ protected: virtual bool sendURLToOtherInstance(const std::string& url); }; -#if LL_DBUS_ENABLED -typedef struct -{ - GObject parent; - DBusGConnection *connection; -} ViewerAppAPI; - -extern "C" { - gboolean viewer_app_api_GoSLURL(ViewerAppAPI *obj, gchar *slurl, gboolean **success_rtn, GError **error); -} - -#define VIEWERAPI_SERVICE "com.secondlife.ViewerAppAPIService" -#define VIEWERAPI_PATH "/com/secondlife/ViewerAppAPI" -#define VIEWERAPI_INTERFACE "com.secondlife.ViewerAppAPI" - -#endif // LL_DBUS_ENABLED - #endif // LL_LLAPPVIEWERLINUX_H diff --git a/indra/newview/llappviewerlinux_api.h b/indra/newview/llappviewerlinux_api.h deleted file mode 100644 index 3d1324dd19..0000000000 --- a/indra/newview/llappviewerlinux_api.h +++ /dev/null @@ -1,143 +0,0 @@ -/* Generated by dbus-binding-tool; do not edit! */ -/** - * $LicenseInfo:firstyear=2008&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 of the License only. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA - * $/LicenseInfo$ - */ - -#ifndef __dbus_glib_marshal_viewerapp_MARSHAL_H__ -#define __dbus_glib_marshal_viewerapp_MARSHAL_H__ - -#include <glib-object.h> - -G_BEGIN_DECLS - -#ifdef G_ENABLE_DEBUG -#define g_marshal_value_peek_boolean(v) g_value_get_boolean (v) -#define g_marshal_value_peek_char(v) g_value_get_char (v) -#define g_marshal_value_peek_uchar(v) g_value_get_uchar (v) -#define g_marshal_value_peek_int(v) g_value_get_int (v) -#define g_marshal_value_peek_uint(v) g_value_get_uint (v) -#define g_marshal_value_peek_long(v) g_value_get_long (v) -#define g_marshal_value_peek_ulong(v) g_value_get_ulong (v) -#define g_marshal_value_peek_int64(v) g_value_get_int64 (v) -#define g_marshal_value_peek_uint64(v) g_value_get_uint64 (v) -#define g_marshal_value_peek_enum(v) g_value_get_enum (v) -#define g_marshal_value_peek_flags(v) g_value_get_flags (v) -#define g_marshal_value_peek_float(v) g_value_get_float (v) -#define g_marshal_value_peek_double(v) g_value_get_double (v) -#define g_marshal_value_peek_string(v) (char*) g_value_get_string (v) -#define g_marshal_value_peek_param(v) g_value_get_param (v) -#define g_marshal_value_peek_boxed(v) g_value_get_boxed (v) -#define g_marshal_value_peek_pointer(v) g_value_get_pointer (v) -#define g_marshal_value_peek_object(v) g_value_get_object (v) -#else /* !G_ENABLE_DEBUG */ -/* WARNING: This code accesses GValues directly, which is UNSUPPORTED API. - * Do not access GValues directly in your code. Instead, use the - * g_value_get_*() functions - */ -#define g_marshal_value_peek_boolean(v) (v)->data[0].v_int -#define g_marshal_value_peek_char(v) (v)->data[0].v_int -#define g_marshal_value_peek_uchar(v) (v)->data[0].v_uint -#define g_marshal_value_peek_int(v) (v)->data[0].v_int -#define g_marshal_value_peek_uint(v) (v)->data[0].v_uint -#define g_marshal_value_peek_long(v) (v)->data[0].v_long -#define g_marshal_value_peek_ulong(v) (v)->data[0].v_ulong -#define g_marshal_value_peek_int64(v) (v)->data[0].v_int64 -#define g_marshal_value_peek_uint64(v) (v)->data[0].v_uint64 -#define g_marshal_value_peek_enum(v) (v)->data[0].v_long -#define g_marshal_value_peek_flags(v) (v)->data[0].v_ulong -#define g_marshal_value_peek_float(v) (v)->data[0].v_float -#define g_marshal_value_peek_double(v) (v)->data[0].v_double -#define g_marshal_value_peek_string(v) (v)->data[0].v_pointer -#define g_marshal_value_peek_param(v) (v)->data[0].v_pointer -#define g_marshal_value_peek_boxed(v) (v)->data[0].v_pointer -#define g_marshal_value_peek_pointer(v) (v)->data[0].v_pointer -#define g_marshal_value_peek_object(v) (v)->data[0].v_pointer -#endif /* !G_ENABLE_DEBUG */ - - -/* BOOLEAN:STRING,POINTER,POINTER (/tmp/dbus-binding-tool-c-marshallers.5XXD8T:1) */ -extern void dbus_glib_marshal_viewerapp_BOOLEAN__STRING_POINTER_POINTER (GClosure *closure, - GValue *return_value, - guint n_param_values, - const GValue *param_values, - gpointer invocation_hint, - gpointer marshal_data); -void -dbus_glib_marshal_viewerapp_BOOLEAN__STRING_POINTER_POINTER (GClosure *closure, - GValue *return_value, - guint n_param_values, - const GValue *param_values, - gpointer invocation_hint, - gpointer marshal_data) -{ - typedef gboolean (*GMarshalFunc_BOOLEAN__STRING_POINTER_POINTER) (gpointer data1, - gpointer arg_1, - gpointer arg_2, - gpointer arg_3, - gpointer data2); - register GMarshalFunc_BOOLEAN__STRING_POINTER_POINTER callback; - register GCClosure *cc = (GCClosure*) closure; - register gpointer data1, data2; - gboolean v_return; - - g_return_if_fail (return_value != NULL); - g_return_if_fail (n_param_values == 4); - - if (G_CCLOSURE_SWAP_DATA (closure)) - { - data1 = closure->data; - data2 = g_value_peek_pointer (param_values + 0); - } - else - { - data1 = g_value_peek_pointer (param_values + 0); - data2 = closure->data; - } - callback = (GMarshalFunc_BOOLEAN__STRING_POINTER_POINTER) (marshal_data ? marshal_data : cc->callback); - - v_return = callback (data1, - g_marshal_value_peek_string (param_values + 1), - g_marshal_value_peek_pointer (param_values + 2), - g_marshal_value_peek_pointer (param_values + 3), - data2); - - g_value_set_boolean (return_value, v_return); -} - -G_END_DECLS - -#endif /* __dbus_glib_marshal_viewerapp_MARSHAL_H__ */ - -#include <dbus/dbus-glib.h> -static const DBusGMethodInfo dbus_glib_viewerapp_methods[] = { - { (GCallback) viewer_app_api_GoSLURL, dbus_glib_marshal_viewerapp_BOOLEAN__STRING_POINTER_POINTER, 0 }, -}; - -const DBusGObjectInfo dbus_glib_viewerapp_object_info = { - 0, - dbus_glib_viewerapp_methods, - 1, -"com.secondlife.ViewerAppAPI\0GoSLURL\0S\0slurl\0I\0s\0success_ret\0O\0F\0N\0b\0\0\0", -"\0", -"\0" -}; - diff --git a/indra/newview/llappviewerlinux_api.xml b/indra/newview/llappviewerlinux_api.xml deleted file mode 100644 index fac35b7adc..0000000000 --- a/indra/newview/llappviewerlinux_api.xml +++ /dev/null @@ -1,14 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" ?> - -<!-- dbus-binding-tool -mode=glib-server llappviewerlinux_api.xml -prefix=viewerapp -output=llappviewerlinux_api.h --> - -<node name="/com/secondlife/ViewerAppAPI"> - <interface name="com.secondlife.ViewerAppAPI"> - <annotation name="org.freedesktop.DBus.GLib.CSymbol" value="viewer_app_api"/> - <method name="GoSLURL"> - <annotation name="org.freedesktop.DBus.GLib.CSymbol" value="viewer_app_api_GoSLURL"/> - <arg type="s" name="slurl" direction="in" /> - <arg type="b" name="success_ret" direction="out" /> - </method> - </interface> -</node> diff --git a/indra/newview/llappviewerlinux_api_dbus.cpp b/indra/newview/llappviewerlinux_api_dbus.cpp deleted file mode 100644 index 9aed8a98d4..0000000000 --- a/indra/newview/llappviewerlinux_api_dbus.cpp +++ /dev/null @@ -1,126 +0,0 @@ -/** - * @file llappviewerlinux_api_dbus.cpp - * @brief dynamic DBus symbol-grabbing code - * - * $LicenseInfo:firstyear=2008&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 of the License only. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA - * $/LicenseInfo$ - */ - -#if LL_DBUS_ENABLED - -#include "linden_common.h" - -extern "C" { -#include <dbus/dbus-glib.h> - -#include "apr_pools.h" -#include "apr_dso.h" -} - -#define DEBUGMSG(...) do { LL_DEBUGS() << llformat(__VA_ARGS__) << LL_ENDL; } while(0) -#define INFOMSG(...) do { LL_INFOS() << llformat(__VA_ARGS__) << LL_ENDL; } while(0) -#define WARNMSG(...) do { LL_WARNS() << llformat(__VA_ARGS__) << LL_ENDL; } while(0) - -#define LL_DBUS_SYM(REQUIRED, DBUSSYM, RTN, ...) RTN (*ll##DBUSSYM)(__VA_ARGS__) = NULL -#include "llappviewerlinux_api_dbus_syms_raw.inc" -#undef LL_DBUS_SYM - -static bool sSymsGrabbed = false; -static apr_pool_t *sSymDBUSDSOMemoryPool = NULL; -static apr_dso_handle_t *sSymDBUSDSOHandleG = NULL; - -bool grab_dbus_syms(std::string dbus_dso_name) -{ - if (sSymsGrabbed) - { - // already have grabbed good syms - return true; - } - - bool sym_error = false; - bool rtn = false; - apr_status_t rv; - apr_dso_handle_t *sSymDBUSDSOHandle = NULL; - -#define LL_DBUS_SYM(REQUIRED, DBUSSYM, RTN, ...) do{rv = apr_dso_sym((apr_dso_handle_sym_t*)&ll##DBUSSYM, sSymDBUSDSOHandle, #DBUSSYM); if (rv != APR_SUCCESS) {INFOMSG("Failed to grab symbol: %s", #DBUSSYM); if (REQUIRED) sym_error = true;} else DEBUGMSG("grabbed symbol: %s from %p", #DBUSSYM, (void*)ll##DBUSSYM);}while(0) - - //attempt to load the shared library - apr_pool_create(&sSymDBUSDSOMemoryPool, NULL); - - if ( APR_SUCCESS == (rv = apr_dso_load(&sSymDBUSDSOHandle, - dbus_dso_name.c_str(), - sSymDBUSDSOMemoryPool) )) - { - INFOMSG("Found DSO: %s", dbus_dso_name.c_str()); - -#include "llappviewerlinux_api_dbus_syms_raw.inc" - - if ( sSymDBUSDSOHandle ) - { - sSymDBUSDSOHandleG = sSymDBUSDSOHandle; - sSymDBUSDSOHandle = NULL; - } - - rtn = !sym_error; - } - else - { - INFOMSG("Couldn't load DSO: %s", dbus_dso_name.c_str()); - rtn = false; // failure - } - - if (sym_error) - { - WARNMSG("Failed to find necessary symbols in DBUS-GLIB libraries."); - } -#undef LL_DBUS_SYM - - sSymsGrabbed = rtn; - return rtn; -} - - -void ungrab_dbus_syms() -{ - // should be safe to call regardless of whether we've - // actually grabbed syms. - - if ( sSymDBUSDSOHandleG ) - { - apr_dso_unload(sSymDBUSDSOHandleG); - sSymDBUSDSOHandleG = NULL; - } - - if ( sSymDBUSDSOMemoryPool ) - { - apr_pool_destroy(sSymDBUSDSOMemoryPool); - sSymDBUSDSOMemoryPool = NULL; - } - - // NULL-out all of the symbols we'd grabbed -#define LL_DBUS_SYM(REQUIRED, DBUSSYM, RTN, ...) do{ll##DBUSSYM = NULL;}while(0) -#include "llappviewerlinux_api_dbus_syms_raw.inc" -#undef LL_DBUS_SYM - - sSymsGrabbed = false; -} - -#endif // LL_DBUS_ENABLED diff --git a/indra/newview/llappviewerlinux_api_dbus_syms_raw.inc b/indra/newview/llappviewerlinux_api_dbus_syms_raw.inc deleted file mode 100644 index c0548e2fba..0000000000 --- a/indra/newview/llappviewerlinux_api_dbus_syms_raw.inc +++ /dev/null @@ -1,9 +0,0 @@ - -// required symbols to grab -LL_DBUS_SYM(true, dbus_g_bus_get, DBusGConnection*, DBusBusType, GError**); -LL_DBUS_SYM(true, dbus_g_proxy_new_for_name, DBusGProxy*, DBusGConnection*, const char *, const char*, const char*); -LL_DBUS_SYM(true, dbus_g_proxy_call, gboolean, DBusGProxy*, const char*, GError**, GType, ...); -LL_DBUS_SYM(true, dbus_g_object_type_install_info, void, GType, const DBusGObjectInfo*); -LL_DBUS_SYM(true, dbus_g_connection_register_g_object, void, DBusGConnection*, const char*, GObject*); - -// optional symbols to grab diff --git a/indra/newview/llappviewermacosx-for-objc.h b/indra/newview/llappviewermacosx-for-objc.h index 5a69cd93fc..c3f1e35872 100644 --- a/indra/newview/llappviewermacosx-for-objc.h +++ b/indra/newview/llappviewermacosx-for-objc.h @@ -41,6 +41,7 @@ void clearDumpLogsDir(); struct CrashMetadata { std::string logFilePathname; + std::string attributesPathname; std::string userSettingsPathname; std::string accountSettingsPathname; std::string staticDebugPathname; diff --git a/indra/newview/llappviewermacosx.cpp b/indra/newview/llappviewermacosx.cpp index 4162c0479a..aab6d00573 100644 --- a/indra/newview/llappviewermacosx.cpp +++ b/indra/newview/llappviewermacosx.cpp @@ -172,6 +172,8 @@ CrashMetadataSingleton::CrashMetadataSingleton() // Note: we depend on being able to read the static_debug_info.log file // from the *previous* run before we overwrite it with the new one for // *this* run. LLAppViewer initialization must happen in the Right Order. + + // Todo: consider converting static file into bugspalt attributes file staticDebugPathname = *gViewerAppPtr->getStaticDebugFile(); std::ifstream static_file(staticDebugPathname); LLSD info; @@ -215,7 +217,32 @@ CrashMetadataSingleton::CrashMetadataSingleton() } } } + + // Populate bugsplat attributes + LLXMLNodePtr out_node = new LLXMLNode("XmlCrashContext", false); + + out_node->createChild("OS", false)->setValue(OSInfo); + out_node->createChild("AppState", false)->setValue(info["StartupState"].asString()); + out_node->createChild("GraphicsCard", false)->setValue(info["GraphicsCard"].asString()); + out_node->createChild("GLVersion", false)->setValue(info["GLInfo"]["GLVersion"].asString()); + out_node->createChild("GLRenderer", false)->setValue(info["GLInfo"]["GLRenderer"].asString()); + out_node->createChild("RAM", false)->setValue(info["RAMInfo"]["Physical"].asString()); + + if (!out_node->isNull()) + { + attributesPathname = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, "CrashContext.xml"); + LLFILE* fp = LLFile::fopen(attributesPathname, "w"); + + if (fp != NULL) + { + LLXMLNode::writeHeaderToFile(fp); + out_node->writeToFile(fp); + + fclose(fp); + } + } } + // else Todo: consider fillig at least some values, like OS } // Avoid having to compile all of our LLSingleton machinery in Objective-C++. diff --git a/indra/newview/llappviewerwin32.cpp b/indra/newview/llappviewerwin32.cpp index 023ec3410a..169fea320a 100644 --- a/indra/newview/llappviewerwin32.cpp +++ b/indra/newview/llappviewerwin32.cpp @@ -155,10 +155,10 @@ namespace sBugSplatSender->setAttribute(WCSTR(L"OS"), WCSTR(LLOSInfo::instance().getOSStringSimple())); // In case we ever stop using email for this sBugSplatSender->setAttribute(WCSTR(L"AppState"), WCSTR(LLStartUp::getStartupStateString())); - sBugSplatSender->setAttribute(WCSTR(L"GL Vendor"), WCSTR(gGLManager.mGLVendor)); - sBugSplatSender->setAttribute(WCSTR(L"GL Version"), WCSTR(gGLManager.mGLVersionString)); - sBugSplatSender->setAttribute(WCSTR(L"GPU Version"), WCSTR(gGLManager.mDriverVersionVendorString)); - sBugSplatSender->setAttribute(WCSTR(L"GL Renderer"), WCSTR(gGLManager.mGLRenderer)); + sBugSplatSender->setAttribute(WCSTR(L"GLVendor"), WCSTR(gGLManager.mGLVendor)); + sBugSplatSender->setAttribute(WCSTR(L"GLVersion"), WCSTR(gGLManager.mGLVersionString)); + sBugSplatSender->setAttribute(WCSTR(L"GPUVersion"), WCSTR(gGLManager.mDriverVersionVendorString)); + sBugSplatSender->setAttribute(WCSTR(L"GLRenderer"), WCSTR(gGLManager.mGLRenderer)); sBugSplatSender->setAttribute(WCSTR(L"VRAM"), WCSTR(STRINGIZE(gGLManager.mVRAM))); sBugSplatSender->setAttribute(WCSTR(L"RAM"), WCSTR(STRINGIZE(gSysMemory.getPhysicalMemoryKB().value()))); @@ -396,17 +396,10 @@ void ll_nvapi_init(NvDRSSessionHandle hSession) } } -//#define DEBUGGING_SEH_FILTER 1 -#if DEBUGGING_SEH_FILTER -# define WINMAIN DebuggingWinMain -#else -# define WINMAIN wWinMain -#endif - -int APIENTRY WINMAIN(HINSTANCE hInstance, - HINSTANCE hPrevInstance, - PWSTR pCmdLine, - int nCmdShow) +int APIENTRY wWinMain(HINSTANCE hInstance, + HINSTANCE hPrevInstance, + PWSTR pCmdLine, + int nCmdShow) { // Call Tracy first thing to have it allocate memory // https://github.com/wolfpld/tracy/issues/196 @@ -555,27 +548,6 @@ int APIENTRY WINMAIN(HINSTANCE hInstance, return 0; } -#if DEBUGGING_SEH_FILTER -// The compiler doesn't like it when you use __try/__except blocks -// in a method that uses object destructors. Go figure. -// This winmain just calls the real winmain inside __try. -// The __except calls our exception filter function. For debugging purposes. -int APIENTRY wWinMain(HINSTANCE hInstance, - HINSTANCE hPrevInstance, - PWSTR lpCmdLine, - int nCmdShow) -{ - __try - { - WINMAIN(hInstance, hPrevInstance, lpCmdLine, nCmdShow); - } - __except( viewer_windows_exception_handler( GetExceptionInformation() ) ) - { - _tprintf( _T("Exception handled.\n") ); - } -} -#endif - void LLAppViewerWin32::disableWinErrorReporting() { std::string executable_name = gDirUtilp->getExecutableFilename(); @@ -804,14 +776,16 @@ bool LLAppViewerWin32::cleanup() return result; } -void LLAppViewerWin32::reportCrashToBugsplat(void* pExcepInfo) +bool LLAppViewerWin32::reportCrashToBugsplat(void* pExcepInfo) { #if defined(LL_BUGSPLAT) if (sBugSplatSender) { sBugSplatSender->createReport((EXCEPTION_POINTERS*)pExcepInfo); + return true; } #endif // LL_BUGSPLAT + return false; } void LLAppViewerWin32::initLoggingAndGetLastDuration() diff --git a/indra/newview/llappviewerwin32.h b/indra/newview/llappviewerwin32.h index 2242c95b06..250e72edf3 100644 --- a/indra/newview/llappviewerwin32.h +++ b/indra/newview/llappviewerwin32.h @@ -43,7 +43,7 @@ public: bool init() override; // Override to do application initialization bool cleanup() override; - void reportCrashToBugsplat(void* pExcepInfo) override; + bool reportCrashToBugsplat(void* pExcepInfo) override; protected: void initLoggingAndGetLastDuration() override; // Override to clean stack_trace info. diff --git a/indra/newview/llattachmentsmgr.cpp b/indra/newview/llattachmentsmgr.cpp index 8b5db2c0fa..73ac895d0d 100644 --- a/indra/newview/llattachmentsmgr.cpp +++ b/indra/newview/llattachmentsmgr.cpp @@ -545,3 +545,28 @@ void LLAttachmentsMgr::spamStatusInfo() } #endif } + +// [SL:KB] - Patch: Appearance-PhantomAttach | Checked: Catznip-5.0 +void LLAttachmentsMgr::refreshAttachments() +{ + if (!isAgentAvatarValid()) + return; + + for (const auto& kvpAttachPt : gAgentAvatarp->mAttachmentPoints) + { + for (const LLViewerObject* pAttachObj : kvpAttachPt.second->mAttachedObjects) + { + const LLUUID& idItem = pAttachObj->getAttachmentItemID(); + if ( (mAttachmentRequests.wasRequestedRecently(idItem)) || (pAttachObj->isTempAttachment()) ) + continue; + + AttachmentsInfo attachment; + attachment.mItemID = idItem; + attachment.mAttachmentPt = kvpAttachPt.first; + attachment.mAdd = true; + mPendingAttachments.push_back(attachment); + mAttachmentRequests.addTime(idItem); + } + } +} +// [/SL:KB] diff --git a/indra/newview/llattachmentsmgr.h b/indra/newview/llattachmentsmgr.h index 2428acfb38..de36253339 100644 --- a/indra/newview/llattachmentsmgr.h +++ b/indra/newview/llattachmentsmgr.h @@ -87,6 +87,9 @@ public: bool isAttachmentStateComplete() const; + // [SL:KB] - Patch: Appearance-PhantomAttach | Checked: Catznip-5.0 + void refreshAttachments(); + private: class LLItemRequestTimes: public std::map<LLUUID,LLTimer> diff --git a/indra/newview/llavatarlist.cpp b/indra/newview/llavatarlist.cpp index 8f858fe4e1..52cd86951d 100644 --- a/indra/newview/llavatarlist.cpp +++ b/indra/newview/llavatarlist.cpp @@ -36,6 +36,7 @@ #include "lltextutil.h" // newview +#include "llagent.h" #include "llagentdata.h" // for comparator #include "llavatariconctrl.h" #include "llavatarnamecache.h" @@ -47,11 +48,12 @@ #include "llvoiceclient.h" #include "llviewercontrol.h" // for gSavedSettings #include "lltooldraganddrop.h" +#include "llworld.h" static LLDefaultChildRegistry::Register<LLAvatarList> r("avatar_list"); // Last interaction time update period. -static const F32 LIT_UPDATE_PERIOD = 5; +static const F32 LIT_UPDATE_PERIOD = 1; // Maximum number of avatars that can be added to a list in one pass. // Used to limit time spent for avatar list update per frame. @@ -119,6 +121,8 @@ static const LLFlatListView::ItemReverseComparator REVERSE_NAME_COMPARATOR(NAME_ LLAvatarList::Params::Params() : ignore_online_status("ignore_online_status", false) +, show_avatar_arrival_time("show_avatar_arrival_time", false) +, show_avatar_distance("show_avatar_distance", false) , show_last_interaction_time("show_last_interaction_time", false) , show_info_btn("show_info_btn", true) , show_profile_btn("show_profile_btn", true) @@ -131,6 +135,8 @@ LLAvatarList::LLAvatarList(const Params& p) : LLFlatListViewEx(p) , mIgnoreOnlineStatus(p.ignore_online_status) , mShowLastInteractionTime(p.show_last_interaction_time) +, mAvatarDistance(p.show_avatar_distance) +, mAvatarArrivalTime(p.show_avatar_arrival_time) , mContextMenu(NULL) , mDirty(true) // to force initial update , mNeedUpdateNames(false) @@ -147,7 +153,7 @@ LLAvatarList::LLAvatarList(const Params& p) // Set default sort order. setComparator(&NAME_COMPARATOR); - if (mShowLastInteractionTime) + if (mShowLastInteractionTime || mAvatarDistance || mAvatarArrivalTime) { mLITUpdateTimer = new LLTimer(); mLITUpdateTimer->setTimerExpirySec(0); // zero to force initial update @@ -196,9 +202,20 @@ void LLAvatarList::draw() if (mDirty) refresh(); - if (mShowLastInteractionTime && mLITUpdateTimer->hasExpired()) + if ((mShowLastInteractionTime || mAvatarDistance || mAvatarArrivalTime) && mLITUpdateTimer->hasExpired()) { + if (mAvatarArrivalTime) + { + updateAvatarArrivalTime(); + } + if (mAvatarDistance) + { + updateAvatarDistance(); + } + if (mShowLastInteractionTime) + { updateLastInteractionTimes(); + } mLITUpdateTimer->setTimerExpirySec(LIT_UPDATE_PERIOD); // restart the timer } } @@ -422,6 +439,8 @@ void LLAvatarList::addNewItem(const LLUUID& id, const std::string& name, bool is // This sets the name as a side effect item->setAvatarId(id, mSessionID, mIgnoreOnlineStatus); item->setOnline(mIgnoreOnlineStatus ? true : is_online); + item->showAvatarArrivalTime(mAvatarArrivalTime); + item->showAvatarDistance(mAvatarDistance); item->showLastInteractionTime(mShowLastInteractionTime); item->setAvatarIconVisible(mShowIcons); @@ -528,6 +547,46 @@ void LLAvatarList::computeDifference( LLCommonUtils::computeDifference(vnew_unsorted, vcur, vadded, vremoved); } +void LLAvatarList::updateAvatarArrivalTime() +{ + std::vector<LLPanel*> items; + getItems(items); + auto uuids = getIDs(); + std::vector<LLVector3d> positions; + auto me_pos = gAgent.getPositionGlobal(); + LLWorld::getInstance()->getAvatars(&uuids, &positions, me_pos, gSavedSettings.getF32("MPVNearMeRange")); + LLRecentPeople::instance().updateAvatarsArrivalTime(uuids); + for (auto it = items.begin(); it != items.end(); it++) + { + auto item = static_cast<LLAvatarListItem*>(*it); + auto secs_since = LLDate::now().secondsSinceEpoch() - LLRecentPeople::instance().getArrivalTimeByID(item->getAvatarId()); + if (secs_since >= 0) + item->setAvatarArrivalTime(secs_since); + } +} + + void LLAvatarList::updateAvatarDistance() +{ + std::vector<LLPanel*> items; + getItems(items); + auto uuids = getIDs(); + std::vector<LLVector3d> positions; + auto me_pos = gAgent.getPositionGlobal(); + LLWorld::getInstance()->getAvatars(&uuids, &positions, me_pos, gSavedSettings.getF32("MPVNearMeRange")); + std::map <LLUUID, LLVector3d> avatarsPositions; + auto pos_it = positions.begin(); + auto id_it = uuids.begin(); + for (;pos_it != positions.end() && id_it != uuids.end(); ++pos_it, ++id_it) + { + avatarsPositions[*id_it] = *pos_it; + } + for (auto it = items.begin(); it != items.end(); it++) + { + auto item = static_cast<LLAvatarListItem*>(*it); + item->setAvatarDistance(dist_vec(avatarsPositions[item->getAvatarId()], me_pos)); + } +} + // Refresh shown time of our last interaction with all listed avatars. void LLAvatarList::updateLastInteractionTimes() { diff --git a/indra/newview/llavatarlist.h b/indra/newview/llavatarlist.h index af5bfefcde..37ad578a20 100644 --- a/indra/newview/llavatarlist.h +++ b/indra/newview/llavatarlist.h @@ -50,6 +50,8 @@ public: struct Params : public LLInitParam::Block<Params, LLFlatListViewEx::Params> { Optional<bool> ignore_online_status, // show all items as online + show_avatar_arrival_time, + show_avatar_distance, show_last_interaction_time, // show most recent interaction time. *HACK: move this to a derived class show_info_btn, show_profile_btn, @@ -110,6 +112,8 @@ protected: const uuid_vec_t& vnew, uuid_vec_t& vadded, uuid_vec_t& vremoved); + void updateAvatarArrivalTime(); + void updateAvatarDistance(); void updateLastInteractionTimes(); void rebuildNames(); void onItemDoubleClicked(LLUICtrl* ctrl, S32 x, S32 y, MASK mask); @@ -118,6 +122,8 @@ protected: private: bool mIgnoreOnlineStatus; + bool mAvatarArrivalTime; + bool mAvatarDistance; bool mShowLastInteractionTime; bool mDirty; bool mNeedUpdateNames; diff --git a/indra/newview/llavatarlistitem.cpp b/indra/newview/llavatarlistitem.cpp index 880910d18e..7be4f4eeb8 100644 --- a/indra/newview/llavatarlistitem.cpp +++ b/indra/newview/llavatarlistitem.cpp @@ -65,6 +65,8 @@ LLAvatarListItem::LLAvatarListItem(bool not_from_ui_factory/* = true*/) LLFriendObserver(), mAvatarIcon(NULL), mAvatarName(NULL), + mAvatarArrivalTime(NULL), + mAvatarDistance(NULL), mLastInteractionTime(NULL), mIconPermissionOnline(NULL), mIconPermissionMap(NULL), @@ -107,6 +109,8 @@ bool LLAvatarListItem::postBuild() { mAvatarIcon = getChild<LLAvatarIconCtrl>("avatar_icon"); mAvatarName = getChild<LLTextBox>("avatar_name"); + mAvatarArrivalTime = getChild<LLTextBox>("avatar_arrival_time"); + mAvatarDistance = getChild<LLTextBox>("avatar_distance"); mLastInteractionTime = getChild<LLTextBox>("last_interaction"); mIconPermissionOnline = getChild<LLIconCtrl>("permission_online_icon"); @@ -301,6 +305,28 @@ void LLAvatarListItem::setAvatarId(const LLUUID& id, const LLUUID& session_id, b } } +void LLAvatarListItem::showAvatarArrivalTime(bool show) +{ + mAvatarArrivalTime->setVisible(show); + updateChildren(); +} + +void LLAvatarListItem::setAvatarArrivalTime(F32 arrival_time) +{ + mAvatarArrivalTime->setValue(formatSeconds(arrival_time)); +} + +void LLAvatarListItem::showAvatarDistance(bool show) +{ + mAvatarDistance->setVisible(show); + updateChildren(); +} + +void LLAvatarListItem::setAvatarDistance(F32 distance) +{ + mAvatarDistance->setValue(llformat("%.1f m", distance)); +} + void LLAvatarListItem::showLastInteractionTime(bool show) { mLastInteractionTime->setVisible(show); @@ -538,6 +564,12 @@ void LLAvatarListItem::initChildrenWidths(LLAvatarListItem* avatar_item) // last interaction time textbox width + padding S32 last_interaction_time_width = avatar_item->mIconPermissionEditTheirs->getRect().mLeft - avatar_item->mLastInteractionTime->getRect().mLeft; + // avatar distance textbox width + padding + S32 avatar_distance_width = avatar_item->mAvatarDistance->getRect().mLeft - avatar_item->mAvatarArrivalTime->getRect().mLeft; + + // avatar arrival time textbox width + padding + S32 avatar_arrival_time = avatar_item->mAvatarArrivalTime->getRect().mLeft - avatar_item->mAvatarName->getRect().mLeft; + // avatar icon width + padding S32 icon_width = avatar_item->mAvatarName->getRect().mLeft - avatar_item->mAvatarIcon->getRect().mLeft; @@ -546,6 +578,8 @@ void LLAvatarListItem::initChildrenWidths(LLAvatarListItem* avatar_item) S32 index = ALIC_COUNT; sChildrenWidths[--index] = icon_width; sChildrenWidths[--index] = 0; // for avatar name we don't need its width, it will be calculated as "left available space" + sChildrenWidths[--index] = avatar_arrival_time; + sChildrenWidths[--index] = avatar_distance_width; sChildrenWidths[--index] = last_interaction_time_width; sChildrenWidths[--index] = permission_edit_theirs_width; sChildrenWidths[--index] = permission_edit_mine_width; @@ -666,6 +700,12 @@ LLView* LLAvatarListItem::getItemChildView(EAvatarListItemChildIndex child_view_ case ALIC_NAME: child_view = mAvatarName; break; + case ALIC_ARRIVAL_TIME: + child_view = mAvatarArrivalTime; + break; + case ALIC_DISTANCE: + child_view = mAvatarDistance; + break; case ALIC_INTERACTION_TIME: child_view = mLastInteractionTime; break; diff --git a/indra/newview/llavatarlistitem.h b/indra/newview/llavatarlistitem.h index 2e4c597d30..630a7ec751 100644 --- a/indra/newview/llavatarlistitem.h +++ b/indra/newview/llavatarlistitem.h @@ -98,12 +98,16 @@ public: void setHighlight(const std::string& highlight); void setState(EItemState item_style); void setAvatarId(const LLUUID& id, const LLUUID& session_id, bool ignore_status_changes = false, bool is_resident = true); + void setAvatarArrivalTime(F32 arrival_time); + void setAvatarDistance(F32 distance); void setLastInteractionTime(U32 secs_since); //Show/hide profile/info btn, translating speaker indicator and avatar name coordinates accordingly void setShowProfileBtn(bool show); void setShowInfoBtn(bool show); void showSpeakingIndicator(bool show); void setShowPermissions(bool show) { mShowPermissions = show; }; + void showAvatarArrivalTime(bool show); + void showAvatarDistance(bool show); void showLastInteractionTime(bool show); void setAvatarIconVisible(bool visible); void setShowCompleteName(bool show) { mShowCompleteName = show;}; @@ -158,6 +162,8 @@ private: ALIC_PERMISSION_EDIT_MINE, ALIC_PERMISSION_EDIT_THEIRS, ALIC_INTERACTION_TIME, + ALIC_DISTANCE, + ALIC_ARRIVAL_TIME, ALIC_NAME, ALIC_ICON, ALIC_COUNT, @@ -199,6 +205,8 @@ private: LLView* getItemChildView(EAvatarListItemChildIndex child_index); LLTextBox* mAvatarName; + LLTextBox* mAvatarArrivalTime; + LLTextBox* mAvatarDistance; LLTextBox* mLastInteractionTime; LLStyle::Params mAvatarNameStyle; diff --git a/indra/newview/llavatarpropertiesprocessor.cpp b/indra/newview/llavatarpropertiesprocessor.cpp index 6277e65b2d..a2e81ed255 100644 --- a/indra/newview/llavatarpropertiesprocessor.cpp +++ b/indra/newview/llavatarpropertiesprocessor.cpp @@ -473,6 +473,8 @@ void LLAvatarPropertiesProcessor::processClassifiedInfoReply(LLMessageSystem* ms // Request processed, no longer pending self->removePendingRequest(c_info.creator_id, APT_CLASSIFIED_INFO); self->notifyObservers(c_info.creator_id, &c_info, APT_CLASSIFIED_INFO); + self->removePendingRequest(c_info.classified_id, APT_CLASSIFIED_INFO); + self->notifyObservers(c_info.classified_id, &c_info, APT_CLASSIFIED_INFO); } @@ -669,6 +671,7 @@ void LLAvatarPropertiesProcessor::sendClassifiedInfoUpdate(const LLAvatarClassif void LLAvatarPropertiesProcessor::sendPickInfoRequest(const LLUUID& creator_id, const LLUUID& pick_id) { + LL_DEBUGS("PickInfo") << " Requiesting pick info for " << pick_id << LL_ENDL; // Must ask for a pick based on the creator id because // the pick database is distributed to the inventory cluster. JC std::vector<std::string> request_params{ creator_id.asString(), pick_id.asString() }; diff --git a/indra/newview/llavatarpropertiesprocessor.h b/indra/newview/llavatarpropertiesprocessor.h index 1592629fca..a490f3da10 100644 --- a/indra/newview/llavatarpropertiesprocessor.h +++ b/indra/newview/llavatarpropertiesprocessor.h @@ -52,6 +52,9 @@ enum EAvatarProcessorType { APT_PROPERTIES_LEGACY, // APT_PROPERTIES via udp request (Truncates data!!!) APT_PROPERTIES, // APT_PROPERTIES via http request + APT_NOTES, + APT_GROUPS, + APT_PICKS, APT_PICK_INFO, APT_TEXTURES, APT_CLASSIFIEDS, @@ -105,6 +108,24 @@ struct LLAvatarData typedef std::pair<LLUUID, std::string> pick_data_t; typedef std::list< pick_data_t> picks_list_t; picks_list_t picks_list; + BOOL allow_publish; + LLAvatarData() = default; + LLAvatarData(const LLAvatarLegacyData& legacy_data) + { + agent_id = legacy_data.agent_id; + avatar_id = legacy_data.avatar_id; + image_id = legacy_data.image_id; + fl_image_id = legacy_data.fl_image_id; + partner_id = legacy_data.partner_id; + about_text = legacy_data.about_text; + fl_about_text = legacy_data.fl_about_text; + born_on = legacy_data.born_on; + profile_url = legacy_data.profile_url; + caption_index = legacy_data.caption_index; + caption_text = legacy_data.caption_text; + customer_type = legacy_data.customer_type; + flags = legacy_data.flags; + } }; struct LLAvatarData::LLGroupData @@ -140,6 +161,45 @@ struct LLPickData LLUUID session_id; }; +struct LLAvatarPicks +{ + LLUUID agent_id; + LLUUID target_id; //target id + + typedef std::pair<LLUUID,std::string> pick_data_t; + typedef std::list< pick_data_t> picks_list_t; + picks_list_t picks_list; +}; + +struct LLAvatarNotes +{ + LLUUID agent_id; + LLUUID target_id; //target id + std::string notes; +}; + +struct LLAvatarGroups +{ + LLUUID agent_id; + LLUUID avatar_id; //target id + BOOL list_in_profile; + + struct LLGroupData; + typedef std::list<LLGroupData> group_list_t; + + group_list_t group_list; + + struct LLGroupData + { + U64 group_powers; + BOOL accept_notices; + std::string group_title; + LLUUID group_id; + std::string group_name; + LLUUID group_insignia_id; + }; +}; + struct LLAvatarClassifieds { LLUUID agent_id; diff --git a/indra/newview/llcallingcard.cpp b/indra/newview/llcallingcard.cpp index 8e9ab8f87f..76e308a966 100644 --- a/indra/newview/llcallingcard.cpp +++ b/indra/newview/llcallingcard.cpp @@ -42,6 +42,7 @@ #include "llinventorymodel.h" #include "llnotifications.h" #include "llslurl.h" +#include "llstartup.h" #include "llimview.h" #include "lltrans.h" #include "llviewercontrol.h" @@ -271,6 +272,22 @@ S32 LLAvatarTracker::addBuddyList(const LLAvatarTracker::buddy_map_t& buds) << "]" << LL_ENDL; } } + + // It's possible that the buddy list getting propagated from the inventory may have happened after we actually got the buddy list. + // Any buddies that we got prior will reside in a special queue that we must process and update statuses accordingly with. + // Do that here. + // -Geenz 2025-03-12 + while (!mBuddyStatusQueue.empty()) + { + auto buddyStatus = mBuddyStatusQueue.front(); + mBuddyStatusQueue.pop(); + + if (mBuddyInfo.find(buddyStatus.first) != mBuddyInfo.end()) + { + setBuddyOnline(buddyStatus.first, buddyStatus.second); + } + } + // do not notify observers here - list can be large so let it be done on idle. return new_buddy_count; @@ -335,6 +352,8 @@ void LLAvatarTracker::setBuddyOnline(const LLUUID& id, bool is_online) { LL_WARNS() << "!! No buddy info found for " << id << ", setting to " << (is_online ? "Online" : "Offline") << LL_ENDL; + LL_WARNS() << "Did we receive a buddy status update before the buddy info?" << LL_ENDL; + mBuddyStatusQueue.push(std::make_pair(id, is_online)); } } @@ -485,7 +504,7 @@ void LLAvatarTracker::idleNotifyObservers() void LLAvatarTracker::notifyObservers() { - if (mIsNotifyObservers) + if (mIsNotifyObservers || (LLStartUp::getStartupState() <= STATE_INVENTORY_CALLBACKS)) { // Don't allow multiple calls. // new masks and ids will be processed later from idle. @@ -706,6 +725,8 @@ void LLAvatarTracker::processNotify(LLMessageSystem* msg, bool online) { LL_WARNS() << "Received online notification for unknown buddy: " << agent_id << " is " << (online ? "ONLINE" : "OFFLINE") << LL_ENDL; + LL_WARNS() << "Adding buddy to buddy queue." << LL_ENDL; + mBuddyStatusQueue.push(std::make_pair(agent_id, true)); } if(tracking_id == agent_id) @@ -723,7 +744,11 @@ void LLAvatarTracker::processNotify(LLMessageSystem* msg, bool online) mModifyMask |= LLFriendObserver::ONLINE; instance().notifyObservers(); - gInventory.notifyObservers(); + // Skip if we had received the friends list before the inventory callbacks were properly initialized + if (LLStartUp::getStartupState() > STATE_INVENTORY_CALLBACKS) + { + gInventory.notifyObservers(); + } } } diff --git a/indra/newview/llcallingcard.h b/indra/newview/llcallingcard.h index 48b93fdf9d..156ea90e0a 100644 --- a/indra/newview/llcallingcard.h +++ b/indra/newview/llcallingcard.h @@ -30,6 +30,7 @@ #include <map> #include <set> #include <string> +#include <queue> #include <vector> #include "lluserrelations.h" #include "lluuid.h" @@ -109,6 +110,7 @@ public: // add or remove agents from buddy list. Each method takes a set // of buddies and returns how many were actually added or removed. typedef std::map<LLUUID, LLRelationship*> buddy_map_t; + typedef std::queue<std::pair<LLUUID, bool>> buddy_status_queue_t; S32 addBuddyList(const buddy_map_t& buddies); //S32 removeBuddyList(const buddy_list_t& exes); @@ -194,6 +196,7 @@ protected: //LLInventoryObserver* mInventoryObserver; buddy_map_t mBuddyInfo; + buddy_status_queue_t mBuddyStatusQueue; typedef std::set<LLUUID> changed_buddy_t; changed_buddy_t mChangedBuddyIDs; diff --git a/indra/newview/llchathistory.cpp b/indra/newview/llchathistory.cpp index a48e22bc73..305b5be194 100644 --- a/indra/newview/llchathistory.cpp +++ b/indra/newview/llchathistory.cpp @@ -1250,7 +1250,10 @@ void LLChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LL LLStyle::Params body_message_params; body_message_params.color(txt_color); - body_message_params.readonly_color(txt_color); + if (args["COLOR"]) + body_message_params.readonly_color(LLUIColorTable::instance().getColor(args["COLOR"].asString())); + else + body_message_params.readonly_color(txt_color); body_message_params.alpha(alpha); body_message_params.font.name(font_name); body_message_params.font.size(font_size); diff --git a/indra/newview/llchiclet.cpp b/indra/newview/llchiclet.cpp index e8a069dfdb..0cad51137c 100644 --- a/indra/newview/llchiclet.cpp +++ b/indra/newview/llchiclet.cpp @@ -240,10 +240,11 @@ void LLNotificationChiclet::setCounter(S32 counter) bool LLNotificationChiclet::ChicletNotificationChannel::filterNotification( LLNotificationPtr notification ) { bool displayNotification; + LLFloaterNotificationsTabbed* floater = LLFloaterNotificationsTabbed::getInstance(); if ( (notification->getName() == "ScriptDialog") // special case for scripts // if there is no toast window for the notification, filter it //|| (!LLNotificationWellWindow::getInstance()->findItemByID(notification->getID())) - || (!LLFloaterNotificationsTabbed::getInstance()->findItemByID(notification->getID(), notification->getName())) + || (floater && !floater->findItemByID(notification->getID(), notification->getName())) ) { displayNotification = false; diff --git a/indra/newview/llconversationmodel.cpp b/indra/newview/llconversationmodel.cpp index 4cd85ac756..af5a46742c 100644 --- a/indra/newview/llconversationmodel.cpp +++ b/indra/newview/llconversationmodel.cpp @@ -357,8 +357,9 @@ void LLConversationItemSession::clearParticipants() void LLConversationItemSession::clearAndDeparentModels() { - for (LLFolderViewModelItem* child : mChildren) + for (child_list_t::iterator it = mChildren.begin(); it != mChildren.end();) { + LLFolderViewModelItem* child = *it; if (child->getNumRefs() == 0) { // LLConversationItemParticipant can be created but not assigned to any view, @@ -370,8 +371,8 @@ void LLConversationItemSession::clearAndDeparentModels() // Model is still assigned to some view/widget child->setParent(NULL); } + it = mChildren.erase(it); } - mChildren.clear(); } LLConversationItemParticipant* LLConversationItemSession::findParticipant(const LLUUID& participant_id) @@ -726,8 +727,11 @@ bool LLConversationSort::operator()(const LLConversationItem* const& a, const LL { if ((type_a == LLConversationItem::CONV_SESSION_NEARBY) || (type_b == LLConversationItem::CONV_SESSION_NEARBY)) { + if (gSavedSettings.getBOOL("IMNearbySessionFirst")) + return (type_b != LLConversationItem::CONV_SESSION_NEARBY); + else // If one is the nearby session, put nearby session *always* last - return (type_b == LLConversationItem::CONV_SESSION_NEARBY); + return (type_b == LLConversationItem::CONV_SESSION_NEARBY); } else if (sort_order == LLConversationFilter::SO_SESSION_TYPE) { diff --git a/indra/newview/lldirpicker.cpp b/indra/newview/lldirpicker.cpp index e967ff3df2..1425aab947 100644 --- a/indra/newview/lldirpicker.cpp +++ b/indra/newview/lldirpicker.cpp @@ -37,10 +37,15 @@ #include "llviewercontrol.h" #include "llwin32headers.h" -#if LL_LINUX || LL_DARWIN +#if LL_LINUX || LL_DARWIN || __FreeBSD__ # include "llfilepicker.h" #endif +#ifdef LL_FLTK + #include "FL/Fl.H" + #include "FL/Fl_Native_File_Chooser.H" +#endif + #if LL_WINDOWS #include <shlobj.h> #endif @@ -208,26 +213,34 @@ std::string LLDirPicker::getDirName() return mFilePicker->getFirstFile(); } -#elif LL_LINUX +#elif LL_LINUX || __FreeBSD__ LLDirPicker::LLDirPicker() : mFileName(NULL), mLocked(false) { +#ifndef LL_FLTK mFilePicker = new LLFilePicker(); +#endif reset(); } LLDirPicker::~LLDirPicker() { +#ifndef LL_FLTK delete mFilePicker; +#endif } void LLDirPicker::reset() { +#ifndef LL_FLTK if (mFilePicker) mFilePicker->reset(); +#else + mDir = ""; +#endif } bool LLDirPicker::getDir(std::string* filename, bool blocking) @@ -240,33 +253,38 @@ bool LLDirPicker::getDir(std::string* filename, bool blocking) return false; } -#if !LL_MESA_HEADLESS - - if (mFilePicker) +#ifdef LL_FLTK + gViewerWindow->getWindow()->beforeDialog(); + Fl_Native_File_Chooser flDlg; + flDlg.title(LLTrans::getString("choose_the_directory").c_str()); + flDlg.type(Fl_Native_File_Chooser::BROWSE_DIRECTORY ); + int res = flDlg.show(); + gViewerWindow->getWindow()->afterDialog(); + if( res == 0 ) { - GtkWindow* picker = mFilePicker->buildFilePicker(false, true, - "dirpicker"); - - if (picker) - { - gtk_window_set_title(GTK_WINDOW(picker), LLTrans::getString("choose_the_directory").c_str()); - gtk_widget_show_all(GTK_WIDGET(picker)); - gtk_main(); - return (!mFilePicker->getFirstFile().empty()); - } + char const *pDir = flDlg.filename(0); + if( pDir ) + mDir = pDir; } -#endif // !LL_MESA_HEADLESS - - return false; + else if( res == -1 ) + { + LL_WARNS() << "FLTK failed: " << flDlg.errmsg() << LL_ENDL; + } + return !mDir.empty(); +#endif } std::string LLDirPicker::getDirName() { +#ifndef LL_FLTK if (mFilePicker) { return mFilePicker->getFirstFile(); } return ""; +#else + return mDir; +#endif } #else // not implemented diff --git a/indra/newview/lldirpicker.h b/indra/newview/lldirpicker.h index dc740caab2..4bbe7db144 100644 --- a/indra/newview/lldirpicker.h +++ b/indra/newview/lldirpicker.h @@ -75,10 +75,12 @@ private: void buildDirname( void ); bool check_local_file_access_enabled(); -#if LL_LINUX || LL_DARWIN +#if LL_LINUX || LL_DARWIN || __FreeBSD__ // On Linux we just implement LLDirPicker on top of LLFilePicker +#ifndef LL_FLTK LLFilePicker *mFilePicker; #endif +#endif std::string* mFileName; diff --git a/indra/newview/lldrawable.cpp b/indra/newview/lldrawable.cpp index 70ae4ee13f..9d212cfe8b 100644 --- a/indra/newview/lldrawable.cpp +++ b/indra/newview/lldrawable.cpp @@ -33,6 +33,7 @@ // viewer includes #include "llagent.h" +#include "llagentcamera.h" #include "llcriticaldamp.h" #include "llface.h" #include "lllightconstants.h" @@ -252,7 +253,15 @@ void LLDrawable::cleanupReferences() std::for_each(mFaces.begin(), mFaces.end(), DeletePointer()); mFaces.clear(); - gPipeline.unlinkDrawable(this); + if (gPipeline.mInitialized) + { + gPipeline.unlinkDrawable(this); + } + else if (getSpatialGroup()) + { + // Not supposed to happen? + getSpatialGroup()->getSpatialPartition()->remove(this, getSpatialGroup()); + } removeFromOctree(); @@ -778,6 +787,14 @@ bool LLDrawable::updateMove() makeActive(); + // #3256 force undampened movement for attached objects in mouselook + // to prevent animation bork for linkset with animated parts + if (!isRoot() && gAgentCamera.cameraMouselook() && + !mVObjp->isRiggedMesh() && mVObjp->getAvatar() && mVObjp->getAvatar()->isSelf()) + { + return updateMoveUndamped(); + } + return isState(MOVE_UNDAMPED) ? updateMoveUndamped() : updateMoveDamped(); } diff --git a/indra/newview/lldrawpool.cpp b/indra/newview/lldrawpool.cpp index 7bd5206453..325c3f9b94 100644 --- a/indra/newview/lldrawpool.cpp +++ b/indra/newview/lldrawpool.cpp @@ -42,6 +42,7 @@ #include "lldrawpooltree.h" #include "lldrawpoolterrain.h" #include "lldrawpoolwater.h" +#include "lldrawpoolwaterexclusion.h" #include "llface.h" #include "llviewerobjectlist.h" // For debug listing. #include "pipeline.h" @@ -119,6 +120,9 @@ LLDrawPool *LLDrawPool::createPool(const U32 type, LLViewerTexture *tex0) case POOL_GLTF_PBR_ALPHA_MASK: poolp = new LLDrawPoolGLTFPBR(LLDrawPool::POOL_GLTF_PBR_ALPHA_MASK); break; + case POOL_WATEREXCLUSION: + poolp = new LLDrawPoolWaterExclusion(); + break; default: LL_ERRS() << "Unknown draw pool type!" << LL_ENDL; return NULL; @@ -365,7 +369,9 @@ void LLFacePool::LLOverrideFaceColor::setColor(const LLColor4& color) void LLFacePool::LLOverrideFaceColor::setColor(const LLColor4U& color) { +#if GL_VERSION_1_1 glColor4ubv(color.mV); +#endif } void LLFacePool::LLOverrideFaceColor::setColor(F32 r, F32 g, F32 b, F32 a) diff --git a/indra/newview/lldrawpool.h b/indra/newview/lldrawpool.h index bc412214c7..1c8864a9df 100644 --- a/indra/newview/lldrawpool.h +++ b/indra/newview/lldrawpool.h @@ -55,6 +55,7 @@ public: // based on fill rate and likelihood to occlude future passes (faster, large occluders first). // POOL_SKY = 1, + POOL_WATEREXCLUSION, POOL_WL_SKY, POOL_SIMPLE, POOL_FULLBRIGHT, @@ -140,7 +141,7 @@ public: PASS_GRASS, PASS_FULLBRIGHT, PASS_FULLBRIGHT_RIGGED, - PASS_INVISIBLE, + PASS_INVISIBLE, // Formerly, invisiprims. Now, water exclusion surfaces. PASS_INVISIBLE_RIGGED, PASS_INVISI_SHINY, PASS_INVISI_SHINY_RIGGED, diff --git a/indra/newview/lldrawpoolterrain.cpp b/indra/newview/lldrawpoolterrain.cpp index 5e676bc5b3..2f4f47df6f 100644 --- a/indra/newview/lldrawpoolterrain.cpp +++ b/indra/newview/lldrawpoolterrain.cpp @@ -666,6 +666,7 @@ void LLDrawPoolTerrain::renderFull4TU() gGL.getTexUnit(0)->activate(); gGL.getTexUnit(0)->bind(detail_texture0p); +#if GL_VERSION_1_1 glEnable(GL_TEXTURE_GEN_S); glEnable(GL_TEXTURE_GEN_T); glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); @@ -673,6 +674,7 @@ void LLDrawPoolTerrain::renderFull4TU() glTexGenfv(GL_S, GL_OBJECT_PLANE, tp0.mV); glTexGenfv(GL_T, GL_OBJECT_PLANE, tp1.mV); +#endif // // Stage 1: Generate alpha ramp for detail0/detail1 transition @@ -689,12 +691,14 @@ void LLDrawPoolTerrain::renderFull4TU() gGL.getTexUnit(2)->enable(LLTexUnit::TT_TEXTURE); gGL.getTexUnit(2)->activate(); +#if GL_VERSION_1_1 glEnable(GL_TEXTURE_GEN_S); glEnable(GL_TEXTURE_GEN_T); glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); glTexGenfv(GL_S, GL_OBJECT_PLANE, tp0.mV); glTexGenfv(GL_T, GL_OBJECT_PLANE, tp1.mV); +#endif // // Stage 3: Modulate with primary (vertex) color for lighting @@ -716,12 +720,14 @@ void LLDrawPoolTerrain::renderFull4TU() gGL.getTexUnit(0)->activate(); gGL.getTexUnit(0)->bind(detail_texture3p); +#if GL_VERSION_1_1 glEnable(GL_TEXTURE_GEN_S); glEnable(GL_TEXTURE_GEN_T); glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); glTexGenfv(GL_S, GL_OBJECT_PLANE, tp0.mV); glTexGenfv(GL_T, GL_OBJECT_PLANE, tp1.mV); +#endif // // Stage 1: Generate alpha ramp for detail2/detail3 transition @@ -742,12 +748,14 @@ void LLDrawPoolTerrain::renderFull4TU() gGL.getTexUnit(2)->enable(LLTexUnit::TT_TEXTURE); gGL.getTexUnit(2)->activate(); +#if GL_VERSION_1_1 glEnable(GL_TEXTURE_GEN_S); glEnable(GL_TEXTURE_GEN_T); glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); glTexGenfv(GL_S, GL_OBJECT_PLANE, tp0.mV); glTexGenfv(GL_T, GL_OBJECT_PLANE, tp1.mV); +#endif // // Stage 3: Generate alpha ramp for detail1/detail2 transition @@ -782,8 +790,10 @@ void LLDrawPoolTerrain::renderFull4TU() gGL.getTexUnit(2)->disable(); gGL.getTexUnit(2)->activate(); +#if GL_VERSION_1_1 glDisable(GL_TEXTURE_GEN_S); glDisable(GL_TEXTURE_GEN_T); +#endif gGL.matrixMode(LLRender::MM_TEXTURE); gGL.loadIdentity(); gGL.matrixMode(LLRender::MM_MODELVIEW); @@ -806,8 +816,10 @@ void LLDrawPoolTerrain::renderFull4TU() gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); +#if GL_VERSION_1_1 glDisable(GL_TEXTURE_GEN_S); glDisable(GL_TEXTURE_GEN_T); +#endif gGL.matrixMode(LLRender::MM_TEXTURE); gGL.loadIdentity(); gGL.matrixMode(LLRender::MM_MODELVIEW); @@ -841,6 +853,7 @@ void LLDrawPoolTerrain::renderFull2TU() // Stage 0: Render detail 0 into base // gGL.getTexUnit(0)->bind(detail_texture0p); +#if GL_VERSION_1_1 glEnable(GL_TEXTURE_GEN_S); glEnable(GL_TEXTURE_GEN_T); glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); @@ -848,6 +861,7 @@ void LLDrawPoolTerrain::renderFull2TU() glTexGenfv(GL_S, GL_OBJECT_PLANE, tp0.mV); glTexGenfv(GL_T, GL_OBJECT_PLANE, tp1.mV); +#endif drawLoop(); @@ -859,8 +873,10 @@ void LLDrawPoolTerrain::renderFull2TU() // gGL.getTexUnit(0)->bind(m2DAlphaRampImagep); +#if GL_VERSION_1_1 glDisable(GL_TEXTURE_GEN_S); glDisable(GL_TEXTURE_GEN_T); +#endif // // Stage 1: Write detail1 @@ -869,12 +885,14 @@ void LLDrawPoolTerrain::renderFull2TU() gGL.getTexUnit(1)->enable(LLTexUnit::TT_TEXTURE); gGL.getTexUnit(1)->activate(); +#if GL_VERSION_1_1 glEnable(GL_TEXTURE_GEN_S); glEnable(GL_TEXTURE_GEN_T); glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); glTexGenfv(GL_S, GL_OBJECT_PLANE, tp0.mV); glTexGenfv(GL_T, GL_OBJECT_PLANE, tp1.mV); +#endif gGL.getTexUnit(0)->activate(); { @@ -902,12 +920,14 @@ void LLDrawPoolTerrain::renderFull2TU() gGL.getTexUnit(1)->enable(LLTexUnit::TT_TEXTURE); gGL.getTexUnit(1)->activate(); +#if GL_VERSION_1_1 glEnable(GL_TEXTURE_GEN_S); glEnable(GL_TEXTURE_GEN_T); glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); glTexGenfv(GL_S, GL_OBJECT_PLANE, tp0.mV); glTexGenfv(GL_T, GL_OBJECT_PLANE, tp1.mV); +#endif { LLGLEnable blend(GL_BLEND); @@ -933,12 +953,14 @@ void LLDrawPoolTerrain::renderFull2TU() gGL.getTexUnit(1)->enable(LLTexUnit::TT_TEXTURE); gGL.getTexUnit(1)->activate(); +#if GL_VERSION_1_1 glEnable(GL_TEXTURE_GEN_S); glEnable(GL_TEXTURE_GEN_T); glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); glTexGenfv(GL_S, GL_OBJECT_PLANE, tp0.mV); glTexGenfv(GL_T, GL_OBJECT_PLANE, tp1.mV); +#endif gGL.getTexUnit(0)->activate(); { @@ -955,8 +977,10 @@ void LLDrawPoolTerrain::renderFull2TU() gGL.getTexUnit(1)->disable(); gGL.getTexUnit(1)->activate(); +#if GL_VERSION_1_1 glDisable(GL_TEXTURE_GEN_S); glDisable(GL_TEXTURE_GEN_T); +#endif gGL.matrixMode(LLRender::MM_TEXTURE); gGL.loadIdentity(); gGL.matrixMode(LLRender::MM_MODELVIEW); @@ -967,8 +991,10 @@ void LLDrawPoolTerrain::renderFull2TU() gGL.getTexUnit(0)->activate(); gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); +#if GL_VERSION_1_1 glDisable(GL_TEXTURE_GEN_S); glDisable(GL_TEXTURE_GEN_T); +#endif gGL.matrixMode(LLRender::MM_TEXTURE); gGL.loadIdentity(); gGL.matrixMode(LLRender::MM_MODELVIEW); diff --git a/indra/newview/lldrawpooltree.cpp b/indra/newview/lldrawpooltree.cpp index 6efd503574..26ef190fbb 100644 --- a/indra/newview/lldrawpooltree.cpp +++ b/indra/newview/lldrawpooltree.cpp @@ -108,8 +108,9 @@ void LLDrawPoolTree::beginShadowPass(S32 pass) { LL_PROFILE_ZONE_SCOPED; - glPolygonOffset(gSavedSettings.getF32("RenderDeferredTreeShadowOffset"), - gSavedSettings.getF32("RenderDeferredTreeShadowBias")); + static LLCachedControl<F32> shadow_offset(gSavedSettings, "RenderDeferredTreeShadowOffset"); + static LLCachedControl<F32> shadow_bias(gSavedSettings, "RenderDeferredTreeShadowBias"); + glPolygonOffset(shadow_offset(), shadow_bias()); LLEnvironment& environment = LLEnvironment::instance(); diff --git a/indra/newview/lldrawpoolwater.cpp b/indra/newview/lldrawpoolwater.cpp index 53d6e528b6..7d58511d41 100644 --- a/indra/newview/lldrawpoolwater.cpp +++ b/indra/newview/lldrawpoolwater.cpp @@ -176,173 +176,156 @@ void LLDrawPoolWater::renderPostDeferred(S32 pass) light_diffuse *= (1.5f + (6.f * ground_proj_sq)); } - // set up normal maps filtering - for (auto norm_map : mWaterNormp) - { - if (norm_map) norm_map->setFilteringOption(has_normal_mips ? LLTexUnit::TFO_ANISOTROPIC : LLTexUnit::TFO_POINT); - } + LLTexUnit::eTextureFilterOptions filter_mode = has_normal_mips ? LLTexUnit::TFO_ANISOTROPIC : LLTexUnit::TFO_POINT; LLColor4 specular(sun_up ? psky->getSunlightColor() : psky->getMoonlightColor()); F32 phase_time = (F32) LLFrameTimer::getElapsedSeconds() * 0.5f; LLGLSLShader *shader = nullptr; - // two passes, first with standard water shader bound, second with edge water shader bound - for (int edge = 0; edge < 2; edge++) + // One pass, one of two shaders. Void water and region water share state. + // There isn't a good reason anymore to really have void water run in a separate pass. + // It also just introduced a bunch of weird state consistency stuff that we really don't need. + // Not to mention, re-binding the the same shader and state for that shader is kind of wasteful. + // - Geenz 2025-02-11 + // select shader + if (underwater) { - // select shader - if (underwater) - { - shader = &gUnderWaterProgram; - } - else - { - if (edge) - { - shader = &gWaterEdgeProgram; - } - else - { - shader = &gWaterProgram; - } - } + shader = &gUnderWaterProgram; + } + else + { + shader = &gWaterProgram; + } - gPipeline.bindDeferredShader(*shader, nullptr, &gPipeline.mWaterDis); + gPipeline.bindDeferredShader(*shader, nullptr, &gPipeline.mWaterDis); - //bind normal map - S32 bumpTex = shader->enableTexture(LLViewerShaderMgr::BUMP_MAP); - S32 bumpTex2 = shader->enableTexture(LLViewerShaderMgr::BUMP_MAP2); + LLViewerTexture* tex_a = mWaterNormp[0]; + LLViewerTexture* tex_b = mWaterNormp[1]; - LLViewerTexture* tex_a = mWaterNormp[0]; - LLViewerTexture* tex_b = mWaterNormp[1]; + F32 blend_factor = (F32)pwater->getBlendFactor(); - F32 blend_factor = (F32)pwater->getBlendFactor(); + if (tex_a && (!tex_b || (tex_a == tex_b))) + { + shader->bindTexture(LLViewerShaderMgr::BUMP_MAP, tex_a); + tex_a->setFilteringOption(filter_mode); + blend_factor = 0; // only one tex provided, no blending + } + else if (tex_b && !tex_a) + { + shader->bindTexture(LLViewerShaderMgr::BUMP_MAP, tex_b); + tex_b->setFilteringOption(filter_mode); + blend_factor = 0; // only one tex provided, no blending + } + else if (tex_b != tex_a) + { + shader->bindTexture(LLViewerShaderMgr::BUMP_MAP, tex_a); + tex_a->setFilteringOption(filter_mode); + shader->bindTexture(LLViewerShaderMgr::BUMP_MAP2, tex_b); + tex_b->setFilteringOption(filter_mode); + } - gGL.getTexUnit(bumpTex)->unbind(LLTexUnit::TT_TEXTURE); - gGL.getTexUnit(bumpTex2)->unbind(LLTexUnit::TT_TEXTURE); + shader->bindTexture(LLShaderMgr::WATER_EXCLUSIONTEX, &gPipeline.mWaterExclusionMask); - if (tex_a && (!tex_b || (tex_a == tex_b))) - { - gGL.getTexUnit(bumpTex)->bind(tex_a); - blend_factor = 0; // only one tex provided, no blending - } - else if (tex_b && !tex_a) - { - gGL.getTexUnit(bumpTex)->bind(tex_b); - blend_factor = 0; // only one tex provided, no blending - } - else if (tex_b != tex_a) - { - gGL.getTexUnit(bumpTex)->bind(tex_a); - gGL.getTexUnit(bumpTex2)->bind(tex_b); - } + shader->uniform1f(LLShaderMgr::BLEND_FACTOR, blend_factor); - // bind reflection texture from RenderTarget - S32 screentex = shader->enableTexture(LLShaderMgr::WATER_SCREENTEX); + F32 fog_density = pwater->getModifiedWaterFogDensity(underwater); - F32 screenRes[] = { 1.f / gGLViewport[2], 1.f / gGLViewport[3] }; + shader->bindTexture(LLShaderMgr::WATER_SCREENTEX, &gPipeline.mWaterDis); - shader->uniform2fv(LLShaderMgr::DEFERRED_SCREEN_RES, 1, screenRes); - shader->uniform1f(LLShaderMgr::BLEND_FACTOR, blend_factor); + if (mShaderLevel == 1) + { + fog_color.mV[VALPHA] = (F32)(log(fog_density) / log(2)); + } - F32 fog_density = pwater->getModifiedWaterFogDensity(underwater); + F32 water_height = environment.getWaterHeight(); + F32 camera_height = LLViewerCamera::getInstance()->getOrigin().mV[2]; + shader->uniform1f(LLShaderMgr::WATER_WATERHEIGHT, camera_height - water_height); + shader->uniform1f(LLShaderMgr::WATER_TIME, phase_time); + shader->uniform3fv(LLShaderMgr::WATER_EYEVEC, 1, LLViewerCamera::getInstance()->getOrigin().mV); - if (screentex > -1) - { - shader->uniform1f(LLShaderMgr::WATER_FOGDENSITY, fog_density); - gGL.getTexUnit(screentex)->bind(&gPipeline.mWaterDis); - } + shader->uniform3fv(LLShaderMgr::WATER_SPECULAR, 1, light_diffuse.mV); - if (mShaderLevel == 1) - { - fog_color.mV[VALPHA] = (F32)(log(fog_density) / log(2)); - } + shader->uniform2fv(LLShaderMgr::WATER_WAVE_DIR1, 1, pwater->getWave1Dir().mV); + shader->uniform2fv(LLShaderMgr::WATER_WAVE_DIR2, 1, pwater->getWave2Dir().mV); - F32 water_height = environment.getWaterHeight(); - F32 camera_height = LLViewerCamera::getInstance()->getOrigin().mV[2]; - shader->uniform1f(LLShaderMgr::WATER_WATERHEIGHT, camera_height - water_height); - shader->uniform1f(LLShaderMgr::WATER_TIME, phase_time); - shader->uniform3fv(LLShaderMgr::WATER_EYEVEC, 1, LLViewerCamera::getInstance()->getOrigin().mV); + shader->uniform3fv(LLShaderMgr::WATER_LIGHT_DIR, 1, light_dir.mV); - shader->uniform4fv(LLShaderMgr::SPECULAR_COLOR, 1, specular.mV); - shader->uniform4fv(LLShaderMgr::WATER_FOGCOLOR, 1, fog_color.mV); - shader->uniform3fv(LLShaderMgr::WATER_FOGCOLOR_LINEAR, 1, fog_color_linear.mV); + shader->uniform3fv(LLShaderMgr::WATER_NORM_SCALE, 1, pwater->getNormalScale().mV); + shader->uniform1f(LLShaderMgr::WATER_FRESNEL_SCALE, pwater->getFresnelScale()); + shader->uniform1f(LLShaderMgr::WATER_FRESNEL_OFFSET, pwater->getFresnelOffset()); + shader->uniform1f(LLShaderMgr::WATER_BLUR_MULTIPLIER, fmaxf(0, pwater->getBlurMultiplier()) * 2); - shader->uniform3fv(LLShaderMgr::WATER_SPECULAR, 1, light_diffuse.mV); - shader->uniform1f(LLShaderMgr::WATER_SPECULAR_EXP, light_exp); + static LLStaticHashedString s_exposure("exposure"); + static LLStaticHashedString tonemap_mix("tonemap_mix"); + static LLStaticHashedString tonemap_type("tonemap_type"); - shader->uniform2fv(LLShaderMgr::WATER_WAVE_DIR1, 1, pwater->getWave1Dir().mV); - shader->uniform2fv(LLShaderMgr::WATER_WAVE_DIR2, 1, pwater->getWave2Dir().mV); + static LLCachedControl<F32> exposure(gSavedSettings, "RenderExposure", 1.f); - shader->uniform3fv(LLShaderMgr::WATER_LIGHT_DIR, 1, light_dir.mV); + F32 e = llclamp(exposure(), 0.5f, 4.f); - shader->uniform3fv(LLShaderMgr::WATER_NORM_SCALE, 1, pwater->getNormalScale().mV); - shader->uniform1f(LLShaderMgr::WATER_FRESNEL_SCALE, pwater->getFresnelScale()); - shader->uniform1f(LLShaderMgr::WATER_FRESNEL_OFFSET, pwater->getFresnelOffset()); - shader->uniform1f(LLShaderMgr::WATER_BLUR_MULTIPLIER, pwater->getBlurMultiplier()); + static LLCachedControl<bool> should_auto_adjust(gSavedSettings, "RenderSkyAutoAdjustLegacy", false); - F32 sunAngle = llmax(0.f, light_dir.mV[1]); - F32 scaledAngle = 1.f - sunAngle; + shader->uniform1f(s_exposure, e); + static LLCachedControl<U32> tonemap_type_setting(gSavedSettings, "RenderTonemapType", 0U); + shader->uniform1i(tonemap_type, tonemap_type_setting); + shader->uniform1f(tonemap_mix, psky->getTonemapMix(should_auto_adjust())); - shader->uniform1i(LLShaderMgr::SUN_UP_FACTOR, sun_up ? 1 : 0); - shader->uniform1f(LLShaderMgr::WATER_SUN_ANGLE, sunAngle); - shader->uniform1f(LLShaderMgr::WATER_SCALED_ANGLE, scaledAngle); - shader->uniform1f(LLShaderMgr::WATER_SUN_ANGLE2, 0.1f + 0.2f * sunAngle); - shader->uniform1i(LLShaderMgr::WATER_EDGE_FACTOR, edge ? 1 : 0); + F32 sunAngle = llmax(0.f, light_dir.mV[1]); + F32 scaledAngle = 1.f - sunAngle; - // SL-15861 This was changed from getRotatedLightNorm() as it was causing - // lightnorm in shaders\class1\windlight\atmosphericsFuncs.glsl in have inconsistent additive lighting for 180 degrees of the FOV. - LLVector4 rotated_light_direction = LLEnvironment::instance().getClampedLightNorm(); - shader->uniform3fv(LLViewerShaderMgr::LIGHTNORM, 1, rotated_light_direction.mV); + shader->uniform1i(LLShaderMgr::SUN_UP_FACTOR, sun_up ? 1 : 0); - shader->uniform3fv(LLShaderMgr::WL_CAMPOSLOCAL, 1, LLViewerCamera::getInstance()->getOrigin().mV); + // SL-15861 This was changed from getRotatedLightNorm() as it was causing + // lightnorm in shaders\class1\windlight\atmosphericsFuncs.glsl in have inconsistent additive lighting for 180 degrees of the FOV. + LLVector4 rotated_light_direction = LLEnvironment::instance().getClampedLightNorm(); + shader->uniform3fv(LLViewerShaderMgr::LIGHTNORM, 1, rotated_light_direction.mV); - if (LLViewerCamera::getInstance()->cameraUnderWater()) - { - shader->uniform1f(LLShaderMgr::WATER_REFSCALE, pwater->getScaleBelow()); - } - else - { - shader->uniform1f(LLShaderMgr::WATER_REFSCALE, pwater->getScaleAbove()); - } + shader->uniform3fv(LLShaderMgr::WL_CAMPOSLOCAL, 1, LLViewerCamera::getInstance()->getOrigin().mV); - LLGLDisable cullface(GL_CULL_FACE); + if (LLViewerCamera::getInstance()->cameraUnderWater()) + { + shader->uniform1f(LLShaderMgr::WATER_REFSCALE, pwater->getScaleBelow()); + } + else + { + shader->uniform1f(LLShaderMgr::WATER_REFSCALE, pwater->getScaleAbove()); + } - LLVOWater* water = nullptr; - for (LLFace* const& face : mDrawFace) - { - if (!face) continue; - water = static_cast<LLVOWater*>(face->getViewerObject()); - if (!water) continue; - - if ((bool)edge == (bool)water->getIsEdgePatch()) - { - face->renderIndexed(); - - // Note non-void water being drawn, updates required - if (!edge) // SL-16461 remove !LLPipeline::sUseOcclusion check - { - sNeedsReflectionUpdate = true; - sNeedsDistortionUpdate = true; - } - } - } + LLGLDisable cullface(GL_CULL_FACE); - shader->disableTexture(LLShaderMgr::ENVIRONMENT_MAP, LLTexUnit::TT_CUBE_MAP); - shader->disableTexture(LLShaderMgr::WATER_SCREENTEX); - shader->disableTexture(LLShaderMgr::BUMP_MAP); - shader->disableTexture(LLShaderMgr::WATER_REFTEX); + // Only push the water planes once. + // Previously we did this twice: once for void water and one for region water. + // However, the void water and region water shaders are the same exact shader. + // They also had the same exact state with the sole exception setting an edge water flag. + // That flag was not actually used anywhere in the shaders. + // - Geenz 2025-02-11 + pushWaterPlanes(0); - // clean up - gPipeline.unbindDeferredShader(*shader); + // clean up + gPipeline.unbindDeferredShader(*shader); - gGL.getTexUnit(bumpTex)->unbind(LLTexUnit::TT_TEXTURE); - gGL.getTexUnit(bumpTex2)->unbind(LLTexUnit::TT_TEXTURE); - } + gGL.setColorMask(true, false); +} - gGL.getTexUnit(0)->activate(); - gGL.getTexUnit(0)->enable(LLTexUnit::TT_TEXTURE); +void LLDrawPoolWater::pushWaterPlanes(int pass) +{ + LLVOWater* water = nullptr; + for (LLFace* const& face : mDrawFace) + { + water = static_cast<LLVOWater*>(face->getViewerObject()); - gGL.setColorMask(true, false); + face->renderIndexed(); + + // Note non-void water being drawn, updates required + // Previously we had some logic to determine if this pass was also our water edge pass. + // Now we only have one pass. Check if we're doing a region water plane or void water plane. + // - Geenz 2025-02-11 + if (!water->getIsEdgePatch()) + { + sNeedsReflectionUpdate = true; + sNeedsDistortionUpdate = true; + } + } } LLViewerTexture *LLDrawPoolWater::getDebugTexture() diff --git a/indra/newview/lldrawpoolwater.h b/indra/newview/lldrawpoolwater.h index f64477a059..7fc9b68bcf 100644 --- a/indra/newview/lldrawpoolwater.h +++ b/indra/newview/lldrawpoolwater.h @@ -74,6 +74,8 @@ public: void setOpaqueTexture(const LLUUID& opaqueTextureId); void setNormalMaps(const LLUUID& normalMapId, const LLUUID& nextNormalMapId); + void pushWaterPlanes(int pass); + protected: void renderOpaqueLegacyWater(); }; diff --git a/indra/newview/lldrawpoolwaterexclusion.cpp b/indra/newview/lldrawpoolwaterexclusion.cpp new file mode 100644 index 0000000000..5d8fa9b7a1 --- /dev/null +++ b/indra/newview/lldrawpoolwaterexclusion.cpp @@ -0,0 +1,79 @@ +/** + * @file lldrawpool.cpp + * @brief LLDrawPoolMaterials class implementation + * @author Jonathan "Geenz" Goodman + * + * $LicenseInfo:firstyear=2002&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2013, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" + +#include "lldrawpoolwaterexclusion.h" +#include "llviewershadermgr.h" +#include "pipeline.h" +#include "llglcommonfunc.h" +#include "llvoavatar.h" +#include "lldrawpoolwater.h" + +LLDrawPoolWaterExclusion::LLDrawPoolWaterExclusion() : LLRenderPass(LLDrawPool::POOL_WATEREXCLUSION) +{ + LL_INFOS("DPInvisible") << "Creating water exclusion draw pool" << LL_ENDL; +} + + +void LLDrawPoolWaterExclusion::render(S32 pass) +{ // render invisiprims + LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; // LL_RECORD_BLOCK_TIME(FTM_RENDER_INVISIBLE); + + if (gPipeline.shadersLoaded()) + { + gDrawColorProgram.bind(); + } + + + LLGLDepthTest depth(GL_TRUE); + gDrawColorProgram.uniform4f(LLShaderMgr::DIFFUSE_COLOR, 1, 1, 1, 1); + + LLDrawPoolWater* pwaterpool = (LLDrawPoolWater*)gPipeline.getPool(LLDrawPool::POOL_WATER); + if (pwaterpool) + { + // Just treat our water planes as double sided for the purposes of generating the exclusion mask. + LLGLDisable cullface(GL_CULL_FACE); + pwaterpool->pushWaterPlanes(0); + + // Take care of the edge water tiles. + //pwaterpool->pushWaterPlanes(1); + } + + gDrawColorProgram.uniform4f(LLShaderMgr::DIFFUSE_COLOR, 0, 0, 0, 1); + + static LLStaticHashedString waterSign("waterSign"); + gDrawColorProgram.uniform1f(waterSign, 1.f); + + pushBatches(LLRenderPass::PASS_INVISIBLE, false, false); + + + if (gPipeline.shadersLoaded()) + { + gDrawColorProgram.unbind(); + } +} diff --git a/indra/newview/lldrawpoolwaterexclusion.h b/indra/newview/lldrawpoolwaterexclusion.h new file mode 100644 index 0000000000..e95721a443 --- /dev/null +++ b/indra/newview/lldrawpoolwaterexclusion.h @@ -0,0 +1,61 @@ +/** + * @file lldrawpoolwaterexclusion.h + * @brief LLDrawPoolWaterExclusion class definition + * @author Jonathan "Geenz" Goodman + * + * $LicenseInfo:firstyear=2025&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2013, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#ifndef LL_LLDRAWPOOLWATEREXCLUSION_H +#define LL_LLDRAWPOOLWATEREXCLUSION_H + +#include "v4coloru.h" +#include "v2math.h" +#include "v3math.h" +#include "llvertexbuffer.h" +#include "lldrawpool.h" + +class LLViewerTexture; +class LLDrawInfo; +class LLGLSLShader; + +class LLDrawPoolWaterExclusion : public LLRenderPass +{ +public: + LLDrawPoolWaterExclusion(); + + enum + { + VERTEX_DATA_MASK = LLVertexBuffer::MAP_VERTEX + }; + + virtual U32 getVertexDataMask() { return VERTEX_DATA_MASK; } + + virtual void prerender() {} + + virtual void render(S32 pass = 0); + virtual void beginRenderPass(S32 pass) {} + virtual void endRenderPass(S32 pass) {} + virtual S32 getNumPasses() { return 1; } +}; + +#endif // LL_LLDRAWPOOLWATEREXCLUSION_H diff --git a/indra/newview/llenvironment.h b/indra/newview/llenvironment.h index f1205a72b7..e56548d618 100644 --- a/indra/newview/llenvironment.h +++ b/indra/newview/llenvironment.h @@ -27,6 +27,8 @@ #ifndef LL_ENVIRONMENT_H #define LL_ENVIRONMENT_H +#include <array> + #include "llsingleton.h" #include "llmemory.h" #include "llsd.h" diff --git a/indra/newview/lleventnotifier.cpp b/indra/newview/lleventnotifier.cpp index 25983f4add..16897e9ebd 100644 --- a/indra/newview/lleventnotifier.cpp +++ b/indra/newview/lleventnotifier.cpp @@ -182,6 +182,23 @@ bool LLEventNotifier::add(U32 eventId, F64 eventEpoch, const std::string& eventD } +bool LLEventNotifier::add(const LLEventStruct& event) +{ + if (mNewEventSignal(event)) return false; + LLEventNotification *new_enp = new LLEventNotification(event.eventId, event.eventEpoch, event.eventDateStr, event.eventName); + + LL_INFOS() << "Add event " << event.eventName << " id " << event.eventId << " date " << event.eventDateStr << LL_ENDL; + if(!new_enp->isValid()) + { + delete new_enp; + return false; + } + + mEventNotifications[new_enp->getEventID()] = new_enp; + return true; + +} + void LLEventNotifier::add(U32 eventId) { @@ -211,7 +228,21 @@ void LLEventNotifier::processEventInfoReply(LLMessageSystem *msg, void **) msg->getString("EventData", "Date", eventd_date); msg->getU32("EventData", "DateUTC", event_time_utc); - gEventNotifier.add(event_id, (F64)event_time_utc, eventd_date, event_name); + //gEventNotifier.add(event_id, (F64)event_time_utc, eventd_date, event_name); + + LLEventStruct event(event_id, (F64)event_time_utc, eventd_date, event_name); + msg->getString("EventData", "Creator", event.creator); + msg->getString("EventData", "Category", event.category); + msg->getString("EventData", "Desc", event.desc); + msg->getU32("EventData", "Duration", event.duration); + msg->getU32("EventData", "Cover", event.cover); + msg->getU32("EventData", "Amount", event.amount); + msg->getString("EventData", "SimName", event.simName); + msg->getVector3d("EventData", "GlobalPos", event.globalPos); + msg->getU32("EventData", "EventFlags", event.flags); + + gEventNotifier.add(event); + } @@ -249,11 +280,15 @@ void LLEventNotifier::load(const LLSD& event_options) substitution["datetime"] = date; LLStringUtil::format(dateStr, substitution); - add(response["event_id"].asInteger(), response["event_date_ut"], dateStr, response["event_name"].asString()); + //add(response["event_id"].asInteger(), response["event_date_ut"], dateStr, response["event_name"].asString()); + LLEventStruct event(response["event_id"].asInteger(), response["event_date_ut"], dateStr, response["event_name"].asString()); + add(event); } else { - add(response["event_id"].asInteger(), response["event_date_ut"], response["event_date"].asString(), response["event_name"].asString()); + //add(response["event_id"].asInteger(), response["event_date_ut"], response["event_date"].asString(), response["event_name"].asString()); + LLEventStruct event(response["event_id"].asInteger(), response["event_date_ut"], response["event_date"].asString(), response["event_name"].asString()); + add(event); } } } @@ -287,21 +322,21 @@ void LLEventNotifier::remove(const U32 event_id) void LLEventNotifier::serverPushRequest(U32 event_id, bool add) { // Push up a message to tell the server we have this notification. - gMessageSystem->newMessage(add?"EventNotificationAddRequest":"EventNotificationRemoveRequest"); + gMessageSystem->newMessageFast(add ? _PREHASH_EventNotificationAddRequest : _PREHASH_EventNotificationRemoveRequest); gMessageSystem->nextBlockFast(_PREHASH_AgentData); gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID() ); gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); - gMessageSystem->nextBlock("EventData"); - gMessageSystem->addU32("EventID", event_id); + gMessageSystem->nextBlockFast(_PREHASH_EventData); + gMessageSystem->addU32Fast(_PREHASH_EventID, event_id); gAgent.sendReliableMessage(); } -LLEventNotification::LLEventNotification(U32 eventId, F64 eventEpoch, const std::string& eventDateStr, const std::string &eventName) : +LLEventNotification::LLEventNotification(U32 eventId, F64 eventEpoch, std::string eventDateStr, std::string eventName) : mEventID(eventId), - mEventName(eventName), + mEventName(std::move(eventName)), mEventDateEpoch(eventEpoch), - mEventDateStr(eventDateStr) + mEventDateStr(std::move(eventDateStr)) { } diff --git a/indra/newview/lleventnotifier.h b/indra/newview/lleventnotifier.h index 030c9abb87..f013f6d02e 100644 --- a/indra/newview/lleventnotifier.h +++ b/indra/newview/lleventnotifier.h @@ -27,12 +27,31 @@ #ifndef LL_LLEVENTNOTIFIER_H #define LL_LLEVENTNOTIFIER_H +#include <utility> #include "llframetimer.h" #include "v3dmath.h" class LLEventNotification; class LLMessageSystem; +typedef struct event_st{ + U32 eventId = 0; + F64 eventEpoch = 0.0; + std::string eventDateStr; + std::string eventName; + std::string creator; + std::string category; + std::string desc; + U32 duration = 0; + U32 cover = 0; + U32 amount = 0; + std::string simName; + LLVector3d globalPos; + U32 flags = 0; + event_st(U32 id, F64 epoch, std::string date_str, std::string name) + : eventId(id), eventEpoch(epoch), eventDateStr(std::move(date_str)), eventName(std::move(name)){} + event_st() = default; +} LLEventStruct; class LLEventNotifier { @@ -41,6 +60,7 @@ public: virtual ~LLEventNotifier(); void update(); // Notify the user of the event if it's coming up + bool add(const LLEventStruct& event); bool add(U32 eventId, F64 eventEpoch, const std::string& eventDateStr, const std::string &eventName); void add(U32 eventId); @@ -56,6 +76,13 @@ public: static void processEventInfoReply(LLMessageSystem *msg, void **); + typedef boost::signals2::signal<bool(LLEventStruct event)> new_event_signal_t; + new_event_signal_t mNewEventSignal; + boost::signals2::connection setNewEventCallback(const new_event_signal_t::slot_type& cb) + { + return mNewEventSignal.connect(cb); + }; + protected: en_map mEventNotifications; LLFrameTimer mNotificationTimer; @@ -65,7 +92,7 @@ protected: class LLEventNotification { public: - LLEventNotification(U32 eventId, F64 eventEpoch, const std::string& eventDateStr, const std::string &eventName); + LLEventNotification(U32 eventId, F64 eventEpoch, std::string eventDateStr, std::string eventName); U32 getEventID() const { return mEventID; } diff --git a/indra/newview/lleventpoll.cpp b/indra/newview/lleventpoll.cpp index c05a7fef44..c6fea1ba82 100644 --- a/indra/newview/lleventpoll.cpp +++ b/indra/newview/lleventpoll.cpp @@ -101,10 +101,18 @@ namespace Details void LLEventPollImpl::handleMessage(const LLSD& content) { LL_PROFILE_ZONE_SCOPED_CATEGORY_APP; - std::string msg_name = content["message"]; + std::string msg_name = content["message"].asString(); LLSD message; - message["sender"] = mSenderIp; - message["body"] = content["body"]; + try + { + message["sender"] = mSenderIp; + message["body"] = content["body"]; + } + catch (std::bad_alloc&) + { + LLError::LLUserWarningMsg::showOutOfMemory(); + LL_ERRS("LLCoros") << "Bad memory allocation on message: " << msg_name << LL_ENDL; + } LLMessageSystem::dispatch(msg_name, message); } diff --git a/indra/newview/llface.cpp b/indra/newview/llface.cpp index 3ccb363321..fb4db9a216 100644 --- a/indra/newview/llface.cpp +++ b/indra/newview/llface.cpp @@ -58,12 +58,6 @@ #include "llmeshrepository.h" #include "llskinningutil.h" -#if LL_LINUX -// Work-around spurious used before init warning on Vector4a -// -#pragma GCC diagnostic ignored "-Wuninitialized" -#endif - #define LL_MAX_INDICES_COUNT 1000000 static LLStaticHashedString sTextureIndexIn("texture_index_in"); @@ -549,15 +543,21 @@ void LLFace::renderSelected(LLViewerTexture *imagep, const LLColor4& color) gGL.multMatrix((F32*) volume->getRelativeXform().mMatrix); const LLVolumeFace& vol_face = rigged->getVolumeFace(getTEOffset()); LLVertexBuffer::unbind(); +#if GL_VERSION_1_1 glVertexPointer(3, GL_FLOAT, 16, vol_face.mPositions); +#endif if (vol_face.mTexCoords) { +#if GL_VERSION_1_1 glEnableClientState(GL_TEXTURE_COORD_ARRAY); glTexCoordPointer(2, GL_FLOAT, 8, vol_face.mTexCoords); +#endif } gGL.syncMatrices(); glDrawElements(GL_TRIANGLES, vol_face.mNumIndices, GL_UNSIGNED_SHORT, vol_face.mIndices); +#if GL_VERSION_1_1 glDisableClientState(GL_TEXTURE_COORD_ARRAY); +#endif } } #endif @@ -644,10 +644,14 @@ void LLFace::renderOneWireframe(const LLColor4 &color, F32 fogCfx, bool wirefram { LLGLDisable depth(wireframe_selection ? 0 : GL_BLEND); +#if GL_VERSION_1_1 LLGLEnable offset(GL_POLYGON_OFFSET_LINE); +#endif glPolygonOffset(3.f, 3.f); glLineWidth(5.f); +#if GL_VERSION_1_1 glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); +#endif renderFace(mDrawablep, this); } } @@ -842,7 +846,6 @@ bool LLFace::genVolumeBBoxes(const LLVolume &volume, S32 f, //VECTORIZE THIS LLMatrix4a mat_vert; mat_vert.loadu(mat_vert_in); - LLVector4a new_extents[2]; llassert(less_than_max_mag(face.mExtents[0])); llassert(less_than_max_mag(face.mExtents[1])); @@ -893,7 +896,7 @@ LLVector2 LLFace::surfaceToTexture(LLVector2 surface_coord, const LLVector4a& po //VECTORIZE THIS // see if we have a non-default mapping - U8 texgen = getTextureEntry()->getTexGen(); + U8 texgen = tep->getTexGen(); if (texgen != LLTextureEntry::TEX_GEN_DEFAULT) { LLVector4a& center = *(mDrawablep->getVOVolume()->getVolume()->getVolumeFace(mTEOffset).mCenter); @@ -983,8 +986,17 @@ bool LLFace::calcAlignedPlanarTE(const LLFace* align_to, LLVector2* res_st_offs return false; } const LLTextureEntry *orig_tep = align_to->getTextureEntry(); + if (!orig_tep) + { + return false; + } + const LLTextureEntry* tep = getTextureEntry(); + if (!tep) + { + return false; + } if ((orig_tep->getTexGen() != LLTextureEntry::TEX_GEN_PLANAR) || - (getTextureEntry()->getTexGen() != LLTextureEntry::TEX_GEN_PLANAR)) + (tep->getTexGen() != LLTextureEntry::TEX_GEN_PLANAR)) { return false; } @@ -1563,7 +1575,8 @@ bool LLFace::getGeometryVolume(const LLVolume& volume, bump_t_primary_light_ray.load3((offset_multiple * t_scale * primary_light_ray).mV); } - U8 texgen = getTextureEntry()->getTexGen(); + const LLTextureEntry* tep = getTextureEntry(); + U8 texgen = tep ? tep->getTexGen() : LLTextureEntry::TEX_GEN_DEFAULT; if (rebuild_tcoord && texgen != LLTextureEntry::TEX_GEN_DEFAULT) { //planar texgen needs binormals mVObjp->getVolume()->genTangents(face_index); @@ -2051,7 +2064,12 @@ bool LLFace::getGeometryVolume(const LLVolume& volume, LLStrider<LLColor4U> emissive; mVertexBuffer->getEmissiveStrider(emissive, mGeomIndex, mGeomCount); - U8 glow = (U8) llclamp((S32) (getTextureEntry()->getGlow()*255), 0, 255); + const LLTextureEntry* tep = getTextureEntry(); + U8 glow = 0; + if (tep) + { + glow = (U8)llclamp((S32)(tep->getGlow() * 255), 0, 255); + } LLVector4a src; @@ -2203,7 +2221,7 @@ bool LLFace::calcPixelArea(F32& cos_angle_to_view_dir, F32& radius) { LL_PROFILE_ZONE_NAMED_CATEGORY_FACE("calcPixelArea - rigged"); //override with joint volume face joint bounding boxes - LLVOAvatar* avatar = mVObjp->getAvatar(); + LLVOAvatar* avatar = mVObjp.notNull() ? mVObjp->getAvatar() : nullptr; bool hasRiggedExtents = false; if (avatar && avatar->mDrawable) diff --git a/indra/newview/llfasttimerview.cpp b/indra/newview/llfasttimerview.cpp index 8056983c7c..aa2578fec6 100644 --- a/indra/newview/llfasttimerview.cpp +++ b/indra/newview/llfasttimerview.cpp @@ -1098,7 +1098,7 @@ void LLFastTimerView::drawLineGraph() cur_max_calls = llmax(cur_max_calls, calls); } F32 x = mGraphRect.mRight - j * (F32)(mGraphRect.getWidth())/(mRecording.getNumRecordedPeriods()-1); - F32 y; + F32 y = 0.0; switch(mDisplayType) { case DISPLAY_TIME: diff --git a/indra/newview/llfeaturemanager.cpp b/indra/newview/llfeaturemanager.cpp index ba54d93c75..2bbe5e90c6 100644 --- a/indra/newview/llfeaturemanager.cpp +++ b/indra/newview/llfeaturemanager.cpp @@ -62,7 +62,7 @@ #if LL_DARWIN const char FEATURE_TABLE_FILENAME[] = "featuretable_mac.txt"; -#elif LL_LINUX +#elif LL_LINUX || __FreeBSD__ const char FEATURE_TABLE_FILENAME[] = "featuretable_linux.txt"; #else const char FEATURE_TABLE_FILENAME[] = "featuretable.txt"; diff --git a/indra/newview/llfetchedgltfmaterial.cpp b/indra/newview/llfetchedgltfmaterial.cpp index c2821d56d6..558fc92018 100644 --- a/indra/newview/llfetchedgltfmaterial.cpp +++ b/indra/newview/llfetchedgltfmaterial.cpp @@ -199,6 +199,7 @@ bool LLFetchedGLTFMaterial::replaceLocalTexture(const LLUUID& tracking_id, const { mTrackingIdToLocalTexture.erase(tracking_id); } + updateLocalTexDataDigest(); return res; } diff --git a/indra/newview/llfilepicker.cpp b/indra/newview/llfilepicker.cpp index 0afb275d13..2516bece8d 100644 --- a/indra/newview/llfilepicker.cpp +++ b/indra/newview/llfilepicker.cpp @@ -40,7 +40,12 @@ #include "llwindowsdl.h" // for some X/GTK utils to help with filepickers #endif // LL_SDL -#if LL_LINUX +#ifdef LL_FLTK + #include "FL/Fl.H" + #include "FL/Fl_Native_File_Chooser.H" +#endif + +#if LL_LINUX || __FreeBSD__ #include "llhttpconstants.h" // file picker uses some of thes constants on Linux #endif @@ -670,6 +675,7 @@ std::unique_ptr<std::vector<std::string>> LLFilePicker::navOpenFilterProc(ELoadF break; case FFLOAD_HDRI: allowedv->push_back("exr"); + case FFLOAD_MODEL: case FFLOAD_COLLADA: allowedv->push_back("dae"); break; @@ -1100,490 +1106,233 @@ bool LLFilePicker::getSaveFileModeless(ESaveFilter filter, } //END LL_DARWIN -#elif LL_LINUX - -# if LL_GTK - -// static -void LLFilePicker::add_to_selectedfiles(gpointer data, gpointer user_data) -{ - // We need to run g_filename_to_utf8 in the user's locale - std::string saved_locale(setlocale(LC_ALL, NULL)); - setlocale(LC_ALL, ""); - - LLFilePicker* picker = (LLFilePicker*) user_data; - GError *error = NULL; - gchar* filename_utf8 = g_filename_to_utf8((gchar*)data, - -1, NULL, NULL, &error); - if (error) - { - // *FIXME. - // This condition should really be notified to the user, e.g. - // through a message box. Just logging it is inappropriate. - - // g_filename_display_name is ideal, but >= glib 2.6, so: - // a hand-rolled hacky makeASCII which disallows control chars - std::string display_name; - for (const gchar *str = (const gchar *)data; *str; str++) - { - display_name += (char)((*str >= 0x20 && *str <= 0x7E) ? *str : '?'); - } - LL_WARNS() << "g_filename_to_utf8 failed on \"" << display_name << "\": " << error->message << LL_ENDL; - } - - if (filename_utf8) - { - picker->mFiles.push_back(std::string(filename_utf8)); - LL_DEBUGS() << "ADDED FILE " << filename_utf8 << LL_ENDL; - g_free(filename_utf8); - } - - setlocale(LC_ALL, saved_locale.c_str()); -} - -// static -void LLFilePicker::chooser_responder(GtkWidget *widget, gint response, gpointer user_data) -{ - LLFilePicker* picker = (LLFilePicker*)user_data; - - LL_DEBUGS() << "GTK DIALOG RESPONSE " << response << LL_ENDL; - - if (response == GTK_RESPONSE_ACCEPT) - { - GSList *file_list = gtk_file_chooser_get_filenames(GTK_FILE_CHOOSER(widget)); - g_slist_foreach(file_list, (GFunc)add_to_selectedfiles, user_data); - g_slist_foreach(file_list, (GFunc)g_free, NULL); - g_slist_free (file_list); - } - - // let's save the extension of the last added file(considering current filter) - GtkFileFilter *gfilter = gtk_file_chooser_get_filter(GTK_FILE_CHOOSER(widget)); - if(gfilter) - { - std::string filter = gtk_file_filter_get_name(gfilter); - - if(filter == LLTrans::getString("png_image_files")) - { - picker->mCurrentExtension = ".png"; - } - else if(filter == LLTrans::getString("targa_image_files")) - { - picker->mCurrentExtension = ".tga"; - } - } - - // set the default path for this usage context. - const char* cur_folder = gtk_file_chooser_get_current_folder(GTK_FILE_CHOOSER(widget)); - if (cur_folder != NULL) - { - picker->mContextToPathMap[picker->mCurContextName] = cur_folder; - } - - gtk_widget_destroy(widget); - gtk_main_quit(); -} - - -GtkWindow* LLFilePicker::buildFilePicker(bool is_save, bool is_folder, std::string context) -{ -#ifndef LL_MESA_HEADLESS - if (LLWindowSDL::ll_try_gtk_init()) - { - GtkWidget *win = NULL; - GtkFileChooserAction pickertype = - is_save? - (is_folder? - GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER : - GTK_FILE_CHOOSER_ACTION_SAVE) : - (is_folder? - GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER : - GTK_FILE_CHOOSER_ACTION_OPEN); - - win = gtk_file_chooser_dialog_new(NULL, NULL, - pickertype, - GTK_STOCK_CANCEL, - GTK_RESPONSE_CANCEL, - is_folder ? - GTK_STOCK_APPLY : - (is_save ? - GTK_STOCK_SAVE : - GTK_STOCK_OPEN), - GTK_RESPONSE_ACCEPT, - (gchar *)NULL); - mCurContextName = context; - - // get the default path for this usage context if it's been - // seen before. - std::map<std::string,std::string>::iterator - this_path = mContextToPathMap.find(context); - if (this_path != mContextToPathMap.end()) - { - gtk_file_chooser_set_current_folder - (GTK_FILE_CHOOSER(win), - this_path->second.c_str()); - } - -# if LL_X11 - // Make GTK tell the window manager to associate this - // dialog with our non-GTK raw X11 window, which should try - // to keep it on top etc. - Window XWindowID = LLWindowSDL::get_SDL_XWindowID(); - if (None != XWindowID) - { - gtk_widget_realize(GTK_WIDGET(win)); // so we can get its gdkwin - GdkWindow *gdkwin = gdk_window_foreign_new(XWindowID); - gdk_window_set_transient_for(GTK_WIDGET(win)->window, - gdkwin); - } - else - { - LL_WARNS() << "Hmm, couldn't get xwid to use for transient." << LL_ENDL; - } -# endif //LL_X11 - - g_signal_connect (GTK_FILE_CHOOSER(win), - "response", - G_CALLBACK(LLFilePicker::chooser_responder), - this); - - gtk_window_set_modal(GTK_WINDOW(win), TRUE); +#elif LL_LINUX || __FreeBSD__ - /* GTK 2.6: if (is_folder) - gtk_file_chooser_set_show_hidden(GTK_FILE_CHOOSER(win), - TRUE); */ +#if LL_FLTK - return GTK_WINDOW(win); - } - else - { - return NULL; - } -#else - return NULL; -#endif //LL_MESA_HEADLESS -} - -static void add_common_filters_to_gtkchooser(GtkFileFilter *gfilter, - GtkWindow *picker, - std::string filtername) -{ - gtk_file_filter_set_name(gfilter, filtername.c_str()); - gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(picker), - gfilter); - GtkFileFilter *allfilter = gtk_file_filter_new(); - gtk_file_filter_add_pattern(allfilter, "*"); - gtk_file_filter_set_name(allfilter, LLTrans::getString("all_files").c_str()); - gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(picker), allfilter); - gtk_file_chooser_set_filter(GTK_FILE_CHOOSER(picker), gfilter); -} - -static std::string add_simple_pattern_filter_to_gtkchooser(GtkWindow *picker, - std::string pattern, - std::string filtername) -{ - GtkFileFilter *gfilter = gtk_file_filter_new(); - gtk_file_filter_add_pattern(gfilter, pattern.c_str()); - add_common_filters_to_gtkchooser(gfilter, picker, filtername); - return filtername; -} - -static std::string add_simple_mime_filter_to_gtkchooser(GtkWindow *picker, - std::string mime, - std::string filtername) -{ - GtkFileFilter *gfilter = gtk_file_filter_new(); - gtk_file_filter_add_mime_type(gfilter, mime.c_str()); - add_common_filters_to_gtkchooser(gfilter, picker, filtername); - return filtername; -} - -static std::string add_wav_filter_to_gtkchooser(GtkWindow *picker) +bool LLFilePicker::getSaveFileModeless(ESaveFilter filter, + const std::string& filename, + void (*callback)(bool, std::string&, void*), + void *userdata) { - return add_simple_mime_filter_to_gtkchooser(picker, "audio/x-wav", - LLTrans::getString("sound_files") + " (*.wav)"); + LL_ERRS() << "NOT IMPLEMENTED" << LL_ENDL; + return FALSE; } -static std::string add_anim_filter_to_gtkchooser(GtkWindow *picker) +bool LLFilePicker::getOpenFileModeless(ELoadFilter filter, + void (*callback)(bool, std::vector<std::string> &, void*), + void *userdata) { - GtkFileFilter *gfilter = gtk_file_filter_new(); - gtk_file_filter_add_pattern(gfilter, "*.bvh"); - gtk_file_filter_add_pattern(gfilter, "*.anim"); - std::string filtername = LLTrans::getString("animation_files") + " (*.bvh; *.anim)"; - add_common_filters_to_gtkchooser(gfilter, picker, filtername); - return filtername; + LL_ERRS() << "NOT IMPLEMENTED" << LL_ENDL; + return FALSE; } -static std::string add_xml_filter_to_gtkchooser(GtkWindow *picker) +bool LLFilePicker::getMultipleOpenFilesModeless(ELoadFilter filter, + void (*callback)(bool, std::vector<std::string> &, void*), + void *userdata ) { - return add_simple_pattern_filter_to_gtkchooser(picker, "*.xml", - LLTrans::getString("xml_files") + " (*.xml)"); + LL_ERRS() << "NOT IMPLEMENTED" << LL_ENDL; + return FALSE; } -static std::string add_collada_filter_to_gtkchooser(GtkWindow *picker) -{ - return add_simple_pattern_filter_to_gtkchooser(picker, "*.dae", - LLTrans::getString("scene_files") + " (*.dae)"); -} -static std::string add_imageload_filter_to_gtkchooser(GtkWindow *picker) -{ - GtkFileFilter *gfilter = gtk_file_filter_new(); - gtk_file_filter_add_pattern(gfilter, "*.tga"); - gtk_file_filter_add_mime_type(gfilter, HTTP_CONTENT_IMAGE_JPEG.c_str()); - gtk_file_filter_add_mime_type(gfilter, HTTP_CONTENT_IMAGE_PNG.c_str()); - gtk_file_filter_add_mime_type(gfilter, HTTP_CONTENT_IMAGE_BMP.c_str()); - std::string filtername = LLTrans::getString("image_files") + " (*.tga; *.bmp; *.jpg; *.png)"; - add_common_filters_to_gtkchooser(gfilter, picker, filtername); - return filtername; -} -static std::string add_script_filter_to_gtkchooser(GtkWindow *picker) +bool LLFilePicker::getSaveFile( ESaveFilter filter, const std::string& filename, bool blocking ) { - return add_simple_mime_filter_to_gtkchooser(picker, HTTP_CONTENT_TEXT_PLAIN, - LLTrans::getString("script_files") + " (*.lsl)"); + return openFileDialog( filter, blocking, eSaveFile ); } -static std::string add_dictionary_filter_to_gtkchooser(GtkWindow *picker) +bool LLFilePicker::getOpenFile( ELoadFilter filter, bool blocking ) { - return add_simple_mime_filter_to_gtkchooser(picker, HTTP_CONTENT_TEXT_PLAIN, - LLTrans::getString("dictionary_files") + " (*.dic; *.xcu)"); + return openFileDialog( filter, blocking, eOpenFile ); } -static std::string add_save_texture_filter_to_gtkchooser(GtkWindow *picker) +bool LLFilePicker::getMultipleOpenFiles( ELoadFilter filter, bool blocking) { - GtkFileFilter *gfilter_tga = gtk_file_filter_new(); - GtkFileFilter *gfilter_png = gtk_file_filter_new(); - - gtk_file_filter_add_pattern(gfilter_tga, "*.tga"); - gtk_file_filter_add_mime_type(gfilter_png, "image/png"); - std::string caption = LLTrans::getString("save_texture_image_files") + " (*.tga; *.png)"; - gtk_file_filter_set_name(gfilter_tga, LLTrans::getString("targa_image_files").c_str()); - gtk_file_filter_set_name(gfilter_png, LLTrans::getString("png_image_files").c_str()); - - gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(picker), - gfilter_png); - gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(picker), - gfilter_tga); - return caption; + return openFileDialog( filter, blocking, eOpenMultiple ); } -bool LLFilePicker::getSaveFile( ESaveFilter filter, const std::string& filename, bool blocking ) +bool LLFilePicker::openFileDialog( int32_t filter, bool blocking, EType aType ) { - bool rtn = false; - - // if local file browsing is turned off, return without opening dialog - if (!check_local_file_access_enabled()) - { + if ( check_local_file_access_enabled() == false ) return false; - } - gViewerWindow->getWindow()->beforeDialog(); - reset(); - - GtkWindow* picker = buildFilePicker(true, false, "savefile"); - - if (picker) - { - std::string suggest_name = "untitled"; - std::string suggest_ext = ""; - std::string caption = LLTrans::getString("save_file_verb") + " "; - switch (filter) + Fl_Native_File_Chooser::Type flType = Fl_Native_File_Chooser::BROWSE_FILE; + if( aType == eOpenMultiple ) + flType = Fl_Native_File_Chooser::BROWSE_MULTI_FILE; + else if( aType == eSaveFile ) + flType = Fl_Native_File_Chooser::BROWSE_SAVE_FILE; + Fl_Native_File_Chooser flDlg; + std::string file_dialog_title; + std::string file_dialog_filter; + if (aType == EType::eSaveFile) + { + std::string file_type("all_files"); + switch ((ESaveFilter) filter) { - case FFSAVE_WAV: - caption += add_wav_filter_to_gtkchooser(picker); - suggest_ext = ".wav"; - break; - case FFSAVE_TGA: - caption += add_simple_pattern_filter_to_gtkchooser - (picker, "*.tga", LLTrans::getString("targa_image_files") + " (*.tga)"); - suggest_ext = ".tga"; - break; - case FFSAVE_BMP: - caption += add_simple_mime_filter_to_gtkchooser - (picker, HTTP_CONTENT_IMAGE_BMP, LLTrans::getString("bitmap_image_files") + " (*.bmp)"); - suggest_ext = ".bmp"; - break; - case FFSAVE_PNG: - caption += add_simple_mime_filter_to_gtkchooser - (picker, "image/png", LLTrans::getString("png_image_files") + " (*.png)"); - suggest_ext = ".png"; - break; - case FFSAVE_TGAPNG: - caption += add_save_texture_filter_to_gtkchooser(picker); - suggest_ext = ".png"; - break; - case FFSAVE_AVI: - caption += add_simple_mime_filter_to_gtkchooser - (picker, "video/x-msvideo", - LLTrans::getString("avi_movie_file") + " (*.avi)"); - suggest_ext = ".avi"; - break; - case FFSAVE_ANIM: - caption += add_simple_pattern_filter_to_gtkchooser - (picker, "*.xaf", LLTrans::getString("xaf_animation_file") + " (*.xaf)"); - suggest_ext = ".xaf"; - break; - case FFSAVE_XML: - caption += add_simple_pattern_filter_to_gtkchooser - (picker, "*.xml", LLTrans::getString("xml_file") + " (*.xml)"); - suggest_ext = ".xml"; - break; - case FFSAVE_RAW: - caption += add_simple_pattern_filter_to_gtkchooser - (picker, "*.raw", LLTrans::getString("raw_file") + " (*.raw)"); - suggest_ext = ".raw"; - break; - case FFSAVE_J2C: - // *TODO: Should this be 'image/j2c' ? - caption += add_simple_mime_filter_to_gtkchooser - (picker, "images/jp2", - LLTrans::getString("compressed_image_files") + " (*.j2c)"); - suggest_ext = ".j2c"; - break; - case FFSAVE_SCRIPT: - caption += add_script_filter_to_gtkchooser(picker); - suggest_ext = ".lsl"; - break; - default:; - break; + case FFSAVE_ALL: + break; + case FFSAVE_TGA: + file_type = "targa_image_files"; + file_dialog_filter = "*.tga"; + break; + case FFSAVE_BMP: + file_type = "bitmap_image_files"; + file_dialog_filter = "*.bmp"; + break; + case FFSAVE_AVI: + file_type = "avi_movie_file"; + file_dialog_filter = "*.avi"; + break; + case FFSAVE_ANIM: + file_type = "xaf_animation_file"; + file_dialog_filter = "*.xaf"; + break; + case FFSAVE_XML: + file_type = "xml_file"; + file_dialog_filter = "*.xml"; + break; + case FFSAVE_COLLADA: + file_type = "collada_files"; + file_dialog_filter = "*.dae"; + break; + case FFSAVE_RAW: + file_type = "raw_file"; + file_dialog_filter = "*.raw"; + break; + case FFSAVE_J2C: + file_type = "compressed_image_files"; + file_dialog_filter = "*.j2c"; + break; + case FFSAVE_PNG: + file_type = "png_image_files"; + file_dialog_filter = "*.png"; + break; + case FFSAVE_JPEG: + file_type = "jpeg_image_files"; + file_dialog_filter = "*.{jpg,jpeg}"; + break; + case FFSAVE_SCRIPT: + file_type = "script_files"; + file_dialog_filter = "*.lsl"; + break; + case FFSAVE_TGAPNG: + file_type = "save_texture_image_files"; + file_dialog_filter = "*.{tga,png}"; + break; + case FFSAVE_WAV: + file_type = "sound_files"; + file_dialog_filter = "*.wav"; + break; + case FFSAVE_GLTF: + file_type = "gltf_asset_file"; + file_dialog_filter = "*.{gltf,glb}"; + break; } - - gtk_window_set_title(GTK_WINDOW(picker), caption.c_str()); - - if (filename.empty()) + file_dialog_title = LLTrans::getString("save_file_verb") + " " + LLTrans::getString(file_type); + file_dialog_filter = LLTrans::getString(file_type) + " \t" + file_dialog_filter; + } + else + { + std::string file_type("all_files"); + switch ((ELoadFilter) filter) { - suggest_name += suggest_ext; + case FFLOAD_ALL: + break; + case FFLOAD_WAV: + file_type = "sound_files"; + file_dialog_filter = "*.wav"; + break; + case FFLOAD_IMAGE: + file_type = "image_files"; + file_dialog_filter = "*.{tga,bmp,jpg,jpeg,png}"; + break; + case FFLOAD_ANIM: + file_type = "animation_files"; + file_dialog_filter = "*.{bvh,anim}"; + break; + case FFLOAD_XML: + file_type = "xml_file"; + file_dialog_filter = "*.xml"; + break; + case FFLOAD_SLOBJECT: + file_type = "xml_file"; + file_dialog_filter = "*.slobject"; + break; + case FFLOAD_RAW: + file_type = "raw_file"; + file_dialog_filter = "*.raw"; + break; + case FFLOAD_MODEL: + case FFLOAD_COLLADA: + file_type = "collada_files"; + file_dialog_filter = "*.dae"; + break; + case FFLOAD_SCRIPT: + file_type = "script_files"; + file_dialog_filter = "*.lsl"; + break; + case FFLOAD_DICTIONARY: + file_type = "dictionary_files"; + file_dialog_filter = "*.{dic,xcu}"; + break; + case FFLOAD_DIRECTORY: + file_type = "choose_the_directory"; + break; + case FFLOAD_EXE: + file_type = "executable_files"; + break; + case FFLOAD_GLTF: + case FFLOAD_MATERIAL: + file_type = "gltf_asset_file"; + file_dialog_filter = "*.{gltg,glb}"; + break; + case FFLOAD_MATERIAL_TEXTURE: + file_dialog_filter = "*.{gltf,glb,tga,bmp,jpg,jpeg,png}"; + file_type = "image_files"; + break; + case FFLOAD_HDRI: + file_dialog_filter = "*.exr"; - gtk_file_chooser_set_current_name - (GTK_FILE_CHOOSER(picker), - suggest_name.c_str()); } - else + if (aType == EType::eOpenMultiple) { - gtk_file_chooser_set_current_name - (GTK_FILE_CHOOSER(picker), filename.c_str()); + file_dialog_title = LLTrans::getString("load_files"); } - - gtk_widget_show_all(GTK_WIDGET(picker)); - - gtk_main(); - - rtn = (getFileCount() == 1); - - if(rtn && filter == FFSAVE_TGAPNG) + else { - std::string selected_file = mFiles.back(); - mFiles.pop_back(); - mFiles.push_back(selected_file + mCurrentExtension); + file_dialog_title = LLTrans::getString("load_file_verb") + " " + LLTrans::getString(file_type); + file_dialog_filter = LLTrans::getString(file_type) + " \t" + file_dialog_filter; } } - - gViewerWindow->getWindow()->afterDialog(); - - return rtn; -} - -bool LLFilePicker::getOpenFile( ELoadFilter filter, bool blocking ) -{ - bool rtn = false; - - // if local file browsing is turned off, return without opening dialog - if (!check_local_file_access_enabled()) + flDlg.title(file_dialog_title.c_str()); + flDlg.type(flType); + if (!file_dialog_filter.empty()) { - return false; + flDlg.filter(file_dialog_filter.c_str()); } - - gViewerWindow->getWindow()->beforeDialog(); - - reset(); - - GtkWindow* picker = buildFilePicker(false, false, "openfile"); - - if (picker) + int res = flDlg.show(); + gViewerWindow->getWindow()->afterDialog(); + if( res == 0 ) { - std::string caption = LLTrans::getString("load_file_verb") + " "; - std::string filtername = ""; - switch (filter) + int32_t count = flDlg.count(); + if( count < 0 ) + count = 0; + for( int32_t i = 0; i < count; ++i ) { - case FFLOAD_WAV: - filtername = add_wav_filter_to_gtkchooser(picker); - break; - case FFLOAD_ANIM: - filtername = add_anim_filter_to_gtkchooser(picker); - break; - case FFLOAD_XML: - filtername = add_xml_filter_to_gtkchooser(picker); - break; - case FFLOAD_GLTF: - filtername = dead_code_should_blow_up_here(picker); - break; - case FFLOAD_COLLADA: - filtername = add_collada_filter_to_gtkchooser(picker); - break; - case FFLOAD_IMAGE: - filtername = add_imageload_filter_to_gtkchooser(picker); - break; - case FFLOAD_SCRIPT: - filtername = add_script_filter_to_gtkchooser(picker); - break; - case FFLOAD_DICTIONARY: - filtername = add_dictionary_filter_to_gtkchooser(picker); - break; - default:; - break; + char const *pFile = flDlg.filename(i); + if( pFile && strlen(pFile) > 0 ) + mFiles.push_back( pFile ); } - - caption += filtername; - - gtk_window_set_title(GTK_WINDOW(picker), caption.c_str()); - - gtk_widget_show_all(GTK_WIDGET(picker)); - gtk_main(); - - rtn = (getFileCount() == 1); - } - - gViewerWindow->getWindow()->afterDialog(); - - return rtn; -} - -bool LLFilePicker::getMultipleOpenFiles( ELoadFilter filter, bool blocking) -{ - bool rtn = false; - - // if local file browsing is turned off, return without opening dialog - if (!check_local_file_access_enabled()) - { - return false; } - - gViewerWindow->getWindow()->beforeDialog(); - - reset(); - - GtkWindow* picker = buildFilePicker(false, false, "openfile"); - - if (picker) + else if( res == -1 ) { - gtk_file_chooser_set_select_multiple (GTK_FILE_CHOOSER(picker), - TRUE); - - gtk_window_set_title(GTK_WINDOW(picker), LLTrans::getString("load_files").c_str()); - - gtk_widget_show_all(GTK_WIDGET(picker)); - gtk_main(); - rtn = !mFiles.empty(); + LL_WARNS() << "FLTK failed: " << flDlg.errmsg() << LL_ENDL; } - - gViewerWindow->getWindow()->afterDialog(); - - return rtn; + return mFiles.empty()?FALSE:TRUE; } - -# else // LL_GTK - +#else // Hacky stubs designed to facilitate fake getSaveFile and getOpenFile with // static results, when we don't have a real filepicker. @@ -1671,17 +1420,17 @@ bool LLFilePicker::getMultipleOpenFilesModeless(ELoadFilter filter, return false; } -#endif // LL_GTK +#endif // LL_FLTK #else // not implemented -bool LLFilePicker::getSaveFile( ESaveFilter filter, const std::string& filename ) +bool LLFilePicker::getSaveFile( ESaveFilter filter, const std::string& filename, bool blocking ) { reset(); return false; } -bool LLFilePicker::getOpenFile( ELoadFilter filter ) +bool LLFilePicker::getOpenFile( ELoadFilter filter, bool blocking ) { reset(); return false; diff --git a/indra/newview/llfilepicker.h b/indra/newview/llfilepicker.h index 75ff14f4cf..b99156c61e 100644 --- a/indra/newview/llfilepicker.h +++ b/indra/newview/llfilepicker.h @@ -54,19 +54,8 @@ #include <commdlg.h> #endif -extern "C" { -// mostly for Linux, possible on others -#if LL_GTK -# include "gtk/gtk.h" -#endif // LL_GTK -} - class LLFilePicker { -#ifdef LL_GTK - friend class LLDirPicker; - friend void chooser_responder(GtkWidget *, gint, gpointer); -#endif // LL_GTK public: // calling this before main() is undefined static LLFilePicker& instance( void ) { return sInstance; } @@ -184,14 +173,12 @@ private: void *userdata); #endif -#if LL_GTK - static void add_to_selectedfiles(gpointer data, gpointer user_data); - static void chooser_responder(GtkWidget *widget, gint response, gpointer user_data); - // we remember the last path that was accessed for a particular usage - std::map <std::string, std::string> mContextToPathMap; - std::string mCurContextName; - // we also remember the extension of the last added file. - std::string mCurrentExtension; +#if LL_FLTK + enum EType + { + eSaveFile, eOpenFile, eOpenMultiple + }; + bool openFileDialog( int32_t filter, bool blocking, EType aType ); #endif std::vector<std::string> mFiles; @@ -200,12 +187,6 @@ private: static LLFilePicker sInstance; -protected: -#if LL_GTK - GtkWindow* buildFilePicker(bool is_save, bool is_folder, - std::string context = "generic"); -#endif - public: // don't call these directly please. LLFilePicker(); diff --git a/indra/newview/llfloater360capture.cpp b/indra/newview/llfloater360capture.cpp index ff30c83f51..25970f8a08 100644 --- a/indra/newview/llfloater360capture.cpp +++ b/indra/newview/llfloater360capture.cpp @@ -33,6 +33,7 @@ #include "llagentui.h" #include "llbase64.h" #include "llcallbacklist.h" +#include "lldate.h" #include "llenvironment.h" #include "llimagejpeg.h" #include "llmediactrl.h" @@ -692,7 +693,15 @@ void LLFloater360Capture::handleMediaEvent(LLPluginClassMedia* self, EMediaEvent ); // execute the command on the page - mWebBrowser->getMediaPlugin()->executeJavaScript(cmd); + LLPluginClassMedia* plugin = mWebBrowser->getMediaPlugin(); + if (plugin) + { + plugin->executeJavaScript(cmd); + } + else + { + LL_WARNS("360Capture") << "No media plugin found" << LL_ENDL; + } } } break; @@ -773,7 +782,15 @@ void LLFloater360Capture::onSaveLocalBtn() // send it to the browser instance, triggering the equirectangular capture // process and complimentary offer to save the image - mWebBrowser->getMediaPlugin()->executeJavaScript(cmd); + LLPluginClassMedia* plugin = mWebBrowser->getMediaPlugin(); + if (plugin) + { + plugin->executeJavaScript(cmd); + } + else + { + LL_WARNS("360Capture") << "No media plugin found" << LL_ENDL; + } } // We capture all 6 images sequentially and if parts of the world are moving @@ -863,15 +880,7 @@ const std::string LLFloater360Capture::generate_proposed_filename() filename << "_"; // add in the current HH-MM-SS (with leading 0's) so users can easily save many shots in same folder - std::time_t cur_epoch = std::time(nullptr); - std::tm* tm_time = std::localtime(&cur_epoch); - filename << std::setfill('0') << std::setw(4) << (tm_time->tm_year + 1900); - filename << std::setfill('0') << std::setw(2) << (tm_time->tm_mon + 1); - filename << std::setfill('0') << std::setw(2) << tm_time->tm_mday; - filename << "_"; - filename << std::setfill('0') << std::setw(2) << tm_time->tm_hour; - filename << std::setfill('0') << std::setw(2) << tm_time->tm_min; - filename << std::setfill('0') << std::setw(2) << tm_time->tm_sec; + filename << LLDate::now().toLocalDateString("%Y%m%d_%H%M%S"); // the unusual way we save the output image (originates in the // embedded browser and not the C++ code) means that the system diff --git a/indra/newview/llfloatercamera.cpp b/indra/newview/llfloatercamera.cpp index 4a5a755696..8a15f1a34a 100644 --- a/indra/newview/llfloatercamera.cpp +++ b/indra/newview/llfloatercamera.cpp @@ -478,10 +478,8 @@ bool LLFloaterCamera::postBuild() mZoom = getChild<LLPanelCameraZoom>(ZOOM); mTrack = getChild<LLJoystickCameraTrack>(PAN); mPresetCombo = getChild<LLComboBox>("preset_combo"); - mPreciseCtrls = getChild<LLTextBox>("precise_ctrs_label"); + mPreciseCtrls = getChild<LLButton>("precise_btn"); - mPreciseCtrls->setShowCursorHand(false); - mPreciseCtrls->setSoundFlags(LLView::MOUSE_UP); mPreciseCtrls->setClickedCallback(boost::bind(&LLFloaterReg::showInstance, "prefs_view_advanced", LLSD(), false)); mPresetCombo->setCommitCallback(boost::bind(&LLFloaterCamera::onCustomPresetSelected, this)); @@ -492,6 +490,11 @@ bool LLFloaterCamera::postBuild() // ensure that appearance mode is handled while building. See EXT-7796. handleAvatarEditingAppearance(sAppearanceEditing); + mCollapseCtrl = getChild<LLButton>("collapse_btn"); + mCollapseCtrl->setCommitCallback(boost::bind(&LLFloaterCamera::toggleCollapsedView, this)); + + updateCollapsedView(); + return LLFloater::postBuild(); } @@ -736,3 +739,19 @@ void LLFloaterCamera::onCustomPresetSelected() switchToPreset(selected_preset); } } + +void LLFloaterCamera::toggleCollapsedView() +{ + BOOL isCollapsed = gSavedSettings.getBOOL("MPVCameraCollapsed"); + gSavedSettings.setBOOL("MPVCameraCollapsed", !isCollapsed); + updateCollapsedView(); +} + +void LLFloaterCamera::updateCollapsedView() +{ + BOOL isCollapsed = gSavedSettings.getBOOL("MPVCameraCollapsed"); + mCollapseCtrl->setImageOverlay(!isCollapsed ? "Conv_toolbar_collapse" : "Conv_toolbar_expand"); + getChild<LLPanel>("buttons_panel")->setVisible(!isCollapsed); + //mPreciseCtrls->setVisible(!collapse); + reshape(!isCollapsed ? 362 : 172, getRect().getHeight(), FALSE); +} diff --git a/indra/newview/llfloatercamera.h b/indra/newview/llfloatercamera.h index ece3d8218e..7db903f470 100644 --- a/indra/newview/llfloatercamera.h +++ b/indra/newview/llfloatercamera.h @@ -122,6 +122,9 @@ private: void showDebugInfo(bool show); + void toggleCollapsedView(); + void updateCollapsedView(); + // set to true when free camera mode is selected in modes list // remains true until preset camera mode is chosen, or pan button is clicked, or escape pressed static bool sFreeCamera; @@ -135,7 +138,8 @@ private: LLPanel* mViewerCameraInfo { nullptr }; LLPanel* mAgentCameraInfo { nullptr }; LLComboBox* mPresetCombo { nullptr }; - LLTextBox* mPreciseCtrls { nullptr }; + LLButton* mPreciseCtrls { nullptr }; + LLButton* mCollapseCtrl { nullptr }; }; /** diff --git a/indra/newview/llfloatercreatelandmark.cpp b/indra/newview/llfloatercreatelandmark.cpp index 2ce8a7a212..77ea544c5d 100644 --- a/indra/newview/llfloatercreatelandmark.cpp +++ b/indra/newview/llfloatercreatelandmark.cpp @@ -31,6 +31,7 @@ #include "llagent.h" #include "llagentui.h" #include "llcombobox.h" +#include "llfloaterreg.h" #include "llinventoryfunctions.h" #include "llinventoryobserver.h" #include "lllandmarkactions.h" @@ -286,8 +287,7 @@ void LLFloaterCreateLandmark::onCreateFolderClicked() std::string folder_name = resp["message"].asString(); if (!folder_name.empty()) { - inventory_func_type func = boost::bind(&LLFloaterCreateLandmark::folderCreatedCallback, this, _1); - gInventory.createNewCategory(mLandmarksID, LLFolderType::FT_NONE, folder_name, func); + gInventory.createNewCategory(mLandmarksID, LLFolderType::FT_NONE, folder_name, folderCreatedCallback); gInventory.notifyObservers(); } } @@ -296,7 +296,11 @@ void LLFloaterCreateLandmark::onCreateFolderClicked() void LLFloaterCreateLandmark::folderCreatedCallback(LLUUID folder_id) { - populateFoldersList(folder_id); + LLFloaterCreateLandmark* floater = LLFloaterReg::findTypedInstance<LLFloaterCreateLandmark>("add_landmark"); + if (floater && !floater->isDead()) + { + floater->populateFoldersList(folder_id); + } } void LLFloaterCreateLandmark::onSaveClicked() @@ -389,6 +393,7 @@ void LLFloaterCreateLandmark::setItem(const uuid_set_t& items) { mItem = item; mAssetID = mItem->getAssetUUID(); + mParentID = mItem->getParentUUID(); setVisibleAndFrontmost(true); break; } @@ -418,8 +423,7 @@ void LLFloaterCreateLandmark::updateItem(const uuid_set_t& items, U32 mask) closeFloater(); } - LLUUID folder_id = mFolderCombo->getValue().asUUID(); - if (folder_id != mItem->getParentUUID()) + if (mParentID != mItem->getParentUUID()) { // user moved landmark in inventory, // assume that we are done all other changes should already be commited diff --git a/indra/newview/llfloatercreatelandmark.h b/indra/newview/llfloatercreatelandmark.h index fa6d001b8e..bcf9d8578c 100644 --- a/indra/newview/llfloatercreatelandmark.h +++ b/indra/newview/llfloatercreatelandmark.h @@ -62,13 +62,14 @@ private: void onSaveClicked(); void onCancelClicked(); - void folderCreatedCallback(LLUUID folder_id); + static void folderCreatedCallback(LLUUID folder_id); LLComboBox* mFolderCombo; LLLineEditor* mLandmarkTitleEditor; LLTextEditor* mNotesEditor; LLUUID mLandmarksID; LLUUID mAssetID; + LLUUID mParentID; LLLandmarksInventoryObserver* mInventoryObserver; LLPointer<LLInventoryItem> mItem; diff --git a/indra/newview/llfloateremojipicker.cpp b/indra/newview/llfloateremojipicker.cpp index cc13e5d059..ffbda0265d 100644 --- a/indra/newview/llfloateremojipicker.cpp +++ b/indra/newview/llfloateremojipicker.cpp @@ -57,8 +57,7 @@ static const S32 USED_EMOJIS_IMAGE_INDEX = 0x23F2; // https://www.compart.com/en/unicode/U+1F6D1 static const S32 EMPTY_LIST_IMAGE_INDEX = 0x1F6D1; // The following categories should follow the required alphabetic order -static const std::string RECENTLY_USED_CATEGORY = "1 recently used"; -static const std::string FREQUENTLY_USED_CATEGORY = "2 frequently used"; +static const std::string FREQUENTLY_USED_CATEGORY = "frequently used"; // Floater state related variables static std::list<llwchar> sRecentlyUsed; @@ -436,6 +435,7 @@ void LLFloaterEmojiPicker::fillGroups() LLButton::Params params; params.font = LLFontGL::getFontEmojiLarge(); + params.name = "all_categories"; LLRect rect; rect.mTop = mGroups->getRect().getHeight(); @@ -445,11 +445,10 @@ void LLFloaterEmojiPicker::fillGroups() params.name = "all_categories"; createGroupButton(params, rect, ALL_EMOJIS_IMAGE_INDEX); - // Create group and button for "Recently used" and/or "Frequently used" - if (!sRecentlyUsed.empty() || !sFrequentlyUsed.empty()) + // Create group and button for "Frequently used" + if (!sFrequentlyUsed.empty()) { std::map<std::string, std::vector<LLEmojiSearchResult>> cats; - fillCategoryRecentlyUsed(cats); fillCategoryFrequentlyUsed(cats); if (!cats.empty()) @@ -482,40 +481,6 @@ void LLFloaterEmojiPicker::fillGroups() resizeGroupButtons(); } -void LLFloaterEmojiPicker::fillCategoryRecentlyUsed(std::map<std::string, std::vector<LLEmojiSearchResult>>& cats) -{ - if (sRecentlyUsed.empty()) - return; - - std::vector<LLEmojiSearchResult> emojis; - - // In case of empty mFilterPattern we'd use sRecentlyUsed directly - if (!mFilterPattern.empty()) - { - // List all emojis in "Recently used" - const LLEmojiDictionary::emoji2descr_map_t& emoji2descr = LLEmojiDictionary::instance().getEmoji2Descr(); - std::size_t begin, end; - for (llwchar emoji : sRecentlyUsed) - { - auto e2d = emoji2descr.find(emoji); - if (e2d != emoji2descr.end() && !e2d->second->ShortCodes.empty()) - { - for (const std::string& shortcode : e2d->second->ShortCodes) - { - if (LLEmojiDictionary::searchInShortCode(begin, end, shortcode, mFilterPattern)) - { - emojis.emplace_back(emoji, shortcode, begin, end); - } - } - } - } - if (emojis.empty()) - return; - } - - cats.emplace(std::make_pair(RECENTLY_USED_CATEGORY, emojis)); -} - void LLFloaterEmojiPicker::fillCategoryFrequentlyUsed(std::map<std::string, std::vector<LLEmojiSearchResult>>& cats) { if (sFrequentlyUsed.empty()) @@ -756,7 +721,6 @@ void LLFloaterEmojiPicker::fillEmojisCategory(const std::vector<LLEmojiSearchRes { // Place the category title std::string title = - category == RECENTLY_USED_CATEGORY ? getString("title_for_recently_used") : category == FREQUENTLY_USED_CATEGORY ? getString("title_for_frequently_used") : isupper(category.front()) ? category : LLStringUtil::capitalize(category); LLEmojiGridDivider* div = new LLEmojiGridDivider(row_panel_params, title); @@ -769,21 +733,7 @@ void LLFloaterEmojiPicker::fillEmojisCategory(const std::vector<LLEmojiSearchRes { const LLEmojiDictionary::emoji2descr_map_t& emoji2descr = LLEmojiDictionary::instance().getEmoji2Descr(); LLEmojiSearchResult emoji { 0, "", 0, 0 }; - if (category == RECENTLY_USED_CATEGORY) - { - for (llwchar code : sRecentlyUsed) - { - const LLEmojiDictionary::emoji2descr_map_t::const_iterator& e2d = emoji2descr.find(code); - if (e2d != emoji2descr.end() && !e2d->second->ShortCodes.empty()) - { - emoji.Character = code; - emoji.String = e2d->second->ShortCodes.front(); - createEmojiIcon(emoji, category, row_panel_params, row_list_params, icon_params, - icon_rect, max_icons, bg, row, icon_index); - } - } - } - else if (category == FREQUENTLY_USED_CATEGORY) + if (category == FREQUENTLY_USED_CATEGORY) { for (const auto& code : sFrequentlyUsed) { diff --git a/indra/newview/llfloateremojipicker.h b/indra/newview/llfloateremojipicker.h index 669683eb9e..b807adb67d 100644 --- a/indra/newview/llfloateremojipicker.h +++ b/indra/newview/llfloateremojipicker.h @@ -60,7 +60,6 @@ public: private: void initialize(); void fillGroups(); - void fillCategoryRecentlyUsed(std::map<std::string, std::vector<LLEmojiSearchResult>>& cats); void fillCategoryFrequentlyUsed(std::map<std::string, std::vector<LLEmojiSearchResult>>& cats); void fillGroupEmojis(std::map<std::string, std::vector<LLEmojiSearchResult>>& cats, U32 index); void createGroupButton(LLButton::Params& params, const LLRect& rect, llwchar emoji); diff --git a/indra/newview/llfloaterimcontainer.cpp b/indra/newview/llfloaterimcontainer.cpp index e55bf50724..4fed8eebb8 100644 --- a/indra/newview/llfloaterimcontainer.cpp +++ b/indra/newview/llfloaterimcontainer.cpp @@ -1059,6 +1059,10 @@ void LLFloaterIMContainer::onCustomAction(const LLSD& userdata) { setSortOrderParticipants(LLConversationFilter::SO_DISTANCE); } + if ("put_nearby_session_first" == command) + { + gSavedSettings.setBOOL("IMNearbySessionFirst", !gSavedSettings.getBOOL("IMNearbySessionFirst")); + } if ("chat_preferences" == command) { LLFloaterPreference * floater_prefp = LLFloaterReg::showTypedInstance<LLFloaterPreference>("preferences"); @@ -1109,6 +1113,10 @@ bool LLFloaterIMContainer::isActionChecked(const LLSD& userdata) { return (order.getSortOrderParticipants() == LLConversationFilter::SO_DISTANCE); } + if ("put_nearby_session_first" == command) + { + return gSavedSettings.getBOOL("IMNearbySessionFirst"); + } if ("Translating.Enabled" == command) { return gSavedPerAccountSettings.getBOOL("TranslatingEnabled"); @@ -1939,7 +1947,7 @@ bool LLFloaterIMContainer::removeConversationListItem(const LLUUID& uuid, bool c mConversationEventQueue.erase(uuid); // Don't let the focus fall IW, select and refocus on the first conversation in the list - if (change_focus) + if (change_focus && isInVisibleChain()) { setFocus(true); if (new_selection) @@ -1959,6 +1967,10 @@ bool LLFloaterIMContainer::removeConversationListItem(const LLUUID& uuid, bool c } } } + else + { + LL_INFOS() << "Conversation widgets: " << (S32)mConversationsWidgets.size() << LL_ENDL; + } return is_widget_selected; } diff --git a/indra/newview/llfloaterimsessiontab.cpp b/indra/newview/llfloaterimsessiontab.cpp index af38d696bc..335aba2cc9 100644 --- a/indra/newview/llfloaterimsessiontab.cpp +++ b/indra/newview/llfloaterimsessiontab.cpp @@ -598,7 +598,8 @@ void LLFloaterIMSessionTab::deleteAllChildren() std::string LLFloaterIMSessionTab::appendTime() { std::string timeStr = "[" + LLTrans::getString("TimeHour") + "]:" - "[" + LLTrans::getString("TimeMin") + "]"; + "[" + LLTrans::getString("TimeMin") + "]:" + "[" + LLTrans::getString("TimeSec") + "]"; LLSD substitution; substitution["datetime"] = (S32)time_corrected(); @@ -633,7 +634,8 @@ void LLFloaterIMSessionTab::appendMessage(const LLChat& chat, const LLSD& args) chat_args["show_names_for_p2p_conv"] = !mIsP2PChat || gSavedSettings.getBOOL("IMShowNamesForP2PConv"); - mChatHistory->appendMessage(chat, chat_args); + static const LLStyle::Params input_append_params = LLStyle::Params(); + mChatHistory->appendMessage(chat, chat_args, input_append_params); } void LLFloaterIMSessionTab::updateUsedEmojis(LLWStringView text) diff --git a/indra/newview/llfloaterlagmeter.cpp b/indra/newview/llfloaterlagmeter.cpp index 28fa8dea9a..1377526f69 100644 --- a/indra/newview/llfloaterlagmeter.cpp +++ b/indra/newview/llfloaterlagmeter.cpp @@ -200,6 +200,7 @@ void LLFloaterLagMeter::determineNetwork() // the network handlers are de-synched from the rendering. F32Milliseconds client_frame_time = frame_recording.getPeriodMean(LLStatViewer::FRAME_STACKTIME); + // Todo: account for LLPacketRing dropped packets? viewer drops those when it can't keep up if(packet_loss >= mNetworkPacketLossCritical) { mNetworkButton->setImageUnselected(LLUI::getUIImage(LAG_CRITICAL_IMAGE_NAME)); diff --git a/indra/newview/llfloaterperformance.cpp b/indra/newview/llfloaterperformance.cpp index 315508f22b..3eb0c849d3 100644 --- a/indra/newview/llfloaterperformance.cpp +++ b/indra/newview/llfloaterperformance.cpp @@ -115,12 +115,12 @@ bool LLFloaterPerformance::postBuild() mHUDList = mHUDsPanel->getChild<LLNameListCtrl>("hud_list"); mHUDList->setNameListType(LLNameListCtrl::SPECIAL); mHUDList->setHoverIconName("StopReload_Off"); - mHUDList->setIconClickedCallback(boost::bind(&LLFloaterPerformance::detachItem, this, _1)); + mHUDList->setIconClickedCallback(boost::bind(&LLFloaterPerformance::detachObject, this, _1)); mObjectList = mComplexityPanel->getChild<LLNameListCtrl>("obj_list"); mObjectList->setNameListType(LLNameListCtrl::SPECIAL); mObjectList->setHoverIconName("StopReload_Off"); - mObjectList->setIconClickedCallback(boost::bind(&LLFloaterPerformance::detachItem, this, _1)); + mObjectList->setIconClickedCallback(boost::bind(&LLFloaterPerformance::detachObject, this, _1)); mSettingsPanel->getChild<LLButton>("advanced_btn")->setCommitCallback(boost::bind(&LLFloaterPerformance::onClickAdvanced, this)); mSettingsPanel->getChild<LLButton>("defaults_btn")->setCommitCallback(boost::bind(&LLFloaterPerformance::onClickDefaults, this)); @@ -527,9 +527,13 @@ void LLFloaterPerformance::setFPSText() mTextFPSLabel->setValue(fps_text); } -void LLFloaterPerformance::detachItem(const LLUUID& item_id) +void LLFloaterPerformance::detachObject(const LLUUID& obj_id) { - LLAppearanceMgr::instance().removeItemFromAvatar(item_id); + LLViewerObject* obj = gObjectList.findObject(obj_id); + if (obj) + { + LLAppearanceMgr::instance().removeItemFromAvatar(obj->getAttachmentItemID()); + } } void LLFloaterPerformance::onClickAdvanced() diff --git a/indra/newview/llfloaterperformance.h b/indra/newview/llfloaterperformance.h index a7100eb350..6cca85a009 100644 --- a/indra/newview/llfloaterperformance.h +++ b/indra/newview/llfloaterperformance.h @@ -48,7 +48,7 @@ public: void hidePanels(); void showAutoadjustmentsPanel(); - void detachItem(const LLUUID& item_id); + void detachObject(const LLUUID& obj_id); void onAvatarListRightClick(LLUICtrl* ctrl, S32 x, S32 y); diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp index e673752986..fdac390e8a 100644 --- a/indra/newview/llfloaterpreference.cpp +++ b/indra/newview/llfloaterpreference.cpp @@ -329,6 +329,7 @@ LLFloaterPreference::LLFloaterPreference(const LLSD& key) mCommitCallbackRegistrar.add("Pref.AutoAdjustments", boost::bind(&LLFloaterPreference::onClickAutoAdjustments, this)); mCommitCallbackRegistrar.add("Pref.HardwareDefaults", boost::bind(&LLFloaterPreference::setHardwareDefaults, this)); mCommitCallbackRegistrar.add("Pref.AvatarImpostorsEnable", boost::bind(&LLFloaterPreference::onAvatarImpostorsEnable, this)); + mCommitCallbackRegistrar.add("Pref.UpdateIndirectMaxNonImpostors", boost::bind(&LLFloaterPreference::updateMaxNonImpostors, this)); mCommitCallbackRegistrar.add("Pref.UpdateIndirectMaxComplexity", boost::bind(&LLFloaterPreference::updateMaxComplexity, this)); mCommitCallbackRegistrar.add("Pref.RenderOptionUpdate", boost::bind(&LLFloaterPreference::onRenderOptionEnable, this)); mCommitCallbackRegistrar.add("Pref.WindowedMod", boost::bind(&LLFloaterPreference::onCommitWindowedMode, this)); @@ -360,6 +361,7 @@ LLFloaterPreference::LLFloaterPreference(const LLSD& key) LLAvatarPropertiesProcessor::getInstance()->addObserver( gAgent.getID(), this ); mComplexityChangedSignal = gSavedSettings.getControl("RenderAvatarMaxComplexity")->getCommitSignal()->connect(boost::bind(&LLFloaterPreference::updateComplexityText, this)); + mImpostorsChangedSignal = gSavedSettings.getControl("RenderAvatarMaxNonImpostors")->getSignal()->connect(boost::bind(&LLFloaterPreference::updateIndirectMaxNonImpostors, this, _2)); mCommitCallbackRegistrar.add("Pref.ClearLog", boost::bind(&LLConversationLog::onClearLog, &LLConversationLog::instance())); mCommitCallbackRegistrar.add("Pref.DeleteTranscripts", boost::bind(&LLFloaterPreference::onDeleteTranscripts, this)); @@ -542,7 +544,12 @@ void LLFloaterPreference::onDoNotDisturbResponseChanged() LLFloaterPreference::~LLFloaterPreference() { LLConversationLog::instance().removeObserver(this); + if (LLAvatarPropertiesProcessor::instanceExists()) + { + LLAvatarPropertiesProcessor::getInstance()->removeObserver(gAgent.getID(), this); + } mComplexityChangedSignal.disconnect(); + mImpostorsChangedSignal.disconnect(); } void LLFloaterPreference::draw() @@ -1287,6 +1294,9 @@ void LLAvatarComplexityControls::setIndirectMaxArc() void LLFloaterPreference::refresh() { LLPanel::refresh(); + setMaxNonImpostorsText( + gSavedSettings.getU32("RenderAvatarMaxNonImpostors"), + getChild<LLTextBox>("IndirectMaxNonImpostorsText", true)); LLAvatarComplexityControls::setText( gSavedSettings.getU32("RenderAvatarMaxComplexity"), getChild<LLTextBox>("IndirectMaxComplexityText", true)); @@ -1561,6 +1571,44 @@ void LLAvatarComplexityControls::setRenderTimeText(F32 value, LLTextBox* text_bo } } +void LLFloaterPreference::updateMaxNonImpostors() +{ + // Called when the IndirectMaxNonImpostors control changes + // Responsible for fixing the slider label (IndirectMaxNonImpostorsText) and setting RenderAvatarMaxNonImpostors + LLSliderCtrl* ctrl = getChild<LLSliderCtrl>("IndirectMaxNonImpostors", true); + U32 value = ctrl->getValue().asInteger(); + + if (0 == value || LLVOAvatar::NON_IMPOSTORS_MAX_SLIDER <= value) + { + value = 0; + } + gSavedSettings.setU32("RenderAvatarMaxNonImpostors", value); + LLVOAvatar::updateImpostorRendering(value); // make it effective immediately + setMaxNonImpostorsText(value, getChild<LLTextBox>("IndirectMaxNonImpostorsText")); +} + +void LLFloaterPreference::updateIndirectMaxNonImpostors(const LLSD& newvalue) +{ + U32 value = newvalue.asInteger(); + if ((value != 0) && (value != gSavedSettings.getU32("IndirectMaxNonImpostors"))) + { + gSavedSettings.setU32("IndirectMaxNonImpostors", value); + } + setMaxNonImpostorsText(value, getChild<LLTextBox>("IndirectMaxNonImpostorsText")); +} + +void LLFloaterPreference::setMaxNonImpostorsText(U32 value, LLTextBox* text_box) +{ + if (0 == value) + { + text_box->setText(LLTrans::getString("no_limit")); + } + else + { + text_box->setText(llformat("%d", value)); + } +} + void LLFloaterPreference::updateMaxComplexity() { // Called when the IndirectMaxComplexity control changes diff --git a/indra/newview/llfloaterpreference.h b/indra/newview/llfloaterpreference.h index 51ed3d8179..fa9c421a8f 100644 --- a/indra/newview/llfloaterpreference.h +++ b/indra/newview/llfloaterpreference.h @@ -206,6 +206,9 @@ private: void onDeleteTranscripts(); void onDeleteTranscriptsResponse(const LLSD& notification, const LLSD& response); void updateDeleteTranscriptsButton(); + void updateMaxNonImpostors(); + void updateIndirectMaxNonImpostors(const LLSD& newvalue); + void setMaxNonImpostorsText(U32 value, LLTextBox* text_box); void updateMaxComplexity(); void updateComplexityText(); static bool loadFromFilename(const std::string& filename, std::map<std::string, std::string> &label_map); @@ -234,6 +237,7 @@ private: std::unique_ptr< ll::prefs::SearchData > mSearchData; bool mSearchDataDirty; + boost::signals2::connection mImpostorsChangedSignal; boost::signals2::connection mComplexityChangedSignal; void onUpdateFilterTerm( bool force = false ); diff --git a/indra/newview/llfloaterpreferencesgraphicsadvanced.cpp b/indra/newview/llfloaterpreferencesgraphicsadvanced.cpp index 8e8967ee3d..94b95b21c2 100644 --- a/indra/newview/llfloaterpreferencesgraphicsadvanced.cpp +++ b/indra/newview/llfloaterpreferencesgraphicsadvanced.cpp @@ -51,6 +51,8 @@ LLFloaterPreferenceGraphicsAdvanced::LLFloaterPreferenceGraphicsAdvanced(const L mCommitCallbackRegistrar.add("Pref.Cancel", boost::bind(&LLFloaterPreferenceGraphicsAdvanced::onBtnCancel, this, _2)); mCommitCallbackRegistrar.add("Pref.OK", boost::bind(&LLFloaterPreferenceGraphicsAdvanced::onBtnOK, this, _2)); + + mImpostorsChangedSignal = gSavedSettings.getControl("RenderAvatarMaxNonImpostors")->getSignal()->connect(boost::bind(&LLFloaterPreferenceGraphicsAdvanced::updateIndirectMaxNonImpostors, this, _2)); } LLFloaterPreferenceGraphicsAdvanced::~LLFloaterPreferenceGraphicsAdvanced() @@ -58,7 +60,6 @@ LLFloaterPreferenceGraphicsAdvanced::~LLFloaterPreferenceGraphicsAdvanced() mComplexityChangedSignal.disconnect(); mComplexityModeChangedSignal.disconnect(); mLODFactorChangedSignal.disconnect(); - mNumImpostorsChangedSignal.disconnect(); } bool LLFloaterPreferenceGraphicsAdvanced::postBuild() @@ -254,8 +255,8 @@ void LLFloaterPreferenceGraphicsAdvanced::updateIndirectMaxNonImpostors(const LL if ((value != 0) && (value != gSavedSettings.getU32("IndirectMaxNonImpostors"))) { gSavedSettings.setU32("IndirectMaxNonImpostors", value); - setMaxNonImpostorsText(value, getChild<LLTextBox>("IndirectMaxNonImpostorsText")); } + setMaxNonImpostorsText(value, getChild<LLTextBox>("IndirectMaxNonImpostorsText")); } void LLFloaterPreferenceGraphicsAdvanced::setMaxNonImpostorsText(U32 value, LLTextBox* text_box) @@ -273,7 +274,9 @@ void LLFloaterPreferenceGraphicsAdvanced::setMaxNonImpostorsText(U32 value, LLTe void LLFloaterPreferenceGraphicsAdvanced::disableUnavailableSettings() { LLComboBox* ctrl_shadows = getChild<LLComboBox>("ShadowDetail"); + LLComboBox* ctrl_shadows_quality = getChild<LLComboBox>("MPShadowQuality"); LLTextBox* shadows_text = getChild<LLTextBox>("RenderShadowDetailText"); + LLTextBox* shadows_quality_text = getChild<LLTextBox>("RenderShadowQualityText"); LLCheckBoxCtrl* ctrl_ssao = getChild<LLCheckBoxCtrl>("UseSSAO"); LLCheckBoxCtrl* ctrl_dof = getChild<LLCheckBoxCtrl>("UseDoF"); LLSliderCtrl* sky = getChild<LLSliderCtrl>("SkyMeshDetail"); @@ -289,7 +292,9 @@ void LLFloaterPreferenceGraphicsAdvanced::disableUnavailableSettings() //deferred needs windlight, disable deferred ctrl_shadows->setEnabled(false); ctrl_shadows->setValue(0); + ctrl_shadows_quality->setEnabled(false); shadows_text->setEnabled(false); + shadows_quality_text->setEnabled(false); ctrl_ssao->setEnabled(false); ctrl_ssao->setValue(false); @@ -303,7 +308,9 @@ void LLFloaterPreferenceGraphicsAdvanced::disableUnavailableSettings() { ctrl_shadows->setEnabled(false); ctrl_shadows->setValue(0); + ctrl_shadows_quality->setEnabled(false); shadows_text->setEnabled(false); + shadows_quality_text->setEnabled(false); ctrl_ssao->setEnabled(false); ctrl_ssao->setValue(false); @@ -324,7 +331,9 @@ void LLFloaterPreferenceGraphicsAdvanced::disableUnavailableSettings() { ctrl_shadows->setEnabled(false); ctrl_shadows->setValue(0); + ctrl_shadows_quality->setEnabled(false); shadows_text->setEnabled(false); + shadows_quality_text->setEnabled(false); } // Vintage mode @@ -354,7 +363,9 @@ void LLFloaterPreferenceGraphicsAdvanced::refreshEnabledState() LLCheckBoxCtrl* ctrl_ssao = getChild<LLCheckBoxCtrl>("UseSSAO"); LLCheckBoxCtrl* ctrl_dof = getChild<LLCheckBoxCtrl>("UseDoF"); LLComboBox* ctrl_shadow = getChild<LLComboBox>("ShadowDetail"); + LLComboBox* ctrl_shadow_quality = getChild<LLComboBox>("MPShadowQuality"); LLTextBox* shadow_text = getChild<LLTextBox>("RenderShadowDetailText"); + LLTextBox* shadows_quality_text = getChild<LLTextBox>("RenderShadowQualityText"); // note, okay here to get from ctrl_deferred as it's twin, ctrl_deferred2 will alway match it enabled = enabled && LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferredSSAO");// && ctrl_deferred->get(); @@ -367,7 +378,9 @@ void LLFloaterPreferenceGraphicsAdvanced::refreshEnabledState() enabled = enabled && LLFeatureManager::getInstance()->isFeatureAvailable("RenderShadowDetail"); ctrl_shadow->setEnabled(enabled); + ctrl_shadow_quality->setEnabled(enabled); shadow_text->setEnabled(enabled); + shadows_quality_text->setEnabled(enabled); // Hardware settings diff --git a/indra/newview/llfloaterpreferencesgraphicsadvanced.h b/indra/newview/llfloaterpreferencesgraphicsadvanced.h index 61203be068..a1a54f238d 100644 --- a/indra/newview/llfloaterpreferencesgraphicsadvanced.h +++ b/indra/newview/llfloaterpreferencesgraphicsadvanced.h @@ -61,6 +61,7 @@ protected: void onBtnOK(const LLSD& userdata); void onBtnCancel(const LLSD& userdata); + boost::signals2::connection mImpostorsChangedSignal; boost::signals2::connection mComplexityChangedSignal; boost::signals2::connection mComplexityModeChangedSignal; boost::signals2::connection mLODFactorChangedSignal; diff --git a/indra/newview/llfloaterregioninfo.cpp b/indra/newview/llfloaterregioninfo.cpp index 3239921259..2d972ea3f5 100644 --- a/indra/newview/llfloaterregioninfo.cpp +++ b/indra/newview/llfloaterregioninfo.cpp @@ -851,6 +851,13 @@ void LLPanelRegionInfo::initCtrl(const std::string& name) getChild<LLUICtrl>(name)->setCommitCallback(boost::bind(&LLPanelRegionInfo::onChangeAnything, this)); } +void LLPanelRegionInfo::initAndSetTexCtrl(LLTextureCtrl*& ctrl, const std::string& name) +{ + ctrl = findChild<LLTextureCtrl>(name); + if (ctrl) + ctrl->setOnSelectCallback([this](LLUICtrl* ctrl, const LLSD& param){ onChangeAnything(); }); +} + template<typename CTRL> void LLPanelRegionInfo::initAndSetCtrl(CTRL*& ctrl, const std::string& name) { @@ -1580,7 +1587,7 @@ bool LLPanelRegionTerrainInfo::postBuild() for(S32 i = 0; i < LLTerrainMaterials::ASSET_COUNT; ++i) { - initAndSetCtrl(mTextureDetailCtrl[i], llformat("texture_detail_%d", i)); + initAndSetTexCtrl(mTextureDetailCtrl[i], llformat("texture_detail_%d", i)); if (mTextureDetailCtrl[i]) { mTextureDetailCtrl[i]->setBakeTextureEnabled(false); @@ -4346,7 +4353,6 @@ void LLPanelRegionEnvironment::onChkAllowOverride(bool value) mAllowOverrideRestore = mAllowOverride; mAllowOverride = value; - std::string notification("EstateParcelEnvironmentOverride"); if (LLPanelEstateInfo::isLindenEstate()) notification = "ChangeLindenEstate"; diff --git a/indra/newview/llfloaterregioninfo.h b/indra/newview/llfloaterregioninfo.h index 201d8b0a68..a8631c36ca 100644 --- a/indra/newview/llfloaterregioninfo.h +++ b/indra/newview/llfloaterregioninfo.h @@ -159,6 +159,7 @@ public: protected: void initCtrl(const std::string& name); template<typename CTRL> void initAndSetCtrl(CTRL*& ctrl, const std::string& name); + void initAndSetTexCtrl(LLTextureCtrl*& ctrl, const std::string& name); // Returns true if update sent and apply button should be // disabled. diff --git a/indra/newview/llfloaterslapptest.cpp b/indra/newview/llfloaterslapptest.cpp new file mode 100644 index 0000000000..0075379529 --- /dev/null +++ b/indra/newview/llfloaterslapptest.cpp @@ -0,0 +1,51 @@ +/** + * @file llfloaterslapptest.cpp + * + * $LicenseInfo:firstyear=2025&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2025, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" + +#include "llfloaterslapptest.h" +#include "lluictrlfactory.h" + +#include "lllineeditor.h" +#include "lltextbox.h" + +LLFloaterSLappTest::LLFloaterSLappTest(const LLSD& key) + : LLFloater("floater_test_slapp") +{ +} + +LLFloaterSLappTest::~LLFloaterSLappTest() +{} + +bool LLFloaterSLappTest::postBuild() +{ + getChild<LLLineEditor>("remove_folder_id")->setKeystrokeCallback([this](LLLineEditor* editor, void*) + { + std::string slapp(getString("remove_folder_slapp")); + getChild<LLTextBox>("remove_folder_txt")->setValue(slapp + editor->getValue().asString()); + }, NULL); + + return true; +} diff --git a/indra/newview/llfloaterslapptest.h b/indra/newview/llfloaterslapptest.h new file mode 100644 index 0000000000..ec727cb629 --- /dev/null +++ b/indra/newview/llfloaterslapptest.h @@ -0,0 +1,42 @@ +/** + * @file llfloaterslapptest.h + * + * $LicenseInfo:firstyear=2025&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2025, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#ifndef LL_LLFLOATERSLAPPTEST_H +#define LL_LLFLOATERSLAPPTEST_H + +#include "llfloater.h" + +class LLFloaterSLappTest: + public LLFloater +{ + friend class LLFloaterReg; + virtual bool postBuild() override; + +private: + LLFloaterSLappTest(const LLSD& key); + ~LLFloaterSLappTest(); +}; + +#endif diff --git a/indra/newview/llfloatersnapshot.cpp b/indra/newview/llfloatersnapshot.cpp index fb4537f22a..68b9e758a1 100644 --- a/indra/newview/llfloatersnapshot.cpp +++ b/indra/newview/llfloatersnapshot.cpp @@ -60,6 +60,10 @@ LLPanelSnapshot* LLFloaterSnapshot::Impl::getActivePanel(LLFloaterSnapshotBase* { LLSideTrayPanelContainer* panel_container = floater->getChild<LLSideTrayPanelContainer>("panel_container"); LLPanelSnapshot* active_panel = dynamic_cast<LLPanelSnapshot*>(panel_container->getCurrentPanel()); + if (!active_panel) + { + LL_WARNS() << "No snapshot active panel, current panel index: " << panel_container->getCurrentPanelIndex() << LL_ENDL; + } if (!ok_if_not_found) { llassert_always(active_panel != NULL); @@ -643,20 +647,18 @@ void LLFloaterSnapshotBase::ImplBase::setWorking(bool working) working_lbl->setVisible(working); mFloater->getChild<LLUICtrl>("working_indicator")->setVisible(working); - if (working) - { - const std::string panel_name = getActivePanel(mFloater, false)->getName(); - const std::string prefix = panel_name.substr(getSnapshotPanelPrefix().size()); - std::string progress_text = mFloater->getString(prefix + "_" + "progress_str"); - working_lbl->setValue(progress_text); - } - // All controls should be disabled while posting. mFloater->setCtrlsEnabled(!working); - LLPanelSnapshot* active_panel = getActivePanel(mFloater); - if (active_panel) + if (LLPanelSnapshot* active_panel = getActivePanel(mFloater)) { active_panel->enableControls(!working); + if (working) + { + const std::string panel_name = active_panel->getName(); + const std::string prefix = panel_name.substr(getSnapshotPanelPrefix().size()); + std::string progress_text = mFloater->getString(prefix + "_" + "progress_str"); + working_lbl->setValue(progress_text); + } } } diff --git a/indra/newview/llfloatertos.cpp b/indra/newview/llfloatertos.cpp index 8eec5b753a..63ba51e559 100644 --- a/indra/newview/llfloatertos.cpp +++ b/indra/newview/llfloatertos.cpp @@ -96,6 +96,8 @@ bool LLFloaterTOS::postBuild() external_prompt->setVisible(true); web_browser->setVisible(false); + + updateAgreeEnabled(true); #else web_browser->addObserver(this); diff --git a/indra/newview/llfloateruipreview.cpp b/indra/newview/llfloateruipreview.cpp index 990a299c50..9bc075d03f 100644 --- a/indra/newview/llfloateruipreview.cpp +++ b/indra/newview/llfloateruipreview.cpp @@ -72,6 +72,7 @@ #if LL_DARWIN #include <CoreFoundation/CFURL.h> +#include <CoreFoundation/CFBundle.h> #endif // Static initialization diff --git a/indra/newview/llgiveinventory.cpp b/indra/newview/llgiveinventory.cpp index 1259b65ebe..57dd203f2f 100644 --- a/indra/newview/llgiveinventory.cpp +++ b/indra/newview/llgiveinventory.cpp @@ -414,7 +414,11 @@ void LLGiveInventory::commitGiveInventoryItem(const LLUUID& to_agent, effectp->setTargetObject(gObjectList.findObject(to_agent)); effectp->setDuration(LL_HUD_DUR_SHORT); effectp->setColor(LLColor4U(gAgent.getEffectColor())); - gFloaterTools->dirty(); + + if (gFloaterTools) + { + gFloaterTools->dirty(); + } LLMuteList::getInstance()->autoRemove(to_agent, LLMuteList::AR_INVENTORY); @@ -572,7 +576,11 @@ bool LLGiveInventory::commitGiveInventoryCategory(const LLUUID& to_agent, effectp->setTargetObject(gObjectList.findObject(to_agent)); effectp->setDuration(LL_HUD_DUR_SHORT); effectp->setColor(LLColor4U(gAgent.getEffectColor())); - gFloaterTools->dirty(); + + if (gFloaterTools) + { + gFloaterTools->dirty(); + } LLMuteList::getInstance()->autoRemove(to_agent, LLMuteList::AR_INVENTORY); diff --git a/indra/newview/llgltfmateriallist.cpp b/indra/newview/llgltfmateriallist.cpp index 25438eae5e..d8b3f996aa 100644 --- a/indra/newview/llgltfmateriallist.cpp +++ b/indra/newview/llgltfmateriallist.cpp @@ -353,6 +353,18 @@ void LLGLTFMaterialList::queueApply(const LLViewerObject* obj, S32 side, const L } } +void LLGLTFMaterialList::queueApply(const LLViewerObject* obj, S32 side, const LLUUID& asset_id, const std::string &override_json) +{ + if (asset_id.isNull() || override_json.empty()) + { + queueApply(obj, side, asset_id); + } + else + { + sApplyQueue.push_back({ obj->getID(), side, asset_id, nullptr, override_json }); + } +} + void LLGLTFMaterialList::queueApply(const LLViewerObject* obj, S32 side, const LLUUID& asset_id, const LLGLTFMaterial* material_override) { if (asset_id.isNull() || material_override == nullptr) @@ -456,6 +468,10 @@ void LLGLTFMaterialList::flushUpdatesOnce(std::shared_ptr<CallbackHolder> callba { data[i]["gltf_json"] = e.override_data->asJSON(); } + if (!e.override_json.empty()) + { + data[i]["gltf_json"] = e.override_json; + } else { // Clear all overrides diff --git a/indra/newview/llgltfmateriallist.h b/indra/newview/llgltfmateriallist.h index e79da3592a..97d173d3a7 100644 --- a/indra/newview/llgltfmateriallist.h +++ b/indra/newview/llgltfmateriallist.h @@ -67,6 +67,7 @@ public: // // NOTE: Implicitly clears most override data if present static void queueApply(const LLViewerObject* obj, S32 side, const LLUUID& asset_id); + static void queueApply(const LLViewerObject* obj, S32 side, const LLUUID& asset_id, const std::string& override_json); // Queue an application of a material asset we want to send to the simulator. // Call "flushUpdates" to flush pending updates immediately. @@ -160,6 +161,7 @@ protected: S32 side = -1; LLUUID asset_id; LLPointer<LLGLTFMaterial> override_data; + std::string override_json; }; typedef std::list<ApplyMaterialAssetData> apply_queue_t; diff --git a/indra/newview/llgltfmaterialpreviewmgr.cpp b/indra/newview/llgltfmaterialpreviewmgr.cpp index cf6b08797d..da1f1a466f 100644 --- a/indra/newview/llgltfmaterialpreviewmgr.cpp +++ b/indra/newview/llgltfmaterialpreviewmgr.cpp @@ -472,9 +472,9 @@ bool LLGLTFPreviewTexture::render() gPipeline.setupHWLights(); glm::mat4 mat = get_current_modelview(); - glm::vec4 transformed_light_dir = glm::make_vec4(light_dir.mV); + glm::vec4 transformed_light_dir(light_dir); transformed_light_dir = mat * transformed_light_dir; - SetTemporarily<LLVector4> force_sun_direction_high_graphics(&gPipeline.mTransformedSunDir, LLVector4(glm::value_ptr(transformed_light_dir))); + SetTemporarily<LLVector4> force_sun_direction_high_graphics(&gPipeline.mTransformedSunDir, LLVector4(transformed_light_dir)); // Override lights to ensure the sun is always shining from a certain direction (low graphics) // See also force_sun_direction_high_graphics and fixup_shader_constants { diff --git a/indra/newview/llheroprobemanager.cpp b/indra/newview/llheroprobemanager.cpp index ce419498cf..343bb01072 100644 --- a/indra/newview/llheroprobemanager.cpp +++ b/indra/newview/llheroprobemanager.cpp @@ -80,6 +80,17 @@ void LLHeroProbeManager::update() return; } + // Part of a hacky workaround to fix #3331. + // For some reason clearing shaders will cause mirrors to actually work. + // There's likely some deeper state issue that needs to be resolved. + // - Geenz 2025-02-25 + if (!mInitialized && LLStartUp::getStartupState() > STATE_PRECACHE) + { + LLViewerShaderMgr::instance()->clearShaderCache(); + LLViewerShaderMgr::instance()->setShaders(); + mInitialized = true; + } + LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY; llassert(!gCubeSnapshot); // assert a snapshot is not in progress if (LLAppViewer::instance()->logoutRequestSent()) @@ -89,9 +100,11 @@ void LLHeroProbeManager::update() initReflectionMaps(); + static LLCachedControl<bool> render_hdr(gSavedSettings, "RenderHDREnabled", true); + if (!mRenderTarget.isComplete()) { - U32 color_fmt = GL_RGBA16F; + U32 color_fmt = render_hdr ? GL_RGBA16F : GL_RGBA8; mRenderTarget.allocate(mProbeResolution, mProbeResolution, color_fmt, true); } @@ -103,7 +116,7 @@ void LLHeroProbeManager::update() mMipChain.resize(count); for (U32 i = 0; i < count; ++i) { - mMipChain[i].allocate(res, res, GL_RGBA16F); + mMipChain[i].allocate(res, res, render_hdr ? GL_RGBA16F : GL_RGBA8); res /= 2; } } @@ -220,7 +233,7 @@ void LLHeroProbeManager::renderProbes() static LLCachedControl<S32> sUpdateRate(gSavedSettings, "RenderHeroProbeUpdateRate", 0); F32 near_clip = 0.01f; - if (mNearestHero != nullptr && + if (mNearestHero != nullptr && !mNearestHero->isDead() && !gTeleportDisplay && !gDisconnected && !LLAppViewer::instance()->logoutRequestSent()) { LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("hpmu - realtime"); @@ -249,12 +262,13 @@ void LLHeroProbeManager::renderProbes() LL_PROFILE_ZONE_NUM(gFrameCount % rate); LL_PROFILE_ZONE_NUM(rate); + bool dynamic = mNearestHero->getReflectionProbeIsDynamic() && sDetail() > 0; for (U32 i = 0; i < 6; ++i) { if ((gFrameCount % rate) == (i % rate)) { // update 6/rate faces per frame LL_PROFILE_ZONE_NUM(i); - updateProbeFace(mProbes[0], i, mNearestHero->getReflectionProbeIsDynamic() && sDetail > 0, near_clip); + updateProbeFace(mProbes[0], i, dynamic, near_clip); } } generateRadiance(mProbes[0]); @@ -414,8 +428,10 @@ void LLHeroProbeManager::generateRadiance(LLReflectionMap* probe) gHeroRadianceGenProgram.bind(); mVertexBuffer->setBuffer(); +#if GL_VERSION_4_0 S32 channel = gHeroRadianceGenProgram.enableTexture(LLShaderMgr::REFLECTION_PROBES, LLTexUnit::TT_CUBE_MAP_ARRAY); mTexture->bind(channel); +#endif gHeroRadianceGenProgram.uniform1i(sSourceIdx, sourceIdx); gHeroRadianceGenProgram.uniform1f(LLShaderMgr::REFLECTION_PROBE_MAX_LOD, mMaxProbeLOD); gHeroRadianceGenProgram.uniform1f(LLShaderMgr::REFLECTION_PROBE_STRENGTH, mHeroProbeStrength); @@ -537,8 +553,10 @@ void LLHeroProbeManager::initReflectionMaps() mTexture = new LLCubeMapArray(); + static LLCachedControl<bool> render_hdr(gSavedSettings, "RenderHDREnabled", true); + // store mReflectionProbeCount+2 cube maps, final two cube maps are used for render target and radiance map generation source) - mTexture->allocate(mProbeResolution, 3, mReflectionProbeCount + 2); + mTexture->allocate(mProbeResolution, 3, mReflectionProbeCount + 2, true, render_hdr); if (mDefaultProbe.isNull()) { diff --git a/indra/newview/llheroprobemanager.h b/indra/newview/llheroprobemanager.h index 58a94a3de8..2737ec5ddf 100644 --- a/indra/newview/llheroprobemanager.h +++ b/indra/newview/llheroprobemanager.h @@ -144,6 +144,7 @@ private: std::vector<LLPointer<LLVOVolume>> mHeroVOList; LLPointer<LLVOVolume> mNearestHero; - + // Part of a hacky workaround to fix #3331. + bool mInitialized = false; }; diff --git a/indra/newview/llhttpretrypolicy.cpp b/indra/newview/llhttpretrypolicy.cpp index 3e55030610..c5692554c6 100644 --- a/indra/newview/llhttpretrypolicy.cpp +++ b/indra/newview/llhttpretrypolicy.cpp @@ -91,14 +91,14 @@ void LLAdaptiveRetryPolicy::onSuccess() void LLAdaptiveRetryPolicy::onFailure(S32 status, const LLSD& headers) { - F32 retry_header_time; + F32 retry_header_time{}; bool has_retry_header_time = getRetryAfter(headers,retry_header_time); onFailureCommon(status, has_retry_header_time, retry_header_time); } void LLAdaptiveRetryPolicy::onFailure(const LLCore::HttpResponse *response) { - F32 retry_header_time; + F32 retry_header_time{}; const LLCore::HttpHeaders::ptr_t headers = response->getHeaders(); bool has_retry_header_time = getRetryAfter(headers,retry_header_time); onFailureCommon(response->getStatus().getType(), has_retry_header_time, retry_header_time); @@ -184,4 +184,3 @@ bool LLAdaptiveRetryPolicy::getSecondsUntilRetryAfter(const std::string& retry_a return true; } - diff --git a/indra/newview/llhudrender.cpp b/indra/newview/llhudrender.cpp index 135fba7897..6850e57b94 100644 --- a/indra/newview/llhudrender.cpp +++ b/indra/newview/llhudrender.cpp @@ -106,7 +106,7 @@ void hud_render_text(const LLWString &wstr, const LLVector3 &pos_agent, LLRect world_view_rect = gViewerWindow->getWorldViewRectRaw(); glm::ivec4 viewport(world_view_rect.mLeft, world_view_rect.mBottom, world_view_rect.getWidth(), world_view_rect.getHeight()); - glm::vec3 win_coord = glm::project(glm::make_vec3(render_pos.mV), get_current_modelview(), get_current_projection(), viewport); + glm::vec3 win_coord = glm::project(glm::vec3(render_pos), get_current_modelview(), get_current_projection(), viewport); //fonts all render orthographically, set up projection`` gGL.matrixMode(LLRender::MM_PROJECTION); diff --git a/indra/newview/llimprocessing.cpp b/indra/newview/llimprocessing.cpp index 590cd09a31..4e8bcc4f7a 100644 --- a/indra/newview/llimprocessing.cpp +++ b/indra/newview/llimprocessing.cpp @@ -650,14 +650,6 @@ void LLIMProcessing::processNewMessage(LLUUID from_id, asset_type = (LLAssetType::EType)(atoi((*(iter++)).c_str())); iter++; // wearable type if applicable, otherwise asset type item_name = std::string((*(iter++)).c_str()); - // Note There is more elements in 'tokens' ... - - - for (int i = 0; i < 6; i++) - { - LL_WARNS() << *(iter++) << LL_ENDL; - iter++; - } } } else diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp index 34a4b5b230..756f3b33ed 100644 --- a/indra/newview/llimview.cpp +++ b/indra/newview/llimview.cpp @@ -24,6 +24,8 @@ * $/LicenseInfo$ */ +#include <array> + #include "llviewerprecompiledheaders.h" #include "llimview.h" @@ -3192,6 +3194,7 @@ void LLIMMgr::addMessage( if (session) { skip_message &= !session->isGroupSessionType(); // Do not skip group chats... + skip_message |= LLMuteList::getInstance()->isMuted(LLUUID::null, std::string{"Group:" + new_session_id.asString()}); // unless the group is muted. if (skip_message) { gIMMgr->leaveSession(new_session_id); @@ -3550,6 +3553,7 @@ void LLIMMgr::inviteToSession( && voice_invite && "VoiceInviteQuestionDefault" == question_type) { LL_INFOS("IMVIEW") << "Rejecting voice call from initiating muted resident " << caller_name << LL_ENDL; + payload["voice_channel_info"] = voice_channel_info; LLIncomingCallDialog::processCallResponse(1, payload); return; } @@ -3598,6 +3602,7 @@ void LLIMMgr::inviteToSession( send_do_not_disturb_message(gMessageSystem, caller_id, session_id); } // silently decline the call + payload["voice_channel_info"] = voice_channel_info; LLIncomingCallDialog::processCallResponse(1, payload); return; } diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp index 2e8b1b94fe..15190854a2 100644 --- a/indra/newview/llinventorybridge.cpp +++ b/indra/newview/llinventorybridge.cpp @@ -844,7 +844,7 @@ void LLInvFVBridge::getClipboardEntries(bool show_asset_id, disabled_items.push_back(std::string("Copy")); } - if (isAgentInventory() && !single_folder_root) + if (isAgentInventory() && !single_folder_root && !isMarketplaceListingsFolder()) { items.push_back(std::string("New folder from selected")); items.push_back(std::string("Subfolder Separator")); @@ -3599,6 +3599,13 @@ void LLFolderBridge::performAction(LLInventoryModel* model, std::string action) const LLUUID &marketplacelistings_id = model->findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS); move_folder_to_marketplacelistings(cat, marketplacelistings_id, ("move_to_marketplace_listings" != action), (("copy_or_move_to_marketplace_listings" == action))); } + else if ("copy_folder_uuid" == action) + { + LLInventoryCategory* cat = gInventory.getCategory(mUUID); + if (!cat) return; + gViewerWindow->getWindow()->copyTextToClipboard(utf8str_to_wstring(mUUID.asString())); + return; + } } void LLFolderBridge::gatherMessage(std::string& message, S32 depth, LLError::ELevel log_level) @@ -4231,14 +4238,9 @@ void LLFolderBridge::staticFolderOptionsMenu() bool LLFolderBridge::checkFolderForContentsOfType(LLInventoryModel* model, LLInventoryCollectFunctor& is_type) { - LLInventoryModel::cat_array_t cat_array; - LLInventoryModel::item_array_t item_array; - model->collectDescendentsIf(mUUID, - cat_array, - item_array, + return model->hasMatchingDescendents(mUUID, LLInventoryModel::EXCLUDE_TRASH, is_type); - return !item_array.empty(); } void LLFolderBridge::buildContextMenuOptions(U32 flags, menuentry_vec_t& items, menuentry_vec_t& disabled_items) @@ -4415,22 +4417,29 @@ void LLFolderBridge::buildContextMenuOptions(U32 flags, menuentry_vec_t& items //Added by aura to force inventory pull on right-click to display folder options correctly. 07-17-06 mCallingCards = mWearables = false; - LLIsType is_callingcard(LLAssetType::AT_CALLINGCARD); - if (checkFolderForContentsOfType(model, is_callingcard)) + if (gInventory.getRootFolderID() != mUUID) { - mCallingCards=true; - } + LLIsType is_callingcard(LLAssetType::AT_CALLINGCARD); + if (checkFolderForContentsOfType(model, is_callingcard)) + { + mCallingCards = true; + } - LLFindWearables is_wearable; - LLIsType is_object( LLAssetType::AT_OBJECT ); - LLIsType is_gesture( LLAssetType::AT_GESTURE ); + const std::vector<LLAssetType::EType> types = { LLAssetType::AT_CLOTHING, LLAssetType::AT_BODYPART, LLAssetType::AT_OBJECT, LLAssetType::AT_GESTURE }; + LLIsOneOfTypes is_wearable(types); - if (checkFolderForContentsOfType(model, is_wearable) || - checkFolderForContentsOfType(model, is_object) || - checkFolderForContentsOfType(model, is_gesture) ) + if (checkFolderForContentsOfType(model, is_wearable)) + { + mWearables = true; + } + } + else { - mWearables=true; + // Assume that there are wearables in the root folder + mWearables = true; } + + items.push_back(std::string("Set favorite folder")); } else { @@ -4442,13 +4451,10 @@ void LLFolderBridge::buildContextMenuOptions(U32 flags, menuentry_vec_t& items LLFolderType::EType type = category->getPreferredType(); const bool is_system_folder = LLFolderType::lookupIsProtectedType(type); - LLFindWearables is_wearable; - LLIsType is_object(LLAssetType::AT_OBJECT); - LLIsType is_gesture(LLAssetType::AT_GESTURE); + const std::vector<LLAssetType::EType> types = { LLAssetType::AT_CLOTHING, LLAssetType::AT_BODYPART, LLAssetType::AT_OBJECT, LLAssetType::AT_GESTURE }; + LLIsOneOfTypes is_wearable(types); - if (checkFolderForContentsOfType(model, is_wearable) || - checkFolderForContentsOfType(model, is_object) || - checkFolderForContentsOfType(model, is_gesture)) + if (checkFolderForContentsOfType(model, is_wearable)) { mWearables = true; } @@ -4469,6 +4475,14 @@ void LLFolderBridge::buildContextMenuOptions(U32 flags, menuentry_vec_t& items { disabled_items.push_back(std::string("Delete System Folder")); } + else + { + static LLCachedControl<bool> show_copy_id(gSavedSettings, "InventoryExposeFolderID", false); + if (show_copy_id()) + { + items.push_back(std::string("Copy UUID")); + } + } if (isAgentInventory() && !isMarketplaceListingsFolder()) { @@ -4571,14 +4585,11 @@ void LLFolderBridge::buildContextMenuFolderOptions(U32 flags, menuentry_vec_t& // wearables related functionality for folders. //is_wearable - LLFindWearables is_wearable; - LLIsType is_object( LLAssetType::AT_OBJECT ); - LLIsType is_gesture( LLAssetType::AT_GESTURE ); + const std::vector<LLAssetType::EType> types = { LLAssetType::AT_CLOTHING, LLAssetType::AT_BODYPART, LLAssetType::AT_OBJECT, LLAssetType::AT_GESTURE }; + LLIsOneOfTypes is_wearable(types); if (mWearables || - checkFolderForContentsOfType(model, is_wearable) || - checkFolderForContentsOfType(model, is_object) || - checkFolderForContentsOfType(model, is_gesture) ) + checkFolderForContentsOfType(model, is_wearable)) { // Only enable add/replace outfit for non-system folders. if (!is_system_folder) @@ -5321,7 +5332,7 @@ void LLFolderBridge::dropToMyOutfits(LLInventoryCategory* inv_cat, LLPointer<LLI // Note: creation will take time, so passing folder id to callback is slightly unreliable, // but so is collecting and passing descendants' ids - inventory_func_type func = boost::bind(&LLFolderBridge::outfitFolderCreatedCallback, this, inv_cat->getUUID(), _1, cb); + inventory_func_type func = boost::bind(outfitFolderCreatedCallback, inv_cat->getUUID(), _1, cb, mInventoryPanel); gInventory.createNewCategory(dest_id, LLFolderType::FT_OUTFIT, inv_cat->getName(), @@ -5329,11 +5340,25 @@ void LLFolderBridge::dropToMyOutfits(LLInventoryCategory* inv_cat, LLPointer<LLI inv_cat->getThumbnailUUID()); } -void LLFolderBridge::outfitFolderCreatedCallback(LLUUID cat_source_id, LLUUID cat_dest_id, LLPointer<LLInventoryCallback> cb) +void LLFolderBridge::outfitFolderCreatedCallback(LLUUID cat_source_id, + LLUUID cat_dest_id, + LLPointer<LLInventoryCallback> cb, + LLHandle<LLInventoryPanel> inventory_panel) { LLInventoryModel::cat_array_t* categories; LLInventoryModel::item_array_t* items; - getInventoryModel()->getDirectDescendentsOf(cat_source_id, categories, items); + + LLInventoryPanel* panel = inventory_panel.get(); + if (!panel) + { + return; + } + LLInventoryModel* model = panel->getModel(); + if (!model) + { + return; + } + model->getDirectDescendentsOf(cat_source_id, categories, items); LLInventoryObject::const_object_list_t link_array; diff --git a/indra/newview/llinventorybridge.h b/indra/newview/llinventorybridge.h index 746b79ce87..3e7f74384b 100644 --- a/indra/newview/llinventorybridge.h +++ b/indra/newview/llinventorybridge.h @@ -378,7 +378,10 @@ public: static void staticFolderOptionsMenu(); protected: - void outfitFolderCreatedCallback(LLUUID cat_source_id, LLUUID cat_dest_id, LLPointer<LLInventoryCallback> cb); + static void outfitFolderCreatedCallback(LLUUID cat_source_id, + LLUUID cat_dest_id, + LLPointer<LLInventoryCallback> cb, + LLHandle<LLInventoryPanel> inventory_panel); void callback_pasteFromClipboard(const LLSD& notification, const LLSD& response); void perform_pasteFromClipboard(); void gatherMessage(std::string& message, S32 depth, LLError::ELevel log_level); diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp index dadd0590a9..1ccefa3212 100644 --- a/indra/newview/llinventoryfunctions.cpp +++ b/indra/newview/llinventoryfunctions.cpp @@ -2634,6 +2634,22 @@ bool LLIsType::operator()(LLInventoryCategory* cat, LLInventoryItem* item) return false; } +bool LLIsOneOfTypes::operator()(LLInventoryCategory* cat, LLInventoryItem* item) +{ + for (LLAssetType::EType &type : mTypes) + { + if (type == LLAssetType::AT_CATEGORY) + { + if (cat) return true; + } + if (item) + { + if (item->getType() == type) return true; + } + } + return false; +} + bool LLIsNotType::operator()(LLInventoryCategory* cat, LLInventoryItem* item) { if(mType == LLAssetType::AT_CATEGORY) diff --git a/indra/newview/llinventoryfunctions.h b/indra/newview/llinventoryfunctions.h index a25c0d5ad6..13a64f21dc 100644 --- a/indra/newview/llinventoryfunctions.h +++ b/indra/newview/llinventoryfunctions.h @@ -246,6 +246,24 @@ protected: }; //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// Class LLIsOneOfTypes +// +// Implementation of a LLInventoryCollectFunctor which returns true if +// the type is one of the types passed in during construction. +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +class LLIsOneOfTypes : public LLInventoryCollectFunctor +{ +public: + LLIsOneOfTypes(const std::vector<LLAssetType::EType> &types) : mTypes(types) {} + virtual ~LLIsOneOfTypes() {} + virtual bool operator()(LLInventoryCategory* cat, + LLInventoryItem* item); +protected: + std::vector <LLAssetType::EType> mTypes; +}; + +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Class LLIsNotType // // Implementation of a LLInventoryCollectFunctor which returns false if the diff --git a/indra/newview/llinventorygallerymenu.cpp b/indra/newview/llinventorygallerymenu.cpp index dbf4821ca1..0c35a7f695 100644 --- a/indra/newview/llinventorygallerymenu.cpp +++ b/indra/newview/llinventorygallerymenu.cpp @@ -92,6 +92,7 @@ LLContextMenu* LLInventoryGalleryContextMenu::createMenu() registrar.add("Inventory.DoToSelected", boost::bind(&LLInventoryGalleryContextMenu::doToSelected, this, _2)); registrar.add("Inventory.FileUploadLocation", boost::bind(&LLInventoryGalleryContextMenu::fileUploadLocation, this, _2)); + registrar.add("Inventory.SetFavoriteFolder", boost::bind(&LLInventoryGalleryContextMenu::setFavoriteFolder, this)); registrar.add("Inventory.EmptyTrash", boost::bind(&LLInventoryModel::emptyFolderType, &gInventory, "ConfirmEmptyTrash", LLFolderType::FT_TRASH)); registrar.add("Inventory.EmptyLostAndFound", boost::bind(&LLInventoryModel::emptyFolderType, &gInventory, "ConfirmEmptyLostAndFound", LLFolderType::FT_LOST_AND_FOUND)); registrar.add("Inventory.DoCreate", [this](LLUICtrl*, const LLSD& data) @@ -110,6 +111,7 @@ LLContextMenu* LLInventoryGalleryContextMenu::createMenu() registrar.add("Inventory.Share", boost::bind(&LLAvatarActions::shareWithAvatars, uuids, gFloaterView->getParentFloater(mGallery))); enable_registrar.add("Inventory.CanSetUploadLocation", boost::bind(&LLInventoryGalleryContextMenu::canSetUploadLocation, this, _2)); + enable_registrar.add("Inventory.CanSetFavoriteFolder", boost::bind(&LLInventoryGalleryContextMenu::canSetFavoriteFolder, this)); enable_registrar.add("Inventory.EnvironmentEnabled", [](LLUICtrl*, const LLSD&) { @@ -504,6 +506,25 @@ bool LLInventoryGalleryContextMenu::canSetUploadLocation(const LLSD& userdata) return true; } +void LLInventoryGalleryContextMenu::setFavoriteFolder() +{ + gSavedPerAccountSettings.setString("FavoriteFolder", mUUIDs.front().asString()); +} + +bool LLInventoryGalleryContextMenu::canSetFavoriteFolder() +{ + if (mUUIDs.size() != 1) + { + return false; + } + LLInventoryCategory* cat = gInventory.getCategory(mUUIDs.front()); + if (!cat) + { + return false; + } + return true; +} + bool is_inbox_folder(LLUUID item_id) { const LLUUID inbox_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_INBOX); @@ -769,6 +790,8 @@ void LLInventoryGalleryContextMenu::updateMenuItemsVisibility(LLContextMenu* men items.push_back(std::string("upload_def")); } + items.push_back(std::string("Set favorite folder")); + if(is_outfits && !isRootFolder()) { items.push_back(std::string("New Outfit")); @@ -843,6 +866,8 @@ void LLInventoryGalleryContextMenu::updateMenuItemsVisibility(LLContextMenu* men { disabled_items.push_back(std::string("Copy")); } + + disabled_items.push_back(std::string("Set favorite folder")); } if((obj->getType() == LLAssetType::AT_SETTINGS) || ((obj->getType() <= LLAssetType::AT_GESTURE) diff --git a/indra/newview/llinventorygallerymenu.h b/indra/newview/llinventorygallerymenu.h index 7c3545432b..7f6598e171 100644 --- a/indra/newview/llinventorygallerymenu.h +++ b/indra/newview/llinventorygallerymenu.h @@ -49,6 +49,9 @@ protected: void fileUploadLocation(const LLSD& userdata); bool canSetUploadLocation(const LLSD& userdata); + void setFavoriteFolder(); + bool canSetFavoriteFolder(); + static void onRename(const LLSD& notification, const LLSD& response); private: diff --git a/indra/newview/llinventoryitemslist.cpp b/indra/newview/llinventoryitemslist.cpp index 9e936eee5b..2e0669fc38 100644 --- a/indra/newview/llinventoryitemslist.cpp +++ b/indra/newview/llinventoryitemslist.cpp @@ -99,7 +99,7 @@ void LLInventoryItemsList::updateSelection() for(std::vector<LLSD>::const_iterator cur_id_it = cur.begin(); cur_id_it != cur.end() && !mSelectTheseIDs.empty(); ++cur_id_it) { - uuid_vec_t::iterator select_ids_it = std::find(mSelectTheseIDs.begin(), mSelectTheseIDs.end(), *cur_id_it); + uuid_vec_t::iterator select_ids_it = std::find(mSelectTheseIDs.begin(), mSelectTheseIDs.end(), cur_id_it->asUUID()); if(select_ids_it != mSelectTheseIDs.end()) { selectItemByUUID(*select_ids_it); diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp index d57cb13362..b6ff31a7ed 100644 --- a/indra/newview/llinventorymodel.cpp +++ b/indra/newview/llinventorymodel.cpp @@ -1305,6 +1305,47 @@ void LLInventoryModel::collectDescendentsIf(const LLUUID& id, } } +bool LLInventoryModel::hasMatchingDescendents(const LLUUID& id, + bool include_trash, + LLInventoryCollectFunctor& matches) +{ + if (!include_trash) + { + const LLUUID trash_id = findCategoryUUIDForType(LLFolderType::FT_TRASH); + if (trash_id.notNull() && (trash_id == id)) + return false; + } + cat_array_t* cat_array = get_ptr_in_map(mParentChildCategoryTree, id); + if (cat_array) + { + for (auto& cat : *cat_array) + { + if (matches(cat, NULL)) + { + return true; + } + if (hasMatchingDescendents(cat->getUUID(), include_trash, matches)) + { + return true; + } + } + } + + item_array_t* item_array = get_ptr_in_map(mParentChildItemTree, id); + + if (item_array) + { + for (auto& item : *item_array) + { + if (matches(NULL, item)) + { + return true; + } + } + } + return false; +} + void LLInventoryModel::addChangedMaskForLinks(const LLUUID& object_id, U32 mask) { const LLInventoryObject *obj = getObject(object_id); @@ -2037,8 +2078,8 @@ void LLInventoryModel::deleteObject(const LLUUID& id, bool fix_broken_links, boo { LL_WARNS(LOG_INV) << "Deleting cat " << id << " while it still has child cats" << LL_ENDL; } - delete cat_list; mParentChildCategoryTree.erase(id); + delete cat_list; } addChangedMask(LLInventoryObserver::REMOVE, id); @@ -5035,4 +5076,3 @@ void LLInventoryModel::FetchItemHttpHandler::processFailure(const char * const r << LLCoreHttpUtil::responseToString(response) << "]" << LL_ENDL; gInventory.notifyObservers(); } - diff --git a/indra/newview/llinventorymodel.h b/indra/newview/llinventorymodel.h index 1472b705e4..d28743357e 100644 --- a/indra/newview/llinventorymodel.h +++ b/indra/newview/llinventorymodel.h @@ -287,6 +287,9 @@ public: item_array_t& items, bool include_trash, LLInventoryCollectFunctor& add); + bool hasMatchingDescendents(const LLUUID& id, + bool include_trash, + LLInventoryCollectFunctor& add); // Collect all items in inventory that are linked to item_id. // Assumes item_id is itself not a linked item. diff --git a/indra/newview/llinventorymodelbackgroundfetch.cpp b/indra/newview/llinventorymodelbackgroundfetch.cpp index d8e6bf380e..2cf1554957 100644 --- a/indra/newview/llinventorymodelbackgroundfetch.cpp +++ b/indra/newview/llinventorymodelbackgroundfetch.cpp @@ -30,6 +30,7 @@ #include "llaisapi.h" #include "llagent.h" #include "llappviewer.h" +#include "llappearancemgr.h" #include "llcallbacklist.h" #include "llinventorymodel.h" #include "llinventorypanel.h" @@ -470,6 +471,22 @@ void LLInventoryModelBackgroundFetch::fetchCOF(nullary_func_t callback) callback(); LLUUID cat_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_CURRENT_OUTFIT); LLInventoryModelBackgroundFetch::getInstance()->onAISFolderCalback(cat_id, id, FT_DEFAULT); + + if (id.notNull()) + { + // COF might have fetched base outfit folder through a link, but it hasn't + // fetched base outfit's content, which doesn't nessesary match COF, + // so make sure it's up to date + LLUUID baseoutfit_id = LLAppearanceMgr::getInstance()->getBaseOutfitUUID(); + if (baseoutfit_id.notNull()) + { + LLViewerInventoryCategory* cat = gInventory.getCategory(baseoutfit_id); + if (!cat || cat->getVersion() == LLViewerInventoryCategory::VERSION_UNKNOWN) + { + LLInventoryModelBackgroundFetch::getInstance()->fetchFolderAndLinks(baseoutfit_id, no_op); + } + } + } }); // start idle loop to track completion diff --git a/indra/newview/llinventorypanel.cpp b/indra/newview/llinventorypanel.cpp index e4d1010231..1795de727d 100644 --- a/indra/newview/llinventorypanel.cpp +++ b/indra/newview/llinventorypanel.cpp @@ -185,6 +185,7 @@ LLInventoryPanel::LLInventoryPanel(const LLInventoryPanel::Params& p) : mCommitCallbackRegistrar.add("Inventory.BeginIMSession", boost::bind(&LLInventoryPanel::beginIMSession, this)); mCommitCallbackRegistrar.add("Inventory.Share", boost::bind(&LLAvatarActions::shareWithAvatars, this)); mCommitCallbackRegistrar.add("Inventory.FileUploadLocation", boost::bind(&LLInventoryPanel::fileUploadLocation, this, _2)); + mCommitCallbackRegistrar.add("Inventory.SetFavoriteFolder", boost::bind(&LLInventoryPanel::setFavoriteFolder, this)); mCommitCallbackRegistrar.add("Inventory.OpenNewFolderWindow", boost::bind(&LLInventoryPanel::openSingleViewInventory, this, LLUUID())); } @@ -579,9 +580,9 @@ void LLInventoryPanel::itemChanged(const LLUUID& item_id, U32 mask, const LLInve { if (model_item && view_item && viewmodel_item) { - const LLUUID& idp = viewmodel_item->getUUID(); - view_item->destroyView(); + const LLUUID idp = viewmodel_item->getUUID(); removeItemID(idp); + view_item->destroyView(); } LLInventoryObject const* objectp = mInventory->getObject(item_id); @@ -1334,6 +1335,8 @@ void LLInventoryPanel::openStartFolderOrMyInventory() LLFolderViewFolder *fchild = dynamic_cast<LLFolderViewFolder*>(child); if (fchild && fchild->getViewModelItem() + // Is this right? Name might be localized, + // use FT_ROOT_INVENTORY or gInventory.getRootFolderID()? && fchild->getViewModelItem()->getName() == "My Inventory") { fchild->setOpen(true); @@ -1759,6 +1762,11 @@ void LLInventoryPanel::fileUploadLocation(const LLSD& userdata) } } +void LLInventoryPanel::setFavoriteFolder() +{ + gSavedPerAccountSettings.setString("FavoriteFolder", LLFolderBridge::sSelf.get()->getUUID().asString()); +} + void LLInventoryPanel::openSingleViewInventory(LLUUID folder_id) { LLPanelMainInventory::newFolderWindow(folder_id.isNull() ? LLFolderBridge::sSelf.get()->getUUID() : folder_id); @@ -2024,7 +2032,7 @@ void LLInventoryPanel::removeItemID(const LLUUID& id) ++it) { mItemMap.erase((*it)->getUUID()); -} + } for (LLInventoryModel::item_array_t::iterator it = items.begin(), end_it = items.end(); it != end_it; diff --git a/indra/newview/llinventorypanel.h b/indra/newview/llinventorypanel.h index 56909c8d98..ab17196e5f 100644 --- a/indra/newview/llinventorypanel.h +++ b/indra/newview/llinventorypanel.h @@ -225,6 +225,7 @@ public: void doCreate(const LLSD& userdata); bool beginIMSession(); void fileUploadLocation(const LLSD& userdata); + void setFavoriteFolder(); void openSingleViewInventory(LLUUID folder_id = LLUUID()); void purgeSelectedItems(); bool attachObject(const LLSD& userdata); diff --git a/indra/newview/lllocalbitmaps.cpp b/indra/newview/lllocalbitmaps.cpp index 31c9eb8966..101ee215cb 100644 --- a/indra/newview/lllocalbitmaps.cpp +++ b/indra/newview/lllocalbitmaps.cpp @@ -293,8 +293,9 @@ void LLLocalBitmap::addGLTFMaterial(LLGLTFMaterial* mat) return; } - mat_list_t::iterator end = mGLTFMaterialWithLocalTextures.end(); - for (mat_list_t::iterator it = mGLTFMaterialWithLocalTextures.begin(); it != end;) + mat->addLocalTextureTracking(getTrackingID(), getWorldID()); + + for (mat_list_t::iterator it = mGLTFMaterialWithLocalTextures.begin(); it != mGLTFMaterialWithLocalTextures.end();) { if (it->get() == mat) { @@ -304,15 +305,12 @@ void LLLocalBitmap::addGLTFMaterial(LLGLTFMaterial* mat) if ((*it)->getNumRefs() == 1) { it = mGLTFMaterialWithLocalTextures.erase(it); - end = mGLTFMaterialWithLocalTextures.end(); } else { it++; } } - - mat->addLocalTextureTracking(getTrackingID(), getWorldID()); mGLTFMaterialWithLocalTextures.push_back(mat); } @@ -628,16 +626,16 @@ void LLLocalBitmap::updateUserLayers(LLUUID old_id, LLUUID new_id, LLWearableTyp void LLLocalBitmap::updateGLTFMaterials(LLUUID old_id, LLUUID new_id) { // Might be a better idea to hold this in LLGLTFMaterialList - mat_list_t::iterator end = mGLTFMaterialWithLocalTextures.end(); - for (mat_list_t::iterator it = mGLTFMaterialWithLocalTextures.begin(); it != end;) + for (mat_list_t::iterator it = mGLTFMaterialWithLocalTextures.begin(); it != mGLTFMaterialWithLocalTextures.end();) { if ((*it)->getNumRefs() == 1) { // render and override materials are often recreated, // clean up any remains it = mGLTFMaterialWithLocalTextures.erase(it); - end = mGLTFMaterialWithLocalTextures.end(); } + // Render material consists of base and override materials, make sure replaceLocalTexture + // gets called for base and override before applyOverride else if ((*it)->replaceLocalTexture(mTrackingID, old_id, new_id)) { it++; @@ -647,43 +645,51 @@ void LLLocalBitmap::updateGLTFMaterials(LLUUID old_id, LLUUID new_id) // Matching id not found, no longer in use // material would clean itself, remove from the list it = mGLTFMaterialWithLocalTextures.erase(it); - end = mGLTFMaterialWithLocalTextures.end(); } } - // Render material consists of base and override materials, make sure replaceLocalTexture - // gets called for base and override before applyOverride - end = mGLTFMaterialWithLocalTextures.end(); - for (mat_list_t::iterator it = mGLTFMaterialWithLocalTextures.begin(); it != end;) + // Updating render materials calls updateTextureTracking which can modify + // mGLTFMaterialWithLocalTextures, so precollect all entries that need to be updated + std::set<LLTextureEntry*> update_entries; + for (LLGLTFMaterial* mat : mGLTFMaterialWithLocalTextures) { - LLFetchedGLTFMaterial* fetched_mat = dynamic_cast<LLFetchedGLTFMaterial*>((*it).get()); + // mGLTFMaterialWithLocalTextures includes overrides that are not 'fetched' + // and don't have texture entries (they don't need to since render material does). + LLFetchedGLTFMaterial* fetched_mat = dynamic_cast<LLFetchedGLTFMaterial*>(mat); if (fetched_mat) { for (LLTextureEntry* entry : fetched_mat->mTextureEntires) { - // Normally a change in applied material id is supposed to - // drop overrides thus reset material, but local materials - // currently reuse their existing asset id, and purpose is - // to preview how material will work in-world, overrides - // included, so do an override to render update instead. - LLGLTFMaterial* override_mat = entry->getGLTFMaterialOverride(); - if (override_mat) - { - // do not create a new material, reuse existing pointer - LLFetchedGLTFMaterial* render_mat = dynamic_cast<LLFetchedGLTFMaterial*>(entry->getGLTFRenderMaterial()); - if (render_mat) - { - *render_mat = *fetched_mat; - render_mat->applyOverride(*override_mat); - } - else - { - LL_WARNS_ONCE() << "Failed to apply local material override, render material not found" << LL_ENDL; - } - } + update_entries.insert(entry); + } + } + } + + + for (LLTextureEntry* entry : update_entries) + { + // Normally a change in applied material id is supposed to + // drop overrides thus reset material, but local materials + // currently reuse their existing asset id, and purpose is + // to preview how material will work in-world, overrides + // included, so do an override to render update instead. + LLGLTFMaterial* override_mat = entry->getGLTFMaterialOverride(); + LLGLTFMaterial* mat = entry->getGLTFMaterial(); + if (override_mat && mat) + { + // do not create a new material, reuse existing pointer + // so that mTextureEntires remains untouched + LLGLTFMaterial* render_mat = entry->getGLTFRenderMaterial(); + if (render_mat && render_mat != mat) + { + *render_mat = *mat; + render_mat->applyOverride(*override_mat); // can update mGLTFMaterialWithLocalTextures + } + else + { + LL_WARNS() << "A TE had an override, but no render material" << LL_ENDL; } } - ++it; } } diff --git a/indra/newview/lllocalbitmaps.h b/indra/newview/lllocalbitmaps.h index e169f96e70..de2dcb3467 100644 --- a/indra/newview/lllocalbitmaps.h +++ b/indra/newview/lllocalbitmaps.h @@ -106,7 +106,7 @@ class LLLocalBitmap // Store a list of accosiated materials // Might be a better idea to hold this in LLGLTFMaterialList - typedef std::vector<LLPointer<LLGLTFMaterial> > mat_list_t; + typedef std::list<LLPointer<LLGLTFMaterial> > mat_list_t; mat_list_t mGLTFMaterialWithLocalTextures; }; diff --git a/indra/newview/lllogchat.cpp b/indra/newview/lllogchat.cpp index bf49f33049..5e230d95bd 100644 --- a/indra/newview/lllogchat.cpp +++ b/indra/newview/lllogchat.cpp @@ -312,12 +312,14 @@ std::string LLLogChat::timestamp2LogString(U32 timestamp, bool withdate) + LLTrans::getString ("TimeMonth") + "]/[" + LLTrans::getString ("TimeDay") + "] [" + LLTrans::getString ("TimeHour") + "]:[" - + LLTrans::getString ("TimeMin") + "]"; + + LLTrans::getString ("TimeMin") + "]:[" + + LLTrans::getString ("TimeSec") + "]"; } else { timeStr = "[" + LLTrans::getString("TimeHour") + "]:[" - + LLTrans::getString ("TimeMin")+"]"; + + LLTrans::getString ("TimeMin")+"]:[" + + LLTrans::getString ("TimeSec")+"]"; } LLSD substitution; @@ -892,6 +894,11 @@ bool LLLogChat::isTranscriptFileFound(std::string fullname) return result; } +std::string LLLogChat::getGroupChatSuffix() +{ + return GROUP_CHAT_SUFFIX; +} + //*TODO mark object's names in a special way so that they will be distinguishable form avatar name //which are more strict by its nature (only firstname and secondname) //Example, an object's name can be written like "Object <actual_object's_name>" diff --git a/indra/newview/lllogchat.h b/indra/newview/lllogchat.h index dbbd8ae1ba..39c40b985e 100644 --- a/indra/newview/lllogchat.h +++ b/indra/newview/lllogchat.h @@ -127,6 +127,8 @@ public: static bool isAdHocTranscriptExist(std::string file_name); static bool isTranscriptFileFound(std::string fullname); + static std::string getGroupChatSuffix(); + bool historyThreadsFinished(LLUUID session_id); LLLoadHistoryThread* getLoadHistoryThread(LLUUID session_id); LLDeleteHistoryThread* getDeleteHistoryThread(LLUUID session_id); diff --git a/indra/newview/lllogininstance.cpp b/indra/newview/lllogininstance.cpp index ad04c11cc6..cbc3744aa3 100644 --- a/indra/newview/lllogininstance.cpp +++ b/indra/newview/lllogininstance.cpp @@ -212,6 +212,7 @@ void LLLoginInstance::constructAuthParams(LLPointer<LLCredential> user_credentia request_params["read_critical"] = false; // handleTOSResponse request_params["last_exec_event"] = mLastExecEvent; request_params["last_exec_duration"] = mLastExecDuration; + request_params["last_exec_session_id"] = mLastAgentSessionId.asString(); request_params["mac"] = (char*)hashed_unique_id_string; request_params["version"] = LLVersionInfo::instance().getVersion(); request_params["channel"] = LLVersionInfo::instance().getChannel(); diff --git a/indra/newview/lllogininstance.h b/indra/newview/lllogininstance.h index 624408d46d..748909c069 100644 --- a/indra/newview/lllogininstance.h +++ b/indra/newview/lllogininstance.h @@ -64,6 +64,7 @@ public: void setSerialNumber(const std::string& sn) { mSerialNumber = sn; } void setLastExecEvent(int lee) { mLastExecEvent = lee; } void setLastExecDuration(S32 duration) { mLastExecDuration = duration; } + void setLastAgentSessionId(const LLUUID& id) { mLastAgentSessionId = id; } void setPlatformInfo(const std::string platform, const std::string platform_version, const std::string platform_name); void setNotificationsInterface(LLNotificationsInterface* ni) { mNotifications = ni; } @@ -101,6 +102,7 @@ private: std::string mSerialNumber; int mLastExecEvent; S32 mLastExecDuration; + LLUUID mLastAgentSessionId; std::string mPlatform; std::string mPlatformVersion; std::string mPlatformVersionName; diff --git a/indra/newview/llmanip.cpp b/indra/newview/llmanip.cpp index 0d617753c8..3fdf7bd925 100644 --- a/indra/newview/llmanip.cpp +++ b/indra/newview/llmanip.cpp @@ -574,9 +574,6 @@ void LLManip::renderTickValue(const LLVector3& pos, F32 value, const std::string gGL.scalef(inv_zoom_amt, inv_zoom_amt, inv_zoom_amt); } - LLColor4 shadow_color = LLColor4::black; - shadow_color.mV[VALPHA] = color.mV[VALPHA] * 0.5f; - if (fractional_portion != 0) { fraction_string = llformat("%c%02d%s", LLResMgr::getInstance()->getDecimalPoint(), fractional_portion, suffix.c_str()); diff --git a/indra/newview/llmaniprotate.cpp b/indra/newview/llmaniprotate.cpp index 5bdf3f81b5..b63b8be095 100644 --- a/indra/newview/llmaniprotate.cpp +++ b/indra/newview/llmaniprotate.cpp @@ -274,7 +274,9 @@ void LLManipRotate::render() } LLGLEnable cull_face(GL_CULL_FACE); +#if GL_VERSION_1_1 LLGLEnable clip_plane0(GL_CLIP_PLANE0); +#endif LLGLDepthTest gls_depth(GL_FALSE); //LLGLDisable gls_stencil(GL_STENCIL_TEST); diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index 1e3a328464..28160177f6 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -2857,9 +2857,16 @@ void LLMaterialEditor::importMaterial() { return; } - if (filenames.size() > 0) + try { - LLMaterialEditor::loadMaterialFromFile(filenames[0], -1); + if (filenames.size() > 0) + { + LLMaterialEditor::loadMaterialFromFile(filenames[0], -1); + } + } + catch (std::bad_alloc&) + { + LLNotificationsUtil::add("CannotOpenFileTooBig"); } }, LLFilePicker::FFLOAD_MATERIAL, diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp index a5bed1dbe6..a8c6f69425 100644 --- a/indra/newview/llmeshrepository.cpp +++ b/indra/newview/llmeshrepository.cpp @@ -255,12 +255,12 @@ // mSkinInfoQ mMutex rw.repo.mMutex, rw.main.mMutex [5] (was: [0]) // mDecompositionRequests mMutex rw.repo.mMutex, ro.repo.none [5] // mPhysicsShapeRequests mMutex rw.repo.mMutex, ro.repo.none [5] -// mDecompositionQ mMutex rw.repo.mMutex, rw.main.mMutex [5] (was: [0]) +// mDecompositionQ mMutex rw.repo.mLoadedMutex, rw.main.mLoadedMutex [5] (was: [0]) // mHeaderReqQ mMutex ro.repo.none [5], rw.repo.mMutex, rw.any.mMutex // mLODReqQ mMutex ro.repo.none [5], rw.repo.mMutex, rw.any.mMutex -// mUnavailableQ mMutex rw.repo.none [0], ro.main.none [5], rw.main.mMutex -// mLoadedQ mMutex rw.repo.mMutex, ro.main.none [5], rw.main.mMutex -// mPendingLOD mMutex rw.repo.mMutex, rw.any.mMutex +// mUnavailableQ mMutex rw.repo.none [0], ro.main.none [5], rw.main.mLoadedMutex +// mLoadedQ mMutex rw.repo.mLoadedMutex, ro.main.none [5], rw.main.mLoadedMutex +// mPendingLOD mMutex rw.repo.mPendingMutex, rw.any.mPendingMutex // mGetMeshCapability mMutex rw.main.mMutex, ro.repo.mMutex (was: [0]) // mGetMesh2Capability mMutex rw.main.mMutex, ro.repo.mMutex (was: [0]) // mGetMeshVersion mMutex rw.main.mMutex, ro.repo.mMutex @@ -343,20 +343,22 @@ static LLFastTimer::DeclareTimer FTM_MESH_FETCH("Mesh Fetch"); LLMeshRepository gMeshRepo; -const S32 MESH_HEADER_SIZE = 4096; // Important: assumption is that headers fit in this space +constexpr U32 CACHE_PREAMBLE_VERSION = 1; +constexpr S32 CACHE_PREAMBLE_SIZE = sizeof(U32) * 3; //version, header_size, flags +constexpr S32 MESH_HEADER_SIZE = 4096; // Important: assumption is that headers fit in this space -const S32 REQUEST2_HIGH_WATER_MIN = 32; // Limits for GetMesh2 regions -const S32 REQUEST2_HIGH_WATER_MAX = 100; -const S32 REQUEST2_LOW_WATER_MIN = 16; -const S32 REQUEST2_LOW_WATER_MAX = 50; +constexpr S32 REQUEST2_HIGH_WATER_MIN = 32; // Limits for GetMesh2 regions +constexpr S32 REQUEST2_HIGH_WATER_MAX = 100; +constexpr S32 REQUEST2_LOW_WATER_MIN = 16; +constexpr S32 REQUEST2_LOW_WATER_MAX = 50; -const U32 LARGE_MESH_FETCH_THRESHOLD = 1U << 21; // Size at which requests goes to narrow/slow queue -const long SMALL_MESH_XFER_TIMEOUT = 120L; // Seconds to complete xfer, small mesh downloads -const long LARGE_MESH_XFER_TIMEOUT = 600L; // Seconds to complete xfer, large downloads +constexpr U32 LARGE_MESH_FETCH_THRESHOLD = 1U << 21; // Size at which requests goes to narrow/slow queue +constexpr long SMALL_MESH_XFER_TIMEOUT = 120L; // Seconds to complete xfer, small mesh downloads +constexpr long LARGE_MESH_XFER_TIMEOUT = 600L; // Seconds to complete xfer, large downloads -const U32 DOWNLOAD_RETRY_LIMIT = 8; -const F32 DOWNLOAD_RETRY_DELAY = 0.5f; // seconds +constexpr U32 DOWNLOAD_RETRY_LIMIT = 8; +constexpr F32 DOWNLOAD_RETRY_DELAY = 0.5f; // seconds // Would normally like to retry on uploads as some // retryable failures would be recoverable. Unfortunately, @@ -366,7 +368,7 @@ const F32 DOWNLOAD_RETRY_DELAY = 0.5f; // seconds // cap which then produces a 404 on retry destroying some // (occasionally) useful error information. We'll leave // upload retries to the user as in the past. SH-4667. -const long UPLOAD_RETRY_LIMIT = 0L; +constexpr long UPLOAD_RETRY_LIMIT = 0L; // Maximum mesh version to support. Three least significant digits are reserved for the minor version, // with major version changes indicating a format change that is not backwards compatible and should not @@ -374,7 +376,7 @@ const long UPLOAD_RETRY_LIMIT = 0L; // present, the version is 0.001. A viewer that can parse version 0.001 can also parse versions up to 0.999, // but not 1.0 (integer 1000). // See wiki at https://wiki.secondlife.com/wiki/Mesh/Mesh_Asset_Format -const S32 MAX_MESH_VERSION = 999; +constexpr S32 MAX_MESH_VERSION = 999; U32 LLMeshRepository::sBytesReceived = 0; U32 LLMeshRepository::sMeshRequestCount = 0; @@ -386,12 +388,12 @@ U32 LLMeshRepository::sLODProcessing = 0; U32 LLMeshRepository::sLODPending = 0; U32 LLMeshRepository::sCacheBytesRead = 0; -U32 LLMeshRepository::sCacheBytesWritten = 0; +std::atomic<U32> LLMeshRepository::sCacheBytesWritten = 0; U32 LLMeshRepository::sCacheBytesHeaders = 0; U32 LLMeshRepository::sCacheBytesSkins = 0; U32 LLMeshRepository::sCacheBytesDecomps = 0; U32 LLMeshRepository::sCacheReads = 0; -U32 LLMeshRepository::sCacheWrites = 0; +std::atomic<U32> LLMeshRepository::sCacheWrites = 0; U32 LLMeshRepository::sMaxLockHoldoffs = 0; LLDeadmanTimer LLMeshRepository::sQuiescentTimer(15.0, false); // true -> gather cpu metrics @@ -548,8 +550,9 @@ LLViewerFetchedTexture* LLMeshUploadThread::FindViewerTexture(const LLImportMate return ppTex ? (*ppTex).get() : NULL; } -volatile S32 LLMeshRepoThread::sActiveHeaderRequests = 0; -volatile S32 LLMeshRepoThread::sActiveLODRequests = 0; +std::atomic<S32> LLMeshRepoThread::sActiveHeaderRequests = 0; +std::atomic<S32> LLMeshRepoThread::sActiveLODRequests = 0; +std::atomic<S32> LLMeshRepoThread::sActiveSkinRequests = 0; U32 LLMeshRepoThread::sMaxConcurrentRequests = 1; S32 LLMeshRepoThread::sRequestLowWater = REQUEST2_LOW_WATER_MIN; S32 LLMeshRepoThread::sRequestHighWater = REQUEST2_HIGH_WATER_MIN; @@ -584,6 +587,7 @@ public: : LLCore::HttpHandler(), mMeshParams(), mProcessed(false), + mHasDataOwnership(true), mHttpHandle(LLCORE_HTTP_HANDLE_INVALID), mOffset(offset), mRequestedBytes(requested_bytes) @@ -607,6 +611,9 @@ public: LLCore::HttpHandle mHttpHandle; U32 mOffset; U32 mRequestedBytes; + +protected: + bool mHasDataOwnership = true; }; @@ -659,6 +666,9 @@ public: virtual void processData(LLCore::BufferArray * body, S32 body_offset, U8 * data, S32 data_size); virtual void processFailure(LLCore::HttpStatus status); +private: + void processLod(U8* data, S32 data_size); + public: S32 mLOD; }; @@ -674,13 +684,17 @@ public: LLMeshSkinInfoHandler(const LLUUID& id, U32 offset, U32 requested_bytes) : LLMeshHandlerBase(offset, requested_bytes), mMeshID(id) - {} + { + LLMeshRepoThread::incActiveSkinRequests(); + } virtual ~LLMeshSkinInfoHandler(); protected: LLMeshSkinInfoHandler(const LLMeshSkinInfoHandler &); // Not defined void operator=(const LLMeshSkinInfoHandler &); // Not defined + void processSkin(U8* data, S32 data_size); + public: virtual void processData(LLCore::BufferArray * body, S32 body_offset, U8 * data, S32 data_size); virtual void processFailure(LLCore::HttpStatus status); @@ -823,6 +837,14 @@ void log_upload_error(LLCore::HttpStatus status, const LLSD& content, gMeshRepo.uploadError(args); } +void write_preamble(LLFileSystem &file, S32 header_bytes, S32 flags) +{ + LLMeshRepository::sCacheBytesWritten += CACHE_PREAMBLE_SIZE; + file.write((U8*)&CACHE_PREAMBLE_VERSION, sizeof(U32)); + file.write((U8*)&header_bytes, sizeof(U32)); + file.write((U8*)&flags, sizeof(U32)); +} + LLMeshRepoThread::LLMeshRepoThread() : LLThread("mesh repo"), mHttpRequest(NULL), @@ -837,6 +859,9 @@ LLMeshRepoThread::LLMeshRepoThread() mMutex = new LLMutex(); mHeaderMutex = new LLMutex(); + mLoadedMutex = new LLMutex(); + mPendingMutex = new LLMutex(); + mSkinMapMutex = new LLMutex(); mSignal = new LLCondition(); mHttpRequest = new LLCore::HttpRequest; mHttpOptions = LLCore::HttpOptions::ptr_t(new LLCore::HttpOptions); @@ -849,6 +874,11 @@ LLMeshRepoThread::LLMeshRepoThread() mHttpHeaders->append(HTTP_OUT_HEADER_ACCEPT, HTTP_CONTENT_VND_LL_MESH); mHttpPolicyClass = app_core_http.getPolicy(LLAppCoreHttp::AP_MESH2); mHttpLargePolicyClass = app_core_http.getPolicy(LLAppCoreHttp::AP_LARGE_MESH); + + // Lod processing is expensive due to the number of requests + // and a need to do expensive cacheOptimize(). + mMeshThreadPool.reset(new LL::ThreadPool("MeshLodProcessing", 2)); + mMeshThreadPool->start(); } @@ -875,13 +905,21 @@ LLMeshRepoThread::~LLMeshRepoThread() } delete mHttpRequest; - mHttpRequest = NULL; + mHttpRequest = nullptr; delete mMutex; - mMutex = NULL; + mMutex = nullptr; delete mHeaderMutex; - mHeaderMutex = NULL; + mHeaderMutex = nullptr; + delete mLoadedMutex; + mLoadedMutex = nullptr; + delete mPendingMutex; + mPendingMutex = nullptr; + delete mSkinMapMutex; + mSkinMapMutex = nullptr; delete mSignal; - mSignal = NULL; + mSignal = nullptr; + delete[] mDiskCacheBuffer; + mDiskCacheBuffer = nullptr; } void LLMeshRepoThread::run() @@ -908,6 +946,7 @@ void LLMeshRepoThread::run() // On the other hand, this may actually be an effective and efficient scheme... mSignal->wait(); + LL_PROFILE_ZONE_NAMED("mesh_thread_loop") if (LLApp::isExiting()) { @@ -925,11 +964,55 @@ void LLMeshRepoThread::run() } sRequestWaterLevel = static_cast<S32>(mHttpRequestSet.size()); // Stats data update - // NOTE: order of queue processing intentionally favors LOD requests over header requests + // NOTE: order of queue processing intentionally favors LOD and Skin requests over header requests // Todo: we are processing mLODReqQ, mHeaderReqQ, mSkinRequests, mDecompositionRequests and mPhysicsShapeRequests // in relatively similar manners, remake code to simplify/unify the process, // like processRequests(&requestQ, fetchFunction); which does same thing for each element + if (mHttpRequestSet.size() < sRequestHighWater + && !mSkinRequests.empty()) + { + if (!mSkinRequests.empty()) + { + std::list<UUIDBasedRequest> incomplete; + while (!mSkinRequests.empty() && mHttpRequestSet.size() < sRequestHighWater) + { + + mMutex->lock(); + auto req = mSkinRequests.front(); + mSkinRequests.pop_front(); + mMutex->unlock(); + if (req.isDelayed()) + { + incomplete.emplace_back(req); + } + else if (!fetchMeshSkinInfo(req.mId)) + { + if (req.canRetry()) + { + req.updateTime(); + incomplete.emplace_back(req); + } + else + { + LLMutexLock locker(mLoadedMutex); + mSkinUnavailableQ.push_back(req); + LL_DEBUGS() << "mSkinReqQ failed: " << req.mId << LL_ENDL; + } + } + } + + if (!incomplete.empty()) + { + LLMutexLock locker(mMutex); + for (const auto& req : incomplete) + { + mSkinRequests.push_back(req); + } + } + } + } + if (!mLODReqQ.empty() && mHttpRequestSet.size() < sRequestHighWater) { std::list<LODRequest> incomplete; @@ -950,7 +1033,7 @@ void LLMeshRepoThread::run() // failed to load before, wait a bit incomplete.push_front(req); } - else if (!fetchMeshLOD(req.mMeshParams, req.mLOD, req.canRetry())) + else if (!fetchMeshLOD(req.mMeshParams, req.mLOD)) { if (req.canRetry()) { @@ -961,7 +1044,7 @@ void LLMeshRepoThread::run() else { // too many fails - LLMutexLock lock(mMutex); + LLMutexLock lock(mLoadedMutex); mUnavailableQ.push_back(req); LL_WARNS() << "Failed to load " << req.mMeshParams << " , skip" << LL_ENDL; } @@ -998,7 +1081,7 @@ void LLMeshRepoThread::run() // failed to load before, wait a bit incomplete.push_front(req); } - else if (!fetchMeshHeader(req.mMeshParams, req.canRetry())) + else if (!fetchMeshHeader(req.mMeshParams)) { if (req.canRetry()) { @@ -1028,54 +1111,13 @@ void LLMeshRepoThread::run() // performing long-duration actions. if (mHttpRequestSet.size() < sRequestHighWater - && (!mSkinRequests.empty() - || !mDecompositionRequests.empty() + && (!mDecompositionRequests.empty() || !mPhysicsShapeRequests.empty())) { // Something to do probably, lock and double-check. We don't want // to hold the lock long here. That will stall main thread activities // so we bounce it. - if (!mSkinRequests.empty()) - { - std::list<UUIDBasedRequest> incomplete; - while (!mSkinRequests.empty() && mHttpRequestSet.size() < sRequestHighWater) - { - - mMutex->lock(); - auto req = mSkinRequests.front(); - mSkinRequests.pop_front(); - mMutex->unlock(); - if (req.isDelayed()) - { - incomplete.emplace_back(req); - } - else if (!fetchMeshSkinInfo(req.mId, req.canRetry())) - { - if (req.canRetry()) - { - req.updateTime(); - incomplete.emplace_back(req); - } - else - { - LLMutexLock locker(mMutex); - mSkinUnavailableQ.push_back(req); - LL_DEBUGS() << "mSkinReqQ failed: " << req.mId << LL_ENDL; - } - } - } - - if (!incomplete.empty()) - { - LLMutexLock locker(mMutex); - for (const auto& req : incomplete) - { - mSkinRequests.push_back(req); - } - } - } - // holding lock, try next list // *TODO: For UI/debug-oriented lists, we might drop the fine- // grained locking as there's a lowered expectation of smoothness @@ -1103,7 +1145,7 @@ void LLMeshRepoThread::run() } else { - LL_DEBUGS() << "mDecompositionRequests failed: " << req.mId << LL_ENDL; + LL_DEBUGS(LOG_MESH) << "mDecompositionRequests failed: " << req.mId << LL_ENDL; } } } @@ -1139,7 +1181,7 @@ void LLMeshRepoThread::run() } else { - LL_DEBUGS() << "mPhysicsShapeRequests failed: " << req.mId << LL_ENDL; + LL_DEBUGS(LOG_MESH) << "mPhysicsShapeRequests failed: " << req.mId << LL_ENDL; } } } @@ -1195,40 +1237,91 @@ void LLMeshRepoThread::lockAndLoadMeshLOD(const LLVolumeParams& mesh_params, S32 } } - void LLMeshRepoThread::loadMeshLOD(const LLVolumeParams& mesh_params, S32 lod) { //could be called from any thread const LLUUID& mesh_id = mesh_params.getSculptID(); - LLMutexLock lock(mMutex); - LLMutexLock header_lock(mHeaderMutex); - mesh_header_map::iterator iter = mMeshHeader.find(mesh_id); - if (iter != mMeshHeader.end()) + loadMeshLOD(mesh_id, mesh_params, lod); +} + +void LLMeshRepoThread::loadMeshLOD(const LLUUID& mesh_id, const LLVolumeParams& mesh_params, S32 lod) +{ + if (hasHeader(mesh_id)) { //if we have the header, request LOD byte range LODRequest req(mesh_params, lod); { + LLMutexLock lock(mMutex); mLODReqQ.push(req); LLMeshRepository::sLODProcessing++; } } else { + LLMutexLock lock(mPendingMutex); HeaderRequest req(mesh_params); pending_lod_map::iterator pending = mPendingLOD.find(mesh_id); if (pending != mPendingLOD.end()) - { //append this lod request to existing header request - pending->second.push_back(lod); - llassert(pending->second.size() <= LLModel::NUM_LODS); + { + //append this lod request to existing header request + if (lod < LLModel::NUM_LODS && lod >= 0) + { + pending->second[lod]++; + } + else + { + LL_WARNS(LOG_MESH) << "Invalid LOD request: " << lod << "for mesh" << mesh_id << LL_ENDL; + } + llassert_msg(lod < LLModel::NUM_LODS, "Requested lod is out of bounds"); } else - { //if no header request is pending, fetch header + { + //if no header request is pending, fetch header + auto& array = mPendingLOD[mesh_id]; + std::fill(array.begin(), array.end(), 0); + array[lod]++; + + LLMutexLock lock(mMutex); mHeaderReqQ.push(req); - mPendingLOD[mesh_id].push_back(lod); } } } +U8* LLMeshRepoThread::getDiskCacheBuffer(S32 size) +{ + if (mDiskCacheBufferSize < size) + { + const S32 MINIMUM_BUFFER_SIZE = 8192; // a minimum to avoid frequent early reallocations + size = llmax(MINIMUM_BUFFER_SIZE, size); + delete[] mDiskCacheBuffer; + try + { + mDiskCacheBuffer = new U8[size]; + } + catch (std::bad_alloc&) + { + LL_WARNS(LOG_MESH) << "Failed to allocate memory for mesh thread's buffer, size: " << size << LL_ENDL; + mDiskCacheBuffer = NULL; + + // Not sure what size is reasonable + // but if 30MB allocation failed, we definitely have issues + const S32 MAX_SIZE = 30 * 1024 * 1024; //30MB + if (size < MAX_SIZE) + { + LLAppViewer::instance()->outOfMemorySoftQuit(); + } // else ignore failures for anomalously large data + } + mDiskCacheBufferSize = size; + } + else + { + // reusing old buffer, reset heading bytes to ensure + // old content won't be parsable if something fails. + memset(mDiskCacheBuffer, 0, 16); + } + return mDiskCacheBuffer; +} + // Mutex: must be holding mMutex when called void LLMeshRepoThread::setGetMeshCap(const std::string & mesh_cap) { @@ -1327,7 +1420,7 @@ LLCore::HttpHandle LLMeshRepoThread::getByteRange(const std::string & url, } -bool LLMeshRepoThread::fetchMeshSkinInfo(const LLUUID& mesh_id, bool can_retry) +bool LLMeshRepoThread::fetchMeshSkinInfo(const LLUUID& mesh_id) { LL_PROFILE_ZONE_SCOPED; if (!mHeaderMutex) @@ -1337,7 +1430,7 @@ bool LLMeshRepoThread::fetchMeshSkinInfo(const LLUUID& mesh_id, bool can_retry) mHeaderMutex->lock(); - auto header_it = mMeshHeader.find(mesh_id); + mesh_header_map::const_iterator header_it = mMeshHeader.find(mesh_id); if (header_it == mMeshHeader.end()) { //we have no header info for this mesh, do nothing mHeaderMutex->unlock(); @@ -1346,23 +1439,24 @@ bool LLMeshRepoThread::fetchMeshSkinInfo(const LLUUID& mesh_id, bool can_retry) ++LLMeshRepository::sMeshRequestCount; bool ret = true; - U32 header_size = header_it->second.first; + const LLMeshHeader& header = header_it->second; + U32 header_size = header.mHeaderSize; if (header_size > 0) { - const LLMeshHeader& header = header_it->second.second; - S32 version = header.mVersion; S32 offset = header_size + header.mSkinOffset; S32 size = header.mSkinSize; + bool in_cache = header.mSkinInCache; mHeaderMutex->unlock(); if (version <= MAX_MESH_VERSION && offset >= 0 && size > 0) { //check cache for mesh skin info + S32 disk_ofset = offset + CACHE_PREAMBLE_SIZE; LLFileSystem file(mesh_id, LLAssetType::AT_MESH); - if (file.getSize() >= offset + size) + if (in_cache && file.getSize() >= disk_ofset + size) { U8* buffer = new(std::nothrow) U8[size]; if (!buffer) @@ -1370,19 +1464,19 @@ bool LLMeshRepoThread::fetchMeshSkinInfo(const LLUUID& mesh_id, bool can_retry) LL_WARNS(LOG_MESH) << "Failed to allocate memory for skin info, size: " << size << LL_ENDL; // Not sure what size is reasonable for skin info, - // but if 20MB allocation failed, we definetely have issues + // but if 30MB allocation failed, we definitely have issues const S32 MAX_SIZE = 30 * 1024 * 1024; //30MB if (size < MAX_SIZE) { LLAppViewer::instance()->outOfMemorySoftQuit(); } // else ignore failures for anomalously large data - LLMutexLock locker(mMutex); + LLMutexLock locker(mLoadedMutex); mSkinUnavailableQ.emplace_back(mesh_id); return true; } LLMeshRepository::sCacheBytesRead += size; ++LLMeshRepository::sCacheReads; - file.seek(offset); + file.seek(disk_ofset); file.read(buffer, size); //make sure buffer isn't all 0's by checking the first 1KB (reserved block but not written) @@ -1393,14 +1487,67 @@ bool LLMeshRepoThread::fetchMeshSkinInfo(const LLUUID& mesh_id, bool can_retry) } if (!zero) - { //attempt to parse - if (skinInfoReceived(mesh_id, buffer, size)) + { + //attempt to parse + bool posted = mMeshThreadPool->getQueue().post( + [mesh_id, buffer, size] + () + { + if (!gMeshRepo.mThread->skinInfoReceived(mesh_id, buffer, size)) + { + // either header is faulty or something else overwrote the cache + S32 header_size = 0; + U32 header_flags = 0; + { + LL_DEBUGS(LOG_MESH) << "Mesh header for ID " << mesh_id << " cache mismatch." << LL_ENDL; + + LLMutexLock lock(gMeshRepo.mThread->mHeaderMutex); + + auto header_it = gMeshRepo.mThread->mMeshHeader.find(mesh_id); + if (header_it != gMeshRepo.mThread->mMeshHeader.end()) + { + LLMeshHeader& header = header_it->second; + // for safety just mark everything as missing + header.mSkinInCache = false; + header.mPhysicsConvexInCache = false; + header.mPhysicsMeshInCache = false; + for (S32 i = 0; i < LLModel::NUM_LODS; ++i) + { + header.mLodInCache[i] = false; + } + header_size = header.mHeaderSize; + header_flags = header.getFlags(); + } + } + + if (header_size > 0) + { + LLFileSystem file(mesh_id, LLAssetType::AT_MESH, LLFileSystem::READ_WRITE); + if (file.getMaxSize() >= CACHE_PREAMBLE_SIZE) + { + write_preamble(file, header_size, header_flags); + } + } + + { + LLMutexLock lock(gMeshRepo.mThread->mMutex); + UUIDBasedRequest req(mesh_id); + gMeshRepo.mThread->mSkinRequests.push_back(req); + } + } + delete[] buffer; + }); + if (posted) + { + // lambda owns buffer + return true; + } + else if (skinInfoReceived(mesh_id, buffer, size)) { delete[] buffer; return true; } } - delete[] buffer; } @@ -1420,26 +1567,21 @@ bool LLMeshRepoThread::fetchMeshSkinInfo(const LLUUID& mesh_id, bool can_retry) << LL_ENDL; ret = false; } - else if(can_retry) + else { handler->mHttpHandle = handle; mHttpRequestSet.insert(handler); } - else - { - LLMutexLock locker(mMutex); - mSkinUnavailableQ.emplace_back(mesh_id); - } } else { - LLMutexLock locker(mMutex); + LLMutexLock locker(mLoadedMutex); mSkinUnavailableQ.emplace_back(mesh_id); } } else { - LLMutexLock locker(mMutex); + LLMutexLock locker(mLoadedMutex); mSkinUnavailableQ.emplace_back(mesh_id); } } @@ -1470,42 +1612,35 @@ bool LLMeshRepoThread::fetchMeshDecomposition(const LLUUID& mesh_id) } ++LLMeshRepository::sMeshRequestCount; - U32 header_size = header_it->second.first; + const auto& header = header_it->second; + U32 header_size = header.mHeaderSize; bool ret = true; if (header_size > 0) { - const auto& header = header_it->second.second; S32 version = header.mVersion; S32 offset = header_size + header.mPhysicsConvexOffset; S32 size = header.mPhysicsConvexSize; + bool in_cache = header.mPhysicsConvexInCache; mHeaderMutex->unlock(); if (version <= MAX_MESH_VERSION && offset >= 0 && size > 0) { - //check cache for mesh skin info + // check cache for mesh decomposition + S32 disk_ofset = offset + CACHE_PREAMBLE_SIZE; LLFileSystem file(mesh_id, LLAssetType::AT_MESH); - if (file.getSize() >= offset+size) + if (in_cache && file.getSize() >= disk_ofset + size) { - U8* buffer = new(std::nothrow) U8[size]; + U8* buffer = getDiskCacheBuffer(size); if (!buffer) { - LL_WARNS(LOG_MESH) << "Failed to allocate memory for mesh decomposition, size: " << size << LL_ENDL; - - // Not sure what size is reasonable for decomposition - // but if 20MB allocation failed, we definetely have issues - const S32 MAX_SIZE = 30 * 1024 * 1024; //30MB - if (size < MAX_SIZE) - { - LLAppViewer::instance()->outOfMemorySoftQuit(); - } // else ignore failures for anomalously large decompositiions return true; } LLMeshRepository::sCacheBytesRead += size; ++LLMeshRepository::sCacheReads; - file.seek(offset); + file.seek(disk_ofset); file.read(buffer, size); //make sure buffer isn't all 0's by checking the first 1KB (reserved block but not written) @@ -1519,12 +1654,9 @@ bool LLMeshRepoThread::fetchMeshDecomposition(const LLUUID& mesh_id) { //attempt to parse if (decompositionReceived(mesh_id, buffer, size)) { - delete[] buffer; return true; } } - - delete[] buffer; } //reading from cache failed for whatever reason, fetch from sim @@ -1578,41 +1710,36 @@ bool LLMeshRepoThread::fetchMeshPhysicsShape(const LLUUID& mesh_id) } ++LLMeshRepository::sMeshRequestCount; - U32 header_size = header_it->second.first; + const auto& header = header_it->second; + U32 header_size = header.mHeaderSize; bool ret = true; if (header_size > 0) { - const auto& header = header_it->second.second; S32 version = header.mVersion; S32 offset = header_size + header.mPhysicsMeshOffset; S32 size = header.mPhysicsMeshSize; + bool in_cache = header.mPhysicsMeshInCache; mHeaderMutex->unlock(); + // todo: check header.mHasPhysicsMesh if (version <= MAX_MESH_VERSION && offset >= 0 && size > 0) { //check cache for mesh physics shape info + S32 disk_ofset = offset + CACHE_PREAMBLE_SIZE; LLFileSystem file(mesh_id, LLAssetType::AT_MESH); - if (file.getSize() >= offset+size) + if (in_cache && file.getSize() >= disk_ofset +size) { LLMeshRepository::sCacheBytesRead += size; ++LLMeshRepository::sCacheReads; - file.seek(offset); - U8* buffer = new(std::nothrow) U8[size]; + + U8* buffer = getDiskCacheBuffer(size); if (!buffer) { - LL_WARNS(LOG_MESH) << "Failed to allocate memory for mesh decomposition, size: " << size << LL_ENDL; - - // Not sure what size is reasonable for physcis - // but if 20MB allocation failed, we definetely have issues - const S32 MAX_SIZE = 30 * 1024 * 1024; //30MB - if (size < MAX_SIZE) - { - LLAppViewer::instance()->outOfMemorySoftQuit(); - } // else ignore failures for anomalously large data return true; } + file.seek(disk_ofset); file.read(buffer, size); //make sure buffer isn't all 0's by checking the first 1KB (reserved block but not written) @@ -1626,12 +1753,9 @@ bool LLMeshRepoThread::fetchMeshPhysicsShape(const LLUUID& mesh_id) { //attempt to parse if (physicsShapeReceived(mesh_id, buffer, size) == MESH_OK) { - delete[] buffer; return true; } } - - delete[] buffer; } //reading from cache failed for whatever reason, fetch from sim @@ -1699,8 +1823,22 @@ void LLMeshRepoThread::decActiveHeaderRequests() --LLMeshRepoThread::sActiveHeaderRequests; } +//static +void LLMeshRepoThread::incActiveSkinRequests() +{ + LLMutexLock lock(gMeshRepo.mThread->mMutex); + ++LLMeshRepoThread::sActiveSkinRequests; +} + +//static +void LLMeshRepoThread::decActiveSkinRequests() +{ + LLMutexLock lock(gMeshRepo.mThread->mMutex); + --LLMeshRepoThread::sActiveSkinRequests; +} + //return false if failed to get header -bool LLMeshRepoThread::fetchMeshHeader(const LLVolumeParams& mesh_params, bool can_retry) +bool LLMeshRepoThread::fetchMeshHeader(const LLVolumeParams& mesh_params) { LL_PROFILE_ZONE_SCOPED; ++LLMeshRepository::sMeshRequestCount; @@ -1714,17 +1852,34 @@ bool LLMeshRepoThread::fetchMeshHeader(const LLVolumeParams& mesh_params, bool c if (size > 0) { // *NOTE: if the header size is ever more than 4KB, this will break - U8 buffer[MESH_HEADER_SIZE]; - S32 bytes = llmin(size, MESH_HEADER_SIZE); + constexpr S32 DISK_MINIMAL_READ = 4096; + U8 buffer[DISK_MINIMAL_READ * 2]; + S32 bytes = llmin(size, DISK_MINIMAL_READ); LLMeshRepository::sCacheBytesRead += bytes; ++LLMeshRepository::sCacheReads; + file.read(buffer, bytes); - if (headerReceived(mesh_params, buffer, bytes) == MESH_OK) + + U32 version = 0; + memcpy(&version, buffer, sizeof(U32)); + if (version == CACHE_PREAMBLE_VERSION) { - LL_DEBUGS(LOG_MESH) << "Mesh/Cache: Mesh header for ID " << mesh_params.getSculptID() << " - was retrieved from the cache." << LL_ENDL; + S32 header_size = 0; + memcpy(&header_size, buffer + sizeof(U32), sizeof(S32)); + if (header_size + CACHE_PREAMBLE_SIZE > DISK_MINIMAL_READ) + { + bytes = llmin(size , DISK_MINIMAL_READ * 2); + file.read(buffer + DISK_MINIMAL_READ, bytes - DISK_MINIMAL_READ); + } + U32 flags = 0; + memcpy(&flags, buffer + 2 * sizeof(U32), sizeof(U32)); + if (headerReceived(mesh_params, buffer + CACHE_PREAMBLE_SIZE, bytes - CACHE_PREAMBLE_SIZE, flags) == MESH_OK) + { + LL_DEBUGS(LOG_MESH) << "Mesh/Cache: Mesh header for ID " << mesh_params.getSculptID() << " - was retrieved from the cache." << LL_ENDL; - // Found mesh in cache - return true; + // Found mesh in cache + return true; + } } } } @@ -1753,7 +1908,7 @@ bool LLMeshRepoThread::fetchMeshHeader(const LLVolumeParams& mesh_params, bool c << LL_ENDL; retval = false; } - else if (can_retry) + else { handler->mHttpHandle = handle; mHttpRequestSet.insert(handler); @@ -1764,7 +1919,7 @@ bool LLMeshRepoThread::fetchMeshHeader(const LLVolumeParams& mesh_params, bool c } //return false if failed to get mesh lod. -bool LLMeshRepoThread::fetchMeshLOD(const LLVolumeParams& mesh_params, S32 lod, bool can_retry) +bool LLMeshRepoThread::fetchMeshLOD(const LLVolumeParams& mesh_params, S32 lod) { LL_PROFILE_ZONE_SCOPED; if (!mHeaderMutex) @@ -1784,41 +1939,43 @@ bool LLMeshRepoThread::fetchMeshLOD(const LLVolumeParams& mesh_params, S32 lod, ++LLMeshRepository::sMeshRequestCount; bool retval = true; - U32 header_size = header_it->second.first; + const auto& header = header_it->second; + U32 header_size = header.mHeaderSize; if (header_size > 0) { - const auto& header = header_it->second.second; S32 version = header.mVersion; S32 offset = header_size + header.mLodOffset[lod]; S32 size = header.mLodSize[lod]; + bool in_cache = header.mLodInCache[lod]; mHeaderMutex->unlock(); if (version <= MAX_MESH_VERSION && offset >= 0 && size > 0) { - + S32 disk_ofset = offset + CACHE_PREAMBLE_SIZE; //check cache for mesh asset LLFileSystem file(mesh_id, LLAssetType::AT_MESH); - if (file.getSize() >= offset+size) + if (in_cache && (file.getSize() >= disk_ofset + size)) { - U8* buffer = new(std::nothrow) U8[size]; + U8* buffer = new(std::nothrow) U8[size]; // todo, make buffer thread local and read in thread? if (!buffer) { LL_WARNS(LOG_MESH) << "Can't allocate memory for mesh " << mesh_id << " LOD " << lod << ", size: " << size << LL_ENDL; // Not sure what size is reasonable for a mesh, - // but if 20MB allocation failed, we definetely have issues + // but if 30MB allocation failed, we definitely have issues const S32 MAX_SIZE = 30 * 1024 * 1024; //30MB if (size < MAX_SIZE) { LLAppViewer::instance()->outOfMemorySoftQuit(); } // else ignore failures for anomalously large data - LLMutexLock lock(mMutex); + + LLMutexLock lock(mLoadedMutex); mUnavailableQ.push_back(LODRequest(mesh_params, lod)); return true; } LLMeshRepository::sCacheBytesRead += size; ++LLMeshRepository::sCacheReads; - file.seek(offset); + file.seek(disk_ofset); file.read(buffer, size); //make sure buffer isn't all 0's by checking the first 1KB (reserved block but not written) @@ -1829,15 +1986,76 @@ bool LLMeshRepoThread::fetchMeshLOD(const LLVolumeParams& mesh_params, S32 lod, } if (!zero) - { //attempt to parse - if (lodReceived(mesh_params, lod, buffer, size) == MESH_OK) + { + //attempt to parse + const LLVolumeParams params(mesh_params); + bool posted = mMeshThreadPool->getQueue().post( + [params, mesh_id, lod, buffer, size] + () { + if (gMeshRepo.mThread->lodReceived(params, lod, buffer, size) == MESH_OK) + { + LL_DEBUGS(LOG_MESH) << "Mesh/Cache: Mesh body for ID " << mesh_id << " - was retrieved from the cache." << LL_ENDL; + } + else + { + // either header is faulty or something else overwrote the cache + S32 header_size = 0; + U32 header_flags = 0; + { + LL_DEBUGS(LOG_MESH) << "Mesh header for ID " << mesh_id << " cache mismatch." << LL_ENDL; + + LLMutexLock lock(gMeshRepo.mThread->mHeaderMutex); + + auto header_it = gMeshRepo.mThread->mMeshHeader.find(mesh_id); + if (header_it != gMeshRepo.mThread->mMeshHeader.end()) + { + LLMeshHeader& header = header_it->second; + // for safety just mark everything as missing + header.mSkinInCache = false; + header.mPhysicsConvexInCache = false; + header.mPhysicsMeshInCache = false; + for (S32 i = 0; i < LLModel::NUM_LODS; ++i) + { + header.mLodInCache[i] = false; + } + header_size = header.mHeaderSize; + header_flags = header.getFlags(); + } + } + + if (header_size > 0) + { + LLFileSystem file(mesh_id, LLAssetType::AT_MESH, LLFileSystem::READ_WRITE); + if (file.getMaxSize() >= CACHE_PREAMBLE_SIZE) + { + write_preamble(file, header_size, header_flags); + } + } + + { + LLMutexLock lock(gMeshRepo.mThread->mMutex); + LODRequest req(params, lod); + gMeshRepo.mThread->mLODReqQ.push(req); + LLMeshRepository::sLODProcessing++; + } + } delete[] buffer; + }); + if (posted) + { + // now lambda owns buffer + return true; + } + else if (lodReceived(mesh_params, lod, buffer, size) == MESH_OK) + { + delete[] buffer; LL_DEBUGS(LOG_MESH) << "Mesh/Cache: Mesh body for ID " << mesh_id << " - was retrieved from the cache." << LL_ENDL; return true; } + } delete[] buffer; @@ -1861,27 +2079,22 @@ bool LLMeshRepoThread::fetchMeshLOD(const LLVolumeParams& mesh_params, S32 lod, << LL_ENDL; retval = false; } - else if (can_retry) + else { + // we already made a request, store the handle handler->mHttpHandle = handle; mHttpRequestSet.insert(handler); - // *NOTE: Allowing a re-request, not marking as unavailable. Is that correct? - } - else - { - LLMutexLock lock(mMutex); - mUnavailableQ.push_back(LODRequest(mesh_params, lod)); } } else { - LLMutexLock lock(mMutex); + LLMutexLock lock(mLoadedMutex); mUnavailableQ.push_back(LODRequest(mesh_params, lod)); } } else { - LLMutexLock lock(mMutex); + LLMutexLock lock(mLoadedMutex); mUnavailableQ.push_back(LODRequest(mesh_params, lod)); } } @@ -1893,14 +2106,19 @@ bool LLMeshRepoThread::fetchMeshLOD(const LLVolumeParams& mesh_params, S32 lod, return retval; } -EMeshProcessingResult LLMeshRepoThread::headerReceived(const LLVolumeParams& mesh_params, U8* data, S32 data_size) +EMeshProcessingResult LLMeshRepoThread::headerReceived(const LLVolumeParams& mesh_params, U8* data, S32 data_size, U32 flags) { + LL_PROFILE_ZONE_SCOPED; const LLUUID mesh_id = mesh_params.getSculptID(); LLSD header_data; LLMeshHeader header; llssize header_size = 0; + S32 skin_offset = -1; + S32 skin_size = -1; + S32 lod_offset[LLModel::NUM_LODS] = { -1 }; + S32 lod_size[LLModel::NUM_LODS] = { -1 }; if (data_size > 0) { llssize dsize = data_size; @@ -1933,7 +2151,40 @@ EMeshProcessingResult LLMeshRepoThread::headerReceived(const LLVolumeParams& mes // make sure there is at least one lod, function returns -1 and marks as 404 otherwise else if (LLMeshRepository::getActualMeshLOD(header, 0) >= 0) { - header_size += stream.tellg(); + header.mHeaderSize = (S32)stream.tellg(); + header_size += header.mHeaderSize; + skin_offset = header.mSkinOffset; + skin_size = header.mSkinSize; + + memcpy(lod_offset, header.mLodOffset, sizeof(lod_offset)); + memcpy(lod_size, header.mLodSize, sizeof(lod_size)); + + if (flags != 0) + { + header.setFromFlags(flags); + } + else + { + if (header.mSkinSize > 0 && header_size + header.mSkinOffset + header.mSkinSize < data_size) + { + header.mSkinInCache = true; + } + if (header.mPhysicsConvexSize > 0 && header_size + header.mPhysicsConvexOffset + header.mPhysicsConvexSize < data_size) + { + header.mPhysicsConvexInCache = true; + } + if (header.mPhysicsMeshSize > 0 && header_size + header.mPhysicsMeshOffset + header.mPhysicsMeshSize < data_size) + { + header.mPhysicsMeshInCache = true; + } + for (S32 i = 0; i < LLModel::NUM_LODS; ++i) + { + if (lod_size[i] > 0 && header_size + lod_offset[i] + lod_size[i] < data_size) + { + header.mLodInCache[i] = true; + } + } + } } } else @@ -1947,35 +2198,84 @@ EMeshProcessingResult LLMeshRepoThread::headerReceived(const LLVolumeParams& mes { LLMutexLock lock(mHeaderMutex); - mMeshHeader[mesh_id] = { (U32)header_size, header }; + mMeshHeader[mesh_id] = header; LLMeshRepository::sCacheBytesHeaders += (U32)header_size; } // immediately request SkinInfo since we'll need it before we can render any LoD if it is present + if (skin_offset >= 0 && skin_size > 0) { - LLMutexLock lock(gMeshRepo.mMeshMutex); + { + LLMutexLock lock(gMeshRepo.mMeshMutex); - if (gMeshRepo.mLoadingSkins.find(mesh_id) == gMeshRepo.mLoadingSkins.end()) + if (gMeshRepo.mLoadingSkins.find(mesh_id) == gMeshRepo.mLoadingSkins.end()) + { + gMeshRepo.mLoadingSkins[mesh_id] = {}; // add an empty vector to indicate to main thread that we are loading skin info + } + } + + S32 offset = (S32)header_size + skin_offset; + bool request_skin = true; + if (offset + skin_size < data_size) + { + request_skin = !skinInfoReceived(mesh_id, data + offset, skin_size); + } + if (request_skin) { - gMeshRepo.mLoadingSkins[mesh_id] = {}; // add an empty vector to indicate to main thread that we are loading skin info + mSkinRequests.push_back(UUIDBasedRequest(mesh_id)); } } - fetchMeshSkinInfo(mesh_id); - - LLMutexLock lock(mMutex); // make sure only one thread access mPendingLOD at the same time. + std::array<S32, LLModel::NUM_LODS> pending_lods; + bool has_pending_lods = false; + { + LLMutexLock lock(mPendingMutex); // make sure only one thread access mPendingLOD at the same time. + pending_lod_map::iterator iter = mPendingLOD.find(mesh_id); + if (iter != mPendingLOD.end()) + { + pending_lods = iter->second; + mPendingLOD.erase(iter); + has_pending_lods = true; + } + } //check for pending requests - pending_lod_map::iterator iter = mPendingLOD.find(mesh_id); - if (iter != mPendingLOD.end()) + if (has_pending_lods) { - for (U32 i = 0; i < iter->second.size(); ++i) + for (S32 i = 0; i < pending_lods.size(); ++i) { - LODRequest req(mesh_params, iter->second[i]); - mLODReqQ.push(req); - LLMeshRepository::sLODProcessing++; + if (pending_lods[i] > 1) + { + // mLoadingMeshes should be protecting from dupplciates, but looks + // like this is possible if object rezzes, unregisterMesh, then + // rezzes again before first request completes. + // mLoadingMeshes might need to change a bit to not rerequest if + // mesh is already pending. + // + // Todo: Improve mLoadingMeshes and once done turn this into an assert. + // Low priority since such situation should be relatively rare + LL_INFOS(LOG_MESH) << "Multiple dupplicate requests for mesd ID: " << mesh_id << " LOD: " << i + << LL_ENDL; + } + if (pending_lods[i] > 0 && lod_size[i] > 0) + { + // try to load from data we just received + bool request_lod = true; + S32 offset = (S32)header_size + lod_offset[i]; + if (offset + lod_size[i] <= data_size) + { + // initial request is 4096 bytes, it's big enough to fit this lod + request_lod = lodReceived(mesh_params, i, data + offset, lod_size[i]) != MESH_OK; + } + if (request_lod) + { + LLMutexLock lock(mMutex); + LODRequest req(mesh_params, i); + mLODReqQ.push(req); + LLMeshRepository::sLODProcessing++; + } + } } - mPendingLOD.erase(iter); } } @@ -1995,8 +2295,16 @@ EMeshProcessingResult LLMeshRepoThread::lodReceived(const LLVolumeParams& mesh_p if (volume->getNumFaces() > 0) { // if we have a valid SkinInfo, cache per-joint bounding boxes for this LOD - LLMeshSkinInfo* skin_info = mSkinMap[mesh_params.getSculptID()]; - if (skin_info && isAgentAvatarValid()) + LLPointer<LLMeshSkinInfo> skin_info = nullptr; + { + LLMutexLock lock(mSkinMapMutex); + skin_map::iterator iter = mSkinMap.find(mesh_params.getSculptID()); + if (iter != mSkinMap.end()) + { + skin_info = iter->second; + } + } + if (skin_info.notNull() && isAgentAvatarValid()) { for (S32 i = 0; i < volume->getNumFaces(); ++i) { @@ -2008,7 +2316,7 @@ EMeshProcessingResult LLMeshRepoThread::lodReceived(const LLVolumeParams& mesh_p LoadedMesh mesh(volume, mesh_params, lod); { - LLMutexLock lock(mMutex); + LLMutexLock lock(mLoadedMutex); mLoadedQ.push_back(mesh); // LLPointer is not thread safe, since we added this pointer into // threaded list, make sure counter gets decreased inside mutex lock @@ -2026,6 +2334,7 @@ EMeshProcessingResult LLMeshRepoThread::lodReceived(const LLVolumeParams& mesh_p bool LLMeshRepoThread::skinInfoReceived(const LLUUID& mesh_id, U8* data, S32 data_size) { + LL_PROFILE_ZONE_SCOPED; LLSD skin; if (data_size > 0) @@ -2060,12 +2369,15 @@ bool LLMeshRepoThread::skinInfoReceived(const LLUUID& mesh_id, U8* data, S32 dat // copy the skin info for the background thread so we can use it // to calculate per-joint bounding boxes when volumes are loaded - mSkinMap[mesh_id] = new LLMeshSkinInfo(*info); + { + LLMutexLock lock(mSkinMapMutex); + mSkinMap[mesh_id] = new LLMeshSkinInfo(*info); + } { // Move the LLPointer in to the skin info queue to avoid reference // count modification after we leave the lock - LLMutexLock lock(mMutex); + LLMutexLock lock(mLoadedMutex); mSkinInfoQ.emplace_back(std::move(info)); } } @@ -2075,6 +2387,7 @@ bool LLMeshRepoThread::skinInfoReceived(const LLUUID& mesh_id, U8* data, S32 dat bool LLMeshRepoThread::decompositionReceived(const LLUUID& mesh_id, U8* data, S32 data_size) { + LL_PROFILE_ZONE_SCOPED; LLSD decomp; if (data_size > 0) @@ -2101,7 +2414,7 @@ bool LLMeshRepoThread::decompositionReceived(const LLUUID& mesh_id, U8* data, S3 LLModel::Decomposition* d = new LLModel::Decomposition(decomp); d->mMeshID = mesh_id; { - LLMutexLock lock(mMutex); + LLMutexLock lock(mLoadedMutex); mDecompositionQ.push_back(d); } } @@ -2111,6 +2424,7 @@ bool LLMeshRepoThread::decompositionReceived(const LLUUID& mesh_id, U8* data, S3 EMeshProcessingResult LLMeshRepoThread::physicsShapeReceived(const LLUUID& mesh_id, U8* data, S32 data_size) { + LL_PROFILE_ZONE_SCOPED; LLSD physics_shape; LLModel::Decomposition* d = new LLModel::Decomposition(); @@ -2150,7 +2464,7 @@ EMeshProcessingResult LLMeshRepoThread::physicsShapeReceived(const LLUUID& mesh_ } { - LLMutexLock lock(mMutex); + LLMutexLock lock(mLoadedMutex); mDecompositionQ.push_back(d); } return MESH_OK; @@ -2202,7 +2516,6 @@ LLMeshUploadThread::~LLMeshUploadThread() mHttpRequest = NULL; delete mMutex; mMutex = NULL; - } LLMeshUploadThread::DecompRequest::DecompRequest(LLModel* mdl, LLModel* base_model, LLMeshUploadThread* thread) @@ -2943,15 +3256,17 @@ void LLMeshRepoThread::notifyLoadedMeshes() return; } + LL_PROFILE_ZONE_SCOPED; + if (!mLoadedQ.empty()) { std::deque<LoadedMesh> loaded_queue; - mMutex->lock(); + mLoadedMutex->lock(); if (!mLoadedQ.empty()) { loaded_queue.swap(mLoadedQ); - mMutex->unlock(); + mLoadedMutex->unlock(); update_metrics = true; @@ -2960,40 +3275,47 @@ void LLMeshRepoThread::notifyLoadedMeshes() { if (mesh.mVolume->getNumVolumeFaces() > 0) { - gMeshRepo.notifyMeshLoaded(mesh.mMeshParams, mesh.mVolume); + gMeshRepo.notifyMeshLoaded(mesh.mMeshParams, mesh.mVolume, mesh.mLOD); } else { - gMeshRepo.notifyMeshUnavailable(mesh.mMeshParams, - LLVolumeLODGroup::getVolumeDetailFromScale(mesh.mVolume->getDetail())); + gMeshRepo.notifyMeshUnavailable(mesh.mMeshParams, mesh.mLOD, LLVolumeLODGroup::getVolumeDetailFromScale(mesh.mVolume->getDetail())); } } } + else + { + mLoadedMutex->unlock(); + } } if (!mUnavailableQ.empty()) { std::deque<LODRequest> unavil_queue; - mMutex->lock(); + mLoadedMutex->lock(); if (!mUnavailableQ.empty()) { unavil_queue.swap(mUnavailableQ); - mMutex->unlock(); + mLoadedMutex->unlock(); update_metrics = true; // Process the elements free of the lock for (const auto& req : unavil_queue) { - gMeshRepo.notifyMeshUnavailable(req.mMeshParams, req.mLOD); + gMeshRepo.notifyMeshUnavailable(req.mMeshParams, req.mLOD, req.mLOD); } } + else + { + mLoadedMutex->unlock(); + } } if (!mSkinInfoQ.empty() || !mSkinUnavailableQ.empty() || ! mDecompositionQ.empty()) { - if (mMutex->trylock()) + if (mLoadedMutex->trylock()) { std::deque<LLPointer<LLMeshSkinInfo>> skin_info_q; std::deque<UUIDBasedRequest> skin_info_unavail_q; @@ -3014,7 +3336,7 @@ void LLMeshRepoThread::notifyLoadedMeshes() decomp_q.swap(mDecompositionQ); } - mMutex->unlock(); + mLoadedMutex->unlock(); // Process the elements free of the lock while (! skin_info_q.empty()) @@ -3051,9 +3373,11 @@ S32 LLMeshRepoThread::getActualMeshLOD(const LLVolumeParams& mesh_params, S32 lo if (iter != mMeshHeader.end()) { - auto& header = iter->second.second; - - return LLMeshRepository::getActualMeshLOD(header, lod); + auto& header = iter->second; + if (header.mHeaderSize > 0) + { + return LLMeshRepository::getActualMeshLOD(header, lod); + } } return lod; @@ -3220,7 +3544,10 @@ void LLMeshHandlerBase::onCompleted(LLCore::HttpHandle handle, LLCore::HttpRespo processData(body, body_offset, data, static_cast<S32>(data_size) - body_offset); - delete [] data; + if (mHasDataOwnership) + { + delete [] data; + } } // Release handler @@ -3253,7 +3580,7 @@ void LLMeshHeaderHandler::processFailure(LLCore::HttpStatus status) << LL_ENDL; // Can't get the header so none of the LODs will be available - LLMutexLock lock(gMeshRepo.mThread->mMutex); + LLMutexLock lock(gMeshRepo.mThread->mLoadedMutex); for (int i(0); i < LLVolumeLODGroup::NUM_LODS; ++i) { gMeshRepo.mThread->mUnavailableQ.push_back(LLMeshRepoThread::LODRequest(mMeshParams, i)); @@ -3263,6 +3590,7 @@ void LLMeshHeaderHandler::processFailure(LLCore::HttpStatus status) void LLMeshHeaderHandler::processData(LLCore::BufferArray * /* body */, S32 /* body_offset */, U8 * data, S32 data_size) { + LL_PROFILE_ZONE_SCOPED; LLUUID mesh_id = mMeshParams.getSculptID(); bool success = (!MESH_HEADER_PROCESS_FAILED) && ((data != NULL) == (data_size > 0)); // if we have data but no size or have size but no data, something is wrong; @@ -3282,7 +3610,7 @@ void LLMeshHeaderHandler::processData(LLCore::BufferArray * /* body */, S32 /* b << LL_ENDL; // Can't get the header so none of the LODs will be available - LLMutexLock lock(gMeshRepo.mThread->mMutex); + LLMutexLock lock(gMeshRepo.mThread->mLoadedMutex); for (int i(0); i < LLVolumeLODGroup::NUM_LODS; ++i) { gMeshRepo.mThread->mUnavailableQ.push_back(LLMeshRepoThread::LODRequest(mMeshParams, i)); @@ -3298,8 +3626,8 @@ void LLMeshHeaderHandler::processData(LLCore::BufferArray * /* body */, S32 /* b LLMeshRepoThread::mesh_header_map::iterator iter = gMeshRepo.mThread->mMeshHeader.find(mesh_id); if (iter != gMeshRepo.mThread->mMeshHeader.end()) { - header_bytes = (S32)iter->second.first; - header = iter->second.second; + header = iter->second; + header_bytes = header.mHeaderSize; } if (header_bytes > 0 @@ -3324,7 +3652,7 @@ void LLMeshHeaderHandler::processData(LLCore::BufferArray * /* body */, S32 /* b // LLSD is smart and can work like smart pointer, is not thread safe. gMeshRepo.mThread->mHeaderMutex->unlock(); - S32 bytes = lod_bytes + header_bytes; + S32 bytes = lod_bytes + header_bytes + CACHE_PREAMBLE_SIZE; // It's possible for the remote asset to have more data than is needed for the local cache @@ -3337,6 +3665,11 @@ void LLMeshHeaderHandler::processData(LLCore::BufferArray * /* body */, S32 /* b LLMeshRepository::sCacheBytesWritten += data_size; ++LLMeshRepository::sCacheWrites; + // write preamble + U32 flags = header.getFlags(); + write_preamble(file, header_bytes, flags); + + // write header file.write(data, data_size); S32 remaining = bytes - file.tell(); @@ -3359,7 +3692,7 @@ void LLMeshHeaderHandler::processData(LLCore::BufferArray * /* body */, S32 /* b gMeshRepo.mThread->mHeaderMutex->unlock(); // headerReceived() parsed header, but header's data is invalid so none of the LODs will be available - LLMutexLock lock(gMeshRepo.mThread->mMutex); + LLMutexLock lock(gMeshRepo.mThread->mLoadedMutex); for (int i(0); i < LLVolumeLODGroup::NUM_LODS; ++i) { gMeshRepo.mThread->mUnavailableQ.push_back(LLMeshRepoThread::LODRequest(mMeshParams, i)); @@ -3388,9 +3721,64 @@ void LLMeshLODHandler::processFailure(LLCore::HttpStatus status) << " (" << status.toTerseString() << "). Not retrying." << LL_ENDL; - LLMutexLock lock(gMeshRepo.mThread->mMutex); + LLMutexLock lock(gMeshRepo.mThread->mLoadedMutex); gMeshRepo.mThread->mUnavailableQ.push_back(LLMeshRepoThread::LODRequest(mMeshParams, mLOD)); } +void LLMeshLODHandler::processLod(U8* data, S32 data_size) +{ + EMeshProcessingResult result = gMeshRepo.mThread->lodReceived(mMeshParams, mLOD, data, data_size); + if (result == MESH_OK) + { + // good fetch from sim, write to cache + LLFileSystem file(mMeshParams.getSculptID(), LLAssetType::AT_MESH, LLFileSystem::READ_WRITE); + + S32 offset = mOffset + CACHE_PREAMBLE_SIZE; + S32 size = mRequestedBytes; + + if (file.getSize() >= offset + size) + { + S32 header_bytes = 0; + U32 flags = 0; + { + LLMutexLock lock(gMeshRepo.mThread->mHeaderMutex); + + LLMeshRepoThread::mesh_header_map::iterator header_it = gMeshRepo.mThread->mMeshHeader.find(mMeshParams.getSculptID()); + if (header_it != gMeshRepo.mThread->mMeshHeader.end()) + { + LLMeshHeader& header = header_it->second; + // update header + if (!header.mLodInCache[mLOD]) + { + header.mLodInCache[mLOD] = true; + header_bytes = header.mHeaderSize; + flags = header.getFlags(); + } + // todo: handle else because we shouldn't have requested twice? + } + } + if (flags > 0) + { + write_preamble(file, header_bytes, flags); + } + + file.seek(offset, 0); + file.write(data, size); + LLMeshRepository::sCacheBytesWritten += size; + ++LLMeshRepository::sCacheWrites; + } + } + else + { + LL_WARNS(LOG_MESH) << "Error during mesh LOD processing. ID: " << mMeshParams.getSculptID() + << ", Reason: " << result + << " LOD: " << mLOD + << " Data size: " << data_size + << " Not retrying." + << LL_ENDL; + LLMutexLock lock(gMeshRepo.mThread->mLoadedMutex); + gMeshRepo.mThread->mUnavailableQ.push_back(LLMeshRepoThread::LODRequest(mMeshParams, mLOD)); + } +} void LLMeshLODHandler::processData(LLCore::BufferArray * /* body */, S32 /* body_offset */, U8 * data, S32 data_size) @@ -3399,33 +3787,26 @@ void LLMeshLODHandler::processData(LLCore::BufferArray * /* body */, S32 /* body if ((!MESH_LOD_PROCESS_FAILED) && ((data != NULL) == (data_size > 0))) // if we have data but no size or have size but no data, something is wrong { - EMeshProcessingResult result = gMeshRepo.mThread->lodReceived(mMeshParams, mLOD, data, data_size); - if (result == MESH_OK) + LLMeshHandlerBase::ptr_t shrd_handler = shared_from_this(); + bool posted = gMeshRepo.mThread->mMeshThreadPool->getQueue().post( + [shrd_handler, data, data_size] + () { - // good fetch from sim, write to cache - LLFileSystem file(mMeshParams.getSculptID(), LLAssetType::AT_MESH, LLFileSystem::READ_WRITE); - - S32 offset = mOffset; - S32 size = mRequestedBytes; + LLMeshLODHandler* handler = (LLMeshLODHandler * )shrd_handler.get(); + handler->processLod(data, data_size); + delete[] data; + }); - if (file.getSize() >= offset+size) - { - file.seek(offset); - file.write(data, size); - LLMeshRepository::sCacheBytesWritten += size; - ++LLMeshRepository::sCacheWrites; - } + if (posted) + { + // ownership of data was passed to the lambda + mHasDataOwnership = false; } else { - LL_WARNS(LOG_MESH) << "Error during mesh LOD processing. ID: " << mMeshParams.getSculptID() - << ", Reason: " << result - << " LOD: " << mLOD - << " Data size: " << data_size - << " Not retrying." - << LL_ENDL; - LLMutexLock lock(gMeshRepo.mThread->mMutex); - gMeshRepo.mThread->mUnavailableQ.push_back(LLMeshRepoThread::LODRequest(mMeshParams, mLOD)); + // mesh thread dies later than event queue, so this is normal + LL_INFOS_ONCE(LOG_MESH) << "Failed to post work into mMeshThreadPool" << LL_ENDL; + processLod(data, data_size); } } else @@ -3435,7 +3816,7 @@ void LLMeshLODHandler::processData(LLCore::BufferArray * /* body */, S32 /* body << " LOD: " << mLOD << " Data size: " << data_size << LL_ENDL; - LLMutexLock lock(gMeshRepo.mThread->mMutex); + LLMutexLock lock(gMeshRepo.mThread->mLoadedMutex); gMeshRepo.mThread->mUnavailableQ.push_back(LLMeshRepoThread::LODRequest(mMeshParams, mLOD)); } } @@ -3446,6 +3827,7 @@ LLMeshSkinInfoHandler::~LLMeshSkinInfoHandler() { LL_WARNS(LOG_MESH) << "deleting unprocessed request handler (may be ok on exit)" << LL_ENDL; } + LLMeshRepoThread::decActiveSkinRequests(); } void LLMeshSkinInfoHandler::processFailure(LLCore::HttpStatus status) @@ -3454,38 +3836,98 @@ void LLMeshSkinInfoHandler::processFailure(LLCore::HttpStatus status) << ", Reason: " << status.toString() << " (" << status.toTerseString() << "). Not retrying." << LL_ENDL; - LLMutexLock lock(gMeshRepo.mThread->mMutex); + LLMutexLock lock(gMeshRepo.mThread->mLoadedMutex); gMeshRepo.mThread->mSkinUnavailableQ.emplace_back(mMeshID); } -void LLMeshSkinInfoHandler::processData(LLCore::BufferArray * /* body */, S32 /* body_offset */, - U8 * data, S32 data_size) +void LLMeshSkinInfoHandler::processSkin(U8* data, S32 data_size) { - LL_PROFILE_ZONE_SCOPED; - if ((!MESH_SKIN_INFO_PROCESS_FAILED) - && ((data != NULL) == (data_size > 0)) // if we have data but no size or have size but no data, something is wrong - && gMeshRepo.mThread->skinInfoReceived(mMeshID, data, data_size)) + if (gMeshRepo.mThread->skinInfoReceived(mMeshID, data, data_size)) { // good fetch from sim, write to cache LLFileSystem file(mMeshID, LLAssetType::AT_MESH, LLFileSystem::READ_WRITE); - S32 offset = mOffset; + S32 offset = mOffset + CACHE_PREAMBLE_SIZE; S32 size = mRequestedBytes; - if (file.getSize() >= offset+size) + if (file.getSize() >= offset + size) { LLMeshRepository::sCacheBytesWritten += size; ++LLMeshRepository::sCacheWrites; - file.seek(offset); + + S32 header_bytes = 0; + U32 flags = 0; + { + LLMutexLock lock(gMeshRepo.mThread->mHeaderMutex); + + LLMeshRepoThread::mesh_header_map::iterator header_it = gMeshRepo.mThread->mMeshHeader.find(mMeshID); + if (header_it != gMeshRepo.mThread->mMeshHeader.end()) + { + LLMeshHeader& header = header_it->second; + // update header + if (!header.mSkinInCache) + { + header.mSkinInCache = true; + header_bytes = header.mHeaderSize; + flags = header.getFlags(); + } + // todo: handle else because we shouldn't have requested twice? + } + } + if (flags > 0) + { + write_preamble(file, header_bytes, flags); + } + + file.seek(offset, 0); file.write(data, size); } } else { LL_WARNS(LOG_MESH) << "Error during mesh skin info processing. ID: " << mMeshID + << ", Unknown reason. Not retrying." + << LL_ENDL; + LLMutexLock lock(gMeshRepo.mThread->mLoadedMutex); + gMeshRepo.mThread->mSkinUnavailableQ.emplace_back(mMeshID); + } +} + +void LLMeshSkinInfoHandler::processData(LLCore::BufferArray * /* body */, S32 /* body_offset */, + U8 * data, S32 data_size) +{ + LL_PROFILE_ZONE_SCOPED; + if ((!MESH_SKIN_INFO_PROCESS_FAILED) + && ((data != NULL) == (data_size > 0))) // if we have data but no size or have size but no data, something is wrong + { + LLMeshHandlerBase::ptr_t shrd_handler = shared_from_this(); + bool posted = gMeshRepo.mThread->mMeshThreadPool->getQueue().post( + [shrd_handler, data, data_size] + () + { + LLMeshSkinInfoHandler* handler = (LLMeshSkinInfoHandler*)shrd_handler.get(); + handler->processSkin(data, data_size); + delete[] data; + }); + + if (posted) + { + // ownership of data was passed to the lambda + mHasDataOwnership = false; + } + else + { + // mesh thread dies later than event queue, so this is normal + LL_INFOS_ONCE(LOG_MESH) << "Failed to post work into mMeshThreadPool" << LL_ENDL; + processSkin(data, data_size); + } + } + else + { + LL_WARNS(LOG_MESH) << "Error during mesh skin info processing. ID: " << mMeshID << ", Unknown reason. Not retrying." << LL_ENDL; - LLMutexLock lock(gMeshRepo.mThread->mMutex); + LLMutexLock lock(gMeshRepo.mThread->mLoadedMutex); gMeshRepo.mThread->mSkinUnavailableQ.emplace_back(mMeshID); } } @@ -3519,14 +3961,39 @@ void LLMeshDecompositionHandler::processData(LLCore::BufferArray * /* body */, S // good fetch from sim, write to cache LLFileSystem file(mMeshID, LLAssetType::AT_MESH, LLFileSystem::READ_WRITE); - S32 offset = mOffset; + S32 offset = mOffset + CACHE_PREAMBLE_SIZE; S32 size = mRequestedBytes; if (file.getSize() >= offset+size) { LLMeshRepository::sCacheBytesWritten += size; ++LLMeshRepository::sCacheWrites; - file.seek(offset); + + S32 header_bytes = 0; + U32 flags = 0; + { + LLMutexLock lock(gMeshRepo.mThread->mHeaderMutex); + + LLMeshRepoThread::mesh_header_map::iterator header_it = gMeshRepo.mThread->mMeshHeader.find(mMeshID); + if (header_it != gMeshRepo.mThread->mMeshHeader.end()) + { + LLMeshHeader& header = header_it->second; + // update header + if (!header.mPhysicsConvexInCache) + { + header.mPhysicsConvexInCache = true; + header_bytes = header.mHeaderSize; + flags = header.getFlags(); + } + // todo: handle else because we shouldn't have requested twice? + } + } + if (flags > 0) + { + write_preamble(file, header_bytes, flags); + } + + file.seek(offset, 0); file.write(data, size); } } @@ -3567,14 +4034,39 @@ void LLMeshPhysicsShapeHandler::processData(LLCore::BufferArray * /* body */, S3 // good fetch from sim, write to cache for caching LLFileSystem file(mMeshID, LLAssetType::AT_MESH, LLFileSystem::READ_WRITE); - S32 offset = mOffset; + S32 offset = mOffset + CACHE_PREAMBLE_SIZE; S32 size = mRequestedBytes; if (file.getSize() >= offset+size) { LLMeshRepository::sCacheBytesWritten += size; ++LLMeshRepository::sCacheWrites; - file.seek(offset); + + S32 header_bytes = 0; + U32 flags = 0; + { + LLMutexLock lock(gMeshRepo.mThread->mHeaderMutex); + + LLMeshRepoThread::mesh_header_map::iterator header_it = gMeshRepo.mThread->mMeshHeader.find(mMeshID); + if (header_it != gMeshRepo.mThread->mMeshHeader.end()) + { + LLMeshHeader& header = header_it->second; + // update header + if (!header.mPhysicsMeshInCache) + { + header.mPhysicsMeshInCache = true; + header_bytes = header.mHeaderSize; + flags = header.getFlags(); + } + // todo: handle else because we shouldn't have requested twice? + } + } + if (flags > 0) + { + write_preamble(file, header_bytes, flags); + } + + file.seek(offset, 0); file.write(data, size); } } @@ -3636,6 +4128,7 @@ void LLMeshRepository::shutdown() } mThread->mSignal->broadcast(); + mThread->mMeshThreadPool->close(); while (!mThread->isStopped()) { @@ -3710,24 +4203,24 @@ void LLMeshRepository::unregisterMesh(LLVOVolume* vobj) } } -S32 LLMeshRepository::loadMesh(LLVOVolume* vobj, const LLVolumeParams& mesh_params, S32 detail, S32 last_lod) +S32 LLMeshRepository::loadMesh(LLVOVolume* vobj, const LLVolumeParams& mesh_params, S32 new_lod, S32 last_lod) { LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK; //LL_LL_RECORD_BLOCK_TIME(FTM_MESH_FETCH); // Manage time-to-load metrics for mesh download operations. metricsProgress(1); - if (detail < 0 || detail >= LLVolumeLODGroup::NUM_LODS) + if (new_lod < 0 || new_lod >= LLVolumeLODGroup::NUM_LODS) { - return detail; + return new_lod; } { LLMutexLock lock(mMeshMutex); //add volume to list of loading meshes const auto& mesh_id = mesh_params.getSculptID(); - mesh_load_map::iterator iter = mLoadingMeshes[detail].find(mesh_id); - if (iter != mLoadingMeshes[detail].end()) + mesh_load_map::iterator iter = mLoadingMeshes[new_lod].find(mesh_id); + if (iter != mLoadingMeshes[new_lod].end()) { //request pending for this mesh, append volume id to list auto it = std::find(iter->second.begin(), iter->second.end(), vobj); if (it == iter->second.end()) { @@ -3737,8 +4230,8 @@ S32 LLMeshRepository::loadMesh(LLVOVolume* vobj, const LLVolumeParams& mesh_para else { //first request for this mesh - mLoadingMeshes[detail][mesh_id].push_back(vobj); - mPendingRequests.push_back(LLMeshRepoThread::LODRequest(mesh_params, detail)); + mLoadingMeshes[new_lod][mesh_id].push_back(vobj); + mPendingRequests.emplace_back(new PendingRequestLOD(mesh_params, new_lod)); LLMeshRepository::sLODPending++; } } @@ -3767,7 +4260,7 @@ S32 LLMeshRepository::loadMesh(LLVOVolume* vobj, const LLVolumeParams& mesh_para } //next, see what the next lowest LOD available might be - for (S32 i = detail-1; i >= 0; --i) + for (S32 i = new_lod -1; i >= 0; --i) { LLVolume* lod = group->refLOD(i); if (lod && lod->isMeshAssetLoaded() && lod->getNumVolumeFaces() > 0) @@ -3780,7 +4273,7 @@ S32 LLMeshRepository::loadMesh(LLVOVolume* vobj, const LLVolumeParams& mesh_para } //no lower LOD is a available, is a higher lod available? - for (S32 i = detail+1; i < LLVolumeLODGroup::NUM_LODS; ++i) + for (S32 i = new_lod+1; i < LLVolumeLODGroup::NUM_LODS; ++i) { LLVolume* lod = group->refLOD(i); if (lod && lod->isMeshAssetLoaded() && lod->getNumVolumeFaces() > 0) @@ -3794,7 +4287,51 @@ S32 LLMeshRepository::loadMesh(LLVOVolume* vobj, const LLVolumeParams& mesh_para } } - return detail; + return new_lod; +} + +F32 calculate_score(LLVOVolume* object) +{ + if (!object) + { + return -1.f; + } + LLDrawable* drawable = object->mDrawable; + if (!drawable) + { + return -1; + } + if (drawable->isState(LLDrawable::RIGGED) || object->isAttachment()) + { + LLVOAvatar* avatar = object->getAvatar(); + LLDrawable* av_drawable = avatar ? avatar->mDrawable : nullptr; + if (avatar && av_drawable) + { + // See LLVOVolume::calcLOD() + F32 radius; + if (avatar->isControlAvatar()) + { + const LLVector3* box = avatar->getLastAnimExtents(); + LLVector3 diag = box[1] - box[0]; + radius = diag.magVec() * 0.5f; + } + else + { + // Volume in a rigged mesh attached to a regular avatar. + const LLVector3* box = avatar->getLastAnimExtents(); + LLVector3 diag = box[1] - box[0]; + radius = diag.magVec(); + + if (!avatar->isSelf() && !avatar->hasFirstFullAttachmentData()) + { + // slightly deprioritize avatars that are still receiving data + radius *= 0.9f; + } + } + return radius / llmax(av_drawable->mDistanceWRTCamera, 1.f); + } + } + return drawable->getRadius() / llmax(drawable->mDistanceWRTCamera, 1.f); } void LLMeshRepository::notifyLoadedMeshes() @@ -3916,8 +4453,9 @@ void LLMeshRepository::notifyLoadedMeshes() } // erase from background thread - mThread->mWorkQueue.post([=]() + mThread->mWorkQueue.post([=, this]() { + LLMutexLock(mThread->mSkinMapMutex); mThread->mSkinMap.erase(id); }); } @@ -3974,8 +4512,12 @@ void LLMeshRepository::notifyLoadedMeshes() mUploadErrorQ.pop(); } - S32 active_count = LLMeshRepoThread::sActiveHeaderRequests + LLMeshRepoThread::sActiveLODRequests; - if (active_count < LLMeshRepoThread::sRequestLowWater) + // mPendingRequests go into queues, queues go into active http requests. + // Checking sRequestHighWater to keep queues at least somewhat populated + // for faster transition into http + S32 active_count = LLMeshRepoThread::sActiveHeaderRequests + LLMeshRepoThread::sActiveLODRequests + LLMeshRepoThread::sActiveSkinRequests; + active_count += (S32)(mThread->mLODReqQ.size() + mThread->mHeaderReqQ.size() + mThread->mSkinInfoQ.size()); + if (active_count < LLMeshRepoThread::sRequestHighWater) { S32 push_count = LLMeshRepoThread::sRequestHighWater - active_count; @@ -3996,50 +4538,71 @@ void LLMeshRepository::notifyLoadedMeshes() F32 max_score = 0.f; for (auto obj_iter = iter->second.begin(); obj_iter != iter->second.end(); ++obj_iter) { - LLVOVolume* object = *obj_iter; - if (object) + F32 cur_score = calculate_score(*obj_iter); + if (cur_score >= 0.f) { - LLDrawable* drawable = object->mDrawable; - if (drawable) - { - F32 cur_score = drawable->getRadius()/llmax(drawable->mDistanceWRTCamera, 1.f); - max_score = llmax(max_score, cur_score); - } + max_score = llmax(max_score, cur_score); } } score_map[iter->first] = max_score; } } + for (mesh_load_map::iterator iter = mLoadingSkins.begin(); iter != mLoadingSkins.end(); ++iter) + { + F32 max_score = 0.f; + for (auto obj_iter = iter->second.begin(); obj_iter != iter->second.end(); ++obj_iter) + { + F32 cur_score = calculate_score(*obj_iter); + if (cur_score >= 0.f) + { + max_score = llmax(max_score, cur_score); + } + } + + score_map[iter->first] = max_score; + } //set "score" for pending requests - for (std::vector<LLMeshRepoThread::LODRequest>::iterator iter = mPendingRequests.begin(); iter != mPendingRequests.end(); ++iter) + for (std::unique_ptr<PendingRequestBase>& req_p : mPendingRequests) { - iter->mScore = score_map[iter->mMeshParams.getSculptID()]; + req_p->setScore(score_map[req_p->getId()]); } //sort by "score" std::partial_sort(mPendingRequests.begin(), mPendingRequests.begin() + push_count, - mPendingRequests.end(), LLMeshRepoThread::CompareScoreGreater()); + mPendingRequests.end(), PendingRequestBase::CompareScoreGreater()); } - + LLMutexTrylock lock3(mThread->mHeaderMutex); + LLMutexTrylock lock4(mThread->mPendingMutex); while (!mPendingRequests.empty() && push_count > 0) { - LLMeshRepoThread::LODRequest& request = mPendingRequests.front(); - mThread->loadMeshLOD(request.mMeshParams, request.mLOD); + std::unique_ptr<PendingRequestBase>& req_p = mPendingRequests.front(); + switch (req_p->getRequestType()) + { + case MESH_REQUEST_LOD: + { + PendingRequestLOD* lod = (PendingRequestLOD*)req_p.get(); + mThread->loadMeshLOD(lod->mMeshParams, lod->mLOD); + LLMeshRepository::sLODPending--; + break; + } + case MESH_REQUEST_SKIN: + { + PendingRequestUUID* skin = (PendingRequestUUID*)req_p.get(); + mThread->loadMeshSkinInfo(skin->getId()); + break; + } + + default: + LL_ERRS() << "Unknown request type in LLMeshRepository::notifyLoadedMeshes" << LL_ENDL; + break; + } mPendingRequests.erase(mPendingRequests.begin()); - LLMeshRepository::sLODPending--; push_count--; } } - //send skin info requests - while (!mPendingSkinRequests.empty()) - { - mThread->loadMeshSkinInfo(mPendingSkinRequests.front()); - mPendingSkinRequests.pop(); - } - //send decomposition requests while (!mPendingDecompositionRequests.empty()) { @@ -4116,15 +4679,14 @@ void LLMeshRepository::notifyDecompositionReceived(LLModel::Decomposition* decom } } -void LLMeshRepository::notifyMeshLoaded(const LLVolumeParams& mesh_params, LLVolume* volume) +void LLMeshRepository::notifyMeshLoaded(const LLVolumeParams& mesh_params, LLVolume* volume, S32 lod) { //called from main thread - S32 detail = LLVolumeLODGroup::getVolumeDetailFromScale(volume->getDetail()); //get list of objects waiting to be notified this mesh is loaded const auto& mesh_id = mesh_params.getSculptID(); - mesh_load_map::iterator obj_iter = mLoadingMeshes[detail].find(mesh_id); + mesh_load_map::iterator obj_iter = mLoadingMeshes[lod].find(mesh_id); - if (volume && obj_iter != mLoadingMeshes[detail].end()) + if (volume && obj_iter != mLoadingMeshes[lod].end()) { //make sure target volume is still valid if (volume->getNumVolumeFaces() <= 0) @@ -4134,6 +4696,7 @@ void LLMeshRepository::notifyMeshLoaded(const LLVolumeParams& mesh_params, LLVol } { //update system volume + S32 detail = LLVolumeLODGroup::getVolumeDetailFromScale(volume->getDetail()); LLVolume* sys_volume = LLPrimitive::getVolumeManager()->refVolume(mesh_params, detail); if (sys_volume) { @@ -4157,22 +4720,22 @@ void LLMeshRepository::notifyMeshLoaded(const LLVolumeParams& mesh_params, LLVol } } - mLoadingMeshes[detail].erase(obj_iter); + mLoadingMeshes[lod].erase(obj_iter); LLViewerStatsRecorder::instance().meshLoaded(); } } -void LLMeshRepository::notifyMeshUnavailable(const LLVolumeParams& mesh_params, S32 lod) +void LLMeshRepository::notifyMeshUnavailable(const LLVolumeParams& mesh_params, S32 request_lod, S32 volume_lod) { //called from main thread //get list of objects waiting to be notified this mesh is loaded const auto& mesh_id = mesh_params.getSculptID(); - mesh_load_map::iterator obj_iter = mLoadingMeshes[lod].find(mesh_id); - if (obj_iter != mLoadingMeshes[lod].end()) + mesh_load_map::iterator obj_iter = mLoadingMeshes[request_lod].find(mesh_id); + if (obj_iter != mLoadingMeshes[request_lod].end()) { - F32 detail = LLVolumeLODGroup::getVolumeScaleFromDetail(lod); + F32 detail = LLVolumeLODGroup::getVolumeScaleFromDetail(volume_lod); - LLVolume* sys_volume = LLPrimitive::getVolumeManager()->refVolume(mesh_params, lod); + LLVolume* sys_volume = LLPrimitive::getVolumeManager()->refVolume(mesh_params, volume_lod); if (sys_volume) { sys_volume->setMeshAssetUnavaliable(true); @@ -4189,12 +4752,12 @@ void LLMeshRepository::notifyMeshUnavailable(const LLVolumeParams& mesh_params, obj_volume->getDetail() == detail && obj_volume->getParams() == mesh_params) { //should force volume to find most appropriate LOD - vobj->setVolume(obj_volume->getParams(), lod); + vobj->setVolume(obj_volume->getParams(), volume_lod); } } } - mLoadingMeshes[lod].erase(obj_iter); + mLoadingMeshes[request_lod].erase(obj_iter); } } @@ -4231,7 +4794,7 @@ const LLMeshSkinInfo* LLMeshRepository::getSkinInfo(const LLUUID& mesh_id, LLVOV { //first request for this mesh mLoadingSkins[mesh_id].push_back(requesting_obj); - mPendingSkinRequests.push(mesh_id); + mPendingRequests.emplace_back(new PendingRequestUUID(mesh_id, MESH_REQUEST_SKIN)); } } } @@ -4358,7 +4921,7 @@ bool LLMeshRepository::hasSkinInfo(const LLUUID& mesh_id) return false; } -bool LLMeshRepository::hasHeader(const LLUUID& mesh_id) +bool LLMeshRepository::hasHeader(const LLUUID& mesh_id) const { if (mesh_id.isNull()) { @@ -4368,13 +4931,13 @@ bool LLMeshRepository::hasHeader(const LLUUID& mesh_id) return mThread->hasHeader(mesh_id); } -bool LLMeshRepoThread::hasPhysicsShapeInHeader(const LLUUID& mesh_id) +bool LLMeshRepoThread::hasPhysicsShapeInHeader(const LLUUID& mesh_id) const { LLMutexLock lock(mHeaderMutex); - mesh_header_map::iterator iter = mMeshHeader.find(mesh_id); - if (iter != mMeshHeader.end() && iter->second.first > 0) + mesh_header_map::const_iterator iter = mMeshHeader.find(mesh_id); + if (iter != mMeshHeader.end() && iter->second.mHeaderSize > 0) { - LLMeshHeader &mesh = iter->second.second; + const LLMeshHeader &mesh = iter->second; if (mesh.mPhysicsMeshSize > 0) { return true; @@ -4384,13 +4947,13 @@ bool LLMeshRepoThread::hasPhysicsShapeInHeader(const LLUUID& mesh_id) return false; } -bool LLMeshRepoThread::hasSkinInfoInHeader(const LLUUID& mesh_id) +bool LLMeshRepoThread::hasSkinInfoInHeader(const LLUUID& mesh_id) const { LLMutexLock lock(mHeaderMutex); - mesh_header_map::iterator iter = mMeshHeader.find(mesh_id); - if (iter != mMeshHeader.end() && iter->second.first > 0) + mesh_header_map::const_iterator iter = mMeshHeader.find(mesh_id); + if (iter != mMeshHeader.end() && iter->second.mHeaderSize > 0) { - LLMeshHeader& mesh = iter->second.second; + const LLMeshHeader& mesh = iter->second; if (mesh.mSkinOffset >= 0 && mesh.mSkinSize > 0) { @@ -4401,10 +4964,10 @@ bool LLMeshRepoThread::hasSkinInfoInHeader(const LLUUID& mesh_id) return false; } -bool LLMeshRepoThread::hasHeader(const LLUUID& mesh_id) +bool LLMeshRepoThread::hasHeader(const LLUUID& mesh_id) const { LLMutexLock lock(mHeaderMutex); - mesh_header_map::iterator iter = mMeshHeader.find(mesh_id); + mesh_header_map::const_iterator iter = mMeshHeader.find(mesh_id); return iter != mMeshHeader.end(); } @@ -4419,16 +4982,16 @@ void LLMeshRepository::uploadModel(std::vector<LLModelInstance>& data, LLVector3 mUploadWaitList.push_back(thread); } -S32 LLMeshRepository::getMeshSize(const LLUUID& mesh_id, S32 lod) +S32 LLMeshRepository::getMeshSize(const LLUUID& mesh_id, S32 lod) const { LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME; if (mThread && mesh_id.notNull() && LLPrimitive::NO_LOD != lod) { LLMutexLock lock(mThread->mHeaderMutex); - LLMeshRepoThread::mesh_header_map::iterator iter = mThread->mMeshHeader.find(mesh_id); - if (iter != mThread->mMeshHeader.end() && iter->second.first > 0) + LLMeshRepoThread::mesh_header_map::const_iterator iter = mThread->mMeshHeader.find(mesh_id); + if (iter != mThread->mMeshHeader.end() && iter->second.mHeaderSize > 0) { - const LLMeshHeader& header = iter->second.second; + const LLMeshHeader& header = iter->second; if (header.m404) { @@ -4532,9 +5095,9 @@ F32 LLMeshRepository::getStreamingCostLegacy(LLUUID mesh_id, F32 radius, S32* by { LLMutexLock lock(mThread->mHeaderMutex); LLMeshRepoThread::mesh_header_map::iterator iter = mThread->mMeshHeader.find(mesh_id); - if (iter != mThread->mMeshHeader.end() && iter->second.first > 0) + if (iter != mThread->mMeshHeader.end() && iter->second.mHeaderSize > 0) { - result = getStreamingCostLegacy(iter->second.second, radius, bytes, bytes_visible, lod, unscaled_value); + result = getStreamingCostLegacy(iter->second, radius, bytes, bytes_visible, lod, unscaled_value); } } if (result > 0.f) @@ -4726,7 +5289,7 @@ bool LLMeshCostData::init(const LLMeshHeader& header) } -S32 LLMeshCostData::getSizeByLOD(S32 lod) +S32 LLMeshCostData::getSizeByLOD(S32 lod) const { if (llclamp(lod,0,3) != lod) { @@ -4735,12 +5298,12 @@ S32 LLMeshCostData::getSizeByLOD(S32 lod) return mSizeByLOD[lod]; } -S32 LLMeshCostData::getSizeTotal() +S32 LLMeshCostData::getSizeTotal() const { return mSizeByLOD[0] + mSizeByLOD[1] + mSizeByLOD[2] + mSizeByLOD[3]; } -F32 LLMeshCostData::getEstTrisByLOD(S32 lod) +F32 LLMeshCostData::getEstTrisByLOD(S32 lod) const { if (llclamp(lod,0,3) != lod) { @@ -4749,12 +5312,12 @@ F32 LLMeshCostData::getEstTrisByLOD(S32 lod) return mEstTrisByLOD[lod]; } -F32 LLMeshCostData::getEstTrisMax() +F32 LLMeshCostData::getEstTrisMax() const { return llmax(mEstTrisByLOD[0], mEstTrisByLOD[1], mEstTrisByLOD[2], mEstTrisByLOD[3]); } -F32 LLMeshCostData::getRadiusWeightedTris(F32 radius) +F32 LLMeshCostData::getRadiusWeightedTris(F32 radius) const { F32 max_distance = 512.f; @@ -4798,7 +5361,7 @@ F32 LLMeshCostData::getRadiusWeightedTris(F32 radius) return weighted_avg; } -F32 LLMeshCostData::getEstTrisForStreamingCost() +F32 LLMeshCostData::getEstTrisForStreamingCost() const { LL_DEBUGS("StreamingCost") << "tris_by_lod: " << mEstTrisByLOD[0] << ", " @@ -4808,7 +5371,7 @@ F32 LLMeshCostData::getEstTrisForStreamingCost() F32 charged_tris = mEstTrisByLOD[3]; F32 allowed_tris = mEstTrisByLOD[3]; - const F32 ENFORCE_FLOOR = 64.0f; + constexpr F32 ENFORCE_FLOOR = 64.0f; for (S32 i=2; i>=0; i--) { // How many tris can we have in this LOD without affecting land impact? @@ -4825,13 +5388,13 @@ F32 LLMeshCostData::getEstTrisForStreamingCost() return charged_tris; } -F32 LLMeshCostData::getRadiusBasedStreamingCost(F32 radius) +F32 LLMeshCostData::getRadiusBasedStreamingCost(F32 radius) const { static LLCachedControl<U32> mesh_triangle_budget(gSavedSettings, "MeshTriangleBudget"); return getRadiusWeightedTris(radius)/mesh_triangle_budget*15000.f; } -F32 LLMeshCostData::getTriangleBasedStreamingCost() +F32 LLMeshCostData::getTriangleBasedStreamingCost() const { F32 result = ANIMATED_OBJECT_COST_PER_KTRI * 0.001f * getEstTrisForStreamingCost(); return result; @@ -4846,9 +5409,9 @@ bool LLMeshRepository::getCostData(LLUUID mesh_id, LLMeshCostData& data) { LLMutexLock lock(mThread->mHeaderMutex); LLMeshRepoThread::mesh_header_map::iterator iter = mThread->mMeshHeader.find(mesh_id); - if (iter != mThread->mMeshHeader.end() && iter->second.first > 0) + if (iter != mThread->mMeshHeader.end() && iter->second.mHeaderSize > 0) { - LLMeshHeader& header = iter->second.second; + LLMeshHeader& header = iter->second; bool header_invalid = (header.m404 || header.mLodSize[0] <= 0 diff --git a/indra/newview/llmeshrepository.h b/indra/newview/llmeshrepository.h index b5c2424578..0d9da32e27 100644 --- a/indra/newview/llmeshrepository.h +++ b/indra/newview/llmeshrepository.h @@ -63,6 +63,16 @@ typedef enum e_mesh_processing_result_enum MESH_UNKNOWN } EMeshProcessingResult; +typedef enum e_mesh_request_type_enum +{ + MESH_REQUEST_HEADER, + MESH_REQUEST_LOD, + MESH_REQUEST_SKIN, + MESH_REQUEST_DECOMPOSITION, + MESH_REQUEST_PHYSICS, + MESH_REQUEST_UKNOWN +} EMeshRequestType; + class LLMeshUploadData { public: @@ -183,7 +193,8 @@ public: class RequestStats { public: - RequestStats() : mRetries(0) {}; + + RequestStats() :mRetries(0) {}; void updateTime(); bool canRetry() const; @@ -195,6 +206,67 @@ private: LLFrameTimer mTimer; }; + +class PendingRequestBase +{ +public: + struct CompareScoreGreater + { + bool operator()(const std::unique_ptr<PendingRequestBase>& lhs, const std::unique_ptr<PendingRequestBase>& rhs) + { + return lhs->mScore > rhs->mScore; // greatest = first + } + }; + + PendingRequestBase() : mScore(0.f) {}; + virtual ~PendingRequestBase() {} + + bool operator<(const PendingRequestBase& rhs) const + { + return mId < rhs.mId; + } + + void setScore(F32 score) { mScore = score; } + F32 getScore() const { return mScore; } + LLUUID getId() const { return mId; } + virtual EMeshRequestType getRequestType() const = 0; + +protected: + F32 mScore; + LLUUID mId; +}; + +class PendingRequestLOD : public PendingRequestBase +{ +public: + LLVolumeParams mMeshParams; + S32 mLOD; + + PendingRequestLOD(const LLVolumeParams& mesh_params, S32 lod) + : PendingRequestBase(), mMeshParams(mesh_params), mLOD(lod) + { + mId = mMeshParams.getSculptID(); + } + + EMeshRequestType getRequestType() const override { return MESH_REQUEST_LOD; } +}; + +class PendingRequestUUID : public PendingRequestBase +{ +public: + + PendingRequestUUID(const LLUUID& id, EMeshRequestType type) + : PendingRequestBase(), mRequestType(type) + { + mId = id; + } + + EMeshRequestType getRequestType() const override { return mRequestType; } + +private: + EMeshRequestType mRequestType; +}; + class LLMeshHeader { public: @@ -235,19 +307,67 @@ public: m404 = header.has("404"); } +private: + + enum EDiskCacheFlags { + FLAG_SKIN = 1 << LLModel::NUM_LODS, + FLAG_PHYSCONVEX = 1 << (LLModel::NUM_LODS + 1), + FLAG_PHYSMESH = 1 << (LLModel::NUM_LODS + 2), + }; +public: + U32 getFlags() + { + U32 flags = 0; + for (U32 i = 0; i < LLModel::NUM_LODS; i++) + { + if (mLodInCache[i]) + { + flags |= 1 << i; + } + } + if (mSkinInCache) + { + flags |= FLAG_SKIN; + } + if (mPhysicsConvexInCache) + { + flags |= FLAG_PHYSCONVEX; + } + if (mPhysicsMeshInCache) + { + flags |= FLAG_PHYSMESH; + } + return flags; + } + + void setFromFlags(U32 flags) + { + for (U32 i = 0; i < LLModel::NUM_LODS; i++) + { + mLodInCache[i] = (flags & (1 << i)) != 0; + } + mSkinInCache = (flags & FLAG_SKIN) != 0; + mPhysicsConvexInCache = (flags & FLAG_PHYSCONVEX) != 0; + mPhysicsMeshInCache = (flags & FLAG_PHYSMESH) != 0; + } S32 mVersion = -1; S32 mSkinOffset = -1; S32 mSkinSize = -1; + bool mSkinInCache = false; S32 mPhysicsConvexOffset = -1; S32 mPhysicsConvexSize = -1; + bool mPhysicsConvexInCache = false; S32 mPhysicsMeshOffset = -1; S32 mPhysicsMeshSize = -1; + bool mPhysicsMeshInCache = false; - S32 mLodOffset[4] = { -1 }; - S32 mLodSize[4] = { -1 }; + S32 mLodOffset[LLModel::NUM_LODS] = { -1 }; + S32 mLodSize[LLModel::NUM_LODS] = { -1 }; + bool mLodInCache[LLModel::NUM_LODS] = { false }; + S32 mHeaderSize = -1; bool m404 = false; }; @@ -256,8 +376,9 @@ class LLMeshRepoThread : public LLThread { public: - volatile static S32 sActiveHeaderRequests; - volatile static S32 sActiveLODRequests; + static std::atomic<S32> sActiveHeaderRequests; + static std::atomic<S32> sActiveLODRequests; + static std::atomic<S32> sActiveSkinRequests; static U32 sMaxConcurrentRequests; static S32 sRequestLowWater; static S32 sRequestHighWater; @@ -265,10 +386,13 @@ public: LLMutex* mMutex; LLMutex* mHeaderMutex; + LLMutex* mLoadedMutex; + LLMutex* mPendingMutex; + LLMutex* mSkinMapMutex; LLCondition* mSignal; //map of known mesh headers - typedef boost::unordered_map<LLUUID, std::pair<U32, LLMeshHeader>> mesh_header_map; // pair is header_size and data + typedef boost::unordered_map<LLUUID, LLMeshHeader> mesh_header_map; // pair is header_size and data mesh_header_map mMeshHeader; class HeaderRequest : public RequestStats @@ -292,19 +416,10 @@ public: public: LLVolumeParams mMeshParams; S32 mLOD; - F32 mScore; LODRequest(const LLVolumeParams& mesh_params, S32 lod) - : RequestStats(), mMeshParams(mesh_params), mLOD(lod), mScore(0.f) - { - } - }; - - struct CompareScoreGreater - { - bool operator()(const LODRequest& lhs, const LODRequest& rhs) + : RequestStats(), mMeshParams(mesh_params), mLOD(lod) { - return lhs.mScore > rhs.mScore; // greatest = first } }; @@ -369,7 +484,7 @@ public: std::deque<LoadedMesh> mLoadedQ; //map of pending header requests and currently desired LODs - typedef std::unordered_map<LLUUID, std::vector<S32> > pending_lod_map; + typedef std::unordered_map<LLUUID, std::array<S32, LLModel::NUM_LODS> > pending_lod_map; pending_lod_map mPendingLOD; // map of mesh ID to skin info (mirrors LLMeshRepository::mSkinMap) @@ -379,6 +494,8 @@ public: // workqueue for processing generic requests LL::WorkQueue mWorkQueue; + // lods have their own thread due to costly cacheOptimize() calls + std::unique_ptr<LL::ThreadPool> mMeshThreadPool; // llcorehttp library interface objects. LLCore::HttpStatus mHttpStatus; @@ -402,16 +519,16 @@ public: void lockAndLoadMeshLOD(const LLVolumeParams& mesh_params, S32 lod); void loadMeshLOD(const LLVolumeParams& mesh_params, S32 lod); - bool fetchMeshHeader(const LLVolumeParams& mesh_params, bool can_retry = true); - bool fetchMeshLOD(const LLVolumeParams& mesh_params, S32 lod, bool can_retry = true); - EMeshProcessingResult headerReceived(const LLVolumeParams& mesh_params, U8* data, S32 data_size); + bool fetchMeshHeader(const LLVolumeParams& mesh_params); + bool fetchMeshLOD(const LLVolumeParams& mesh_params, S32 lod); + EMeshProcessingResult headerReceived(const LLVolumeParams& mesh_params, U8* data, S32 data_size, U32 flags = 0); EMeshProcessingResult lodReceived(const LLVolumeParams& mesh_params, S32 lod, U8* data, S32 data_size); bool skinInfoReceived(const LLUUID& mesh_id, U8* data, S32 data_size); bool decompositionReceived(const LLUUID& mesh_id, U8* data, S32 data_size); EMeshProcessingResult physicsShapeReceived(const LLUUID& mesh_id, U8* data, S32 data_size); - bool hasPhysicsShapeInHeader(const LLUUID& mesh_id); - bool hasSkinInfoInHeader(const LLUUID& mesh_id); - bool hasHeader(const LLUUID& mesh_id); + bool hasPhysicsShapeInHeader(const LLUUID& mesh_id) const; + bool hasSkinInfoInHeader(const LLUUID& mesh_id) const; + bool hasHeader(const LLUUID& mesh_id) const; void notifyLoadedMeshes(); S32 getActualMeshLOD(const LLVolumeParams& mesh_params, S32 lod); @@ -422,7 +539,7 @@ public: //send request for skin info, returns true if header info exists // (should hold onto mesh_id and try again later if header info does not exist) - bool fetchMeshSkinInfo(const LLUUID& mesh_id, bool can_retry = true); + bool fetchMeshSkinInfo(const LLUUID& mesh_id); //send request for decomposition, returns true if header info exists // (should hold onto mesh_id and try again later if header info does not exist) @@ -436,6 +553,8 @@ public: static void decActiveLODRequests(); static void incActiveHeaderRequests(); static void decActiveHeaderRequests(); + static void incActiveSkinRequests(); + static void decActiveSkinRequests(); // Set the caps strings and preferred version for constructing // mesh fetch URLs. @@ -456,6 +575,14 @@ private: LLCore::HttpHandle getByteRange(const std::string & url, size_t offset, size_t len, const LLCore::HttpHandler::ptr_t &handler); + + // Mutex: acquires mPendingMutex, mMutex and mHeaderMutex as needed + void loadMeshLOD(const LLUUID &mesh_id, const LLVolumeParams& mesh_params, S32 lod); + + // Threads: Repo thread only + U8* getDiskCacheBuffer(S32 size); + S32 mDiskCacheBufferSize = 0; + U8* mDiskCacheBuffer = nullptr; }; @@ -568,35 +695,35 @@ public: bool init(const LLMeshHeader& header); // Size for given LOD - S32 getSizeByLOD(S32 lod); + S32 getSizeByLOD(S32 lod) const; // Sum of all LOD sizes. - S32 getSizeTotal(); + S32 getSizeTotal() const; // Estimated triangle counts for the given LOD. - F32 getEstTrisByLOD(S32 lod); + F32 getEstTrisByLOD(S32 lod) const; // Estimated triangle counts for the largest LOD. Typically this // is also the "high" LOD, but not necessarily. - F32 getEstTrisMax(); + F32 getEstTrisMax() const; // Triangle count as computed by original streaming cost // formula. Triangles in each LOD are weighted based on how // frequently they will be seen. // This was called "unscaled_value" in the original getStreamingCost() functions. - F32 getRadiusWeightedTris(F32 radius); + F32 getRadiusWeightedTris(F32 radius) const; // Triangle count used by triangle-based cost formula. Based on // triangles in highest LOD plus potentially partial charges for // lower LODs depending on complexity. - F32 getEstTrisForStreamingCost(); + F32 getEstTrisForStreamingCost() const; // Streaming cost. This should match the server-side calculation // for the corresponding volume. - F32 getRadiusBasedStreamingCost(F32 radius); + F32 getRadiusBasedStreamingCost(F32 radius) const; // New streaming cost formula, currently only used for animated objects. - F32 getTriangleBasedStreamingCost(); + F32 getTriangleBasedStreamingCost() const; private: // From the "size" field of the mesh header. LOD 0=lowest, 3=highest. @@ -620,12 +747,12 @@ public: static U32 sLODPending; static U32 sLODProcessing; static U32 sCacheBytesRead; - static U32 sCacheBytesWritten; + static std::atomic<U32> sCacheBytesWritten; static U32 sCacheBytesHeaders; static U32 sCacheBytesSkins; static U32 sCacheBytesDecomps; static U32 sCacheReads; - static U32 sCacheWrites; + static std::atomic<U32> sCacheWrites; static U32 sMaxLockHoldoffs; // Maximum sequential locking failures static LLDeadmanTimer sQuiescentTimer; // Time-to-complete-mesh-downloads after significant events @@ -646,11 +773,11 @@ public: void unregisterMesh(LLVOVolume* volume); //mesh management functions - S32 loadMesh(LLVOVolume* volume, const LLVolumeParams& mesh_params, S32 detail = 0, S32 last_lod = -1); + S32 loadMesh(LLVOVolume* volume, const LLVolumeParams& mesh_params, S32 new_lod = 0, S32 last_lod = -1); void notifyLoadedMeshes(); - void notifyMeshLoaded(const LLVolumeParams& mesh_params, LLVolume* volume); - void notifyMeshUnavailable(const LLVolumeParams& mesh_params, S32 lod); + void notifyMeshLoaded(const LLVolumeParams& mesh_params, LLVolume* volume, S32 lod); + void notifyMeshUnavailable(const LLVolumeParams& mesh_params, S32 request_lod, S32 volume_lod); void notifySkinInfoReceived(LLMeshSkinInfo* info); void notifySkinInfoUnavailable(const LLUUID& info); void notifyDecompositionReceived(LLModel::Decomposition* info); @@ -662,7 +789,7 @@ public: void fetchPhysicsShape(const LLUUID& mesh_id); bool hasPhysicsShape(const LLUUID& mesh_id); bool hasSkinInfo(const LLUUID& mesh_id); - bool hasHeader(const LLUUID& mesh_id); + bool hasHeader(const LLUUID& mesh_id) const; void buildHull(const LLVolumeParams& params, S32 detail); void buildPhysicsMesh(LLModel::Decomposition& decomp); @@ -676,7 +803,7 @@ public: LLHandle<LLWholeModelFeeObserver> fee_observer= (LLHandle<LLWholeModelFeeObserver>()), LLHandle<LLWholeModelUploadObserver> upload_observer = (LLHandle<LLWholeModelUploadObserver>())); - S32 getMeshSize(const LLUUID& mesh_id, S32 lod); + S32 getMeshSize(const LLUUID& mesh_id, S32 lod) const; // Quiescent timer management, main thread only. static void metricsStart(); @@ -684,7 +811,7 @@ public: static void metricsProgress(unsigned int count); static void metricsUpdate(); - typedef boost::unordered_map<LLUUID, std::vector<LLVOVolume*> > mesh_load_map; + typedef std::unordered_map<LLUUID, std::vector<LLVOVolume*> > mesh_load_map; mesh_load_map mLoadingMeshes[4]; typedef std::unordered_map<LLUUID, LLPointer<LLMeshSkinInfo>> skin_map; @@ -695,15 +822,13 @@ public: LLMutex* mMeshMutex; - std::vector<LLMeshRepoThread::LODRequest> mPendingRequests; + typedef std::vector <std::unique_ptr<PendingRequestBase> > pending_requests_vec; + pending_requests_vec mPendingRequests; //list of mesh ids awaiting skin info - typedef boost::unordered_map<LLUUID, std::vector<LLVOVolume*> > skin_load_map; + typedef std::unordered_map<LLUUID, std::vector<LLVOVolume*> > skin_load_map; skin_load_map mLoadingSkins; - //list of mesh ids that need to send skin info fetch requests - std::queue<LLUUID> mPendingSkinRequests; - //list of mesh ids awaiting decompositions std::unordered_set<LLUUID> mLoadingDecompositions; diff --git a/indra/newview/llmodelpreview.cpp b/indra/newview/llmodelpreview.cpp index 29ab4e38c0..64ea1710f5 100644 --- a/indra/newview/llmodelpreview.cpp +++ b/indra/newview/llmodelpreview.cpp @@ -3517,9 +3517,13 @@ bool LLModelPreview::render() if (show_edges) { glLineWidth(PREVIEW_EDGE_WIDTH); +#if GL_VERSION_1_1 glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); +#endif buffer->drawRange(LLRender::TRIANGLES, 0, buffer->getNumVerts() - 1, buffer->getNumIndices(), 0); +#if GL_VERSION_1_1 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); +#endif glLineWidth(1.f); } buffer->unmapBuffer(); @@ -3644,10 +3648,14 @@ bool LLModelPreview::render() gGL.diffuseColor4fv(PREVIEW_PSYH_EDGE_COL.mV); glLineWidth(PREVIEW_PSYH_EDGE_WIDTH); +#if GL_VERSION_1_1 glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); +#endif buffer->drawRange(LLRender::TRIANGLES, 0, buffer->getNumVerts() - 1, buffer->getNumIndices(), 0); +#if GL_VERSION_1_1 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); +#endif glLineWidth(1.f); buffer->unmapBuffer(); @@ -3661,7 +3669,9 @@ bool LLModelPreview::render() if (mHasDegenerate) { glLineWidth(PREVIEW_DEG_EDGE_WIDTH); +#if GL_VERSION_1_1 glPointSize(PREVIEW_DEG_POINT_SIZE); +#endif gPipeline.enableLightsFullbright(); //show degenerate triangles LLGLDepthTest depth(GL_TRUE, GL_TRUE, GL_ALWAYS); @@ -3731,7 +3741,9 @@ bool LLModelPreview::render() gGL.popMatrix(); } glLineWidth(1.f); +#if GL_VERSION_1_1 glPointSize(1.f); +#endif gPipeline.enableLightsPreview(); gGL.setSceneBlendType(LLRender::BT_ALPHA); } @@ -3853,9 +3865,13 @@ bool LLModelPreview::render() gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); gGL.diffuseColor4fv(PREVIEW_EDGE_COL.mV); glLineWidth(PREVIEW_EDGE_WIDTH); +#if GL_VERSION_1_1 glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); +#endif buffer->draw(LLRender::TRIANGLES, buffer->getNumIndices(), 0); +#if GL_VERSION_1_1 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); +#endif glLineWidth(1.f); } } diff --git a/indra/newview/llnotificationhandlerutil.cpp b/indra/newview/llnotificationhandlerutil.cpp index 23f1f8fa5a..cdf7f05ada 100644 --- a/indra/newview/llnotificationhandlerutil.cpp +++ b/indra/newview/llnotificationhandlerutil.cpp @@ -92,10 +92,18 @@ void LLHandlerUtil::logToIM(const EInstantMessage& session_type, from = SYSTEM_FROM; } - // Build a new format username or firstname_lastname for legacy names - // to use it for a history log filename. - std::string user_name = LLCacheName::buildUsername(session_name); - LLIMModel::instance().logToFile(user_name, from, from_id, message); + std::string file_name; + if (session_type == IM_SESSION_GROUP_START) + { + file_name = session_name + LLLogChat::getGroupChatSuffix(); + } + else + { + // Build a new format username or firstname_lastname for legacy names + // to use it for a history log filename. + file_name = LLCacheName::buildUsername(session_name); + } + LLIMModel::instance().logToFile(file_name, from, from_id, message); } else { diff --git a/indra/newview/lloutfitslist.cpp b/indra/newview/lloutfitslist.cpp index 0f5f7aebf8..6e666b8a4b 100644 --- a/indra/newview/lloutfitslist.cpp +++ b/indra/newview/lloutfitslist.cpp @@ -924,8 +924,8 @@ void LLOutfitListBase::onIdleRefreshList() if (cat) { std::string name = cat->getName(); - updateChangedCategoryName(cat, name); - } + updateChangedCategoryName(cat, name); + } curent_time = LLTimer::getTotalSeconds(); if (curent_time >= end_time) diff --git a/indra/newview/llpanelclassified.cpp b/indra/newview/llpanelclassified.cpp index 1faf241aaa..449a670de9 100644 --- a/indra/newview/llpanelclassified.cpp +++ b/indra/newview/llpanelclassified.cpp @@ -266,6 +266,15 @@ void LLPanelClassifiedInfo::processProperties(void* data, EAvatarProcessorType t } } +void LLPanelClassifiedInfo::setAvatarId(const LLUUID& avatar_id) +{ + if (mAvatarId.notNull()) + { + LLAvatarPropertiesProcessor::getInstance()->removeObserver(mAvatarId, this); + } + mAvatarId = avatar_id; +} + void LLPanelClassifiedInfo::resetData() { setClassifiedName(LLStringUtil::null); diff --git a/indra/newview/llpanelclassified.h b/indra/newview/llpanelclassified.h index 266b9d222a..a429468a52 100644 --- a/indra/newview/llpanelclassified.h +++ b/indra/newview/llpanelclassified.h @@ -53,7 +53,7 @@ public: /*virtual*/ void processProperties(void* data, EAvatarProcessorType type); - void setAvatarId(const LLUUID& avatar_id) { mAvatarId = avatar_id; } + void setAvatarId(const LLUUID& avatar_id); LLUUID& getAvatarId() { return mAvatarId; } diff --git a/indra/newview/llpanelcontents.cpp b/indra/newview/llpanelcontents.cpp index dbf56c2b6d..7910bcb41d 100644 --- a/indra/newview/llpanelcontents.cpp +++ b/indra/newview/llpanelcontents.cpp @@ -139,32 +139,60 @@ void LLPanelContents::getState(LLViewerObject *objectp ) void LLPanelContents::onFilterEdit() { const std::string& filter_substring = mFilterEditor->getText(); - if (filter_substring.empty()) + if (!mPanelInventoryObject->hasInventory()) { - if (mPanelInventoryObject->getFilter().getFilterSubString().empty()) - { - // The current filter and the new filter are empty, nothing to do - return; - } - - mSavedFolderState.setApply(true); - mPanelInventoryObject->getRootFolder()->applyFunctorRecursively(mSavedFolderState); - - // Add a folder with the current item to the list of previously opened folders - LLOpenFoldersWithSelection opener; - mPanelInventoryObject->getRootFolder()->applyFunctorRecursively(opener); - mPanelInventoryObject->getRootFolder()->scrollToShowSelection(); + mDirtyFilter = true; } - else if (mPanelInventoryObject->getFilter().getFilterSubString().empty()) + else { - // The first letter in search term, save existing folder open state - if (!mPanelInventoryObject->getFilter().isNotDefault()) + LLFolderView* root_folder = mPanelInventoryObject->getRootFolder(); + if (filter_substring.empty()) { - mSavedFolderState.setApply(false); - mPanelInventoryObject->getRootFolder()->applyFunctorRecursively(mSavedFolderState); + if (mPanelInventoryObject->getFilter().getFilterSubString().empty()) + { + // The current filter and the new filter are empty, nothing to do + return; + } + + if (mDirtyFilter && !mSavedFolderState.hasOpenFolders()) + { + if (root_folder) + { + root_folder->setOpenArrangeRecursively(true, LLFolderViewFolder::ERecurseType::RECURSE_DOWN); + } + } + else + { + mSavedFolderState.setApply(true); + if (root_folder) + { + root_folder->applyFunctorRecursively(mSavedFolderState); + } + } + mDirtyFilter = false; + + // Add a folder with the current item to the list of previously opened folders + if (root_folder) + { + LLOpenFoldersWithSelection opener; + root_folder->applyFunctorRecursively(opener); + root_folder->scrollToShowSelection(); + } + } + else if (mPanelInventoryObject->getFilter().getFilterSubString().empty()) + { + // The first letter in search term, save existing folder open state + if (!mPanelInventoryObject->getFilter().isNotDefault()) + { + mSavedFolderState.setApply(false); + if (root_folder) + { + root_folder->applyFunctorRecursively(mSavedFolderState); + } + mDirtyFilter = false; + } } } - mPanelInventoryObject->getFilter().setFilterSubString(filter_substring); } diff --git a/indra/newview/llpanelcontents.h b/indra/newview/llpanelcontents.h index bb6308e8b8..6e02b17bab 100644 --- a/indra/newview/llpanelcontents.h +++ b/indra/newview/llpanelcontents.h @@ -70,6 +70,8 @@ protected: void getState(LLViewerObject *object); void onFilterEdit(); + bool mDirtyFilter { false }; + public: class LLFilterEditor* mFilterEditor; LLSaveFolderState mSavedFolderState; diff --git a/indra/newview/llpanelemojicomplete.cpp b/indra/newview/llpanelemojicomplete.cpp index cb89a5910e..3a6a6a5ec3 100644 --- a/indra/newview/llpanelemojicomplete.cpp +++ b/indra/newview/llpanelemojicomplete.cpp @@ -68,6 +68,9 @@ LLPanelEmojiComplete::LLPanelEmojiComplete(const LLPanelEmojiComplete::Params& p { LLScrollbar::Params sbparams; sbparams.orientation(LLScrollbar::VERTICAL); + sbparams.doc_size(static_cast<S32>(mTotalEmojis)); + sbparams.doc_pos(0); + sbparams.page_size(static_cast<S32>(mVisibleEmojis)); sbparams.change_callback([this](S32 index, LLScrollbar*) { onScrollbarChange(index); }); mScrollbar = LLUICtrlFactory::create<LLScrollbar>(sbparams); addChild(mScrollbar); @@ -438,7 +441,7 @@ void LLPanelEmojiComplete::updateConstraints() { mRenderRect = getLocalRect(); - mEmojiWidth = (U16)(mIconFont->getWidthF32(u8"\U0001F431") + mPadding * 2); + mEmojiWidth = (U16)(mIconFont->getWidthF32(LLWString(1, 0x1F431).c_str()) + mPadding * 2); if (mVertical) { mEmojiHeight = mIconFont->getLineHeight() + mPadding * 2; diff --git a/indra/newview/llpanelface.cpp b/indra/newview/llpanelface.cpp index 544b6fbc9c..4ada9c445c 100644 --- a/indra/newview/llpanelface.cpp +++ b/indra/newview/llpanelface.cpp @@ -420,6 +420,7 @@ bool LLPanelFace::postBuild() mCtrlColorTransp->setFollowsLeft(); getChildSetCommitCallback(mCheckFullbright, "checkbox fullbright", [&](LLUICtrl*, const LLSD&) { onCommitFullbright(); }); + getChildSetCommitCallback(mCheckHideWater, "checkbox_hide_water", [&](LLUICtrl*, const LLSD&) { onCommitHideWater(); }); mLabelTexGen = getChild<LLTextBox>("tex gen"); getChildSetCommitCallback(mComboTexGen, "combobox texgen", [&](LLUICtrl*, const LLSD&) { onCommitTexGen(); }); @@ -898,6 +899,10 @@ struct LLPanelFaceGetIsAlignedTEFunctor : public LLSelectedTEFunctor if (facep->calcAlignedPlanarTE(mCenterFace, &aligned_st_offset, &aligned_st_scale, &aligned_st_rot)) { const LLTextureEntry* tep = facep->getTextureEntry(); + if (!tep) + { + return false; + } LLVector2 st_offset, st_scale; tep->getOffset(&st_offset.mV[VX], &st_offset.mV[VY]); tep->getScale(&st_scale.mV[VX], &st_scale.mV[VY]); @@ -1020,6 +1025,13 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/) LLSelectedTEMaterial::getNormalID(normmap_id, identical_norm); LLSelectedTEMaterial::getSpecularID(specmap_id, identical_spec); + LLColor4 color = LLColor4::white; + bool identical_color = false; + + LLSelectedTE::getColor(color, identical_color); + F32 transparency = (1.f - color.mV[VALPHA]) * 100.f; + mExcludeWater = (id == IMG_ALPHA_GRAD) && normmap_id.isNull() && specmap_id.isNull() && (transparency == 0); + static S32 selected_te = -1; static LLUUID prev_obj_id; if ((LLToolFace::getInstance() == LLToolMgr::getInstance()->getCurrentTool()) && @@ -1094,12 +1106,26 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/) updateVisibility(objectp); + // Water exclusion + { + mCheckHideWater->setEnabled(editable && !has_pbr_material && !isMediaTexSelected()); + mCheckHideWater->set(mExcludeWater); + if (mExcludeWater && !has_pbr_material) + { + mComboMatMedia->selectNthItem(MATMEDIA_MATERIAL); + } + editable &= !mExcludeWater; + + // disable controls for water exclusion face after updateVisibility, so the whole panel is not hidden + mComboMatMedia->setEnabled(editable); + mRadioMaterialType->setEnabled(editable); + mRadioPbrType->setEnabled(editable); + mCheckSyncSettings->setEnabled(editable); + } + // Color swatch mLabelColor->setEnabled(editable); - LLColor4 color = LLColor4::white; - bool identical_color = false; - LLSelectedTE::getColor(color, identical_color); LLColor4 prev_color = mColorSwatch->get(); mColorSwatch->setOriginal(color); mColorSwatch->set(color, force_set_values || (prev_color != color) || !editable); @@ -1110,7 +1136,6 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/) // Color transparency mLabelColorTransp->setEnabled(editable); - F32 transparency = (1.f - color.mV[VALPHA]) * 100.f; mCtrlColorTransp->setValue(editable ? transparency : 0); mCtrlColorTransp->setEnabled(editable && has_material); @@ -1982,7 +2007,8 @@ void LLPanelFace::updateCopyTexButton() mMenuClipboardTexture->setEnabled(objectp && objectp->getPCode() == LL_PCODE_VOLUME && objectp->permModify() && !objectp->isPermanentEnforced() && !objectp->isInventoryPending() && (LLSelectMgr::getInstance()->getSelection()->getObjectCount() == 1) - && LLMaterialEditor::canClipboardObjectsMaterial()); + && LLMaterialEditor::canClipboardObjectsMaterial() + && !mExcludeWater); std::string tooltip = (objectp && objectp->isInventoryPending()) ? LLTrans::getString("LoadingContents") : getString("paste_options"); mMenuClipboardTexture->setToolTip(tooltip); } @@ -3023,6 +3049,36 @@ void LLPanelFace::onCommitFullbright() sendFullbright(); } +void LLPanelFace::onCommitHideWater() +{ + if (mCheckHideWater->get()) + { + LLHandle<LLPanel> handle = getHandle(); + LLNotificationsUtil::add("WaterExclusionSurfacesWarning", LLSD(), LLSD(), + [handle](const LLSD& notification, const LLSD& response) + { + if(LLPanelFace* panel = (LLPanelFace*)handle.get()) + { + if (LLNotificationsUtil::getSelectedOption(notification, response) == 1) + { + panel->mCheckHideWater->setValue(false); + return; + } + // apply invisiprim texture and reset related params to set water exclusion surface + panel->sendBump(0); + panel->sendShiny(0); + LLSelectMgr::getInstance()->selectionSetAlphaOnly(1.f); + LLSelectMgr::getInstance()->selectionSetImage(IMG_ALPHA_GRAD); + LLSelectedTEMaterial::setDiffuseAlphaMode(panel, LLMaterial::DIFFUSE_ALPHA_MODE_BLEND); + } + }); + } + else + { + LLSelectMgr::getInstance()->clearWaterExclusion(); + } +} + void LLPanelFace::onCommitGlow() { sendGlow(); @@ -4407,21 +4463,14 @@ void LLPanelFace::onPasteTexture(LLViewerObject* objectp, S32 te) tep->setGLTFRenderMaterial(nullptr); tep->setGLTFMaterialOverride(nullptr); - LLSD override_data; - override_data["object_id"] = objectp->getID(); - override_data["side"] = te; if (te_data["te"].has("pbr_override")) { - override_data["gltf_json"] = te_data["te"]["pbr_override"]; + LLGLTFMaterialList::queueApply(objectp, te, te_data["te"]["pbr"].asUUID(), te_data["te"]["pbr_override"]); } else { - override_data["gltf_json"] = ""; + LLGLTFMaterialList::queueApply(objectp, te, te_data["te"]["pbr"].asUUID()); } - - override_data["asset_id"] = te_data["te"]["pbr"].asUUID(); - - LLGLTFMaterialList::queueUpdate(override_data); } else { @@ -4887,6 +4936,26 @@ bool LLPanelFace::isIdenticalPlanarTexgen() return (identical_texgen && (selected_texgen == LLTextureEntry::TEX_GEN_PLANAR)); } +bool LLPanelFace::isMediaTexSelected() +{ + LLSelectNode* node = LLSelectMgr::getInstance()->getSelection()->getFirstNode(); + if (LLViewerObject* objectp = node->getObject()) + { + S32 num_tes = llmin((S32)objectp->getNumTEs(), (S32)objectp->getNumFaces()); + for (S32 te = 0; te < num_tes; ++te) + { + if (node->isTESelected(te)) + { + if (objectp->getTE(te) && objectp->getTE(te)->hasMedia()) + { + return true; + } + } + } + } + return false; +} + void LLPanelFace::LLSelectedTE::getFace(LLFace*& face_to_return, bool& identical_face) { struct LLSelectedTEGetFace : public LLSelectedTEGetFunctor<LLFace *> @@ -5199,4 +5268,3 @@ void LLPanelFace::LLSelectedTE::getMaxDiffuseRepeats(F32& repeats, bool& identic } max_diff_repeats_func; identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &max_diff_repeats_func, repeats ); } - diff --git a/indra/newview/llpanelface.h b/indra/newview/llpanelface.h index dfd3201533..1ee9bf2cf7 100644 --- a/indra/newview/llpanelface.h +++ b/indra/newview/llpanelface.h @@ -139,6 +139,8 @@ protected: void updateMediaSettings(); void updateMediaTitle(); + bool isMediaTexSelected(); + void getState(); void sendTexture(); // applies and sends texture @@ -238,6 +240,7 @@ protected: void onCommitShiny(); void onCommitAlphaMode(); void onCommitFullbright(); + void onCommitHideWater(); void onCommitGlow(); void onCommitPlanarAlign(); void onCommitRepeatsPerMeter(); @@ -308,6 +311,7 @@ private: LLRadioGroup* mRadioPbrType { nullptr }; LLCheckBoxCtrl* mCheckFullbright { nullptr }; + LLCheckBoxCtrl* mCheckHideWater{ nullptr }; LLTextBox* mLabelColorTransp { nullptr }; LLSpinCtrl* mCtrlColorTransp { nullptr }; // transparency = 1 - alpha @@ -479,7 +483,7 @@ private: ReturnType (LLMaterial::* const MaterialGetFunc)() const > static void getTEMaterialValue(DataType& data_to_return, bool& identical,DataType default_value, bool has_tolerance = false, DataType tolerance = DataType()) { - DataType data_value; + DataType data_value{}; struct GetTEMaterialVal : public LLSelectedTEGetFunctor<DataType> { GetTEMaterialVal(DataType default_value) : _default(default_value) {} @@ -512,7 +516,7 @@ private: ReturnType (LLTextureEntry::* const TEGetFunc)() const > static void getTEValue(DataType& data_to_return, bool& identical, DataType default_value, bool has_tolerance = false, DataType tolerance = DataType()) { - DataType data_value; + DataType data_value {}; struct GetTEVal : public LLSelectedTEGetFunctor<DataType> { GetTEVal(DataType default_value) : _default(default_value) {} @@ -555,6 +559,7 @@ private: LLMenuButton* mMenuClipboardTexture; bool mIsAlpha; + bool mExcludeWater { false }; LLSD mClipboardParams; @@ -707,4 +712,3 @@ public: }; #endif - diff --git a/indra/newview/llpanelgroupbulk.cpp b/indra/newview/llpanelgroupbulk.cpp index 433db74cda..8032e207cd 100644 --- a/indra/newview/llpanelgroupbulk.cpp +++ b/indra/newview/llpanelgroupbulk.cpp @@ -56,6 +56,7 @@ LLPanelGroupBulkImpl::LLPanelGroupBulkImpl(const LLUUID& group_id) : mGroupID(group_id), mBulkAgentList(NULL), mOKButton(NULL), + mAddButton(nullptr), mRemoveButton(NULL), mGroupName(NULL), mLoadingText(), @@ -79,29 +80,18 @@ LLPanelGroupBulkImpl::~LLPanelGroupBulkImpl() } } -// static -void LLPanelGroupBulkImpl::callbackClickAdd(void* userdata) +void LLPanelGroupBulkImpl::callbackClickAdd(LLPanelGroupBulk* panelp) { - if (LLPanelGroupBulk* panelp = (LLPanelGroupBulk*)userdata) - { - // Right now this is hard coded with some knowledge that it is part - // of a floater since the avatar picker needs to be added as a dependent - // floater to the parent floater. - // Soon the avatar picker will be embedded into this panel - // instead of being it's own separate floater. But that is next week. - // This will do for now. -jwolk May 10, 2006 - LLView* button = panelp->findChild<LLButton>("add_button"); - LLFloater* root_floater = gFloaterView->getParentFloater(panelp); - LLFloaterAvatarPicker* picker = LLFloaterAvatarPicker::show( - [&](const uuid_vec_t& agent_ids, const std::vector<LLAvatarName>&) - { - panelp->mImplementation->addUsers(agent_ids); - }, true, false, false, root_floater->getName(), button); - if (picker) + LLFloater* root_floater = gFloaterView->getParentFloater(panelp); + LLFloaterAvatarPicker* picker = LLFloaterAvatarPicker::show( + [this](const uuid_vec_t& agent_ids, const std::vector<LLAvatarName>&) { - root_floater->addDependentFloater(picker); - LLGroupMgr::getInstance()->sendCapGroupMembersRequest(panelp->mImplementation->mGroupID); - } + addUsers(agent_ids); + }, true, false, false, root_floater->getName(), mAddButton); + if (picker) + { + root_floater->addDependentFloater(picker); + LLGroupMgr::getInstance()->sendCapGroupMembersRequest(mGroupID); } } diff --git a/indra/newview/llpanelgroupbulkban.cpp b/indra/newview/llpanelgroupbulkban.cpp index 3c764887a6..1d3edad0f3 100644 --- a/indra/newview/llpanelgroupbulkban.cpp +++ b/indra/newview/llpanelgroupbulkban.cpp @@ -68,35 +68,26 @@ bool LLPanelGroupBulkBan::postBuild() mImplementation->mBulkAgentList->setCommitCallback(LLPanelGroupBulkImpl::callbackSelect, mImplementation); } - LLButton* button = getChild<LLButton>("add_button", recurse); - if ( button ) + mImplementation->mAddButton = getChild<LLButton>("add_button", recurse); + // default to opening avatarpicker automatically + mImplementation->mAddButton->setClickedCallback( + [this](LLUICtrl* ctrl, const LLSD& param) { - // default to opening avatarpicker automatically - // (*impl::callbackClickAdd)((void*)this); - button->setClickedCallback(LLPanelGroupBulkImpl::callbackClickAdd, this); - } + mImplementation->callbackClickAdd(this); + }); mImplementation->mRemoveButton = getChild<LLButton>("remove_button", recurse); - if ( mImplementation->mRemoveButton ) - { - mImplementation->mRemoveButton->setClickedCallback(LLPanelGroupBulkImpl::callbackClickRemove, mImplementation); - mImplementation->mRemoveButton->setEnabled(false); - } + mImplementation->mRemoveButton->setClickedCallback(LLPanelGroupBulkImpl::callbackClickRemove, mImplementation); + mImplementation->mRemoveButton->setEnabled(false); mImplementation->mOKButton = getChild<LLButton>("ban_button", recurse); - if ( mImplementation->mOKButton ) - { - mImplementation->mOKButton->setClickedCallback(LLPanelGroupBulkBan::callbackClickSubmit, this); - mImplementation->mOKButton->setEnabled(false); - } + mImplementation->mOKButton->setClickedCallback(LLPanelGroupBulkBan::callbackClickSubmit, this); + mImplementation->mOKButton->setEnabled(false); - button = getChild<LLButton>("cancel_button", recurse); - if ( button ) - { - button->setClickedCallback(LLPanelGroupBulkImpl::callbackClickCancel, mImplementation); - } + LLButton* button = getChild<LLButton>("cancel_button", recurse); + button->setClickedCallback(LLPanelGroupBulkImpl::callbackClickCancel, mImplementation); mImplementation->mTooManySelected = getString("ban_selection_too_large"); mImplementation->mBanNotPermitted = getString("ban_not_permitted"); diff --git a/indra/newview/llpanelgroupbulkimpl.h b/indra/newview/llpanelgroupbulkimpl.h index 5a479f8117..5515bd6d9a 100644 --- a/indra/newview/llpanelgroupbulkimpl.h +++ b/indra/newview/llpanelgroupbulkimpl.h @@ -44,7 +44,7 @@ public: LLPanelGroupBulkImpl(const LLUUID& group_id); ~LLPanelGroupBulkImpl(); - static void callbackClickAdd(void* userdata); + void callbackClickAdd(LLPanelGroupBulk* panelp); static void callbackClickRemove(void* userdata); static void callbackClickCancel(void* userdata); @@ -70,6 +70,7 @@ public: LLNameListCtrl* mBulkAgentList; LLButton* mOKButton; + LLButton* mAddButton; LLButton* mRemoveButton; LLTextBox* mGroupName; diff --git a/indra/newview/llpanelgroupgeneral.cpp b/indra/newview/llpanelgroupgeneral.cpp index ca429ae2f8..0c331b4cec 100644 --- a/indra/newview/llpanelgroupgeneral.cpp +++ b/indra/newview/llpanelgroupgeneral.cpp @@ -34,6 +34,7 @@ #include "llsdparam.h" #include "lluictrlfactory.h" #include "roles_constants.h" +#include "llmutelist.h" // UI elements #include "llbutton.h" @@ -76,6 +77,7 @@ LLPanelGroupGeneral::LLPanelGroupGeneral() mCtrlEnrollmentFee(NULL), mSpinEnrollmentFee(NULL), mCtrlReceiveNotices(NULL), + mCtrlReceiveGroupChat(NULL), // <exodus/> mCtrlListGroup(NULL), mActiveTitleLabel(NULL), mComboActiveTitle(NULL) @@ -154,6 +156,18 @@ bool LLPanelGroupGeneral::postBuild() mCtrlReceiveNotices->set(accept_notices); mCtrlReceiveNotices->setEnabled(data.mID.notNull()); } + // <exodus> + mCtrlReceiveGroupChat = getChild<LLCheckBoxCtrl>("receive_chat", recurse); + if(mCtrlReceiveGroupChat) + { + mCtrlReceiveGroupChat->setCommitCallback(onCommitUserOnly, this); + mCtrlReceiveGroupChat->setEnabled(data.mID.notNull()); + if(data.mID.notNull()) + { + mCtrlReceiveGroupChat->set(!LLMuteList::getInstance()->isMuted(LLUUID::null, std::string{"Group:" + data.mID.asString()})); + } + } + // </exodus> mCtrlListGroup = getChild<LLCheckBoxCtrl>("list_groups_in_profile", recurse); if (mCtrlListGroup) @@ -389,6 +403,19 @@ bool LLPanelGroupGeneral::apply(std::string& mesg) list_in_profile = mCtrlListGroup->get(); gAgent.setUserGroupFlags(mGroupID, receive_notices, list_in_profile); + // <exodus> + if(mCtrlReceiveGroupChat) + { + if(mCtrlReceiveGroupChat->get()) + { + LLMuteList::getInstance()->remove(LLMute(LLUUID::null, std::string{"Group:" + mGroupID.asString()})); + } + else + { + LLMuteList::getInstance()->add(LLMute(LLUUID::null, std::string{"Group:" + mGroupID.asString()})); + } + } + // </exodus> resetDirty(); @@ -556,6 +583,16 @@ void LLPanelGroupGeneral::update(LLGroupChange gc) } } + // <exodus> + if (mCtrlReceiveGroupChat) + { + mCtrlReceiveGroupChat->setVisible(is_member); + if (is_member) + { + mCtrlReceiveGroupChat->setEnabled(mAllowEdit); + } + } + // </exodus> if (mInsignia) mInsignia->setEnabled(mAllowEdit && can_change_ident); if (mEditCharter) mEditCharter->setEnabled(mAllowEdit && can_change_ident); @@ -598,6 +635,7 @@ void LLPanelGroupGeneral::updateChanged() mCtrlEnrollmentFee, mSpinEnrollmentFee, mCtrlReceiveNotices, + mCtrlReceiveGroupChat, // <exodus/> mCtrlListGroup, mActiveTitleLabel, mComboActiveTitle @@ -653,6 +691,12 @@ void LLPanelGroupGeneral::reset() mInsignia->setImageAssetName(mInsignia->getDefaultImageName()); + // <exodus> + mCtrlReceiveGroupChat->set(false); + mCtrlReceiveGroupChat->setEnabled(false); + mCtrlReceiveGroupChat->setVisible(true); + // </exodus> + { std::string empty_str = ""; mEditCharter->setText(empty_str); @@ -684,6 +728,7 @@ void LLPanelGroupGeneral::resetDirty() mCtrlEnrollmentFee, mSpinEnrollmentFee, mCtrlReceiveNotices, + mCtrlReceiveGroupChat, // <exodus/> mCtrlListGroup, mActiveTitleLabel, mComboActiveTitle @@ -730,6 +775,18 @@ void LLPanelGroupGeneral::setGroupID(const LLUUID& id) mCtrlListGroup->setEnabled(data.mID.notNull()); } + // <exodus> + mCtrlReceiveGroupChat = getChild<LLCheckBoxCtrl>("receive_chat"); + if (mCtrlReceiveGroupChat) + { + if(data.mID.notNull()) + { + mCtrlReceiveGroupChat->set(!LLMuteList::getInstance()->isMuted(LLUUID::null, std::string{"Group:" + data.mID.asString()})); + } + mCtrlReceiveGroupChat->setEnabled(data.mID.notNull()); + } + // </exodus> + mCtrlShowInGroupList->setEnabled(data.mID.notNull()); mActiveTitleLabel = getChild<LLTextBox>("active_title_label"); diff --git a/indra/newview/llpanelgroupgeneral.h b/indra/newview/llpanelgroupgeneral.h index e5d766dc40..37db2e96a0 100644 --- a/indra/newview/llpanelgroupgeneral.h +++ b/indra/newview/llpanelgroupgeneral.h @@ -98,6 +98,7 @@ private: LLTextBox *mActiveTitleLabel; LLComboBox *mComboActiveTitle; LLComboBox *mComboMature; + LLCheckBoxCtrl *mCtrlReceiveGroupChat; // <exodus/> }; #endif diff --git a/indra/newview/llpanelmaininventory.cpp b/indra/newview/llpanelmaininventory.cpp index 377af4384a..d964fa9170 100644 --- a/indra/newview/llpanelmaininventory.cpp +++ b/indra/newview/llpanelmaininventory.cpp @@ -1582,7 +1582,7 @@ void LLPanelMainInventory::initInventoryViews() void LLPanelMainInventory::toggleViewMode() { - if(mSingleFolderMode && isCombinationViewMode()) + if(mSingleFolderMode && isCombinationViewMode() && mCombinationGalleryPanel->getRootFolder().notNull()) { mCombinationInventoryPanel->getRootFolder()->setForceArrange(false); } @@ -2030,7 +2030,11 @@ void LLPanelMainInventory::onVisibilityChange( bool new_visibility ) { menu->setVisible(false); } - getActivePanel()->getRootFolder()->finishRenamingItem(); + LLFolderView* root_folder = mActivePanel ? mActivePanel->getRootFolder() : nullptr; + if (root_folder) + { + root_folder->finishRenamingItem(); + } } } @@ -2043,7 +2047,8 @@ bool LLPanelMainInventory::isSaveTextureEnabled(const LLSD& userdata) } else { - LLFolderViewItem* current_item = getActivePanel()->getRootFolder()->getCurSelectedItem(); + LLFolderView* root_folder = getActivePanel() ? getActivePanel()->getRootFolder() : nullptr; + LLFolderViewItem* current_item = root_folder ? root_folder->getCurSelectedItem() : nullptr; if (current_item) { inv_item = dynamic_cast<LLViewerInventoryItem*>(static_cast<LLFolderViewModelItemInventory*>(current_item->getViewModelItem())->getInventoryObject()); @@ -2425,18 +2430,20 @@ void LLPanelMainInventory::updateCombinationVisibility() mCombinationGalleryLayoutPanel->setVisible(!is_gallery_empty); mCombinationListLayoutPanel->setVisible(show_inv_pane); - mCombinationInventoryPanel->getRootFolder()->setForceArrange(!show_inv_pane); - if(mCombinationInventoryPanel->hasVisibleItems()) + LLFolderView* root_folder = mCombinationInventoryPanel->getRootFolder(); + if (root_folder) { - mForceShowInvLayout = false; + root_folder->setForceArrange(!show_inv_pane); + if (mCombinationInventoryPanel->hasVisibleItems()) + { + mForceShowInvLayout = false; + } } if(is_gallery_empty) { mCombinationGalleryPanel->handleModifiedFilter(); } - getActivePanel()->getRootFolder(); - if (mReshapeInvLayout && show_inv_pane && (mCombinationGalleryPanel->hasVisibleItems() || mCombinationGalleryPanel->areViewsInitialized()) @@ -2493,8 +2500,12 @@ void LLPanelMainInventory::updateCombinationVisibility() && mCombinationInventoryPanel->areViewsInitialized()) { mCombinationInventoryPanel->setSelectionByID(mCombInvUUIDNeedsRename, true); - mCombinationInventoryPanel->getRootFolder()->scrollToShowSelection(); - mCombinationInventoryPanel->getRootFolder()->setNeedsAutoRename(true); + LLFolderView* root = mCombinationInventoryPanel->getRootFolder(); + if (root) + { + root->scrollToShowSelection(); + root->setNeedsAutoRename(true); + } mCombInvUUIDNeedsRename.setNull(); } } diff --git a/indra/newview/llpanelobjectinventory.h b/indra/newview/llpanelobjectinventory.h index abb48dbeed..154639e4bb 100644 --- a/indra/newview/llpanelobjectinventory.h +++ b/indra/newview/llpanelobjectinventory.h @@ -85,6 +85,8 @@ public: static void idle(void* user_data); + bool hasInventory(){ return mHaveInventory; }; + protected: void reset(); /*virtual*/ void inventoryChanged(LLViewerObject* object, diff --git a/indra/newview/llpanelpeople.cpp b/indra/newview/llpanelpeople.cpp index 25672db318..72fa553023 100644 --- a/indra/newview/llpanelpeople.cpp +++ b/indra/newview/llpanelpeople.cpp @@ -841,7 +841,7 @@ void LLPanelPeople::updateNearbyList() std::vector<LLVector3d> positions; - LLWorld::getInstance()->getAvatars(&mNearbyList->getIDs(), &positions, gAgent.getPositionGlobal(), gSavedSettings.getF32("NearMeRange")); + LLWorld::getInstance()->getAvatars(&mNearbyList->getIDs(), &positions, gAgent.getPositionGlobal(), gSavedSettings.getF32("MPVNearMeRange")); mNearbyList->setDirty(); DISTANCE_COMPARATOR.updateAvatarsPositions(positions, mNearbyList->getIDs()); @@ -1127,6 +1127,12 @@ void LLPanelPeople::onAvatarListDoubleClicked(LLUICtrl* ctrl) #if 0 // SJB: Useful for testing, but not currently functional or to spec LLAvatarActions::showProfile(clicked_id); #else // spec says open IM window + if (item->getParentUICtrl()->getParentUICtrl() == mNearbyList + && gSavedSettings.getBOOL("DoubleClickZoomIn")) + { + handle_zoom_to_object(clicked_id); + return; + } LLAvatarActions::startIM(clicked_id); #endif } diff --git a/indra/newview/llpanelpeoplemenus.cpp b/indra/newview/llpanelpeoplemenus.cpp index f8a73ddb46..04b8af49c1 100644 --- a/indra/newview/llpanelpeoplemenus.cpp +++ b/indra/newview/llpanelpeoplemenus.cpp @@ -74,6 +74,7 @@ LLContextMenu* PeopleContextMenu::createMenu() registrar.add("Avatar.Call", boost::bind(&LLAvatarActions::startCall, id)); registrar.add("Avatar.OfferTeleport", boost::bind(&PeopleContextMenu::offerTeleport, this)); registrar.add("Avatar.ZoomIn", boost::bind(&handle_zoom_to_object, id)); + registrar.add("Avatar.TeleportTo", boost::bind(&handle_teleport_to_object, id)); registrar.add("Avatar.ShowOnMap", boost::bind(&LLAvatarActions::showOnMap, id)); registrar.add("Avatar.Share", boost::bind(&LLAvatarActions::share, id)); registrar.add("Avatar.Pay", boost::bind(&LLAvatarActions::pay, id)); @@ -404,6 +405,7 @@ void NearbyPeopleContextMenu::buildContextMenu(class LLMenuGL& menu, U32 flags) items.push_back(std::string("invite_to_group")); items.push_back(std::string("separator_invite_to_group")); items.push_back(std::string("zoom_in")); + items.push_back(std::string("teleport_to")); items.push_back(std::string("map")); items.push_back(std::string("share")); items.push_back(std::string("pay")); diff --git a/indra/newview/llpanelprimmediacontrols.cpp b/indra/newview/llpanelprimmediacontrols.cpp index 4db0a5b59d..7b562337a3 100644 --- a/indra/newview/llpanelprimmediacontrols.cpp +++ b/indra/newview/llpanelprimmediacontrols.cpp @@ -294,7 +294,7 @@ void LLPanelPrimMediaControls::updateShape() LLViewerMediaImpl* media_impl = getTargetMediaImpl(); LLViewerObject* objectp = getTargetObject(); - if(!media_impl || gFloaterTools->getVisible()) + if(!media_impl || (gFloaterTools && gFloaterTools->getVisible())) { setVisible(false); return; @@ -660,11 +660,11 @@ void LLPanelPrimMediaControls::updateShape() for(; vert_it != vert_end; ++vert_it) { // project silhouette vertices into screen space - glm::vec3 screen_vert(glm::make_vec3(vert_it->mV)); + glm::vec3 screen_vert(*vert_it); screen_vert = mul_mat4_vec3(mat, screen_vert); // add to screenspace bounding box - update_min_max(min, max, LLVector3(glm::value_ptr(screen_vert))); + update_min_max(min, max, LLVector3(screen_vert)); } // convert screenspace bbox to pixels (in screen coords) @@ -777,7 +777,7 @@ void LLPanelPrimMediaControls::draw() else if(mFadeTimer.getStarted()) { F32 time = mFadeTimer.getElapsedTimeF32(); - alpha *= llmax(lerp(1.0, 0.0, time / mControlFadeTime), 0.0f); + alpha *= llmax(lerp(1.0f, 0.0f, time / mControlFadeTime), 0.0f); if(time >= mControlFadeTime) { diff --git a/indra/newview/llpanelprofile.cpp b/indra/newview/llpanelprofile.cpp index 08605f7cf4..132098ba99 100644 --- a/indra/newview/llpanelprofile.cpp +++ b/indra/newview/llpanelprofile.cpp @@ -1429,6 +1429,11 @@ void LLPanelProfileSecondLife::onCommitMenu(const LLSD& userdata) LLWString wstr = utf8str_to_wstring(getAvatarId().asString()); LLClipboard::instance().copyToClipboard(wstr, 0, static_cast<S32>(wstr.size())); } + else if (item_name == "copy_profile_link") + { + LLWString wstr = utf8str_to_wstring(llformat("secondlife:///app/agent/%s/about", getAvatarId().asString().c_str())); + LLClipboard::instance().copyToClipboard(wstr, 0, wstr.size()); + } else if (item_name == "agent_permissions") { onShowAgentPermissionsDialog(); diff --git a/indra/newview/llpanelprofileclassifieds.h b/indra/newview/llpanelprofileclassifieds.h index 9f0b27139a..42cd5f8975 100644 --- a/indra/newview/llpanelprofileclassifieds.h +++ b/indra/newview/llpanelprofileclassifieds.h @@ -324,8 +324,11 @@ private: S32 mPriceForListing; +public: static void handleSearchStatResponse(LLUUID classifiedId, LLSD result); +private: + typedef std::list<LLPanelProfileClassified*> panel_list_t; static panel_list_t sAllPanels; diff --git a/indra/newview/llpanelprofilepicks.cpp b/indra/newview/llpanelprofilepicks.cpp index 08f3d3af5a..a87ef4f0f9 100644 --- a/indra/newview/llpanelprofilepicks.cpp +++ b/indra/newview/llpanelprofilepicks.cpp @@ -55,6 +55,8 @@ static LLPanelInjector<LLPanelProfilePicks> t_panel_profile_picks("panel_profile_picks"); static LLPanelInjector<LLPanelProfilePick> t_panel_profile_pick("panel_profile_pick"); +constexpr F32 REQUEST_TIMEOUT = 60; +constexpr F32 LOCATION_CACHE_TIMOUT = 900; class LLPickHandler : public LLCommandHandler { @@ -306,6 +308,7 @@ void LLPanelProfilePicks::processProperties(void* data, EAvatarProcessorType typ void LLPanelProfilePicks::processProperties(const LLAvatarData* avatar_picks) { + LL_DEBUGS("PickInfo") << "Processing picks for avatar " << getAvatarId() << LL_ENDL; LLUUID selected_id = mPickToSelectOnLoad; bool has_selection = false; if (mPickToSelectOnLoad.isNull()) @@ -320,6 +323,25 @@ void LLPanelProfilePicks::processProperties(const LLAvatarData* avatar_picks) } } + // Avoid pointlesly requesting parcel data, + // store previous values + std::map<LLUUID, std::string> parcelid_location_map; + std::map<LLUUID, LLUUID> pickid_parcelid_map; + + for (S32 tab_idx = 0; tab_idx < mTabContainer->getTabCount(); ++tab_idx) + { + LLPanelProfilePick* pick_panel = dynamic_cast<LLPanelProfilePick*>(mTabContainer->getPanelByIndex(tab_idx)); + if (pick_panel && pick_panel->getPickId().notNull()) + { + std::string location = pick_panel->getPickLocation(); + if (!location.empty()) + { + parcelid_location_map[pick_panel->getParcelID()] = pick_panel->getPickLocation(); + pickid_parcelid_map[pick_panel->getPickId()] = pick_panel->getParcelID(); + } + } + } + mTabContainer->deleteAllTabs(); LLAvatarData::picks_list_t::const_iterator it = avatar_picks->picks_list.begin(); @@ -334,6 +356,15 @@ void LLPanelProfilePicks::processProperties(const LLAvatarData* avatar_picks) pick_panel->setPickName(pick_name); pick_panel->setAvatarId(getAvatarId()); + std::map<LLUUID, LLUUID>::const_iterator found_pick = pickid_parcelid_map.find(pick_id); + if (found_pick != pickid_parcelid_map.end()) + { + std::map<LLUUID, std::string>::const_iterator found = parcelid_location_map.find(found_pick->second); + if (found != parcelid_location_map.end() && !found->second.empty()) + { + pick_panel->setPickLocation(found_pick->second, found->second); + } + } mTabContainer->addTabPanel( LLTabContainer::TabPanelParams(). panel(pick_panel). @@ -353,6 +384,11 @@ void LLPanelProfilePicks::processProperties(const LLAvatarData* avatar_picks) LLPanelProfilePick* pick_panel = LLPanelProfilePick::create(); pick_panel->setAvatarId(getAvatarId()); + std::map<LLUUID, std::string>::const_iterator found = parcelid_location_map.find(data.parcel_id); + if (found != parcelid_location_map.end() && !found->second.empty()) + { + pick_panel->setPickLocation(data.parcel_id, found->second); + } pick_panel->processProperties(&data); mTabContainer->addTabPanel( LLTabContainer::TabPanelParams(). @@ -638,9 +674,14 @@ void LLPanelProfilePick::processProperties(void* data, EAvatarProcessorType type void LLPanelProfilePick::processProperties(const LLPickData* pick_info) { + LL_DEBUGS("PickInfo") << "Processing properties for pick " << mPickId << LL_ENDL; mIsEditing = false; mPickDescription->setParseHTML(true); - mParcelId = pick_info->parcel_id; + if (mParcelId != pick_info->parcel_id) + { + mParcelId = pick_info->parcel_id; + mPickLocationStr.clear(); + } setSnapshotId(pick_info->snapshot_id); if (!getSelfProfile()) { @@ -650,8 +691,11 @@ void LLPanelProfilePick::processProperties(const LLPickData* pick_info) setPickDesc(pick_info->desc); setPosGlobal(pick_info->pos_global); - // Send remote parcel info request to get parcel name and sim (region) name. - sendParcelInfoRequest(); + if (mPickLocationStr.empty() || mLastRequestTimer.getElapsedTimeF32() > LOCATION_CACHE_TIMOUT) + { + // Send remote parcel info request to get parcel name and sim (region) name. + sendParcelInfoRequest(); + } // *NOTE dzaporozhan // We want to keep listening to APT_PICK_INFO because user may @@ -691,9 +735,17 @@ void LLPanelProfilePick::setPickDesc(const std::string& desc) mPickDescription->setValue(desc); } +void LLPanelProfilePick::setPickLocation(const LLUUID &parcel_id, const std::string& location) +{ + setParcelID(parcel_id); // resets mPickLocationStr + setPickLocation(location); +} + void LLPanelProfilePick::setPickLocation(const std::string& location) { getChild<LLUICtrl>("pick_location")->setValue(location); + mPickLocationStr = location; + mLastRequestTimer.reset(); } void LLPanelProfilePick::onClickMap() @@ -790,16 +842,19 @@ std::string LLPanelProfilePick::getLocationNotice() void LLPanelProfilePick::sendParcelInfoRequest() { - if (mParcelId != mRequestedId) + if (mParcelId != mRequestedId || mLastRequestTimer.getElapsedTimeF32() > REQUEST_TIMEOUT) { if (mRequestedId.notNull()) { LLRemoteParcelInfoProcessor::getInstance()->removeObserver(mRequestedId, this); } + LL_DEBUGS("PickInfo") << "Sending parcel request " << mParcelId << " for pick " << mPickId << LL_ENDL; LLRemoteParcelInfoProcessor::getInstance()->addObserver(mParcelId, this); LLRemoteParcelInfoProcessor::getInstance()->sendParcelInfoRequest(mParcelId); mRequestedId = mParcelId; + mLastRequestTimer.reset(); + mPickLocationStr.clear(); } } @@ -816,6 +871,20 @@ void LLPanelProfilePick::processParcelInfo(const LLParcelData& parcel_data) } } +void LLPanelProfilePick::setParcelID(const LLUUID& parcel_id) +{ + if (mParcelId != parcel_id) + { + mParcelId = parcel_id; + mPickLocationStr.clear(); + } + if (mRequestedId.notNull() && mRequestedId != parcel_id) + { + LLRemoteParcelInfoProcessor::getInstance()->removeObserver(mRequestedId, this); + mRequestedId.setNull(); + } +} + void LLPanelProfilePick::sendUpdate() { LLPickData pick_data; diff --git a/indra/newview/llpanelprofilepicks.h b/indra/newview/llpanelprofilepicks.h index e3f50f5576..b4d3eb010e 100644 --- a/indra/newview/llpanelprofilepicks.h +++ b/indra/newview/llpanelprofilepicks.h @@ -117,6 +117,8 @@ public: virtual void setPickName(const std::string& name); const std::string getPickName(); + virtual void setPickLocation(const LLUUID& parcel_id, const std::string& location); + std::string getPickLocation() { return mPickLocationStr; }; void processProperties(void* data, EAvatarProcessorType type) override; void processProperties(const LLPickData* pick_data); @@ -135,7 +137,8 @@ public: //This stuff we got from LLRemoteParcelObserver, in the last one we intentionally do nothing void processParcelInfo(const LLParcelData& parcel_data) override; - void setParcelID(const LLUUID& parcel_id) override { mParcelId = parcel_id; } + void setParcelID(const LLUUID& parcel_id) override; + LLUUID getParcelID() const { return mParcelId; } void setErrorStatus(S32 status, const std::string& reason) override {}; protected: @@ -230,6 +233,8 @@ protected: LLUUID mPickId; LLUUID mRequestedId; std::string mPickNameStr; + std::string mPickLocationStr; + LLTimer mLastRequestTimer; boost::signals2::connection mRegionCallbackConnection; boost::signals2::connection mParcelCallbackConnection; diff --git a/indra/newview/llpreviewgesture.cpp b/indra/newview/llpreviewgesture.cpp index 66dcd2f7ba..c684113d4e 100644 --- a/indra/newview/llpreviewgesture.cpp +++ b/indra/newview/llpreviewgesture.cpp @@ -505,9 +505,17 @@ void LLPreviewGesture::addKeys() LLComboBox* combo = mKeyCombo; combo->add( NONE_LABEL ); - for (KEY key = KEY_F2; key <= KEY_F12; key++) + for (KEY key = ' '; key < KEY_NONE; key++) { - combo->add( LLKeyboard::stringFromKey(key), ADD_BOTTOM ); + char buffer[] = { (char)key, '\0' }; + std::string str_org(buffer); + std::string str_translated = LLKeyboard::stringFromKey(key); + + if (str_org == str_translated) + { + if (key >= ' ' && key <= '~') combo->add(str_translated, ADD_BOTTOM); + } + else combo->add(str_translated, ADD_BOTTOM); } combo->setCurrentByIndex(0); } diff --git a/indra/newview/llprogressview.cpp b/indra/newview/llprogressview.cpp index 80e403dfde..2c09943b83 100644 --- a/indra/newview/llprogressview.cpp +++ b/indra/newview/llprogressview.cpp @@ -81,10 +81,9 @@ bool LLProgressView::postBuild() { mProgressBar = getChild<LLProgressBar>("login_progress_bar"); - mLogosLabel = getChild<LLTextBox>("logos_lbl"); - mProgressText = getChild<LLTextBox>("progress_text"); mMessageText = getChild<LLTextBox>("message_text"); + mMessageTextRectInitial = mMessageText->getRect(); // auto resizes, save initial size // media control that is used to play intro video mMediaCtrl = getChild<LLMediaCtrl>("login_media_panel"); @@ -96,6 +95,12 @@ bool LLProgressView::postBuild() mCancelBtn = getChild<LLButton>("cancel_btn"); mCancelBtn->setClickedCallback( LLProgressView::onCancelButtonClicked, NULL ); + mLayoutPanel4 = getChild<LLView>("panel4"); + mLayoutPanel4RectInitial = mLayoutPanel4->getRect(); + + mLayoutMOTD = getChild<LLView>("panel_motd"); + mLayoutMOTDRectInitial = mLayoutMOTD->getRect(); + getChild<LLTextBox>("title_text")->setText(LLStringExplicit(LLAppViewer::instance()->getSecondLifeTitle())); getChild<LLTextBox>("message_text")->setClickedCallback(onClickMessage, this); @@ -234,33 +239,6 @@ void LLProgressView::drawStartTexture(F32 alpha) gGL.popMatrix(); } -void LLProgressView::drawLogos(F32 alpha) -{ - if (mLogosList.empty()) - { - return; - } - - // logos are tied to label, - // due to potential resizes we have to figure offsets out on draw or resize - S32 offset_x, offset_y; - mLogosLabel->localPointToScreen(0, 0, &offset_x, &offset_y); - std::vector<TextureData>::const_iterator iter = mLogosList.begin(); - std::vector<TextureData>::const_iterator end = mLogosList.end(); - for (; iter != end; iter++) - { - gl_draw_scaled_image_with_border(iter->mDrawRect.mLeft + offset_x, - iter->mDrawRect.mBottom + offset_y, - iter->mDrawRect.getWidth(), - iter->mDrawRect.getHeight(), - iter->mTexturep.get(), - UI_VERTEX_COLOR % alpha, - false, - iter->mClipRect, - iter->mOffsetRect); - } -} - void LLProgressView::draw() { static LLTimer timer; @@ -276,7 +254,6 @@ void LLProgressView::draw() } LLPanel::draw(); - drawLogos(alpha); return; } @@ -289,7 +266,6 @@ void LLProgressView::draw() drawStartTexture(alpha); LLPanel::draw(); - drawLogos(alpha); // faded out completely - remove panel and reveal world if (mFadeToWorldTimer.getElapsedTimeF32() > FADE_TO_WORLD_TIME ) @@ -324,7 +300,6 @@ void LLProgressView::draw() drawStartTexture(1.0f); // draw children LLPanel::draw(); - drawLogos(1.0f); } void LLProgressView::setText(const std::string& text) @@ -341,90 +316,18 @@ void LLProgressView::setMessage(const std::string& msg) { mMessage = msg; mMessageText->setValue(mMessage); -} - -void LLProgressView::loadLogo(const std::string &path, - const U8 image_codec, - const LLRect &pos_rect, - const LLRectf &clip_rect, - const LLRectf &offset_rect) -{ - // We need these images very early, so we have to force-load them, otherwise they might not load in time. - if (!gDirUtilp->fileExists(path)) + S32 height = mMessageText->getTextPixelHeight(); + S32 delta = height - mMessageTextRectInitial.getHeight(); + if (delta > 0) { - return; + mLayoutPanel4->reshape(mLayoutPanel4RectInitial.getWidth(), mLayoutPanel4RectInitial.getHeight() + delta); + mLayoutMOTD->reshape(mLayoutMOTDRectInitial.getWidth(), mLayoutMOTDRectInitial.getHeight() + delta); } - - LLPointer<LLImageFormatted> start_image_frmted = LLImageFormatted::createFromType(image_codec); - if (!start_image_frmted->load(path)) - { - LL_WARNS("AppInit") << "Image load failed: " << path << LL_ENDL; - return; - } - - LLPointer<LLImageRaw> raw = new LLImageRaw; - if (!start_image_frmted->decode(raw, 0.0f)) + else { - LL_WARNS("AppInit") << "Image decode failed " << path << LL_ENDL; - return; + mLayoutPanel4->reshape(mLayoutPanel4RectInitial.getWidth(), mLayoutPanel4RectInitial.getHeight()); + mLayoutMOTD->reshape(mLayoutMOTDRectInitial.getWidth(), mLayoutMOTDRectInitial.getHeight()); } - // HACK: getLocalTexture allows only power of two dimentions - raw->expandToPowerOfTwo(); - - TextureData data; - data.mTexturep = LLViewerTextureManager::getLocalTexture(raw.get(), false); - data.mDrawRect = pos_rect; - data.mClipRect = clip_rect; - data.mOffsetRect = offset_rect; - mLogosList.push_back(data); -} - -void LLProgressView::initLogos() -{ - mLogosList.clear(); - - const U8 image_codec = IMG_CODEC_PNG; - const LLRectf default_clip(0.f, 1.f, 1.f, 0.f); - const S32 default_height = 28; - const S32 default_pad = 15; - - S32 icon_width, icon_height; - - // We don't know final screen rect yet, so we can't precalculate position fully - S32 texture_start_x = (S32)mLogosLabel->getFont()->getWidthF32(mLogosLabel->getWText().c_str()) + default_pad; - S32 texture_start_y = -7; - - // Normally we would just preload these textures from textures.xml, - // and display them via icon control, but they are only needed on - // startup and preloaded/UI ones stay forever - // (and this code was done already so simply reused it) - std::string temp_str = gDirUtilp->getExpandedFilename(LL_PATH_DEFAULT_SKIN, "textures", "3p_icons"); - - temp_str += gDirUtilp->getDirDelimiter(); - -#ifdef LL_HAVOK - // original image size is 342x113, central element is on a larger side - // plus internal padding, so it gets slightly more height than desired 32 - icon_width = 88; - icon_height = 29; - S32 pad_havok_y = -1; - loadLogo(temp_str + "havok_logo.png", - image_codec, - LLRect(texture_start_x, texture_start_y + pad_havok_y + icon_height, texture_start_x + icon_width, texture_start_y + pad_havok_y), - default_clip, - default_clip); - - texture_start_x += icon_width + default_pad; -#endif //LL_HAVOK - - // 108x41 - icon_width = 74; - icon_height = default_height; - loadLogo(temp_str + "vivox_logo.png", - image_codec, - LLRect(texture_start_x, texture_start_y + icon_height, texture_start_x + icon_width, texture_start_y), - default_clip, - default_clip); } void LLProgressView::initStartTexture(S32 location_id, bool is_in_production) @@ -505,19 +408,11 @@ void LLProgressView::initStartTexture(S32 location_id, bool is_in_production) void LLProgressView::initTextures(S32 location_id, bool is_in_production) { initStartTexture(location_id, is_in_production); - initLogos(); - - childSetVisible("panel_icons", !mLogosList.empty()); - childSetVisible("panel_top_spacer", mLogosList.empty()); } void LLProgressView::releaseTextures() { gStartTexture = NULL; - mLogosList.clear(); - - childSetVisible("panel_top_spacer", true); - childSetVisible("panel_icons", false); } void LLProgressView::setCancelButtonVisible(bool b, const std::string& label) diff --git a/indra/newview/llprogressview.h b/indra/newview/llprogressview.h index 15b04a8eb9..250ee511d7 100644 --- a/indra/newview/llprogressview.h +++ b/indra/newview/llprogressview.h @@ -53,7 +53,6 @@ public: /*virtual*/ void draw(); void drawStartTexture(F32 alpha); - void drawLogos(F32 alpha); /*virtual*/ bool handleHover(S32 x, S32 y, MASK mask); /*virtual*/ bool handleKeyHere(KEY key, MASK mask); @@ -86,7 +85,6 @@ public: protected: LLProgressBar* mProgressBar; LLMediaCtrl* mMediaCtrl; - LLTextBox* mLogosLabel = nullptr; LLTextBox* mProgressText = nullptr; LLTextBox* mMessageText = nullptr; F32 mPercentDone; @@ -95,6 +93,13 @@ protected: LLFrameTimer mFadeToWorldTimer; LLFrameTimer mFadeFromLoginTimer; LLRect mOutlineRect; + LLView* mLayoutPanel4 = nullptr; + LLView* mLayoutMOTD = nullptr; + // Rects for resizing purposes + LLRect mMessageTextRectInitial; + LLRect mLayoutPanel4RectInitial; + LLRect mLayoutMOTDRectInitial; + bool mMouseDownInActiveArea; bool mStartupComplete; @@ -105,25 +110,8 @@ protected: bool handleUpdate(const LLSD& event_data); static void onIdle(void* user_data); - void loadLogo(const std::string &path, const U8 image_codec, const LLRect &pos_rect, const LLRectf &clip_rect, const LLRectf &offset_rect); - // logos have unusual location and need to be preloaded to not appear grey, then deleted - void initLogos(); // Loads a bitmap to display during load void initStartTexture(S32 location_id, bool is_in_production); - -private: - // We need to draw textures on login, but only once. - // So this vector gets filled up for textures to render and gets cleaned later - // Some textures have unusual requirements, so we are rendering directly - class TextureData - { - public: - LLPointer<LLViewerTexture> mTexturep; - LLRect mDrawRect; - LLRectf mClipRect; - LLRectf mOffsetRect; - }; - std::vector<TextureData> mLogosList; }; #endif // LL_LLPROGRESSVIEW_H diff --git a/indra/newview/llreflectionmap.cpp b/indra/newview/llreflectionmap.cpp index f77d37f821..910509928d 100644 --- a/indra/newview/llreflectionmap.cpp +++ b/indra/newview/llreflectionmap.cpp @@ -52,6 +52,9 @@ LLReflectionMap::~LLReflectionMap() void LLReflectionMap::update(U32 resolution, U32 face, bool force_dynamic, F32 near_clip, bool useClipPlane, LLPlane clipPlane) { LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY; + if (!mCubeArray.notNull()) + return; + mLastUpdateTime = gFrameTimeSeconds; llassert(mCubeArray.notNull()); llassert(mCubeIndex != -1); @@ -65,8 +68,9 @@ void LLReflectionMap::update(U32 resolution, U32 face, bool force_dynamic, F32 n } F32 clip = (near_clip > 0) ? near_clip : getNearClip(); + bool dynamic = force_dynamic || getIsDynamic(); - gViewerWindow->cubeSnapshot(LLVector3(mOrigin), mCubeArray, mCubeIndex, face, clip, getIsDynamic() || force_dynamic, useClipPlane, clipPlane); + gViewerWindow->cubeSnapshot(LLVector3(mOrigin), mCubeArray, mCubeIndex, face, clip, dynamic, useClipPlane, clipPlane); } void LLReflectionMap::autoAdjustOrigin() @@ -185,7 +189,7 @@ void LLReflectionMap::autoAdjustOrigin() } } -bool LLReflectionMap::intersects(LLReflectionMap* other) +bool LLReflectionMap::intersects(LLReflectionMap* other) const { LLVector4a delta; delta.setSub(other->mOrigin, mOrigin); @@ -201,24 +205,24 @@ bool LLReflectionMap::intersects(LLReflectionMap* other) extern LLControlGroup gSavedSettings; -F32 LLReflectionMap::getAmbiance() +F32 LLReflectionMap::getAmbiance() const { F32 ret = 0.f; - if (mViewerObject && mViewerObject->getVolume()) + if (mViewerObject && mViewerObject->getVolumeConst()) { - ret = ((LLVOVolume*)mViewerObject)->getReflectionProbeAmbiance(); + ret = mViewerObject->getReflectionProbeAmbiance(); } return ret; } -F32 LLReflectionMap::getNearClip() +F32 LLReflectionMap::getNearClip() const { const F32 MINIMUM_NEAR_CLIP = 0.1f; F32 ret = 0.f; - if (mViewerObject && mViewerObject->getVolume()) + if (mViewerObject && mViewerObject->getVolumeConst()) { ret = mViewerObject->getReflectionProbeNearClip(); } @@ -234,11 +238,13 @@ F32 LLReflectionMap::getNearClip() return llmax(ret, MINIMUM_NEAR_CLIP); } -bool LLReflectionMap::getIsDynamic() +bool LLReflectionMap::getIsDynamic() const { - if (gSavedSettings.getS32("RenderReflectionProbeDetail") > (S32) LLReflectionMapManager::DetailLevel::STATIC_ONLY && + static LLCachedControl<S32> detail(gSavedSettings, "RenderReflectionProbeDetail", 1); + if (detail() > (S32)LLReflectionMapManager::DetailLevel::STATIC_ONLY && mViewerObject && - mViewerObject->getVolume()) + !mViewerObject->isDead() && + mViewerObject->getVolumeConst()) { return mViewerObject->getReflectionProbeIsDynamic(); } @@ -256,7 +262,7 @@ bool LLReflectionMap::getBox(LLMatrix4& box) glm::mat4 mv(get_current_modelview()); LLVector3 s = mViewerObject->getScale().scaledVec(LLVector3(0.5f, 0.5f, 0.5f)); mRadius = s.magVec(); - glm::mat4 scale = glm::scale(glm::make_vec3(s.mV)); + glm::mat4 scale = glm::scale(glm::vec3(s)); if (mViewerObject->mDrawable != nullptr) { // object to agent space (no scale) @@ -278,12 +284,12 @@ bool LLReflectionMap::getBox(LLMatrix4& box) return false; } -bool LLReflectionMap::isActive() +bool LLReflectionMap::isActive() const { return mCubeIndex != -1; } -bool LLReflectionMap::isRelevant() +bool LLReflectionMap::isRelevant() const { static LLCachedControl<S32> RenderReflectionProbeLevel(gSavedSettings, "RenderReflectionProbeLevel", 3); diff --git a/indra/newview/llreflectionmap.h b/indra/newview/llreflectionmap.h index 117ea4cfa6..d20bba7059 100644 --- a/indra/newview/llreflectionmap.h +++ b/indra/newview/llreflectionmap.h @@ -58,16 +58,16 @@ public: void autoAdjustOrigin(); // return true if given Reflection Map's influence volume intersect's with this one's - bool intersects(LLReflectionMap* other); + bool intersects(LLReflectionMap* other) const; // Get the ambiance value to use for this probe - F32 getAmbiance(); + F32 getAmbiance() const; // Get the near clip plane distance to use for this probe - F32 getNearClip(); + F32 getNearClip() const; // Return true if this probe should include avatars in its reflection map - bool getIsDynamic(); + bool getIsDynamic() const; // get the encoded bounding box of this probe's influence volume // will only return a box if this probe is associated with a VOVolume @@ -76,13 +76,13 @@ public: bool getBox(LLMatrix4& box); // return true if this probe is active for rendering - bool isActive(); + bool isActive() const; // perform occlusion query/readback void doOcclusion(const LLVector4a& eye); // return false if this probe isn't currently relevant (for example, disabled due to graphics preferences) - bool isRelevant(); + bool isRelevant() const; // point at which environment map was last generated from (in agent space) LLVector4a mOrigin; diff --git a/indra/newview/llreflectionmapmanager.cpp b/indra/newview/llreflectionmapmanager.cpp index 8f75b108cc..fae6acec3c 100644 --- a/indra/newview/llreflectionmapmanager.cpp +++ b/indra/newview/llreflectionmapmanager.cpp @@ -144,13 +144,14 @@ static void touch_default_probe(LLReflectionMap* probe) LLReflectionMapManager::LLReflectionMapManager() { + mDynamicProbeCount = LL_MAX_REFLECTION_PROBE_COUNT; initCubeFree(); } void LLReflectionMapManager::initCubeFree() { // start at 1 because index 0 is reserved for mDefaultProbe - for (int i = 1; i < LL_MAX_REFLECTION_PROBE_COUNT; ++i) + for (U32 i = 1; i < mDynamicProbeCount; ++i) { mCubeFree.push_back(i); } @@ -221,11 +222,62 @@ void LLReflectionMapManager::update() resume(); } + static LLCachedControl<S32> sDetail(gSavedSettings, "RenderReflectionProbeDetail", -1); + static LLCachedControl<S32> sLevel(gSavedSettings, "RenderReflectionProbeLevel", 3); + static LLCachedControl<U32> sReflectionProbeCount(gSavedSettings, "RenderReflectionProbeCount", 256U); + static LLCachedControl<S32> sProbeDynamicAllocation(gSavedSettings, "RenderReflectionProbeDynamicAllocation", -1); + mResetFade = llmin((F32)(mResetFade + gFrameIntervalSeconds * 2.f), 1.f); + + { + U32 probe_count_temp = mDynamicProbeCount; + if (sProbeDynamicAllocation > -1) + { + if (sLevel == 0) + { + mDynamicProbeCount = 1; + } + else if (sLevel == 1) + { + mDynamicProbeCount = (U32)mProbes.size(); + } + else if (sLevel == 2) + { + mDynamicProbeCount = llmax((U32)mProbes.size(), 128); + } + else + { + mDynamicProbeCount = 256; + } + + if (sProbeDynamicAllocation > 1) + { + // Round mDynamicProbeCount to the nearest increment of 16 + mDynamicProbeCount = ((mDynamicProbeCount + sProbeDynamicAllocation / 2) / sProbeDynamicAllocation) * 16; + mDynamicProbeCount = llclamp(mDynamicProbeCount, 1, sReflectionProbeCount); + } + else + { + mDynamicProbeCount = llclamp(mDynamicProbeCount + sProbeDynamicAllocation, 1, sReflectionProbeCount); + } + } + else + { + mDynamicProbeCount = sReflectionProbeCount; + } + + mDynamicProbeCount = llmin(mDynamicProbeCount, LL_MAX_REFLECTION_PROBE_COUNT); + + if (mDynamicProbeCount != probe_count_temp) + mResetFade = 1.f; + } + initReflectionMaps(); + static LLCachedControl<bool> render_hdr(gSavedSettings, "RenderHDREnabled", true); + if (!mRenderTarget.isComplete()) { - U32 color_fmt = GL_RGB16F; + U32 color_fmt = render_hdr ? GL_R11F_G11F_B10F : GL_RGB8; U32 targetRes = mProbeResolution * 4; // super sample mRenderTarget.allocate(targetRes, targetRes, color_fmt, true); } @@ -238,7 +290,7 @@ void LLReflectionMapManager::update() mMipChain.resize(count); for (U32 i = 0; i < count; ++i) { - mMipChain[i].allocate(res, res, GL_RGB16F); + mMipChain[i].allocate(res, res, render_hdr ? GL_R11F_G11F_B10F : GL_RGB8); res /= 2; } } @@ -276,9 +328,6 @@ void LLReflectionMapManager::update() bool did_update = false; - static LLCachedControl<S32> sDetail(gSavedSettings, "RenderReflectionProbeDetail", -1); - static LLCachedControl<S32> sLevel(gSavedSettings, "RenderReflectionProbeLevel", 3); - bool realtime = sDetail >= (S32)LLReflectionMapManager::DetailLevel::REALTIME; LLReflectionMap* closestDynamic = nullptr; @@ -306,13 +355,14 @@ void LLReflectionMapManager::update() LLReflectionMap* probe = mProbes[i]; llassert(probe != nullptr); - if (probe->mCubeIndex != -1 && mUpdatingProbe != probe) + if (probe && probe->mCubeIndex != -1 && mUpdatingProbe != probe) { // free this index mCubeFree.push_back(probe->mCubeIndex); probe->mCubeArray = nullptr; probe->mCubeIndex = -1; probe->mComplete = false; + probe->mFadeIn = 0; } } @@ -333,6 +383,8 @@ void LLReflectionMapManager::update() } } + mResetFade = llmin((F32)(mResetFade + gFrameIntervalSeconds * 2.f), 1.f); + for (unsigned int i = 0; i < mProbes.size(); ++i) { LLReflectionMap* probe = mProbes[i]; @@ -503,6 +555,16 @@ LLReflectionMap* LLReflectionMapManager::addProbe(LLSpatialGroup* group) return probe; } +U32 LLReflectionMapManager::probeCount() +{ + return mDynamicProbeCount; +} + +U32 LLReflectionMapManager::probeMemory() +{ + return (mDynamicProbeCount * 6 * (mProbeResolution * mProbeResolution) * 4) / 1024 / 1024 + (mDynamicProbeCount * 6 * (LL_IRRADIANCE_MAP_RESOLUTION * LL_IRRADIANCE_MAP_RESOLUTION) * 4) / 1024 / 1024; +} + struct CompareProbeDepth { bool operator()(const LLReflectionMap* lhs, const LLReflectionMap* rhs) @@ -815,7 +877,9 @@ void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face) LL_PROFILE_GPU_ZONE("probe mip copy"); mTexture->bind(0); //glCopyTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, mip, 0, 0, probe->mCubeIndex * 6 + face, 0, 0, res, res); +#if GL_VERSION_4_0 glCopyTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, mip, 0, 0, sourceIdx * 6 + face, 0, 0, res, res); +#endif //if (i == 0) //{ //glCopyTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, mip, 0, 0, probe->mCubeIndex * 6 + face, 0, 0, res, res); @@ -844,8 +908,10 @@ void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face) gRadianceGenProgram.bind(); mVertexBuffer->setBuffer(); +#if GL_VERSION_4_0 S32 channel = gRadianceGenProgram.enableTexture(LLShaderMgr::REFLECTION_PROBES, LLTexUnit::TT_CUBE_MAP_ARRAY); mTexture->bind(channel); +#endif gRadianceGenProgram.uniform1i(sSourceIdx, sourceIdx); gRadianceGenProgram.uniform1f(LLShaderMgr::REFLECTION_PROBE_MAX_LOD, mMaxProbeLOD); gRadianceGenProgram.uniform1f(LLShaderMgr::REFLECTION_PROBE_STRENGTH, 1.f); @@ -874,7 +940,9 @@ void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face) mVertexBuffer->drawArrays(gGL.TRIANGLE_STRIP, 0, 4); +#if GL_VERSION_4_0 glCopyTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, i, 0, 0, probe->mCubeIndex * 6 + cf, 0, 0, res, res); +#endif } if (i != mMipChain.size() - 1) @@ -890,8 +958,10 @@ void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face) { //generate irradiance map gIrradianceGenProgram.bind(); +#if GL_VERSION_4_0 S32 channel = gIrradianceGenProgram.enableTexture(LLShaderMgr::REFLECTION_PROBES, LLTexUnit::TT_CUBE_MAP_ARRAY); mTexture->bind(channel); +#endif gIrradianceGenProgram.uniform1i(sSourceIdx, sourceIdx); gIrradianceGenProgram.uniform1f(LLShaderMgr::REFLECTION_PROBE_MAX_LOD, mMaxProbeLOD); @@ -924,9 +994,11 @@ void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face) mVertexBuffer->drawArrays(gGL.TRIANGLE_STRIP, 0, 4); S32 res = mMipChain[i].getWidth(); +#if GL_VERSION_4_0 mIrradianceMaps->bind(channel); glCopyTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, i - start_mip, 0, 0, probe->mCubeIndex * 6 + cf, 0, 0, res, res); mTexture->bind(channel); +#endif } } } @@ -1010,60 +1082,18 @@ void LLReflectionMapManager::updateUniforms() LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY; - // structure for packing uniform buffer object - // see class3/deferred/reflectionProbeF.glsl - struct ReflectionProbeData - { - // for box probes, matrix that transforms from camera space to a [-1, 1] cube representing the bounding box of - // the box probe - LLMatrix4 refBox[LL_MAX_REFLECTION_PROBE_COUNT]; - - LLMatrix4 heroBox; - - // for sphere probes, origin (xyz) and radius (w) of refmaps in clip space - LLVector4 refSphere[LL_MAX_REFLECTION_PROBE_COUNT]; - - // extra parameters - // x - irradiance scale - // y - radiance scale - // z - fade in - // w - znear - LLVector4 refParams[LL_MAX_REFLECTION_PROBE_COUNT]; - - LLVector4 heroSphere; - - // indices used by probe: - // [i][0] - cubemap array index for this probe - // [i][1] - index into "refNeighbor" for probes that intersect this probe - // [i][2] - number of probes that intersect this probe, or -1 for no neighbors - // [i][3] - priority (probe type stored in sign bit - positive for spheres, negative for boxes) - GLint refIndex[LL_MAX_REFLECTION_PROBE_COUNT][4]; - - // list of neighbor indices - GLint refNeighbor[4096]; - - GLint refBucket[256][4]; //lookup table for which index to start with for the given Z depth - // numbrer of active refmaps - GLint refmapCount; - - GLint heroShape; - GLint heroMipCount; - GLint heroProbeCount; - }; mReflectionMaps.resize(mReflectionProbeCount); getReflectionMaps(mReflectionMaps); - ReflectionProbeData rpd; - F32 minDepth[256]; for (int i = 0; i < 256; ++i) { - rpd.refBucket[i][0] = mReflectionProbeCount; - rpd.refBucket[i][1] = mReflectionProbeCount; - rpd.refBucket[i][2] = mReflectionProbeCount; - rpd.refBucket[i][3] = mReflectionProbeCount; + mProbeData.refBucket[i][0] = mReflectionProbeCount; + mProbeData.refBucket[i][1] = mReflectionProbeCount; + mProbeData.refBucket[i][2] = mReflectionProbeCount; + mProbeData.refBucket[i][3] = mReflectionProbeCount; minDepth[i] = FLT_MAX; } @@ -1083,7 +1113,11 @@ void LLReflectionMapManager::updateUniforms() bool is_ambiance_pass = gCubeSnapshot && !isRadiancePass(); F32 ambscale = is_ambiance_pass ? 0.f : 1.f; + ambscale *= mResetFade; + ambscale = llmax(0, ambscale); F32 radscale = is_ambiance_pass ? 0.5f : 1.f; + radscale *= mResetFade; + radscale = llmax(0, radscale); for (auto* refmap : mReflectionMaps) { @@ -1109,7 +1143,7 @@ void LLReflectionMapManager::updateUniforms() if (refmap->mMinDepth < minDepth[i]) { minDepth[i] = refmap->mMinDepth; - rpd.refBucket[i][0] = refmap->mProbeIndex; + mProbeData.refBucket[i][0] = refmap->mProbeIndex; } } } @@ -1137,23 +1171,23 @@ void LLReflectionMapManager::updateUniforms() } } modelview.affineTransform(refmap->mOrigin, oa); - rpd.refSphere[count].set(oa.getF32ptr()); - rpd.refSphere[count].mV[3] = refmap->mRadius; + mProbeData.refSphere[count].set(oa.getF32ptr()); + mProbeData.refSphere[count].mV[3] = refmap->mRadius; } - rpd.refIndex[count][0] = refmap->mCubeIndex; + mProbeData.refIndex[count][0] = refmap->mCubeIndex; llassert(nc % 4 == 0); - rpd.refIndex[count][1] = nc / 4; - rpd.refIndex[count][3] = refmap->mPriority; + mProbeData.refIndex[count][1] = nc / 4; + mProbeData.refIndex[count][3] = refmap->mPriority; // for objects that are reflection probes, use the volume as the influence volume of the probe // only possibile influence volumes are boxes and spheres, so detect boxes and treat everything else as spheres - if (refmap->getBox(rpd.refBox[count])) + if (refmap->getBox(mProbeData.refBox[count])) { // negate priority to indicate this probe has a box influence volume - rpd.refIndex[count][3] = -rpd.refIndex[count][3]; + mProbeData.refIndex[count][3] = -mProbeData.refIndex[count][3]; } - rpd.refParams[count].set( + mProbeData.refParams[count].set( llmax(minimum_ambiance, refmap->getAmbiance())*ambscale, // ambiance scale radscale, // radiance scale refmap->mFadeIn, // fade in weight @@ -1180,7 +1214,7 @@ void LLReflectionMapManager::updateUniforms() } // this neighbor may be sampled - rpd.refNeighbor[ni++] = idx; + mProbeData.refNeighbor[ni++] = idx; neighbor_count++; if (neighbor_count >= max_neighbors) @@ -1193,11 +1227,11 @@ void LLReflectionMapManager::updateUniforms() if (nc == ni) { //no neighbors, tag as empty - rpd.refIndex[count][1] = -1; + mProbeData.refIndex[count][1] = -1; } else { - rpd.refIndex[count][2] = ni - nc; + mProbeData.refIndex[count][2] = ni - nc; // move the cursor forward nc = ni; @@ -1235,19 +1269,19 @@ void LLReflectionMapManager::updateUniforms() } #endif - rpd.refmapCount = count; + mProbeData.refmapCount = count; gPipeline.mHeroProbeManager.updateUniforms(); // Get the hero data. - rpd.heroBox = gPipeline.mHeroProbeManager.mHeroData.heroBox; - rpd.heroSphere = gPipeline.mHeroProbeManager.mHeroData.heroSphere; - rpd.heroShape = gPipeline.mHeroProbeManager.mHeroData.heroShape; - rpd.heroMipCount = gPipeline.mHeroProbeManager.mHeroData.heroMipCount; - rpd.heroProbeCount = gPipeline.mHeroProbeManager.mHeroData.heroProbeCount; + mProbeData.heroBox = gPipeline.mHeroProbeManager.mHeroData.heroBox; + mProbeData.heroSphere = gPipeline.mHeroProbeManager.mHeroData.heroSphere; + mProbeData.heroShape = gPipeline.mHeroProbeManager.mHeroData.heroShape; + mProbeData.heroMipCount = gPipeline.mHeroProbeManager.mHeroData.heroMipCount; + mProbeData.heroProbeCount = gPipeline.mHeroProbeManager.mHeroData.heroProbeCount; - //copy rpd into uniform buffer object + //copy mProbeData into uniform buffer object if (mUBO == 0) { glGenBuffers(1, &mUBO); @@ -1256,7 +1290,7 @@ void LLReflectionMapManager::updateUniforms() { LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("rmmsu - update buffer"); glBindBuffer(GL_UNIFORM_BUFFER, mUBO); - glBufferData(GL_UNIFORM_BUFFER, sizeof(ReflectionProbeData), &rpd, GL_STREAM_DRAW); + glBufferData(GL_UNIFORM_BUFFER, sizeof(ReflectionProbeData), &mProbeData, GL_STREAM_DRAW); glBindBuffer(GL_UNIFORM_BUFFER, 0); } @@ -1390,11 +1424,9 @@ void LLReflectionMapManager::renderDebug() void LLReflectionMapManager::initReflectionMaps() { - U32 count = LL_MAX_REFLECTION_PROBE_COUNT; - static LLCachedControl<U32> ref_probe_res(gSavedSettings, "RenderReflectionProbeResolution", 128U); U32 probe_resolution = nhpo2(llclamp(ref_probe_res(), (U32)64, (U32)512)); - if (mTexture.isNull() || mReflectionProbeCount != count || mProbeResolution != probe_resolution || mReset) + if (mTexture.isNull() || mReflectionProbeCount != mDynamicProbeCount || mProbeResolution != probe_resolution || mReset) { if(mProbeResolution != probe_resolution) { @@ -1403,9 +1435,8 @@ void LLReflectionMapManager::initReflectionMaps() } gEXRImage = nullptr; - mReset = false; - mReflectionProbeCount = count; + mReflectionProbeCount = mDynamicProbeCount; mProbeResolution = probe_resolution; mMaxProbeLOD = log2f((F32)mProbeResolution) - 1.f; // number of mips - 1 @@ -1413,13 +1444,25 @@ void LLReflectionMapManager::initReflectionMaps() mTexture->getWidth() != mProbeResolution || mReflectionProbeCount + 2 != mTexture->getCount()) { - mTexture = new LLCubeMapArray(); + if (mTexture) + { + mTexture = new LLCubeMapArray(*mTexture, mProbeResolution, mReflectionProbeCount + 2); - // store mReflectionProbeCount+2 cube maps, final two cube maps are used for render target and radiance map generation source) - mTexture->allocate(mProbeResolution, 3, mReflectionProbeCount + 2); + mIrradianceMaps = new LLCubeMapArray(*mIrradianceMaps, LL_IRRADIANCE_MAP_RESOLUTION, mReflectionProbeCount); + } + else + { + mTexture = new LLCubeMapArray(); - mIrradianceMaps = new LLCubeMapArray(); - mIrradianceMaps->allocate(LL_IRRADIANCE_MAP_RESOLUTION, 3, mReflectionProbeCount, false); + static LLCachedControl<bool> render_hdr(gSavedSettings, "RenderHDREnabled", true); + + // store mReflectionProbeCount+2 cube maps, final two cube maps are used for render target and radiance map generation + // source) + mTexture->allocate(mProbeResolution, 3, mReflectionProbeCount + 2, true, render_hdr); + + mIrradianceMaps = new LLCubeMapArray(); + mIrradianceMaps->allocate(LL_IRRADIANCE_MAP_RESOLUTION, 3, mReflectionProbeCount, false, render_hdr); + } } // reset probe state @@ -1439,6 +1482,7 @@ void LLReflectionMapManager::initReflectionMaps() probe->mCubeArray = nullptr; probe->mCubeIndex = -1; probe->mNeighbors.clear(); + probe->mFadeIn = 0; } mCubeFree.clear(); diff --git a/indra/newview/llreflectionmapmanager.h b/indra/newview/llreflectionmapmanager.h index f81fb30738..0719c28134 100644 --- a/indra/newview/llreflectionmapmanager.h +++ b/indra/newview/llreflectionmapmanager.h @@ -38,7 +38,7 @@ class LLViewerObject; #define LL_MAX_REFLECTION_PROBE_COUNT 256 // reflection probe resolution -#define LL_IRRADIANCE_MAP_RESOLUTION 64 +#define LL_IRRADIANCE_MAP_RESOLUTION 16 // reflection probe mininum scale #define LL_REFLECTION_PROBE_MINIMUM_SCALE 1.f; @@ -56,6 +56,51 @@ public: REALTIME = 2 }; + // General guidance for UBOs is to statically allocate all of these fields to make your life ever so slightly easier. + // Then set a "max" value for the number of probes you'll ever have, and use that to index into the arrays. + // We do this with refmapCount. The shaders will just pick up on it there. + // This data structure should _always_ match what's in class3/deferred/reflectionProbeF.glsl. + // The shader can and will break otherwise. + // -Geenz 2025-03-10 + struct ReflectionProbeData + { + // for box probes, matrix that transforms from camera space to a [-1, 1] cube representing the bounding box of + // the box probe + LLMatrix4 refBox[LL_MAX_REFLECTION_PROBE_COUNT]; + + LLMatrix4 heroBox; + + // for sphere probes, origin (xyz) and radius (w) of refmaps in clip space + LLVector4 refSphere[LL_MAX_REFLECTION_PROBE_COUNT]; + + // extra parameters + // x - irradiance scale + // y - radiance scale + // z - fade in + // w - znear + LLVector4 refParams[LL_MAX_REFLECTION_PROBE_COUNT]; + + LLVector4 heroSphere; + + // indices used by probe: + // [i][0] - cubemap array index for this probe + // [i][1] - index into "refNeighbor" for probes that intersect this probe + // [i][2] - number of probes that intersect this probe, or -1 for no neighbors + // [i][3] - priority (probe type stored in sign bit - positive for spheres, negative for boxes) + GLint refIndex[LL_MAX_REFLECTION_PROBE_COUNT][4]; + + // list of neighbor indices + GLint refNeighbor[4096]; + + GLint refBucket[256][4]; // lookup table for which index to start with for the given Z depth + // numbrer of active refmaps + GLint refmapCount; + + GLint heroShape; + GLint heroMipCount; + GLint heroProbeCount; + }; + // allocate an environment map of the given resolution LLReflectionMapManager(); @@ -114,6 +159,9 @@ public: // with false when done. void forceDefaultProbeAndUpdateUniforms(bool force = true); + U32 probeCount(); + U32 probeMemory(); + private: friend class LLPipeline; friend class LLHeroProbeManager; @@ -121,6 +169,9 @@ private: // initialize mCubeFree array to default values void initCubeFree(); + // Just does a bulk clear of all of the cubemaps. + void clearCubeMaps(); + // delete the probe with the given index in mProbes void deleteProbe(U32 i); @@ -195,6 +246,8 @@ private: // number of reflection probes to use for rendering U32 mReflectionProbeCount; + U32 mDynamicProbeCount; + // resolution of reflection probes U32 mProbeResolution = 128; @@ -207,8 +260,13 @@ private: // if true, reset all probe render state on the next update (for teleports and sky changes) bool mReset = false; + float mResetFade = 1.f; + float mGlobalFadeTarget = 1.f; + // if true, only update the default probe bool mPaused = false; F32 mResumeTime = 0.f; + + ReflectionProbeData mProbeData; }; diff --git a/indra/newview/llremoteparcelrequest.cpp b/indra/newview/llremoteparcelrequest.cpp index 7b80e8c27f..d0aa1af2f3 100644 --- a/indra/newview/llremoteparcelrequest.cpp +++ b/indra/newview/llremoteparcelrequest.cpp @@ -102,7 +102,15 @@ void LLRemoteParcelInfoProcessor::processParcelInfoReply(LLMessageSystem* msg, v msg->getS32 ("Data", "SalePrice", parcel_data.sale_price); msg->getS32 ("Data", "AuctionID", parcel_data.auction_id); - LLRemoteParcelInfoProcessor::observer_multimap_t & observers = LLRemoteParcelInfoProcessor::getInstance()->mObservers; + LLRemoteParcelInfoProcessor* inst = LLRemoteParcelInfoProcessor::getInstance(); + + requests_map_t::const_iterator found = inst->mPendingParcelRequests.find(parcel_data.parcel_id); + if (found != inst->mPendingParcelRequests.end()) + { + inst->mPendingParcelRequests.erase(found); + } + + LLRemoteParcelInfoProcessor::observer_multimap_t & observers = inst->mObservers; typedef std::vector<observer_multimap_t::iterator> deadlist_t; deadlist_t dead_iters; @@ -151,6 +159,15 @@ void LLRemoteParcelInfoProcessor::processParcelInfoReply(LLMessageSystem* msg, v void LLRemoteParcelInfoProcessor::sendParcelInfoRequest(const LLUUID& parcel_id) { + constexpr F32 DUPPLICATE_TIMEOUT = 0.5f; + requests_map_t::const_iterator found = mPendingParcelRequests.find(parcel_id); + if (found != mPendingParcelRequests.end() && found->second.getElapsedTimeF32() < DUPPLICATE_TIMEOUT) + { + // recently requested + return; + } + mPendingParcelRequests[parcel_id].reset(); + LLMessageSystem *msg = gMessageSystem; msg->newMessage("ParcelInfoRequest"); diff --git a/indra/newview/llremoteparcelrequest.h b/indra/newview/llremoteparcelrequest.h index 1420b4032e..7059e14bec 100644 --- a/indra/newview/llremoteparcelrequest.h +++ b/indra/newview/llremoteparcelrequest.h @@ -91,6 +91,8 @@ public: private: typedef std::multimap<LLUUID, LLHandle<LLRemoteParcelInfoObserver> > observer_multimap_t; observer_multimap_t mObservers; + typedef std::map<LLUUID, LLTimer> requests_map_t; + requests_map_t mPendingParcelRequests; // Dupplicate request avoidance void regionParcelInfoCoro(std::string url, LLUUID regionId, LLVector3 posRegion, LLVector3d posGlobal, LLHandle<LLRemoteParcelInfoObserver> observerHandle); }; diff --git a/indra/newview/llscrollingpanelparam.h b/indra/newview/llscrollingpanelparam.h index 3aba4e4e40..93daf22e76 100644 --- a/indra/newview/llscrollingpanelparam.h +++ b/indra/newview/llscrollingpanelparam.h @@ -81,7 +81,6 @@ public: protected: LLTimer mMouseDownTimer; // timer for how long mouse has been held down on a hint. F32 mLastHeldTime; - bool mAllowModify; LLButton* mLessBtn; LLButton* mMoreBtn; diff --git a/indra/newview/llsearchcombobox.h b/indra/newview/llsearchcombobox.h index e0162bac80..17787ca5e6 100644 --- a/indra/newview/llsearchcombobox.h +++ b/indra/newview/llsearchcombobox.h @@ -61,6 +61,11 @@ public: ~LLSearchComboBox(); + /** + * Sets focus to text box + */ + void focusTextEntry(); + protected: LLSearchComboBox(const Params&p); @@ -93,11 +98,6 @@ protected: */ void onSelectionCommit(); - /** - * Sets focus to text box - */ - void focusTextEntry(); - LLButton* mSearchButton; }; diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp index fceb25b3d3..1876cd3086 100644 --- a/indra/newview/llselectmgr.cpp +++ b/indra/newview/llselectmgr.cpp @@ -1995,7 +1995,7 @@ bool LLSelectMgr::selectionSetGLTFMaterial(const LLUUID& mat_id) asset_id = BLANK_MATERIAL_ASSET_ID; } } - + objectp->clearTEWaterExclusion(te); // Blank out most override data on the object and send to server objectp->setRenderMaterialID(te, asset_id); @@ -2477,6 +2477,7 @@ void LLSelectMgr::selectionSetMedia(U8 media_type, const LLSD &media_data) } else { // Add/update media + object->clearTEWaterExclusion(te); object->setTEMediaFlags(te, mMediaFlags); LLVOVolume *vo = dynamic_cast<LLVOVolume*>(object); llassert(NULL != vo); @@ -6490,7 +6491,9 @@ void LLSelectMgr::renderSilhouettes(bool for_hud) } } +#if GL_VERSION_1_1 glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); +#endif S32 num_tes = llmin((S32)objectp->getNumTEs(), (S32)objectp->getNumFaces()); // avatars have TEs but no faces for (S32 te = 0; te < num_tes; ++te) @@ -6505,7 +6508,9 @@ void LLSelectMgr::renderSilhouettes(bool for_hud) gGL.popMatrix(); glLineWidth(1.f); +#if GL_VERSION_1_1 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); +#endif if (shader) { @@ -7253,7 +7258,10 @@ void dialog_refresh_all() // *TODO: Eliminate all calls into outside classes below, make those // objects register with the update signal. - gFloaterTools->dirty(); + if (gFloaterTools) + { + gFloaterTools->dirty(); + } gMenuObject->needsArrange(); @@ -7482,7 +7490,8 @@ void LLSelectMgr::updatePointAt() LLVector3 select_offset; const LLPickInfo& pick = gViewerWindow->getLastPick(); LLViewerObject *click_object = pick.getObject(); - if (click_object && click_object->isSelected()) + bool was_hud = pick.mPickHUD && click_object && !click_object->isHUDAttachment(); + if (click_object && click_object->isSelected() && !was_hud) { // clicked on another object in our selection group, use that as target select_offset.setVec(pick.mObjectOffset); @@ -7720,6 +7729,14 @@ void LLSelectMgr::setAgentHUDZoom(F32 target_zoom, F32 current_zoom) gAgentCamera.mHUDCurZoom = current_zoom; } +void LLSelectMgr::clearWaterExclusion() +{ + // reset texture to default plywood + LLSelectMgr::getInstance()->selectionSetImage(DEFAULT_OBJECT_TEXTURE); + // reset texture repeats, that might be altered by invisiprim script from wiki + LLSelectMgr::getInstance()->selectionTexScaleAutofit(2.f); +} + ///////////////////////////////////////////////////////////////////////////// // Object selection iterator helpers ///////////////////////////////////////////////////////////////////////////// diff --git a/indra/newview/llselectmgr.h b/indra/newview/llselectmgr.h index b70ec3dbea..0dbdc133e3 100644 --- a/indra/newview/llselectmgr.h +++ b/indra/newview/llselectmgr.h @@ -836,6 +836,7 @@ public: void getAgentHUDZoom(F32 &target_zoom, F32 ¤t_zoom) const; void updatePointAt(); + void clearWaterExclusion(); // Internal list maintenance functions. TODO: Make these private! void remove(std::vector<LLViewerObject*>& objects); diff --git a/indra/newview/llsettingsvo.cpp b/indra/newview/llsettingsvo.cpp index cf96072ae2..6023f6885d 100644 --- a/indra/newview/llsettingsvo.cpp +++ b/indra/newview/llsettingsvo.cpp @@ -807,7 +807,7 @@ void LLSettingsVOSky::applySpecial(void *ptarget, bool force) static LLCachedControl<F32> tonemap_mix_setting(gSavedSettings, "RenderTonemapMix", 1.f); // sky is a "classic" sky following pre SL 7.0 shading - bool classic_mode = psky->canAutoAdjust(); + bool classic_mode = psky->canAutoAdjust() && !should_auto_adjust(); if (!classic_mode) { @@ -832,6 +832,10 @@ void LLSettingsVOSky::applySpecial(void *ptarget, bool force) { shader->uniform3fv(LLShaderMgr::AMBIENT, LLVector3(ambient.mV)); shader->uniform1f(LLShaderMgr::SKY_HDR_SCALE, sqrtf(g)*2.0f); // use a modifier here so 1.0 maps to the "most desirable" default and the maximum value doesn't go off the rails + + // Low quality setting + if (!LLPipeline::sReflectionProbesEnabled) + probe_ambiance = DEFAULT_AUTO_ADJUST_PROBE_AMBIANCE; } else if (psky->canAutoAdjust() && should_auto_adjust) { // auto-adjust legacy sky to take advantage of probe ambiance @@ -1093,8 +1097,8 @@ void LLSettingsVOWater::applySpecial(void *ptarget, bool force) LLVector4 waterPlane(enorm.x, enorm.y, enorm.z, -glm::dot(ep, enorm)); - norm = glm::make_vec3(gPipeline.mHeroProbeManager.mMirrorNormal.mV); - p = glm::make_vec3(gPipeline.mHeroProbeManager.mMirrorPosition.mV); + norm = glm::vec3(gPipeline.mHeroProbeManager.mMirrorNormal); + p = glm::vec3(gPipeline.mHeroProbeManager.mMirrorPosition); enorm = mul_mat4_vec3(invtrans, norm); enorm = glm::normalize(enorm); ep = mul_mat4_vec3(mat, p); diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp index a1a67c319c..a90ff73578 100644 --- a/indra/newview/llspatialpartition.cpp +++ b/indra/newview/llspatialpartition.cpp @@ -1655,7 +1655,9 @@ void renderOctree(LLSpatialGroup* group) { LLGLDepthTest gl_depth(false, false); +#if GL_VERSION_1_1 glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); +#endif gGL.diffuseColor4f(1,0,0,group->mBuilt); gGL.flush(); @@ -1752,7 +1754,9 @@ void renderOctree(LLSpatialGroup* group) gGL.popMatrix(); } } +#if GL_VERSION_1_1 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); +#endif gDebugProgram.bind(); // make sure non-rigged variant is bound gGL.diffuseColor4f(1,1,1,1); } @@ -2491,7 +2495,9 @@ void renderPhysicsShape(LLDrawable* drawable, LLVOVolume* volume, bool wireframe llassert(LLGLSLShader::sCurBoundShader != 0); LLVertexBuffer::unbind(); +#if GL_VERSION_1_1 glVertexPointer(3, GL_FLOAT, 16, phys_volume->mHullPoints); +#endif gGL.diffuseColor4fv(color.mV); @@ -2609,12 +2615,8 @@ void renderTexturePriority(LLDrawable* drawable) LLGLDisable blend(GL_BLEND); - //LLViewerTexture* imagep = facep->getTexture(); - //if (imagep) if (facep) { - - //F32 vsize = imagep->mMaxVirtualSize; F32 vsize = facep->getPixelArea(); if (vsize > sCurMaxTexPriority) @@ -2640,18 +2642,6 @@ void renderTexturePriority(LLDrawable* drawable) size.mul(0.5f); size.add(LLVector4a(0.01f)); drawBox(center, size); - - /*S32 boost = imagep->getBoostLevel(); - if (boost>LLGLTexture::BOOST_NONE) - { - F32 t = (F32) boost / (F32) (LLGLTexture::BOOST_MAX_LEVEL-1); - LLVector4 col = lerp(boost_cold, boost_hot, t); - LLGLEnable blend_on(GL_BLEND); - gGL.blendFunc(GL_SRC_ALPHA, GL_ONE); - gGL.diffuseColor4fv(col.mV); - drawBox(center, size); - gGL.blendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - }*/ } } @@ -2688,7 +2678,9 @@ void renderTextureAnim(LLDrawInfo* params) void renderBatchSize(LLDrawInfo* params) { +#if GL_VERSION_1_1 LLGLEnable offset(GL_POLYGON_OFFSET_FILL); +#endif glPolygonOffset(-1.f, 1.f); LLGLSLShader* old_shader = LLGLSLShader::sCurBoundShaderPtr; bool bind = false; @@ -2994,7 +2986,9 @@ void renderRaycast(LLDrawable* drawablep) dir.setSub(end, start); gGL.flush(); +#if GL_VERSION_1_1 glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); +#endif { //render face positions @@ -3013,7 +3007,9 @@ void renderRaycast(LLDrawable* drawablep) } gGL.popMatrix(); +#if GL_VERSION_1_1 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); +#endif } } } @@ -3601,16 +3597,22 @@ void LLSpatialPartition::renderDebug() LLGLEnable blend(GL_BLEND); LLGLDepthTest depth_under(GL_TRUE, GL_FALSE, GL_GREATER); +#if GL_VERSION_1_1 glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); +#endif gGL.diffuseColor4f(0.5f, 0.0f, 0, 0.25f); +#if GL_VERSION_1_1 LLGLEnable offset(GL_POLYGON_OFFSET_LINE); +#endif glPolygonOffset(-1.f, -1.f); LLOctreeRenderXRay xray(camera); xray.traverse(mOctree); +#if GL_VERSION_1_1 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); +#endif } } gDebugProgram.unbind(); diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp index b32b80331a..9a26ebc5f9 100644 --- a/indra/newview/llstartup.cpp +++ b/indra/newview/llstartup.cpp @@ -39,6 +39,10 @@ #include "llviewermedia_streamingaudio.h" #include "llaudioengine.h" +#ifdef LL_FMODSTUDIO +# include "llaudioengine_fmodstudio.h" +#endif + #ifdef LL_OPENAL #include "llaudioengine_openal.h" #endif @@ -210,6 +214,9 @@ #include "lldxhardware.h" #endif +#include "fsfloatersearch.h" + + // // exported globals // @@ -297,16 +304,62 @@ void callback_cache_name(const LLUUID& id, const std::string& full_name, bool is // exported functionality // +void do_startup_frame() +{ + // Until after STATE_AGENT_SEND we don't get very many UDP packets to poll the socket, + // and after STATE_PRECACHE the LLAppViewer::idleNetwork() will do UDP processing, + // so we only bother to process between those two states. + EStartupState state = LLStartUp::getStartupState(); + if (state > STATE_AGENT_SEND && state < STATE_PRECACHE) + { + // drain the UDP socket... + U64 t0 = totalTime(); + constexpr U64 MAX_STARTUP_FRAME_TIME = 2000; // usec + constexpr U64 MAX_STARTUP_FRAME_MESSAGES = 100; + S32 num_messages = 0; + bool needs_drain = false; + LockMessageChecker lmc(gMessageSystem); + while (lmc.checkAllMessages(gFrameCount, gServicePump)) + { + if (gDoDisconnect) + { + // We're disconnecting, don't process any more messages from the server + // We're usually disconnecting due to either network corruption or a + // server going down, so this is OK. + break; + } + if (++num_messages >= MAX_STARTUP_FRAME_MESSAGES + || (totalTime() - t0) > MAX_STARTUP_FRAME_TIME) + { + needs_drain = true; + break; + } + } + if (needs_drain || gMessageSystem->mPacketRing.getNumBufferedPackets() > 0) + { + gMessageSystem->drainUdpSocket(); + } + lmc.processAcks(); + } + // ...then call display_startup() + display_startup(); +} + void pump_idle_startup_network(void) { + // while there are message to process: + // process one then call display_startup() + S32 num_messages = 0; { LockMessageChecker lmc(gMessageSystem); while (lmc.checkAllMessages(gFrameCount, gServicePump)) { display_startup(); + ++num_messages; } lmc.processAcks(); } + // finally call one last display_startup() display_startup(); } @@ -623,21 +676,6 @@ bool idle_startup() F32 dropPercent = gSavedSettings.getF32("PacketDropPercentage"); msg->mPacketRing.setDropPercentage(dropPercent); - - F32 inBandwidth = gSavedSettings.getF32("InBandwidth"); - F32 outBandwidth = gSavedSettings.getF32("OutBandwidth"); - if (inBandwidth != 0.f) - { - LL_DEBUGS("AppInit") << "Setting packetring incoming bandwidth to " << inBandwidth << LL_ENDL; - msg->mPacketRing.setUseInThrottle(true); - msg->mPacketRing.setInBandwidth(inBandwidth); - } - if (outBandwidth != 0.f) - { - LL_DEBUGS("AppInit") << "Setting packetring outgoing bandwidth to " << outBandwidth << LL_ENDL; - msg->mPacketRing.setUseOutThrottle(true); - msg->mPacketRing.setOutBandwidth(outBandwidth); - } } LL_INFOS("AppInit") << "Message System Initialized." << LL_ENDL; @@ -652,6 +690,15 @@ bool idle_startup() delete gAudiop; gAudiop = NULL; +#ifdef LL_FMODSTUDIO +#if !LL_WINDOWS + if (NULL == getenv("LL_BAD_FMODSTUDIO_DRIVER")) +#endif // !LL_WINDOWS + { + gAudiop = (LLAudioEngine *) new LLAudioEngine_FMODSTUDIO(gSavedSettings.getBOOL("FMODExProfilerEnable")); + } +#endif + #ifdef LL_OPENAL #if !LL_WINDOWS if (NULL == getenv("LL_BAD_OPENAL_DRIVER")) @@ -672,8 +719,19 @@ bool idle_startup() #endif if (gAudiop->init(window_handle, LLAppViewer::instance()->getSecondLifeTitle())) { - LL_INFOS("AppInit") << "Using media plugins to render streaming audio" << LL_ENDL; - gAudiop->setStreamingAudioImpl(new LLStreamingAudio_MediaPlugins()); + if (FALSE == gSavedSettings.getBOOL("UseMediaPluginsForStreamingAudio")) + { + LL_INFOS("AppInit") << "Using default impl to render streaming audio" << LL_ENDL; + gAudiop->setStreamingAudioImpl(gAudiop->createDefaultStreamingAudioImpl()); + } + + // if the audio engine hasn't set up its own preferred handler for streaming audio + // then set up the generic streaming audio implementation which uses media plugins + if (NULL == gAudiop->getStreamingAudioImpl()) + { + LL_INFOS("AppInit") << "Using media plugins to render streaming audio" << LL_ENDL; + gAudiop->setStreamingAudioImpl(new LLStreamingAudio_MediaPlugins()); + } gAudiop->setMuted(true); } @@ -743,7 +801,7 @@ bool idle_startup() LL_DEBUGS("AppInit") << "STATE_BROWSER_INIT" << LL_ENDL; std::string msg = LLTrans::getString("LoginInitializingBrowser"); set_startup_status(0.03f, msg.c_str(), gAgent.mMOTD.c_str()); - display_startup(); + do_startup_frame(); // LLViewerMedia::initBrowser(); LLStartUp::setStartupState( STATE_LOGIN_SHOW ); return false; @@ -808,7 +866,7 @@ bool idle_startup() LL_DEBUGS("AppInit") << "FirstLoginThisInstall off" << LL_ENDL; } } - display_startup(); + do_startup_frame(); LLStartUp::setStartupState( STATE_LOGIN_WAIT ); // Wait for user input } else @@ -839,7 +897,7 @@ bool idle_startup() } LL_DEBUGS("AppInit") << "PeekMessage processed" << LL_ENDL; #endif - display_startup(); + do_startup_frame(); timeout.reset(); return false; } @@ -854,7 +912,7 @@ bool idle_startup() // Don't do anything. Wait for the login view to call the login_callback, // which will push us to the next state. - // display() function will be the one to run display_startup() + // display() function will be the one to run do_startup_frame() // Sleep so we don't spin the CPU ms_sleep(1); return false; @@ -1036,7 +1094,7 @@ bool idle_startup() auth_desc = LLTrans::getString("LoginInProgress"); set_startup_status(progress, auth_desc, auth_message); progress += 0.02f; - display_startup(); + do_startup_frame(); // Setting initial values... LLLoginInstance* login = LLLoginInstance::getInstance(); @@ -1045,6 +1103,7 @@ bool idle_startup() login->setSerialNumber(LLAppViewer::instance()->getSerialNumber()); login->setLastExecEvent(gLastExecEvent); login->setLastExecDuration(gLastExecDuration); + login->setLastAgentSessionId(gLastAgentSessionId); // This call to LLLoginInstance::connect() starts the // authentication process. @@ -1072,7 +1131,7 @@ bool idle_startup() emsg << LLTrans::getString("LoginFailedHeader") << "\n"; if(LLLoginInstance::getInstance()->authFailure()) { - LL_INFOS("LLStartup") << "Login failed, LLLoginInstance::getResponse(): " + LL_INFOS("LLStartUp") << "Login failed, LLLoginInstance::getResponse(): " << LLLoginInstance::getInstance()->getResponse() << LL_ENDL; LLSD response = LLLoginInstance::getInstance()->getResponse(); // Still have error conditions that may need some @@ -1144,7 +1203,7 @@ bool idle_startup() // If optional was skipped this case shouldn't // be reached. - LL_INFOS("LLStartup") << "Forcing a quit due to update." << LL_ENDL; + LL_INFOS("LLStartUp") << "Forcing a quit due to update." << LL_ENDL; LLLoginInstance::getInstance()->disconnect(); LLAppViewer::instance()->forceQuit(); } @@ -1172,7 +1231,7 @@ bool idle_startup() } catch (LLCertException &cert_exception) { - LL_WARNS("LLStartup", "SECAPI") << "Caught " << cert_exception.what() << " certificate expception on getCertificate("<< response["certificate"] << ")" << LL_ENDL; + LL_WARNS("LLStartUp", "SECAPI") << "Caught " << cert_exception.what() << " certificate expception on getCertificate("<< response["certificate"] << ")" << LL_ENDL; LLSD args; args["REASON"] = LLTrans::getString(cert_exception.what()); @@ -1224,7 +1283,7 @@ bool idle_startup() // notificatioin message. LLSD args; args["ERROR_MESSAGE"] = emsg.str(); - LL_INFOS("LLStartup") << "Notification: " << args << LL_ENDL; + LL_INFOS("LLStartUp") << "Notification: " << args << LL_ENDL; LLNotificationsUtil::add("ErrorMessage", args, LLSD(), login_alert_done); } } @@ -1247,7 +1306,7 @@ bool idle_startup() { LLSD args; args["ERROR_MESSAGE"] = emsg.str(); - LL_INFOS("LLStartup") << "Notification: " << args << LL_ENDL; + LL_INFOS("LLStartUp") << "Notification: " << args << LL_ENDL; LLNotificationsUtil::add("ErrorMessage", args, LLSD(), login_alert_done); transition_back_to_login_panel(emsg.str()); show_connect_box = true; @@ -1263,71 +1322,71 @@ bool idle_startup() if (STATE_WORLD_INIT == LLStartUp::getStartupState()) { set_startup_status(0.30f, LLTrans::getString("LoginInitializingWorld"), gAgent.mMOTD); - display_startup(); + do_startup_frame(); // We should have an agent id by this point. llassert(!(gAgentID == LLUUID::null)); // Finish agent initialization. (Requires gSavedSettings, builds camera) gAgent.init(); - display_startup(); + do_startup_frame(); gAgentCamera.init(); - display_startup(); - display_startup(); + do_startup_frame(); + do_startup_frame(); // Since we connected, save off the settings so the user doesn't have to // type the name/password again if we crash. gSavedSettings.saveToFile(gSavedSettings.getString("ClientSettingsFile"), true); LLUIColorTable::instance().saveUserSettings(); - display_startup(); + do_startup_frame(); // // Initialize classes w/graphics stuff. // LLSurface::initClasses(); - display_startup(); + do_startup_frame(); - display_startup(); + do_startup_frame(); LLDrawable::initClass(); - display_startup(); + do_startup_frame(); // init the shader managers LLPostProcess::initClass(); - display_startup(); + do_startup_frame(); LLAvatarAppearance::initClass("avatar_lad.xml","avatar_skeleton.xml"); - display_startup(); + do_startup_frame(); LLViewerObject::initVOClasses(); - display_startup(); + do_startup_frame(); // Initialize all our tools. Must be done after saved settings loaded. // NOTE: This also is where gToolMgr used to be instantiated before being turned into a singleton. LLToolMgr::getInstance()->initTools(); - display_startup(); + do_startup_frame(); // Pre-load floaters, like the world map, that are slow to spawn // due to XML complexity. gViewerWindow->initWorldUI(); - display_startup(); + do_startup_frame(); // This is where we used to initialize gWorldp. Original comment said: // World initialization must be done after above window init // User might have overridden far clip LLWorld::getInstance()->setLandFarClip(gAgentCamera.mDrawDistance); - display_startup(); + do_startup_frame(); // Before we create the first region, we need to set the agent's mOriginGlobal // This is necessary because creating objects before this is set will result in a // bad mPositionAgent cache. gAgent.initOriginGlobal(from_region_handle(gFirstSimHandle)); - display_startup(); + do_startup_frame(); LLWorld::getInstance()->addRegion(gFirstSimHandle, gFirstSim); - display_startup(); + do_startup_frame(); LLViewerRegion *regionp = LLWorld::getInstance()->getRegionFromHandle(gFirstSimHandle); LL_INFOS("AppInit") << "Adding initial simulator " << regionp->getOriginGlobal() << LL_ENDL; @@ -1336,18 +1395,18 @@ bool idle_startup() << gFirstSimSeedCap << LL_ENDL; regionp->setSeedCapability(gFirstSimSeedCap); LL_DEBUGS("AppInit") << "Waiting for seed grant ...." << LL_ENDL; - display_startup(); + do_startup_frame(); // Set agent's initial region to be the one we just created. gAgent.setRegion(regionp); - display_startup(); + do_startup_frame(); // Set agent's initial position, which will be read by LLVOAvatar when the avatar // object is created. I think this must be done after setting the region. JC gAgent.setPositionAgent(agent_start_position_region); - display_startup(); + do_startup_frame(); LLStartUp::initExperiences(); - display_startup(); + do_startup_frame(); // If logging should be enebled, turns it on and loads history from disk // Note: does not happen on init of singleton because preferences can use @@ -1368,7 +1427,7 @@ bool idle_startup() { LLStartUp::multimediaInit(); LLStartUp::setStartupState( STATE_FONT_INIT ); - display_startup(); + do_startup_frame(); return false; } @@ -1377,7 +1436,7 @@ bool idle_startup() { LLStartUp::fontInit(); LLStartUp::setStartupState( STATE_SEED_GRANTED_WAIT ); - display_startup(); + do_startup_frame(); return false; } @@ -1393,7 +1452,7 @@ bool idle_startup() } else if (regionp->capabilitiesError()) { - LL_WARNS("AppInit") << "Failed to get capabilities. Backing up to login screen!" << LL_ENDL; + LL_WARNS("AppInit") << "Failed to get capabilities. Logging out and backing up to login screen!" << LL_ENDL; if (gRememberPassword) { LLNotificationsUtil::add("LoginPacketNeverReceived", LLSD(), LLSD(), login_alert_status); @@ -1402,6 +1461,15 @@ bool idle_startup() { LLNotificationsUtil::add("LoginPacketNeverReceivedNoTP", LLSD(), LLSD(), login_alert_status); } + + // Session was created, don't just hang up on server, send a logout request + LLMessageSystem* msg = gMessageSystem; + msg->newMessageFast(_PREHASH_LogoutRequest); + msg->nextBlockFast(_PREHASH_AgentData); + msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); + msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); + gAgent.sendReliableMessage(); + reset_login(); } else @@ -1409,7 +1477,7 @@ bool idle_startup() U32 num_retries = regionp->getNumSeedCapRetries(); if (num_retries > MAX_SEED_CAP_ATTEMPTS_BEFORE_ABORT) { - LL_WARNS("AppInit") << "Failed to get capabilities. Backing up to login screen!" << LL_ENDL; + LL_WARNS("AppInit") << "Failed to get capabilities. Logging out and backing up to login screen!" << LL_ENDL; if (gRememberPassword) { LLNotificationsUtil::add("LoginPacketNeverReceived", LLSD(), LLSD(), login_alert_status); @@ -1418,6 +1486,15 @@ bool idle_startup() { LLNotificationsUtil::add("LoginPacketNeverReceivedNoTP", LLSD(), LLSD(), login_alert_status); } + + // Session was created, don't just hang up on server, send a logout request + LLMessageSystem* msg = gMessageSystem; + msg->newMessageFast(_PREHASH_LogoutRequest); + msg->nextBlockFast(_PREHASH_AgentData); + msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); + msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); + gAgent.sendReliableMessage(); + reset_login(); } else if (num_retries > 0) @@ -1431,7 +1508,7 @@ bool idle_startup() set_startup_status(0.4f, LLTrans::getString("LoginRequestSeedCapGrant"), gAgent.mMOTD.c_str()); } } - display_startup(); + do_startup_frame(); return false; } @@ -1442,7 +1519,7 @@ bool idle_startup() //--------------------------------------------------------------------- if (STATE_SEED_CAP_GRANTED == LLStartUp::getStartupState()) { - display_startup(); + do_startup_frame(); // These textures are not warrantied to be cached, so needs // to hapen with caps granted @@ -1451,9 +1528,9 @@ bool idle_startup() // will init images, should be done with caps, but before gSky.init() LLEnvironment::getInstance()->initSingleton(); - display_startup(); + do_startup_frame(); update_texture_fetch(); - display_startup(); + do_startup_frame(); if ( gViewerWindow != NULL) { // This isn't the first logon attempt, so show the UI @@ -1461,15 +1538,15 @@ bool idle_startup() } gLoginMenuBarView->setVisible( false ); gLoginMenuBarView->setEnabled( false ); - display_startup(); + do_startup_frame(); // direct logging to the debug console's line buffer LLError::logToFixedBuffer(gDebugView->mDebugConsolep); - display_startup(); + do_startup_frame(); // set initial visibility of debug console gDebugView->mDebugConsolep->setVisible(gSavedSettings.getBOOL("ShowDebugConsole")); - display_startup(); + do_startup_frame(); // // Set message handlers @@ -1478,23 +1555,23 @@ bool idle_startup() // register callbacks for messages. . . do this after initial handshake to make sure that we don't catch any unwanted register_viewer_callbacks(gMessageSystem); - display_startup(); + do_startup_frame(); // Debugging info parameters gMessageSystem->setMaxMessageTime( 0.5f ); // Spam if decoding all msgs takes more than 500 ms - display_startup(); + do_startup_frame(); #ifndef LL_RELEASE_FOR_DOWNLOAD gMessageSystem->setTimeDecodes( true ); // Time the decode of each msg gMessageSystem->setTimeDecodesSpamThreshold( 0.05f ); // Spam if a single msg takes over 50ms to decode #endif - display_startup(); + do_startup_frame(); gXferManager->registerCallbacks(gMessageSystem); - display_startup(); + do_startup_frame(); LLStartUp::initNameCache(); - display_startup(); + do_startup_frame(); // update the voice settings *after* gCacheName initialization // so that we can construct voice UI that relies on the name cache @@ -1502,12 +1579,12 @@ bool idle_startup() { LLVoiceClient::getInstance()->updateSettings(); } - display_startup(); + do_startup_frame(); // create a container's instance for start a controlling conversation windows // by the voice's events LLFloaterIMContainer *im_inst = LLFloaterIMContainer::getInstance(); - if(gAgent.isFirstLogin()) + if(gAgent.isFirstLogin() && im_inst) { im_inst->openFloater(im_inst->getKey()); } @@ -1523,12 +1600,12 @@ bool idle_startup() // register null callbacks for audio until the audio system is initialized gMessageSystem->setHandlerFuncFast(_PREHASH_SoundTrigger, null_message_callback, NULL); gMessageSystem->setHandlerFuncFast(_PREHASH_AttachedSound, null_message_callback, NULL); - display_startup(); + do_startup_frame(); //reset statistics LLViewerStats::instance().resetStats(); - display_startup(); + do_startup_frame(); // // Set up region and surface defaults // @@ -1553,7 +1630,7 @@ bool idle_startup() LLViewerCamera::getInstance()->setAspect(gViewerWindow->getWorldViewAspectRatio()); // Initialize FOV LLViewerCamera::getInstance()->setDefaultFOV(gSavedSettings.getF32("CameraAngle")); - display_startup(); + do_startup_frame(); // Move agent to starting location. The position handed to us by // the space server is in global coordinates, but the agent frame @@ -1564,7 +1641,7 @@ bool idle_startup() gAgent.resetAxes(gAgentStartLookAt); gAgentCamera.stopCameraAnimation(); gAgentCamera.resetCamera(); - display_startup(); + do_startup_frame(); // Initialize global class data needed for surfaces (i.e. textures) LL_DEBUGS("AppInit") << "Initializing sky..." << LL_ENDL; @@ -1575,7 +1652,7 @@ bool idle_startup() LLGLState::checkStates(); - display_startup(); + do_startup_frame(); LL_DEBUGS("AppInit") << "Decoding images..." << LL_ENDL; // For all images pre-loaded into viewer cache, init @@ -1589,12 +1666,12 @@ bool idle_startup() { F32 frac = (F32)i / (F32)DECODE_TIME_SEC; set_startup_status(0.45f + frac*0.1f, LLTrans::getString("LoginDecodingImages"), gAgent.mMOTD); - display_startup(); + do_startup_frame(); gTextureList.decodeAllImages(1.f); } LLStartUp::setStartupState( STATE_WORLD_WAIT ); - display_startup(); + do_startup_frame(); // JC - Do this as late as possible to increase likelihood Purify // will run. @@ -1623,7 +1700,7 @@ bool idle_startup() NULL); timeout.reset(); - display_startup(); + do_startup_frame(); return false; } @@ -1650,7 +1727,7 @@ bool idle_startup() { LL_DEBUGS("AppInit") << "Connecting to region..." << LL_ENDL; set_startup_status(0.60f, LLTrans::getString("LoginConnectingToRegion"), gAgent.mMOTD); - display_startup(); + do_startup_frame(); // register with the message system so it knows we're // expecting this message LLMessageSystem* msg = gMessageSystem; @@ -1664,7 +1741,16 @@ bool idle_startup() gAssetStorage->setUpstream(regionp->getHost()); gCacheName->setUpstream(regionp->getHost()); } - display_startup(); + + // It is entirely possible that we may get the friends list _before_ we have the callbacks registered to process that. + // This will lead to the friends list not being processed properly and online statuses not being updated appropriately at login. + // So, we need to make sure that we have the callbacks registered before we get the friends list. + // This appears to crop up on some systems somewhere between STATE_AGENT_SEND and STATE_INVENTORY_SEND. It's happened to me a few times now. + // -Geenz 2025-03-12 + LL_INFOS() << " AvatarTracker" << LL_ENDL; + LLAvatarTracker::instance().registerCallbacks(gMessageSystem); + + do_startup_frame(); // Create login effect // But not on first login, because you can't see your avatar then @@ -1679,7 +1765,7 @@ bool idle_startup() LLStartUp::setStartupState( STATE_AGENT_WAIT ); // Go to STATE_AGENT_WAIT timeout.reset(); - display_startup(); + do_startup_frame(); return false; } @@ -1688,39 +1774,17 @@ bool idle_startup() //--------------------------------------------------------------------- if (STATE_AGENT_WAIT == LLStartUp::getStartupState()) { - { - LockMessageChecker lmc(gMessageSystem); - while (lmc.checkAllMessages(gFrameCount, gServicePump)) - { - if (gAgentMovementCompleted) - { - // Sometimes we have more than one message in the - // queue. break out of this loop and continue - // processing. If we don't, then this could skip one - // or more login steps. - break; - } - else - { - LL_DEBUGS("AppInit") << "Awaiting AvatarInitComplete, got " - << gMessageSystem->getMessageName() << LL_ENDL; - } - display_startup(); - } - lmc.processAcks(); - } - - display_startup(); + do_startup_frame(); if (gAgentMovementCompleted) { LLStartUp::setStartupState( STATE_INVENTORY_SEND ); } - display_startup(); + do_startup_frame(); if (!gAgentMovementCompleted && timeout.getElapsedTimeF32() > STATE_AGENT_WAIT_TIMEOUT) { - LL_WARNS("AppInit") << "Backing up to login screen!" << LL_ENDL; + LL_WARNS("AppInit") << "Timeout on agent movement. Sending logout and backing up to login screen!" << LL_ENDL; if (gRememberPassword) { LLNotificationsUtil::add("LoginPacketNeverReceived", LLSD(), LLSD(), login_alert_status); @@ -1729,6 +1793,15 @@ bool idle_startup() { LLNotificationsUtil::add("LoginPacketNeverReceivedNoTP", LLSD(), LLSD(), login_alert_status); } + + // Session was created, don't just hang up on server, send a logout request + LLMessageSystem* msg = gMessageSystem; + msg->newMessageFast(_PREHASH_LogoutRequest); + msg->nextBlockFast(_PREHASH_AgentData); + msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); + msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); + gAgent.sendReliableMessage(); + reset_login(); } return false; @@ -1740,7 +1813,7 @@ bool idle_startup() if (STATE_INVENTORY_SEND == LLStartUp::getStartupState()) { LL_PROFILE_ZONE_NAMED("State inventory send") - display_startup(); + do_startup_frame(); // request mute list LL_INFOS() << "Requesting Mute List" << LL_ENDL; @@ -1750,12 +1823,12 @@ bool idle_startup() LL_INFOS() << "Requesting Money Balance" << LL_ENDL; LLStatusBar::sendMoneyBalanceRequest(); - display_startup(); + do_startup_frame(); // Inform simulator of our language preference LLAgentLanguage::update(); - display_startup(); + do_startup_frame(); // unpack thin inventory LLSD response = LLLoginInstance::getInstance()->getResponse(); //bool dump_buffer = false; @@ -1770,7 +1843,7 @@ bool idle_startup() gInventory.setLibraryRootFolderID(id.asUUID()); } } - display_startup(); + do_startup_frame(); LLSD inv_lib_owner = response["inventory-lib-owner"]; if(inv_lib_owner.isDefined()) @@ -1782,9 +1855,9 @@ bool idle_startup() gInventory.setLibraryOwnerID(LLUUID(id.asUUID())); } } - display_startup(); + do_startup_frame(); LLStartUp::setStartupState(STATE_INVENTORY_SKEL); - display_startup(); + do_startup_frame(); return false; } @@ -1803,7 +1876,7 @@ bool idle_startup() LL_WARNS("AppInit") << "Problem loading inventory-skel-lib" << LL_ENDL; } } - display_startup(); + do_startup_frame(); LLSD inv_skeleton = response["inventory-skeleton"]; if (inv_skeleton.isDefined()) @@ -1814,9 +1887,9 @@ bool idle_startup() LL_WARNS("AppInit") << "Problem loading inventory-skel-targets" << LL_ENDL; } } - display_startup(); + do_startup_frame(); LLStartUp::setStartupState(STATE_INVENTORY_SEND2); - display_startup(); + do_startup_frame(); return false; } @@ -1862,7 +1935,7 @@ bool idle_startup() list[agent_id] = new LLRelationship(given_rights, has_rights, false); } LLAvatarTracker::instance().addBuddyList(list); - display_startup(); + do_startup_frame(); } bool show_hud = false; @@ -1890,7 +1963,7 @@ bool idle_startup() //} } } - display_startup(); + do_startup_frame(); // Either we want to show tutorial because this is the first login // to a Linden Help Island or the user quit with the tutorial @@ -1899,21 +1972,21 @@ bool idle_startup() { LLFloaterReg::showInstance("hud", LLSD(), false); } - display_startup(); + do_startup_frame(); LLSD event_notifications = response["event_notifications"]; if(event_notifications.isDefined()) { gEventNotifier.load(event_notifications); } - display_startup(); + do_startup_frame(); LLSD classified_categories = response["classified_categories"]; if(classified_categories.isDefined()) { LLClassifiedInfo::loadCategories(classified_categories); } - display_startup(); + do_startup_frame(); // This method MUST be called before gInventory.findCategoryUUIDForType because of // gInventory.mIsAgentInvUsable is set to true in the gInventory.buildParentChildMap. @@ -1932,7 +2005,7 @@ bool idle_startup() LLInventoryModelBackgroundFetch::instance().start(); gInventory.createCommonSystemCategories(); LLStartUp::setStartupState(STATE_INVENTORY_CALLBACKS ); - display_startup(); + do_startup_frame(); return false; } @@ -1944,7 +2017,7 @@ bool idle_startup() { if (!LLInventoryModel::isSysFoldersReady()) { - display_startup(); + do_startup_frame(); return false; } @@ -1969,29 +2042,27 @@ bool idle_startup() gInventory.addChangedMask(LLInventoryObserver::ALL, LLUUID::null); gInventory.notifyObservers(); - display_startup(); + do_startup_frame(); // set up callbacks LL_INFOS() << "Registering Callbacks" << LL_ENDL; LLMessageSystem* msg = gMessageSystem; LL_INFOS() << " Inventory" << LL_ENDL; LLInventoryModel::registerCallbacks(msg); - LL_INFOS() << " AvatarTracker" << LL_ENDL; - LLAvatarTracker::instance().registerCallbacks(msg); LL_INFOS() << " Landmark" << LL_ENDL; LLLandmark::registerCallbacks(msg); - display_startup(); + do_startup_frame(); // request all group information LL_INFOS() << "Requesting Agent Data" << LL_ENDL; gAgent.sendAgentDataUpdateRequest(); - display_startup(); + do_startup_frame(); // Create the inventory views LL_INFOS() << "Creating Inventory Views" << LL_ENDL; LLFloaterReg::getInstance("inventory"); - display_startup(); + do_startup_frame(); LLStartUp::setStartupState( STATE_MISC ); - display_startup(); + do_startup_frame(); return false; } @@ -2041,7 +2112,7 @@ bool idle_startup() gSavedSettings.setBOOL("ShowStartLocation", true); } - display_startup(); + do_startup_frame(); // Load stored local environment if needed. LLEnvironment::instance().loadFromSettings(); @@ -2049,7 +2120,7 @@ bool idle_startup() // *TODO : Uncomment that line once the whole grid migrated to SLM and suppress it from LLAgent::handleTeleportFinished() (llagent.cpp) //check_merchant_status(); - display_startup(); + do_startup_frame(); if (gSavedSettings.getBOOL("HelpFloaterOpen")) { @@ -2057,7 +2128,7 @@ bool idle_startup() LLViewerHelp::instance().showTopic(""); } - display_startup(); + do_startup_frame(); // We're successfully logged in. gSavedSettings.setBOOL("FirstLoginThisInstall", false); @@ -2066,12 +2137,12 @@ bool idle_startup() LLFloaterGridStatus::getInstance()->startGridStatusTimer(); - display_startup(); + do_startup_frame(); - display_startup(); + do_startup_frame(); // JC: Initializing audio requests many sounds for download. init_audio(); - display_startup(); + do_startup_frame(); // JC: Initialize "active" gestures. This may also trigger // many gesture downloads, if this is the user's first @@ -2109,7 +2180,7 @@ bool idle_startup() LLGestureMgr::instance().startFetch(); } gDisplaySwapBuffers = true; - display_startup(); + do_startup_frame(); LLMessageSystem* msg = gMessageSystem; msg->setHandlerFuncFast(_PREHASH_SoundTrigger, process_sound_trigger); @@ -2187,10 +2258,10 @@ bool idle_startup() } } - display_startup(); + do_startup_frame(); //DEV-17797. get null folder. Any items found here moved to Lost and Found LLInventoryModelBackgroundFetch::instance().findLostItems(); - display_startup(); + do_startup_frame(); LLStartUp::setStartupState( STATE_PRECACHE ); timeout.reset(); @@ -2199,7 +2270,7 @@ bool idle_startup() if (STATE_PRECACHE == LLStartUp::getStartupState()) { - display_startup(); + do_startup_frame(); F32 timeout_frac = timeout.getElapsedTimeF32()/PRECACHING_DELAY; // We now have an inventory skeleton, so if this is a user's first @@ -2225,7 +2296,7 @@ bool idle_startup() callAfterCOFFetch(set_flags_and_update_appearance); } - display_startup(); + do_startup_frame(); // wait precache-delay and for agent's avatar or a lot longer. if ((timeout_frac > 1.f) && isAgentAvatarValid()) @@ -2250,7 +2321,7 @@ bool idle_startup() set_startup_status(0.60f + 0.30f * timeout_frac, LLTrans::getString("LoginPrecaching"), gAgent.mMOTD.c_str()); - display_startup(); + do_startup_frame(); } return true; @@ -2278,7 +2349,7 @@ bool idle_startup() LLStartUp::setStartupState( STATE_CLEANUP ); } - display_startup(); + do_startup_frame(); if (gAgent.isOutfitChosen() && (wearables_time > MAX_WEARABLES_TIME)) { @@ -2319,7 +2390,7 @@ bool idle_startup() if (STATE_CLEANUP == LLStartUp::getStartupState()) { set_startup_status(1.0, "", ""); - display_startup(); + do_startup_frame(); if (!mBenefitsSuccessfullyInit) { @@ -2340,7 +2411,7 @@ bool idle_startup() //gViewerWindow->revealIntroPanel(); gViewerWindow->setStartupComplete(); gViewerWindow->setProgressCancelButtonVisible(false); - display_startup(); + do_startup_frame(); // We're not away from keyboard, even though login might have taken // a while. JC @@ -2372,7 +2443,7 @@ bool idle_startup() // LLUserAuth::getInstance()->reset(); LLStartUp::setStartupState( STATE_STARTED ); - display_startup(); + do_startup_frame(); // Unmute audio if desired and setup volumes. // This is a not-uncommon crash site, so surround it with @@ -2388,7 +2459,7 @@ bool idle_startup() LLAgentPicksInfo::getInstance()->requestNumberOfPicks(); - display_startup(); + do_startup_frame(); llassert(LLPathfindingManager::getInstance() != NULL); LLPathfindingManager::getInstance()->initSystem(); @@ -2765,6 +2836,14 @@ void register_viewer_callbacks(LLMessageSystem* msg) msg->setHandlerFunc("AvatarPickerReply", LLFloaterAvatarPicker::processAvatarPickerReply); + // directory search + msg->setHandlerFuncFast(_PREHASH_DirPeopleReply, FSPanelSearchPeople::processSearchReply); + msg->setHandlerFuncFast(_PREHASH_DirPlacesReply, FSPanelSearchPlaces::processSearchReply); + msg->setHandlerFuncFast(_PREHASH_DirGroupsReply, FSPanelSearchGroups::processSearchReply); + msg->setHandlerFuncFast(_PREHASH_DirEventsReply, FSPanelSearchEvents::processSearchReply); + msg->setHandlerFuncFast(_PREHASH_DirLandReply, FSPanelSearchLand::processSearchReply); + msg->setHandlerFuncFast(_PREHASH_DirClassifiedReply, FSPanelSearchClassifieds::processSearchReply); + msg->setHandlerFunc("MapBlockReply", LLWorldMapMessage::processMapBlockReply); msg->setHandlerFunc("MapItemReply", LLWorldMapMessage::processMapItemReply); msg->setHandlerFunc("EventInfoReply", LLEventNotifier::processEventInfoReply); @@ -2993,9 +3072,7 @@ std::string LLStartUp::startupStateToString(EStartupState state) // static void LLStartUp::setStartupState( EStartupState state ) { - LL_INFOS("AppInit") << "Startup state changing from " << - getStartupStateString() << " to " << - startupStateToString(state) << LL_ENDL; + LL_INFOS("AppInit") << getStartupStateString() << " --> " << startupStateToString(state) << LL_ENDL; getPhases().stopPhase(getStartupStateString()); gStartupState = state; @@ -3059,7 +3136,7 @@ void LLStartUp::multimediaInit() LL_DEBUGS("AppInit") << "Initializing Multimedia...." << LL_ENDL; std::string msg = LLTrans::getString("LoginInitializingMultimedia"); set_startup_status(0.42f, msg.c_str(), gAgent.mMOTD.c_str()); - display_startup(); + do_startup_frame(); } void LLStartUp::fontInit() @@ -3067,7 +3144,7 @@ void LLStartUp::fontInit() LL_DEBUGS("AppInit") << "Initializing fonts...." << LL_ENDL; std::string msg = LLTrans::getString("LoginInitializingFonts"); set_startup_status(0.45f, msg.c_str(), gAgent.mMOTD.c_str()); - display_startup(); + do_startup_frame(); LLFontGL::loadDefaultFonts(); } @@ -3529,6 +3606,7 @@ bool process_login_success_response() text = response["session_id"].asString(); if(!text.empty()) gAgentSessionID.set(text); gDebugInfo["SessionID"] = text; + LLAppViewer::instance()->recordSessionToMarker(); // Session id needed for parcel info request in LLUrlEntryParcel // to resolve parcel name. @@ -3763,14 +3841,14 @@ bool process_login_success_response() { // We got an answer from the grid -> use that for map for the current session gSavedSettings.setString("CurrentMapServerURL", map_server_url); - LL_INFOS("LLStartup") << "map-server-url : we got an answer from the grid : " << map_server_url << LL_ENDL; + LL_INFOS("LLStartUp") << "map-server-url : we got an answer from the grid : " << map_server_url << LL_ENDL; } else { // No answer from the grid -> use the default setting for current session map_server_url = gSavedSettings.getString("MapServerURL"); gSavedSettings.setString("CurrentMapServerURL", map_server_url); - LL_INFOS("LLStartup") << "map-server-url : no map-server-url answer, we use the default setting for the map : " << map_server_url << LL_ENDL; + LL_INFOS("LLStartUp") << "map-server-url : no map-server-url answer, we use the default setting for the map : " << map_server_url << LL_ENDL; } // Default male and female avatars allowing the user to choose their avatar on first login. diff --git a/indra/newview/llstatusbar.cpp b/indra/newview/llstatusbar.cpp index ecbbc4b2c5..1bab602364 100644 --- a/indra/newview/llstatusbar.cpp +++ b/indra/newview/llstatusbar.cpp @@ -109,6 +109,7 @@ static void onClickVolume(void*); LLStatusBar::LLStatusBar(const LLRect& rect) : LLPanel(), mTextTime(NULL), + mTextFps(NULL), mSGBandwidth(NULL), mSGPacketLoss(NULL), mBtnVolume(NULL), @@ -127,6 +128,7 @@ LLStatusBar::LLStatusBar(const LLRect& rect) mBalanceTimer = new LLFrameTimer(); mHealthTimer = new LLFrameTimer(); + mFpsUpdateTimer = new LLFrameTimer(); buildFromFile("panel_status_bar.xml"); } @@ -165,6 +167,9 @@ bool LLStatusBar::postBuild() mTextTime = getChild<LLTextBox>("TimeText" ); + mTextFps = getChild<LLButton>("FpsText"); + mTextFps->setClickedCallback( &LLStatusBar::onClickFps, this ); + getChild<LLUICtrl>("buyL")->setCommitCallback( boost::bind(&LLStatusBar::onClickBuyCurrency, this)); @@ -297,6 +302,16 @@ void LLStatusBar::refresh() //mSGBandwidth->setThreshold(2, bwtotal); } + if(mFpsUpdateTimer->getElapsedTimeF32() >= 1.0f) + { + mFpsUpdateTimer->reset(); + + S32 fps = (S32) llround(LLTrace::get_frame_recording().getPeriodMedianPerSec(LLStatViewer::FPS, 50)); + std::string fpsStr = std::to_string(fps); + //mTextFps->setText(fpsStr); + mTextFps->setLabel(fpsStr); + } + // update clock every 10 seconds if(mClockUpdateTimer.getElapsedTimeF32() > 10.f) { @@ -637,6 +652,12 @@ void LLStatusBar::onClickMediaToggle(void* data) LLViewerMedia::getInstance()->setAllMediaPaused(pause); } +//static +void LLStatusBar::onClickFps(void* data) +{ + LLFloaterReg::toggleInstance("mpv_performance"); +} + bool can_afford_transaction(S32 cost) { return((cost <= 0)||((gStatusBar) && (gStatusBar->getBalance() >=cost))); diff --git a/indra/newview/llstatusbar.h b/indra/newview/llstatusbar.h index 4c9d3e0c08..7e1ecf08ca 100644 --- a/indra/newview/llstatusbar.h +++ b/indra/newview/llstatusbar.h @@ -109,6 +109,8 @@ private: static void onClickMediaToggle(void* data); static void onClickBalance(void* data); + static void onClickFps(void* data); + LLSearchEditor *mFilterEdit; LLPanel *mSearchPanel; void onUpdateFilterTerm(); @@ -121,6 +123,7 @@ private: private: LLTextBox *mTextTime; + LLButton *mTextFps; LLStatGraph *mSGBandwidth; LLStatGraph *mSGPacketLoss; @@ -131,6 +134,7 @@ private: LLTextBox *mBoxBalance; LLButton *mMediaToggle; LLFrameTimer mClockUpdateTimer; + LLFrameTimer *mFpsUpdateTimer; S32 mBalance; S32 mHealth; diff --git a/indra/newview/lltexturefetch.cpp b/indra/newview/lltexturefetch.cpp index bac0c736b1..087761cbd0 100644 --- a/indra/newview/lltexturefetch.cpp +++ b/indra/newview/lltexturefetch.cpp @@ -29,6 +29,7 @@ #include <iostream> #include <map> #include <algorithm> +#include <atomic> #include "lltexturefetch.h" @@ -2843,7 +2844,7 @@ bool LLTextureFetch::getRequestFinished(const LLUUID& id, S32& discard_level, S3 bool LLTextureFetch::updateRequestPriority(const LLUUID& id, F32 priority) { LL_PROFILE_ZONE_SCOPED; - mRequestQueue.tryPost([=]() + mRequestQueue.tryPost([=, this]() { LLTextureFetchWorker* worker = getWorker(id); if (worker) @@ -3571,29 +3572,30 @@ TFReqSendMetrics::doWork(LLTextureFetch * fetcher) //if (! gViewerAssetStatsThread1) // return true; - static volatile bool reporting_started(false); - static volatile S32 report_sequence(0); + static std::atomic<bool> reporting_started(false); + static std::atomic<S32> report_sequence(0); // In mStatsSD, we have a copy we own of the LLSD representation // of the asset stats. Add some additional fields and ship it off. static const S32 metrics_data_version = 2; - bool initial_report = !reporting_started; + bool initial_report = !reporting_started.load(); mStatsSD["session_id"] = mSessionID; mStatsSD["agent_id"] = mAgentID; mStatsSD["message"] = "ViewerAssetMetrics"; - mStatsSD["sequence"] = report_sequence; + mStatsSD["sequence"] = report_sequence.load(); mStatsSD["initial"] = initial_report; mStatsSD["version"] = metrics_data_version; mStatsSD["break"] = static_cast<bool>(LLTextureFetch::svMetricsDataBreak); // Update sequence number - if (S32_MAX == ++report_sequence) + if (S32_MAX == report_sequence.fetch_add(1)) { - report_sequence = 0; + report_sequence.store(0); } - reporting_started = true; + + reporting_started.store(true); // Limit the size of the stats report if necessary. diff --git a/indra/newview/lltextureview.cpp b/indra/newview/lltextureview.cpp index bda53f66eb..8560a01c4b 100644 --- a/indra/newview/lltextureview.cpp +++ b/indra/newview/lltextureview.cpp @@ -559,10 +559,12 @@ void LLGLTexMemBar::draw() gGL.color4f(0.f, 0.f, 0.f, 0.25f); gl_rect_2d(-10, getRect().getHeight() + line_height*2 + 1, getRect().getWidth()+2, getRect().getHeight()+2); - text = llformat("Est. Free: %d MB Sys Free: %d MB FBO: %d MB Bias: %.2f Cache: %.1f/%.1f MB", + text = llformat("Est. Free: %d MB Sys Free: %d MB FBO: %d MB Probe#: %d Probe Mem: %d MB Bias: %.2f Cache: %.1f/%.1f MB", (S32)LLViewerTexture::sFreeVRAMMegabytes, LLMemory::getAvailableMemKB()/1024, LLRenderTarget::sBytesAllocated/(1024*1024), + gPipeline.mReflectionMapManager.probeCount(), + gPipeline.mReflectionMapManager.probeMemory(), discard_bias, cache_usage, cache_max_usage); @@ -642,7 +644,7 @@ void LLGLTexMemBar::draw() text = llformat("Mesh: Reqs(Tot/Htp/Big): %u/%u/%u Rtr/Err: %u/%u Cread/Cwrite: %u/%u Low/At/High: %d/%d/%d", LLMeshRepository::sMeshRequestCount, LLMeshRepository::sHTTPRequestCount, LLMeshRepository::sHTTPLargeRequestCount, LLMeshRepository::sHTTPRetryCount, LLMeshRepository::sHTTPErrorCount, - LLMeshRepository::sCacheReads, LLMeshRepository::sCacheWrites, + (U32)LLMeshRepository::sCacheReads, (U32)LLMeshRepository::sCacheWrites, LLMeshRepoThread::sRequestLowWater, LLMeshRepoThread::sRequestWaterLevel, LLMeshRepoThread::sRequestHighWater); LLFontGL::getFontMonospace()->renderUTF8(text, 0, 0, v_offset + line_height*2, text_color, LLFontGL::LEFT, LLFontGL::TOP); diff --git a/indra/newview/lltoast.cpp b/indra/newview/lltoast.cpp index 84503e66a5..84854a79d4 100644 --- a/indra/newview/lltoast.cpp +++ b/indra/newview/lltoast.cpp @@ -436,6 +436,14 @@ void LLToast::setVisible(bool show) void LLToast::updateHoveredState() { + if (!mWrapperPanel) + { + // Shouldn't be happening. + // mWrapperPanel should have been inited in the constructor + // This needs to be figured out and fixed + llassert(false); + return; + } S32 x, y; LLUI::getInstance()->getMousePositionScreen(&x, &y); diff --git a/indra/newview/lltoastalertpanel.h b/indra/newview/lltoastalertpanel.h index 167a7b2363..c2cdd775f1 100644 --- a/indra/newview/lltoastalertpanel.h +++ b/indra/newview/lltoastalertpanel.h @@ -82,14 +82,10 @@ private: struct ButtonData { - ButtonData() - : mWidth(0) - {} - - LLButton* mButton; + LLButton* mButton = nullptr; std::string mURL; - U32 mURLExternal; - S32 mWidth; + U32 mURLExternal = 0; + S32 mWidth = 0; }; std::vector<ButtonData> mButtonData; diff --git a/indra/newview/lltoolbrush.cpp b/indra/newview/lltoolbrush.cpp index 2fe81df4fb..cf7b123fa7 100644 --- a/indra/newview/lltoolbrush.cpp +++ b/indra/newview/lltoolbrush.cpp @@ -447,7 +447,10 @@ void LLToolBrushLand::handleSelect() { gEditMenuHandler = this; - gFloaterTools->setStatusText("modifyland"); + if (gFloaterTools) + { + gFloaterTools->setStatusText("modifyland"); + } // if (!mBrushSelected) { mBrushSelected = true; diff --git a/indra/newview/lltooldraganddrop.cpp b/indra/newview/lltooldraganddrop.cpp index 4efa289141..9d6f44c096 100644 --- a/indra/newview/lltooldraganddrop.cpp +++ b/indra/newview/lltooldraganddrop.cpp @@ -574,12 +574,13 @@ bool LLToolDragAndDrop::handleKey(KEY key, MASK mask) bool LLToolDragAndDrop::handleToolTip(S32 x, S32 y, MASK mask) { + const F32 DRAG_N_DROP_TOOLTIP_DELAY = 0.1f; if (!mToolTipMsg.empty()) { LLToolTipMgr::instance().unblockToolTips(); LLToolTipMgr::instance().show(LLToolTip::Params() .message(mToolTipMsg) - .delay_time(gSavedSettings.getF32( "DragAndDropToolTipDelay" ))); + .delay_time(DRAG_N_DROP_TOOLTIP_DELAY)); return true; } return false; @@ -1253,6 +1254,7 @@ void LLToolDragAndDrop::dropMaterial(LLViewerObject* hit_obj, // If user dropped a material onto face it implies // applying texture now without cancel, save to selection if (nodep + && gFloaterTools && gFloaterTools->getVisible() && nodep->mSavedGLTFMaterialIds.size() > hit_face) { @@ -1429,10 +1431,10 @@ void LLToolDragAndDrop::dropTexture(LLViewerObject* hit_obj, // If user dropped a texture onto face it implies // applying texture now without cancel, save to selection - LLPanelFace* panel_face = gFloaterTools->getPanelFace(); + LLPanelFace* panel_face = gFloaterTools ? gFloaterTools->getPanelFace() : nullptr; if (nodep - && gFloaterTools->getVisible() && panel_face + && gFloaterTools->getVisible() && panel_face->getTextureDropChannel() == 0 /*texture*/ && nodep->mSavedTextures.size() > hit_face) { @@ -1488,8 +1490,8 @@ void LLToolDragAndDrop::dropTextureOneFace(LLViewerObject* hit_obj, if (allow_adding_to_override) { LLGLTFMaterial::TextureInfo drop_channel = LLGLTFMaterial::GLTF_TEXTURE_INFO_BASE_COLOR; - LLPanelFace* panel_face = gFloaterTools->getPanelFace(); - if (gFloaterTools->getVisible() && panel_face) + LLPanelFace* panel_face = gFloaterTools ? gFloaterTools->getPanelFace() : nullptr; + if (panel_face && gFloaterTools->getVisible()) { drop_channel = panel_face->getPBRDropChannel(); } @@ -1514,9 +1516,9 @@ void LLToolDragAndDrop::dropTextureOneFace(LLViewerObject* hit_obj, LLTextureEntry* tep = hit_obj->getTE(hit_face); - LLPanelFace* panel_face = gFloaterTools->getPanelFace(); + LLPanelFace* panel_face = gFloaterTools ? gFloaterTools->getPanelFace() : nullptr; - if (gFloaterTools->getVisible() && panel_face) + if (panel_face && gFloaterTools->getVisible()) { tex_channel = (tex_channel > -1) ? tex_channel : panel_face->getTextureDropChannel(); switch (tex_channel) @@ -1611,7 +1613,10 @@ void LLToolDragAndDrop::dropScript(LLViewerObject* hit_obj, } } hit_obj->saveScript(new_script, active, true); - gFloaterTools->dirty(); + if (gFloaterTools) + { + gFloaterTools->dirty(); + } // VEFFECT: SetScript LLHUDEffectSpiral *effectp = (LLHUDEffectSpiral *)LLHUDManager::getInstance()->createViewerEffect(LLHUDObject::LL_HUD_EFFECT_BEAM, true); @@ -1844,7 +1849,10 @@ void LLToolDragAndDrop::dropInventory(LLViewerObject* hit_obj, effectp->setTargetObject(hit_obj); effectp->setDuration(LL_HUD_DUR_SHORT); effectp->setColor(LLColor4U(gAgent.getEffectColor())); - gFloaterTools->dirty(); + if (gFloaterTools) + { + gFloaterTools->dirty(); + } } // accessor that looks at permissions, copyability, and names of diff --git a/indra/newview/lltoolplacer.cpp b/indra/newview/lltoolplacer.cpp index b15bb5efd5..0d141d7545 100644 --- a/indra/newview/lltoolplacer.cpp +++ b/indra/newview/lltoolplacer.cpp @@ -527,7 +527,10 @@ bool LLToolPlacer::handleHover(S32 x, S32 y, MASK mask) void LLToolPlacer::handleSelect() { - gFloaterTools->setStatusText("place"); + if (gFloaterTools) + { + gFloaterTools->setStatusText("place"); + } } void LLToolPlacer::handleDeselect() diff --git a/indra/newview/lltoolselectland.cpp b/indra/newview/lltoolselectland.cpp index 88553c7557..331581fd88 100644 --- a/indra/newview/lltoolselectland.cpp +++ b/indra/newview/lltoolselectland.cpp @@ -207,7 +207,10 @@ void LLToolSelectLand::render() void LLToolSelectLand::handleSelect() { - gFloaterTools->setStatusText("selectland"); + if (gFloaterTools) + { + gFloaterTools->setStatusText("selectland"); + } } diff --git a/indra/newview/lltracker.cpp b/indra/newview/lltracker.cpp index d4d3e71b46..b1bee0f2c7 100644 --- a/indra/newview/lltracker.cpp +++ b/indra/newview/lltracker.cpp @@ -493,7 +493,7 @@ void draw_shockwave(F32 center_z, F32 t, S32 steps, LLColor4 color) void LLTracker::drawBeacon(LLVector3 pos_agent, std::string direction, LLColor4 fogged_color, F32 dist) { const F32 MAX_HEIGHT = 5020.f; - const U32 BEACON_ROWS = 256; + const U32 BEACON_ROWS = 128; U32 nRows; F32 height; @@ -520,8 +520,6 @@ void LLTracker::drawBeacon(LLVector3 pos_agent, std::string direction, LLColor4 if(nRows<2) nRows=2; rowHeight = height / nRows; - gGL.color4fv(fogged_color.mV); - LLVector3 x_axis = LLViewerCamera::getInstance()->getLeftAxis(); F32 t = gRenderStartTime.getElapsedTimeF32(); @@ -536,6 +534,8 @@ void LLTracker::drawBeacon(LLVector3 pos_agent, std::string direction, LLColor4 bool tracking_avatar = getTrackingStatus() == TRACKING_AVATAR; + gGL.color4fv(fogged_color.mV); + gGL.begin(LLRender::TRIANGLES); for (U32 i = 0; i < nRows; i++) diff --git a/indra/newview/llversioninfo.cpp b/indra/newview/llversioninfo.cpp index 4e8320b72a..b7ea95c694 100644 --- a/indra/newview/llversioninfo.cpp +++ b/indra/newview/llversioninfo.cpp @@ -158,9 +158,9 @@ LLVersionInfo::ViewerMaturity LLVersionInfo::getViewerMaturity() const else { LL_WARNS() << "Channel '" << channel - << "' does not follow naming convention, assuming Test" + << "' does not follow naming convention, assuming Release" << LL_ENDL; - maturity = TEST_VIEWER; + maturity = RELEASE_VIEWER; } return maturity; } diff --git a/indra/newview/llviewerassetstorage.cpp b/indra/newview/llviewerassetstorage.cpp index 5ab9f76e47..255cfc998a 100644 --- a/indra/newview/llviewerassetstorage.cpp +++ b/indra/newview/llviewerassetstorage.cpp @@ -402,10 +402,10 @@ void LLViewerAssetStorage::queueRequestHttp( manager->enqueueCoprocedure( VIEWER_ASSET_STORAGE_CORO_POOL, "LLViewerAssetStorage::assetRequestCoro", - [this, req, uuid, atype, callback, user_data] + [this, uuid, atype, callback, user_data] (LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t&, const LLUUID&) { - assetRequestCoro(req, uuid, atype, callback, user_data); + assetRequestCoro(uuid, atype, callback, user_data); }); } } @@ -440,7 +440,6 @@ struct LLScopedIncrement }; void LLViewerAssetStorage::assetRequestCoro( - LLViewerAssetRequest *req, const LLUUID uuid, LLAssetType::EType atype, LLGetAssetCallback callback, @@ -464,7 +463,7 @@ void LLViewerAssetStorage::assetRequestCoro( LL_WARNS_ONCE("ViewerAsset") << "Asset request fails: no region set" << LL_ENDL; result_code = LL_ERR_ASSET_REQUEST_FAILED; ext_status = LLExtStat::NONE; - removeAndCallbackPendingDownloads(uuid, atype, uuid, atype, result_code, ext_status); + removeAndCallbackPendingDownloads(uuid, atype, uuid, atype, result_code, ext_status, 0); return; } else if (!gAgent.getRegion()->capabilitiesReceived()) @@ -495,7 +494,7 @@ void LLViewerAssetStorage::assetRequestCoro( LL_WARNS_ONCE("ViewerAsset") << "asset request fails: caps received but no viewer asset cap found" << LL_ENDL; result_code = LL_ERR_ASSET_REQUEST_FAILED; ext_status = LLExtStat::NONE; - removeAndCallbackPendingDownloads(uuid, atype, uuid, atype, result_code, ext_status); + removeAndCallbackPendingDownloads(uuid, atype, uuid, atype, result_code, ext_status, 0); return; } std::string url = getAssetURL(mViewerAssetUrl, uuid,atype); @@ -517,6 +516,7 @@ void LLViewerAssetStorage::assetRequestCoro( mCountCompleted++; + S32 bytes_fetched = 0; LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS]; LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults); if (!status) @@ -554,7 +554,7 @@ void LLViewerAssetStorage::assetRequestCoro( LLUUID temp_id; temp_id.generate(); LLFileSystem vf(temp_id, atype, LLFileSystem::WRITE); - req->mBytesFetched = size; + bytes_fetched = size; if (!vf.write(raw.data(),size)) { // TODO asset-http: handle error @@ -583,7 +583,7 @@ void LLViewerAssetStorage::assetRequestCoro( } // Clean up pending downloads and trigger callbacks - removeAndCallbackPendingDownloads(uuid, atype, uuid, atype, result_code, ext_status); + removeAndCallbackPendingDownloads(uuid, atype, uuid, atype, result_code, ext_status, bytes_fetched); } std::string LLViewerAssetStorage::getAssetURL(const std::string& cap_url, const LLUUID& uuid, LLAssetType::EType atype) diff --git a/indra/newview/llviewerassetstorage.h b/indra/newview/llviewerassetstorage.h index fdb8af7457..42dd9d1dd8 100644 --- a/indra/newview/llviewerassetstorage.h +++ b/indra/newview/llviewerassetstorage.h @@ -82,8 +82,7 @@ protected: void capsRecvForRegion(const LLUUID& region_id, std::string pumpname); - void assetRequestCoro(LLViewerAssetRequest *req, - const LLUUID uuid, + void assetRequestCoro(const LLUUID uuid, LLAssetType::EType atype, LLGetAssetCallback callback, void *user_data); diff --git a/indra/newview/llviewercamera.cpp b/indra/newview/llviewercamera.cpp index aa43b2dbad..6cf99b68b2 100644 --- a/indra/newview/llviewercamera.cpp +++ b/indra/newview/llviewercamera.cpp @@ -420,7 +420,7 @@ bool LLViewerCamera::projectPosAgentToScreen(const LLVector3 &pos_agent, LLCoord LLRect world_view_rect = gViewerWindow->getWorldViewRectRaw(); glm::ivec4 viewport(world_view_rect.mLeft, world_view_rect.mBottom, world_view_rect.getWidth(), world_view_rect.getHeight()); - glm::vec3 win_coord = glm::project(glm::make_vec3(pos_agent.mV), get_current_modelview(), get_current_projection(), viewport); + glm::vec3 win_coord = glm::project(glm::vec3(pos_agent), get_current_modelview(), get_current_projection(), viewport); { // convert screen coordinates to virtual UI coordinates @@ -502,6 +502,7 @@ bool LLViewerCamera::projectPosAgentToScreen(const LLVector3 &pos_agent, LLCoord bool LLViewerCamera::projectPosAgentToScreenEdge(const LLVector3 &pos_agent, LLCoordGL &out_point) const { +#if GLU_VERSION_1_1 LLVector3 dir_to_point = pos_agent - getOrigin(); dir_to_point /= dir_to_point.magVec(); @@ -514,7 +515,7 @@ bool LLViewerCamera::projectPosAgentToScreenEdge(const LLVector3 &pos_agent, LLRect world_view_rect = gViewerWindow->getWorldViewRectRaw(); glm::ivec4 viewport(world_view_rect.mLeft, world_view_rect.mBottom, world_view_rect.getWidth(), world_view_rect.getHeight()); - glm::vec3 win_coord = glm::project(glm::make_vec3(pos_agent.mV), get_current_modelview(), get_current_projection(), viewport); + glm::vec3 win_coord = glm::project(glm::vec3(pos_agent), get_current_modelview(), get_current_projection(), viewport); { win_coord.x /= gViewerWindow->getDisplayScale().mV[VX]; @@ -632,6 +633,7 @@ bool LLViewerCamera::projectPosAgentToScreenEdge(const LLVector3 &pos_agent, out_point.mY = int_y + world_rect.mBottom; return true; } +#endif // GLU_VERSION_1_1 return false; } diff --git a/indra/newview/llviewercontrol.cpp b/indra/newview/llviewercontrol.cpp index 18746e76fc..598ad89907 100644 --- a/indra/newview/llviewercontrol.cpp +++ b/indra/newview/llviewercontrol.cpp @@ -261,6 +261,8 @@ static bool handleDisableVintageMode(const LLSD& newvalue) static bool handleEnableHDR(const LLSD& newvalue) { + gPipeline.mReflectionMapManager.reset(); + gPipeline.mHeroProbeManager.reset(); return handleReleaseGLBufferChanged(newvalue) && handleSetShaderChanged(newvalue); } @@ -448,11 +450,11 @@ static bool handleReflectionProbeDetailChanged(const LLSD& newvalue) if (gPipeline.isInit()) { LLPipeline::refreshCachedSettings(); + gPipeline.mReflectionMapManager.reset(); + gPipeline.mHeroProbeManager.reset(); gPipeline.releaseGLBuffers(); gPipeline.createGLBuffers(); LLViewerShaderMgr::instance()->setShaders(); - gPipeline.mReflectionMapManager.reset(); - gPipeline.mHeroProbeManager.reset(); } return true; } @@ -762,9 +764,9 @@ LLPointer<LLControlVariable> setting_get_control(LLControlGroup& group, const st LLPointer<LLControlVariable> cntrl_ptr = group.getControl(setting); if (cntrl_ptr.isNull()) { + LLError::LLUserWarningMsg::showMissingFiles(); LL_ERRS() << "Unable to set up setting listener for " << setting - << ". Please reinstall viewer from https ://secondlife.com/support/downloads/ and contact https://support.secondlife.com if issue persists after reinstall." - << LL_ENDL; + << "." << LL_ENDL; } return cntrl_ptr; } diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp index 32019f860d..24f1be3d1c 100644 --- a/indra/newview/llviewerdisplay.cpp +++ b/indra/newview/llviewerdisplay.cpp @@ -1674,7 +1674,9 @@ void render_ui_2d() // Render 2D UI elements that overlay the world (no z compare) // Disable wireframe mode below here, as this is HUD/menus +#if GL_VERSION_1_1 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); +#endif // Menu overlays, HUD, etc gViewerWindow->setup2DRender(); diff --git a/indra/newview/llviewerfloaterreg.cpp b/indra/newview/llviewerfloaterreg.cpp index ef68609182..7d138dfb3b 100644 --- a/indra/newview/llviewerfloaterreg.cpp +++ b/indra/newview/llviewerfloaterreg.cpp @@ -83,6 +83,7 @@ #include "llfloatergroups.h" #include "llfloaterhelpbrowser.h" #include "llfloaterhoverheight.h" +#include "mpfloatertuning.h" #include "llfloaterhowto.h" #include "llfloaterhud.h" #include "llfloaterimagepreview.h" @@ -137,6 +138,7 @@ #include "llfloatersettingscolor.h" #include "llfloatersettingsdebug.h" #include "llfloatersidepanelcontainer.h" +#include "llfloaterslapptest.h" #include "llfloatersnapshot.h" #include "llfloatersounddevices.h" #include "llfloaterspellchecksettings.h" @@ -176,6 +178,8 @@ #include "llscriptfloater.h" #include "llsyswellwindow.h" +#include "fsfloatersearch.h" + // *NOTE: Please add files in alphabetical order to keep merges easy. // handle secondlife:///app/openfloater/{NAME} URLs @@ -278,7 +282,8 @@ public: "upload_model", "upload_script", "upload_sound", - "bulk_upload" + "bulk_upload", + "slapp_test" }; return std::find(blacklist_untrusted.begin(), blacklist_untrusted.end(), fl_name) == blacklist_untrusted.end(); } @@ -389,6 +394,9 @@ void LLViewerFloaterReg::registerFloaters() LLFloaterReg::add("edit_hover_height", "floater_edit_hover_height.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterHoverHeight>); LLFloaterReg::add("hud", "floater_hud.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterHUD>); + LLFloaterReg::add("mpv_performance", "floater_mp_performance.xml", (LLFloaterBuildFunc)& + LLFloaterReg::build<MPFloaterTuning>); + LLFloaterReg::add("impanel", "floater_im_session.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterIMSession>); LLFloaterReg::add("im_container", "floater_im_container.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterIMContainer>); LLFloaterReg::add("im_well_window", "floater_sys_well.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLIMWellWindow>); @@ -496,9 +504,11 @@ void LLViewerFloaterReg::registerFloaters() LLFloaterReg::add("stop_queue", "floater_script_queue.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterNotRunQueue>); LLFloaterReg::add("snapshot", "floater_snapshot.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSnapshot>); LLFloaterReg::add("simple_snapshot", "floater_simple_snapshot.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSimpleSnapshot>); - LLFloaterReg::add("search", "floater_search.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSearch>); + LLFloaterReg::add("search", "floater_fs_search.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<FSFloaterSearch>); + //LLFloaterReg::add("search", "floater_search.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSearch>); LLFloaterReg::add("profile", "floater_profile.xml",(LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterProfile>); LLFloaterReg::add("guidebook", "floater_how_to.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterHowTo>); + LLFloaterReg::add("slapp_test", "floater_test_slapp.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSLappTest>); LLFloaterReg::add("big_preview", "floater_big_preview.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterBigPreview>); diff --git a/indra/newview/llviewerinput.cpp b/indra/newview/llviewerinput.cpp index ea3088613f..ffcbd1b4d8 100644 --- a/indra/newview/llviewerinput.cpp +++ b/indra/newview/llviewerinput.cpp @@ -48,6 +48,9 @@ #include "llinitparam.h" #include "llselectmgr.h" +#include "llfloaterwebcontent.h" +#include "fsfloatersearch.h" + // // Constants // @@ -648,6 +651,12 @@ bool start_chat( EKeystate s ) bool start_gesture( EKeystate s ) { + LLFloater* focused_floater = gFloaterView->getFocusedFloater(); + if (focused_floater && (dynamic_cast<LLFloaterWebContent*>(focused_floater) || dynamic_cast<FSFloaterSearch*>(focused_floater))) + { + return true; + } + LLUICtrl* focus_ctrlp = dynamic_cast<LLUICtrl*>(gFocusMgr.getKeyboardFocus()); if (KEYSTATE_UP == s && ! (focus_ctrlp && focus_ctrlp->acceptsTextInput())) diff --git a/indra/newview/llviewerjointattachment.cpp b/indra/newview/llviewerjointattachment.cpp index 511fac9788..e5cf1bcb69 100644 --- a/indra/newview/llviewerjointattachment.cpp +++ b/indra/newview/llviewerjointattachment.cpp @@ -28,6 +28,9 @@ #include "llviewerjointattachment.h" +// [SL:KB] - Patch: Appearance-PhantomAttach | Checked: Catznip-5.0 +#include "llagent.h" +// [/SL:KB] #include "llviewercontrol.h" #include "lldrawable.h" #include "llgl.h" @@ -168,7 +171,7 @@ void LLViewerJointAttachment::setupDrawable(LLViewerObject *object) //----------------------------------------------------------------------------- bool LLViewerJointAttachment::addObject(LLViewerObject* object) { - object->extractAttachmentItemID(); +// object->extractAttachmentItemID(); // Same object reattached if (isObjectAttached(object)) @@ -179,17 +182,39 @@ bool LLViewerJointAttachment::addObject(LLViewerObject* object) // re-connect object to the joint correctly } +// [SL:KB] - Patch: Appearance-Misc | Checked: 2011-01-13 (Catznip-2.4) + // LLViewerJointAttachment::removeObject() sets the object's item to the NULL UUID so we need to extract it *after* the block above + object->extractAttachmentItemID(); +// [/SL:KB] + // Two instances of the same inventory item attached -- // Request detach, and kill the object in the meantime. - if (getAttachedObject(object->getAttachmentItemID())) +// [SL:KB] - Patch: Appearance-PhantomAttach | Checked: Catznip-5.0 + if (LLViewerObject* pAttachObj = getAttachedObject(object->getAttachmentItemID())) { LL_INFOS() << "(same object re-attached)" << LL_ENDL; - object->markDead(); - - // If this happens to be attached to self, then detach. - LLVOAvatarSelf::detachAttachmentIntoInventory(object->getAttachmentItemID()); - return false; + pAttachObj->markDead(); + if (pAttachObj->permYouOwner()) + { + gMessageSystem->newMessage("ObjectDetach"); + gMessageSystem->nextBlockFast(_PREHASH_AgentData); + gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); + gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); + gMessageSystem->nextBlockFast(_PREHASH_ObjectData); + gMessageSystem->addU32Fast(_PREHASH_ObjectLocalID, pAttachObj->getLocalID()); + gMessageSystem->sendReliable(gAgent.getRegionHost()); + } } +// [/SL:KB] +// if (getAttachedObject(object->getAttachmentItemID())) +// { +// LL_INFOS() << "(same object re-attached)" << LL_ENDL; +// object->markDead(); +// +// // If this happens to be attached to self, then detach. +// LLVOAvatarSelf::detachAttachmentIntoInventory(object->getAttachmentItemID()); +// return FALSE; +// } mAttachedObjects.push_back(object); setupDrawable(object); @@ -461,7 +486,10 @@ const LLViewerObject *LLViewerJointAttachment::getAttachedObject(const LLUUID &o ++iter) { const LLViewerObject* attached_object = iter->get(); - if (attached_object->getAttachmentItemID() == object_id) +// if (attached_object->getAttachmentItemID() == object_id) +// [SL:KB] - Patch: Appearance-PhantomAttach | Checked: Catznip-5.0 + if ( (attached_object->getAttachmentItemID() == object_id) && (!attached_object->isDead()) ) +// [/SL:KB] { return attached_object; } diff --git a/indra/newview/llviewerjointmesh.cpp b/indra/newview/llviewerjointmesh.cpp index f0567b18c4..3ecf3c39b2 100644 --- a/indra/newview/llviewerjointmesh.cpp +++ b/indra/newview/llviewerjointmesh.cpp @@ -56,7 +56,7 @@ #include "llmatrix4a.h" #include "llperfstats.h" -#if !LL_DARWIN && !LL_LINUX +#if !LL_DARWIN && !LL_LINUX && !__FreeBSD__ extern PFNGLWEIGHTPOINTERARBPROC glWeightPointerARB; extern PFNGLWEIGHTFVARBPROC glWeightfvARB; extern PFNGLVERTEXBLENDARBPROC glVertexBlendARB; @@ -242,7 +242,9 @@ U32 LLViewerJointMesh::drawShape( F32 pixelArea, bool first_pass, bool is_dummy) stop_glerror(); +#if GL_VERSION_1_1 LLGLSSpecular specular(LLColor4(1.f,1.f,1.f,1.f), 0.f); +#endif //---------------------------------------------------------------- // setup current texture @@ -407,10 +409,16 @@ void LLViewerJointMesh::updateFaceData(LLFace *face, F32 pixel_area, bool damp_w F32* vw = (F32*) vertex_weightsp.get(); F32* cw = (F32*) clothing_weightsp.get(); - S32 tc_size = (num_verts*2*sizeof(F32)+0xF) & ~0xF; - LLVector4a::memcpyNonAliased16(tc, (F32*) mMesh->getTexCoords(), tc_size); - S32 vw_size = (num_verts*sizeof(F32)+0xF) & ~0xF; - LLVector4a::memcpyNonAliased16(vw, (F32*) mMesh->getWeights(), vw_size); + //S32 tc_size = (num_verts*2*sizeof(F32)+0xF) & ~0xF; + //LLVector4a::memcpyNonAliased16(tc, (F32*) mMesh->getTexCoords(), tc_size); + //S32 vw_size = (num_verts*sizeof(F32)+0xF) & ~0xF; + //LLVector4a::memcpyNonAliased16(vw, (F32*) mMesh->getWeights(), vw_size); + + // Both allocated in LLPolyMeshSharedData::allocateVertexData(unsigned int) + + memcpy(tc, mMesh->getTexCoords(), num_verts*2*sizeof(F32) ); + memcpy(vw, mMesh->getWeights(), num_verts*sizeof(F32) ); + LLVector4a::memcpyNonAliased16(cw, (F32*) mMesh->getClothingWeights(), num_verts*4*sizeof(F32)); } diff --git a/indra/newview/llviewermedia.cpp b/indra/newview/llviewermedia.cpp index 4e7416bb63..569924298f 100644 --- a/indra/newview/llviewermedia.cpp +++ b/indra/newview/llviewermedia.cpp @@ -397,7 +397,7 @@ std::string LLViewerMedia::getCurrentUserAgent() // This was also helpful: // http://www.mozilla.org/build/revised-user-agent-strings.html std::ostringstream codec; - codec << "SecondLife/"; + codec << "Megapahit/"; codec << LLVersionInfo::instance().getVersion(); codec << " (" << channel << "; " << skin_name << " skin)"; LL_INFOS() << codec.str() << LL_ENDL; @@ -1726,12 +1726,17 @@ LLPluginClassMedia* LLViewerMediaImpl::newSourceFromMediaType(std::string media_ { std::string launcher_name = gDirUtilp->getLLPluginLauncher(); std::string plugin_name = gDirUtilp->getLLPluginFilename(plugin_basename); +#if __FreeBSD__ + if (plugin_basename == "media_plugin_cef") + { + launcher_name = "/compat/linux/usr/libexec/megapahit/SLPlugin"; + plugin_name = "/compat/linux/usr/lib/x86_64-linux-gnu/libmedia_plugin_cef.so"; + } +#endif std::string user_data_path_cache = gDirUtilp->getCacheDir(false); user_data_path_cache += gDirUtilp->getDirDelimiter(); - std::string user_data_path_cef_log = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "cef_log.txt"); - // See if the plugin executable exists llstat s; if(LLFile::stat(launcher_name, &s)) @@ -1740,14 +1745,13 @@ LLPluginClassMedia* LLViewerMediaImpl::newSourceFromMediaType(std::string media_ } else if(LLFile::stat(plugin_name, &s)) { -#if !LL_LINUX LL_WARNS_ONCE("Media") << "Couldn't find plugin at " << plugin_name << LL_ENDL; -#endif } else { media_source = new LLPluginClassMedia(owner); media_source->setSize(default_width, default_height); + std::string user_data_path_cef_log = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "cef.log"); media_source->setUserDataPath(user_data_path_cache, gDirUtilp->getUserName(), user_data_path_cef_log); media_source->setLanguageCode(LLUI::getLanguage()); media_source->setZoomFactor(zoom_factor); @@ -1773,6 +1777,11 @@ LLPluginClassMedia* LLViewerMediaImpl::newSourceFromMediaType(std::string media_ bool media_plugin_debugging_enabled = gSavedSettings.getBOOL("MediaPluginDebugging"); media_source->enableMediaPluginDebugging( media_plugin_debugging_enabled || clean_browser); +#if LL_LINUX + bool media_plugin_pipewire_volume_catcher = gSavedSettings.getBOOL("MediaPluginPipeWireVolumeCatcher"); + media_source->enablePipeWireVolumeCatcher( media_plugin_pipewire_volume_catcher ); +#endif + // need to set agent string here before instance created media_source->setBrowserUserAgent(LLViewerMedia::getInstance()->getCurrentUserAgent()); @@ -1782,7 +1791,16 @@ LLPluginClassMedia* LLViewerMediaImpl::newSourceFromMediaType(std::string media_ media_source->setTarget(target); +#if __FreeBSD__ + std::string plugin_dir = gDirUtilp->getLLPluginDir(); + if (plugin_basename == "media_plugin_cef") + { + plugin_dir = "/compat/linux/usr/lib/x86_64-linux-gnu"; + plugin_name = "/usr/lib/x86_64-linux-gnu/libmedia_plugin_cef.so"; + } +#else const std::string plugin_dir = gDirUtilp->getLLPluginDir(); +#endif if (media_source->init(launcher_name, plugin_dir, plugin_name, gSavedSettings.getBOOL("PluginAttachDebuggerToPlugins"))) { return media_source; @@ -1794,9 +1812,7 @@ LLPluginClassMedia* LLViewerMediaImpl::newSourceFromMediaType(std::string media_ } } } -#if !LL_LINUX LL_WARNS_ONCE("Plugin") << "plugin initialization failed for mime type: " << media_type << LL_ENDL; -#endif if(gAgent.isInitialized()) { @@ -2902,14 +2918,14 @@ void LLViewerMediaImpl::update() media_tex->ref(); main_queue->postTo( mTexUpdateQueue, // Worker thread queue - [=]() // work done on update worker thread + [=, this]() // work done on update worker thread { #if LL_IMAGEGL_THREAD_CHECK media_tex->getGLTexture()->mActiveThread = LLThread::currentID(); #endif doMediaTexUpdate(media_tex, data, data_width, data_height, x_pos, y_pos, width, height, true); }, - [=]() // callback to main thread + [=, this]() // callback to main thread { #if LL_IMAGEGL_THREAD_CHECK media_tex->getGLTexture()->mActiveThread = LLThread::currentID(); diff --git a/indra/newview/llviewermedia_streamingaudio.cpp b/indra/newview/llviewermedia_streamingaudio.cpp index b68ffbe1a2..21f5ba64d7 100644 --- a/indra/newview/llviewermedia_streamingaudio.cpp +++ b/indra/newview/llviewermedia_streamingaudio.cpp @@ -34,6 +34,7 @@ #include "llmimetypes.h" #include "lldir.h" +#include "llnotificationmanager.h" LLStreamingAudio_MediaPlugins::LLStreamingAudio_MediaPlugins() : mMediaPlugin(NULL), @@ -111,6 +112,8 @@ void LLStreamingAudio_MediaPlugins::update() mMediaPlugin->idle(); } +extern void send_chat_from_viewer(const std::string& utf8_out_text, EChatType type, S32 channel); + int LLStreamingAudio_MediaPlugins::isPlaying() { if (!mMediaPlugin) @@ -118,6 +121,21 @@ int LLStreamingAudio_MediaPlugins::isPlaying() LLPluginClassMediaOwner::EMediaStatus status = mMediaPlugin->getStatus(); + auto nowPlaying = mMediaPlugin->getMediaNowPlaying(); + if (!nowPlaying.empty() && mNowPlaying != nowPlaying) + { + mTitle = mMediaPlugin->getMediaTitle(); + mNowPlaying = nowPlaying; + auto text = llformat("Now playing %s.", nowPlaying.c_str()); + LLChat chat{text}; + chat.mFromName = mTitle; + chat.mSourceType = CHAT_SOURCE_SYSTEM; + LLNotificationsUI::LLNotificationManager::instance().onChat(chat, LLSD{}); + if (gSavedSettings.getBOOL("StreamNotificationChannelEnabled")) + { + send_chat_from_viewer(text, CHAT_TYPE_NORMAL, gSavedSettings.getS32("StreamNotificationChannel")); + } + } switch (status) { diff --git a/indra/newview/llviewermedia_streamingaudio.h b/indra/newview/llviewermedia_streamingaudio.h index bf4d92c29e..e1f7cd71d9 100644 --- a/indra/newview/llviewermedia_streamingaudio.h +++ b/indra/newview/llviewermedia_streamingaudio.h @@ -56,6 +56,8 @@ private: LLPluginClassMedia *mMediaPlugin; std::string mURL; + std::string mTitle; + std::string mNowPlaying; F32 mGain; }; diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index 80c75ec919..1f8f960300 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -39,6 +39,7 @@ #include "llfloaterreg.h" #include "llfloatersidepanelcontainer.h" #include "llinventorypanel.h" +#include "llsidepanelinventory.h" #include "llnotifications.h" #include "llnotificationsutil.h" #include "llviewereventrecorder.h" @@ -52,6 +53,9 @@ #include "llagentui.h" #include "llagentwearables.h" #include "llagentpilot.h" +// [SL:KB] - Patch: Appearance-PhantomAttach | Checked: Catznip-5.0 +#include "llattachmentsmgr.h" +// [/SL:KB] #include "llcompilequeue.h" #include "llconsole.h" #include "lldebugview.h" @@ -73,6 +77,7 @@ #include "llfloaterpay.h" #include "llfloaterreporter.h" #include "llfloatersearch.h" +#include "fsfloatersearch.h" #include "llfloaterscriptdebug.h" #include "llfloatersnapshot.h" #include "llfloatertools.h" @@ -286,6 +291,8 @@ void force_error_software_exception(); void force_error_os_exception(); void force_error_driver_crash(); void force_error_coroutine_crash(); +void force_error_coroprocedure_crash(); +void force_error_work_queue_crash(); void force_error_thread_crash(); void handle_force_delete(); @@ -2170,6 +2177,13 @@ class LLAdvancedRebakeTextures : public view_listener_t }; +// [SL:KB] - Patch: Appearance-PhantomAttach | Checked: Catznip-5.0 +void handle_refresh_attachments() +{ + LLAttachmentsMgr::instance().refreshAttachments(); +} +// [/SL:KB] + #if 1 //ndef LL_RELEASE_FOR_DOWNLOAD /////////////////////////// // DEBUG AVATAR TEXTURES // @@ -2634,6 +2648,24 @@ class LLAdvancedForceErrorCoroutineCrash : public view_listener_t } }; +class LLAdvancedForceErrorCoroprocedureCrash : public view_listener_t +{ + bool handleEvent(const LLSD& userdata) + { + force_error_coroprocedure_crash(); + return true; + } +}; + +class LLAdvancedForceErrorWorkQueueCrash : public view_listener_t +{ + bool handleEvent(const LLSD& userdata) + { + force_error_work_queue_crash(); + return true; + } +}; + class LLAdvancedForceErrorThreadCrash : public view_listener_t { bool handleEvent(const LLSD& userdata) @@ -3157,7 +3189,11 @@ void handle_object_edit() LLFloaterReg::showInstance("build"); LLToolMgr::getInstance()->setCurrentToolset(gBasicToolset); - gFloaterTools->setEditTool( LLToolCompTranslate::getInstance() ); + + if (gFloaterTools) + { + gFloaterTools->setEditTool( LLToolCompTranslate::getInstance() ); + } LLViewerJoystick::getInstance()->moveObjects(true); LLViewerJoystick::getInstance()->setNeedsReset(true); @@ -5199,15 +5235,16 @@ void handle_take(bool take_separate) // MAINT-290 // Reason: Showing the confirmation dialog resets object selection, thus there is nothing to derez. // Fix: pass selection to the confirm_take, so that selection doesn't "die" after confirmation dialog is opened - params.functor.function([take_separate](const LLSD ¬ification, const LLSD &response) + LLObjectSelectionHandle obj_selection = LLSelectMgr::instance().getSelection(); + params.functor.function([take_separate, obj_selection](const LLSD ¬ification, const LLSD &response) { if (take_separate) { - confirm_take_separate(notification, response, LLSelectMgr::instance().getSelection()); + confirm_take_separate(notification, response, obj_selection); } else { - confirm_take(notification, response, LLSelectMgr::instance().getSelection()); + confirm_take(notification, response, obj_selection); } }); @@ -6476,6 +6513,26 @@ void handle_zoom_to_object(const LLUUID& object_id) } } +void handle_teleport_to_object(LLUUID object_id) +{ + LLViewerObject* object = gObjectList.findObject(object_id); + + if (object) + { + gAgentCamera.setFocusOnAvatar(FALSE, ANIMATE); + + LLBBox bbox = object->getBoundingBoxAgent() ; + + LLVector3 obj_to_cam = LLViewerCamera::getInstance()->getOrigin() - bbox.getCenterAgent(); + obj_to_cam.normVec(); + + + LLVector3d object_center_global = gAgent.getPosGlobalFromAgent(bbox.getCenterAgent()); + + gAgent.teleportViaLocation(object_center_global); + } +} + class LLAvatarInviteToGroup : public view_listener_t { bool handleEvent(const LLSD& userdata) @@ -6578,6 +6635,35 @@ class LLAvatarToggleSearch : public view_listener_t } }; +// <FS:CR> Resync Animations +class FSToolsResyncAnimations : public view_listener_t +{ + bool handleEvent(const LLSD& userdata) + { + for (S32 i = 0; i < gObjectList.getNumObjects(); i++) + { + LLViewerObject* object = gObjectList.getObject(i); + if (object && + object->isAvatar()) + { + LLVOAvatar* avatarp = (LLVOAvatar*)object; + if (avatarp) + { + for (LLVOAvatar::AnimIterator anim_it = avatarp->mPlayingAnimations.begin(); + anim_it != avatarp->mPlayingAnimations.end(); + anim_it++) + { + avatarp->stopMotion(anim_it->first, true); + avatarp->startMotion(anim_it->first); + } + } + } + } + return true; + } +}; +// </FS:CR> Resync Animations + class LLAvatarResetSkeleton : public view_listener_t { bool handleEvent(const LLSD& userdata) @@ -6711,6 +6797,59 @@ void handle_give_money_dialog() } } +LLFloaterSidePanelContainer* get_favorite_inventory_folder() +{ + LLUUID folder_id = LLUUID(gSavedPerAccountSettings.getString("FavoriteFolder")); + if (!folder_id.isNull()) + { + LLFloaterReg::const_instance_list_t& inst_list = LLFloaterReg::getFloaterList("inventory"); + for (LLFloaterReg::const_instance_list_t::const_iterator iter = inst_list.begin(); iter != inst_list.end();) + { + LLFloaterSidePanelContainer* inventory_container = dynamic_cast<LLFloaterSidePanelContainer*>(*iter++); + if (inventory_container) + { + LLSidepanelInventory* sidepanel_inventory = dynamic_cast<LLSidepanelInventory*>(inventory_container->findChild<LLPanel>("main_panel", true)); + if (sidepanel_inventory) + { + LLPanelMainInventory* main_inventory = sidepanel_inventory->getMainInventoryPanel(); + if (main_inventory && main_inventory->isSingleFolderMode() + && (main_inventory->getCurrentSFVRoot() == folder_id)) + { + return inventory_container; + } + } + } + } + } + + return NULL; +} + +void toggle_favorite_inventory_folder() +{ + LLUUID folder_id = LLUUID(gSavedPerAccountSettings.getString("FavoriteFolder")); + if ((folder_id.isNull()) || (!gInventory.getCategory(folder_id))) + { + LLNotificationsUtil::add("MissingFavoriteFolder"); + return; + } + + LLFloaterSidePanelContainer* inventory_container = get_favorite_inventory_folder(); + if (inventory_container) + { + inventory_container->closeFloater(); + } + else + { + LLPanelMainInventory::newFolderWindow(folder_id); + } +} + +bool favorite_inventory_folder_visible() +{ + return (get_favorite_inventory_folder() != NULL); +} + bool enable_pay_avatar() { LLViewerObject* obj = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject(); @@ -8656,6 +8795,16 @@ void force_error_coroutine_crash() LLAppViewer::instance()->forceErrorCoroutineCrash(); } +void force_error_coroprocedure_crash() +{ + LLAppViewer::instance()->forceErrorCoroprocedureCrash(); +} + +void force_error_work_queue_crash() +{ + LLAppViewer::instance()->forceErrorWorkQueueCrash(); +} + void force_error_thread_crash() { LLAppViewer::instance()->forceErrorThreadCrash(); @@ -9832,6 +9981,9 @@ void initialize_menus() view_listener_t::addMenu(new LLAdvancedCheckDebugCharacterVis(), "Advanced.CheckDebugCharacterVis"); view_listener_t::addMenu(new LLAdvancedDumpAttachments(), "Advanced.DumpAttachments"); view_listener_t::addMenu(new LLAdvancedRebakeTextures(), "Advanced.RebakeTextures"); +// [SL:KB] - Patch: Appearance-PhantomAttach | Checked: Catznip-5.0 + commit.add("Advanced.RefreshAttachments", boost::bind(&handle_refresh_attachments)); +// [/SL:KB] view_listener_t::addMenu(new LLAdvancedDebugAvatarTextures(), "Advanced.DebugAvatarTextures"); view_listener_t::addMenu(new LLAdvancedDumpAvatarLocalTextures(), "Advanced.DumpAvatarLocalTextures"); // Advanced > Network @@ -9860,6 +10012,8 @@ void initialize_menus() view_listener_t::addMenu(new LLAdvancedForceErrorSoftwareExceptionCoro(), "Advanced.ForceErrorSoftwareExceptionCoro"); view_listener_t::addMenu(new LLAdvancedForceErrorDriverCrash(), "Advanced.ForceErrorDriverCrash"); view_listener_t::addMenu(new LLAdvancedForceErrorCoroutineCrash(), "Advanced.ForceErrorCoroutineCrash"); + view_listener_t::addMenu(new LLAdvancedForceErrorCoroprocedureCrash(), "Advanced.ForceErrorCoroprocedureCrash"); + view_listener_t::addMenu(new LLAdvancedForceErrorWorkQueueCrash(), "Advanced.ForceErrorWorkQueueCrash"); view_listener_t::addMenu(new LLAdvancedForceErrorThreadCrash(), "Advanced.ForceErrorThreadCrash"); view_listener_t::addMenu(new LLAdvancedForceErrorDisconnectViewer(), "Advanced.ForceErrorDisconnectViewer"); @@ -9936,6 +10090,7 @@ void initialize_menus() view_listener_t::addMenu(new LLAvatarToggleMyProfile(), "Avatar.ToggleMyProfile"); view_listener_t::addMenu(new LLAvatarTogglePicks(), "Avatar.TogglePicks"); view_listener_t::addMenu(new LLAvatarToggleSearch(), "Avatar.ToggleSearch"); + view_listener_t::addMenu(new FSToolsResyncAnimations(), "Tools.ResyncAnimations"); // <FS:CR> Resync Animations view_listener_t::addMenu(new LLAvatarResetSkeleton(), "Avatar.ResetSkeleton"); view_listener_t::addMenu(new LLAvatarEnableResetSkeleton(), "Avatar.EnableResetSkeleton"); view_listener_t::addMenu(new LLAvatarResetSkeletonAndAnimations(), "Avatar.ResetSkeletonAndAnimations"); @@ -10037,6 +10192,9 @@ void initialize_menus() commit.add("Inventory.NewWindow", boost::bind(&LLPanelMainInventory::newWindow)); + commit.add("Inventory.OpenFavoriteFolder", boost::bind(&toggle_favorite_inventory_folder)); + enable.add("Inventory.IsFavoriteFolderOpen", boost::bind(&favorite_inventory_folder_visible)); + enable.add("EnablePayObject", boost::bind(&enable_pay_object)); enable.add("EnablePayAvatar", boost::bind(&enable_pay_avatar)); enable.add("EnableEdit", boost::bind(&enable_object_edit)); diff --git a/indra/newview/llviewermenu.h b/indra/newview/llviewermenu.h index 68c3dbc126..68ba740f67 100644 --- a/indra/newview/llviewermenu.h +++ b/indra/newview/llviewermenu.h @@ -74,6 +74,7 @@ void handle_take(bool take_separate = false); void handle_take_copy(); void handle_look_at_selection(const LLSD& param); void handle_zoom_to_object(const LLUUID& object_id); +void handle_teleport_to_object(LLUUID object_id); void handle_object_return(); void handle_object_delete(); void handle_object_edit(); diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp index 1d4828fd33..5fd820f91d 100644 --- a/indra/newview/llviewermessage.cpp +++ b/indra/newview/llviewermessage.cpp @@ -3147,7 +3147,9 @@ void send_agent_update(bool force_send, bool send_reliable) LL_PROFILE_ZONE_SCOPED; llassert(!gCubeSnapshot); - if (gAgent.getTeleportState() != LLAgent::TELEPORT_NONE) + LLAgent::ETeleportState tp_state = gAgent.getTeleportState(); + if (tp_state != LLAgent::TELEPORT_NONE + && tp_state != LLAgent::TELEPORT_ARRIVING) { // We don't care if they want to send an agent update, they're not allowed // until the target simulator is ready to receive them @@ -3322,7 +3324,36 @@ void send_agent_update(bool force_send, bool send_reliable) msg->addVector3Fast(_PREHASH_CameraAtAxis, camera_at); msg->addVector3Fast(_PREHASH_CameraLeftAxis, LLViewerCamera::getInstance()->getLeftAxis()); msg->addVector3Fast(_PREHASH_CameraUpAxis, LLViewerCamera::getInstance()->getUpAxis()); - msg->addF32Fast(_PREHASH_Far, gAgentCamera.mDrawDistance); + + static F32 last_draw_disatance_step = 1024; + if (tp_state == LLAgent::TELEPORT_ARRIVING || LLStartUp::getStartupState() < STATE_MISC) + { + // Inform interest list, prioritize closer area. + // Reason: currently server doesn't distance sort attachments, by restricting range + // we reduce the number of attachments sent to the viewer, thus prioritizing + // closer ones. + // Todo: revise and remove once server gets distance sorting. + last_draw_disatance_step = llmax((F32)(gAgentCamera.mDrawDistance / 2.f), 50.f); + msg->addF32Fast(_PREHASH_Far, last_draw_disatance_step); + } + else if (last_draw_disatance_step < gAgentCamera.mDrawDistance) + { + static LLFrameTimer last_step_time; + if (last_step_time.getElapsedTimeF32() > 1.f) + { + // gradually increase draw distance + // Idealy this should be not per second, but based on how loaded + // mesh thread is, but hopefully this is temporary. + last_step_time.reset(); + F32 step = gAgentCamera.mDrawDistance * 0.1f; + last_draw_disatance_step = llmin(last_draw_disatance_step + step, gAgentCamera.mDrawDistance); + } + msg->addF32Fast(_PREHASH_Far, last_draw_disatance_step); + } + else + { + msg->addF32Fast(_PREHASH_Far, gAgentCamera.mDrawDistance); + } msg->addU32Fast(_PREHASH_ControlFlags, control_flags); diff --git a/indra/newview/llviewernetwork.cpp b/indra/newview/llviewernetwork.cpp index 16ddc2f89c..b8c9594aa7 100644 --- a/indra/newview/llviewernetwork.cpp +++ b/indra/newview/llviewernetwork.cpp @@ -629,6 +629,18 @@ bool LLGridManager::isInProductionGrid() return mIsInProductionGrid; } +bool LLGridManager::isInSecondlife() +{ + //return (isInSLMain() || isInSLBeta()); + return true; +} + +bool LLGridManager::isInOpenSim() +{ + // FIX THIS TO SUPPORT OPENSIM + return false; +} + bool LLGridManager::isSystemGrid(const std::string& grid) { std::string grid_name = getGrid(grid); diff --git a/indra/newview/llviewernetwork.h b/indra/newview/llviewernetwork.h index 2ed663e038..7d9c70994c 100644 --- a/indra/newview/llviewernetwork.h +++ b/indra/newview/llviewernetwork.h @@ -174,6 +174,20 @@ class LLGridManager : public LLSingleton<LLGridManager> //@} + typedef enum e_grid_platform { + NOPLATFORM = 0, + SLMAIN, + SLBETA, + OPENSIM, + HALCYON + } EGridPlatform; + + typedef enum e_add_grid { + ADD_MANUAL = 0, + ADD_HYPERGRID, + ADD_LINK + } EAddGridType; + /* ================================================================ * @name Selecting the current grid * @{ @@ -198,6 +212,11 @@ class LLGridManager : public LLSingleton<LLGridManager> /// Is the selected grid one of the hard-coded default grids (Agni or Aditi) bool isSystemGrid() { return isSystemGrid(mGrid); } + /// Is the selected grid Second Life? + bool isInSecondlife(); + + bool isInOpenSim(); + /// Is the selected grid a production grid? bool isInProductionGrid(); /** diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp index 86440fca48..c5e81dd179 100644 --- a/indra/newview/llviewerobject.cpp +++ b/indra/newview/llviewerobject.cpp @@ -1290,7 +1290,7 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys, #endif //clear cost and linkset cost setObjectCostStale(); - if (isSelected()) + if (isSelected() && gFloaterTools) { gFloaterTools->dirty(); } @@ -1729,7 +1729,7 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys, #endif setObjectCostStale(); - if (isSelected()) + if (isSelected() && gFloaterTools) { gFloaterTools->dirty(); } @@ -2917,6 +2917,17 @@ void LLViewerObject::fetchInventoryFromServer() delete mInventory; mInventory = NULL; + // This will get reset by doInventoryCallback or processTaskInv + mInvRequestState = INVENTORY_REQUEST_PENDING; + + if (mRegionp && !mRegionp->getCapability("RequestTaskInventory").empty()) + { + LLCoros::instance().launch("LLViewerObject::fetchInventoryFromCapCoro()", + boost::bind(&LLViewerObject::fetchInventoryFromCapCoro, mID)); + } + else + { + LL_WARNS() << "Using old task inventory path!" << LL_ENDL; // Results in processTaskInv LLMessageSystem* msg = gMessageSystem; msg->newMessageFast(_PREHASH_RequestTaskInventory); @@ -2926,15 +2937,13 @@ void LLViewerObject::fetchInventoryFromServer() msg->nextBlockFast(_PREHASH_InventoryData); msg->addU32Fast(_PREHASH_LocalID, mLocalID); msg->sendReliable(mRegionp->getHost()); - - // This will get reset by doInventoryCallback or processTaskInv - mInvRequestState = INVENTORY_REQUEST_PENDING; + } } } void LLViewerObject::fetchInventoryDelayed(const F64 &time_seconds) { - // unless already waiting, drop previous request and shedule an update + // unless already waiting, drop previous request and schedule an update if (mInvRequestState != INVENTORY_REQUEST_WAIT) { if (mInvRequestXFerId != 0) @@ -2965,6 +2974,80 @@ void LLViewerObject::fetchInventoryDelayedCoro(const LLUUID task_inv, const F64 } } +//static +void LLViewerObject::fetchInventoryFromCapCoro(const LLUUID task_inv) +{ + LLViewerObject *obj = gObjectList.findObject(task_inv); + if (obj) + { + LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID); + LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t + httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("TaskInventoryRequest", httpPolicy)); + LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest); + std::string url = obj->mRegionp->getCapability("RequestTaskInventory") + "?task_id=" + obj->mID.asString(); + // If we already have a copy of the inventory then add it so the server won't re-send something we already have. + // We expect this case to crop up in the case of failed inventory mutations, but it might happen otherwise as well. + if (obj->mInventorySerialNum && obj->mInventory) + url += "&inventory_serial=" + std::to_string(obj->mInventorySerialNum); + + obj->mInvRequestState = INVENTORY_XFER; + LLSD result = httpAdapter->getAndSuspend(httpRequest, url); + + LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS]; + LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults); + + // Object may have gone away while we were suspended, double-check that it still exists + obj = gObjectList.findObject(task_inv); + if (!obj) + { + LL_WARNS() << "Object " << task_inv << " went away while fetching inventory, dropping result" << LL_ENDL; + return; + } + + bool potentially_stale = false; + if (status) + { + // Dealing with inventory serials is kind of funky. They're monotonically increasing and 16 bits, + // so we expect them to overflow, but we can use inv serial < expected serial as a signal that we may + // have mutated the task inventory since we kicked off the request, and those mutations may have not + // been taken into account yet. Of course, those mutations may have actually failed which would result + // in the inv serial never increasing. + // + // When we detect this case, set the expected inv serial to the inventory serial we actually received + // and kick off a re-request after a slight delay. + S16 serial = (S16)result["inventory_serial"].asInteger(); + potentially_stale = serial < obj->mExpectedInventorySerialNum; + LL_INFOS() << "Inventory loaded for " << task_inv << LL_ENDL; + obj->mInventorySerialNum = serial; + obj->mExpectedInventorySerialNum = serial; + obj->loadTaskInvLLSD(result); + } + else if (status.getType() == 304) + { + LL_INFOS() << "Inventory wasn't changed on server!" << LL_ENDL; + obj->mInvRequestState = INVENTORY_REQUEST_STOPPED; + // Even though it wasn't necessary to send a response, we still may have mutated + // the inventory since we kicked off the request, check for that case. + potentially_stale = obj->mInventorySerialNum < obj->mExpectedInventorySerialNum; + // Set this to what we already have so that we don't re-request a second time. + obj->mExpectedInventorySerialNum = obj->mInventorySerialNum; + } + else + { + // Not sure that there's anything sensible we can do to recover here, retrying in a loop would be bad. + LL_WARNS() << "Error status while requesting task inventory: " << status.toString() << LL_ENDL; + obj->mInvRequestState = INVENTORY_REQUEST_STOPPED; + } + + if (potentially_stale) + { + // Stale? I guess we can use what we got for now, but we'll have to re-request + LL_WARNS() << "Stale inv_serial? Re-requesting." << LL_ENDL; + obj->fetchInventoryDelayed(INVENTORY_UPDATE_WAIT_TIME_OUTDATED); + } + } +} + LLControlAvatar *LLViewerObject::getControlAvatar() { return getRootEdit()->mControlAvatar.get(); @@ -3140,6 +3223,20 @@ void LLViewerObject::processTaskInv(LLMessageSystem* msg, void** user_data) S16 serial = 0; msg->getS16Fast(_PREHASH_InventoryData, _PREHASH_Serial, serial); + if (object->mRegionp && !object->mRegionp->getCapability("RequestTaskInventory").empty()) + { + // It seems that simulator may ask us to re-download the task inventory if an update to the inventory + // happened out-of-band while we had the object selected (like if a script is saved.) + // + // If we're meant to use the HTTP capability, ignore the contents of the UDP message and fetch the + // inventory via the CAP so that we don't flow down the UDP inventory request path unconditionally here. + // We shouldn't need to wait, as any updates should already be ready to fetch by this point. + LL_INFOS() << "Handling unsolicited ReplyTaskInventory for " << task_id << LL_ENDL; + object->mExpectedInventorySerialNum = serial; + object->fetchInventoryFromServer(); + return; + } + if (serial == object->mInventorySerialNum && serial < object->mExpectedInventorySerialNum) { @@ -3347,6 +3444,47 @@ bool LLViewerObject::loadTaskInvFile(const std::string& filename) return true; } +void LLViewerObject::loadTaskInvLLSD(const LLSD& inv_result) +{ + if (inv_result.has("contents")) + { + if(mInventory) + { + mInventory->clear(); // will deref and delete it + } + else + { + mInventory = new LLInventoryObject::object_list_t; + } + + // Synthesize the "Contents" category, the viewer expects it, but it isn't sent. + LLPointer<LLInventoryObject> inv = new LLInventoryObject(mID, LLUUID::null, LLAssetType::AT_CATEGORY, "Contents"); + mInventory->push_front(inv); + + const LLSD& inventory = inv_result["contents"]; + for (const auto& inv_entry : llsd::inArray(inventory)) + { + if (inv_entry.has("item_id")) + { + LLPointer<LLViewerInventoryItem> inv = new LLViewerInventoryItem; + inv->unpackMessage(inv_entry); + mInventory->push_front(inv); + } + else + { + LL_WARNS_ONCE() << "Unknown inventory entry while reading from inventory file. Entry: '" + << inv_entry << "'" << LL_ENDL; + } + } + } + else + { + LL_WARNS() << "unable to load task inventory: " << inv_result << LL_ENDL; + return; + } + doInventoryCallback(); +} + void LLViewerObject::doInventoryCallback() { for (callback_list_t::iterator iter = mInventoryCallbacks.begin(); @@ -3747,7 +3885,7 @@ void LLViewerObject::setObjectCost(F32 cost) mObjectCost = cost; mCostStale = false; - if (isSelected()) + if (isSelected() && gFloaterTools) { gFloaterTools->dirty(); } @@ -3767,7 +3905,7 @@ void LLViewerObject::setLinksetCost(F32 cost) iter++; } - if (needs_refresh) + if (needs_refresh && gFloaterTools) { gFloaterTools->dirty(); } @@ -3778,7 +3916,7 @@ void LLViewerObject::setPhysicsCost(F32 cost) mPhysicsCost = cost; mCostStale = false; - if (isSelected()) + if (isSelected() && gFloaterTools) { gFloaterTools->dirty(); } @@ -3789,7 +3927,7 @@ void LLViewerObject::setLinksetPhysicsCost(F32 cost) mLinksetPhysicsCost = cost; mCostStale = false; - if (isSelected()) + if (isSelected() && gFloaterTools) { gFloaterTools->dirty(); } @@ -4682,6 +4820,18 @@ void LLViewerObject::setPositionParent(const LLVector3 &pos_parent, bool damped) else { setPositionRegion(pos_parent, damped); + + // #1964 mark reflection probe in the linkset to update position after moving via script + for (LLViewerObject* child : mChildList) + { + if (child && child->isReflectionProbe()) + { + if (LLDrawable* drawablep = child->mDrawable) + { + gPipeline.markMoved(drawablep); + } + } + } } } @@ -7532,6 +7682,31 @@ void LLViewerObject::setGLTFAsset(const LLUUID& id) updateVolume(volume_params); } +void LLViewerObject::clearTEWaterExclusion(const U8 te) +{ + if (permModify()) + { + LLViewerTexture* image = getTEImage(te); + if (image && (IMG_ALPHA_GRAD == image->getID())) + { + // reset texture to default plywood + setTEImage(te, LLViewerTextureManager::getFetchedTexture(DEFAULT_OBJECT_TEXTURE, FTT_DEFAULT, true, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE)); + + // reset texture repeats, that might be altered by invisiprim script from wiki + U32 s_axis, t_axis; + if (!LLPrimitive::getTESTAxes(te, &s_axis, &t_axis)) + { + return; + } + F32 DEFAULT_REPEATS = 2.f; + F32 new_s = getScale().mV[s_axis] * DEFAULT_REPEATS; + F32 new_t = getScale().mV[t_axis] * DEFAULT_REPEATS; + + setTEScale(te, new_s, new_t); + sendTEUpdate(); + } + } +} class ObjectPhysicsProperties : public LLHTTPNode { diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h index b6846c6716..2b52ea2076 100644 --- a/indra/newview/llviewerobject.h +++ b/indra/newview/llviewerobject.h @@ -405,6 +405,8 @@ public: LLViewerTexture *getTENormalMap(const U8 te) const; LLViewerTexture *getTESpecularMap(const U8 te) const; + void clearTEWaterExclusion(const U8 te); + bool isImageAlphaBlended(const U8 te) const; void fitFaceTexture(const U8 face); @@ -688,6 +690,7 @@ private: // forms task inventory request after some time passed, marks request as pending void fetchInventoryDelayed(const F64 &time_seconds); static void fetchInventoryDelayedCoro(const LLUUID task_inv, const F64 time_seconds); + static void fetchInventoryFromCapCoro(const LLUUID task_inv); public: // @@ -727,6 +730,9 @@ public: // index into LLViewerObjectList::mActiveObjects or -1 if not in list S32 mListIndex; + // last index data for mIndexAndLocalIDToUUID + U32 mRegionIndex; + LLPointer<LLViewerTexture> *mTEImages; LLPointer<LLViewerTexture> *mTENormalMaps; LLPointer<LLViewerTexture> *mTESpecularMaps; @@ -755,6 +761,7 @@ public: // Associated GLTF Asset std::shared_ptr<LL::GLTF::Asset> mGLTFAsset; + bool mIsGLTFAssetMissing = false; // Pipeline classes LLPointer<LLDrawable> mDrawable; @@ -822,6 +829,7 @@ protected: static void processTaskInvFile(void** user_data, S32 error_code, LLExtStat ext_status); bool loadTaskInvFile(const std::string& filename); + void loadTaskInvLLSD(const LLSD &inv_result); void doInventoryCallback(); bool isOnMap(); diff --git a/indra/newview/llviewerobjectlist.cpp b/indra/newview/llviewerobjectlist.cpp index d667fdbea8..d72d428c08 100644 --- a/indra/newview/llviewerobjectlist.cpp +++ b/indra/newview/llviewerobjectlist.cpp @@ -164,21 +164,14 @@ U64 LLViewerObjectList::getIndex(const U32 local_id, return (((U64)index) << 32) | (U64)local_id; } -bool LLViewerObjectList::removeFromLocalIDTable(const LLViewerObject* objectp) +bool LLViewerObjectList::removeFromLocalIDTable(LLViewerObject* objectp) { LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK; - if(objectp && objectp->getRegion()) + if(objectp && objectp->mRegionIndex != 0) { U32 local_id = objectp->mLocalID; - U32 ip = objectp->getRegion()->getHost().getAddress(); - U32 port = objectp->getRegion()->getHost().getPort(); - U64 ipport = (((U64)ip) << 32) | (U64)port; - U32 index = mIPAndPortToIndex[ipport]; - - // LL_INFOS() << "Removing object from table, local ID " << local_id << ", ip " << ip << ":" << port << LL_ENDL; - - U64 indexid = (((U64)index) << 32) | (U64)local_id; + U64 indexid = (((U64)objectp->mRegionIndex) << 32) | (U64)local_id; std::map<U64, LLUUID>::iterator iter = mIndexAndLocalIDToUUID.find(indexid); if (iter == mIndexAndLocalIDToUUID.end()) @@ -190,6 +183,7 @@ bool LLViewerObjectList::removeFromLocalIDTable(const LLViewerObject* objectp) if (iter->second == objectp->getID()) { // Full UUIDs match, so remove the entry mIndexAndLocalIDToUUID.erase(iter); + objectp->mRegionIndex = 0; return true; } // UUIDs did not match - this would zap a valid entry, so don't erase it @@ -203,7 +197,8 @@ bool LLViewerObjectList::removeFromLocalIDTable(const LLViewerObject* objectp) void LLViewerObjectList::setUUIDAndLocal(const LLUUID &id, const U32 local_id, const U32 ip, - const U32 port) + const U32 port, + LLViewerObject* objectp) { U64 ipport = (((U64)ip) << 32) | (U64)port; @@ -215,6 +210,7 @@ void LLViewerObjectList::setUUIDAndLocal(const LLUUID &id, mIPAndPortToIndex[ipport] = index; } + objectp->mRegionIndex = index; // should never be zero, sSimulatorMachineIndex starts from 1 U64 indexid = (((U64)index) << 32) | (U64)local_id; mIndexAndLocalIDToUUID[indexid] = id; @@ -335,7 +331,8 @@ LLViewerObject* LLViewerObjectList::processObjectUpdateFromCache(LLVOCacheEntry* removeFromLocalIDTable(objectp); setUUIDAndLocal(fullid, entry->getLocalID(), regionp->getHost().getAddress(), - regionp->getHost().getPort()); + regionp->getHost().getPort(), + objectp); if (objectp->mLocalID != entry->getLocalID()) { // Update local ID in object with the one sent from the region @@ -582,7 +579,8 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys, setUUIDAndLocal(fullid, local_id, gMessageSystem->getSenderIP(), - gMessageSystem->getSenderPort()); + gMessageSystem->getSenderPort(), + objectp); if (objectp->mLocalID != local_id) { // Update local ID in object with the one sent from the region @@ -1381,11 +1379,20 @@ void LLViewerObjectList::killObjects(LLViewerRegion *regionp) void LLViewerObjectList::killAllObjects() { // Used only on global destruction. - LLViewerObject *objectp; + // Mass cleanup to not clear lists one item at a time + mIndexAndLocalIDToUUID.clear(); + mActiveObjects.clear(); + mMapObjects.clear(); + + LLViewerObject *objectp; for (vobj_list_t::iterator iter = mObjects.begin(); iter != mObjects.end(); ++iter) { objectp = *iter; + objectp->setOnActiveList(false); + objectp->setListIndex(-1); + objectp->mRegionIndex = 0; + objectp->mOnMap = false; killObject(objectp); // Object must be dead, or it's the LLVOAvatarSelf which never dies. llassert((objectp == gAgentAvatarp) || objectp->isDead()); @@ -1398,18 +1405,6 @@ void LLViewerObjectList::killAllObjects() LL_WARNS() << "LLViewerObjectList::killAllObjects still has entries in mObjects: " << mObjects.size() << LL_ENDL; mObjects.clear(); } - - if (!mActiveObjects.empty()) - { - LL_WARNS() << "Some objects still on active object list!" << LL_ENDL; - mActiveObjects.clear(); - } - - if (!mMapObjects.empty()) - { - LL_WARNS() << "Some objects still on map object list!" << LL_ENDL; - mMapObjects.clear(); - } } void LLViewerObjectList::cleanDeadObjects(bool use_timer) @@ -1471,20 +1466,25 @@ void LLViewerObjectList::removeFromActiveList(LLViewerObject* objectp) { S32 idx = objectp->getListIndex(); if (idx != -1) - { //remove by moving last element to this object's position - llassert(mActiveObjects[idx] == objectp); - + { objectp->setListIndex(-1); - S32 last_index = static_cast<S32>(mActiveObjects.size()) - 1; - - if (idx != last_index) + S32 size = (S32)mActiveObjects.size(); + if (size > 0) // mActiveObjects could have been cleaned already { - mActiveObjects[idx] = mActiveObjects[last_index]; - mActiveObjects[idx]->setListIndex(idx); - } + // Remove by moving last element to this object's position - mActiveObjects.pop_back(); + llassert(idx < size); // idx should be always within mActiveObjects, unless killAllObjects was called + llassert(mActiveObjects[idx] == objectp); // object should be there + + S32 last_index = size - 1; + if (idx < last_index) + { + mActiveObjects[idx] = mActiveObjects[last_index]; + mActiveObjects[idx]->setListIndex(idx); + } // else assume it's the last element, no need to swap + mActiveObjects.pop_back(); + } } } @@ -1509,9 +1509,9 @@ void LLViewerObjectList::updateActive(LLViewerObject *objectp) mActiveObjects.push_back(objectp); objectp->setListIndex(static_cast<S32>(mActiveObjects.size()) - 1); objectp->setOnActiveList(true); - } - else - { + } + else + { llassert(idx < mActiveObjects.size()); llassert(mActiveObjects[idx] == objectp); @@ -1863,7 +1863,8 @@ LLViewerObject *LLViewerObjectList::createObjectFromCache(const LLPCode pcode, L setUUIDAndLocal(uuid, local_id, regionp->getHost().getAddress(), - regionp->getHost().getPort()); + regionp->getHost().getPort(), + objectp); mObjects.push_back(objectp); updateActive(objectp); @@ -1901,7 +1902,8 @@ LLViewerObject *LLViewerObjectList::createObject(const LLPCode pcode, LLViewerRe setUUIDAndLocal(fullid, local_id, gMessageSystem->getSenderIP(), - gMessageSystem->getSenderPort()); + gMessageSystem->getSenderPort(), + objectp); mObjects.push_back(objectp); diff --git a/indra/newview/llviewerobjectlist.h b/indra/newview/llviewerobjectlist.h index dc31995eb1..547ef9fb2d 100644 --- a/indra/newview/llviewerobjectlist.h +++ b/indra/newview/llviewerobjectlist.h @@ -179,9 +179,10 @@ public: void setUUIDAndLocal(const LLUUID &id, const U32 local_id, const U32 ip, - const U32 port); // Requires knowledge of message system info! + const U32 port, + LLViewerObject* objectp); // Requires knowledge of message system info! - bool removeFromLocalIDTable(const LLViewerObject* objectp); + bool removeFromLocalIDTable(LLViewerObject* objectp); // Used ONLY by the orphaned object code. U64 getIndex(const U32 local_id, const U32 ip, const U32 port); diff --git a/indra/newview/llvieweroctree.cpp b/indra/newview/llvieweroctree.cpp index b1673d2232..a1c2e0f9ff 100644 --- a/indra/newview/llvieweroctree.cpp +++ b/indra/newview/llvieweroctree.cpp @@ -1217,7 +1217,15 @@ void LLOcclusionCullingGroup::doOcclusion(LLCamera* camera, const LLVector4a* sh LLGLEnable clamp(use_depth_clamp ? GL_DEPTH_CLAMP : 0); - U32 mode = gGLManager.mGLVersion >= 3.3f ? GL_ANY_SAMPLES_PASSED : GL_SAMPLES_PASSED; + U32 mode = +#if GL_VERSION_1_5 + gGLManager.mGLVersion >= 3.3f ? +#endif + GL_ANY_SAMPLES_PASSED +#if GL_VERSION_1_5 + : GL_SAMPLES_PASSED +#endif + ; #if LL_TRACK_PENDING_OCCLUSION_QUERIES sPendingQueries.insert(mOcclusionQuery[LLViewerCamera::sCurCameraID]); diff --git a/indra/newview/llviewerparcelmgr.cpp b/indra/newview/llviewerparcelmgr.cpp index 8c24b2438b..8e6657b4b9 100644 --- a/indra/newview/llviewerparcelmgr.cpp +++ b/indra/newview/llviewerparcelmgr.cpp @@ -1824,6 +1824,16 @@ void LLViewerParcelMgr::processParcelProperties(LLMessageSystem *msg, void **use S32 bitmap_size = parcel_mgr.mParcelsPerEdge * parcel_mgr.mParcelsPerEdge / 8; + S32 size = msg->getSizeFast(_PREHASH_ParcelData, _PREHASH_Bitmap); + if (size != bitmap_size) + { + // Might be better to ignore bitmap and drop highlights + LL_WARNS("ParcelMgr") << "Parcel Bitmap size expected: " << bitmap_size + << " actual " << size + << ". Bitmap might be corrupted!" << LL_ENDL; + bitmap_size = size; + } + U8* bitmap = new U8[ bitmap_size ]; msg->getBinaryDataFast(_PREHASH_ParcelData, _PREHASH_Bitmap, bitmap, bitmap_size); diff --git a/indra/newview/llviewerparceloverlay.cpp b/indra/newview/llviewerparceloverlay.cpp index 2e9b5de72b..da03d3b015 100755 --- a/indra/newview/llviewerparceloverlay.cpp +++ b/indra/newview/llviewerparceloverlay.cpp @@ -581,7 +581,7 @@ void LLViewerParcelOverlay::addPropertyLine(F32 start_x, F32 start_y, F32 dx, F3 outside_y += dy * (dy - LINE_WIDTH); // Middle part, full width - const S32 GRID_STEP = S32( PARCEL_GRID_STEP_METERS ); + const S32 GRID_STEP = (S32)PARCEL_GRID_STEP_METERS; for (S32 i = 1; i < GRID_STEP; i++) { inside_z = land.resolveHeightRegion( inside_x, inside_y ); @@ -666,7 +666,9 @@ void LLViewerParcelOverlay::renderPropertyLines() return; LLSurface& land = mRegion->getLand(); - F32 water_z = land.getWaterHeight() + 0.01f; + + bool render_water = gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_WATER); + F32 water_z = render_water ? land.getWaterHeight() + 0.01f : 0; LLGLSUIDefault gls_ui; // called from pipeline gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); diff --git a/indra/newview/llviewerprecompiledheaders.h b/indra/newview/llviewerprecompiledheaders.h index a857887247..5700d8b278 100644 --- a/indra/newview/llviewerprecompiledheaders.h +++ b/indra/newview/llviewerprecompiledheaders.h @@ -29,22 +29,28 @@ #ifndef LL_LLVIEWERPRECOMPILEDHEADERS_H #define LL_LLVIEWERPRECOMPILEDHEADERS_H -#include "llwin32headers.h" - // This file MUST be the first one included by each .cpp file // in viewer. // It is used to precompile headers for improved build speed. #include "linden_common.h" +#include "llwin32headers.h" + #include <algorithm> #include <deque> #include <functional> +#include <list> #include <map> #include <set> #include <vector> +#include <string_view> +#include <unordered_map> +#include <unordered_set> // Library headers from llcommon project: +#include "apply.h" +#include "function_types.h" #include "indra_constants.h" #include "llinitparam.h" #include "llapp.h" @@ -54,8 +60,10 @@ #include "llerror.h" #include "llfasttimer.h" #include "llframetimer.h" +#include "llinstancetracker.h" #include "llpointer.h" #include "llprocessor.h" +#include "llrand.h" #include "llrefcount.h" #include "llsafehandle.h" #include "llsd.h" @@ -65,11 +73,13 @@ #include "llstring.h" #include "llsys.h" #include "lltimer.h" +#include "lluuid.h" #include "stdtypes.h" #include "u64.h" // Library includes from llmath project #include "llmath.h" +#include "llbbox.h" #include "llbboxlocal.h" #include "llcamera.h" #include "llcoord.h" @@ -77,9 +87,7 @@ #include "llcrc.h" #include "llplane.h" #include "llquantize.h" -#include "llrand.h" #include "llrect.h" -#include "lluuid.h" #include "m3math.h" #include "m4math.h" #include "llquaternion.h" @@ -91,11 +99,42 @@ #include "v4coloru.h" #include "v4math.h" #include "xform.h" +#include "llvector4a.h" +#include "llmatrix4a.h" +#include "lloctree.h" +#include "llvolume.h" +// Library includes from llfilesystem project #include "lldir.h" // Library includes from llmessage project +#include "llassetstorage.h" +#include "llavatarnamecache.h" #include "llcachename.h" +#include "llcorehttputil.h" + +// Library includes from llrender project +#include "llgl.h" +#include "llrender.h" + +// Library includes from llrender project +#include "llcharacter.h" + +// Library includes from llui project +#include "llnotifications.h" +#include "llpanel.h" +#include "llfloater.h" + +#include <boost/function.hpp> +#include <boost/signals2.hpp> +#include <boost/unordered_set.hpp> +#include <boost/unordered_map.hpp> +#include <boost/json.hpp> +#include "glm/glm.hpp" +#include "glm/gtc/type_ptr.hpp" +#include "glm/ext/quaternion_float.hpp" +#include "glm/gtx/quaternion.hpp" +#include "glm/gtx/matrix_decompose.hpp" #endif diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp index c21aeb1d57..697433148b 100755 --- a/indra/newview/llviewerregion.cpp +++ b/indra/newview/llviewerregion.cpp @@ -3239,6 +3239,7 @@ void LLViewerRegionImpl::buildCapabilityNames(LLSD& capabilityNames) capabilityNames.append("FetchInventory2"); capabilityNames.append("FetchInventoryDescendents2"); capabilityNames.append("IncrementCOFVersion"); + capabilityNames.append("RequestTaskInventory"); AISAPI::getCapNames(capabilityNames); capabilityNames.append("InterestList"); diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp index 5b4648a0bf..7ef13c3a35 100644 --- a/indra/newview/llviewershadermgr.cpp +++ b/indra/newview/llviewershadermgr.cpp @@ -101,6 +101,7 @@ LLGLSLShader gReflectionProbeDisplayProgram; LLGLSLShader gCopyProgram; LLGLSLShader gCopyDepthProgram; LLGLSLShader gPBRTerrainBakeProgram; +LLGLSLShader gDrawColorProgram; //object shaders LLGLSLShader gObjectPreviewProgram; @@ -113,7 +114,6 @@ LLGLSLShader gObjectAlphaMaskNoColorProgram; //environment shaders LLGLSLShader gWaterProgram; -LLGLSLShader gWaterEdgeProgram; LLGLSLShader gUnderWaterProgram; //interface shaders @@ -409,7 +409,6 @@ void LLViewerShaderMgr::finalizeShaderList() //ONLY shaders that need WL Param management should be added here mShaderList.push_back(&gAvatarProgram); mShaderList.push_back(&gWaterProgram); - mShaderList.push_back(&gWaterEdgeProgram); mShaderList.push_back(&gAvatarEyeballProgram); mShaderList.push_back(&gImpostorProgram); mShaderList.push_back(&gObjectBumpProgram); @@ -623,6 +622,8 @@ void LLViewerShaderMgr::setShaders() else { // "ShaderLoading" and "Shader" need to be logged + LL_WARNS("Shader") << "Failed loading basic shaders. Retrying with increased log level..." << LL_ENDL; + LLError::ELevel lvl = LLError::getDefaultLevel(); LLError::setDefaultLevel(LLError::LEVEL_DEBUG); loadBasicShaders(); @@ -843,7 +844,7 @@ std::string LLViewerShaderMgr::loadBasicShaders() // Note usage of GL_VERTEX_SHADER if (loadShaderFile(shaders[i].first, shaders[i].second, GL_VERTEX_SHADER, &attribs) == 0) { - LL_WARNS("Shader") << "Failed to load vertex shader " << shaders[i].first << LL_ENDL; + LL_WARNS("Shader") << "Failed to load basic vertex shader " << i << ": " << shaders[i].first << LL_ENDL; return shaders[i].first; } } @@ -874,6 +875,7 @@ std::string LLViewerShaderMgr::loadBasicShaders() index_channels.push_back(-1); shaders.push_back( make_pair( "deferred/shadowUtil.glsl", 1) ); index_channels.push_back(-1); shaders.push_back( make_pair( "deferred/aoUtil.glsl", 1) ); index_channels.push_back(-1); shaders.push_back( make_pair( "deferred/pbrterrainUtilF.glsl", 1) ); + index_channels.push_back(-1); shaders.push_back( make_pair( "deferred/tonemapUtilF.glsl", 1) ); index_channels.push_back(-1); shaders.push_back( make_pair( "deferred/reflectionProbeF.glsl", has_reflection_probes ? 3 : 2) ); index_channels.push_back(-1); shaders.push_back( make_pair( "deferred/screenSpaceReflUtil.glsl", ssr ? 3 : 1) ); index_channels.push_back(-1); shaders.push_back( make_pair( "lighting/lightNonIndexedF.glsl", mShaderLevel[SHADER_LIGHTING] ) ); @@ -906,7 +908,6 @@ bool LLViewerShaderMgr::loadShadersWater() if (mShaderLevel[SHADER_WATER] == 0) { gWaterProgram.unload(); - gWaterEdgeProgram.unload(); gUnderWaterProgram.unload(); return true; } @@ -920,6 +921,7 @@ bool LLViewerShaderMgr::loadShadersWater() gWaterProgram.mFeatures.hasGamma = true; gWaterProgram.mFeatures.hasSrgb = true; gWaterProgram.mFeatures.hasReflectionProbes = true; + gWaterProgram.mFeatures.hasTonemap = true; gWaterProgram.mFeatures.hasShadows = use_sun_shadow; gWaterProgram.mShaderFiles.clear(); gWaterProgram.mShaderFiles.push_back(make_pair("environment/waterV.glsl", GL_VERTEX_SHADER)); @@ -943,36 +945,6 @@ bool LLViewerShaderMgr::loadShadersWater() if (success) { - // load water shader - gWaterEdgeProgram.mName = "Water Edge Shader"; - gWaterEdgeProgram.mFeatures.calculatesAtmospherics = true; - gWaterEdgeProgram.mFeatures.hasAtmospherics = true; - gWaterEdgeProgram.mFeatures.hasGamma = true; - gWaterEdgeProgram.mFeatures.hasSrgb = true; - gWaterEdgeProgram.mFeatures.hasReflectionProbes = true; - gWaterEdgeProgram.mFeatures.hasShadows = use_sun_shadow; - gWaterEdgeProgram.mShaderFiles.clear(); - gWaterEdgeProgram.mShaderFiles.push_back(make_pair("environment/waterV.glsl", GL_VERTEX_SHADER)); - gWaterEdgeProgram.mShaderFiles.push_back(make_pair("environment/waterF.glsl", GL_FRAGMENT_SHADER)); - gWaterEdgeProgram.clearPermutations(); - gWaterEdgeProgram.addPermutation("WATER_EDGE", "1"); - if (LLPipeline::sRenderTransparentWater) - { - gWaterEdgeProgram.addPermutation("TRANSPARENT_WATER", "1"); - } - - if (use_sun_shadow) - { - gWaterEdgeProgram.addPermutation("HAS_SUN_SHADOW", "1"); - } - gWaterEdgeProgram.mShaderGroup = LLGLSLShader::SG_WATER; - gWaterEdgeProgram.mShaderLevel = mShaderLevel[SHADER_WATER]; - success = gWaterEdgeProgram.createShader(); - llassert(success); - } - - if (success) - { //load under water vertex shader gUnderWaterProgram.mName = "Underwater Shader"; gUnderWaterProgram.mFeatures.calculatesAtmospherics = true; @@ -2481,6 +2453,7 @@ bool LLViewerShaderMgr::loadShadersDeferred() gDeferredPostTonemapProgram.mName = "Deferred Tonemap Post Process"; gDeferredPostTonemapProgram.mFeatures.hasSrgb = true; gDeferredPostTonemapProgram.mFeatures.isDeferred = true; + gDeferredPostTonemapProgram.mFeatures.hasTonemap = true; gDeferredPostTonemapProgram.mShaderFiles.clear(); gDeferredPostTonemapProgram.clearPermutations(); gDeferredPostTonemapProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredNoTCV.glsl", GL_VERTEX_SHADER)); @@ -2495,6 +2468,7 @@ bool LLViewerShaderMgr::loadShadersDeferred() gNoPostTonemapProgram.mName = "No Post Tonemap Post Process"; gNoPostTonemapProgram.mFeatures.hasSrgb = true; gNoPostTonemapProgram.mFeatures.isDeferred = true; + gNoPostTonemapProgram.mFeatures.hasTonemap = true; gNoPostTonemapProgram.mShaderFiles.clear(); gNoPostTonemapProgram.clearPermutations(); gNoPostTonemapProgram.addPermutation("NO_POST", "1"); @@ -2588,10 +2562,10 @@ bool LLViewerShaderMgr::loadShadersDeferred() gSMAAEdgeDetectProgram[i].addPermutations(defines); gSMAAEdgeDetectProgram[i].mShaderFiles.clear(); - gSMAAEdgeDetectProgram[i].mShaderFiles.push_back(make_pair("deferred/SMAAEdgeDetectF.glsl", GL_FRAGMENT_SHADER_ARB)); - gSMAAEdgeDetectProgram[i].mShaderFiles.push_back(make_pair("deferred/SMAAEdgeDetectV.glsl", GL_VERTEX_SHADER_ARB)); - gSMAAEdgeDetectProgram[i].mShaderFiles.push_back(make_pair("deferred/SMAA.glsl", GL_FRAGMENT_SHADER_ARB)); - gSMAAEdgeDetectProgram[i].mShaderFiles.push_back(make_pair("deferred/SMAA.glsl", GL_VERTEX_SHADER_ARB)); + gSMAAEdgeDetectProgram[i].mShaderFiles.push_back(make_pair("deferred/SMAAEdgeDetectF.glsl", GL_FRAGMENT_SHADER)); + gSMAAEdgeDetectProgram[i].mShaderFiles.push_back(make_pair("deferred/SMAAEdgeDetectV.glsl", GL_VERTEX_SHADER)); + gSMAAEdgeDetectProgram[i].mShaderFiles.push_back(make_pair("deferred/SMAA.glsl", GL_FRAGMENT_SHADER)); + gSMAAEdgeDetectProgram[i].mShaderFiles.push_back(make_pair("deferred/SMAA.glsl", GL_VERTEX_SHADER)); gSMAAEdgeDetectProgram[i].mShaderLevel = mShaderLevel[SHADER_DEFERRED]; success = gSMAAEdgeDetectProgram[i].createShader(); // llassert(success); @@ -2614,10 +2588,10 @@ bool LLViewerShaderMgr::loadShadersDeferred() gSMAABlendWeightsProgram[i].addPermutations(defines); gSMAABlendWeightsProgram[i].mShaderFiles.clear(); - gSMAABlendWeightsProgram[i].mShaderFiles.push_back(make_pair("deferred/SMAABlendWeightsF.glsl", GL_FRAGMENT_SHADER_ARB)); - gSMAABlendWeightsProgram[i].mShaderFiles.push_back(make_pair("deferred/SMAABlendWeightsV.glsl", GL_VERTEX_SHADER_ARB)); - gSMAABlendWeightsProgram[i].mShaderFiles.push_back(make_pair("deferred/SMAA.glsl", GL_FRAGMENT_SHADER_ARB)); - gSMAABlendWeightsProgram[i].mShaderFiles.push_back(make_pair("deferred/SMAA.glsl", GL_VERTEX_SHADER_ARB)); + gSMAABlendWeightsProgram[i].mShaderFiles.push_back(make_pair("deferred/SMAABlendWeightsF.glsl", GL_FRAGMENT_SHADER)); + gSMAABlendWeightsProgram[i].mShaderFiles.push_back(make_pair("deferred/SMAABlendWeightsV.glsl", GL_VERTEX_SHADER)); + gSMAABlendWeightsProgram[i].mShaderFiles.push_back(make_pair("deferred/SMAA.glsl", GL_FRAGMENT_SHADER)); + gSMAABlendWeightsProgram[i].mShaderFiles.push_back(make_pair("deferred/SMAA.glsl", GL_VERTEX_SHADER)); gSMAABlendWeightsProgram[i].mShaderLevel = mShaderLevel[SHADER_DEFERRED]; success = gSMAABlendWeightsProgram[i].createShader(); // llassert(success); @@ -2640,10 +2614,10 @@ bool LLViewerShaderMgr::loadShadersDeferred() gSMAANeighborhoodBlendProgram[i].addPermutations(defines); gSMAANeighborhoodBlendProgram[i].mShaderFiles.clear(); - gSMAANeighborhoodBlendProgram[i].mShaderFiles.push_back(make_pair("deferred/SMAANeighborhoodBlendF.glsl", GL_FRAGMENT_SHADER_ARB)); - gSMAANeighborhoodBlendProgram[i].mShaderFiles.push_back(make_pair("deferred/SMAANeighborhoodBlendV.glsl", GL_VERTEX_SHADER_ARB)); - gSMAANeighborhoodBlendProgram[i].mShaderFiles.push_back(make_pair("deferred/SMAA.glsl", GL_FRAGMENT_SHADER_ARB)); - gSMAANeighborhoodBlendProgram[i].mShaderFiles.push_back(make_pair("deferred/SMAA.glsl", GL_VERTEX_SHADER_ARB)); + gSMAANeighborhoodBlendProgram[i].mShaderFiles.push_back(make_pair("deferred/SMAANeighborhoodBlendF.glsl", GL_FRAGMENT_SHADER)); + gSMAANeighborhoodBlendProgram[i].mShaderFiles.push_back(make_pair("deferred/SMAANeighborhoodBlendV.glsl", GL_VERTEX_SHADER)); + gSMAANeighborhoodBlendProgram[i].mShaderFiles.push_back(make_pair("deferred/SMAA.glsl", GL_FRAGMENT_SHADER)); + gSMAANeighborhoodBlendProgram[i].mShaderFiles.push_back(make_pair("deferred/SMAA.glsl", GL_VERTEX_SHADER)); gSMAANeighborhoodBlendProgram[i].mShaderLevel = mShaderLevel[SHADER_DEFERRED]; success = gSMAANeighborhoodBlendProgram[i].createShader(); // llassert(success); @@ -3353,6 +3327,17 @@ bool LLViewerShaderMgr::loadShadersInterface() success = gCopyDepthProgram.createShader(); } + if (success) + { + gDrawColorProgram.mName = "Draw Color Shader"; + gDrawColorProgram.mShaderFiles.clear(); + gDrawColorProgram.mShaderFiles.push_back(make_pair("objects/simpleNoAtmosV.glsl", GL_VERTEX_SHADER)); + gDrawColorProgram.mShaderFiles.push_back(make_pair("objects/simpleColorF.glsl", GL_FRAGMENT_SHADER)); + gDrawColorProgram.clearPermutations(); + gDrawColorProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT]; + success = gDrawColorProgram.createShader(); + } + if (gSavedSettings.getBOOL("LocalTerrainPaintEnabled")) { if (success) diff --git a/indra/newview/llviewershadermgr.h b/indra/newview/llviewershadermgr.h index b08796025a..7ad2da9464 100644 --- a/indra/newview/llviewershadermgr.h +++ b/indra/newview/llviewershadermgr.h @@ -175,6 +175,7 @@ extern LLGLSLShader gReflectionProbeDisplayProgram; extern LLGLSLShader gCopyProgram; extern LLGLSLShader gCopyDepthProgram; extern LLGLSLShader gPBRTerrainBakeProgram; +extern LLGLSLShader gDrawColorProgram; //output tex0[tc0] - tex1[tc1] extern LLGLSLShader gTwoTextureCompareProgram; @@ -191,7 +192,6 @@ extern LLGLSLShader gObjectAlphaMaskNoColorProgram; //environment shaders extern LLGLSLShader gWaterProgram; -extern LLGLSLShader gWaterEdgeProgram; extern LLGLSLShader gUnderWaterProgram; extern LLGLSLShader gGlowProgram; extern LLGLSLShader gGlowExtractProgram; diff --git a/indra/newview/llviewerstats.cpp b/indra/newview/llviewerstats.cpp index 73aabf49d1..ad503cbac7 100644 --- a/indra/newview/llviewerstats.cpp +++ b/indra/newview/llviewerstats.cpp @@ -774,6 +774,8 @@ void send_viewer_stats(bool include_preferences) LL_INFOS("LogViewerStatsPacket") << "Sending viewer statistics: " << body << LL_ENDL; + + // <ND> Do those lines even do anything sane in regard of debug logging? LL_DEBUGS("LogViewerStatsPacket"); std::string filename("viewer_stats_packet.xml"); llofstream of(filename.c_str()); diff --git a/indra/newview/llviewerstatsrecorder.cpp b/indra/newview/llviewerstatsrecorder.cpp index 58065ecce5..3e0e3b28f2 100644 --- a/indra/newview/llviewerstatsrecorder.cpp +++ b/indra/newview/llviewerstatsrecorder.cpp @@ -309,5 +309,3 @@ F32 LLViewerStatsRecorder::getTimeSinceStart() { return (F32) (LLFrameTimer::getTotalSeconds() - mFileOpenTime); } - - diff --git a/indra/newview/llviewertexture.cpp b/indra/newview/llviewertexture.cpp index 36b6787ace..4a9dd1c1b6 100644 --- a/indra/newview/llviewertexture.cpp +++ b/indra/newview/llviewertexture.cpp @@ -87,6 +87,7 @@ S32 LLViewerTexture::sRawCount = 0; S32 LLViewerTexture::sAuxCount = 0; LLFrameTimer LLViewerTexture::sEvaluationTimer; F32 LLViewerTexture::sDesiredDiscardBias = 0.f; +U32 LLViewerTexture::sBiasTexturesUpdated = 0; S32 LLViewerTexture::sMaxSculptRez = 128; //max sculpt image size constexpr S32 MAX_CACHED_RAW_IMAGE_AREA = 64 * 64; @@ -107,12 +108,6 @@ LLViewerTexture::EDebugTexels LLViewerTexture::sDebugTexelsMode = LLViewerTextur const F64 log_2 = log(2.0); -#if ADDRESS_SIZE == 32 -const U32 DESIRED_NORMAL_TEXTURE_SIZE = (U32)LLViewerFetchedTexture::MAX_IMAGE_SIZE_DEFAULT / 2; -#else -const U32 DESIRED_NORMAL_TEXTURE_SIZE = (U32)LLViewerFetchedTexture::MAX_IMAGE_SIZE_DEFAULT; -#endif - //---------------------------------------------------------------------------------------------- //namespace: LLViewerTextureAccess //---------------------------------------------------------------------------------------------- @@ -494,7 +489,12 @@ void LLViewerTexture::updateClass() } LLViewerMediaTexture::updateClass(); - + // This is a divisor used to determine how much VRAM from our overall VRAM budget to use. + // This is **cumulative** on whatever the detected or manually set VRAM budget is. + // If we detect 2048MB of VRAM, this will, by default, only use 1024. + // If you set 1024MB of VRAM, this will, by default, use 512. + // -Geenz 2025-03-03 + static LLCachedControl<U32> tex_vram_divisor(gSavedSettings, "RenderTextureVRAMDivisor", 2); static LLCachedControl<U32> max_vram_budget(gSavedSettings, "RenderMaxVRAMBudget", 0); F64 texture_bytes_alloc = LLImageGL::getTextureBytesAllocated() / 1024.0 / 512.0; @@ -504,7 +504,11 @@ void LLViewerTexture::updateClass() // NOTE: our metrics miss about half the vram we use, so this biases high but turns out to typically be within 5% of the real number F32 used = (F32)ll_round(texture_bytes_alloc + vertex_bytes_alloc); - F32 budget = max_vram_budget == 0 ? (F32)gGLManager.mVRAM : (F32)max_vram_budget; + // For debugging purposes, it's useful to be able to set the VRAM budget manually. + // But when manual control is not enabled, use the VRAM divisor. + // While we're at it, assume we have 1024 to play with at minimum when the divisor is in use. Works more elegantly with the logic below this. + // -Geenz 2025-03-21 + F32 budget = max_vram_budget == 0 ? llmax(1024, (F32)gGLManager.mVRAM / tex_vram_divisor) : (F32)max_vram_budget; // Try to leave at least half a GB for everyone else and for bias, // but keep at least 768MB for ourselves @@ -556,18 +560,20 @@ void LLViewerTexture::updateClass() // don't execute above until the slam to 1.5 has a chance to take effect sEvaluationTimer.reset(); - // lower discard bias over time when free memory is available - if (sDesiredDiscardBias > 1.f && over_pct < 0.f) + // lower discard bias over time when at least 10% of budget is free + const F32 FREE_PERCENTAGE_TRESHOLD = -0.1f; + if (sDesiredDiscardBias > 1.f && over_pct < FREE_PERCENTAGE_TRESHOLD) { static LLCachedControl<F32> high_mem_discard_decrement(gSavedSettings, "RenderHighMemMinDiscardDecrement", .1f); - F32 decrement = high_mem_discard_decrement - llmin(over_pct, 0.f); + F32 decrement = high_mem_discard_decrement - llmin(over_pct - FREE_PERCENTAGE_TRESHOLD, 0.f); sDesiredDiscardBias -= decrement * gFrameIntervalSeconds; } } // set to max discard bias if the window has been backgrounded for a while static F32 last_desired_discard_bias = 1.f; + static F32 last_texture_update_count_bias = 1.f; static bool was_backgrounded = false; static LLFrameTimer backgrounded_timer; static LLCachedControl<F32> minimized_discard_time(gSavedSettings, "TextureDiscardMinimizedTime", 1.f); @@ -603,6 +609,21 @@ void LLViewerTexture::updateClass() } sDesiredDiscardBias = llclamp(sDesiredDiscardBias, 1.f, 4.f); + if (last_texture_update_count_bias < sDesiredDiscardBias) + { + // bias increased, reset texture update counter to + // let updates happen at an increased rate. + last_texture_update_count_bias = sDesiredDiscardBias; + sBiasTexturesUpdated = 0; + } + else if (last_texture_update_count_bias > sDesiredDiscardBias + 0.1f) + { + // bias decreased, 0.1f is there to filter out small fluctuations + // and not reset sBiasTexturesUpdated too often. + // Bias jumps to 1.5 at low memory, so getting stuck at 1.1 is not + // a problem. + last_texture_update_count_bias = sDesiredDiscardBias; + } LLViewerTexture::sFreezeImageUpdates = false; } @@ -1685,6 +1706,16 @@ void LLViewerFetchedTexture::processTextureStats() static LLCachedControl<bool> textures_fullres(gSavedSettings,"TextureLoadFullRes", false); + U32 max_tex_res = MAX_IMAGE_SIZE_DEFAULT; + if (mBoostLevel < LLGLTexture::BOOST_HIGH) + { + // restrict texture resolution to download based on RenderMaxTextureResolution + static LLCachedControl<U32> max_texture_resolution(gSavedSettings, "RenderMaxTextureResolution", 2048); + // sanity clamp debug setting to avoid settings hack shenanigans + max_tex_res = (U32)llclamp((U32)max_texture_resolution, 512, MAX_IMAGE_SIZE_DEFAULT); + mMaxVirtualSize = llmin(mMaxVirtualSize, (F32)(max_tex_res * max_tex_res)); + } + if (textures_fullres) { mDesiredDiscardLevel = 0; @@ -1706,10 +1737,9 @@ void LLViewerFetchedTexture::processTextureStats() } else { - U32 desired_size = MAX_IMAGE_SIZE_DEFAULT; // MAX_IMAGE_SIZE_DEFAULT = 2048 and max size ever is 4096 if(!mKnownDrawWidth || !mKnownDrawHeight || (S32)mFullWidth <= mKnownDrawWidth || (S32)mFullHeight <= mKnownDrawHeight) { - if (mFullWidth > desired_size || mFullHeight > desired_size) + if (mFullWidth > max_tex_res || mFullHeight > max_tex_res) { mDesiredDiscardLevel = 1; } @@ -2913,8 +2943,6 @@ LLViewerLODTexture::LLViewerLODTexture(const std::string& url, FTType f_type, co void LLViewerLODTexture::init(bool firstinit) { mTexelsPerImage = 64*64; - mDiscardVirtualSize = 0.f; - mCalculatedDiscardLevel = -1.f; } //virtual @@ -2939,12 +2967,14 @@ void LLViewerLODTexture::processTextureStats() static LLCachedControl<bool> textures_fullres(gSavedSettings,"TextureLoadFullRes", false); - { // restrict texture resolution to download based on RenderMaxTextureResolution + F32 max_tex_res = MAX_IMAGE_SIZE_DEFAULT; + if (mBoostLevel < LLGLTexture::BOOST_HIGH) + { + // restrict texture resolution to download based on RenderMaxTextureResolution static LLCachedControl<U32> max_texture_resolution(gSavedSettings, "RenderMaxTextureResolution", 2048); // sanity clamp debug setting to avoid settings hack shenanigans - F32 tex_res = (F32)llclamp((S32)max_texture_resolution, 512, 2048); - tex_res *= tex_res; - mMaxVirtualSize = llmin(mMaxVirtualSize, tex_res); + max_tex_res = (F32)llclamp((S32)max_texture_resolution, 512, MAX_IMAGE_SIZE_DEFAULT); + mMaxVirtualSize = llmin(mMaxVirtualSize, max_tex_res * max_tex_res); } if (textures_fullres) @@ -2993,19 +3023,12 @@ void LLViewerLODTexture::processTextureStats() { // Calculate the required scale factor of the image using pixels per texel discard_level = (F32)(log(mTexelsPerImage / mMaxVirtualSize) / log_4); - mDiscardVirtualSize = mMaxVirtualSize; - mCalculatedDiscardLevel = discard_level; } discard_level = floorf(discard_level); F32 min_discard = 0.f; - U32 desired_size = MAX_IMAGE_SIZE_DEFAULT; // MAX_IMAGE_SIZE_DEFAULT = 2048 and max size ever is 4096 - if (mBoostLevel <= LLGLTexture::BOOST_SCULPTED) - { - desired_size = DESIRED_NORMAL_TEXTURE_SIZE; - } - if (mFullWidth > desired_size || mFullHeight > desired_size) + if (mFullWidth > max_tex_res || mFullHeight > max_tex_res) min_discard = 1.f; discard_level = llclamp(discard_level, min_discard, (F32)MAX_DISCARD_LEVEL); @@ -3543,18 +3566,7 @@ void LLViewerMediaTexture::setPlaying(bool playing) for(std::list< LLFace* >::iterator iter = mMediaFaceList.begin(); iter!= mMediaFaceList.end(); ++iter) { LLFace* facep = *iter; - const LLTextureEntry* te = facep->getTextureEntry(); - if (te->getGLTFMaterial()) - { - // PBR material, switch emissive and basecolor - switchTexture(LLRender::EMISSIVE_MAP, *iter); - switchTexture(LLRender::BASECOLOR_MAP, *iter); - } - else - { - // blinn-phong material, switch diffuse map only - switchTexture(LLRender::DIFFUSE_MAP, *iter); - } + switchTexture(LLRender::DIFFUSE_MAP, facep); } } else //stop playing this media diff --git a/indra/newview/llviewertexture.h b/indra/newview/llviewertexture.h index 4241ef958f..e1582c74bd 100644 --- a/indra/newview/llviewertexture.h +++ b/indra/newview/llviewertexture.h @@ -220,6 +220,7 @@ public: static S32 sAuxCount; static LLFrameTimer sEvaluationTimer; static F32 sDesiredDiscardBias; + static U32 sBiasTexturesUpdated; static S32 sMaxSculptRez ; static U32 sMinLargeImageSize ; static U32 sMaxSmallImageSize ; @@ -540,10 +541,6 @@ public: private: void init(bool firstinit) ; - -private: - F32 mDiscardVirtualSize; // Virtual size used to calculate desired discard - F32 mCalculatedDiscardLevel; // Last calculated discard level }; // diff --git a/indra/newview/llviewertexturelist.cpp b/indra/newview/llviewertexturelist.cpp index 0b79c2d8e0..40daac887d 100644 --- a/indra/newview/llviewertexturelist.cpp +++ b/indra/newview/llviewertexturelist.cpp @@ -30,6 +30,7 @@ #include "llviewertexturelist.h" +#include "llagent.h" #include "llgl.h" // fot gathering stats from GL #include "llimagegl.h" #include "llimagebmp.h" @@ -176,15 +177,25 @@ void LLViewerTextureList::doPreloadImages() image->setAddressMode(LLTexUnit::TAM_WRAP); mImagePreloads.insert(image); } +#if GL_VERSION_1_1 image = LLViewerTextureManager::getFetchedTextureFromFile("alpha_gradient.tga", FTT_LOCAL_FILE, MIPMAP_YES, LLViewerFetchedTexture::BOOST_UI, LLViewerTexture::FETCHED_TEXTURE, GL_ALPHA8, GL_ALPHA, IMG_ALPHA_GRAD); +#else + image = LLViewerTextureManager::getFetchedTextureFromFile("alpha_gradient.tga", FTT_LOCAL_FILE, MIPMAP_YES, LLViewerFetchedTexture::BOOST_UI, LLViewerTexture::FETCHED_TEXTURE, + GL_ALPHA8_EXT, GL_ALPHA, IMG_ALPHA_GRAD); +#endif if (image) { image->setAddressMode(LLTexUnit::TAM_CLAMP); mImagePreloads.insert(image); } +#if GL_VERSION_1_1 image = LLViewerTextureManager::getFetchedTextureFromFile("alpha_gradient_2d.j2c", FTT_LOCAL_FILE, MIPMAP_YES, LLViewerFetchedTexture::BOOST_UI, LLViewerTexture::FETCHED_TEXTURE, GL_ALPHA8, GL_ALPHA, IMG_ALPHA_GRAD_2D); +#else + image = LLViewerTextureManager::getFetchedTextureFromFile("alpha_gradient_2d.j2c", FTT_LOCAL_FILE, MIPMAP_YES, LLViewerFetchedTexture::BOOST_UI, LLViewerTexture::FETCHED_TEXTURE, + GL_ALPHA8_EXT, GL_ALPHA, IMG_ALPHA_GRAD_2D); +#endif if (image) { image->setAddressMode(LLTexUnit::TAM_CLAMP); @@ -266,7 +277,7 @@ void LLViewerTextureList::doPrefetchImages() S32 pixel_area = imagesd["area"]; S32 texture_type = imagesd["type"]; - if(LLViewerTexture::FETCHED_TEXTURE == texture_type || LLViewerTexture::LOD_TEXTURE == texture_type) + if((LLViewerTexture::FETCHED_TEXTURE == texture_type || LLViewerTexture::LOD_TEXTURE == texture_type)) { LLViewerFetchedTexture* image = LLViewerTextureManager::getFetchedTexture(uuid, FTT_DEFAULT, MIPMAP_TRUE, LLGLTexture::BOOST_NONE, texture_type); if (image) @@ -815,10 +826,19 @@ void LLViewerTextureList::updateImages(F32 max_time) clearFetchingRequests(); gPipeline.clearRebuildGroups(); cleared = true; + return; + } + // ARRIVING is a delay to let things decode, cache and process, + // so process textures like normal despite gTeleportDisplay + if (gAgent.getTeleportState() != LLAgent::TELEPORT_ARRIVING) + { + return; } - return; } - cleared = false; + else + { + cleared = false; + } LLAppViewer::getTextureFetch()->setTextureBandwidth((F32)LLTrace::get_frame_recording().getPeriodMeanPerSec(LLStatViewer::TEXTURE_NETWORK_DATA_RECEIVED).value()); @@ -889,9 +909,12 @@ void LLViewerTextureList::updateImageDecodePriority(LLViewerFetchedTexture* imag { llassert(!gCubeSnapshot); + constexpr F32 BIAS_TRS_OUT_OF_SCREEN = 1.5f; + constexpr F32 BIAS_TRS_ON_SCREEN = 1.f; + if (imagep->getBoostLevel() < LLViewerFetchedTexture::BOOST_HIGH) // don't bother checking face list for boosted textures { - static LLCachedControl<F32> texture_scale_min(gSavedSettings, "TextureScaleMinAreaFactor", 0.04f); + static LLCachedControl<F32> texture_scale_min(gSavedSettings, "TextureScaleMinAreaFactor", 0.0095f); static LLCachedControl<F32> texture_scale_max(gSavedSettings, "TextureScaleMaxAreaFactor", 25.f); F32 max_vsize = 0.f; @@ -900,7 +923,8 @@ void LLViewerTextureList::updateImageDecodePriority(LLViewerFetchedTexture* imag U32 face_count = 0; // get adjusted bias based on image resolution - F32 max_discard = F32(imagep->getMaxDiscardLevel()); + LLImageGL* img = imagep->getGLTexture(); + F32 max_discard = F32(img ? img->getMaxDiscardLevel() : MAX_DISCARD_LEVEL); F32 bias = llclamp(max_discard - 2.f, 1.f, LLViewerTexture::sDesiredDiscardBias); // convert bias into a vsize scaler @@ -929,12 +953,13 @@ void LLViewerTextureList::updateImageDecodePriority(LLViewerFetchedTexture* imag F32 vsize = face->getPixelArea(); - on_screen = face->mInFrustum; + on_screen |= face->mInFrustum; // Scale desired texture resolution higher or lower depending on texture scale // - // Minimum usage examples: a 1024x1024 texture with aplhabet, runing string - // shows one letter at a time + // Minimum usage examples: a 1024x1024 texture with aplhabet (texture atlas), + // runing string shows one letter at a time. If texture has ten 100px symbols + // per side, minimal scale is (100/1024)^2 = 0.0095 // // Maximum usage examples: huge chunk of terrain repeats texture // TODO: make this work with the GLTF texture transforms @@ -946,7 +971,8 @@ void LLViewerTextureList::updateImageDecodePriority(LLViewerFetchedTexture* imag vsize /= min_scale; // apply bias to offscreen faces all the time, but only to onscreen faces when bias is large - if (!face->mInFrustum || LLViewerTexture::sDesiredDiscardBias > 2.f) + // use mImportanceToCamera to make bias switch a bit more gradual + if (!face->mInFrustum || LLViewerTexture::sDesiredDiscardBias > 1.9f + face->mImportanceToCamera / 2.f) { vsize /= bias; } @@ -959,14 +985,28 @@ void LLViewerTextureList::updateImageDecodePriority(LLViewerFetchedTexture* imag } max_vsize = llmax(max_vsize, vsize); + + // addTextureStats limits size to sMaxVirtualSize + if (max_vsize >= LLViewerFetchedTexture::sMaxVirtualSize + && (on_screen || LLViewerTexture::sDesiredDiscardBias <= BIAS_TRS_ON_SCREEN)) + { + break; + } } } + + if (max_vsize >= LLViewerFetchedTexture::sMaxVirtualSize + && (on_screen || LLViewerTexture::sDesiredDiscardBias <= BIAS_TRS_ON_SCREEN)) + { + break; + } } if (face_count > 1024) { // this texture is used in so many places we should just boost it and not bother checking its vsize // this is especially important because the above is not time sliced and can hit multiple ms for a single texture imagep->setBoostLevel(LLViewerFetchedTexture::BOOST_HIGH); + // Do we ever remove it? This also sets texture nodelete! } if (imagep->getType() == LLViewerTexture::LOD_TEXTURE && imagep->getBoostLevel() == LLViewerTexture::BOOST_NONE) @@ -974,8 +1014,8 @@ void LLViewerTextureList::updateImageDecodePriority(LLViewerFetchedTexture* imag // this is an alternative to decaying mMaxVirtualSize over time // that keeps textures from continously downrezzing and uprezzing in the background - if (LLViewerTexture::sDesiredDiscardBias > 1.5f || - (!on_screen && LLViewerTexture::sDesiredDiscardBias > 1.f)) + if (LLViewerTexture::sDesiredDiscardBias > BIAS_TRS_OUT_OF_SCREEN || + (!on_screen && LLViewerTexture::sDesiredDiscardBias > BIAS_TRS_ON_SCREEN)) { imagep->mMaxVirtualSize = 0.f; } @@ -1081,7 +1121,8 @@ F32 LLViewerTextureList::updateImagesCreateTextures(F32 max_time) imagep->mCreatePending = false; mCreateTextureList.pop(); - if (imagep->hasGLTexture() && imagep->getDiscardLevel() < imagep->getDesiredDiscardLevel()) + if (imagep->hasGLTexture() && imagep->getDiscardLevel() < imagep->getDesiredDiscardLevel() && + (imagep->getDesiredDiscardLevel() <= MAX_DISCARD_LEVEL)) { // NOTE: this may happen if the desired discard reduces while a decode is in progress and does not // necessarily indicate a problem, but if log occurrences excede that of dsiplay_stats: FPS, @@ -1198,10 +1239,17 @@ F32 LLViewerTextureList::updateImagesFetchTextures(F32 max_time) //update MIN_UPDATE_COUNT or 5% of other textures, whichever is greater update_count = llmax((U32) MIN_UPDATE_COUNT, (U32) mUUIDMap.size()/20); - if (LLViewerTexture::sDesiredDiscardBias > 1.f) + if (LLViewerTexture::sDesiredDiscardBias > 1.f + && LLViewerTexture::sBiasTexturesUpdated < (U32)mUUIDMap.size()) { - // we are over memory target, update more agresively + // We are over memory target. Bias affects discard rates, so update + // existing textures agresively to free memory faster. update_count = (S32)(update_count * LLViewerTexture::sDesiredDiscardBias); + + // This isn't particularly precise and can overshoot, but it doesn't need + // to be, just making sure it did a full circle and doesn't get stuck updating + // at bias = 4 with 4 times the rate permanently. + LLViewerTexture::sBiasTexturesUpdated += update_count; } update_count = llmin(update_count, (U32) mUUIDMap.size()); diff --git a/indra/newview/llviewerthrottle.cpp b/indra/newview/llviewerthrottle.cpp index b0a00c29a4..8d935e4243 100644 --- a/indra/newview/llviewerthrottle.cpp +++ b/indra/newview/llviewerthrottle.cpp @@ -48,6 +48,8 @@ const F32 MIN_FRACTIONAL = 0.2f; const F32 MIN_BANDWIDTH = 50.f; const F32 MAX_BANDWIDTH = 6000.f; const F32 STEP_FRACTIONAL = 0.1f; +const F32 HIGH_BUFFER_LOAD_TRESHOLD = 1.f; +const F32 LOW_BUFFER_LOAD_TRESHOLD = 0.8f; const LLUnit<F32, LLUnits::Percent> TIGHTEN_THROTTLE_THRESHOLD(3.0f); // packet loss % per s const LLUnit<F32, LLUnits::Percent> EASE_THROTTLE_THRESHOLD(0.5f); // packet loss % per s const F32 DYNAMIC_UPDATE_DURATION = 5.0f; // seconds @@ -146,7 +148,7 @@ LLViewerThrottleGroup LLViewerThrottleGroup::operator-(const LLViewerThrottleGro void LLViewerThrottleGroup::sendToSim() const { - LL_INFOS() << "Sending throttle settings, total BW " << mThrottleTotal << LL_ENDL; + LL_DEBUGS("Throttle") << "Sending throttle settings, total BW " << mThrottleTotal << LL_ENDL; LLMessageSystem* msg = gMessageSystem; msg->newMessageFast(_PREHASH_AgentThrottle); @@ -305,7 +307,10 @@ void LLViewerThrottle::updateDynamicThrottle() mUpdateTimer.reset(); LLUnit<F32, LLUnits::Percent> mean_packets_lost = LLViewerStats::instance().getRecording().getMean(LLStatViewer::PACKETS_LOST_PERCENT); - if (mean_packets_lost > TIGHTEN_THROTTLE_THRESHOLD) + if ( + mean_packets_lost > TIGHTEN_THROTTLE_THRESHOLD // already losing packets + || mBufferLoadRate >= HIGH_BUFFER_LOAD_TRESHOLD // let viewer sort through the backlog before it starts dropping packets + ) { if (mThrottleFrac <= MIN_FRACTIONAL || mCurrentBandwidth / 1024.0f <= MIN_BANDWIDTH) { @@ -318,7 +323,8 @@ void LLViewerThrottle::updateDynamicThrottle() mCurrent.sendToSim(); LL_INFOS() << "Tightening network throttle to " << mCurrentBandwidth << LL_ENDL; } - else if (mean_packets_lost <= EASE_THROTTLE_THRESHOLD) + else if (mean_packets_lost <= EASE_THROTTLE_THRESHOLD + && mBufferLoadRate < LOW_BUFFER_LOAD_TRESHOLD) { if (mThrottleFrac >= MAX_FRACTIONAL || mCurrentBandwidth / 1024.0f >= MAX_BANDWIDTH) { @@ -331,4 +337,6 @@ void LLViewerThrottle::updateDynamicThrottle() mCurrent.sendToSim(); LL_INFOS() << "Easing network throttle to " << mCurrentBandwidth << LL_ENDL; } + + mBufferLoadRate = 0; } diff --git a/indra/newview/llviewerthrottle.h b/indra/newview/llviewerthrottle.h index 28a24d04fc..9973c88549 100644 --- a/indra/newview/llviewerthrottle.h +++ b/indra/newview/llviewerthrottle.h @@ -70,12 +70,15 @@ public: void updateDynamicThrottle(); void resetDynamicThrottle(); + void setBufferLoadRate(F32 rate) { mBufferLoadRate = llmax(mBufferLoadRate, rate); } + LLViewerThrottleGroup getThrottleGroup(const F32 bandwidth_kbps); static const std::string sNames[TC_EOF]; protected: F32 mMaxBandwidth; F32 mCurrentBandwidth; + F32 mBufferLoadRate = 0; LLViewerThrottleGroup mCurrent; diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index 8a5aac9b8b..ef6409c23b 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -66,6 +66,7 @@ #include "llchatentry.h" #include "indra_constants.h" #include "llassetstorage.h" +#include "lldate.h" #include "llerrorcontrol.h" #include "llfontgl.h" #include "llmousehandler.h" @@ -79,14 +80,12 @@ #include "message.h" #include "object_flags.h" #include "lltimer.h" -#include "llviewermenu.h" #include "lltooltip.h" #include "llmediaentry.h" #include "llurldispatcher.h" #include "raytrace.h" // newview includes -#include "llagent.h" #include "llbox.h" #include "llchicletbar.h" #include "llconsole.h" @@ -118,7 +117,6 @@ #include "llfontfreetype.h" #include "llgesturemgr.h" #include "llglheaders.h" -#include "lltooltip.h" #include "llhudmanager.h" #include "llhudobject.h" #include "llhudview.h" @@ -133,7 +131,6 @@ #include "llmorphview.h" #include "llmoveview.h" #include "llnavigationbar.h" -#include "llnotificationhandler.h" #include "llpaneltopinfobar.h" #include "llpopupview.h" #include "llpreviewtexture.h" @@ -166,17 +163,13 @@ #include "lltoolselectland.h" #include "lltrans.h" #include "lluictrlfactory.h" -#include "llurldispatcher.h" // SLURL from other app instance #include "llversioninfo.h" #include "llvieweraudio.h" -#include "llviewercamera.h" #include "llviewergesture.h" #include "llviewertexturelist.h" #include "llviewerinventory.h" -#include "llviewerinput.h" #include "llviewermedia.h" #include "llviewermediafocus.h" -#include "llviewermenu.h" #include "llviewermessage.h" #include "llviewerobjectlist.h" #include "llviewerparcelmgr.h" @@ -210,7 +203,6 @@ #include "llwindowlistener.h" #include "llviewerwindowlistener.h" -#include "llpaneltopinfobar.h" #include "llcleanup.h" #if LL_WINDOWS @@ -497,7 +489,8 @@ public: clearText(); - if (gSavedSettings.getBOOL("DebugShowTime")) + static LLCachedControl<bool> debug_show_time(gSavedSettings, "DebugShowTime", false); + if (debug_show_time()) { F32 time = gFrameTimeSeconds; S32 hours = (S32)(time / (60*60)); @@ -506,7 +499,8 @@ public: addText(xpos, ypos, llformat("Time: %d:%02d:%02d", hours,mins,secs)); ypos += y_inc; } - if (gSavedSettings.getBOOL("DebugShowMemory")) + static LLCachedControl<bool> debug_show_memory(gSavedSettings, "DebugShowMemory", false); + if (debug_show_memory()) { addText(xpos, ypos, STRINGIZE("Memory: " << (LLMemory::getCurrentRSS() / 1024) << " (KB)")); @@ -599,7 +593,8 @@ public: ypos += y_inc; }*/ - if (gSavedSettings.getBOOL("DebugShowRenderInfo")) + static LLCachedControl<bool> debug_show_render_info(gSavedSettings, "DebugShowRenderInfo", false); + if (debug_show_render_info()) { LLTrace::Recording& last_frame_recording = LLTrace::get_frame_recording().getLastRecording(); @@ -738,7 +733,8 @@ public: gPipeline.mNumVisibleNodes = LLPipeline::sVisibleLightCount = 0; } - if (gSavedSettings.getBOOL("DebugShowAvatarRenderInfo")) + static LLCachedControl<bool> debug_show_avatar_render_info(gSavedSettings, "DebugShowAvatarRenderInfo", false); + if (debug_show_avatar_render_info()) { std::map<std::string, LLVOAvatar*> sorted_avs; { @@ -771,7 +767,8 @@ public: av_iter++; } } - if (gSavedSettings.getBOOL("DebugShowRenderMatrices")) + static LLCachedControl<bool> debug_show_render_matrices(gSavedSettings, "DebugShowRenderMatrices", false); + if (debug_show_render_matrices()) { char camera_lines[8][32]; memset(camera_lines, ' ', sizeof(camera_lines)); @@ -797,7 +794,8 @@ public: ypos += y_inc; } // disable use of glReadPixels which messes up nVidia nSight graphics debugging - if (gSavedSettings.getBOOL("DebugShowColor") && !LLRender::sNsightDebugSupport) + static LLCachedControl<bool> debug_show_color(gSavedSettings, "DebugShowColor", false); + if (debug_show_color() && !LLRender::sNsightDebugSupport) { U8 color[4]; LLCoordGL coord = gViewerWindow->getCurrentMouse(); @@ -889,7 +887,8 @@ public: } } - if (gSavedSettings.getBOOL("DebugShowTextureInfo")) + static LLCachedControl<bool> debug_show_texture_info(gSavedSettings, "DebugShowTextureInfo", false); + if (debug_show_texture_info()) { LLViewerObject* objectp = NULL ; @@ -1331,7 +1330,7 @@ LLWindowCallbacks::DragNDropResult LLViewerWindow::handleDragNDrop( LLWindow *wi // Check the whitelist, if there's media (otherwise just show it) if (te->getMediaData() == NULL || te->getMediaData()->checkCandidateUrl(url)) { - if ( obj != mDragHoveredObject) + if ( obj != mDragHoveredObject.get()) { // Highlight the dragged object LLSelectMgr::getInstance()->unhighlightObjectOnly(mDragHoveredObject); @@ -1458,10 +1457,13 @@ void LLViewerWindow::handleMouseLeave(LLWindow *window) bool LLViewerWindow::handleCloseRequest(LLWindow *window) { - // User has indicated they want to close, but we may need to ask - // about modified documents. - LLAppViewer::instance()->userQuit(); - // Don't quit immediately + if (!LLApp::isExiting() && !LLApp::isStopped()) + { + // User has indicated they want to close, but we may need to ask + // about modified documents. + LLAppViewer::instance()->userQuit(); + // Don't quit immediately + } return false; } @@ -1605,7 +1607,8 @@ bool LLViewerWindow::handleActivate(LLWindow *window, bool activated) mActive = false; // if the user has chosen to go Away automatically after some time, then go Away when minimizing - if (gSavedSettings.getS32("AFKTimeout")) + static LLCachedControl<S32> afk_time(gSavedSettings, "AFKTimeout", 300); + if (afk_time()) { gAgent.setAFK(); } @@ -1746,6 +1749,7 @@ bool LLViewerWindow::handleDeviceChange(LLWindow *window) bool LLViewerWindow::handleDPIChanged(LLWindow *window, F32 ui_scale_factor, S32 window_width, S32 window_height) { + LLFontGL::sResolutionGeneration++; if (ui_scale_factor >= MIN_UI_SCALE && ui_scale_factor <= MAX_UI_SCALE) { LLViewerWindow::reshape(window_width, window_height); @@ -1759,6 +1763,12 @@ bool LLViewerWindow::handleDPIChanged(LLWindow *window, F32 ui_scale_factor, S32 } } +bool LLViewerWindow::handleDisplayChanged() +{ + LLFontGL::sResolutionGeneration++; + return false; +} + bool LLViewerWindow::handleWindowDidChangeScreen(LLWindow *window) { LLCoordScreen window_rect; @@ -1927,6 +1937,7 @@ LLViewerWindow::LLViewerWindow(const Params& p) mDisplayScale.setVec(llmax(1.f / mWindow->getPixelAspectRatio(), 1.f), llmax(mWindow->getPixelAspectRatio(), 1.f)); mDisplayScale *= ui_scale_factor; LLUI::setScaleFactor(mDisplayScale); + LLFontGL::sResolutionGeneration++; { LLCoordWindow size; @@ -2009,6 +2020,8 @@ LLViewerWindow::LLViewerWindow(const Params& p) mDebugText = new LLDebugText(this); mWorldViewRectScaled = calcScaledRect(mWorldViewRectRaw, mDisplayScale); + + mWindow->toggleVSync(gSavedSettings.getBOOL("RenderVSyncEnabled")); } std::string LLViewerWindow::getLastSnapshotDir() @@ -2494,6 +2507,7 @@ void LLViewerWindow::reshape(S32 width, S32 height) bool display_scale_changed = mDisplayScale != LLUI::getScaleFactor(); LLUI::setScaleFactor(mDisplayScale); + LLFontGL::sResolutionGeneration++; // update our window rectangle mWindowRectScaled.mRight = mWindowRectScaled.mLeft + ll_round((F32)width / mDisplayScale.mV[VX]); @@ -4797,26 +4811,23 @@ void LLViewerWindow::saveImageLocal(LLImageFormatted *image, const snapshot_save } // Look for an unused file name - bool is_snapshot_name_loc_set = isSnapshotLocSet(); + auto is_snapshot_name_loc_set = isSnapshotLocSet(); std::string filepath; - S32 i = 1; - S32 err = 0; - std::string extension("." + image->getExtension()); + auto i = 1; + auto err = 0; + auto extension("." + image->getExtension()); + auto now = LLDate::now(); do { filepath = sSnapshotDir; filepath += gDirUtilp->getDirDelimiter(); filepath += sSnapshotBaseName; - - if (is_snapshot_name_loc_set) - { - filepath += llformat("_%.3d",i); - } - + filepath += now.toLocalDateString("_%Y-%m-%d_%H%M%S"); + filepath += llformat("%.2d", i); filepath += extension; llstat stat_info; - err = LLFile::stat( filepath, &stat_info ); + err = LLFile::stat(filepath, &stat_info); i++; } while( -1 != err // Search until the file is not found (i.e., stat() gives an error). @@ -6169,7 +6180,7 @@ void LLPickInfo::fetchResults() mObjectOffset = gAgentCamera.calcFocusOffset(objectp, v_intersection, mPickPt.mX, mPickPt.mY); mObjectID = objectp->mID; mObjectFace = (te_offset == NO_FACE) ? -1 : (S32)te_offset; - + mPickHUD = objectp->isHUDAttachment(); mPosGlobal = gAgent.getPosGlobalFromAgent(v_intersection); diff --git a/indra/newview/llviewerwindow.h b/indra/newview/llviewerwindow.h index 1b995ea650..ac0dfa3fe4 100644 --- a/indra/newview/llviewerwindow.h +++ b/indra/newview/llviewerwindow.h @@ -133,6 +133,7 @@ public: bool mPickParticle; bool mPickUnselectable; bool mPickReflectionProbe = false; + bool mPickHUD{ false }; void getSurfaceInfo(); private: @@ -225,6 +226,7 @@ public: /*virtual*/ bool handleTimerEvent(LLWindow *window); /*virtual*/ bool handleDeviceChange(LLWindow *window); /*virtual*/ bool handleDPIChanged(LLWindow *window, F32 ui_scale_factor, S32 window_width, S32 window_height); + /*virtual*/ bool handleDisplayChanged(); /*virtual*/ bool handleWindowDidChangeScreen(LLWindow *window); /*virtual*/ void handlePingWatchdog(LLWindow *window, const char * msg); diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index 7bc9d06f9a..1cca2161fe 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -70,6 +70,7 @@ #include "llmeshrepository.h" #include "llmutelist.h" #include "llmoveview.h" +#include "llnotificationmanager.h" #include "llnotificationsutil.h" #include "llphysicsshapebuilderutil.h" #include "llquantize.h" @@ -682,7 +683,7 @@ LLVOAvatar::LLVOAvatar(const LLUUID& id, mFullyLoaded(false), mPreviousFullyLoaded(false), mFullyLoadedInitialized(false), - mLastCloudAttachmentCount(0), + mLastCloudAttachmentCount(-1), mVisualComplexity(VISUAL_COMPLEXITY_UNKNOWN), mLoadedCallbacksPaused(false), mLoadedCallbackTextures(0), @@ -817,6 +818,21 @@ LLVOAvatar::~LLVOAvatar() { sInstances.remove(this); + if (gSavedSettings.getBOOL("IMShowArrivalsDepartures")) + { + LLAvatarName av_name; + LLAvatarNameCache::get(getID(), &av_name); + auto display_name = av_name.getDisplayName(); + if (!display_name.empty()) + { + LLChat chat{llformat("%s left.", display_name.c_str())}; + chat.mFromName = display_name; + chat.mFromID = getID(); + LLSD args; + args["COLOR"] = "ChatHistoryTextColor"; + LLNotificationsUI::LLNotificationManager::instance().onChat(chat, args); + } + } if (!mFullyLoaded) { debugAvatarRezTime("AvatarRezLeftCloudNotification","left after ruth seconds as cloud"); @@ -1928,8 +1944,8 @@ bool LLVOAvatar::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& glm::mat4 inverse = glm::inverse(mat); glm::mat4 norm_mat = glm::transpose(inverse); - glm::vec3 p1(glm::make_vec3(start.getF32ptr())); - glm::vec3 p2(glm::make_vec3(end.getF32ptr())); + glm::vec3 p1(start); + glm::vec3 p2(end); p1 = mul_mat4_vec3(inverse, p1); p2 = mul_mat4_vec3(inverse, p2); @@ -1937,12 +1953,12 @@ bool LLVOAvatar::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& LLVector3 position; LLVector3 norm; - if (linesegment_sphere(LLVector3(glm::value_ptr(p1)), LLVector3(glm::value_ptr(p2)), LLVector3(0,0,0), 1.f, position, norm)) + if (linesegment_sphere(LLVector3(p1), LLVector3(p2), LLVector3(0,0,0), 1.f, position, norm)) { - glm::vec3 res_pos(glm::make_vec3(position.mV)); + glm::vec3 res_pos(position); res_pos = mul_mat4_vec3(mat, res_pos); - glm::vec3 res_norm(glm::make_vec3(norm.mV)); + glm::vec3 res_norm(norm); res_norm = glm::normalize(res_norm); res_norm = glm::mat3(norm_mat) * res_norm; @@ -2567,6 +2583,33 @@ U32 LLVOAvatar::processUpdateMessage(LLMessageSystem *mesgsys, { mDebugExistenceTimer.reset(); debugAvatarRezTime("AvatarRezArrivedNotification", "avatar arrived"); + if (gSavedSettings.getBOOL("IMShowArrivalsDepartures")) + { + uuid_vec_t uuids; + std::vector<LLVector3d> positions; + LLWorld::getInstance()->getAvatars(&uuids, &positions, gAgent.getPositionGlobal(), gSavedSettings.getF32("MPVNearMeRange")); + auto pos_it = positions.begin(); + auto id_it = uuids.begin(); + for (;pos_it != positions.end() && id_it != uuids.end(); ++pos_it, ++id_it) + { + if (*id_it == getID() && !isSelf()) + { + LLAvatarName av_name; + LLAvatarNameCache::get(getID(), &av_name); + auto display_name = av_name.getDisplayName(); + if (!display_name.empty()) + { + LLChat chat{llformat("%s arrived (%.1f m).", display_name.c_str(), dist_vec(*pos_it, gAgent.getPositionGlobal()))}; + chat.mFromName = display_name; + chat.mFromID = getID(); + LLSD args; + args["COLOR"] = "ChatHistoryTextColor"; + LLNotificationsUI::LLNotificationManager::instance().onChat(chat, args); + } + break; + } + } + } } if (retval & LLViewerObject::INVALID_UPDATE) @@ -2794,7 +2837,10 @@ void LLVOAvatar::idleUpdate(LLAgent &agent, const F64 &time) } // attach objects that were waiting for a drawable - lazyAttach(); + if (!mPendingAttachment.empty()) + { + lazyAttach(); + } // animate the character // store off last frame's root position to be consistent with camera position @@ -3226,6 +3272,7 @@ void LLVOAvatar::idleUpdateLoadingEffect() if (mFirstFullyVisible) { mFirstFullyVisible = false; + mLastCloudAttachmentCount = (S32)mSimAttachments.size(); mFirstDecloudTime = mFirstAppearanceMessageTimer.getElapsedTimeF32(); if (isSelf()) { @@ -7710,6 +7757,64 @@ void LLVOAvatar::cleanupAttachedMesh( LLViewerObject* pVO ) } } +bool check_object_for_mesh_loading(LLViewerObject* objectp) +{ + if (!objectp || !objectp->getVolume()) + { + return false; + } + LLVolume* volp = objectp->getVolume(); + const LLUUID& mesh_id = volp->getParams().getSculptID(); + if (mesh_id.isNull()) + { + // No mesh nor skin info needed + return false; + } + + if (volp->isMeshAssetUnavaliable()) + { + // Mesh failed to load, do not expect it + return false; + } + + if (!objectp->mDrawable) + { + return false; + } + + LLVOVolume* pvobj = objectp->mDrawable->getVOVolume(); + if (pvobj) + { + if (!pvobj->isMesh()) + { + // Not a mesh + return false; + } + + if (!volp->isMeshAssetLoaded()) + { + // Waiting for mesh + return true; + } + + const LLMeshSkinInfo* skin_data = pvobj->getSkinInfo(); + if (skin_data) + { + // Skin info present, done + return false; + } + + if (pvobj->isSkinInfoUnavaliable()) + { + // Load failed or info not present, don't expect it + return false; + } + } + + // object is not ready + return true; +} + bool LLVOAvatar::hasPendingAttachedMeshes() { for (attachment_map_t::iterator iter = mAttachmentPoints.begin(); @@ -7724,62 +7829,20 @@ bool LLVOAvatar::hasPendingAttachedMeshes() ++attachment_iter) { LLViewerObject* objectp = attachment_iter->get(); - if (objectp) + if (objectp && !objectp->isDead()) { + if (check_object_for_mesh_loading(objectp)) + { + return true; + } LLViewerObject::const_child_list_t& child_list = objectp->getChildren(); for (LLViewerObject::child_list_t::const_iterator iter1 = child_list.begin(); iter1 != child_list.end(); ++iter1) { LLViewerObject* objectchild = *iter1; - if (objectchild && objectchild->getVolume()) + if (check_object_for_mesh_loading(objectchild)) { - const LLUUID& mesh_id = objectchild->getVolume()->getParams().getSculptID(); - if (mesh_id.isNull()) - { - // No mesh nor skin info needed - continue; - } - - if (objectchild->getVolume()->isMeshAssetUnavaliable()) - { - // Mesh failed to load, do not expect it - continue; - } - - if (objectchild->mDrawable) - { - LLVOVolume* pvobj = objectchild->mDrawable->getVOVolume(); - if (pvobj) - { - if (!pvobj->isMesh()) - { - // Not a mesh - continue; - } - - if (!objectchild->getVolume()->isMeshAssetLoaded()) - { - // Waiting for mesh - return true; - } - - const LLMeshSkinInfo* skin_data = pvobj->getSkinInfo(); - if (skin_data) - { - // Skin info present, done - continue; - } - - if (pvobj->isSkinInfoUnavaliable()) - { - // Load failed or info not present, don't expect it - continue; - } - } - - // objectchild is not ready - return true; - } + return true; } } } @@ -8382,7 +8445,7 @@ bool LLVOAvatar::updateIsFullyLoaded() ); // compare amount of attachments to one reported by simulator - if (!loading && !isSelf() && rez_status < 4 && mLastCloudAttachmentCount < mSimAttachments.size()) + if (!isSelf() && mLastCloudAttachmentCount < mSimAttachments.size() && mSimAttachments.size() > 0) { S32 attachment_count = getAttachmentCount(); if (mLastCloudAttachmentCount != attachment_count) @@ -8400,6 +8463,11 @@ bool LLVOAvatar::updateIsFullyLoaded() // waiting loading = true; } + else if (!loading) + { + // for hasFirstFullAttachmentData + mLastCloudAttachmentCount = (S32)mSimAttachments.size(); + } } } updateRezzedStatusTimers(rez_status); @@ -8513,6 +8581,12 @@ bool LLVOAvatar::isFullyLoaded() const return (mRenderUnloadedAvatar || mFullyLoaded); } +bool LLVOAvatar::hasFirstFullAttachmentData() const +{ + return !mFirstFullyVisible // Avatar is fully visible, have all data + || mLastCloudAttachmentCount >= (S32)mSimAttachments.size(); +} + bool LLVOAvatar::isTooComplex() const { bool too_complex; @@ -11699,24 +11773,38 @@ void LLVOAvatar::placeProfileQuery() glGenQueries(1, &mGPUTimerQuery); } - glBeginQuery(GL_TIME_ELAPSED, mGPUTimerQuery); +#if GL_EXT_timer_query || GL_EXT_disjoint_timer_query + glBeginQuery(GL_TIME_ELAPSED_EXT, mGPUTimerQuery); +#endif } void LLVOAvatar::readProfileQuery(S32 retries) { if (!mGPUProfilePending) { - glEndQuery(GL_TIME_ELAPSED); +#if GL_EXT_timer_query || GL_EXT_disjoint_timer_query + glEndQuery(GL_TIME_ELAPSED_EXT); +#endif mGPUProfilePending = true; } +#if GL_ARB_timer_query GLuint64 result = 0; glGetQueryObjectui64v(mGPUTimerQuery, GL_QUERY_RESULT_AVAILABLE, &result); +#else + GLuint result = 0; + glGetQueryObjectuiv(mGPUTimerQuery, GL_QUERY_RESULT_AVAILABLE, &result); +#endif if (result == GL_TRUE || --retries <= 0) { // query available, readback result +#if GL_ARB_timer_query GLuint64 time_elapsed = 0; glGetQueryObjectui64v(mGPUTimerQuery, GL_QUERY_RESULT, &time_elapsed); +#else + GLuint time_elapsed = 0; + glGetQueryObjectuiv(mGPUTimerQuery, GL_QUERY_RESULT, &time_elapsed); +#endif mGPURenderTime = time_elapsed / 1000000.f; mGPUProfilePending = false; diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h index dd1725c322..a2232d21a2 100644 --- a/indra/newview/llvoavatar.h +++ b/indra/newview/llvoavatar.h @@ -385,6 +385,7 @@ public: //-------------------------------------------------------------------- public: bool isFullyLoaded() const; + bool hasFirstFullAttachmentData() const; F32 getFirstDecloudTime() const {return mFirstDecloudTime;} // check and return current state relative to limits @@ -546,7 +547,7 @@ public: U32 renderTransparent(bool first_pass); void renderCollisionVolumes(); void renderBones(const std::string &selected_joint = std::string()); - void renderJoints(); + virtual void renderJoints(); static void deleteCachedImages(bool clearAll=true); static void destroyGL(); static void restoreGL(); diff --git a/indra/newview/llvoavatarself.cpp b/indra/newview/llvoavatarself.cpp index 746ef7cacb..f23af5afa4 100644 --- a/indra/newview/llvoavatarself.cpp +++ b/indra/newview/llvoavatarself.cpp @@ -697,6 +697,7 @@ void LLVOAvatarSelf::idleUpdate(LLAgent &agent, const F64 &time) // virtual LLJoint *LLVOAvatarSelf::getJoint(const std::string &name) { + std::lock_guard lock(mJointMapMutex); LLJoint *jointp = NULL; jointp = LLVOAvatar::getJoint(name); if (!jointp && mScreenp) @@ -714,6 +715,14 @@ LLJoint *LLVOAvatarSelf::getJoint(const std::string &name) return jointp; } + +//virtual +void LLVOAvatarSelf::renderJoints() +{ + std::lock_guard lock(mJointMapMutex); + LLVOAvatar::renderJoints(); +} + // virtual bool LLVOAvatarSelf::setVisualParamWeight(const LLVisualParam *which_param, F32 weight) { diff --git a/indra/newview/llvoavatarself.h b/indra/newview/llvoavatarself.h index 051ac791c0..f9bea41b1d 100644 --- a/indra/newview/llvoavatarself.h +++ b/indra/newview/llvoavatarself.h @@ -92,6 +92,8 @@ public: /*virtual*/ void requestStopMotion(LLMotion* motion); /*virtual*/ LLJoint* getJoint(const std::string &name); + /*virtual*/ void renderJoints(); + /*virtual*/ bool setVisualParamWeight(const LLVisualParam *which_param, F32 weight); /*virtual*/ bool setVisualParamWeight(const char* param_name, F32 weight); /*virtual*/ bool setVisualParamWeight(S32 index, F32 weight); @@ -103,6 +105,8 @@ private: // helper function. Passed in param is assumed to be in avatar's parameter list. bool setParamWeight(const LLViewerVisualParam *param, F32 weight); + std::mutex mJointMapMutex; // getJoint gets used from mesh thread + /******************************************************************************** ** ** ** STATE diff --git a/indra/newview/llvoiceclient.cpp b/indra/newview/llvoiceclient.cpp index 623d8deac9..e5eb2f8008 100644 --- a/indra/newview/llvoiceclient.cpp +++ b/indra/newview/llvoiceclient.cpp @@ -26,7 +26,9 @@ #include "llvoiceclient.h" #include "llvoicevivox.h" +#if !__FreeBSD__ #include "llvoicewebrtc.h" +#endif #include "llviewernetwork.h" #include "llviewercontrol.h" #include "llcommandhandler.h" @@ -120,10 +122,12 @@ LLVoiceModuleInterface *getVoiceModule(const std::string &voice_server_type) { return (LLVoiceModuleInterface *) LLVivoxVoiceClient::getInstance(); } +#if !__FreeBSD__ else if (voice_server_type == WEBRTC_VOICE_SERVER_TYPE) { return (LLVoiceModuleInterface *) LLWebRTCVoiceClient::getInstance(); } +#endif else { LLNotificationsUtil::add("VoiceVersionMismatch"); @@ -165,7 +169,9 @@ void LLVoiceClient::init(LLPumpIO *pump) { // Initialize all of the voice modules m_servicePump = pump; +#if !__FreeBSD__ LLWebRTCVoiceClient::getInstance()->init(pump); +#endif LLVivoxVoiceClient::getInstance()->init(pump); } @@ -176,7 +182,9 @@ void LLVoiceClient::userAuthorized(const std::string& user_id, const LLUUID &age mRegionChangedCallbackSlot.disconnect(); } mRegionChangedCallbackSlot = gAgent.addRegionChangedCallback(boost::bind(&LLVoiceClient::onRegionChanged, this)); +#if !__FreeBSD__ LLWebRTCVoiceClient::getInstance()->userAuthorized(user_id, agentID); +#endif LLVivoxVoiceClient::getInstance()->userAuthorized(user_id, agentID); } @@ -285,7 +293,10 @@ void LLVoiceClient::setNonSpatialVoiceModule(const std::string &voice_server_typ void LLVoiceClient::setHidden(bool hidden) { + LL_INFOS("Voice") << "( " << (hidden ? "true" : "false") << " )" << LL_ENDL; +#if !__FreeBSD__ LLWebRTCVoiceClient::getInstance()->setHidden(hidden); +#endif LLVivoxVoiceClient::getInstance()->setHidden(hidden); } @@ -326,7 +337,9 @@ void LLVoiceClient::updateSettings() updateMicMuteLogic(); +#if !__FreeBSD__ LLWebRTCVoiceClient::getInstance()->updateSettings(); +#endif LLVivoxVoiceClient::getInstance()->updateSettings(); } @@ -335,34 +348,54 @@ void LLVoiceClient::updateSettings() void LLVoiceClient::tuningStart() { +#if !__FreeBSD__ LLWebRTCVoiceClient::getInstance()->tuningStart(); +#endif LLVivoxVoiceClient::getInstance()->tuningStart(); } void LLVoiceClient::tuningStop() { +#if !__FreeBSD__ LLWebRTCVoiceClient::getInstance()->tuningStop(); +#endif LLVivoxVoiceClient::getInstance()->tuningStop(); } bool LLVoiceClient::inTuningMode() { +#if !__FreeBSD__ return LLWebRTCVoiceClient::getInstance()->inTuningMode(); +#else + return LLVivoxVoiceClient::getInstance()->inTuningMode(); +#endif } void LLVoiceClient::tuningSetMicVolume(float volume) { +#if !__FreeBSD__ LLWebRTCVoiceClient::getInstance()->tuningSetMicVolume(volume); +#else + LLVivoxVoiceClient::getInstance()->tuningSetMicVolume(volume); +#endif } void LLVoiceClient::tuningSetSpeakerVolume(float volume) { +#if !__FreeBSD__ LLWebRTCVoiceClient::getInstance()->tuningSetSpeakerVolume(volume); +#else + LLVivoxVoiceClient::getInstance()->tuningSetSpeakerVolume(volume); +#endif } float LLVoiceClient::tuningGetEnergy(void) { +#if !__FreeBSD__ return LLWebRTCVoiceClient::getInstance()->tuningGetEnergy(); +#else + return LLVivoxVoiceClient::getInstance()->tuningGetEnergy(); +#endif } //------------------------------------------------ @@ -370,40 +403,64 @@ float LLVoiceClient::tuningGetEnergy(void) bool LLVoiceClient::deviceSettingsAvailable() { +#if !__FreeBSD__ return LLWebRTCVoiceClient::getInstance()->deviceSettingsAvailable(); +#else + return LLVivoxVoiceClient::getInstance()->deviceSettingsAvailable(); +#endif } bool LLVoiceClient::deviceSettingsUpdated() { +#if !__FreeBSD__ return LLWebRTCVoiceClient::getInstance()->deviceSettingsUpdated(); +#else + return LLVivoxVoiceClient::getInstance()->deviceSettingsUpdated(); +#endif } void LLVoiceClient::refreshDeviceLists(bool clearCurrentList) { +#if !__FreeBSD__ LLWebRTCVoiceClient::getInstance()->refreshDeviceLists(clearCurrentList); +#else + LLVivoxVoiceClient::getInstance()->refreshDeviceLists(clearCurrentList); +#endif } void LLVoiceClient::setCaptureDevice(const std::string& name) { LLVivoxVoiceClient::getInstance()->setCaptureDevice(name); +#if !__FreeBSD__ LLWebRTCVoiceClient::getInstance()->setCaptureDevice(name); +#endif } void LLVoiceClient::setRenderDevice(const std::string& name) { LLVivoxVoiceClient::getInstance()->setRenderDevice(name); +#if !__FreeBSD__ LLWebRTCVoiceClient::getInstance()->setRenderDevice(name); +#endif } const LLVoiceDeviceList& LLVoiceClient::getCaptureDevices() { +#if !__FreeBSD__ return LLWebRTCVoiceClient::getInstance()->getCaptureDevices(); +#else + return LLVivoxVoiceClient::getInstance()->getCaptureDevices(); +#endif } const LLVoiceDeviceList& LLVoiceClient::getRenderDevices() { +#if !__FreeBSD__ return LLWebRTCVoiceClient::getInstance()->getRenderDevices(); +#else + return LLVivoxVoiceClient::getInstance()->getRenderDevices(); +#endif } @@ -412,13 +469,19 @@ const LLVoiceDeviceList& LLVoiceClient::getRenderDevices() void LLVoiceClient::getParticipantList(std::set<LLUUID> &participants) const { +#if !__FreeBSD__ LLWebRTCVoiceClient::getInstance()->getParticipantList(participants); +#endif LLVivoxVoiceClient::getInstance()->getParticipantList(participants); } bool LLVoiceClient::isParticipant(const LLUUID &speaker_id) const { +#if !__FreeBSD__ return LLWebRTCVoiceClient::getInstance()->isParticipant(speaker_id) || +#else + return +#endif LLVivoxVoiceClient::getInstance()->isParticipant(speaker_id); } @@ -511,13 +574,21 @@ void LLVoiceClient::activateSpatialChannel(bool activate) bool LLVoiceClient::isCurrentChannel(const LLSD& channelInfo) { +#if !__FreeBSD__ return LLWebRTCVoiceClient::getInstance()->isCurrentChannel(channelInfo) || +#else + return +#endif LLVivoxVoiceClient::getInstance()->isCurrentChannel(channelInfo); } bool LLVoiceClient::compareChannels(const LLSD &channelInfo1, const LLSD &channelInfo2) { +#if !__FreeBSD__ return LLWebRTCVoiceClient::getInstance()->compareChannels(channelInfo1, channelInfo2) || +#else + return +#endif LLVivoxVoiceClient::getInstance()->compareChannels(channelInfo1, channelInfo2); } @@ -559,13 +630,17 @@ LLVoiceP2POutgoingCallInterface *LLVoiceClient::getOutgoingCallInterface(const L void LLVoiceClient::setVoiceVolume(F32 volume) { +#if !__FreeBSD__ LLWebRTCVoiceClient::getInstance()->setVoiceVolume(volume); +#endif LLVivoxVoiceClient::getInstance()->setVoiceVolume(volume); } void LLVoiceClient::setMicGain(F32 gain) { +#if !__FreeBSD__ LLWebRTCVoiceClient::getInstance()->setMicGain(gain); +#endif LLVivoxVoiceClient::getInstance()->setMicGain(gain); } @@ -612,10 +687,12 @@ bool LLVoiceClient::voiceEnabled() void LLVoiceClient::setVoiceEnabled(bool enabled) { +#if !__FreeBSD__ if (LLWebRTCVoiceClient::instanceExists()) { LLWebRTCVoiceClient::getInstance()->setVoiceEnabled(enabled); } +#endif if (LLVivoxVoiceClient::instanceExists()) { LLVivoxVoiceClient::getInstance()->setVoiceEnabled(enabled); @@ -638,7 +715,9 @@ void LLVoiceClient::updateMicMuteLogic() // Either of these always overrides any other PTT setting. new_mic_mute = true; } +#if !__FreeBSD__ LLWebRTCVoiceClient::getInstance()->setMuteMic(new_mic_mute); +#endif LLVivoxVoiceClient::getInstance()->setMuteMic(new_mic_mute); } @@ -733,18 +812,26 @@ bool LLVoiceClient::getVoiceEnabled(const LLUUID& id) const std::string LLVoiceClient::getDisplayName(const LLUUID& id) const { +#if !__FreeBSD__ std::string result = LLWebRTCVoiceClient::getInstance()->getDisplayName(id); if (result.empty()) { result = LLVivoxVoiceClient::getInstance()->getDisplayName(id); } return result; +#else + return LLVivoxVoiceClient::getInstance()->getDisplayName(id); +#endif } bool LLVoiceClient::isVoiceWorking() const { +#if !__FreeBSD__ return LLVivoxVoiceClient::getInstance()->isVoiceWorking() || LLWebRTCVoiceClient::getInstance()->isVoiceWorking(); +#else + return LLVivoxVoiceClient::getInstance()->isVoiceWorking(); +#endif } bool LLVoiceClient::isParticipantAvatar(const LLUUID& id) @@ -759,7 +846,11 @@ bool LLVoiceClient::isOnlineSIP(const LLUUID& id) bool LLVoiceClient::getIsSpeaking(const LLUUID& id) { +#if !__FreeBSD__ return LLWebRTCVoiceClient::getInstance()->getIsSpeaking(id) || +#else + return +#endif LLVivoxVoiceClient::getInstance()->getIsSpeaking(id); } @@ -767,14 +858,22 @@ bool LLVoiceClient::getIsModeratorMuted(const LLUUID& id) { // don't bother worrying about p2p calls, as // p2p calls don't have mute. +#if !__FreeBSD__ return LLWebRTCVoiceClient::getInstance()->getIsModeratorMuted(id) || +#else + return +#endif LLVivoxVoiceClient::getInstance()->getIsModeratorMuted(id); } F32 LLVoiceClient::getCurrentPower(const LLUUID& id) { +#if !__FreeBSD__ return std::fmax(LLVivoxVoiceClient::getInstance()->getCurrentPower(id), LLWebRTCVoiceClient::getInstance()->getCurrentPower(id)); +#else + return LLVivoxVoiceClient::getInstance()->getCurrentPower(id); +#endif } bool LLVoiceClient::getOnMuteList(const LLUUID& id) @@ -786,12 +885,18 @@ bool LLVoiceClient::getOnMuteList(const LLUUID& id) F32 LLVoiceClient::getUserVolume(const LLUUID& id) { +#if !__FreeBSD__ return std::fmax(LLVivoxVoiceClient::getInstance()->getUserVolume(id), LLWebRTCVoiceClient::getInstance()->getUserVolume(id)); +#else + return LLVivoxVoiceClient::getInstance()->getUserVolume(id); +#endif } void LLVoiceClient::setUserVolume(const LLUUID& id, F32 volume) { +#if !__FreeBSD__ LLWebRTCVoiceClient::getInstance()->setUserVolume(id, volume); +#endif LLVivoxVoiceClient::getInstance()->setUserVolume(id, volume); } @@ -801,7 +906,9 @@ void LLVoiceClient::setUserVolume(const LLUUID& id, F32 volume) void LLVoiceClient::addObserver(LLVoiceClientStatusObserver* observer) { LLVivoxVoiceClient::getInstance()->addObserver(observer); +#if !__FreeBSD__ LLWebRTCVoiceClient::getInstance()->addObserver(observer); +#endif } void LLVoiceClient::removeObserver(LLVoiceClientStatusObserver* observer) @@ -810,16 +917,20 @@ void LLVoiceClient::removeObserver(LLVoiceClientStatusObserver* observer) { LLVivoxVoiceClient::getInstance()->removeObserver(observer); } +#if !__FreeBSD__ if (LLWebRTCVoiceClient::instanceExists()) { LLWebRTCVoiceClient::getInstance()->removeObserver(observer); } +#endif } void LLVoiceClient::addObserver(LLFriendObserver* observer) { LLVivoxVoiceClient::getInstance()->addObserver(observer); +#if !__FreeBSD__ LLWebRTCVoiceClient::getInstance()->addObserver(observer); +#endif } void LLVoiceClient::removeObserver(LLFriendObserver* observer) @@ -828,16 +939,20 @@ void LLVoiceClient::removeObserver(LLFriendObserver* observer) { LLVivoxVoiceClient::getInstance()->removeObserver(observer); } +#if !__FreeBSD__ if (LLWebRTCVoiceClient::instanceExists()) { LLWebRTCVoiceClient::getInstance()->removeObserver(observer); } +#endif } void LLVoiceClient::addObserver(LLVoiceClientParticipantObserver* observer) { LLVivoxVoiceClient::getInstance()->addObserver(observer); +#if !__FreeBSD__ LLWebRTCVoiceClient::getInstance()->addObserver(observer); +#endif } void LLVoiceClient::removeObserver(LLVoiceClientParticipantObserver* observer) @@ -846,10 +961,12 @@ void LLVoiceClient::removeObserver(LLVoiceClientParticipantObserver* observer) { LLVivoxVoiceClient::getInstance()->removeObserver(observer); } +#if !__FreeBSD__ if (LLWebRTCVoiceClient::instanceExists()) { LLWebRTCVoiceClient::getInstance()->removeObserver(observer); } +#endif } std::string LLVoiceClient::sipURIFromID(const LLUUID &id) const @@ -912,10 +1029,12 @@ class LLViewerRequiredVoiceVersion : public LLHTTPNode { voiceModule = (LLVoiceModuleInterface *) LLVivoxVoiceClient::getInstance(); } +#if !__FreeBSD__ else if (voice_server_type == "webrtc") { voiceModule = (LLVoiceModuleInterface *) LLWebRTCVoiceClient::getInstance(); } +#endif else { LL_WARNS("Voice") << "Unknown voice server type " << voice_server_type << LL_ENDL; diff --git a/indra/newview/llvoicevivox.cpp b/indra/newview/llvoicevivox.cpp index 7d6ad743bd..7faef8cc41 100644 --- a/indra/newview/llvoicevivox.cpp +++ b/indra/newview/llvoicevivox.cpp @@ -940,7 +940,7 @@ bool LLVivoxVoiceClient::startAndLaunchDaemon() gDirUtilp->append(exe_path, "SLVoice"); #else std::string exe_path = gDirUtilp->getExecutableDir(); - gDirUtilp->append(exe_path, "SLVoice"); + gDirUtilp->append(exe_path, "SLVoice.exe"); #endif // See if the vivox executable exists llstat s; @@ -948,7 +948,16 @@ bool LLVivoxVoiceClient::startAndLaunchDaemon() { // vivox executable exists. Build the command line and launch the daemon. LLProcess::Params params; +#if LL_LINUX || __FreeBSD__ +#if __FreeBSD__ + params.envs.add("WINEARCH=win32"); + params.envs.add("WINEPREFIX=~/.i386-wine-pkg"); +#endif // __FreeBSD__ + params.executable = "wine"; + params.args.add(exe_path); +#else params.executable = exe_path; +#endif // LL_LINUX || __FreeBSD__ // VOICE-88: Cycle through [portbase..portbase+portrange) on // successive tries because attempting to relaunch (after manually @@ -1014,6 +1023,7 @@ bool LLVivoxVoiceClient::startAndLaunchDaemon() std::string old_log = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "SLVoice.old"); if (gDirUtilp->fileExists(new_log)) { + LLFile::remove(old_log, ENOENT); LLFile::rename(new_log, old_log); } @@ -2004,7 +2014,7 @@ bool LLVivoxVoiceClient::waitForChannel() { recordingAndPlaybackMode(); } - else if (mProcessChannels && (mNextAudioSession == NULL) && checkParcelChanged()) + else if (mProcessChannels && ((mNextAudioSession == NULL) || checkParcelChanged())) { // the parcel is changed, or we have no pending audio sessions, // so try to request the parcel voice info diff --git a/indra/newview/llvoicevivox.h b/indra/newview/llvoicevivox.h index 3167705528..3e0a237905 100644 --- a/indra/newview/llvoicevivox.h +++ b/indra/newview/llvoicevivox.h @@ -39,6 +39,8 @@ class LLVivoxProtocolParser; #include "llcallingcard.h" // for LLFriendObserver #include "lleventcoro.h" #include "llcoros.h" +#include "llparcel.h" +#include "llmutelist.h" #include <queue> #ifdef LL_USESYSTEMLIBS diff --git a/indra/newview/llvoicewebrtc.cpp b/indra/newview/llvoicewebrtc.cpp index b2e5de5371..08fcec86ac 100644 --- a/indra/newview/llvoicewebrtc.cpp +++ b/indra/newview/llvoicewebrtc.cpp @@ -345,6 +345,8 @@ void LLWebRTCVoiceClient::updateSettings() static LLCachedControl<std::string> sOutputDevice(gSavedSettings, "VoiceOutputAudioDevice"); setRenderDevice(sOutputDevice); + LL_INFOS("Voice") << "Input device: " << std::quoted(sInputDevice()) << ", output device: " << std::quoted(sOutputDevice()) << LL_ENDL; + static LLCachedControl<F32> sMicLevel(gSavedSettings, "AudioLevelMic"); setMicGain(sMicLevel); @@ -554,7 +556,7 @@ void LLWebRTCVoiceClient::voiceConnectionCoro() } } LL::WorkQueue::postMaybe(mMainQueue, - [=] { + [=, this] { if (sShuttingDown) { return; @@ -672,7 +674,7 @@ void LLWebRTCVoiceClient::OnDevicesChanged(const llwebrtc::LLWebRTCVoiceDeviceLi { LL::WorkQueue::postMaybe(mMainQueue, - [=] + [=, this] { OnDevicesChangedImpl(render_devices, capture_devices); }); @@ -896,7 +898,7 @@ void LLWebRTCVoiceClient::OnConnectionShutDown(const std::string &channelID, con { if (mSession && mSession->mChannelID == channelID) { - LL_DEBUGS("Voice") << "Main WebRTC Connection Shut Down." << LL_ENDL; + LL_INFOS("Voice") << "Main WebRTC Connection Shut Down." << LL_ENDL; } } mSession->removeAllParticipants(regionID); @@ -1504,6 +1506,11 @@ bool LLWebRTCVoiceClient::compareChannels(const LLSD &channelInfo1, const LLSD & // we're muting the mic, so tell each session such void LLWebRTCVoiceClient::setMuteMic(bool muted) { + if (mMuteMic != muted) + { + LL_INFOS("Voice") << "( " << (muted ? "true" : "false") << " )" << LL_ENDL; + } + mMuteMic = muted; // when you're hidden, your mic is always muted. if (!mHidden) @@ -1552,14 +1559,10 @@ void LLWebRTCVoiceClient::setVoiceEnabled(bool enabled) { LL_PROFILE_ZONE_SCOPED_CATEGORY_VOICE; - LL_DEBUGS("Voice") - << "( " << (enabled ? "enabled" : "disabled") << " )" - << " was "<< (mVoiceEnabled ? "enabled" : "disabled") - << " coro "<< (mIsCoroutineActive ? "active" : "inactive") - << LL_ENDL; - if (enabled != mVoiceEnabled) { + LL_INFOS("Voice") << "( " << (enabled ? "enabled" : "disabled") << " )" + << ", coro: " << (mIsCoroutineActive ? "active" : "inactive") << LL_ENDL; // TODO: Refactor this so we don't call into LLVoiceChannel, but simply // use the status observer mVoiceEnabled = enabled; @@ -2208,7 +2211,7 @@ LLVoiceWebRTCConnection::~LLVoiceWebRTCConnection() void LLVoiceWebRTCConnection::OnIceGatheringState(llwebrtc::LLWebRTCSignalingObserver::EIceGatheringState state) { LL::WorkQueue::postMaybe(mMainQueue, - [=] { + [=, this] { LL_DEBUGS("Voice") << "Ice Gathering voice account. " << state << LL_ENDL; switch (state) @@ -2231,7 +2234,7 @@ void LLVoiceWebRTCConnection::OnIceGatheringState(llwebrtc::LLWebRTCSignalingObs // callback from llwebrtc void LLVoiceWebRTCConnection::OnIceCandidate(const llwebrtc::LLWebRTCIceCandidate& candidate) { - LL::WorkQueue::postMaybe(mMainQueue, [=] { mIceCandidates.push_back(candidate); }); + LL::WorkQueue::postMaybe(mMainQueue, [=, this] { mIceCandidates.push_back(candidate); }); } void LLVoiceWebRTCConnection::processIceUpdates() @@ -2349,7 +2352,7 @@ void LLVoiceWebRTCConnection::processIceUpdatesCoro(connectionPtr_t connection) void LLVoiceWebRTCConnection::OnOfferAvailable(const std::string &sdp) { LL::WorkQueue::postMaybe(mMainQueue, - [=] { + [=, this] { if (mShutDown) { return; @@ -2376,7 +2379,7 @@ void LLVoiceWebRTCConnection::OnOfferAvailable(const std::string &sdp) void LLVoiceWebRTCConnection::OnAudioEstablished(llwebrtc::LLWebRTCAudioInterface* audio_interface) { LL::WorkQueue::postMaybe(mMainQueue, - [=] { + [=, this] { if (mShutDown) { return; @@ -2398,7 +2401,7 @@ void LLVoiceWebRTCConnection::OnAudioEstablished(llwebrtc::LLWebRTCAudioInterfac void LLVoiceWebRTCConnection::OnRenegotiationNeeded() { LL::WorkQueue::postMaybe(mMainQueue, - [=] { + [=, this] { LL_DEBUGS("Voice") << "Voice channel requires renegotiation." << LL_ENDL; if (!mShutDown) { @@ -2412,7 +2415,7 @@ void LLVoiceWebRTCConnection::OnRenegotiationNeeded() void LLVoiceWebRTCConnection::OnPeerConnectionClosed() { LL::WorkQueue::postMaybe(mMainQueue, - [=] { + [=, this] { LL_DEBUGS("Voice") << "Peer connection has closed." << LL_ENDL; if (mVoiceConnectionState == VOICE_STATE_WAIT_FOR_CLOSE) { @@ -2483,7 +2486,7 @@ void LLVoiceWebRTCConnection::breakVoiceConnectionCoro(connectionPtr_t connectio { LL_PROFILE_ZONE_SCOPED_CATEGORY_VOICE; - LL_DEBUGS("Voice") << "Disconnecting voice." << LL_ENDL; + LL_INFOS("Voice") << "Disconnecting voice." << LL_ENDL; if (connection->mWebRTCDataInterface) { connection->mWebRTCDataInterface->unsetDataObserver(connection.get()); @@ -2591,6 +2594,7 @@ void LLVoiceWebRTCSpatialConnection::requestVoiceConnection() LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS]; LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults); + LL_INFOS("Voice") << "Voice connection request: " << (status ? "Success" : status.toString()) << LL_ENDL; if (status) { OnVoiceConnectionRequestSuccess(result); @@ -2884,7 +2888,7 @@ bool LLVoiceWebRTCConnection::connectionStateMachine() // llwebrtc callback void LLVoiceWebRTCConnection::OnDataReceived(const std::string& data, bool binary) { - LL::WorkQueue::postMaybe(mMainQueue, [=] { LLVoiceWebRTCConnection::OnDataReceivedImpl(data, binary); }); + LL::WorkQueue::postMaybe(mMainQueue, [=, this] { LLVoiceWebRTCConnection::OnDataReceivedImpl(data, binary); }); } // @@ -3020,7 +3024,7 @@ void LLVoiceWebRTCConnection::OnDataReceivedImpl(const std::string &data, bool b { root["ug"] = user_gain; } - if (root.size() > 0) + if (root.size() > 0 && mWebRTCDataInterface) { std::string json_data = boost::json::serialize(root); mWebRTCDataInterface->sendData(json_data, false); @@ -3040,7 +3044,7 @@ void LLVoiceWebRTCConnection::OnDataReceivedImpl(const std::string &data, bool b void LLVoiceWebRTCConnection::OnDataChannelReady(llwebrtc::LLWebRTCDataInterface *data_interface) { LL::WorkQueue::postMaybe(mMainQueue, - [=] { + [=, this] { if (mShutDown) { return; @@ -3063,7 +3067,10 @@ void LLVoiceWebRTCConnection::OnDataChannelReady(llwebrtc::LLWebRTCDataInterface void LLVoiceWebRTCConnection::sendJoin() { LL_PROFILE_ZONE_SCOPED_CATEGORY_VOICE; - + if (!mWebRTCDataInterface) + { + return; + } boost::json::object root; boost::json::object join_obj; diff --git a/indra/newview/llvosky.cpp b/indra/newview/llvosky.cpp index ab8d0d2564..38c702c4ca 100644 --- a/indra/newview/llvosky.cpp +++ b/indra/newview/llvosky.cpp @@ -100,8 +100,16 @@ LLSkyTex::LLSkyTex() : void LLSkyTex::init(bool isShiny) { mIsShiny = isShiny; - mSkyData = new LLColor4[(U32)(SKYTEX_RESOLUTION * SKYTEX_RESOLUTION)]; - mSkyDirs = new LLVector3[(U32)(SKYTEX_RESOLUTION * SKYTEX_RESOLUTION)]; + try + { + mSkyData = new LLColor4[(U32)(SKYTEX_RESOLUTION * SKYTEX_RESOLUTION)]; + mSkyDirs = new LLVector3[(U32)(SKYTEX_RESOLUTION * SKYTEX_RESOLUTION)]; + } + catch (std::bad_alloc&) + { + LLError::LLUserWarningMsg::showOutOfMemory(); + LL_ERRS() << "Failed to allocate memory for sky texture data" << LL_ENDL; + } for (S32 i = 0; i < 2; ++i) { diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index 6514db0814..3fb7a3c156 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -645,8 +645,12 @@ void LLVOVolume::animateTextures() // LLVOVolume::updateTextureVirtualSize when the // mTextureMatrix is not yet present gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_TCOORD); - mDrawable->getSpatialGroup()->dirtyGeom(); - gPipeline.markRebuild(mDrawable->getSpatialGroup()); + LLSpatialGroup* group = mDrawable->getSpatialGroup(); + if (group) + { + group->dirtyGeom(); + gPipeline.markRebuild(group); + } } } @@ -5735,13 +5739,23 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) continue; } - LLFetchedGLTFMaterial *gltf_mat = (LLFetchedGLTFMaterial*) facep->getTextureEntry()->getGLTFRenderMaterial(); + LLFetchedGLTFMaterial* gltf_mat = nullptr; + const LLTextureEntry* te = facep->getTextureEntry(); + if (te) + { + gltf_mat = (LLFetchedGLTFMaterial*)te->getGLTFRenderMaterial(); + } // if not te, continue? bool is_pbr = gltf_mat != nullptr; if (is_pbr) { // tell texture streaming system to ignore blinn-phong textures - facep->setTexture(LLRender::DIFFUSE_MAP, nullptr); + // except the special case of the diffuse map containing a + // media texture that will be reused for swapping on to the pbr face + if (!facep->hasMedia()) + { + facep->setTexture(LLRender::DIFFUSE_MAP, nullptr); + } facep->setTexture(LLRender::NORMAL_MAP, nullptr); facep->setTexture(LLRender::SPECULAR_MAP, nullptr); @@ -5797,10 +5811,9 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) { cur_total += facep->getGeomCount(); - const LLTextureEntry* te = facep->getTextureEntry(); LLViewerTexture* tex = facep->getTexture(); - if (te->getGlow() > 0.f) + if (te && te->getGlow() > 0.f) { emissive = true; } @@ -5819,8 +5832,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) { type = LLDrawPool::POOL_GLTF_PBR; } - else - if (type != LLDrawPool::POOL_ALPHA && force_simple) + else if (type != LLDrawPool::POOL_ALPHA && force_simple) { type = LLDrawPool::POOL_SIMPLE; } @@ -5895,6 +5907,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) facep->mLastUpdateTime = gFrameTimeSeconds; } + if (te) { LLGLTFMaterial* gltf_mat = te->getGLTFRenderMaterial(); @@ -5959,6 +5972,11 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) add_face(sFullbrightFaces, fullbright_count, facep); } } + else // no texture entry + { + facep->setState(LLFace::FULLBRIGHT); + add_face(sFullbrightFaces, fullbright_count, facep); + } } } else @@ -6713,8 +6731,11 @@ U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace { //shiny if (tex->getPrimaryFormat() == GL_ALPHA) { //invisiprim+shiny - registerFace(group, facep, LLRenderPass::PASS_INVISI_SHINY); - registerFace(group, facep, LLRenderPass::PASS_INVISIBLE); + if (!facep->getViewerObject()->isAttachment() && !facep->getViewerObject()->isRiggedMesh()) + { + registerFace(group, facep, LLRenderPass::PASS_INVISI_SHINY); + registerFace(group, facep, LLRenderPass::PASS_INVISIBLE); + } } else if (!hud_group) { //deferred rendering @@ -6750,7 +6771,10 @@ U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace { //not alpha and not shiny if (!is_alpha && tex->getPrimaryFormat() == GL_ALPHA) { //invisiprim - registerFace(group, facep, LLRenderPass::PASS_INVISIBLE); + if (!facep->getViewerObject()->isAttachment() && !facep->getViewerObject()->isRiggedMesh()) + { + registerFace(group, facep, LLRenderPass::PASS_INVISIBLE); + } } else if (fullbright || bake_sunlight) { //fullbright diff --git a/indra/newview/llworld.cpp b/indra/newview/llworld.cpp index e0d8c25731..899733ccc3 100644 --- a/indra/newview/llworld.cpp +++ b/indra/newview/llworld.cpp @@ -838,6 +838,7 @@ void LLWorld::printPacketsLost() << " packets lost: " << cdp->getPacketsLost() << LL_ENDL; } } + LL_INFOS() << "Packets dropped by Packet Ring: " << gMessageSystem->mPacketRing.getNumDroppedPackets() << LL_ENDL; } void LLWorld::processCoarseUpdate(LLMessageSystem* msg, void** user_data) diff --git a/indra/newview/llworldmipmap.cpp b/indra/newview/llworldmipmap.cpp index d8ea2b884f..78151ebd1c 100644 --- a/indra/newview/llworldmipmap.cpp +++ b/indra/newview/llworldmipmap.cpp @@ -148,6 +148,11 @@ LLPointer<LLViewerFetchedTexture> LLWorldMipmap::getObjectsTile(U32 grid_x, U32 { // Load it LLPointer<LLViewerFetchedTexture> img = loadObjectsTile(grid_x, grid_y, level); + if(img == nullptr) + { + LL_ERRS() << "loadObjectsTile() failed" << LL_ENDL; + return NULL; + } // Insert the image in the map level_mipmap.insert(sublevel_tiles_t::value_type( handle, img )); // Find the element again in the map (it's there now...) @@ -162,6 +167,12 @@ LLPointer<LLViewerFetchedTexture> LLWorldMipmap::getObjectsTile(U32 grid_x, U32 // Get the image pointer and check if this asset is missing LLPointer<LLViewerFetchedTexture> img = found->second; + if(img == nullptr) + { + LL_ERRS() << "img is NULL" << LL_ENDL; + return NULL; + } + if (img->isMissingAsset()) { // Return NULL if asset missing @@ -191,6 +202,12 @@ LLPointer<LLViewerFetchedTexture> LLWorldMipmap::loadObjectsTile(U32 grid_x, U32 //LL_INFOS("WorldMap") << "LLWorldMipmap::loadObjectsTile(), URL = " << imageurl << LL_ENDL; LLPointer<LLViewerFetchedTexture> img = LLViewerTextureManager::getFetchedTextureFromUrl(imageurl, FTT_MAP_TILE, true, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE); + + if(img == nullptr) + { + LL_ERRS() << "fetching map tile FAILED from " << imageurl << LL_ENDL; + return nullptr; + } LL_INFOS("MAPURL") << "fetching map tile from " << imageurl << LL_ENDL; img->setBoostLevel(LLGLTexture::BOOST_MAP); diff --git a/indra/newview/mpfloatertuning.cpp b/indra/newview/mpfloatertuning.cpp new file mode 100644 index 0000000000..1a3e4cf718 --- /dev/null +++ b/indra/newview/mpfloatertuning.cpp @@ -0,0 +1,87 @@ +/** +* @file mpfloatertuning.cpp +* @brief Controller for viewer tuning +* @author observeur@megapahit.net +* +* $LicenseInfo:firstyear=2014&license=viewerlgpl$ +* Second Life Viewer Source Code +* Copyright (C) 2014, Linden Research, Inc. +* +* This library is free software; you can redistribute it and/or +* modify it under the terms of the GNU Lesser General Public +* License as published by the Free Software Foundation; +* version 2.1 of the License only. +* +* This library is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public +* License along with this library; if not, write to the Free Software +* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +* +* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA +* $/LicenseInfo$ +*/ + +#include "llviewerprecompiledheaders.h" + +#include "mpfloatertuning.h" +#include "llsliderctrl.h" +#include "lltextbox.h" +#include "llcheckboxctrl.h" +#include "llcombobox.h" +#include "llviewercontrol.h" +#include "llsdserialize.h" + +MPFloaterTuning::MPFloaterTuning(const LLSD& key) : LLFloater(key) +{ +} + +void MPFloaterTuning::syncFromPreferenceSetting(void *user_data) +{ + MPFloaterTuning *self = static_cast<MPFloaterTuning*>(user_data); + + U32 fps = gSavedSettings.getU32("MaxFPS"); + if(fps==0) fps=132; + + LLSliderCtrl* fpsSliderCtrl = self->getChild<LLSliderCtrl>("fpsSlider"); + fpsSliderCtrl->setValue(fps,FALSE); + + LLTextBox* fpsText = self->getChild<LLTextBox>("fpsText"); + if(fps>120) fpsText->setValue("no limit"); + else fpsText->setValue(std::to_string(fps)+" fps"); +} + +bool MPFloaterTuning::postBuild() +{ + LLSliderCtrl* fpsSliderCtrl = getChild<LLSliderCtrl>("fpsSlider"); + fpsSliderCtrl->setMinValue(12); + fpsSliderCtrl->setMaxValue(132); + fpsSliderCtrl->setSliderMouseUpCallback(boost::bind(&MPFloaterTuning::onFinalCommit,this)); + + LLTextBox* fpsText = getChild<LLTextBox>("fpsText"); + fpsText->setValue(""); + + syncFromPreferenceSetting(this); + + return TRUE; +} + +// Do send-to-the-server work when slider drag completes, or new +// value entered as text. +void MPFloaterTuning::onFinalCommit() +{ + LLSliderCtrl* fpsSliderCtrl = getChild<LLSliderCtrl>("fpsSlider"); + U32 fps = (U32)fpsSliderCtrl->getValueF32(); + gSavedSettings.setU32("MaxFPS",fps); + + LLTextBox* fpsText = getChild<LLTextBox>("fpsText"); + if(fps>120) fpsText->setValue("no limit"); + else fpsText->setValue(std::to_string(fps)+" fps"); +} + +void MPFloaterTuning::onClose(bool app_quitting) +{ +} diff --git a/indra/newview/mpfloatertuning.h b/indra/newview/mpfloatertuning.h new file mode 100644 index 0000000000..9e9c7f174f --- /dev/null +++ b/indra/newview/mpfloatertuning.h @@ -0,0 +1,48 @@ +/** +* @file mpfloatertuning.h +* @brief Controller for viewer tuning +* @author observeur@megapahit.net +* +* $LicenseInfo:firstyear=2014&license=viewerlgpl$ +* Second Life Viewer Source Code +* Copyright (C) 2014, Linden Research, Inc. +* +* This library is free software; you can redistribute it and/or +* modify it under the terms of the GNU Lesser General Public +* License as published by the Free Software Foundation; +* version 2.1 of the License only. +* +* This library is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public +* License along with this library; if not, write to the Free Software +* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +* +* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA +* $/LicenseInfo$ +*/ +#ifndef LL_MPFLOATERTUNING_H +#define LL_MPFLOATERTUNING_H + +#include "llfloater.h" + +class MPFloaterTuning: public LLFloater +{ +public: + MPFloaterTuning(const LLSD& key); + + bool postBuild(); + + void onFinalCommit(); + + static void syncFromPreferenceSetting(void *user_data); + + //void updateEditEnabled(); + + /*virtual*/ void onClose(bool app_quitting); +}; + +#endif diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 1ca67dd88a..076459a7b2 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -144,6 +144,7 @@ U32 LLPipeline::RenderFSAAType; U32 LLPipeline::RenderResolutionDivisor; bool LLPipeline::RenderUIBuffer; S32 LLPipeline::RenderShadowDetail; +S32 LLPipeline::MPRenderShadowOpti; S32 LLPipeline::RenderShadowSplits; bool LLPipeline::RenderDeferredSSAO; F32 LLPipeline::RenderShadowResolutionScale; @@ -431,6 +432,7 @@ void LLPipeline::init() stop_glerror(); //create render pass pools + getPool(LLDrawPool::POOL_WATEREXCLUSION); getPool(LLDrawPool::POOL_ALPHA_PRE_WATER); getPool(LLDrawPool::POOL_ALPHA_POST_WATER); getPool(LLDrawPool::POOL_SIMPLE); @@ -525,6 +527,7 @@ void LLPipeline::init() connectRefreshCachedSettingsSafe("RenderResolutionDivisor"); connectRefreshCachedSettingsSafe("RenderUIBuffer"); connectRefreshCachedSettingsSafe("RenderShadowDetail"); + connectRefreshCachedSettingsSafe("MPRenderShadowOpti"); connectRefreshCachedSettingsSafe("RenderShadowSplits"); connectRefreshCachedSettingsSafe("RenderDeferredSSAO"); connectRefreshCachedSettingsSafe("RenderShadowResolutionScale"); @@ -673,6 +676,8 @@ void LLPipeline::cleanup() // don't delete wl sky pool it was handled above in the for loop //delete mWLSkyPool; mWLSkyPool = NULL; + delete mWaterExclusionPool; + mWaterExclusionPool = nullptr; releaseGLBuffers(); @@ -726,7 +731,9 @@ void LLPipeline::resizeShadowTexture() { releaseSunShadowTargets(); releaseSpotShadowTargets(); - allocateShadowBuffer(mRT->width, mRT->height); + GLuint resX = gViewerWindow->getWorldViewWidthRaw(); + GLuint resY = gViewerWindow->getWorldViewHeightRaw(); + allocateShadowBuffer(resX, resY); gResizeShadowTexture = false; } @@ -907,6 +914,15 @@ bool LLPipeline::allocateScreenBufferInternal(U32 resX, U32 resY) mPostMap.allocate(resX, resY, screenFormat); + // The water exclusion mask needs its own depth buffer so we can take care of the problem of multiple water planes. + // Should we ever make water not just a plane, it also aids with that as well as the water planes will be rendered into the mask. + // Why do we do this? Because it saves us some janky logic in the exclusion shader when we generate the mask. + // Regardless, this should always only be an R8 texture unless we choose to start having multiple kinds of exclusion that 8 bits can't handle. + // - Geenz 2025-02-06 + bool success = mWaterExclusionMask.allocate(resX, resY, GL_R8, true); + + assert(success); + // used to scale down textures // See LLViwerTextureList::updateImagesCreateTextures and LLImageGL::scaleDown mDownResMap.allocate(1024, 1024, GL_RGBA); @@ -934,7 +950,7 @@ bool LLPipeline::allocateShadowBuffer(U32 resX, U32 resY) LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY; S32 shadow_detail = RenderShadowDetail; - F32 scale = gCubeSnapshot ? 1.0f : llmax(0.f, RenderShadowResolutionScale); // Don't scale probe shadow maps + F32 scale = gCubeSnapshot ? 1.0f : llmax(0.5f, RenderShadowResolutionScale); // Don't scale probe shadow maps U32 sun_shadow_map_width = BlurHappySize(resX, scale); U32 sun_shadow_map_height = BlurHappySize(resY, scale); @@ -992,7 +1008,7 @@ bool LLPipeline::allocateShadowBuffer(U32 resX, U32 resY) gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_ANISOTROPIC); gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_CLAMP); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL); } } @@ -1009,7 +1025,7 @@ bool LLPipeline::allocateShadowBuffer(U32 resX, U32 resY) gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_ANISOTROPIC); gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_CLAMP); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL); } } @@ -1046,6 +1062,7 @@ void LLPipeline::refreshCachedSettings() RenderResolutionDivisor = gSavedSettings.getU32("RenderResolutionDivisor"); RenderUIBuffer = gSavedSettings.getBOOL("RenderUIBuffer"); RenderShadowDetail = gSavedSettings.getS32("RenderShadowDetail"); + MPRenderShadowOpti = gSavedSettings.getS32("MPRenderShadowOpti"); RenderShadowSplits = gSavedSettings.getS32("RenderShadowSplits"); RenderDeferredSSAO = gSavedSettings.getBOOL("RenderDeferredSSAO"); RenderShadowResolutionScale = gSavedSettings.getF32("RenderShadowResolutionScale"); @@ -1166,6 +1183,8 @@ void LLPipeline::releaseGLBuffers() mSceneMap.release(); + mWaterExclusionMask.release(); + mPostMap.release(); mFXAAMap.release(); @@ -1398,7 +1417,18 @@ void LLPipeline::createLUTBuffers() { U32 lightResX = gSavedSettings.getU32("RenderSpecularResX"); U32 lightResY = gSavedSettings.getU32("RenderSpecularResY"); - F32* ls = new F32[lightResX*lightResY]; + F32* ls = nullptr; + try + { + ls = new F32[lightResX*lightResY]; + } + catch (std::bad_alloc&) + { + LLError::LLUserWarningMsg::showOutOfMemory(); + // might be better to set the error into mFatalMessage and rethrow + LL_ERRS() << "Bad memory allocation in createLUTBuffers! lightResX: " + << lightResX << " lightResY: " << lightResY << LL_ENDL; + } F32 specExp = gSavedSettings.getF32("RenderSpecularExponent"); // Calculate the (normalized) blinn-phong specular lookup texture. (with a few tweaks) for (U32 y = 0; y < lightResY; ++y) @@ -1425,7 +1455,7 @@ void LLPipeline::createLUTBuffers() } U32 pix_format = GL_R16F; -#if LL_DARWIN +#if 0 && LL_DARWIN // Need to work around limited precision with 10.6.8 and older drivers // pix_format = GL_R32F; @@ -1472,7 +1502,7 @@ void LLPipeline::createLUTBuffers() glClearColor(0, 0, 0, 0); mExposureMap.flush(); - mLuminanceMap.allocate(256, 256, GL_R16F, false, LLTexUnit::TT_TEXTURE, LLTexUnit::TMG_AUTO); + mLuminanceMap.allocate(256, 256, GL_R16F, false, LLTexUnit::TT_TEXTURE); mLastExposure.allocate(1, 1, GL_R16F); } @@ -1676,6 +1706,10 @@ LLDrawPool *LLPipeline::findPool(const U32 type, LLViewerTexture *tex0) poolp = mPBRAlphaMaskPool; break; + case LLDrawPool::POOL_WATEREXCLUSION: + poolp = mWaterExclusionPool; + break; + default: llassert(0); LL_ERRS() << "Invalid Pool Type in LLPipeline::findPool() type=" << type << LL_ENDL; @@ -3855,7 +3889,12 @@ void LLPipeline::renderSelectedFaces(const LLColor4& color) for (auto facep : mSelectedFaces) { - if (!facep || facep->getDrawable()->isDead()) + if (!facep || !facep->getViewerObject()) + { + LLSelectMgr::getInstance()->clearSelections(); + return; + } + if (!facep->getDrawable() || facep->getDrawable()->isDead()) { LL_ERRS() << "Bad face on selection" << LL_ENDL; return; @@ -4063,6 +4102,8 @@ void LLPipeline::renderGeomDeferred(LLCamera& camera, bool do_occlusion) } } +// Render all of our geometry that's required after our deferred pass. +// This is gonna be stuff like alpha, water, etc. void LLPipeline::renderGeomPostDeferred(LLCamera& camera) { LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; @@ -4079,6 +4120,10 @@ void LLPipeline::renderGeomPostDeferred(LLCamera& camera) bool done_atmospherics = LLPipeline::sRenderingHUDs; //skip atmospherics on huds bool done_water_haze = done_atmospherics; + bool done_water_exclusion = false; + + // do water exclusion just before water pass. + U32 water_exclusion_pass = LLDrawPool::POOL_WATEREXCLUSION; // do atmospheric haze just before post water alpha U32 atmospherics_pass = LLDrawPool::POOL_ALPHA_POST_WATER; @@ -4117,6 +4162,12 @@ void LLPipeline::renderGeomPostDeferred(LLCamera& camera) cur_type = poolp->getType(); + if (cur_type >= water_exclusion_pass && !done_water_exclusion) + { // do water exclusion against depth buffer before rendering alpha + doWaterExclusionMask(); + done_water_exclusion = true; + } + if (cur_type >= atmospherics_pass && !done_atmospherics) { // do atmospherics against depth buffer before rendering alpha doAtmospherics(); @@ -4494,6 +4545,7 @@ void LLPipeline::renderDebug() LLGLDisable cull(i >= 2 ? GL_CULL_FACE : 0); gGL.flush(); + glPolygonMode( GL_FRONT_AND_BACK, GL_FILL ); //get rid of some z-fighting @@ -5196,6 +5248,17 @@ void LLPipeline::addToQuickLookup( LLDrawPool* new_poolp ) } break; + case LLDrawPool::POOL_WATEREXCLUSION: + if (mWaterExclusionPool) + { + llassert(0); + LL_WARNS() << "LLPipeline::addPool(): Ignoring duplicate Water Exclusion Pool" << LL_ENDL; + } + else + { + mWaterExclusionPool = new_poolp; + } + break; default: llassert(0); @@ -5318,6 +5381,11 @@ void LLPipeline::removeFromQuickLookup( LLDrawPool* poolp ) mPBRAlphaMaskPool = NULL; break; + case LLDrawPool::POOL_WATEREXCLUSION: + llassert(poolp == mWaterExclusionPool); + mWaterExclusionPool = nullptr; + break; + default: llassert(0); LL_WARNS() << "Invalid Pool Type in LLPipeline::removeFromQuickLookup() type=" << poolp->getType() << LL_ENDL; @@ -6918,7 +6986,7 @@ void apply_cube_face_rotation(U32 face) void validate_framebuffer_object() { GLenum status; - status = glCheckFramebufferStatus(GL_FRAMEBUFFER_EXT); + status = glCheckFramebufferStatus(GL_FRAMEBUFFER); switch(status) { case GL_FRAMEBUFFER_COMPLETE: @@ -7076,7 +7144,7 @@ void LLPipeline::generateExposure(LLRenderTarget* src, LLRenderTarget* dst, bool LLSettingsSky::ptr_t sky = LLEnvironment::instance().getCurrentSky(); - F32 probe_ambiance = LLEnvironment::instance().getCurrentSky()->getReflectionProbeAmbiance(should_auto_adjust); + F32 probe_ambiance = LLEnvironment::instance().getCurrentSky()->getReflectionProbeAmbiance(should_auto_adjust()); F32 exp_min = 1.f; F32 exp_max = 1.f; @@ -7087,13 +7155,13 @@ void LLPipeline::generateExposure(LLRenderTarget* src, LLRenderTarget* dst, bool { if (dynamic_exposure_enabled) { - exp_min = sky->getHDROffset() - sky->getHDRMin(); - exp_max = sky->getHDROffset() + sky->getHDRMax(); + exp_min = sky->getHDROffset(should_auto_adjust()) - sky->getHDRMin(should_auto_adjust()); + exp_max = sky->getHDROffset(should_auto_adjust()) + sky->getHDRMax(should_auto_adjust()); } else { - exp_min = sky->getHDROffset(); - exp_max = sky->getHDROffset(); + exp_min = sky->getHDROffset(should_auto_adjust()); + exp_max = sky->getHDROffset(should_auto_adjust()); } } else if (dynamic_exposure_enabled) @@ -7113,7 +7181,7 @@ void LLPipeline::generateExposure(LLRenderTarget* src, LLRenderTarget* dst, bool shader->uniform1f(dt, gFrameIntervalSeconds); shader->uniform2f(noiseVec, ll_frand() * 2.0f - 1.0f, ll_frand() * 2.0f - 1.0f); shader->uniform4f(dynamic_exposure_params, dynamic_exposure_coefficient, exp_min, exp_max, dynamic_exposure_speed_error); - shader->uniform4f(dynamic_exposure_params2, sky->getHDROffset(), exp_min, exp_max, dynamic_exposure_speed_target); + shader->uniform4f(dynamic_exposure_params2, sky->getHDROffset(should_auto_adjust()), exp_min, exp_max, dynamic_exposure_speed_target); mScreenTriangleVB->setBuffer(); mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3); @@ -7146,7 +7214,7 @@ void LLPipeline::tonemap(LLRenderTarget* src, LLRenderTarget* dst) LLSettingsSky::ptr_t psky = LLEnvironment::instance().getCurrentSky(); - bool no_post = gSnapshotNoPost || psky->getReflectionProbeAmbiance(should_auto_adjust) == 0.f || (buildNoPost && gFloaterTools->isAvailable()); + bool no_post = gSnapshotNoPost || psky->getReflectionProbeAmbiance(should_auto_adjust) == 0.f || (buildNoPost && gFloaterTools && gFloaterTools->isAvailable()); LLGLSLShader& shader = no_post ? gNoPostTonemapProgram : gDeferredPostTonemapProgram; shader.bind(); @@ -7171,7 +7239,7 @@ void LLPipeline::tonemap(LLRenderTarget* src, LLRenderTarget* dst) static LLCachedControl<U32> tonemap_type_setting(gSavedSettings, "RenderTonemapType", 0U); shader.uniform1i(tonemap_type, tonemap_type_setting); - shader.uniform1f(tonemap_mix, psky->getTonemapMix()); + shader.uniform1f(tonemap_mix, psky->getTonemapMix(should_auto_adjust())); mScreenTriangleVB->setBuffer(); mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3); @@ -7480,7 +7548,8 @@ void LLPipeline::applyFXAA(LLRenderTarget* src, LLRenderTarget* dst) void LLPipeline::generateSMAABuffers(LLRenderTarget* src) { llassert(!gCubeSnapshot); - bool multisample = RenderFSAAType == 2 && gSMAAEdgeDetectProgram[0].isComplete() && mFXAAMap.isComplete() && mSMAABlendBuffer.isComplete(); + if(RenderFSAAType < 2) return; + bool multisample = gSMAAEdgeDetectProgram[0].isComplete() && mFXAAMap.isComplete() && mSMAABlendBuffer.isComplete(); // Present everything. if (multisample) @@ -7598,7 +7667,13 @@ void LLPipeline::generateSMAABuffers(LLRenderTarget* src) void LLPipeline::applySMAA(LLRenderTarget* src, LLRenderTarget* dst) { llassert(!gCubeSnapshot); - bool multisample = RenderFSAAType == 2 && gSMAAEdgeDetectProgram[0].isComplete() && mFXAAMap.isComplete() && mSMAABlendBuffer.isComplete(); + + bool multisample = false; + + if(RenderFSAAType > 1) + { + multisample = gSMAAEdgeDetectProgram[0].isComplete() && mFXAAMap.isComplete() && mSMAABlendBuffer.isComplete(); + } // Present everything. if (multisample) @@ -8391,13 +8466,13 @@ void LLPipeline::renderDeferredLighting() setupHWLights(); // to set mSun/MoonDir; - glm::vec4 tc(glm::make_vec4(mSunDir.mV)); + glm::vec4 tc(mSunDir); tc = mat * tc; - mTransformedSunDir.set(glm::value_ptr(tc)); + mTransformedSunDir.set(tc); - glm::vec4 tc_moon(glm::make_vec4(mMoonDir.mV)); + glm::vec4 tc_moon(mMoonDir); tc_moon = mat * tc_moon; - mTransformedMoonDir.set(glm::value_ptr(tc_moon)); + mTransformedMoonDir.set(tc_moon); if ((RenderDeferredSSAO && !gCubeSnapshot) || RenderShadowDetail > 0) { @@ -8650,7 +8725,7 @@ void LLPipeline::renderDeferredLighting() continue; } - glm::vec3 tc(glm::make_vec3(c)); + glm::vec3 tc(center); tc = mul_mat4_vec3(mat, tc); fullscreen_lights.push_back(LLVector4(tc.x, tc.y, tc.z, s)); @@ -8757,13 +8832,12 @@ void LLPipeline::renderDeferredLighting() LLDrawable* drawablep = *iter; LLVOVolume* volume = drawablep->getVOVolume(); LLVector3 center = drawablep->getPositionAgent(); - F32* c = center.mV; F32 light_size_final = volume->getLightRadius() * 1.5f; F32 light_falloff_final = volume->getLightFalloff(DEFERRED_LIGHT_FALLOFF); sVisibleLightCount++; - glm::vec3 tc(glm::make_vec3(c)); + glm::vec3 tc(center); tc = mul_mat4_vec3(mat, tc); setupSpotLight(gDeferredMultiSpotLightProgram, drawablep); @@ -8820,6 +8894,7 @@ void LLPipeline::renderDeferredLighting() LLPipeline::RENDER_TYPE_FULLBRIGHT_ALPHA_MASK, LLPipeline::RENDER_TYPE_TERRAIN, LLPipeline::RENDER_TYPE_WATER, + LLPipeline::RENDER_TYPE_WATEREXCLUSION, END_RENDER_TYPES); renderGeomPostDeferred(*LLViewerCamera::getInstance()); @@ -8958,6 +9033,8 @@ void LLPipeline::doWaterHaze() static LLStaticHashedString above_water_str("above_water"); haze_shader.uniform1i(above_water_str, sUnderWaterRender ? -1 : 1); + haze_shader.bindTexture(LLShaderMgr::WATER_EXCLUSIONTEX, &mWaterExclusionMask); + if (LLPipeline::sUnderWaterRender) { LLGLDepthTest depth(GL_FALSE); @@ -8988,6 +9065,17 @@ void LLPipeline::doWaterHaze() } } +void LLPipeline::doWaterExclusionMask() +{ + mWaterExclusionMask.bindTarget(); + glClearColor(1, 1, 1, 1); + mWaterExclusionMask.clear(); + mWaterExclusionPool->render(); + + mWaterExclusionMask.flush(); + glClearColor(0, 0, 0, 0); +} + void LLPipeline::setupSpotLight(LLGLSLShader& shader, LLDrawable* drawablep) { //construct frustum @@ -9210,6 +9298,7 @@ void LLPipeline::bindReflectionProbes(LLGLSLShader& shader) S32 channel = shader.enableTexture(LLShaderMgr::REFLECTION_PROBES, LLTexUnit::TT_CUBE_MAP_ARRAY); bool bound = false; + if (channel > -1 && mReflectionMapManager.mTexture.notNull()) { mReflectionMapManager.mTexture->bind(channel); @@ -9405,7 +9494,6 @@ void LLPipeline::renderShadow(const glm::mat4& view, const glm::mat4& proj, LLCa } }; - LLVertexBuffer::unbind(); for (int j = 0; j < 2; ++j) // 0 -- static, 1 -- rigged { @@ -9447,6 +9535,7 @@ void LLPipeline::renderShadow(const glm::mat4& view, const glm::mat4& proj, LLCa renderGeomShadow(shadow_cam); } + if(MPRenderShadowOpti < 3) { LL_PROFILE_ZONE_NAMED_CATEGORY_PIPELINE("shadow alpha"); LL_PROFILE_GPU_ZONE("shadow alpha"); @@ -9777,7 +9866,7 @@ public: void LLPipeline::generateSunShadow(LLCamera& camera) { - if (!sRenderDeferred || RenderShadowDetail <= 0) + if (!sRenderDeferred || RenderShadowDetail <= 0 || (MPRenderShadowOpti > 0 && gCubeSnapshot)) { return; } @@ -9898,10 +9987,7 @@ void LLPipeline::generateSunShadow(LLCamera& camera) LLVector3 lightDir = -caster_dir; lightDir.normVec(); - glm::vec3 light_dir(glm::make_vec3(lightDir.mV)); - //create light space camera matrix - LLVector3 at = lightDir; LLVector3 up = camera.getAtAxis(); @@ -9953,9 +10039,9 @@ void LLPipeline::generateSunShadow(LLCamera& camera) //get good split distances for frustum for (U32 i = 0; i < fp.size(); ++i) { - glm::vec3 v(glm::make_vec3(fp[i].mV)); + glm::vec3 v(fp[i]); v = mul_mat4_vec3(saved_view, v); - fp[i].setVec(glm::value_ptr(v)); + fp[i] = LLVector3(v); } min = fp[0]; @@ -10062,8 +10148,12 @@ void LLPipeline::generateSunShadow(LLCamera& camera) std::vector<LLVector3> fp; + U32 splits = 3; + if(MPRenderShadowOpti == 1) splits = 2; + else if(MPRenderShadowOpti >= 2) splits = 1; + if (!gPipeline.getVisiblePointCloud(shadow_cam, min, max, fp, lightDir) - || j > RenderShadowSplits) + || j > splits) { //no possible shadow receivers if (!gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_SHADOW_FRUSTA) && !gCubeSnapshot) @@ -10104,9 +10194,9 @@ void LLPipeline::generateSunShadow(LLCamera& camera) for (U32 i = 0; i < fp.size(); i++) { - glm::vec3 p = glm::make_vec3(fp[i].mV); + glm::vec3 p(fp[i]); p = mul_mat4_vec3(view[j], p); - wpf.push_back(LLVector3(glm::value_ptr(p))); + wpf.push_back(LLVector3(p)); } min = wpf[0]; @@ -10307,19 +10397,19 @@ void LLPipeline::generateSunShadow(LLCamera& camera) view[j] = glm::inverse(view[j]); //llassert(origin.isFinite()); - glm::vec3 origin_agent(glm::make_vec3(origin.mV)); + glm::vec3 origin_agent(origin); //translate view to origin origin_agent = mul_mat4_vec3(view[j], origin_agent); - eye = LLVector3(glm::value_ptr(origin_agent)); + eye = LLVector3(origin_agent); //llassert(eye.isFinite()); if (!hasRenderDebugMask(LLPipeline::RENDER_DEBUG_SHADOW_FRUSTA) && !gCubeSnapshot) { mShadowFrustOrigin[j] = eye; } - view[j] = look(LLVector3(glm::value_ptr(origin_agent)), lightDir, -up); + view[j] = look(LLVector3(origin_agent), lightDir, -up); F32 fx = 1.f/tanf(fovx); F32 fz = 1.f/tanf(fovz); diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h index 5c9b95ef4a..da9b8189e2 100644 --- a/indra/newview/pipeline.h +++ b/indra/newview/pipeline.h @@ -337,6 +337,9 @@ public: // should be called just before rendering pre-water alpha objects void doWaterHaze(); + // Generate the water exclusion surface mask. + void doWaterExclusionMask(); + void postDeferredGammaCorrect(LLRenderTarget* screen_target); void generateSunShadow(LLCamera& camera); @@ -500,6 +503,7 @@ public: RENDER_TYPE_AVATAR = LLDrawPool::POOL_AVATAR, RENDER_TYPE_CONTROL_AV = LLDrawPool::POOL_CONTROL_AV, // Animesh RENDER_TYPE_TREE = LLDrawPool::POOL_TREE, + RENDER_TYPE_WATEREXCLUSION = LLDrawPool::POOL_WATEREXCLUSION, RENDER_TYPE_VOIDWATER = LLDrawPool::POOL_VOIDWATER, RENDER_TYPE_WATER = LLDrawPool::POOL_WATER, RENDER_TYPE_GLTF_PBR = LLDrawPool::POOL_GLTF_PBR, @@ -698,7 +702,7 @@ public: LLRenderTarget shadow[4]; }; - // main full resoltuion render target + // main full resolution render target RenderTargetPack mMainRT; // auxillary 512x512 render target pack @@ -714,6 +718,7 @@ public: LLRenderTarget mSpotShadow[2]; LLRenderTarget mPbrBrdfLut; + LLRenderTarget mWaterExclusionMask; // copy of the color/depth buffer just before gamma correction // for use by SSR @@ -953,6 +958,7 @@ protected: LLDrawPool* mWLSkyPool = nullptr; LLDrawPool* mPBROpaquePool = nullptr; LLDrawPool* mPBRAlphaMaskPool = nullptr; + LLDrawPool* mWaterExclusionPool = nullptr; // Note: no need to keep an quick-lookup to avatar pools, since there's only one per avatar @@ -1005,6 +1011,7 @@ public: static U32 RenderResolutionDivisor; static bool RenderUIBuffer; static S32 RenderShadowDetail; + static S32 MPRenderShadowOpti; static S32 RenderShadowSplits; static bool RenderDeferredSSAO; static F32 RenderShadowResolutionScale; diff --git a/indra/newview/res-sdl/arrow.BMP b/indra/newview/res-sdl/arrow.BMP Binary files differindex a8f6da64b5..1b1e1dcf9c 100644 --- a/indra/newview/res-sdl/arrow.BMP +++ b/indra/newview/res-sdl/arrow.BMP diff --git a/indra/newview/res-sdl/arrowcop.BMP b/indra/newview/res-sdl/arrowcop.BMP Binary files differindex 1a26a0df34..29ae16c6ed 100644 --- a/indra/newview/res-sdl/arrowcop.BMP +++ b/indra/newview/res-sdl/arrowcop.BMP diff --git a/indra/newview/res-sdl/arrowcopmulti.BMP b/indra/newview/res-sdl/arrowcopmulti.BMP Binary files differindex 48f153cef6..d1c089c266 100644 --- a/indra/newview/res-sdl/arrowcopmulti.BMP +++ b/indra/newview/res-sdl/arrowcopmulti.BMP diff --git a/indra/newview/res-sdl/arrowdrag.BMP b/indra/newview/res-sdl/arrowdrag.BMP Binary files differindex cd868eec20..2a29183d64 100644 --- a/indra/newview/res-sdl/arrowdrag.BMP +++ b/indra/newview/res-sdl/arrowdrag.BMP diff --git a/indra/newview/res-sdl/circleandline.BMP b/indra/newview/res-sdl/circleandline.BMP Binary files differindex 284ae8b7d5..dd630db676 100644 --- a/indra/newview/res-sdl/circleandline.BMP +++ b/indra/newview/res-sdl/circleandline.BMP diff --git a/indra/newview/res-sdl/hand.BMP b/indra/newview/res-sdl/hand.BMP Binary files differindex 2a092fbb7f..ee315cf521 100644 --- a/indra/newview/res-sdl/hand.BMP +++ b/indra/newview/res-sdl/hand.BMP diff --git a/indra/newview/res-sdl/ibeam.BMP b/indra/newview/res-sdl/ibeam.BMP Binary files differindex 820904a228..80a4576eb3 100644 --- a/indra/newview/res-sdl/ibeam.BMP +++ b/indra/newview/res-sdl/ibeam.BMP diff --git a/indra/newview/res-sdl/llarrow.BMP b/indra/newview/res-sdl/llarrow.BMP Binary files differindex a8f6da64b5..13d9cd5910 100644 --- a/indra/newview/res-sdl/llarrow.BMP +++ b/indra/newview/res-sdl/llarrow.BMP diff --git a/indra/newview/res-sdl/llarrowdrag.BMP b/indra/newview/res-sdl/llarrowdrag.BMP Binary files differindex cd868eec20..2a29183d64 100644 --- a/indra/newview/res-sdl/llarrowdrag.BMP +++ b/indra/newview/res-sdl/llarrowdrag.BMP diff --git a/indra/newview/res-sdl/llarrowdragmulti.BMP b/indra/newview/res-sdl/llarrowdragmulti.BMP Binary files differindex fb528bc92d..265b80622d 100644 --- a/indra/newview/res-sdl/llarrowdragmulti.BMP +++ b/indra/newview/res-sdl/llarrowdragmulti.BMP diff --git a/indra/newview/res-sdl/llarrowlocked.BMP b/indra/newview/res-sdl/llarrowlocked.BMP Binary files differindex 0aaa441ab1..8a310a71d7 100644 --- a/indra/newview/res-sdl/llarrowlocked.BMP +++ b/indra/newview/res-sdl/llarrowlocked.BMP diff --git a/indra/newview/res-sdl/llgrablocked.BMP b/indra/newview/res-sdl/llgrablocked.BMP Binary files differindex 847439670f..6c8d40891c 100644 --- a/indra/newview/res-sdl/llgrablocked.BMP +++ b/indra/newview/res-sdl/llgrablocked.BMP diff --git a/indra/newview/res-sdl/llno.BMP b/indra/newview/res-sdl/llno.BMP Binary files differindex 284ae8b7d5..dd630db676 100644 --- a/indra/newview/res-sdl/llno.BMP +++ b/indra/newview/res-sdl/llno.BMP diff --git a/indra/newview/res-sdl/llnolocked.BMP b/indra/newview/res-sdl/llnolocked.BMP Binary files differindex 61f0170cb3..40893c9982 100644 --- a/indra/newview/res-sdl/llnolocked.BMP +++ b/indra/newview/res-sdl/llnolocked.BMP diff --git a/indra/newview/res-sdl/lltoolgrab.BMP b/indra/newview/res-sdl/lltoolgrab.BMP Binary files differindex f2ac68bf3c..91220ec354 100644 --- a/indra/newview/res-sdl/lltoolgrab.BMP +++ b/indra/newview/res-sdl/lltoolgrab.BMP diff --git a/indra/newview/res-sdl/lltoolrotate.BMP b/indra/newview/res-sdl/lltoolrotate.BMP Binary files differindex dd84673018..6115984c62 100644 --- a/indra/newview/res-sdl/lltoolrotate.BMP +++ b/indra/newview/res-sdl/lltoolrotate.BMP diff --git a/indra/newview/res-sdl/lltoolscale.BMP b/indra/newview/res-sdl/lltoolscale.BMP Binary files differindex 882515e5e3..7782817d9b 100644 --- a/indra/newview/res-sdl/lltoolscale.BMP +++ b/indra/newview/res-sdl/lltoolscale.BMP diff --git a/indra/newview/res-sdl/lltooltranslate.BMP b/indra/newview/res-sdl/lltooltranslate.BMP Binary files differindex d084f6a026..4fd761bc9b 100644 --- a/indra/newview/res-sdl/lltooltranslate.BMP +++ b/indra/newview/res-sdl/lltooltranslate.BMP diff --git a/indra/newview/res-sdl/sizeall.BMP b/indra/newview/res-sdl/sizeall.BMP Binary files differindex 03d9bf4654..70b9549d17 100644 --- a/indra/newview/res-sdl/sizeall.BMP +++ b/indra/newview/res-sdl/sizeall.BMP diff --git a/indra/newview/res-sdl/sizenesw.BMP b/indra/newview/res-sdl/sizenesw.BMP Binary files differindex 559579f40e..a7f1804dbc 100644 --- a/indra/newview/res-sdl/sizenesw.BMP +++ b/indra/newview/res-sdl/sizenesw.BMP diff --git a/indra/newview/res-sdl/sizens.BMP b/indra/newview/res-sdl/sizens.BMP Binary files differindex 8373077dff..91473b2ff0 100644 --- a/indra/newview/res-sdl/sizens.BMP +++ b/indra/newview/res-sdl/sizens.BMP diff --git a/indra/newview/res-sdl/sizenwse.BMP b/indra/newview/res-sdl/sizenwse.BMP Binary files differindex 6d069fa765..6c82a68e2a 100644 --- a/indra/newview/res-sdl/sizenwse.BMP +++ b/indra/newview/res-sdl/sizenwse.BMP diff --git a/indra/newview/res-sdl/sizewe.BMP b/indra/newview/res-sdl/sizewe.BMP Binary files differindex 878df453a4..cc8c03fe9c 100644 --- a/indra/newview/res-sdl/sizewe.BMP +++ b/indra/newview/res-sdl/sizewe.BMP diff --git a/indra/newview/res-sdl/toolbuy.BMP b/indra/newview/res-sdl/toolbuy.BMP Binary files differindex 07e9273721..bcc1253053 100644 --- a/indra/newview/res-sdl/toolbuy.BMP +++ b/indra/newview/res-sdl/toolbuy.BMP diff --git a/indra/newview/res-sdl/toolmediaopen.BMP b/indra/newview/res-sdl/toolmediaopen.BMP Binary files differindex ac4b231994..670f07235e 100644 --- a/indra/newview/res-sdl/toolmediaopen.BMP +++ b/indra/newview/res-sdl/toolmediaopen.BMP diff --git a/indra/newview/res-sdl/toolopen.BMP b/indra/newview/res-sdl/toolopen.BMP Binary files differindex 5b87979304..ae4908fd35 100644 --- a/indra/newview/res-sdl/toolopen.BMP +++ b/indra/newview/res-sdl/toolopen.BMP diff --git a/indra/newview/res-sdl/toolpause.BMP b/indra/newview/res-sdl/toolpause.BMP Binary files differindex dd2c6857d2..33e9975b69 100644 --- a/indra/newview/res-sdl/toolpause.BMP +++ b/indra/newview/res-sdl/toolpause.BMP diff --git a/indra/newview/res-sdl/toolpickobject.BMP b/indra/newview/res-sdl/toolpickobject.BMP Binary files differindex 25469fc3a8..668bc2713c 100644 --- a/indra/newview/res-sdl/toolpickobject.BMP +++ b/indra/newview/res-sdl/toolpickobject.BMP diff --git a/indra/newview/res-sdl/toolpickobject2.BMP b/indra/newview/res-sdl/toolpickobject2.BMP Binary files differindex 09df69e675..7910837404 100644 --- a/indra/newview/res-sdl/toolpickobject2.BMP +++ b/indra/newview/res-sdl/toolpickobject2.BMP diff --git a/indra/newview/res-sdl/toolpickobject3.BMP b/indra/newview/res-sdl/toolpickobject3.BMP Binary files differindex fc28698050..324268e76b 100644 --- a/indra/newview/res-sdl/toolpickobject3.BMP +++ b/indra/newview/res-sdl/toolpickobject3.BMP diff --git a/indra/newview/res-sdl/toolplay.BMP b/indra/newview/res-sdl/toolplay.BMP Binary files differindex 9c40d7dbec..d0e14838e9 100644 --- a/indra/newview/res-sdl/toolplay.BMP +++ b/indra/newview/res-sdl/toolplay.BMP diff --git a/indra/newview/res-sdl/toolsit.BMP b/indra/newview/res-sdl/toolsit.BMP Binary files differindex 8ce59ae97a..a19bd70f73 100644 --- a/indra/newview/res-sdl/toolsit.BMP +++ b/indra/newview/res-sdl/toolsit.BMP diff --git a/indra/newview/res-sdl/wait.BMP b/indra/newview/res-sdl/wait.BMP Binary files differindex 26dec59afe..a4f3c5b531 100644 --- a/indra/newview/res-sdl/wait.BMP +++ b/indra/newview/res-sdl/wait.BMP diff --git a/indra/newview/res-sdl/working.BMP b/indra/newview/res-sdl/working.BMP Binary files differindex 26dec59afe..a4f3c5b531 100644 --- a/indra/newview/res-sdl/working.BMP +++ b/indra/newview/res-sdl/working.BMP diff --git a/indra/newview/secondlife.icns b/indra/newview/secondlife.icns Binary files differindex 4560d4bb24..f082c8872b 100644 --- a/indra/newview/secondlife.icns +++ b/indra/newview/secondlife.icns diff --git a/indra/newview/skins/contrast/colors.xml b/indra/newview/skins/contrast/colors.xml new file mode 100644 index 0000000000..f049940e3e --- /dev/null +++ b/indra/newview/skins/contrast/colors.xml @@ -0,0 +1,1001 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<colors> + + <!-- Named Colors --> + <color + name="EmphasisColor" + value="0.24 0.54 0.78 1" /> + <color + name="EmphasisColor_13" + value="0.24 0.54 0.84 0.13" /> + <color + name="EmphasisColor_35" + value="0.24 0.54 0.84 0.35" /> + <color + name="BeaconColor" + value="0.24 0.54 0.84 1" /> + <color + name="White" + value="1 1 1 1" /> + <color + name="White_05" + value="1 1 1 0.05" /> + <color + name="White_10" + value="1 1 1 0.1" /> + <color + name="White_25" + value="1 1 1 0.25" /> + <color + name="White_50" + value="1 1 1 0.5" /> + <color + name="LtGray" + value="0.7 0.7 0.7 1" /> + <color + name="LtGray_35" + value="0.7 0.7 0.7 0.35" /> + <color + name="LtGray_50" + value="0.7 0.7 0.7 0.50" /> + <color + name="Gray" + value="0.4 0.4 0.4 1" /> + <color + name="DkGray0" + value="0.05 0.05 0.05 1" /> + <color + name="DkGray" + value="0.08 0.08 0.08 1" /> + <color + name="DkGray_66" + value="0.08 0.08 0.08 .66" /> + <color + name="DkGray2" + value="0.1 0.1 0.1 1" /> + <color + name="MouseGray" + value="0.12 0.12 0.12 1" /> + <color + name="Black" + value="0 0 0 1" /> + <color + name="Black_10" + value="0 0 0 0.1" /> + <color + name="Black_25" + value="0 0 0 0.25" /> + <color + name="Black_50" + value="0 0 0 0.5" /> + <color + name="FrogGreen" + value="0.26 0.33 0.42 1" /> + <!-- ^(Not actually green) --> + <color + name="Red" + value="1 0 0 1" /> + <color + name="Blue" + value="0 0 1 1" /> + <color + name="Yellow" + value="1 1 0 1" /> + <color + name="Green" + value="0 1 0 1" /> + <color + name="Transparent" + value="0 0 0 0" /> + <color + name="Purple" + value="1 0 1 1" /> + <color + name="Lime" + value=".8 1 .73 1" /> + <color + name="LtYellow" + value="1 1 .79 1" /> + <color + name="DrYellow" + value="1 0.86 0 1" /> + <color + name="LtOrange" + value="1 .85 .73 1" /> + <color + name="MdBlue" + value=".07 .38 .51 1" /> + <color + name="DkBlue" + value=".06 .06 .3 1" /> + <color + name="LtRed" + value="1 0.2 0.2 1" /> + <color + name="LtGreen" + value="0.2 1 0.2 1" /> + <color + name="Red_80" + value="1 0 0 0.8" /> + <color + name="DkRed" + value="0.3 0.06 0.06 1" /> + <color + name="Green_80" + value="0 1 0 0.8" /> + <color + name="Blue_80" + value="0 0 1 0.8" /> + <color + name="Orange" + value="1 .82 .46 1" /> + + <!-- This color name makes potentially unused colors show up bright purple. + Leave this here until all Unused? are removed below, otherwise + the viewer generates many warnings on startup. --> + <color + name="Unused?" + value=".831 1 0 1" /> + + <!-- UI Definitions --> + + <color + name="AccordionHeaderTextColor" + reference="Gray" /> + <color + name="AgentChatColor" + reference="White" /> + <color + name="AlertBoxColor" + value="0.24 0.24 0.24 1" /> + <color + name="AlertCautionBoxColor" + value="1 0.82 0.46 1" /> + <color + name="AlertCautionTextColor" + reference="LtYellow" /> + <color + name="AvatarListItemIconDefaultColor" + reference="White" /> + <color + name="AvatarListItemIconOnlineColor" + reference="White" /> + <color + name="AvatarListItemIconOfflineColor" + value="0.5 0.5 0.5 0.5" /> + <color + name="AvatarListItemIconVoiceInvitedColor" + reference="AvatarListItemIconOfflineColor" /> + <color + name="AvatarListItemIconVoiceJoinedColor" + reference="AvatarListItemIconOnlineColor" /> + <color + name="AvatarListItemIconVoiceLeftColor" + reference="AvatarListItemIconOfflineColor" /> + <color + name="BadgeImageColor" + value="1.0 0.40 0.0 1.0" /> + <color + name="BadgeBorderColor" + value="0.9 0.9 0.9 1.0" /> + <color + name="BadgeLabelColor" + reference="White" /> + <color + name="ButtonBorderColor" + reference="Unused?" /> + <color + name="ButtonCautionImageColor" + reference="Unused?" /> + <color + name="ButtonColor" + reference="Unused?" /> + <color + name="ButtonFlashBgColor" + reference="Unused?" /> + <color + name="ButtonImageColor" + reference="White" /> + <color + name="ButtonLabelColor" + reference="LtGray" /> + <color + name="ButtonLabelDisabledColor" + reference="White_25" /> + <color + name="ButtonLabelSelectedColor" + reference="White" /> + <color + name="ButtonLabelSelectedDisabledColor" + reference="White_25" /> + <color + name="ButtonSelectedBgColor" + reference="Unused?" /> + <color + name="ButtonSelectedColor" + reference="Unused?" /> + <color + name="ButtonUnselectedBgColor" + reference="Unused?" /> + <color + name="ButtonUnselectedFgColor" + reference="Unused?" /> + <color + name="ChatHistoryBgColor" + reference="Transparent" /> + <color + name="ChatHistoryTextColor" + reference="LtGray" /> + <color + name="ChicletFlashColor" + value="0.114 0.65 0.1" /> + <color + name="ColorDropShadow" + reference="Black_50" /> + <color + name="ColorPaletteEntry01" + reference="Black" /> + <color + name="ColorPaletteEntry02" + reference="Gray" /> + <color + name="ColorPaletteEntry03" + value="0.5 0 0 1" /> + <color + name="ColorPaletteEntry04" + value="0.5 0.5 0 1" /> + <color + name="ColorPaletteEntry05" + value="0 0.5 0 1" /> + <color + name="ColorPaletteEntry06" + value="0 0.5 0.5 1" /> + <color + name="ColorPaletteEntry07" + value="0 0 0.5 1" /> + <color + name="ColorPaletteEntry08" + value="0.5 0 0.5 1" /> + <color + name="ColorPaletteEntry09" + value="0.5 0.5 0 1" /> + <color + name="ColorPaletteEntry10" + value="0 0.25 0.25 1" /> + <color + name="ColorPaletteEntry11" + value="0 0.5 1 1" /> + <color + name="ColorPaletteEntry12" + value="0 0.25 0.5 1" /> + <color + name="ColorPaletteEntry13" + value="0.5 0 1 1" /> + <color + name="ColorPaletteEntry14" + value="0.5 0.25 0 1" /> + <color + name="ColorPaletteEntry15" + reference="White" /> + <color + name="ColorPaletteEntry16" + reference="LtYellow" /> + <color + name="ColorPaletteEntry17" + reference="White" /> + <color + name="ColorPaletteEntry18" + reference="LtGray" /> + <color + name="ColorPaletteEntry19" + reference="Red" /> + <color + name="ColorPaletteEntry20" + reference="Yellow" /> + <color + name="ColorPaletteEntry21" + reference="Green" /> + <color + name="ColorPaletteEntry22" + value="0 1 1 1" /> + <color + name="ColorPaletteEntry23" + reference="Blue" /> + <color + name="ColorPaletteEntry24" + reference="Purple" /> + <color + name="ColorPaletteEntry25" + value="1 1 0.5 1" /> + <color + name="ColorPaletteEntry26" + value="0 1 0.5 1" /> + <color + name="ColorPaletteEntry27" + value="0.5 1 1 1" /> + <color + name="ColorPaletteEntry28" + value="0.5 0.5 1 1" /> + <color + name="ColorPaletteEntry29" + value="1 0 0.5 1" /> + <color + name="ColorPaletteEntry30" + value="1 0.5 0 1" /> + <color + name="ColorPaletteEntry31" + reference="White" /> + <color + name="ColorPaletteEntry32" + reference="White" /> + <color + name="ComboListBgColor" + reference="DkGray" /> + <color + name="ConsoleBackground" + reference="Black" /> + <color + name="ContextSilhouetteColor" + reference="EmphasisColor" /> + <color + name="ConversationFriendColor" + value="0.5 0.7 0.85 1" /> + <color + name="DefaultHighlightDark" + reference="White_10" /> + <color + name="DefaultHighlightLight" + reference="White_25" /> + <color + name="DefaultShadowDark" + reference="Black_50" /> + <color + name="DefaultShadowLight" + reference="Black_50" /> + <color + name="EffectColor" + reference="White" /> + <color + name="FilterBackgroundColor" + reference="Black" /> + <color + name="FilterTextColor" + reference="EmphasisColor" /> + <color + name="FloaterButtonImageColor" + reference="Gray" /> + <color + name="FloaterDefaultBackgroundColor" + reference="DkGray_66" /> + <color + name="FloaterFocusBackgroundColor" + reference="DkGray2" /> + <color + name="FloaterFocusBorderColor" + reference="Black_50" /> + <color + name="FloaterUnfocusBorderColor" + reference="Black_50" /> + <color + name="FocusColor" + reference="EmphasisColor" /> + <color + name="FolderViewLoadingMessageTextColor" + value="0.3344 0.545 0.645 1" /> + <color + name="FpsTextColor" + value="0.34 0.51 0.64 0.8" /> + <color + name="GridFocusPointColor" + reference="White_50" /> + <color + name="GridlineBGColor" + value="0.92 0.92 1 0.78" /> + <color + name="GridlineColor" + reference="White" /> + <color + name="GridlineShadowColor" + value="0 0 0 0.31" /> + <color + name="GroupNotifyBoxColor" + value="0.3344 0.5456 0.5159 1" /> + <color + name="GroupNotifyTextColor" + reference="White"/> + <color + name="GroupNotifyDimmedTextColor" + reference="LtGray" /> + <color + name="GroupOverTierColor" + value="0.43 0.06 0.06 1" /> + <color + name="HTMLLinkColor" + reference="EmphasisColor" /> + <color + name="HealthTextColor" + reference="White" /> + <color + name="HelpBgColor" + reference="Unused?" /> + <color + name="HelpFgColor" + reference="Unused?" /> + <color + name="HelpScrollHighlightColor" + reference="Unused?" /> + <color + name="HelpScrollShadowColor" + reference="Unused?" /> + <color + name="HelpScrollThumbColor" + reference="Unused?" /> + <color + name="HelpScrollTrackColor" + reference="Unused?" /> + <color + name="HighlightChildColor" + reference="Yellow" /> + <color + name="HighlightInspectColor" + value="1 0 1 1" /> + <color + name="HighlightParentColor" + value="0.5 0.65 0.8 1" /> + <color + name="IMHistoryBgColor" + reference="Unused?" /> + <color + name="IMHistoryTextColor" + reference="Unused?" /> + <color + name="IconDisabledColor" + reference="White_25" /> + <color + name="IconEnabledColor" + reference="White" /> + <color + name="InventoryBackgroundColor" + reference="DkGray2" /> + <color + name="InventoryFocusOutlineColor" + reference="White_25" /> + <color + name="InventoryItemSuffixColor" + reference="White_25" /> + <color + name="InventoryItemLibraryColor" + reference="EmphasisColor" /> + <color + name="InventoryItemLinkColor" + reference="LtGray_50" /> + <color + name="InventoryMouseOverColor" + reference="LtGray_35" /> + <color + name="InventorySearchStatusColor" + reference="EmphasisColor" /> + <color + name="LabelDisabledColor" + reference="White_25" /> + <color + name="LabelSelectedColor" + reference="White" /> + <color + name="LabelSelectedDisabledColor" + reference="White_25" /> + <color + name="LabelTextColor" + reference="LtGray" /> + <color + name="LoginProgressBarBgColor" + reference="Unused?" /> + <color + name="LoginProgressBarFgColor" + reference="Unused?" /> + <color + name="LoginProgressBoxBorderColor" + value="0 0.12 0.24 0" /> + <color + name="LoginProgressBoxCenterColor" + value="0 0 0 0.78" /> + <color + name="LoginProgressBoxShadowColor" + value="0 0 0 0.78" /> + <color + name="LoginProgressBoxTextColor" + reference="White" /> + <color + name="MapAvatarColor" + reference="White" /> + <color + name="MapAvatarFriendColor" + value="0.5 0.7 0.85 1" /> + <color + name="MapAvatarSelfColor" + value="0.53125 0 0.498047 1" /> + <color + name="MapFrustumColor" + reference="White_10" /> + <color + name="MapParcelOutlineColor" + value="1 1 1 0.5" /> + <color + name="MapTrackColor" + reference="Red" /> + <color + name="MapTrackColorUnder" + reference="Blue" /> + <color + name="MapTrackDisabledColor" + value="0.5 0 0 1" /> + <color + name="MenuBarBgColor" + reference="MouseGray" /> + <color + name="MenuBarGodBgColor" + reference="FrogGreen" /> + <color + name="MenuDefaultBgColor" + reference="DkGray2" /> + <color + name="MenuItemDisabledColor" + reference="LtGray_50" /> + <color + name="MenuItemEnabledColor" + reference="LtGray" /> + <color + name="MenuItemHighlightBgColor" + reference="EmphasisColor_35" /> + <color + name="MenuItemFlashBgColor" + reference="BeaconColor" /> + <color + name="MenuItemHighlightFgColor" + reference="White" /> + <color + name="MenuNonProductionBgColor" + reference="Black" /> + <color + name="MenuNonProductionGodBgColor" + value="0.263 0.325 0.345 1" /> + <color + name="MenuPopupBgColor" + reference="DkGray2" /> + <color + name="ModelUploaderLabels" + value="1 0.6 0 1" /> + <color + name="MultiSliderDisabledThumbColor" + reference="Black" /> + <color + name="MultiSliderThumbCenterColor" + reference="White" /> + <color + name="MultiSliderThumbCenterSelectedColor" + reference="Green" /> + <color + name="MultiSliderThumbOutlineColor" + reference="Unused?" /> + <color + name="MultiSliderTrackColor" + reference="LtGray" /> + <color + name="MultiSliderTriangleColor" + reference="Yellow" /> + <!-- + <color + name="NameTagBackground" + value="0.85 0.85 0.85 0.80" /> + --> + <color + name="NameTagBackground" + value="0 0 0 1" /> + <color + name="NameTagChat" + reference="White" /> + <color + name="NameTagFriend" + value="0.5 0.7 0.85 1" /> + <color + name="NameTagLegacy" + reference="White" /> + <color + name="NameTagMatch" + reference="White" /> + <color + name="NameTagMismatch" + reference="White" /> + <color + name="NetMapBackgroundColor" + value="0 0 0 1" /> + <color + name="NetMapGroupOwnAboveWater" + value="0.85 0 0.85 1" /> + <color + name="NetMapGroupOwnBelowWater" + value="0.63 0 0.63 1" /> + <color + name="NetMapOtherOwnAboveWater" + value="0.24 0.24 0.24 1" /> + <color + name="NetMapOtherOwnBelowWater" + value="0.12 0.12 0.12 1" /> + <color + name="NetMapYouOwnAboveWater" + value="0 0.85 0.85 1" /> + <color + name="NetMapYouOwnBelowWater" + value="0 0.63 0.63 1" /> + <color + name="NotifyBoxColor" + value="LtGray" /> + <color + name="NotifyCautionBoxColor" + value="1 0.82 0.46 1" /> + <color + name="NotifyCautionWarnColor" + reference="White" /> + <color + name="NotifyTextColor" + reference="White" /> + <color + name="ObjectBubbleColor" + reference="DkGray_66" /> + <color + name="ObjectChatColor" + reference="LtYellow" /> + <color + name="OverdrivenColor" + reference="Red" /> + <color + name="PanelDefaultBackgroundColor" + reference="DkGray" /> + <color + name="PanelDefaultHighlightLight" + reference="White_50" /> + <color + name="PanelFocusBackgroundColor" + reference="DkGray2" /> + <color + name="PanelNotificationBackground" + value="1 0.3 0.3 0" /> + <color + name="ParcelHoverColor" + reference="White" /> + <color + name="PathfindingErrorColor" + reference="LtRed" /> + <color + name="PathfindingWarningColor" + reference="DrYellow" /> + <color + name="PathfindingGoodColor" + reference="LtGreen" /> + <color + name="MaterialErrorColor" + reference="LtRed" /> + <color + name="MaterialWarningColor" + reference="DrYellow" /> + <color + name="MaterialGoodColor" + reference="LtGreen" /> + <color + name="PathfindingDefaultBeaconColor" + reference="Red_80" /> + <color + name="PathfindingDefaultBeaconTextColor" + reference="White" /> + <color + name="PathfindingLinksetBeaconColor" + reference="Blue_80" /> + <color + name="PathfindingCharacterBeaconColor" + reference="Red_80" /> + <color + name="PieMenuBgColor" + value="0.24 0.24 0.24 0.59" /> + <color + name="PieMenuLineColor" + value="0 0 0 0.5" /> + <color + name="PieMenuSelectedColor" + value="0.72 0.72 0.74 0.3" /> + <color + name="PropertyColorAuction" + value="0.5 0 1 0.4" /> + <color + name="PropertyColorAvail" + reference="Transparent" /> + <color + name="PropertyColorForSale" + value="1 0.5 0 0.4" /> + <color + name="PropertyColorGroup" + value="0 0.72 0.72 0.4" /> + <color + name="PropertyColorOther" + value="1 0 0 0.4" /> + <color + name="PropertyColorSelf" + value="0 1 0 0.4" /> + <color + name="ScriptBgReadOnlyColor" + value="0.39 0.39 0.39 1" /> + <color + name="ScriptErrorColor" + reference="Red" /> + <color + name="ScrollBGStripeColor" + reference="Transparent" /> + <color + name="ScrollBgReadOnlyColor" + reference="Transparent" /> + <color + name="ScrollBgWriteableColor" + reference="White_05" /> + <color + name="ScrollDisabledColor" + reference="White_25" /> + <color + name="ScrollHighlightedColor" + reference="Unused?" /> + <color + name="ScrollHoveredColor" + reference="EmphasisColor_13" /> + <color + name="ScrollSelectedBGColor" + reference="EmphasisColor_35" /> + <color + name="ScrollSelectedFGColor" + reference="White" /> + <color + name="ScrollUnselectedColor" + reference="LtGray" /> + <color + name="ScrollbarThumbColor" + reference="White" /> + <color + name="ScrollbarTrackColor" + reference="Black" /> + <color + name="SelectedOutfitTextColor" + reference="EmphasisColor" /> + <color + name="SilhouetteChildColor" + value="0.13 0.42 0.77 1" /> + <color + name="SilhouetteParentColor" + reference="Yellow" /> + <color + name="SliderDisabledThumbColor" + reference="White_25" /> + <color + name="SliderThumbCenterColor" + reference="White" /> + <color + name="SliderThumbOutlineColor" + reference="White" /> + <color + name="SliderTrackColor" + reference="Unused?" /> + <color + name="SpeakingColor" + reference="FrogGreen" /> + <color + name="SystemChatColor" + reference="LtGray" /> + <color + name="TextBgFocusColor" + reference="White" /> + <color + name="TextBgReadOnlyColor" + reference="White_05" /> + <color + name="TextBgWriteableColor" + reference="LtGray" /> + <color + name="TextCursorColor" + reference="Black" /> + <color + name="TextDefaultColor" + reference="Black" /> + <color + name="TextEmbeddedItemColor" + value="0 0 0.5 1" /> + <color + name="TextEmbeddedItemReadOnlyColor" + reference="Unused?" /> + <color + name="TextFgColor" + value="0.102 0.102 0.102 1" /> + <color + name="TextFgReadOnlyColor" + reference="LtGray" /> + <color + name="TextFgTentativeColor" + value="0.4 0.4 0.4 1" /> + <color + name="TimeTextColor" + reference="LtGray" /> + <color + name="TitleBarFocusColor" + reference="White_10" /> + <color + name="ToastBackground" + value="0.15 0.15 0.15 0" /> + <color + name="ToolTipBgColor" + value="0.937 0.89 0.655 1" /> + <color + name="ToolTipBorderColor" + value="0.812 0.753 0.451 1" /> + <color + name="ToolTipTextColor" + reference="DkGray2" /> + <color + name="InspectorTipTextColor" + reference="LtGray" /> + <color + name="UserChatColor" + reference="White" /> + <color + name="llOwnerSayChatColor" + reference="LtOrange" /> + + <!-- New Colors --> + <color + name="OutputMonitorMutedColor" + reference="DkGray2" /> + <color + name="SysWellItemUnselected" + value="0 0 0 0" /> + <color + name="SysWellItemSelected" + value="0.3 0.3 0.3 1.0" /> + <color + name="ColorSwatchBorderColor" + value="0.45098 0.517647 0.607843 1"/> + <color + name="ChatTeleportSeparatorColor" + reference="Black" /> + <color + name="ChatTimestampColor" + reference="White" /> + <color + name="MenuBarBetaBgColor" + reference="DkBlue" /> + <color + name="MenuBarProjectBgColor" + reference="MdBlue" /> + <color + name="MenuBarTestBgColor" + reference="DkRed" /> + <color + name="MeshImportTableNormalColor" + value="1 1 1 1"/> + <color + name="MeshImportTableHighlightColor" + value="0.2 0.8 1 1"/> + + <color + name="DirectChatColor" + reference="LtOrange" /> + + <color + name="ToolbarDropZoneColor" + value=".48 .69 1 .5" /> + <color + name="PanelNotificationListItem" + value="0.3 0.3 0.3 .3" /> + + <!-- profiles --> + <color + name="StatusUserOnline" + reference="White" /> + <color + name="StatusUserOffline" + reference="LtGray_35" /> + <!-- Groups visible in own profiles --> + <color + name="GroupVisibleInProfile" + reference="TextBgFocusColor" /> + <color + name="GroupHiddenInProfile" + reference="Gray" /> + + + <!-- Generic color names (legacy) --> + <color + name="white" + value="1 1 1 1"/> + <color + name="black" + value="0 0 0 1"/> + <color + name="red" + value="1 0 0 1"/> + <color + name="green" + value="0 1 0 1"/> + <color + name="blue" + value="0 0 1 1"/> + + <!--Resize bar colors --> + + <color + name="ResizebarBorderLight" + value="0.231 0.231 0.231 1"/> + + <color + name="ResizebarBorderDark" + value="0.133 0.133 0.133 1"/> + + <color + name="ResizebarBody" + value="0.208 0.208 0.208 1"/> + + <!-- syntax highlighting (LSL Scripts) --> + <color + name="ScriptText" + reference="Black" /> + <color + name="ScriptBackground" + reference="White" /> + <color + name="ScriptCursorColor" + reference="Black" /> + <color + name="SyntaxLslComment" + value="0 0.5 0 1" /> + <color + name="SyntaxLslConstant" + value="0 0.6 0.6 1" /> + <color + name="SyntaxLslControlFlow" + value="0.4 0 0.8 1" /> + <color + name="SyntaxLslControlLabel" + value="0 0 0.8 1" /> + <color + name="SyntaxLslDataType" + value="0.8 0.4 0 1" /> + <color + name="SyntaxLslDeprecated" + value="0.9 0.0 0.66, 1" /> + <color + name="SyntaxLslEvent" + value="0 0.3 0.5 1" /> + <color + name="SyntaxLslFunction" + value="0.3 0 0.5 1" /> + <color + name="SyntaxLslGodMode" + value="0.7 .2 .35 1" /> + <color + name="SyntaxLslStringLiteral" + value="1 0.14 0 1" /> + <color + name="OutfitGalleryItemSelected" + reference="EmphasisColor_35" /> + <color + name="OutfitGalleryItemWorn" + reference="EmphasisColor_13" /> + <color + name="OutfitGalleryItemUnselected" + value="0.4 0.4 0.4 1" /> + <color + name="PanelGray" + value="0.27 0.27 0.27 1" /> + <color + name="PerformanceMid" + value="1 0.8 0 1" /> + <color + name="OutfitSnapshotMacMask" + value="0.115 0.115 0.115 1"/> + <color + name="OutfitSnapshotMacMask2" + value="0.1 0.1 0.1 1"/> +</colors> diff --git a/indra/newview/skins/contrast/textures/Blank.png b/indra/newview/skins/contrast/textures/Blank.png Binary files differnew file mode 100644 index 0000000000..f38e9f9100 --- /dev/null +++ b/indra/newview/skins/contrast/textures/Blank.png diff --git a/indra/newview/skins/contrast/textures/Rounded_Rect.png b/indra/newview/skins/contrast/textures/Rounded_Rect.png Binary files differnew file mode 100644 index 0000000000..c270c28039 --- /dev/null +++ b/indra/newview/skins/contrast/textures/Rounded_Rect.png diff --git a/indra/newview/skins/contrast/textures/alpha_gradient.tga b/indra/newview/skins/contrast/textures/alpha_gradient.tga Binary files differnew file mode 100644 index 0000000000..6fdba25d4e --- /dev/null +++ b/indra/newview/skins/contrast/textures/alpha_gradient.tga diff --git a/indra/newview/skins/contrast/textures/alpha_gradient_2d.j2c b/indra/newview/skins/contrast/textures/alpha_gradient_2d.j2c Binary files differnew file mode 100644 index 0000000000..5de5a80a65 --- /dev/null +++ b/indra/newview/skins/contrast/textures/alpha_gradient_2d.j2c diff --git a/indra/newview/skins/contrast/textures/arrow_down.tga b/indra/newview/skins/contrast/textures/arrow_down.tga Binary files differnew file mode 100644 index 0000000000..81dc9d3b6c --- /dev/null +++ b/indra/newview/skins/contrast/textures/arrow_down.tga diff --git a/indra/newview/skins/contrast/textures/arrow_up.tga b/indra/newview/skins/contrast/textures/arrow_up.tga Binary files differnew file mode 100644 index 0000000000..22195cf7fb --- /dev/null +++ b/indra/newview/skins/contrast/textures/arrow_up.tga diff --git a/indra/newview/skins/contrast/textures/avatar_thumb_bkgrnd.png b/indra/newview/skins/contrast/textures/avatar_thumb_bkgrnd.png Binary files differnew file mode 100644 index 0000000000..84cc2159c1 --- /dev/null +++ b/indra/newview/skins/contrast/textures/avatar_thumb_bkgrnd.png diff --git a/indra/newview/skins/contrast/textures/badge_note.j2c b/indra/newview/skins/contrast/textures/badge_note.j2c Binary files differnew file mode 100644 index 0000000000..1ab5233faf --- /dev/null +++ b/indra/newview/skins/contrast/textures/badge_note.j2c diff --git a/indra/newview/skins/contrast/textures/badge_ok.j2c b/indra/newview/skins/contrast/textures/badge_ok.j2c Binary files differnew file mode 100644 index 0000000000..f85b880f1d --- /dev/null +++ b/indra/newview/skins/contrast/textures/badge_ok.j2c diff --git a/indra/newview/skins/contrast/textures/badge_warn.j2c b/indra/newview/skins/contrast/textures/badge_warn.j2c Binary files differnew file mode 100644 index 0000000000..26437ca426 --- /dev/null +++ b/indra/newview/skins/contrast/textures/badge_warn.j2c diff --git a/indra/newview/skins/contrast/textures/bottomtray/Cam_Avatar_Off.png b/indra/newview/skins/contrast/textures/bottomtray/Cam_Avatar_Off.png Binary files differnew file mode 100644 index 0000000000..6b725e153a --- /dev/null +++ b/indra/newview/skins/contrast/textures/bottomtray/Cam_Avatar_Off.png diff --git a/indra/newview/skins/contrast/textures/bottomtray/Cam_FreeCam_Off.png b/indra/newview/skins/contrast/textures/bottomtray/Cam_FreeCam_Off.png Binary files differnew file mode 100644 index 0000000000..9f22080d13 --- /dev/null +++ b/indra/newview/skins/contrast/textures/bottomtray/Cam_FreeCam_Off.png diff --git a/indra/newview/skins/contrast/textures/bottomtray/Cam_Orbit_Off.png b/indra/newview/skins/contrast/textures/bottomtray/Cam_Orbit_Off.png Binary files differnew file mode 100644 index 0000000000..5b2a8eb339 --- /dev/null +++ b/indra/newview/skins/contrast/textures/bottomtray/Cam_Orbit_Off.png diff --git a/indra/newview/skins/contrast/textures/bottomtray/Cam_Pan_Off.png b/indra/newview/skins/contrast/textures/bottomtray/Cam_Pan_Off.png Binary files differnew file mode 100644 index 0000000000..9acf7053d5 --- /dev/null +++ b/indra/newview/skins/contrast/textures/bottomtray/Cam_Pan_Off.png diff --git a/indra/newview/skins/contrast/textures/bottomtray/Cam_Preset_Back_Off.png b/indra/newview/skins/contrast/textures/bottomtray/Cam_Preset_Back_Off.png Binary files differnew file mode 100644 index 0000000000..00158a7bc2 --- /dev/null +++ b/indra/newview/skins/contrast/textures/bottomtray/Cam_Preset_Back_Off.png diff --git a/indra/newview/skins/contrast/textures/bottomtray/Cam_Preset_Back_On.png b/indra/newview/skins/contrast/textures/bottomtray/Cam_Preset_Back_On.png Binary files differnew file mode 100644 index 0000000000..3748f5e190 --- /dev/null +++ b/indra/newview/skins/contrast/textures/bottomtray/Cam_Preset_Back_On.png diff --git a/indra/newview/skins/contrast/textures/bottomtray/Cam_Preset_Eye_Off.png b/indra/newview/skins/contrast/textures/bottomtray/Cam_Preset_Eye_Off.png Binary files differnew file mode 100644 index 0000000000..2b50986780 --- /dev/null +++ b/indra/newview/skins/contrast/textures/bottomtray/Cam_Preset_Eye_Off.png diff --git a/indra/newview/skins/contrast/textures/bottomtray/Cam_Preset_Front_Off.png b/indra/newview/skins/contrast/textures/bottomtray/Cam_Preset_Front_Off.png Binary files differnew file mode 100644 index 0000000000..c49b8f9a27 --- /dev/null +++ b/indra/newview/skins/contrast/textures/bottomtray/Cam_Preset_Front_Off.png diff --git a/indra/newview/skins/contrast/textures/bottomtray/Cam_Preset_Front_On.png b/indra/newview/skins/contrast/textures/bottomtray/Cam_Preset_Front_On.png Binary files differnew file mode 100644 index 0000000000..bc8c4db04d --- /dev/null +++ b/indra/newview/skins/contrast/textures/bottomtray/Cam_Preset_Front_On.png diff --git a/indra/newview/skins/contrast/textures/bottomtray/Cam_Preset_Side_Off.png b/indra/newview/skins/contrast/textures/bottomtray/Cam_Preset_Side_Off.png Binary files differnew file mode 100644 index 0000000000..b919a0a152 --- /dev/null +++ b/indra/newview/skins/contrast/textures/bottomtray/Cam_Preset_Side_Off.png diff --git a/indra/newview/skins/contrast/textures/bottomtray/Cam_Preset_Side_On.png b/indra/newview/skins/contrast/textures/bottomtray/Cam_Preset_Side_On.png Binary files differnew file mode 100644 index 0000000000..de9da359a0 --- /dev/null +++ b/indra/newview/skins/contrast/textures/bottomtray/Cam_Preset_Side_On.png diff --git a/indra/newview/skins/contrast/textures/bottomtray/Cam_Rotate_Center.png b/indra/newview/skins/contrast/textures/bottomtray/Cam_Rotate_Center.png Binary files differnew file mode 100644 index 0000000000..446daf6a90 --- /dev/null +++ b/indra/newview/skins/contrast/textures/bottomtray/Cam_Rotate_Center.png diff --git a/indra/newview/skins/contrast/textures/bottomtray/Cam_Rotate_In.png b/indra/newview/skins/contrast/textures/bottomtray/Cam_Rotate_In.png Binary files differnew file mode 100644 index 0000000000..479c98903e --- /dev/null +++ b/indra/newview/skins/contrast/textures/bottomtray/Cam_Rotate_In.png diff --git a/indra/newview/skins/contrast/textures/bottomtray/Cam_Rotate_Out.png b/indra/newview/skins/contrast/textures/bottomtray/Cam_Rotate_Out.png Binary files differnew file mode 100644 index 0000000000..cc4e6f99ff --- /dev/null +++ b/indra/newview/skins/contrast/textures/bottomtray/Cam_Rotate_Out.png diff --git a/indra/newview/skins/contrast/textures/bottomtray/Cam_Tracking_Center.png b/indra/newview/skins/contrast/textures/bottomtray/Cam_Tracking_Center.png Binary files differnew file mode 100644 index 0000000000..dbafbcc9f0 --- /dev/null +++ b/indra/newview/skins/contrast/textures/bottomtray/Cam_Tracking_Center.png diff --git a/indra/newview/skins/contrast/textures/bottomtray/Cam_Tracking_In.png b/indra/newview/skins/contrast/textures/bottomtray/Cam_Tracking_In.png Binary files differnew file mode 100644 index 0000000000..041a42ecf9 --- /dev/null +++ b/indra/newview/skins/contrast/textures/bottomtray/Cam_Tracking_In.png diff --git a/indra/newview/skins/contrast/textures/bottomtray/Cam_Tracking_Out.png b/indra/newview/skins/contrast/textures/bottomtray/Cam_Tracking_Out.png Binary files differnew file mode 100644 index 0000000000..cffead1703 --- /dev/null +++ b/indra/newview/skins/contrast/textures/bottomtray/Cam_Tracking_Out.png diff --git a/indra/newview/skins/contrast/textures/bottomtray/ChatBarHandle.png b/indra/newview/skins/contrast/textures/bottomtray/ChatBarHandle.png Binary files differnew file mode 100644 index 0000000000..50239c8af8 --- /dev/null +++ b/indra/newview/skins/contrast/textures/bottomtray/ChatBarHandle.png diff --git a/indra/newview/skins/contrast/textures/bottomtray/DownArrow.png b/indra/newview/skins/contrast/textures/bottomtray/DownArrow.png Binary files differnew file mode 100644 index 0000000000..82f58b22b9 --- /dev/null +++ b/indra/newview/skins/contrast/textures/bottomtray/DownArrow.png diff --git a/indra/newview/skins/contrast/textures/bottomtray/Mouselook_View_Off.png b/indra/newview/skins/contrast/textures/bottomtray/Mouselook_View_Off.png Binary files differnew file mode 100644 index 0000000000..8d32cad95f --- /dev/null +++ b/indra/newview/skins/contrast/textures/bottomtray/Mouselook_View_Off.png diff --git a/indra/newview/skins/contrast/textures/bottomtray/Mouselook_View_On.png b/indra/newview/skins/contrast/textures/bottomtray/Mouselook_View_On.png Binary files differnew file mode 100644 index 0000000000..4c98e35868 --- /dev/null +++ b/indra/newview/skins/contrast/textures/bottomtray/Mouselook_View_On.png diff --git a/indra/newview/skins/contrast/textures/bottomtray/Move_Fly_Off.png b/indra/newview/skins/contrast/textures/bottomtray/Move_Fly_Off.png Binary files differnew file mode 100644 index 0000000000..fade065ce7 --- /dev/null +++ b/indra/newview/skins/contrast/textures/bottomtray/Move_Fly_Off.png diff --git a/indra/newview/skins/contrast/textures/bottomtray/Move_Run_Off.png b/indra/newview/skins/contrast/textures/bottomtray/Move_Run_Off.png Binary files differnew file mode 100644 index 0000000000..e2eb38e12d --- /dev/null +++ b/indra/newview/skins/contrast/textures/bottomtray/Move_Run_Off.png diff --git a/indra/newview/skins/contrast/textures/bottomtray/Move_Walk_Off.png b/indra/newview/skins/contrast/textures/bottomtray/Move_Walk_Off.png Binary files differnew file mode 100644 index 0000000000..f314d4e001 --- /dev/null +++ b/indra/newview/skins/contrast/textures/bottomtray/Move_Walk_Off.png diff --git a/indra/newview/skins/contrast/textures/bottomtray/Movement_Backward_Off.png b/indra/newview/skins/contrast/textures/bottomtray/Movement_Backward_Off.png Binary files differnew file mode 100644 index 0000000000..4dddc2b391 --- /dev/null +++ b/indra/newview/skins/contrast/textures/bottomtray/Movement_Backward_Off.png diff --git a/indra/newview/skins/contrast/textures/bottomtray/Movement_Backward_On.png b/indra/newview/skins/contrast/textures/bottomtray/Movement_Backward_On.png Binary files differnew file mode 100644 index 0000000000..1af8e6b956 --- /dev/null +++ b/indra/newview/skins/contrast/textures/bottomtray/Movement_Backward_On.png diff --git a/indra/newview/skins/contrast/textures/bottomtray/Movement_Down_Off.png b/indra/newview/skins/contrast/textures/bottomtray/Movement_Down_Off.png Binary files differnew file mode 100644 index 0000000000..2893c9a9f1 --- /dev/null +++ b/indra/newview/skins/contrast/textures/bottomtray/Movement_Down_Off.png diff --git a/indra/newview/skins/contrast/textures/bottomtray/Movement_Down_On.png b/indra/newview/skins/contrast/textures/bottomtray/Movement_Down_On.png Binary files differnew file mode 100644 index 0000000000..4f97611db1 --- /dev/null +++ b/indra/newview/skins/contrast/textures/bottomtray/Movement_Down_On.png diff --git a/indra/newview/skins/contrast/textures/bottomtray/Movement_Forward_Off.png b/indra/newview/skins/contrast/textures/bottomtray/Movement_Forward_Off.png Binary files differnew file mode 100644 index 0000000000..80d227b6a7 --- /dev/null +++ b/indra/newview/skins/contrast/textures/bottomtray/Movement_Forward_Off.png diff --git a/indra/newview/skins/contrast/textures/bottomtray/Movement_Forward_On.png b/indra/newview/skins/contrast/textures/bottomtray/Movement_Forward_On.png Binary files differnew file mode 100644 index 0000000000..f01c9f3c63 --- /dev/null +++ b/indra/newview/skins/contrast/textures/bottomtray/Movement_Forward_On.png diff --git a/indra/newview/skins/contrast/textures/bottomtray/Movement_Left_Off.png b/indra/newview/skins/contrast/textures/bottomtray/Movement_Left_Off.png Binary files differnew file mode 100644 index 0000000000..3602efa9d9 --- /dev/null +++ b/indra/newview/skins/contrast/textures/bottomtray/Movement_Left_Off.png diff --git a/indra/newview/skins/contrast/textures/bottomtray/Movement_Left_On.png b/indra/newview/skins/contrast/textures/bottomtray/Movement_Left_On.png Binary files differnew file mode 100644 index 0000000000..a120d46e99 --- /dev/null +++ b/indra/newview/skins/contrast/textures/bottomtray/Movement_Left_On.png diff --git a/indra/newview/skins/contrast/textures/bottomtray/Movement_Right_Off.png b/indra/newview/skins/contrast/textures/bottomtray/Movement_Right_Off.png Binary files differnew file mode 100644 index 0000000000..9c3fc37dfe --- /dev/null +++ b/indra/newview/skins/contrast/textures/bottomtray/Movement_Right_Off.png diff --git a/indra/newview/skins/contrast/textures/bottomtray/Movement_Right_On.png b/indra/newview/skins/contrast/textures/bottomtray/Movement_Right_On.png Binary files differnew file mode 100644 index 0000000000..c241ac75df --- /dev/null +++ b/indra/newview/skins/contrast/textures/bottomtray/Movement_Right_On.png diff --git a/indra/newview/skins/contrast/textures/bottomtray/Movement_TurnLeft_Off.png b/indra/newview/skins/contrast/textures/bottomtray/Movement_TurnLeft_Off.png Binary files differnew file mode 100644 index 0000000000..282e8d62de --- /dev/null +++ b/indra/newview/skins/contrast/textures/bottomtray/Movement_TurnLeft_Off.png diff --git a/indra/newview/skins/contrast/textures/bottomtray/Movement_TurnLeft_On.png b/indra/newview/skins/contrast/textures/bottomtray/Movement_TurnLeft_On.png Binary files differnew file mode 100644 index 0000000000..20ce7b9296 --- /dev/null +++ b/indra/newview/skins/contrast/textures/bottomtray/Movement_TurnLeft_On.png diff --git a/indra/newview/skins/contrast/textures/bottomtray/Movement_TurnRight_Off.png b/indra/newview/skins/contrast/textures/bottomtray/Movement_TurnRight_Off.png Binary files differnew file mode 100644 index 0000000000..5039e57c32 --- /dev/null +++ b/indra/newview/skins/contrast/textures/bottomtray/Movement_TurnRight_Off.png diff --git a/indra/newview/skins/contrast/textures/bottomtray/Movement_TurnRight_On.png b/indra/newview/skins/contrast/textures/bottomtray/Movement_TurnRight_On.png Binary files differnew file mode 100644 index 0000000000..7b3d2e8dd8 --- /dev/null +++ b/indra/newview/skins/contrast/textures/bottomtray/Movement_TurnRight_On.png diff --git a/indra/newview/skins/contrast/textures/bottomtray/Movement_Up_Off.png b/indra/newview/skins/contrast/textures/bottomtray/Movement_Up_Off.png Binary files differnew file mode 100644 index 0000000000..a49c43c2cf --- /dev/null +++ b/indra/newview/skins/contrast/textures/bottomtray/Movement_Up_Off.png diff --git a/indra/newview/skins/contrast/textures/bottomtray/Movement_Up_On.png b/indra/newview/skins/contrast/textures/bottomtray/Movement_Up_On.png Binary files differnew file mode 100644 index 0000000000..ecce0d0192 --- /dev/null +++ b/indra/newview/skins/contrast/textures/bottomtray/Movement_Up_On.png diff --git a/indra/newview/skins/contrast/textures/bottomtray/Notices_Unread.png b/indra/newview/skins/contrast/textures/bottomtray/Notices_Unread.png Binary files differnew file mode 100644 index 0000000000..eb2f3dbaa4 --- /dev/null +++ b/indra/newview/skins/contrast/textures/bottomtray/Notices_Unread.png diff --git a/indra/newview/skins/contrast/textures/bottomtray/Object_View_Off.png b/indra/newview/skins/contrast/textures/bottomtray/Object_View_Off.png Binary files differnew file mode 100644 index 0000000000..e9dea7e17e --- /dev/null +++ b/indra/newview/skins/contrast/textures/bottomtray/Object_View_Off.png diff --git a/indra/newview/skins/contrast/textures/bottomtray/Object_View_On.png b/indra/newview/skins/contrast/textures/bottomtray/Object_View_On.png Binary files differnew file mode 100644 index 0000000000..7a348ba22e --- /dev/null +++ b/indra/newview/skins/contrast/textures/bottomtray/Object_View_On.png diff --git a/indra/newview/skins/contrast/textures/bottomtray/PanOrbit_Off.png b/indra/newview/skins/contrast/textures/bottomtray/PanOrbit_Off.png Binary files differnew file mode 100644 index 0000000000..53efa3a9a9 --- /dev/null +++ b/indra/newview/skins/contrast/textures/bottomtray/PanOrbit_Off.png diff --git a/indra/newview/skins/contrast/textures/bottomtray/Snapshot_Off.png b/indra/newview/skins/contrast/textures/bottomtray/Snapshot_Off.png Binary files differnew file mode 100644 index 0000000000..4ab4bbe4af --- /dev/null +++ b/indra/newview/skins/contrast/textures/bottomtray/Snapshot_Off.png diff --git a/indra/newview/skins/contrast/textures/bottomtray/Unread_Chiclet.png b/indra/newview/skins/contrast/textures/bottomtray/Unread_Chiclet.png Binary files differnew file mode 100644 index 0000000000..e8fe243dc7 --- /dev/null +++ b/indra/newview/skins/contrast/textures/bottomtray/Unread_Chiclet.png diff --git a/indra/newview/skins/contrast/textures/bottomtray/VoicePTT_Lvl1.png b/indra/newview/skins/contrast/textures/bottomtray/VoicePTT_Lvl1.png Binary files differnew file mode 100644 index 0000000000..3072512301 --- /dev/null +++ b/indra/newview/skins/contrast/textures/bottomtray/VoicePTT_Lvl1.png diff --git a/indra/newview/skins/contrast/textures/bottomtray/VoicePTT_Lvl2.png b/indra/newview/skins/contrast/textures/bottomtray/VoicePTT_Lvl2.png Binary files differnew file mode 100644 index 0000000000..28872be28f --- /dev/null +++ b/indra/newview/skins/contrast/textures/bottomtray/VoicePTT_Lvl2.png diff --git a/indra/newview/skins/contrast/textures/bottomtray/VoicePTT_Lvl3.png b/indra/newview/skins/contrast/textures/bottomtray/VoicePTT_Lvl3.png Binary files differnew file mode 100644 index 0000000000..14ec77b99a --- /dev/null +++ b/indra/newview/skins/contrast/textures/bottomtray/VoicePTT_Lvl3.png diff --git a/indra/newview/skins/contrast/textures/bottomtray/VoicePTT_Off.png b/indra/newview/skins/contrast/textures/bottomtray/VoicePTT_Off.png Binary files differnew file mode 100644 index 0000000000..48be51e9af --- /dev/null +++ b/indra/newview/skins/contrast/textures/bottomtray/VoicePTT_Off.png diff --git a/indra/newview/skins/contrast/textures/bottomtray/VoicePTT_On.png b/indra/newview/skins/contrast/textures/bottomtray/VoicePTT_On.png Binary files differnew file mode 100644 index 0000000000..823acfc583 --- /dev/null +++ b/indra/newview/skins/contrast/textures/bottomtray/VoicePTT_On.png diff --git a/indra/newview/skins/contrast/textures/bottomtray/WellButton_Lit.png b/indra/newview/skins/contrast/textures/bottomtray/WellButton_Lit.png Binary files differnew file mode 100644 index 0000000000..84711ddc29 --- /dev/null +++ b/indra/newview/skins/contrast/textures/bottomtray/WellButton_Lit.png diff --git a/indra/newview/skins/contrast/textures/bottomtray/WellButton_Lit_Selected.png b/indra/newview/skins/contrast/textures/bottomtray/WellButton_Lit_Selected.png Binary files differnew file mode 100644 index 0000000000..9b9468c574 --- /dev/null +++ b/indra/newview/skins/contrast/textures/bottomtray/WellButton_Lit_Selected.png diff --git a/indra/newview/skins/contrast/textures/build/Object_Cone.png b/indra/newview/skins/contrast/textures/build/Object_Cone.png Binary files differnew file mode 100644 index 0000000000..5167f1a820 --- /dev/null +++ b/indra/newview/skins/contrast/textures/build/Object_Cone.png diff --git a/indra/newview/skins/contrast/textures/build/Object_Cone_Selected.png b/indra/newview/skins/contrast/textures/build/Object_Cone_Selected.png Binary files differnew file mode 100644 index 0000000000..4aeb96c3ae --- /dev/null +++ b/indra/newview/skins/contrast/textures/build/Object_Cone_Selected.png diff --git a/indra/newview/skins/contrast/textures/build/Object_Cube.png b/indra/newview/skins/contrast/textures/build/Object_Cube.png Binary files differnew file mode 100644 index 0000000000..e82af1ca82 --- /dev/null +++ b/indra/newview/skins/contrast/textures/build/Object_Cube.png diff --git a/indra/newview/skins/contrast/textures/build/Object_Cube_Selected.png b/indra/newview/skins/contrast/textures/build/Object_Cube_Selected.png Binary files differnew file mode 100644 index 0000000000..9c9d4f506a --- /dev/null +++ b/indra/newview/skins/contrast/textures/build/Object_Cube_Selected.png diff --git a/indra/newview/skins/contrast/textures/build/Object_Cylinder.png b/indra/newview/skins/contrast/textures/build/Object_Cylinder.png Binary files differnew file mode 100644 index 0000000000..fe1041d4c7 --- /dev/null +++ b/indra/newview/skins/contrast/textures/build/Object_Cylinder.png diff --git a/indra/newview/skins/contrast/textures/build/Object_Cylinder_Selected.png b/indra/newview/skins/contrast/textures/build/Object_Cylinder_Selected.png Binary files differnew file mode 100644 index 0000000000..50bd865cfc --- /dev/null +++ b/indra/newview/skins/contrast/textures/build/Object_Cylinder_Selected.png diff --git a/indra/newview/skins/contrast/textures/build/Object_Grass.png b/indra/newview/skins/contrast/textures/build/Object_Grass.png Binary files differnew file mode 100644 index 0000000000..a88efd5f3e --- /dev/null +++ b/indra/newview/skins/contrast/textures/build/Object_Grass.png diff --git a/indra/newview/skins/contrast/textures/build/Object_Grass_Selected.png b/indra/newview/skins/contrast/textures/build/Object_Grass_Selected.png Binary files differnew file mode 100644 index 0000000000..19cf732d91 --- /dev/null +++ b/indra/newview/skins/contrast/textures/build/Object_Grass_Selected.png diff --git a/indra/newview/skins/contrast/textures/build/Object_Hemi_Cone.png b/indra/newview/skins/contrast/textures/build/Object_Hemi_Cone.png Binary files differnew file mode 100644 index 0000000000..595f64d480 --- /dev/null +++ b/indra/newview/skins/contrast/textures/build/Object_Hemi_Cone.png diff --git a/indra/newview/skins/contrast/textures/build/Object_Hemi_Cone_Selected.png b/indra/newview/skins/contrast/textures/build/Object_Hemi_Cone_Selected.png Binary files differnew file mode 100644 index 0000000000..ae65f1d5e6 --- /dev/null +++ b/indra/newview/skins/contrast/textures/build/Object_Hemi_Cone_Selected.png diff --git a/indra/newview/skins/contrast/textures/build/Object_Hemi_Cylinder.png b/indra/newview/skins/contrast/textures/build/Object_Hemi_Cylinder.png Binary files differnew file mode 100644 index 0000000000..dd41d56fb3 --- /dev/null +++ b/indra/newview/skins/contrast/textures/build/Object_Hemi_Cylinder.png diff --git a/indra/newview/skins/contrast/textures/build/Object_Hemi_Cylinder_Selected.png b/indra/newview/skins/contrast/textures/build/Object_Hemi_Cylinder_Selected.png Binary files differnew file mode 100644 index 0000000000..c837e953da --- /dev/null +++ b/indra/newview/skins/contrast/textures/build/Object_Hemi_Cylinder_Selected.png diff --git a/indra/newview/skins/contrast/textures/build/Object_Hemi_Sphere.png b/indra/newview/skins/contrast/textures/build/Object_Hemi_Sphere.png Binary files differnew file mode 100644 index 0000000000..1489630624 --- /dev/null +++ b/indra/newview/skins/contrast/textures/build/Object_Hemi_Sphere.png diff --git a/indra/newview/skins/contrast/textures/build/Object_Hemi_Sphere_Selected.png b/indra/newview/skins/contrast/textures/build/Object_Hemi_Sphere_Selected.png Binary files differnew file mode 100644 index 0000000000..2d1e035d41 --- /dev/null +++ b/indra/newview/skins/contrast/textures/build/Object_Hemi_Sphere_Selected.png diff --git a/indra/newview/skins/contrast/textures/build/Object_Prism.png b/indra/newview/skins/contrast/textures/build/Object_Prism.png Binary files differnew file mode 100644 index 0000000000..51c6c161a0 --- /dev/null +++ b/indra/newview/skins/contrast/textures/build/Object_Prism.png diff --git a/indra/newview/skins/contrast/textures/build/Object_Prism_Selected.png b/indra/newview/skins/contrast/textures/build/Object_Prism_Selected.png Binary files differnew file mode 100644 index 0000000000..6ec9e72c54 --- /dev/null +++ b/indra/newview/skins/contrast/textures/build/Object_Prism_Selected.png diff --git a/indra/newview/skins/contrast/textures/build/Object_Pyramid.png b/indra/newview/skins/contrast/textures/build/Object_Pyramid.png Binary files differnew file mode 100644 index 0000000000..a147b59553 --- /dev/null +++ b/indra/newview/skins/contrast/textures/build/Object_Pyramid.png diff --git a/indra/newview/skins/contrast/textures/build/Object_Pyramid_Selected.png b/indra/newview/skins/contrast/textures/build/Object_Pyramid_Selected.png Binary files differnew file mode 100644 index 0000000000..ffb878dc72 --- /dev/null +++ b/indra/newview/skins/contrast/textures/build/Object_Pyramid_Selected.png diff --git a/indra/newview/skins/contrast/textures/build/Object_Ring.png b/indra/newview/skins/contrast/textures/build/Object_Ring.png Binary files differnew file mode 100644 index 0000000000..a9790fd60c --- /dev/null +++ b/indra/newview/skins/contrast/textures/build/Object_Ring.png diff --git a/indra/newview/skins/contrast/textures/build/Object_Ring_Selected.png b/indra/newview/skins/contrast/textures/build/Object_Ring_Selected.png Binary files differnew file mode 100644 index 0000000000..ccc1f6d221 --- /dev/null +++ b/indra/newview/skins/contrast/textures/build/Object_Ring_Selected.png diff --git a/indra/newview/skins/contrast/textures/build/Object_Sphere.png b/indra/newview/skins/contrast/textures/build/Object_Sphere.png Binary files differnew file mode 100644 index 0000000000..8e2dd92a82 --- /dev/null +++ b/indra/newview/skins/contrast/textures/build/Object_Sphere.png diff --git a/indra/newview/skins/contrast/textures/build/Object_Sphere_Selected.png b/indra/newview/skins/contrast/textures/build/Object_Sphere_Selected.png Binary files differnew file mode 100644 index 0000000000..ee015e1786 --- /dev/null +++ b/indra/newview/skins/contrast/textures/build/Object_Sphere_Selected.png diff --git a/indra/newview/skins/contrast/textures/build/Object_Tetrahedron.png b/indra/newview/skins/contrast/textures/build/Object_Tetrahedron.png Binary files differnew file mode 100644 index 0000000000..23e22b1796 --- /dev/null +++ b/indra/newview/skins/contrast/textures/build/Object_Tetrahedron.png diff --git a/indra/newview/skins/contrast/textures/build/Object_Tetrahedron_Selected.png b/indra/newview/skins/contrast/textures/build/Object_Tetrahedron_Selected.png Binary files differnew file mode 100644 index 0000000000..1afb115ce5 --- /dev/null +++ b/indra/newview/skins/contrast/textures/build/Object_Tetrahedron_Selected.png diff --git a/indra/newview/skins/contrast/textures/build/Object_Torus.png b/indra/newview/skins/contrast/textures/build/Object_Torus.png Binary files differnew file mode 100644 index 0000000000..15c62423a9 --- /dev/null +++ b/indra/newview/skins/contrast/textures/build/Object_Torus.png diff --git a/indra/newview/skins/contrast/textures/build/Object_Torus_Selected.png b/indra/newview/skins/contrast/textures/build/Object_Torus_Selected.png Binary files differnew file mode 100644 index 0000000000..ff1cce3a79 --- /dev/null +++ b/indra/newview/skins/contrast/textures/build/Object_Torus_Selected.png diff --git a/indra/newview/skins/contrast/textures/build/Object_Tree.png b/indra/newview/skins/contrast/textures/build/Object_Tree.png Binary files differnew file mode 100644 index 0000000000..82c422419b --- /dev/null +++ b/indra/newview/skins/contrast/textures/build/Object_Tree.png diff --git a/indra/newview/skins/contrast/textures/build/Object_Tree_Selected.png b/indra/newview/skins/contrast/textures/build/Object_Tree_Selected.png Binary files differnew file mode 100644 index 0000000000..f21b0e4043 --- /dev/null +++ b/indra/newview/skins/contrast/textures/build/Object_Tree_Selected.png diff --git a/indra/newview/skins/contrast/textures/build/Object_Tube.png b/indra/newview/skins/contrast/textures/build/Object_Tube.png Binary files differnew file mode 100644 index 0000000000..e47fce7511 --- /dev/null +++ b/indra/newview/skins/contrast/textures/build/Object_Tube.png diff --git a/indra/newview/skins/contrast/textures/build/Object_Tube_Selected.png b/indra/newview/skins/contrast/textures/build/Object_Tube_Selected.png Binary files differnew file mode 100644 index 0000000000..5653f06af1 --- /dev/null +++ b/indra/newview/skins/contrast/textures/build/Object_Tube_Selected.png diff --git a/indra/newview/skins/contrast/textures/build/Tool_Create.png b/indra/newview/skins/contrast/textures/build/Tool_Create.png Binary files differnew file mode 100644 index 0000000000..1f1097def5 --- /dev/null +++ b/indra/newview/skins/contrast/textures/build/Tool_Create.png diff --git a/indra/newview/skins/contrast/textures/build/Tool_Dozer.png b/indra/newview/skins/contrast/textures/build/Tool_Dozer.png Binary files differnew file mode 100644 index 0000000000..61744666f4 --- /dev/null +++ b/indra/newview/skins/contrast/textures/build/Tool_Dozer.png diff --git a/indra/newview/skins/contrast/textures/build/Tool_Face.png b/indra/newview/skins/contrast/textures/build/Tool_Face.png Binary files differnew file mode 100644 index 0000000000..5ab42a4ad6 --- /dev/null +++ b/indra/newview/skins/contrast/textures/build/Tool_Face.png diff --git a/indra/newview/skins/contrast/textures/build/Tool_Grab.png b/indra/newview/skins/contrast/textures/build/Tool_Grab.png Binary files differnew file mode 100644 index 0000000000..5c58288d5e --- /dev/null +++ b/indra/newview/skins/contrast/textures/build/Tool_Grab.png diff --git a/indra/newview/skins/contrast/textures/build/Tool_Zoom.png b/indra/newview/skins/contrast/textures/build/Tool_Zoom.png Binary files differnew file mode 100644 index 0000000000..ad493b0d66 --- /dev/null +++ b/indra/newview/skins/contrast/textures/build/Tool_Zoom.png diff --git a/indra/newview/skins/contrast/textures/button_anim_pause.tga b/indra/newview/skins/contrast/textures/button_anim_pause.tga Binary files differnew file mode 100644 index 0000000000..577f9195d0 --- /dev/null +++ b/indra/newview/skins/contrast/textures/button_anim_pause.tga diff --git a/indra/newview/skins/contrast/textures/button_anim_pause_selected.tga b/indra/newview/skins/contrast/textures/button_anim_pause_selected.tga Binary files differnew file mode 100644 index 0000000000..21384316a8 --- /dev/null +++ b/indra/newview/skins/contrast/textures/button_anim_pause_selected.tga diff --git a/indra/newview/skins/contrast/textures/button_anim_play.tga b/indra/newview/skins/contrast/textures/button_anim_play.tga Binary files differnew file mode 100644 index 0000000000..9ed55f829d --- /dev/null +++ b/indra/newview/skins/contrast/textures/button_anim_play.tga diff --git a/indra/newview/skins/contrast/textures/button_anim_play_selected.tga b/indra/newview/skins/contrast/textures/button_anim_play_selected.tga Binary files differnew file mode 100644 index 0000000000..b166a4178d --- /dev/null +++ b/indra/newview/skins/contrast/textures/button_anim_play_selected.tga diff --git a/indra/newview/skins/contrast/textures/checker.png b/indra/newview/skins/contrast/textures/checker.png Binary files differnew file mode 100644 index 0000000000..1ab87e3f02 --- /dev/null +++ b/indra/newview/skins/contrast/textures/checker.png diff --git a/indra/newview/skins/contrast/textures/cloud-particle.j2c b/indra/newview/skins/contrast/textures/cloud-particle.j2c Binary files differnew file mode 100644 index 0000000000..6c03bf6d05 --- /dev/null +++ b/indra/newview/skins/contrast/textures/cloud-particle.j2c diff --git a/indra/newview/skins/contrast/textures/color_swatch_alpha.tga b/indra/newview/skins/contrast/textures/color_swatch_alpha.tga Binary files differnew file mode 100644 index 0000000000..814a004e62 --- /dev/null +++ b/indra/newview/skins/contrast/textures/color_swatch_alpha.tga diff --git a/indra/newview/skins/contrast/textures/containers/Accordion_ArrowClosed_Off.png b/indra/newview/skins/contrast/textures/containers/Accordion_ArrowClosed_Off.png Binary files differnew file mode 100644 index 0000000000..19c842b816 --- /dev/null +++ b/indra/newview/skins/contrast/textures/containers/Accordion_ArrowClosed_Off.png diff --git a/indra/newview/skins/contrast/textures/containers/Accordion_ArrowClosed_Press.png b/indra/newview/skins/contrast/textures/containers/Accordion_ArrowClosed_Press.png Binary files differnew file mode 100644 index 0000000000..b9879dcc8a --- /dev/null +++ b/indra/newview/skins/contrast/textures/containers/Accordion_ArrowClosed_Press.png diff --git a/indra/newview/skins/contrast/textures/containers/Accordion_ArrowOpened_Off.png b/indra/newview/skins/contrast/textures/containers/Accordion_ArrowOpened_Off.png Binary files differnew file mode 100644 index 0000000000..d506cda5c9 --- /dev/null +++ b/indra/newview/skins/contrast/textures/containers/Accordion_ArrowOpened_Off.png diff --git a/indra/newview/skins/contrast/textures/containers/Accordion_ArrowOpened_Press.png b/indra/newview/skins/contrast/textures/containers/Accordion_ArrowOpened_Press.png Binary files differnew file mode 100644 index 0000000000..08f7493a02 --- /dev/null +++ b/indra/newview/skins/contrast/textures/containers/Accordion_ArrowOpened_Press.png diff --git a/indra/newview/skins/contrast/textures/containers/Accordion_Off.png b/indra/newview/skins/contrast/textures/containers/Accordion_Off.png Binary files differnew file mode 100644 index 0000000000..ec2c3f0b47 --- /dev/null +++ b/indra/newview/skins/contrast/textures/containers/Accordion_Off.png diff --git a/indra/newview/skins/contrast/textures/containers/Accordion_Over.png b/indra/newview/skins/contrast/textures/containers/Accordion_Over.png Binary files differnew file mode 100644 index 0000000000..9ce484130f --- /dev/null +++ b/indra/newview/skins/contrast/textures/containers/Accordion_Over.png diff --git a/indra/newview/skins/contrast/textures/containers/Accordion_Press.png b/indra/newview/skins/contrast/textures/containers/Accordion_Press.png Binary files differnew file mode 100644 index 0000000000..36edc1c7c4 --- /dev/null +++ b/indra/newview/skins/contrast/textures/containers/Accordion_Press.png diff --git a/indra/newview/skins/contrast/textures/containers/Accordion_Selected.png b/indra/newview/skins/contrast/textures/containers/Accordion_Selected.png Binary files differnew file mode 100644 index 0000000000..9a6b4b4a27 --- /dev/null +++ b/indra/newview/skins/contrast/textures/containers/Accordion_Selected.png diff --git a/indra/newview/skins/contrast/textures/containers/Container.png b/indra/newview/skins/contrast/textures/containers/Container.png Binary files differnew file mode 100644 index 0000000000..511eb94386 --- /dev/null +++ b/indra/newview/skins/contrast/textures/containers/Container.png diff --git a/indra/newview/skins/contrast/textures/containers/TabTop_Left_Off.png b/indra/newview/skins/contrast/textures/containers/TabTop_Left_Off.png Binary files differnew file mode 100644 index 0000000000..3aad7243bc --- /dev/null +++ b/indra/newview/skins/contrast/textures/containers/TabTop_Left_Off.png diff --git a/indra/newview/skins/contrast/textures/containers/TabTop_Left_Selected.png b/indra/newview/skins/contrast/textures/containers/TabTop_Left_Selected.png Binary files differnew file mode 100644 index 0000000000..8959083014 --- /dev/null +++ b/indra/newview/skins/contrast/textures/containers/TabTop_Left_Selected.png diff --git a/indra/newview/skins/contrast/textures/containers/TabTop_Middle.png b/indra/newview/skins/contrast/textures/containers/TabTop_Middle.png Binary files differnew file mode 100644 index 0000000000..a558943a9d --- /dev/null +++ b/indra/newview/skins/contrast/textures/containers/TabTop_Middle.png diff --git a/indra/newview/skins/contrast/textures/containers/TabTop_Middle_Off.png b/indra/newview/skins/contrast/textures/containers/TabTop_Middle_Off.png Binary files differnew file mode 100644 index 0000000000..586593314f --- /dev/null +++ b/indra/newview/skins/contrast/textures/containers/TabTop_Middle_Off.png diff --git a/indra/newview/skins/contrast/textures/containers/TabTop_Middle_Selected.png b/indra/newview/skins/contrast/textures/containers/TabTop_Middle_Selected.png Binary files differnew file mode 100644 index 0000000000..d590c3284a --- /dev/null +++ b/indra/newview/skins/contrast/textures/containers/TabTop_Middle_Selected.png diff --git a/indra/newview/skins/contrast/textures/containers/TabTop_Right_Flashing.png b/indra/newview/skins/contrast/textures/containers/TabTop_Right_Flashing.png Binary files differnew file mode 100644 index 0000000000..fd13bb699d --- /dev/null +++ b/indra/newview/skins/contrast/textures/containers/TabTop_Right_Flashing.png diff --git a/indra/newview/skins/contrast/textures/containers/TabTop_Right_Off.png b/indra/newview/skins/contrast/textures/containers/TabTop_Right_Off.png Binary files differnew file mode 100644 index 0000000000..4db77fbfde --- /dev/null +++ b/indra/newview/skins/contrast/textures/containers/TabTop_Right_Off.png diff --git a/indra/newview/skins/contrast/textures/containers/TabTop_Right_Selected.png b/indra/newview/skins/contrast/textures/containers/TabTop_Right_Selected.png Binary files differnew file mode 100644 index 0000000000..7295a892fc --- /dev/null +++ b/indra/newview/skins/contrast/textures/containers/TabTop_Right_Selected.png diff --git a/indra/newview/skins/contrast/textures/containers/Toolbar_Left_Flash.png b/indra/newview/skins/contrast/textures/containers/Toolbar_Left_Flash.png Binary files differnew file mode 100644 index 0000000000..9f1e2a469d --- /dev/null +++ b/indra/newview/skins/contrast/textures/containers/Toolbar_Left_Flash.png diff --git a/indra/newview/skins/contrast/textures/containers/Toolbar_Left_Off.png b/indra/newview/skins/contrast/textures/containers/Toolbar_Left_Off.png Binary files differnew file mode 100644 index 0000000000..92ea6428a9 --- /dev/null +++ b/indra/newview/skins/contrast/textures/containers/Toolbar_Left_Off.png diff --git a/indra/newview/skins/contrast/textures/containers/Toolbar_Left_Over.png b/indra/newview/skins/contrast/textures/containers/Toolbar_Left_Over.png Binary files differnew file mode 100644 index 0000000000..31e0f84278 --- /dev/null +++ b/indra/newview/skins/contrast/textures/containers/Toolbar_Left_Over.png diff --git a/indra/newview/skins/contrast/textures/containers/Toolbar_Left_Selected.png b/indra/newview/skins/contrast/textures/containers/Toolbar_Left_Selected.png Binary files differnew file mode 100644 index 0000000000..72e9df7da6 --- /dev/null +++ b/indra/newview/skins/contrast/textures/containers/Toolbar_Left_Selected.png diff --git a/indra/newview/skins/contrast/textures/containers/Toolbar_Middle_Flash.png b/indra/newview/skins/contrast/textures/containers/Toolbar_Middle_Flash.png Binary files differnew file mode 100644 index 0000000000..dd73d655e9 --- /dev/null +++ b/indra/newview/skins/contrast/textures/containers/Toolbar_Middle_Flash.png diff --git a/indra/newview/skins/contrast/textures/containers/Toolbar_Middle_Off.png b/indra/newview/skins/contrast/textures/containers/Toolbar_Middle_Off.png Binary files differnew file mode 100644 index 0000000000..17029352fc --- /dev/null +++ b/indra/newview/skins/contrast/textures/containers/Toolbar_Middle_Off.png diff --git a/indra/newview/skins/contrast/textures/containers/Toolbar_Middle_Over.png b/indra/newview/skins/contrast/textures/containers/Toolbar_Middle_Over.png Binary files differnew file mode 100644 index 0000000000..f9bf4b69ab --- /dev/null +++ b/indra/newview/skins/contrast/textures/containers/Toolbar_Middle_Over.png diff --git a/indra/newview/skins/contrast/textures/containers/Toolbar_Middle_Selected.png b/indra/newview/skins/contrast/textures/containers/Toolbar_Middle_Selected.png Binary files differnew file mode 100644 index 0000000000..1273e7cb53 --- /dev/null +++ b/indra/newview/skins/contrast/textures/containers/Toolbar_Middle_Selected.png diff --git a/indra/newview/skins/contrast/textures/containers/Toolbar_Right_Flash.png b/indra/newview/skins/contrast/textures/containers/Toolbar_Right_Flash.png Binary files differnew file mode 100644 index 0000000000..f6b775c2a0 --- /dev/null +++ b/indra/newview/skins/contrast/textures/containers/Toolbar_Right_Flash.png diff --git a/indra/newview/skins/contrast/textures/containers/Toolbar_Right_Off.png b/indra/newview/skins/contrast/textures/containers/Toolbar_Right_Off.png Binary files differnew file mode 100644 index 0000000000..3cc431f70d --- /dev/null +++ b/indra/newview/skins/contrast/textures/containers/Toolbar_Right_Off.png diff --git a/indra/newview/skins/contrast/textures/containers/Toolbar_Right_Over.png b/indra/newview/skins/contrast/textures/containers/Toolbar_Right_Over.png Binary files differnew file mode 100644 index 0000000000..794731f9fc --- /dev/null +++ b/indra/newview/skins/contrast/textures/containers/Toolbar_Right_Over.png diff --git a/indra/newview/skins/contrast/textures/containers/Toolbar_Right_Selected.png b/indra/newview/skins/contrast/textures/containers/Toolbar_Right_Selected.png Binary files differnew file mode 100644 index 0000000000..5739a50573 --- /dev/null +++ b/indra/newview/skins/contrast/textures/containers/Toolbar_Right_Selected.png diff --git a/indra/newview/skins/contrast/textures/crosshairs.tga b/indra/newview/skins/contrast/textures/crosshairs.tga Binary files differnew file mode 100644 index 0000000000..ac4d63dc59 --- /dev/null +++ b/indra/newview/skins/contrast/textures/crosshairs.tga diff --git a/indra/newview/skins/contrast/textures/default_irradiance.png b/indra/newview/skins/contrast/textures/default_irradiance.png Binary files differnew file mode 100644 index 0000000000..899e0ddf2a --- /dev/null +++ b/indra/newview/skins/contrast/textures/default_irradiance.png diff --git a/indra/newview/skins/contrast/textures/default_land_picture.j2c b/indra/newview/skins/contrast/textures/default_land_picture.j2c Binary files differnew file mode 100644 index 0000000000..d2a8726404 --- /dev/null +++ b/indra/newview/skins/contrast/textures/default_land_picture.j2c diff --git a/indra/newview/skins/contrast/textures/default_profile_picture.j2c b/indra/newview/skins/contrast/textures/default_profile_picture.j2c Binary files differnew file mode 100644 index 0000000000..09e03af0e9 --- /dev/null +++ b/indra/newview/skins/contrast/textures/default_profile_picture.j2c diff --git a/indra/newview/skins/contrast/textures/direction_arrow.tga b/indra/newview/skins/contrast/textures/direction_arrow.tga Binary files differnew file mode 100644 index 0000000000..f3ef1068c4 --- /dev/null +++ b/indra/newview/skins/contrast/textures/direction_arrow.tga diff --git a/indra/newview/skins/contrast/textures/down_arrow.png b/indra/newview/skins/contrast/textures/down_arrow.png Binary files differnew file mode 100644 index 0000000000..21a0fc5ec0 --- /dev/null +++ b/indra/newview/skins/contrast/textures/down_arrow.png diff --git a/indra/newview/skins/contrast/textures/eye_button_active.tga b/indra/newview/skins/contrast/textures/eye_button_active.tga Binary files differnew file mode 100644 index 0000000000..014f785a7b --- /dev/null +++ b/indra/newview/skins/contrast/textures/eye_button_active.tga diff --git a/indra/newview/skins/contrast/textures/eye_button_inactive.tga b/indra/newview/skins/contrast/textures/eye_button_inactive.tga Binary files differnew file mode 100644 index 0000000000..8666f0bbe6 --- /dev/null +++ b/indra/newview/skins/contrast/textures/eye_button_inactive.tga diff --git a/indra/newview/skins/contrast/textures/flatnormal.tga b/indra/newview/skins/contrast/textures/flatnormal.tga Binary files differnew file mode 100644 index 0000000000..6d5abd1782 --- /dev/null +++ b/indra/newview/skins/contrast/textures/flatnormal.tga diff --git a/indra/newview/skins/contrast/textures/folder_arrow.tga b/indra/newview/skins/contrast/textures/folder_arrow.tga Binary files differnew file mode 100644 index 0000000000..77d470731b --- /dev/null +++ b/indra/newview/skins/contrast/textures/folder_arrow.tga diff --git a/indra/newview/skins/contrast/textures/foot_shadow.j2c b/indra/newview/skins/contrast/textures/foot_shadow.j2c Binary files differnew file mode 100644 index 0000000000..f9ce9da7d1 --- /dev/null +++ b/indra/newview/skins/contrast/textures/foot_shadow.j2c diff --git a/indra/newview/skins/contrast/textures/green_checkmark.png b/indra/newview/skins/contrast/textures/green_checkmark.png Binary files differnew file mode 100644 index 0000000000..d2a5b348dc --- /dev/null +++ b/indra/newview/skins/contrast/textures/green_checkmark.png diff --git a/indra/newview/skins/contrast/textures/icn_media_movie.tga b/indra/newview/skins/contrast/textures/icn_media_movie.tga Binary files differnew file mode 100644 index 0000000000..43dd342c9d --- /dev/null +++ b/indra/newview/skins/contrast/textures/icn_media_movie.tga diff --git a/indra/newview/skins/contrast/textures/icn_media_web.tga b/indra/newview/skins/contrast/textures/icn_media_web.tga Binary files differnew file mode 100644 index 0000000000..7c9131dfff --- /dev/null +++ b/indra/newview/skins/contrast/textures/icn_media_web.tga diff --git a/indra/newview/skins/contrast/textures/icon_auction.tga b/indra/newview/skins/contrast/textures/icon_auction.tga Binary files differnew file mode 100644 index 0000000000..baf7d0d000 --- /dev/null +++ b/indra/newview/skins/contrast/textures/icon_auction.tga diff --git a/indra/newview/skins/contrast/textures/icon_avatar_offline.tga b/indra/newview/skins/contrast/textures/icon_avatar_offline.tga Binary files differnew file mode 100644 index 0000000000..cfa95eb00e --- /dev/null +++ b/indra/newview/skins/contrast/textures/icon_avatar_offline.tga diff --git a/indra/newview/skins/contrast/textures/icon_avatar_online.tga b/indra/newview/skins/contrast/textures/icon_avatar_online.tga Binary files differnew file mode 100644 index 0000000000..45221213eb --- /dev/null +++ b/indra/newview/skins/contrast/textures/icon_avatar_online.tga diff --git a/indra/newview/skins/contrast/textures/icon_diurnal.tga b/indra/newview/skins/contrast/textures/icon_diurnal.tga Binary files differnew file mode 100644 index 0000000000..fc720c8269 --- /dev/null +++ b/indra/newview/skins/contrast/textures/icon_diurnal.tga diff --git a/indra/newview/skins/contrast/textures/icon_for_sale_adult.tga b/indra/newview/skins/contrast/textures/icon_for_sale_adult.tga Binary files differnew file mode 100644 index 0000000000..6a99188f87 --- /dev/null +++ b/indra/newview/skins/contrast/textures/icon_for_sale_adult.tga diff --git a/indra/newview/skins/contrast/textures/icon_group.tga b/indra/newview/skins/contrast/textures/icon_group.tga Binary files differnew file mode 100644 index 0000000000..79cd71689d --- /dev/null +++ b/indra/newview/skins/contrast/textures/icon_group.tga diff --git a/indra/newview/skins/contrast/textures/icon_legacy_event.tga b/indra/newview/skins/contrast/textures/icon_legacy_event.tga Binary files differnew file mode 100644 index 0000000000..7805dbce60 --- /dev/null +++ b/indra/newview/skins/contrast/textures/icon_legacy_event.tga diff --git a/indra/newview/skins/contrast/textures/icon_legacy_event_adult.tga b/indra/newview/skins/contrast/textures/icon_legacy_event_adult.tga Binary files differnew file mode 100644 index 0000000000..c344fb1e78 --- /dev/null +++ b/indra/newview/skins/contrast/textures/icon_legacy_event_adult.tga diff --git a/indra/newview/skins/contrast/textures/icon_legacy_event_mature.tga b/indra/newview/skins/contrast/textures/icon_legacy_event_mature.tga Binary files differnew file mode 100644 index 0000000000..61c879bc92 --- /dev/null +++ b/indra/newview/skins/contrast/textures/icon_legacy_event_mature.tga diff --git a/indra/newview/skins/contrast/textures/icon_place.tga b/indra/newview/skins/contrast/textures/icon_place.tga Binary files differnew file mode 100644 index 0000000000..e10655c6ec --- /dev/null +++ b/indra/newview/skins/contrast/textures/icon_place.tga diff --git a/indra/newview/skins/contrast/textures/icon_top_pick.tga b/indra/newview/skins/contrast/textures/icon_top_pick.tga Binary files differnew file mode 100644 index 0000000000..0b34882d2f --- /dev/null +++ b/indra/newview/skins/contrast/textures/icon_top_pick.tga diff --git a/indra/newview/skins/contrast/textures/icons/AddItem_Disabled.png b/indra/newview/skins/contrast/textures/icons/AddItem_Disabled.png Binary files differnew file mode 100644 index 0000000000..d21b72b973 --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/AddItem_Disabled.png diff --git a/indra/newview/skins/contrast/textures/icons/AddItem_Off.png b/indra/newview/skins/contrast/textures/icons/AddItem_Off.png Binary files differnew file mode 100644 index 0000000000..64108d133a --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/AddItem_Off.png diff --git a/indra/newview/skins/contrast/textures/icons/AddItem_Press.png b/indra/newview/skins/contrast/textures/icons/AddItem_Press.png Binary files differnew file mode 100644 index 0000000000..3168f51757 --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/AddItem_Press.png diff --git a/indra/newview/skins/contrast/textures/icons/AudioMute_Off.png b/indra/newview/skins/contrast/textures/icons/AudioMute_Off.png Binary files differnew file mode 100644 index 0000000000..dd89920fae --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/AudioMute_Off.png diff --git a/indra/newview/skins/contrast/textures/icons/AudioMute_Over.png b/indra/newview/skins/contrast/textures/icons/AudioMute_Over.png Binary files differnew file mode 100644 index 0000000000..a4fbec4144 --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/AudioMute_Over.png diff --git a/indra/newview/skins/contrast/textures/icons/Audio_Off.png b/indra/newview/skins/contrast/textures/icons/Audio_Off.png Binary files differnew file mode 100644 index 0000000000..4f6f5512c8 --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/Audio_Off.png diff --git a/indra/newview/skins/contrast/textures/icons/Audio_Press.png b/indra/newview/skins/contrast/textures/icons/Audio_Press.png Binary files differnew file mode 100644 index 0000000000..0268a0f9fb --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/Audio_Press.png diff --git a/indra/newview/skins/contrast/textures/icons/BackArrow_Off.png b/indra/newview/skins/contrast/textures/icons/BackArrow_Off.png Binary files differnew file mode 100644 index 0000000000..3775690531 --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/BackArrow_Off.png diff --git a/indra/newview/skins/contrast/textures/icons/ClipboardMenu_Disabled.png b/indra/newview/skins/contrast/textures/icons/ClipboardMenu_Disabled.png Binary files differnew file mode 100644 index 0000000000..c219ac4446 --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/ClipboardMenu_Disabled.png diff --git a/indra/newview/skins/contrast/textures/icons/ClipboardMenu_Off.png b/indra/newview/skins/contrast/textures/icons/ClipboardMenu_Off.png Binary files differnew file mode 100644 index 0000000000..586f577181 --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/ClipboardMenu_Off.png diff --git a/indra/newview/skins/contrast/textures/icons/ClipboardMenu_Press.png b/indra/newview/skins/contrast/textures/icons/ClipboardMenu_Press.png Binary files differnew file mode 100644 index 0000000000..697bee3bbd --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/ClipboardMenu_Press.png diff --git a/indra/newview/skins/contrast/textures/icons/ClipboardSmallMenu_Disabled.png b/indra/newview/skins/contrast/textures/icons/ClipboardSmallMenu_Disabled.png Binary files differnew file mode 100644 index 0000000000..12cc1857d4 --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/ClipboardSmallMenu_Disabled.png diff --git a/indra/newview/skins/contrast/textures/icons/ClipboardSmallMenu_Off.png b/indra/newview/skins/contrast/textures/icons/ClipboardSmallMenu_Off.png Binary files differnew file mode 100644 index 0000000000..7b40e33e11 --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/ClipboardSmallMenu_Off.png diff --git a/indra/newview/skins/contrast/textures/icons/ClipboardSmallMenu_Press.png b/indra/newview/skins/contrast/textures/icons/ClipboardSmallMenu_Press.png Binary files differnew file mode 100644 index 0000000000..e030c44f01 --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/ClipboardSmallMenu_Press.png diff --git a/indra/newview/skins/contrast/textures/icons/Conv_log_inbox.png b/indra/newview/skins/contrast/textures/icons/Conv_log_inbox.png Binary files differnew file mode 100644 index 0000000000..f4bbdc059d --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/Conv_log_inbox.png diff --git a/indra/newview/skins/contrast/textures/icons/Conv_toolbar_add_person.png b/indra/newview/skins/contrast/textures/icons/Conv_toolbar_add_person.png Binary files differnew file mode 100644 index 0000000000..acb3904e32 --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/Conv_toolbar_add_person.png diff --git a/indra/newview/skins/contrast/textures/icons/Conv_toolbar_arrow_ne.png b/indra/newview/skins/contrast/textures/icons/Conv_toolbar_arrow_ne.png Binary files differnew file mode 100644 index 0000000000..70dec7cad1 --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/Conv_toolbar_arrow_ne.png diff --git a/indra/newview/skins/contrast/textures/icons/Conv_toolbar_arrow_sw.png b/indra/newview/skins/contrast/textures/icons/Conv_toolbar_arrow_sw.png Binary files differnew file mode 100644 index 0000000000..13d424832b --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/Conv_toolbar_arrow_sw.png diff --git a/indra/newview/skins/contrast/textures/icons/Conv_toolbar_call_log.png b/indra/newview/skins/contrast/textures/icons/Conv_toolbar_call_log.png Binary files differnew file mode 100644 index 0000000000..1866dd965c --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/Conv_toolbar_call_log.png diff --git a/indra/newview/skins/contrast/textures/icons/Conv_toolbar_close.png b/indra/newview/skins/contrast/textures/icons/Conv_toolbar_close.png Binary files differnew file mode 100644 index 0000000000..f4f2e2fd37 --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/Conv_toolbar_close.png diff --git a/indra/newview/skins/contrast/textures/icons/Conv_toolbar_collapse.png b/indra/newview/skins/contrast/textures/icons/Conv_toolbar_collapse.png Binary files differnew file mode 100644 index 0000000000..3c427a3cc5 --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/Conv_toolbar_collapse.png diff --git a/indra/newview/skins/contrast/textures/icons/Conv_toolbar_expand.png b/indra/newview/skins/contrast/textures/icons/Conv_toolbar_expand.png Binary files differnew file mode 100644 index 0000000000..6e8031b42c --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/Conv_toolbar_expand.png diff --git a/indra/newview/skins/contrast/textures/icons/Conv_toolbar_hang_up.png b/indra/newview/skins/contrast/textures/icons/Conv_toolbar_hang_up.png Binary files differnew file mode 100644 index 0000000000..887a3b8335 --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/Conv_toolbar_hang_up.png diff --git a/indra/newview/skins/contrast/textures/icons/Conv_toolbar_open_call.png b/indra/newview/skins/contrast/textures/icons/Conv_toolbar_open_call.png Binary files differnew file mode 100644 index 0000000000..fc0da5a810 --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/Conv_toolbar_open_call.png diff --git a/indra/newview/skins/contrast/textures/icons/Conv_toolbar_plus.png b/indra/newview/skins/contrast/textures/icons/Conv_toolbar_plus.png Binary files differnew file mode 100644 index 0000000000..6d45dbbff6 --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/Conv_toolbar_plus.png diff --git a/indra/newview/skins/contrast/textures/icons/Conv_toolbar_sort.png b/indra/newview/skins/contrast/textures/icons/Conv_toolbar_sort.png Binary files differnew file mode 100644 index 0000000000..e3e5f49741 --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/Conv_toolbar_sort.png diff --git a/indra/newview/skins/contrast/textures/icons/Copy.png b/indra/newview/skins/contrast/textures/icons/Copy.png Binary files differnew file mode 100644 index 0000000000..8448e70385 --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/Copy.png diff --git a/indra/newview/skins/contrast/textures/icons/CopyBright.png b/indra/newview/skins/contrast/textures/icons/CopyBright.png Binary files differnew file mode 100644 index 0000000000..ac65d68e0b --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/CopyBright.png diff --git a/indra/newview/skins/contrast/textures/icons/Default_Outfit_Photo.png b/indra/newview/skins/contrast/textures/icons/Default_Outfit_Photo.png Binary files differnew file mode 100644 index 0000000000..1113b4effe --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/Default_Outfit_Photo.png diff --git a/indra/newview/skins/contrast/textures/icons/DownArrow_Off.png b/indra/newview/skins/contrast/textures/icons/DownArrow_Off.png Binary files differnew file mode 100644 index 0000000000..2e1e2964a0 --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/DownArrow_Off.png diff --git a/indra/newview/skins/contrast/textures/icons/Edit_Wrench.png b/indra/newview/skins/contrast/textures/icons/Edit_Wrench.png Binary files differnew file mode 100644 index 0000000000..2b9ba9dc10 --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/Edit_Wrench.png diff --git a/indra/newview/skins/contrast/textures/icons/ExternalBrowser_Off.png b/indra/newview/skins/contrast/textures/icons/ExternalBrowser_Off.png Binary files differnew file mode 100644 index 0000000000..dc4532b5a1 --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/ExternalBrowser_Off.png diff --git a/indra/newview/skins/contrast/textures/icons/Facebook.png b/indra/newview/skins/contrast/textures/icons/Facebook.png Binary files differnew file mode 100644 index 0000000000..9e51e3ac7f --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/Facebook.png diff --git a/indra/newview/skins/contrast/textures/icons/Female.png b/indra/newview/skins/contrast/textures/icons/Female.png Binary files differnew file mode 100644 index 0000000000..c9fef87b6e --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/Female.png diff --git a/indra/newview/skins/contrast/textures/icons/ForSale_Badge.png b/indra/newview/skins/contrast/textures/icons/ForSale_Badge.png Binary files differnew file mode 100644 index 0000000000..3b3a41c7c1 --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/ForSale_Badge.png diff --git a/indra/newview/skins/contrast/textures/icons/ForwardArrow_Off.png b/indra/newview/skins/contrast/textures/icons/ForwardArrow_Off.png Binary files differnew file mode 100644 index 0000000000..c33320cf6e --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/ForwardArrow_Off.png diff --git a/indra/newview/skins/contrast/textures/icons/ForwardArrow_Press.png b/indra/newview/skins/contrast/textures/icons/ForwardArrow_Press.png Binary files differnew file mode 100644 index 0000000000..86eb39c43a --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/ForwardArrow_Press.png diff --git a/indra/newview/skins/contrast/textures/icons/Generic_Group.png b/indra/newview/skins/contrast/textures/icons/Generic_Group.png Binary files differnew file mode 100644 index 0000000000..e96b7fc992 --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/Generic_Group.png diff --git a/indra/newview/skins/contrast/textures/icons/Generic_Group_Large.png b/indra/newview/skins/contrast/textures/icons/Generic_Group_Large.png Binary files differnew file mode 100644 index 0000000000..9396819bfb --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/Generic_Group_Large.png diff --git a/indra/newview/skins/contrast/textures/icons/Generic_Object_Small.png b/indra/newview/skins/contrast/textures/icons/Generic_Object_Small.png Binary files differnew file mode 100644 index 0000000000..142390e3f3 --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/Generic_Object_Small.png diff --git a/indra/newview/skins/contrast/textures/icons/Generic_Person.png b/indra/newview/skins/contrast/textures/icons/Generic_Person.png Binary files differnew file mode 100644 index 0000000000..162735d979 --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/Generic_Person.png diff --git a/indra/newview/skins/contrast/textures/icons/Generic_Person_Large.png b/indra/newview/skins/contrast/textures/icons/Generic_Person_Large.png Binary files differnew file mode 100644 index 0000000000..5be82418c1 --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/Generic_Person_Large.png diff --git a/indra/newview/skins/contrast/textures/icons/Group_Notices.png b/indra/newview/skins/contrast/textures/icons/Group_Notices.png Binary files differnew file mode 100644 index 0000000000..601502d374 --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/Group_Notices.png diff --git a/indra/newview/skins/contrast/textures/icons/Hierarchy_View_Disabled.png b/indra/newview/skins/contrast/textures/icons/Hierarchy_View_Disabled.png Binary files differnew file mode 100644 index 0000000000..6d8ea5fd93 --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/Hierarchy_View_Disabled.png diff --git a/indra/newview/skins/contrast/textures/icons/Hierarchy_View_On.png b/indra/newview/skins/contrast/textures/icons/Hierarchy_View_On.png Binary files differnew file mode 100644 index 0000000000..24f5210286 --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/Hierarchy_View_On.png diff --git a/indra/newview/skins/contrast/textures/icons/Icon_Attachment_Large.png b/indra/newview/skins/contrast/textures/icons/Icon_Attachment_Large.png Binary files differnew file mode 100644 index 0000000000..fb57265dac --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/Icon_Attachment_Large.png diff --git a/indra/newview/skins/contrast/textures/icons/Icon_Attachment_Small.png b/indra/newview/skins/contrast/textures/icons/Icon_Attachment_Small.png Binary files differnew file mode 100644 index 0000000000..907113cbb7 --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/Icon_Attachment_Small.png diff --git a/indra/newview/skins/contrast/textures/icons/Icon_Color_Palette.png b/indra/newview/skins/contrast/textures/icons/Icon_Color_Palette.png Binary files differnew file mode 100644 index 0000000000..28906001ea --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/Icon_Color_Palette.png diff --git a/indra/newview/skins/contrast/textures/icons/Icon_Font_Size.png b/indra/newview/skins/contrast/textures/icons/Icon_Font_Size.png Binary files differnew file mode 100644 index 0000000000..37bdde69aa --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/Icon_Font_Size.png diff --git a/indra/newview/skins/contrast/textures/icons/Icon_For_Sale.png b/indra/newview/skins/contrast/textures/icons/Icon_For_Sale.png Binary files differnew file mode 100644 index 0000000000..57a376f1bf --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/Icon_For_Sale.png diff --git a/indra/newview/skins/contrast/textures/icons/Icon_Notification_Condense.png b/indra/newview/skins/contrast/textures/icons/Icon_Notification_Condense.png Binary files differnew file mode 100644 index 0000000000..3a19e79f82 --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/Icon_Notification_Condense.png diff --git a/indra/newview/skins/contrast/textures/icons/Icon_Notification_Expand.png b/indra/newview/skins/contrast/textures/icons/Icon_Notification_Expand.png Binary files differnew file mode 100644 index 0000000000..f5331feb02 --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/Icon_Notification_Expand.png diff --git a/indra/newview/skins/contrast/textures/icons/Info.png b/indra/newview/skins/contrast/textures/icons/Info.png Binary files differnew file mode 100644 index 0000000000..e05a585f0b --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/Info.png diff --git a/indra/newview/skins/contrast/textures/icons/Info_Over.png b/indra/newview/skins/contrast/textures/icons/Info_Over.png Binary files differnew file mode 100644 index 0000000000..95fd5fa424 --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/Info_Over.png diff --git a/indra/newview/skins/contrast/textures/icons/Info_Small.png b/indra/newview/skins/contrast/textures/icons/Info_Small.png Binary files differnew file mode 100644 index 0000000000..c4ce13e132 --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/Info_Small.png diff --git a/indra/newview/skins/contrast/textures/icons/Inv_Alpha.png b/indra/newview/skins/contrast/textures/icons/Inv_Alpha.png Binary files differnew file mode 100644 index 0000000000..fdad36e2d3 --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/Inv_Alpha.png diff --git a/indra/newview/skins/contrast/textures/icons/Inv_Animation.png b/indra/newview/skins/contrast/textures/icons/Inv_Animation.png Binary files differnew file mode 100644 index 0000000000..6715c736e7 --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/Inv_Animation.png diff --git a/indra/newview/skins/contrast/textures/icons/Inv_BodyShape.png b/indra/newview/skins/contrast/textures/icons/Inv_BodyShape.png Binary files differnew file mode 100644 index 0000000000..cb908a39fb --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/Inv_BodyShape.png diff --git a/indra/newview/skins/contrast/textures/icons/Inv_CallingCard.png b/indra/newview/skins/contrast/textures/icons/Inv_CallingCard.png Binary files differnew file mode 100644 index 0000000000..ee87f8e595 --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/Inv_CallingCard.png diff --git a/indra/newview/skins/contrast/textures/icons/Inv_Clothing.png b/indra/newview/skins/contrast/textures/icons/Inv_Clothing.png Binary files differnew file mode 100644 index 0000000000..430dca6b5e --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/Inv_Clothing.png diff --git a/indra/newview/skins/contrast/textures/icons/Inv_Eye.png b/indra/newview/skins/contrast/textures/icons/Inv_Eye.png Binary files differnew file mode 100644 index 0000000000..d715f135d3 --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/Inv_Eye.png diff --git a/indra/newview/skins/contrast/textures/icons/Inv_FolderClosed.png b/indra/newview/skins/contrast/textures/icons/Inv_FolderClosed.png Binary files differnew file mode 100644 index 0000000000..ec99eaee9e --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/Inv_FolderClosed.png diff --git a/indra/newview/skins/contrast/textures/icons/Inv_FolderOpen.png b/indra/newview/skins/contrast/textures/icons/Inv_FolderOpen.png Binary files differnew file mode 100644 index 0000000000..615a6ec11b --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/Inv_FolderOpen.png diff --git a/indra/newview/skins/contrast/textures/icons/Inv_Gesture.png b/indra/newview/skins/contrast/textures/icons/Inv_Gesture.png Binary files differnew file mode 100644 index 0000000000..9fee34915e --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/Inv_Gesture.png diff --git a/indra/newview/skins/contrast/textures/icons/Inv_Gloves.png b/indra/newview/skins/contrast/textures/icons/Inv_Gloves.png Binary files differnew file mode 100644 index 0000000000..aa151d5404 --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/Inv_Gloves.png diff --git a/indra/newview/skins/contrast/textures/icons/Inv_Hair.png b/indra/newview/skins/contrast/textures/icons/Inv_Hair.png Binary files differnew file mode 100644 index 0000000000..62b3ae81c2 --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/Inv_Hair.png diff --git a/indra/newview/skins/contrast/textures/icons/Inv_Invalid.png b/indra/newview/skins/contrast/textures/icons/Inv_Invalid.png Binary files differnew file mode 100644 index 0000000000..6ab5ba5217 --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/Inv_Invalid.png diff --git a/indra/newview/skins/contrast/textures/icons/Inv_Jacket.png b/indra/newview/skins/contrast/textures/icons/Inv_Jacket.png Binary files differnew file mode 100644 index 0000000000..26514f1c0f --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/Inv_Jacket.png diff --git a/indra/newview/skins/contrast/textures/icons/Inv_Landmark.png b/indra/newview/skins/contrast/textures/icons/Inv_Landmark.png Binary files differnew file mode 100644 index 0000000000..338323fcee --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/Inv_Landmark.png diff --git a/indra/newview/skins/contrast/textures/icons/Inv_Link.png b/indra/newview/skins/contrast/textures/icons/Inv_Link.png Binary files differnew file mode 100644 index 0000000000..28c5f3635a --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/Inv_Link.png diff --git a/indra/newview/skins/contrast/textures/icons/Inv_LinkFolder.png b/indra/newview/skins/contrast/textures/icons/Inv_LinkFolder.png Binary files differnew file mode 100644 index 0000000000..7c43ed3a43 --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/Inv_LinkFolder.png diff --git a/indra/newview/skins/contrast/textures/icons/Inv_LinkItem.png b/indra/newview/skins/contrast/textures/icons/Inv_LinkItem.png Binary files differnew file mode 100644 index 0000000000..7c43ed3a43 --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/Inv_LinkItem.png diff --git a/indra/newview/skins/contrast/textures/icons/Inv_LookFolderClosed.png b/indra/newview/skins/contrast/textures/icons/Inv_LookFolderClosed.png Binary files differnew file mode 100644 index 0000000000..46f2038279 --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/Inv_LookFolderClosed.png diff --git a/indra/newview/skins/contrast/textures/icons/Inv_LookFolderOpen.png b/indra/newview/skins/contrast/textures/icons/Inv_LookFolderOpen.png Binary files differnew file mode 100644 index 0000000000..06a1b05983 --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/Inv_LookFolderOpen.png diff --git a/indra/newview/skins/contrast/textures/icons/Inv_LostClosed.png b/indra/newview/skins/contrast/textures/icons/Inv_LostClosed.png Binary files differnew file mode 100644 index 0000000000..fc9a2a2156 --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/Inv_LostClosed.png diff --git a/indra/newview/skins/contrast/textures/icons/Inv_LostOpen.png b/indra/newview/skins/contrast/textures/icons/Inv_LostOpen.png Binary files differnew file mode 100644 index 0000000000..b15dc3cfa3 --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/Inv_LostOpen.png diff --git a/indra/newview/skins/contrast/textures/icons/Inv_Material.png b/indra/newview/skins/contrast/textures/icons/Inv_Material.png Binary files differnew file mode 100644 index 0000000000..5cbb4fc5c9 --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/Inv_Material.png diff --git a/indra/newview/skins/contrast/textures/icons/Inv_Mesh.png b/indra/newview/skins/contrast/textures/icons/Inv_Mesh.png Binary files differnew file mode 100644 index 0000000000..69217d1cdc --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/Inv_Mesh.png diff --git a/indra/newview/skins/contrast/textures/icons/Inv_Notecard.png b/indra/newview/skins/contrast/textures/icons/Inv_Notecard.png Binary files differnew file mode 100644 index 0000000000..96f45bc55e --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/Inv_Notecard.png diff --git a/indra/newview/skins/contrast/textures/icons/Inv_Object.png b/indra/newview/skins/contrast/textures/icons/Inv_Object.png Binary files differnew file mode 100644 index 0000000000..fe6b201570 --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/Inv_Object.png diff --git a/indra/newview/skins/contrast/textures/icons/Inv_Object_Multi.png b/indra/newview/skins/contrast/textures/icons/Inv_Object_Multi.png Binary files differnew file mode 100644 index 0000000000..3793594059 --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/Inv_Object_Multi.png diff --git a/indra/newview/skins/contrast/textures/icons/Inv_Pants.png b/indra/newview/skins/contrast/textures/icons/Inv_Pants.png Binary files differnew file mode 100644 index 0000000000..5673bc29ed --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/Inv_Pants.png diff --git a/indra/newview/skins/contrast/textures/icons/Inv_Physics.png b/indra/newview/skins/contrast/textures/icons/Inv_Physics.png Binary files differnew file mode 100644 index 0000000000..43bd082d8a --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/Inv_Physics.png diff --git a/indra/newview/skins/contrast/textures/icons/Inv_Script.png b/indra/newview/skins/contrast/textures/icons/Inv_Script.png Binary files differnew file mode 100644 index 0000000000..68d2ac425f --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/Inv_Script.png diff --git a/indra/newview/skins/contrast/textures/icons/Inv_Settings.png b/indra/newview/skins/contrast/textures/icons/Inv_Settings.png Binary files differnew file mode 100644 index 0000000000..ca6cf10314 --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/Inv_Settings.png diff --git a/indra/newview/skins/contrast/textures/icons/Inv_SettingsDay.png b/indra/newview/skins/contrast/textures/icons/Inv_SettingsDay.png Binary files differnew file mode 100644 index 0000000000..d0c4b2cdcd --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/Inv_SettingsDay.png diff --git a/indra/newview/skins/contrast/textures/icons/Inv_SettingsSky.png b/indra/newview/skins/contrast/textures/icons/Inv_SettingsSky.png Binary files differnew file mode 100644 index 0000000000..5332404d37 --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/Inv_SettingsSky.png diff --git a/indra/newview/skins/contrast/textures/icons/Inv_SettingsWater.png b/indra/newview/skins/contrast/textures/icons/Inv_SettingsWater.png Binary files differnew file mode 100644 index 0000000000..88ff803756 --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/Inv_SettingsWater.png diff --git a/indra/newview/skins/contrast/textures/icons/Inv_Shape.png b/indra/newview/skins/contrast/textures/icons/Inv_Shape.png Binary files differnew file mode 100644 index 0000000000..e5db447b36 --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/Inv_Shape.png diff --git a/indra/newview/skins/contrast/textures/icons/Inv_Shirt.png b/indra/newview/skins/contrast/textures/icons/Inv_Shirt.png Binary files differnew file mode 100644 index 0000000000..ffabff9c6c --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/Inv_Shirt.png diff --git a/indra/newview/skins/contrast/textures/icons/Inv_Shoe.png b/indra/newview/skins/contrast/textures/icons/Inv_Shoe.png Binary files differnew file mode 100644 index 0000000000..784d1d23a3 --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/Inv_Shoe.png diff --git a/indra/newview/skins/contrast/textures/icons/Inv_Skin.png b/indra/newview/skins/contrast/textures/icons/Inv_Skin.png Binary files differnew file mode 100644 index 0000000000..a232c5ac67 --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/Inv_Skin.png diff --git a/indra/newview/skins/contrast/textures/icons/Inv_Skirt.png b/indra/newview/skins/contrast/textures/icons/Inv_Skirt.png Binary files differnew file mode 100644 index 0000000000..5970f39b1b --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/Inv_Skirt.png diff --git a/indra/newview/skins/contrast/textures/icons/Inv_Snapshot.png b/indra/newview/skins/contrast/textures/icons/Inv_Snapshot.png Binary files differnew file mode 100644 index 0000000000..9eaca9e7ef --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/Inv_Snapshot.png diff --git a/indra/newview/skins/contrast/textures/icons/Inv_Socks.png b/indra/newview/skins/contrast/textures/icons/Inv_Socks.png Binary files differnew file mode 100644 index 0000000000..95a3a68de6 --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/Inv_Socks.png diff --git a/indra/newview/skins/contrast/textures/icons/Inv_Sound.png b/indra/newview/skins/contrast/textures/icons/Inv_Sound.png Binary files differnew file mode 100644 index 0000000000..138d4c5c36 --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/Inv_Sound.png diff --git a/indra/newview/skins/contrast/textures/icons/Inv_StockFolderClosed.png b/indra/newview/skins/contrast/textures/icons/Inv_StockFolderClosed.png Binary files differnew file mode 100644 index 0000000000..c3aae7c736 --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/Inv_StockFolderClosed.png diff --git a/indra/newview/skins/contrast/textures/icons/Inv_StockFolderOpen.png b/indra/newview/skins/contrast/textures/icons/Inv_StockFolderOpen.png Binary files differnew file mode 100644 index 0000000000..15fd8225fc --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/Inv_StockFolderOpen.png diff --git a/indra/newview/skins/contrast/textures/icons/Inv_SysClosed.png b/indra/newview/skins/contrast/textures/icons/Inv_SysClosed.png Binary files differnew file mode 100644 index 0000000000..2550cae0d4 --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/Inv_SysClosed.png diff --git a/indra/newview/skins/contrast/textures/icons/Inv_SysOpen.png b/indra/newview/skins/contrast/textures/icons/Inv_SysOpen.png Binary files differnew file mode 100644 index 0000000000..5b56d86184 --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/Inv_SysOpen.png diff --git a/indra/newview/skins/contrast/textures/icons/Inv_Tattoo.png b/indra/newview/skins/contrast/textures/icons/Inv_Tattoo.png Binary files differnew file mode 100644 index 0000000000..af5a780685 --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/Inv_Tattoo.png diff --git a/indra/newview/skins/contrast/textures/icons/Inv_Texture.png b/indra/newview/skins/contrast/textures/icons/Inv_Texture.png Binary files differnew file mode 100644 index 0000000000..168a97515a --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/Inv_Texture.png diff --git a/indra/newview/skins/contrast/textures/icons/Inv_Toolbar_SearchVisibility.png b/indra/newview/skins/contrast/textures/icons/Inv_Toolbar_SearchVisibility.png Binary files differnew file mode 100644 index 0000000000..c4b186c3de --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/Inv_Toolbar_SearchVisibility.png diff --git a/indra/newview/skins/contrast/textures/icons/Inv_TrashClosed.png b/indra/newview/skins/contrast/textures/icons/Inv_TrashClosed.png Binary files differnew file mode 100644 index 0000000000..89f0caa5a2 --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/Inv_TrashClosed.png diff --git a/indra/newview/skins/contrast/textures/icons/Inv_TrashOpen.png b/indra/newview/skins/contrast/textures/icons/Inv_TrashOpen.png Binary files differnew file mode 100644 index 0000000000..d1f1eeaf42 --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/Inv_TrashOpen.png diff --git a/indra/newview/skins/contrast/textures/icons/Inv_Underpants.png b/indra/newview/skins/contrast/textures/icons/Inv_Underpants.png Binary files differnew file mode 100644 index 0000000000..77f8e55270 --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/Inv_Underpants.png diff --git a/indra/newview/skins/contrast/textures/icons/Inv_Undershirt.png b/indra/newview/skins/contrast/textures/icons/Inv_Undershirt.png Binary files differnew file mode 100644 index 0000000000..477d76cf11 --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/Inv_Undershirt.png diff --git a/indra/newview/skins/contrast/textures/icons/Inv_Universal.png b/indra/newview/skins/contrast/textures/icons/Inv_Universal.png Binary files differnew file mode 100644 index 0000000000..65b2f88f02 --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/Inv_Universal.png diff --git a/indra/newview/skins/contrast/textures/icons/Inv_UnknownObject.png b/indra/newview/skins/contrast/textures/icons/Inv_UnknownObject.png Binary files differnew file mode 100644 index 0000000000..603a6d7aaa --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/Inv_UnknownObject.png diff --git a/indra/newview/skins/contrast/textures/icons/Inv_VersionFolderClosed.png b/indra/newview/skins/contrast/textures/icons/Inv_VersionFolderClosed.png Binary files differnew file mode 100644 index 0000000000..cd561d24ba --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/Inv_VersionFolderClosed.png diff --git a/indra/newview/skins/contrast/textures/icons/Inv_VersionFolderOpen.png b/indra/newview/skins/contrast/textures/icons/Inv_VersionFolderOpen.png Binary files differnew file mode 100644 index 0000000000..6dc9d451cc --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/Inv_VersionFolderOpen.png diff --git a/indra/newview/skins/contrast/textures/icons/List_View_Disabled.png b/indra/newview/skins/contrast/textures/icons/List_View_Disabled.png Binary files differnew file mode 100644 index 0000000000..125034b0cb --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/List_View_Disabled.png diff --git a/indra/newview/skins/contrast/textures/icons/List_View_On.png b/indra/newview/skins/contrast/textures/icons/List_View_On.png Binary files differnew file mode 100644 index 0000000000..fcf77f004f --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/List_View_On.png diff --git a/indra/newview/skins/contrast/textures/icons/Lock.png b/indra/newview/skins/contrast/textures/icons/Lock.png Binary files differnew file mode 100644 index 0000000000..2db6ed0213 --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/Lock.png diff --git a/indra/newview/skins/contrast/textures/icons/Locked_Icon.png b/indra/newview/skins/contrast/textures/icons/Locked_Icon.png Binary files differnew file mode 100644 index 0000000000..4985af1be1 --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/Locked_Icon.png diff --git a/indra/newview/skins/contrast/textures/icons/MP_Logo.png b/indra/newview/skins/contrast/textures/icons/MP_Logo.png Binary files differnew file mode 100644 index 0000000000..b01e8f4ea3 --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/MP_Logo.png diff --git a/indra/newview/skins/contrast/textures/icons/Male.png b/indra/newview/skins/contrast/textures/icons/Male.png Binary files differnew file mode 100644 index 0000000000..803171f5c6 --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/Male.png diff --git a/indra/newview/skins/contrast/textures/icons/Microphone_On.png b/indra/newview/skins/contrast/textures/icons/Microphone_On.png Binary files differnew file mode 100644 index 0000000000..7a7d39d982 --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/Microphone_On.png diff --git a/indra/newview/skins/contrast/textures/icons/MinusItem_Disabled.png b/indra/newview/skins/contrast/textures/icons/MinusItem_Disabled.png Binary files differnew file mode 100644 index 0000000000..b62ed35182 --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/MinusItem_Disabled.png diff --git a/indra/newview/skins/contrast/textures/icons/MinusItem_Off.png b/indra/newview/skins/contrast/textures/icons/MinusItem_Off.png Binary files differnew file mode 100644 index 0000000000..eb7b8838f7 --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/MinusItem_Off.png diff --git a/indra/newview/skins/contrast/textures/icons/MinusItem_Press.png b/indra/newview/skins/contrast/textures/icons/MinusItem_Press.png Binary files differnew file mode 100644 index 0000000000..2dc6081cb0 --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/MinusItem_Press.png diff --git a/indra/newview/skins/contrast/textures/icons/MusicNote.png b/indra/newview/skins/contrast/textures/icons/MusicNote.png Binary files differnew file mode 100644 index 0000000000..8d3534a94b --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/MusicNote.png diff --git a/indra/newview/skins/contrast/textures/icons/OptionsMenu_Disabled.png b/indra/newview/skins/contrast/textures/icons/OptionsMenu_Disabled.png Binary files differnew file mode 100644 index 0000000000..5755315e23 --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/OptionsMenu_Disabled.png diff --git a/indra/newview/skins/contrast/textures/icons/OptionsMenu_Off.png b/indra/newview/skins/contrast/textures/icons/OptionsMenu_Off.png Binary files differnew file mode 100644 index 0000000000..2e9a5faa21 --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/OptionsMenu_Off.png diff --git a/indra/newview/skins/contrast/textures/icons/OptionsMenu_Press.png b/indra/newview/skins/contrast/textures/icons/OptionsMenu_Press.png Binary files differnew file mode 100644 index 0000000000..1b08648b51 --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/OptionsMenu_Press.png diff --git a/indra/newview/skins/contrast/textures/icons/OutboxPush_Disabled.png b/indra/newview/skins/contrast/textures/icons/OutboxPush_Disabled.png Binary files differnew file mode 100644 index 0000000000..1d2dbd6349 --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/OutboxPush_Disabled.png diff --git a/indra/newview/skins/contrast/textures/icons/OutboxPush_Off.png b/indra/newview/skins/contrast/textures/icons/OutboxPush_Off.png Binary files differnew file mode 100644 index 0000000000..f8f3367c42 --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/OutboxPush_Off.png diff --git a/indra/newview/skins/contrast/textures/icons/OutboxPush_On.png b/indra/newview/skins/contrast/textures/icons/OutboxPush_On.png Binary files differnew file mode 100644 index 0000000000..b1fd734100 --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/OutboxPush_On.png diff --git a/indra/newview/skins/contrast/textures/icons/OutboxPush_On_Over.png b/indra/newview/skins/contrast/textures/icons/OutboxPush_On_Over.png Binary files differnew file mode 100644 index 0000000000..e234400b72 --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/OutboxPush_On_Over.png diff --git a/indra/newview/skins/contrast/textures/icons/OutboxPush_Over.png b/indra/newview/skins/contrast/textures/icons/OutboxPush_Over.png Binary files differnew file mode 100644 index 0000000000..9e1b0e2dfc --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/OutboxPush_Over.png diff --git a/indra/newview/skins/contrast/textures/icons/OutboxPush_Press.png b/indra/newview/skins/contrast/textures/icons/OutboxPush_Press.png Binary files differnew file mode 100644 index 0000000000..14d9eacc52 --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/OutboxPush_Press.png diff --git a/indra/newview/skins/contrast/textures/icons/OutboxPush_Progress_1.png b/indra/newview/skins/contrast/textures/icons/OutboxPush_Progress_1.png Binary files differnew file mode 100644 index 0000000000..85015fc913 --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/OutboxPush_Progress_1.png diff --git a/indra/newview/skins/contrast/textures/icons/OutboxPush_Progress_2.png b/indra/newview/skins/contrast/textures/icons/OutboxPush_Progress_2.png Binary files differnew file mode 100644 index 0000000000..6158242b68 --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/OutboxPush_Progress_2.png diff --git a/indra/newview/skins/contrast/textures/icons/OutboxPush_Progress_3.png b/indra/newview/skins/contrast/textures/icons/OutboxPush_Progress_3.png Binary files differnew file mode 100644 index 0000000000..7105380bff --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/OutboxPush_Progress_3.png diff --git a/indra/newview/skins/contrast/textures/icons/OutboxPush_Progress_4.png b/indra/newview/skins/contrast/textures/icons/OutboxPush_Progress_4.png Binary files differnew file mode 100644 index 0000000000..0e65a60fc8 --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/OutboxPush_Progress_4.png diff --git a/indra/newview/skins/contrast/textures/icons/OutboxPush_Progress_5.png b/indra/newview/skins/contrast/textures/icons/OutboxPush_Progress_5.png Binary files differnew file mode 100644 index 0000000000..7acef05891 --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/OutboxPush_Progress_5.png diff --git a/indra/newview/skins/contrast/textures/icons/OutboxPush_Progress_6.png b/indra/newview/skins/contrast/textures/icons/OutboxPush_Progress_6.png Binary files differnew file mode 100644 index 0000000000..4f5b34a643 --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/OutboxPush_Progress_6.png diff --git a/indra/newview/skins/contrast/textures/icons/OutboxPush_Selected.png b/indra/newview/skins/contrast/textures/icons/OutboxPush_Selected.png Binary files differnew file mode 100644 index 0000000000..d58826da67 --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/OutboxPush_Selected.png diff --git a/indra/newview/skins/contrast/textures/icons/OutboxPush_Selected_Disabled.png b/indra/newview/skins/contrast/textures/icons/OutboxPush_Selected_Disabled.png Binary files differnew file mode 100644 index 0000000000..cad9f118b1 --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/OutboxPush_Selected_Disabled.png diff --git a/indra/newview/skins/contrast/textures/icons/OutboxPush_Selected_Over.png b/indra/newview/skins/contrast/textures/icons/OutboxPush_Selected_Over.png Binary files differnew file mode 100644 index 0000000000..65d914c6b3 --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/OutboxPush_Selected_Over.png diff --git a/indra/newview/skins/contrast/textures/icons/OutboxPush_Selected_Press.png b/indra/newview/skins/contrast/textures/icons/OutboxPush_Selected_Press.png Binary files differnew file mode 100644 index 0000000000..cd50d41903 --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/OutboxPush_Selected_Press.png diff --git a/indra/newview/skins/contrast/textures/icons/Parcel_BuildNo_Dark.png b/indra/newview/skins/contrast/textures/icons/Parcel_BuildNo_Dark.png Binary files differnew file mode 100644 index 0000000000..dd12d94ad2 --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/Parcel_BuildNo_Dark.png diff --git a/indra/newview/skins/contrast/textures/icons/Parcel_BuildNo_Light.png b/indra/newview/skins/contrast/textures/icons/Parcel_BuildNo_Light.png Binary files differnew file mode 100644 index 0000000000..4739c501ad --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/Parcel_BuildNo_Light.png diff --git a/indra/newview/skins/contrast/textures/icons/Parcel_Build_Dark.png b/indra/newview/skins/contrast/textures/icons/Parcel_Build_Dark.png Binary files differnew file mode 100644 index 0000000000..9826491efd --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/Parcel_Build_Dark.png diff --git a/indra/newview/skins/contrast/textures/icons/Parcel_DamageNo_Dark.png b/indra/newview/skins/contrast/textures/icons/Parcel_DamageNo_Dark.png Binary files differnew file mode 100644 index 0000000000..7634e5fab0 --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/Parcel_DamageNo_Dark.png diff --git a/indra/newview/skins/contrast/textures/icons/Parcel_Damage_Dark.png b/indra/newview/skins/contrast/textures/icons/Parcel_Damage_Dark.png Binary files differnew file mode 100644 index 0000000000..7ecd645df2 --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/Parcel_Damage_Dark.png diff --git a/indra/newview/skins/contrast/textures/icons/Parcel_Exp_Color.png b/indra/newview/skins/contrast/textures/icons/Parcel_Exp_Color.png Binary files differnew file mode 100644 index 0000000000..a1b0faa008 --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/Parcel_Exp_Color.png diff --git a/indra/newview/skins/contrast/textures/icons/Parcel_FlyNo_Dark.png b/indra/newview/skins/contrast/textures/icons/Parcel_FlyNo_Dark.png Binary files differnew file mode 100644 index 0000000000..831c25a34b --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/Parcel_FlyNo_Dark.png diff --git a/indra/newview/skins/contrast/textures/icons/Parcel_FlyNo_Light.png b/indra/newview/skins/contrast/textures/icons/Parcel_FlyNo_Light.png Binary files differnew file mode 100644 index 0000000000..be829fb5ef --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/Parcel_FlyNo_Light.png diff --git a/indra/newview/skins/contrast/textures/icons/Parcel_Fly_Dark.png b/indra/newview/skins/contrast/textures/icons/Parcel_Fly_Dark.png Binary files differnew file mode 100644 index 0000000000..579bfe58f8 --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/Parcel_Fly_Dark.png diff --git a/indra/newview/skins/contrast/textures/icons/Parcel_ForSale_Light.png b/indra/newview/skins/contrast/textures/icons/Parcel_ForSale_Light.png Binary files differnew file mode 100644 index 0000000000..3f4ee0b482 --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/Parcel_ForSale_Light.png diff --git a/indra/newview/skins/contrast/textures/icons/Parcel_Health_Dark.png b/indra/newview/skins/contrast/textures/icons/Parcel_Health_Dark.png Binary files differnew file mode 100644 index 0000000000..98618de927 --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/Parcel_Health_Dark.png diff --git a/indra/newview/skins/contrast/textures/icons/Parcel_M_Dark.png b/indra/newview/skins/contrast/textures/icons/Parcel_M_Dark.png Binary files differnew file mode 100644 index 0000000000..ab5a1680a7 --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/Parcel_M_Dark.png diff --git a/indra/newview/skins/contrast/textures/icons/Parcel_M_Light.png b/indra/newview/skins/contrast/textures/icons/Parcel_M_Light.png Binary files differnew file mode 100644 index 0000000000..2db94e37c9 --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/Parcel_M_Light.png diff --git a/indra/newview/skins/contrast/textures/icons/Parcel_PG_Dark.png b/indra/newview/skins/contrast/textures/icons/Parcel_PG_Dark.png Binary files differnew file mode 100644 index 0000000000..e1f7613d04 --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/Parcel_PG_Dark.png diff --git a/indra/newview/skins/contrast/textures/icons/Parcel_PG_Light.png b/indra/newview/skins/contrast/textures/icons/Parcel_PG_Light.png Binary files differnew file mode 100644 index 0000000000..04d13027d2 --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/Parcel_PG_Light.png diff --git a/indra/newview/skins/contrast/textures/icons/Parcel_PushNo_Dark.png b/indra/newview/skins/contrast/textures/icons/Parcel_PushNo_Dark.png Binary files differnew file mode 100644 index 0000000000..2867004014 --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/Parcel_PushNo_Dark.png diff --git a/indra/newview/skins/contrast/textures/icons/Parcel_PushNo_Light.png b/indra/newview/skins/contrast/textures/icons/Parcel_PushNo_Light.png Binary files differnew file mode 100644 index 0000000000..a3a51973af --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/Parcel_PushNo_Light.png diff --git a/indra/newview/skins/contrast/textures/icons/Parcel_Push_Dark.png b/indra/newview/skins/contrast/textures/icons/Parcel_Push_Dark.png Binary files differnew file mode 100644 index 0000000000..e8487ca092 --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/Parcel_Push_Dark.png diff --git a/indra/newview/skins/contrast/textures/icons/Parcel_R_Dark.png b/indra/newview/skins/contrast/textures/icons/Parcel_R_Dark.png Binary files differnew file mode 100644 index 0000000000..5c165c2fac --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/Parcel_R_Dark.png diff --git a/indra/newview/skins/contrast/textures/icons/Parcel_R_Light.png b/indra/newview/skins/contrast/textures/icons/Parcel_R_Light.png Binary files differnew file mode 100644 index 0000000000..dbf43152b3 --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/Parcel_R_Light.png diff --git a/indra/newview/skins/contrast/textures/icons/Parcel_ScriptsNo_Dark.png b/indra/newview/skins/contrast/textures/icons/Parcel_ScriptsNo_Dark.png Binary files differnew file mode 100644 index 0000000000..bfc55fc403 --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/Parcel_ScriptsNo_Dark.png diff --git a/indra/newview/skins/contrast/textures/icons/Parcel_Scripts_Dark.png b/indra/newview/skins/contrast/textures/icons/Parcel_Scripts_Dark.png Binary files differnew file mode 100644 index 0000000000..3477e0654c --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/Parcel_Scripts_Dark.png diff --git a/indra/newview/skins/contrast/textures/icons/Parcel_SeeAVsOff_Dark.png b/indra/newview/skins/contrast/textures/icons/Parcel_SeeAVsOff_Dark.png Binary files differnew file mode 100644 index 0000000000..eff089487e --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/Parcel_SeeAVsOff_Dark.png diff --git a/indra/newview/skins/contrast/textures/icons/Parcel_SeeAVsOff_Light.png b/indra/newview/skins/contrast/textures/icons/Parcel_SeeAVsOff_Light.png Binary files differnew file mode 100644 index 0000000000..68f0b14d44 --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/Parcel_SeeAVsOff_Light.png diff --git a/indra/newview/skins/contrast/textures/icons/Parcel_SeeAVsOn_Dark.png b/indra/newview/skins/contrast/textures/icons/Parcel_SeeAVsOn_Dark.png Binary files differnew file mode 100644 index 0000000000..200e04a59f --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/Parcel_SeeAVsOn_Dark.png diff --git a/indra/newview/skins/contrast/textures/icons/Parcel_SeeAVsOn_Light.png b/indra/newview/skins/contrast/textures/icons/Parcel_SeeAVsOn_Light.png Binary files differnew file mode 100644 index 0000000000..14cafc5bd2 --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/Parcel_SeeAVsOn_Light.png diff --git a/indra/newview/skins/contrast/textures/icons/Parcel_VoiceNo_Dark.png b/indra/newview/skins/contrast/textures/icons/Parcel_VoiceNo_Dark.png Binary files differnew file mode 100644 index 0000000000..ec316e822e --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/Parcel_VoiceNo_Dark.png diff --git a/indra/newview/skins/contrast/textures/icons/Parcel_VoiceNo_Light.png b/indra/newview/skins/contrast/textures/icons/Parcel_VoiceNo_Light.png Binary files differnew file mode 100644 index 0000000000..de3532a70b --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/Parcel_VoiceNo_Light.png diff --git a/indra/newview/skins/contrast/textures/icons/Parcel_Voice_Dark.png b/indra/newview/skins/contrast/textures/icons/Parcel_Voice_Dark.png Binary files differnew file mode 100644 index 0000000000..329620fa69 --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/Parcel_Voice_Dark.png diff --git a/indra/newview/skins/contrast/textures/icons/Parcel_Voice_Light.png b/indra/newview/skins/contrast/textures/icons/Parcel_Voice_Light.png Binary files differnew file mode 100644 index 0000000000..81e0fa7bc4 --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/Parcel_Voice_Light.png diff --git a/indra/newview/skins/contrast/textures/icons/Pathfinding_Dirty.png b/indra/newview/skins/contrast/textures/icons/Pathfinding_Dirty.png Binary files differnew file mode 100644 index 0000000000..d8fee0fef7 --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/Pathfinding_Dirty.png diff --git a/indra/newview/skins/contrast/textures/icons/Pathfinding_Disabled.png b/indra/newview/skins/contrast/textures/icons/Pathfinding_Disabled.png Binary files differnew file mode 100644 index 0000000000..ea2ad79611 --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/Pathfinding_Disabled.png diff --git a/indra/newview/skins/contrast/textures/icons/Pause_Off.png b/indra/newview/skins/contrast/textures/icons/Pause_Off.png Binary files differnew file mode 100644 index 0000000000..5d44412783 --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/Pause_Off.png diff --git a/indra/newview/skins/contrast/textures/icons/Pause_Over.png b/indra/newview/skins/contrast/textures/icons/Pause_Over.png Binary files differnew file mode 100644 index 0000000000..d1609a144b --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/Pause_Over.png diff --git a/indra/newview/skins/contrast/textures/icons/Pause_Press.png b/indra/newview/skins/contrast/textures/icons/Pause_Press.png Binary files differnew file mode 100644 index 0000000000..6b918d1ae6 --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/Pause_Press.png diff --git a/indra/newview/skins/contrast/textures/icons/Permission_Ungranted.png b/indra/newview/skins/contrast/textures/icons/Permission_Ungranted.png Binary files differnew file mode 100644 index 0000000000..d206af4433 --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/Permission_Ungranted.png diff --git a/indra/newview/skins/contrast/textures/icons/Person_Check.png b/indra/newview/skins/contrast/textures/icons/Person_Check.png Binary files differnew file mode 100644 index 0000000000..39a63a70cf --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/Person_Check.png diff --git a/indra/newview/skins/contrast/textures/icons/Person_Star.png b/indra/newview/skins/contrast/textures/icons/Person_Star.png Binary files differnew file mode 100644 index 0000000000..c4e625b3c1 --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/Person_Star.png diff --git a/indra/newview/skins/contrast/textures/icons/Play_Off.png b/indra/newview/skins/contrast/textures/icons/Play_Off.png Binary files differnew file mode 100644 index 0000000000..dac2f2d6db --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/Play_Off.png diff --git a/indra/newview/skins/contrast/textures/icons/Play_Over.png b/indra/newview/skins/contrast/textures/icons/Play_Over.png Binary files differnew file mode 100644 index 0000000000..1d261efcda --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/Play_Over.png diff --git a/indra/newview/skins/contrast/textures/icons/Play_Press.png b/indra/newview/skins/contrast/textures/icons/Play_Press.png Binary files differnew file mode 100644 index 0000000000..f7251ce549 --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/Play_Press.png diff --git a/indra/newview/skins/contrast/textures/icons/Presets_Icon.png b/indra/newview/skins/contrast/textures/icons/Presets_Icon.png Binary files differnew file mode 100644 index 0000000000..13642e88d1 --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/Presets_Icon.png diff --git a/indra/newview/skins/contrast/textures/icons/Presets_Icon_Graphic.png b/indra/newview/skins/contrast/textures/icons/Presets_Icon_Graphic.png Binary files differnew file mode 100644 index 0000000000..96d1021f81 --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/Presets_Icon_Graphic.png diff --git a/indra/newview/skins/contrast/textures/icons/Profile_Friend_Offline.png b/indra/newview/skins/contrast/textures/icons/Profile_Friend_Offline.png Binary files differnew file mode 100644 index 0000000000..55d922cda7 --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/Profile_Friend_Offline.png diff --git a/indra/newview/skins/contrast/textures/icons/Profile_Friend_Online.png b/indra/newview/skins/contrast/textures/icons/Profile_Friend_Online.png Binary files differnew file mode 100644 index 0000000000..febe8e78fa --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/Profile_Friend_Online.png diff --git a/indra/newview/skins/contrast/textures/icons/Profile_Perm_Find_Disabled.png b/indra/newview/skins/contrast/textures/icons/Profile_Perm_Find_Disabled.png Binary files differnew file mode 100644 index 0000000000..2632eb173b --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/Profile_Perm_Find_Disabled.png diff --git a/indra/newview/skins/contrast/textures/icons/Profile_Perm_Find_Enabled.png b/indra/newview/skins/contrast/textures/icons/Profile_Perm_Find_Enabled.png Binary files differnew file mode 100644 index 0000000000..fd8b152c12 --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/Profile_Perm_Find_Enabled.png diff --git a/indra/newview/skins/contrast/textures/icons/Profile_Perm_Objects_Disabled.png b/indra/newview/skins/contrast/textures/icons/Profile_Perm_Objects_Disabled.png Binary files differnew file mode 100644 index 0000000000..cef3ec4e5a --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/Profile_Perm_Objects_Disabled.png diff --git a/indra/newview/skins/contrast/textures/icons/Profile_Perm_Objects_Enabled.png b/indra/newview/skins/contrast/textures/icons/Profile_Perm_Objects_Enabled.png Binary files differnew file mode 100644 index 0000000000..5821566703 --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/Profile_Perm_Objects_Enabled.png diff --git a/indra/newview/skins/contrast/textures/icons/Profile_Perm_Online_Disabled.png b/indra/newview/skins/contrast/textures/icons/Profile_Perm_Online_Disabled.png Binary files differnew file mode 100644 index 0000000000..ea1b55eca0 --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/Profile_Perm_Online_Disabled.png diff --git a/indra/newview/skins/contrast/textures/icons/Profile_Perm_Online_Enabled.png b/indra/newview/skins/contrast/textures/icons/Profile_Perm_Online_Enabled.png Binary files differnew file mode 100644 index 0000000000..eb3fc9e713 --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/Profile_Perm_Online_Enabled.png diff --git a/indra/newview/skins/contrast/textures/icons/ProgressLarge_1.png b/indra/newview/skins/contrast/textures/icons/ProgressLarge_1.png Binary files differnew file mode 100644 index 0000000000..ff277fc431 --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/ProgressLarge_1.png diff --git a/indra/newview/skins/contrast/textures/icons/ProgressLarge_10.png b/indra/newview/skins/contrast/textures/icons/ProgressLarge_10.png Binary files differnew file mode 100644 index 0000000000..1c94e21d89 --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/ProgressLarge_10.png diff --git a/indra/newview/skins/contrast/textures/icons/ProgressLarge_11.png b/indra/newview/skins/contrast/textures/icons/ProgressLarge_11.png Binary files differnew file mode 100644 index 0000000000..89bea9b474 --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/ProgressLarge_11.png diff --git a/indra/newview/skins/contrast/textures/icons/ProgressLarge_12.png b/indra/newview/skins/contrast/textures/icons/ProgressLarge_12.png Binary files differnew file mode 100644 index 0000000000..da38475ba4 --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/ProgressLarge_12.png diff --git a/indra/newview/skins/contrast/textures/icons/ProgressLarge_2.png b/indra/newview/skins/contrast/textures/icons/ProgressLarge_2.png Binary files differnew file mode 100644 index 0000000000..c024275ebe --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/ProgressLarge_2.png diff --git a/indra/newview/skins/contrast/textures/icons/ProgressLarge_3.png b/indra/newview/skins/contrast/textures/icons/ProgressLarge_3.png Binary files differnew file mode 100644 index 0000000000..87b931e72e --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/ProgressLarge_3.png diff --git a/indra/newview/skins/contrast/textures/icons/ProgressLarge_4.png b/indra/newview/skins/contrast/textures/icons/ProgressLarge_4.png Binary files differnew file mode 100644 index 0000000000..6dbef74361 --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/ProgressLarge_4.png diff --git a/indra/newview/skins/contrast/textures/icons/ProgressLarge_5.png b/indra/newview/skins/contrast/textures/icons/ProgressLarge_5.png Binary files differnew file mode 100644 index 0000000000..daccf9b375 --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/ProgressLarge_5.png diff --git a/indra/newview/skins/contrast/textures/icons/ProgressLarge_6.png b/indra/newview/skins/contrast/textures/icons/ProgressLarge_6.png Binary files differnew file mode 100644 index 0000000000..cafddcb88d --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/ProgressLarge_6.png diff --git a/indra/newview/skins/contrast/textures/icons/ProgressLarge_7.png b/indra/newview/skins/contrast/textures/icons/ProgressLarge_7.png Binary files differnew file mode 100644 index 0000000000..8acf6472d4 --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/ProgressLarge_7.png diff --git a/indra/newview/skins/contrast/textures/icons/ProgressLarge_8.png b/indra/newview/skins/contrast/textures/icons/ProgressLarge_8.png Binary files differnew file mode 100644 index 0000000000..df0e825cef --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/ProgressLarge_8.png diff --git a/indra/newview/skins/contrast/textures/icons/ProgressLarge_9.png b/indra/newview/skins/contrast/textures/icons/ProgressLarge_9.png Binary files differnew file mode 100644 index 0000000000..293a7b8f5c --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/ProgressLarge_9.png diff --git a/indra/newview/skins/contrast/textures/icons/Progress_1.png b/indra/newview/skins/contrast/textures/icons/Progress_1.png Binary files differnew file mode 100644 index 0000000000..bc7a1e7e96 --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/Progress_1.png diff --git a/indra/newview/skins/contrast/textures/icons/Progress_10.png b/indra/newview/skins/contrast/textures/icons/Progress_10.png Binary files differnew file mode 100644 index 0000000000..acf4d21aba --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/Progress_10.png diff --git a/indra/newview/skins/contrast/textures/icons/Progress_11.png b/indra/newview/skins/contrast/textures/icons/Progress_11.png Binary files differnew file mode 100644 index 0000000000..1842cd09d0 --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/Progress_11.png diff --git a/indra/newview/skins/contrast/textures/icons/Progress_12.png b/indra/newview/skins/contrast/textures/icons/Progress_12.png Binary files differnew file mode 100644 index 0000000000..0ea9dda83e --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/Progress_12.png diff --git a/indra/newview/skins/contrast/textures/icons/Progress_2.png b/indra/newview/skins/contrast/textures/icons/Progress_2.png Binary files differnew file mode 100644 index 0000000000..29d6bbcbcb --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/Progress_2.png diff --git a/indra/newview/skins/contrast/textures/icons/Progress_3.png b/indra/newview/skins/contrast/textures/icons/Progress_3.png Binary files differnew file mode 100644 index 0000000000..52a03125e9 --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/Progress_3.png diff --git a/indra/newview/skins/contrast/textures/icons/Progress_4.png b/indra/newview/skins/contrast/textures/icons/Progress_4.png Binary files differnew file mode 100644 index 0000000000..4b2798519f --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/Progress_4.png diff --git a/indra/newview/skins/contrast/textures/icons/Progress_5.png b/indra/newview/skins/contrast/textures/icons/Progress_5.png Binary files differnew file mode 100644 index 0000000000..3f02b8f31a --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/Progress_5.png diff --git a/indra/newview/skins/contrast/textures/icons/Progress_6.png b/indra/newview/skins/contrast/textures/icons/Progress_6.png Binary files differnew file mode 100644 index 0000000000..04c8f716d4 --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/Progress_6.png diff --git a/indra/newview/skins/contrast/textures/icons/Progress_7.png b/indra/newview/skins/contrast/textures/icons/Progress_7.png Binary files differnew file mode 100644 index 0000000000..c96b4c08d6 --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/Progress_7.png diff --git a/indra/newview/skins/contrast/textures/icons/Progress_8.png b/indra/newview/skins/contrast/textures/icons/Progress_8.png Binary files differnew file mode 100644 index 0000000000..9463f50707 --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/Progress_8.png diff --git a/indra/newview/skins/contrast/textures/icons/Progress_9.png b/indra/newview/skins/contrast/textures/icons/Progress_9.png Binary files differnew file mode 100644 index 0000000000..928a3e934e --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/Progress_9.png diff --git a/indra/newview/skins/contrast/textures/icons/Refresh_Off.png b/indra/newview/skins/contrast/textures/icons/Refresh_Off.png Binary files differnew file mode 100644 index 0000000000..e645a8159f --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/Refresh_Off.png diff --git a/indra/newview/skins/contrast/textures/icons/SL_Logo.png b/indra/newview/skins/contrast/textures/icons/SL_Logo.png Binary files differnew file mode 100644 index 0000000000..8234387058 --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/SL_Logo.png diff --git a/indra/newview/skins/contrast/textures/icons/Search_Icon.png b/indra/newview/skins/contrast/textures/icons/Search_Icon.png Binary files differnew file mode 100644 index 0000000000..0ea7b14f81 --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/Search_Icon.png diff --git a/indra/newview/skins/contrast/textures/icons/Shirt_Large.png b/indra/newview/skins/contrast/textures/icons/Shirt_Large.png Binary files differnew file mode 100644 index 0000000000..06fce6bbaa --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/Shirt_Large.png diff --git a/indra/newview/skins/contrast/textures/icons/Shop.png b/indra/newview/skins/contrast/textures/icons/Shop.png Binary files differnew file mode 100644 index 0000000000..93353cf2fe --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/Shop.png diff --git a/indra/newview/skins/contrast/textures/icons/SkipBackward_Off.png b/indra/newview/skins/contrast/textures/icons/SkipBackward_Off.png Binary files differnew file mode 100644 index 0000000000..20fd2b8e22 --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/SkipBackward_Off.png diff --git a/indra/newview/skins/contrast/textures/icons/SkipForward_Off.png b/indra/newview/skins/contrast/textures/icons/SkipForward_Off.png Binary files differnew file mode 100644 index 0000000000..30e28d3d31 --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/SkipForward_Off.png diff --git a/indra/newview/skins/contrast/textures/icons/StopReload_Off.png b/indra/newview/skins/contrast/textures/icons/StopReload_Off.png Binary files differnew file mode 100644 index 0000000000..500a81d715 --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/StopReload_Off.png diff --git a/indra/newview/skins/contrast/textures/icons/StopReload_Over.png b/indra/newview/skins/contrast/textures/icons/StopReload_Over.png Binary files differnew file mode 100644 index 0000000000..a065a37d14 --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/StopReload_Over.png diff --git a/indra/newview/skins/contrast/textures/icons/Stop_Off.png b/indra/newview/skins/contrast/textures/icons/Stop_Off.png Binary files differnew file mode 100644 index 0000000000..2d00083e2e --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/Stop_Off.png diff --git a/indra/newview/skins/contrast/textures/icons/Sync_Disabled.png b/indra/newview/skins/contrast/textures/icons/Sync_Disabled.png Binary files differnew file mode 100644 index 0000000000..7b39e7cd6f --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/Sync_Disabled.png diff --git a/indra/newview/skins/contrast/textures/icons/Sync_Enabled.png b/indra/newview/skins/contrast/textures/icons/Sync_Enabled.png Binary files differnew file mode 100644 index 0000000000..0e7e5157cb --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/Sync_Enabled.png diff --git a/indra/newview/skins/contrast/textures/icons/Sync_Progress_1.png b/indra/newview/skins/contrast/textures/icons/Sync_Progress_1.png Binary files differnew file mode 100644 index 0000000000..218edaa986 --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/Sync_Progress_1.png diff --git a/indra/newview/skins/contrast/textures/icons/Sync_Progress_2.png b/indra/newview/skins/contrast/textures/icons/Sync_Progress_2.png Binary files differnew file mode 100644 index 0000000000..23cb9d63c0 --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/Sync_Progress_2.png diff --git a/indra/newview/skins/contrast/textures/icons/Sync_Progress_3.png b/indra/newview/skins/contrast/textures/icons/Sync_Progress_3.png Binary files differnew file mode 100644 index 0000000000..490826011a --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/Sync_Progress_3.png diff --git a/indra/newview/skins/contrast/textures/icons/Sync_Progress_4.png b/indra/newview/skins/contrast/textures/icons/Sync_Progress_4.png Binary files differnew file mode 100644 index 0000000000..de1c815e90 --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/Sync_Progress_4.png diff --git a/indra/newview/skins/contrast/textures/icons/Sync_Progress_5.png b/indra/newview/skins/contrast/textures/icons/Sync_Progress_5.png Binary files differnew file mode 100644 index 0000000000..2897b37382 --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/Sync_Progress_5.png diff --git a/indra/newview/skins/contrast/textures/icons/Sync_Progress_6.png b/indra/newview/skins/contrast/textures/icons/Sync_Progress_6.png Binary files differnew file mode 100644 index 0000000000..862410e9e4 --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/Sync_Progress_6.png diff --git a/indra/newview/skins/contrast/textures/icons/System_Notification_Large.png b/indra/newview/skins/contrast/textures/icons/System_Notification_Large.png Binary files differnew file mode 100644 index 0000000000..01c6e31f41 --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/System_Notification_Large.png diff --git a/indra/newview/skins/contrast/textures/icons/System_Notification_Small.png b/indra/newview/skins/contrast/textures/icons/System_Notification_Small.png Binary files differnew file mode 100644 index 0000000000..69b823d852 --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/System_Notification_Small.png diff --git a/indra/newview/skins/contrast/textures/icons/TrashItem_Disabled.png b/indra/newview/skins/contrast/textures/icons/TrashItem_Disabled.png Binary files differnew file mode 100644 index 0000000000..800d9434d2 --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/TrashItem_Disabled.png diff --git a/indra/newview/skins/contrast/textures/icons/TrashItem_Off.png b/indra/newview/skins/contrast/textures/icons/TrashItem_Off.png Binary files differnew file mode 100644 index 0000000000..0cbff4f1d7 --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/TrashItem_Off.png diff --git a/indra/newview/skins/contrast/textures/icons/TrashItem_Press.png b/indra/newview/skins/contrast/textures/icons/TrashItem_Press.png Binary files differnew file mode 100644 index 0000000000..fac13226e7 --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/TrashItem_Press.png diff --git a/indra/newview/skins/contrast/textures/icons/UnZoom_Off.png b/indra/newview/skins/contrast/textures/icons/UnZoom_Off.png Binary files differnew file mode 100644 index 0000000000..34ec3f5de8 --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/UnZoom_Off.png diff --git a/indra/newview/skins/contrast/textures/icons/UpArrow_Off.png b/indra/newview/skins/contrast/textures/icons/UpArrow_Off.png Binary files differnew file mode 100644 index 0000000000..d5ddc353e7 --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/UpArrow_Off.png diff --git a/indra/newview/skins/contrast/textures/icons/Video_URL_Off.png b/indra/newview/skins/contrast/textures/icons/Video_URL_Off.png Binary files differnew file mode 100644 index 0000000000..d37a189645 --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/Video_URL_Off.png diff --git a/indra/newview/skins/contrast/textures/icons/VoiceMute_Off.png b/indra/newview/skins/contrast/textures/icons/VoiceMute_Off.png Binary files differnew file mode 100644 index 0000000000..425ba267a5 --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/VoiceMute_Off.png diff --git a/indra/newview/skins/contrast/textures/icons/VoicePTT_Lvl1.png b/indra/newview/skins/contrast/textures/icons/VoicePTT_Lvl1.png Binary files differnew file mode 100644 index 0000000000..3072512301 --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/VoicePTT_Lvl1.png diff --git a/indra/newview/skins/contrast/textures/icons/VoicePTT_Lvl2.png b/indra/newview/skins/contrast/textures/icons/VoicePTT_Lvl2.png Binary files differnew file mode 100644 index 0000000000..28872be28f --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/VoicePTT_Lvl2.png diff --git a/indra/newview/skins/contrast/textures/icons/VoicePTT_Lvl3.png b/indra/newview/skins/contrast/textures/icons/VoicePTT_Lvl3.png Binary files differnew file mode 100644 index 0000000000..a4a171bd81 --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/VoicePTT_Lvl3.png diff --git a/indra/newview/skins/contrast/textures/icons/VoicePTT_Off.png b/indra/newview/skins/contrast/textures/icons/VoicePTT_Off.png Binary files differnew file mode 100644 index 0000000000..533663a4fa --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/VoicePTT_Off.png diff --git a/indra/newview/skins/contrast/textures/icons/VoicePTT_On.png b/indra/newview/skins/contrast/textures/icons/VoicePTT_On.png Binary files differnew file mode 100644 index 0000000000..823acfc583 --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/VoicePTT_On.png diff --git a/indra/newview/skins/contrast/textures/icons/Web_Profile_Off.png b/indra/newview/skins/contrast/textures/icons/Web_Profile_Off.png Binary files differnew file mode 100644 index 0000000000..cf8f9c8f94 --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/Web_Profile_Off.png diff --git a/indra/newview/skins/contrast/textures/icons/YouAreHere_Badge.png b/indra/newview/skins/contrast/textures/icons/YouAreHere_Badge.png Binary files differnew file mode 100644 index 0000000000..ed1805c096 --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/YouAreHere_Badge.png diff --git a/indra/newview/skins/contrast/textures/icons/Zoom_Off.png b/indra/newview/skins/contrast/textures/icons/Zoom_Off.png Binary files differnew file mode 100644 index 0000000000..833e608201 --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/Zoom_Off.png diff --git a/indra/newview/skins/contrast/textures/icons/add_icon.png b/indra/newview/skins/contrast/textures/icons/add_icon.png Binary files differnew file mode 100644 index 0000000000..b5b09ae6e0 --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/add_icon.png diff --git a/indra/newview/skins/contrast/textures/icons/back_arrow_off.png b/indra/newview/skins/contrast/textures/icons/back_arrow_off.png Binary files differnew file mode 100644 index 0000000000..0adf0b677e --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/back_arrow_off.png diff --git a/indra/newview/skins/contrast/textures/icons/back_arrow_over.png b/indra/newview/skins/contrast/textures/icons/back_arrow_over.png Binary files differnew file mode 100644 index 0000000000..13ce6a8e4d --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/back_arrow_over.png diff --git a/indra/newview/skins/contrast/textures/icons/back_arrow_press.png b/indra/newview/skins/contrast/textures/icons/back_arrow_press.png Binary files differnew file mode 100644 index 0000000000..311a90ac22 --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/back_arrow_press.png diff --git a/indra/newview/skins/contrast/textures/icons/check_mark.png b/indra/newview/skins/contrast/textures/icons/check_mark.png Binary files differnew file mode 100644 index 0000000000..ea59769d38 --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/check_mark.png diff --git a/indra/newview/skins/contrast/textures/icons/collapse_to_one_line.png b/indra/newview/skins/contrast/textures/icons/collapse_to_one_line.png Binary files differnew file mode 100644 index 0000000000..3730924ad8 --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/collapse_to_one_line.png diff --git a/indra/newview/skins/contrast/textures/icons/copy_clipboard.png b/indra/newview/skins/contrast/textures/icons/copy_clipboard.png Binary files differnew file mode 100644 index 0000000000..9ce67d8547 --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/copy_clipboard.png diff --git a/indra/newview/skins/contrast/textures/icons/delete_icon.png b/indra/newview/skins/contrast/textures/icons/delete_icon.png Binary files differnew file mode 100644 index 0000000000..5a80155d8b --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/delete_icon.png diff --git a/indra/newview/skins/contrast/textures/icons/edit_mine.png b/indra/newview/skins/contrast/textures/icons/edit_mine.png Binary files differnew file mode 100644 index 0000000000..2fb10deba2 --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/edit_mine.png diff --git a/indra/newview/skins/contrast/textures/icons/edit_theirs.png b/indra/newview/skins/contrast/textures/icons/edit_theirs.png Binary files differnew file mode 100644 index 0000000000..586c08c181 --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/edit_theirs.png diff --git a/indra/newview/skins/contrast/textures/icons/emoji_picker_icon.png b/indra/newview/skins/contrast/textures/icons/emoji_picker_icon.png Binary files differnew file mode 100644 index 0000000000..6c1a1a3c62 --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/emoji_picker_icon.png diff --git a/indra/newview/skins/contrast/textures/icons/expand_one_liner.png b/indra/newview/skins/contrast/textures/icons/expand_one_liner.png Binary files differnew file mode 100644 index 0000000000..0d1a60547a --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/expand_one_liner.png diff --git a/indra/newview/skins/contrast/textures/icons/file_upload.png b/indra/newview/skins/contrast/textures/icons/file_upload.png Binary files differnew file mode 100644 index 0000000000..78b75fdd72 --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/file_upload.png diff --git a/indra/newview/skins/contrast/textures/icons/hand.png b/indra/newview/skins/contrast/textures/icons/hand.png Binary files differnew file mode 100644 index 0000000000..3f497eefbb --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/hand.png diff --git a/indra/newview/skins/contrast/textures/icons/map_placeholder.png b/indra/newview/skins/contrast/textures/icons/map_placeholder.png Binary files differnew file mode 100644 index 0000000000..80e5deac7e --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/map_placeholder.png diff --git a/indra/newview/skins/contrast/textures/icons/multi_folder_mode.png b/indra/newview/skins/contrast/textures/icons/multi_folder_mode.png Binary files differnew file mode 100644 index 0000000000..b363848aba --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/multi_folder_mode.png diff --git a/indra/newview/skins/contrast/textures/icons/nearby_chat_icon.png b/indra/newview/skins/contrast/textures/icons/nearby_chat_icon.png Binary files differnew file mode 100644 index 0000000000..c5f52f010e --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/nearby_chat_icon.png diff --git a/indra/newview/skins/contrast/textures/icons/object_icon.png b/indra/newview/skins/contrast/textures/icons/object_icon.png Binary files differnew file mode 100644 index 0000000000..51bf0b0649 --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/object_icon.png diff --git a/indra/newview/skins/contrast/textures/icons/paste_clipboard.png b/indra/newview/skins/contrast/textures/icons/paste_clipboard.png Binary files differnew file mode 100644 index 0000000000..ff8493d4ad --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/paste_clipboard.png diff --git a/indra/newview/skins/contrast/textures/icons/pop_up_caution.png b/indra/newview/skins/contrast/textures/icons/pop_up_caution.png Binary files differnew file mode 100644 index 0000000000..63b5cdfe83 --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/pop_up_caution.png diff --git a/indra/newview/skins/contrast/textures/icons/profile_badge_beta.png b/indra/newview/skins/contrast/textures/icons/profile_badge_beta.png Binary files differnew file mode 100644 index 0000000000..95e277aab0 --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/profile_badge_beta.png diff --git a/indra/newview/skins/contrast/textures/icons/profile_badge_beta_lifetime.png b/indra/newview/skins/contrast/textures/icons/profile_badge_beta_lifetime.png Binary files differnew file mode 100644 index 0000000000..fb145901e2 --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/profile_badge_beta_lifetime.png diff --git a/indra/newview/skins/contrast/textures/icons/profile_badge_lifetime.png b/indra/newview/skins/contrast/textures/icons/profile_badge_lifetime.png Binary files differnew file mode 100644 index 0000000000..3f7fd343b3 --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/profile_badge_lifetime.png diff --git a/indra/newview/skins/contrast/textures/icons/profile_badge_linden.png b/indra/newview/skins/contrast/textures/icons/profile_badge_linden.png Binary files differnew file mode 100644 index 0000000000..6ab9fcebea --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/profile_badge_linden.png diff --git a/indra/newview/skins/contrast/textures/icons/profile_badge_pplus_lifetime.png b/indra/newview/skins/contrast/textures/icons/profile_badge_pplus_lifetime.png Binary files differnew file mode 100644 index 0000000000..5c68ad40ce --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/profile_badge_pplus_lifetime.png diff --git a/indra/newview/skins/contrast/textures/icons/profile_badge_premium_lifetime.png b/indra/newview/skins/contrast/textures/icons/profile_badge_premium_lifetime.png Binary files differnew file mode 100644 index 0000000000..58957b7b96 --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/profile_badge_premium_lifetime.png diff --git a/indra/newview/skins/contrast/textures/icons/profile_group_visibility_eye_off.png b/indra/newview/skins/contrast/textures/icons/profile_group_visibility_eye_off.png Binary files differnew file mode 100644 index 0000000000..331553492c --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/profile_group_visibility_eye_off.png diff --git a/indra/newview/skins/contrast/textures/icons/profile_group_visibility_eye_off_pressed.png b/indra/newview/skins/contrast/textures/icons/profile_group_visibility_eye_off_pressed.png Binary files differnew file mode 100644 index 0000000000..e9e9c1b626 --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/profile_group_visibility_eye_off_pressed.png diff --git a/indra/newview/skins/contrast/textures/icons/profile_group_visibility_eye_on.png b/indra/newview/skins/contrast/textures/icons/profile_group_visibility_eye_on.png Binary files differnew file mode 100644 index 0000000000..4f5374d614 --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/profile_group_visibility_eye_on.png diff --git a/indra/newview/skins/contrast/textures/icons/profile_group_visibility_eye_on_pressed.png b/indra/newview/skins/contrast/textures/icons/profile_group_visibility_eye_on_pressed.png Binary files differnew file mode 100644 index 0000000000..e8a64541ee --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/profile_group_visibility_eye_on_pressed.png diff --git a/indra/newview/skins/contrast/textures/icons/remove_icon.png b/indra/newview/skins/contrast/textures/icons/remove_icon.png Binary files differnew file mode 100644 index 0000000000..d8a45cc21c --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/remove_icon.png diff --git a/indra/newview/skins/contrast/textures/icons/see_me_online.png b/indra/newview/skins/contrast/textures/icons/see_me_online.png Binary files differnew file mode 100644 index 0000000000..5684e27f43 --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/see_me_online.png diff --git a/indra/newview/skins/contrast/textures/icons/see_on_map.png b/indra/newview/skins/contrast/textures/icons/see_on_map.png Binary files differnew file mode 100644 index 0000000000..fc7057cacd --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/see_on_map.png diff --git a/indra/newview/skins/contrast/textures/icons/see_them_on_map.png b/indra/newview/skins/contrast/textures/icons/see_them_on_map.png Binary files differnew file mode 100644 index 0000000000..d309980c13 --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/see_them_on_map.png diff --git a/indra/newview/skins/contrast/textures/icons/see_them_online.png b/indra/newview/skins/contrast/textures/icons/see_them_online.png Binary files differnew file mode 100644 index 0000000000..135e6cdd82 --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/see_them_online.png diff --git a/indra/newview/skins/contrast/textures/icons/single_folder_back.png b/indra/newview/skins/contrast/textures/icons/single_folder_back.png Binary files differnew file mode 100644 index 0000000000..b93bb2525a --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/single_folder_back.png diff --git a/indra/newview/skins/contrast/textures/icons/single_folder_forward.png b/indra/newview/skins/contrast/textures/icons/single_folder_forward.png Binary files differnew file mode 100644 index 0000000000..12a21b2bba --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/single_folder_forward.png diff --git a/indra/newview/skins/contrast/textures/icons/single_folder_mode.png b/indra/newview/skins/contrast/textures/icons/single_folder_mode.png Binary files differnew file mode 100644 index 0000000000..0fc8475917 --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/single_folder_mode.png diff --git a/indra/newview/skins/contrast/textures/icons/single_folder_up.png b/indra/newview/skins/contrast/textures/icons/single_folder_up.png Binary files differnew file mode 100644 index 0000000000..c1c8c63870 --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/single_folder_up.png diff --git a/indra/newview/skins/contrast/textures/icons/snapshot_icon.png b/indra/newview/skins/contrast/textures/icons/snapshot_icon.png Binary files differnew file mode 100644 index 0000000000..9b6ac6eeb0 --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/snapshot_icon.png diff --git a/indra/newview/skins/contrast/textures/icons/texture_icon.png b/indra/newview/skins/contrast/textures/icons/texture_icon.png Binary files differnew file mode 100644 index 0000000000..f5c205208c --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/texture_icon.png diff --git a/indra/newview/skins/contrast/textures/icons/thumbnail_fallback_icon.png b/indra/newview/skins/contrast/textures/icons/thumbnail_fallback_icon.png Binary files differnew file mode 100644 index 0000000000..19629aba04 --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/thumbnail_fallback_icon.png diff --git a/indra/newview/skins/contrast/textures/icons/unknown_icon.png b/indra/newview/skins/contrast/textures/icons/unknown_icon.png Binary files differnew file mode 100644 index 0000000000..9a4e7f8616 --- /dev/null +++ b/indra/newview/skins/contrast/textures/icons/unknown_icon.png diff --git a/indra/newview/skins/contrast/textures/jump_left_in.tga b/indra/newview/skins/contrast/textures/jump_left_in.tga Binary files differnew file mode 100644 index 0000000000..e0656c901d --- /dev/null +++ b/indra/newview/skins/contrast/textures/jump_left_in.tga diff --git a/indra/newview/skins/contrast/textures/jump_left_out.tga b/indra/newview/skins/contrast/textures/jump_left_out.tga Binary files differnew file mode 100644 index 0000000000..fb6dac0c3d --- /dev/null +++ b/indra/newview/skins/contrast/textures/jump_left_out.tga diff --git a/indra/newview/skins/contrast/textures/jump_right_in.tga b/indra/newview/skins/contrast/textures/jump_right_in.tga Binary files differnew file mode 100644 index 0000000000..010c748c2a --- /dev/null +++ b/indra/newview/skins/contrast/textures/jump_right_in.tga diff --git a/indra/newview/skins/contrast/textures/jump_right_out.tga b/indra/newview/skins/contrast/textures/jump_right_out.tga Binary files differnew file mode 100644 index 0000000000..33355262d4 --- /dev/null +++ b/indra/newview/skins/contrast/textures/jump_right_out.tga diff --git a/indra/newview/skins/contrast/textures/lag_status_critical.tga b/indra/newview/skins/contrast/textures/lag_status_critical.tga Binary files differnew file mode 100644 index 0000000000..bbc71d9e77 --- /dev/null +++ b/indra/newview/skins/contrast/textures/lag_status_critical.tga diff --git a/indra/newview/skins/contrast/textures/lag_status_good.tga b/indra/newview/skins/contrast/textures/lag_status_good.tga Binary files differnew file mode 100644 index 0000000000..680ba90f17 --- /dev/null +++ b/indra/newview/skins/contrast/textures/lag_status_good.tga diff --git a/indra/newview/skins/contrast/textures/lag_status_warning.tga b/indra/newview/skins/contrast/textures/lag_status_warning.tga Binary files differnew file mode 100644 index 0000000000..13ce3cc396 --- /dev/null +++ b/indra/newview/skins/contrast/textures/lag_status_warning.tga diff --git a/indra/newview/skins/contrast/textures/legend.tga b/indra/newview/skins/contrast/textures/legend.tga Binary files differnew file mode 100644 index 0000000000..0dbb8fda4f --- /dev/null +++ b/indra/newview/skins/contrast/textures/legend.tga diff --git a/indra/newview/skins/contrast/textures/locked_image.j2c b/indra/newview/skins/contrast/textures/locked_image.j2c Binary files differnew file mode 100644 index 0000000000..9e8998d675 --- /dev/null +++ b/indra/newview/skins/contrast/textures/locked_image.j2c diff --git a/indra/newview/skins/contrast/textures/map_avatar_16.tga b/indra/newview/skins/contrast/textures/map_avatar_16.tga Binary files differnew file mode 100644 index 0000000000..f59e9e9193 --- /dev/null +++ b/indra/newview/skins/contrast/textures/map_avatar_16.tga diff --git a/indra/newview/skins/contrast/textures/map_avatar_32.tga b/indra/newview/skins/contrast/textures/map_avatar_32.tga Binary files differnew file mode 100644 index 0000000000..aebeab4093 --- /dev/null +++ b/indra/newview/skins/contrast/textures/map_avatar_32.tga diff --git a/indra/newview/skins/contrast/textures/map_avatar_8.tga b/indra/newview/skins/contrast/textures/map_avatar_8.tga Binary files differnew file mode 100644 index 0000000000..8500eadeba --- /dev/null +++ b/indra/newview/skins/contrast/textures/map_avatar_8.tga diff --git a/indra/newview/skins/contrast/textures/map_avatar_above_32.tga b/indra/newview/skins/contrast/textures/map_avatar_above_32.tga Binary files differnew file mode 100644 index 0000000000..65bd0561a7 --- /dev/null +++ b/indra/newview/skins/contrast/textures/map_avatar_above_32.tga diff --git a/indra/newview/skins/contrast/textures/map_avatar_below_32.tga b/indra/newview/skins/contrast/textures/map_avatar_below_32.tga Binary files differnew file mode 100644 index 0000000000..496c44b369 --- /dev/null +++ b/indra/newview/skins/contrast/textures/map_avatar_below_32.tga diff --git a/indra/newview/skins/contrast/textures/map_avatar_unknown_32.tga b/indra/newview/skins/contrast/textures/map_avatar_unknown_32.tga Binary files differnew file mode 100644 index 0000000000..d1192478c6 --- /dev/null +++ b/indra/newview/skins/contrast/textures/map_avatar_unknown_32.tga diff --git a/indra/newview/skins/contrast/textures/map_avatar_you_32.tga b/indra/newview/skins/contrast/textures/map_avatar_you_32.tga Binary files differnew file mode 100644 index 0000000000..84b57aceaf --- /dev/null +++ b/indra/newview/skins/contrast/textures/map_avatar_you_32.tga diff --git a/indra/newview/skins/contrast/textures/map_event.tga b/indra/newview/skins/contrast/textures/map_event.tga Binary files differnew file mode 100644 index 0000000000..2c06d08fd2 --- /dev/null +++ b/indra/newview/skins/contrast/textures/map_event.tga diff --git a/indra/newview/skins/contrast/textures/map_home.tga b/indra/newview/skins/contrast/textures/map_home.tga Binary files differnew file mode 100644 index 0000000000..acaaa3db44 --- /dev/null +++ b/indra/newview/skins/contrast/textures/map_home.tga diff --git a/indra/newview/skins/contrast/textures/map_infohub.tga b/indra/newview/skins/contrast/textures/map_infohub.tga Binary files differnew file mode 100644 index 0000000000..d0134fa5fe --- /dev/null +++ b/indra/newview/skins/contrast/textures/map_infohub.tga diff --git a/indra/newview/skins/contrast/textures/map_telehub.tga b/indra/newview/skins/contrast/textures/map_telehub.tga Binary files differnew file mode 100644 index 0000000000..545b8e532c --- /dev/null +++ b/indra/newview/skins/contrast/textures/map_telehub.tga diff --git a/indra/newview/skins/contrast/textures/map_track_16.tga b/indra/newview/skins/contrast/textures/map_track_16.tga Binary files differnew file mode 100644 index 0000000000..451ce24cf0 --- /dev/null +++ b/indra/newview/skins/contrast/textures/map_track_16.tga diff --git a/indra/newview/skins/contrast/textures/map_ui_collapse_icon.png b/indra/newview/skins/contrast/textures/map_ui_collapse_icon.png Binary files differnew file mode 100644 index 0000000000..e4de49d4af --- /dev/null +++ b/indra/newview/skins/contrast/textures/map_ui_collapse_icon.png diff --git a/indra/newview/skins/contrast/textures/map_ui_expand_icon.png b/indra/newview/skins/contrast/textures/map_ui_expand_icon.png Binary files differnew file mode 100644 index 0000000000..08734b4cc0 --- /dev/null +++ b/indra/newview/skins/contrast/textures/map_ui_expand_icon.png diff --git a/indra/newview/skins/contrast/textures/materials_ui_x_24.png b/indra/newview/skins/contrast/textures/materials_ui_x_24.png Binary files differnew file mode 100644 index 0000000000..6d88554914 --- /dev/null +++ b/indra/newview/skins/contrast/textures/materials_ui_x_24.png diff --git a/indra/newview/skins/contrast/textures/megapahit/icon_group.png b/indra/newview/skins/contrast/textures/megapahit/icon_group.png Binary files differnew file mode 100644 index 0000000000..f3872dea3f --- /dev/null +++ b/indra/newview/skins/contrast/textures/megapahit/icon_group.png diff --git a/indra/newview/skins/contrast/textures/megapahit/icon_land_auction.png b/indra/newview/skins/contrast/textures/megapahit/icon_land_auction.png Binary files differnew file mode 100644 index 0000000000..550703968f --- /dev/null +++ b/indra/newview/skins/contrast/textures/megapahit/icon_land_auction.png diff --git a/indra/newview/skins/contrast/textures/megapahit/icon_land_forsale.png b/indra/newview/skins/contrast/textures/megapahit/icon_land_forsale.png Binary files differnew file mode 100644 index 0000000000..209bb868ea --- /dev/null +++ b/indra/newview/skins/contrast/textures/megapahit/icon_land_forsale.png diff --git a/indra/newview/skins/contrast/textures/megapahit/icon_place.png b/indra/newview/skins/contrast/textures/megapahit/icon_place.png Binary files differnew file mode 100644 index 0000000000..60cf42424a --- /dev/null +++ b/indra/newview/skins/contrast/textures/megapahit/icon_place.png diff --git a/indra/newview/skins/contrast/textures/menu_separator.png b/indra/newview/skins/contrast/textures/menu_separator.png Binary files differnew file mode 100644 index 0000000000..7bb27c499d --- /dev/null +++ b/indra/newview/skins/contrast/textures/menu_separator.png diff --git a/indra/newview/skins/contrast/textures/missing_asset.tga b/indra/newview/skins/contrast/textures/missing_asset.tga Binary files differnew file mode 100644 index 0000000000..9a43f4db5d --- /dev/null +++ b/indra/newview/skins/contrast/textures/missing_asset.tga diff --git a/indra/newview/skins/contrast/textures/model_wizard/progress_bar_bg.png b/indra/newview/skins/contrast/textures/model_wizard/progress_bar_bg.png Binary files differnew file mode 100644 index 0000000000..7c6920205f --- /dev/null +++ b/indra/newview/skins/contrast/textures/model_wizard/progress_bar_bg.png diff --git a/indra/newview/skins/contrast/textures/model_wizard/progress_light.png b/indra/newview/skins/contrast/textures/model_wizard/progress_light.png Binary files differnew file mode 100644 index 0000000000..be6b263fb6 --- /dev/null +++ b/indra/newview/skins/contrast/textures/model_wizard/progress_light.png diff --git a/indra/newview/skins/contrast/textures/navbar/Arrow_Left_Off.png b/indra/newview/skins/contrast/textures/navbar/Arrow_Left_Off.png Binary files differnew file mode 100644 index 0000000000..19569501fe --- /dev/null +++ b/indra/newview/skins/contrast/textures/navbar/Arrow_Left_Off.png diff --git a/indra/newview/skins/contrast/textures/navbar/Arrow_Right_Off.png b/indra/newview/skins/contrast/textures/navbar/Arrow_Right_Off.png Binary files differnew file mode 100644 index 0000000000..3648c42656 --- /dev/null +++ b/indra/newview/skins/contrast/textures/navbar/Arrow_Right_Off.png diff --git a/indra/newview/skins/contrast/textures/navbar/BuyArrow_Over.png b/indra/newview/skins/contrast/textures/navbar/BuyArrow_Over.png Binary files differnew file mode 100644 index 0000000000..3d9c758574 --- /dev/null +++ b/indra/newview/skins/contrast/textures/navbar/BuyArrow_Over.png diff --git a/indra/newview/skins/contrast/textures/navbar/BuyArrow_Press.png b/indra/newview/skins/contrast/textures/navbar/BuyArrow_Press.png Binary files differnew file mode 100644 index 0000000000..69b0d43900 --- /dev/null +++ b/indra/newview/skins/contrast/textures/navbar/BuyArrow_Press.png diff --git a/indra/newview/skins/contrast/textures/navbar/Favorite_Link_Over.png b/indra/newview/skins/contrast/textures/navbar/Favorite_Link_Over.png Binary files differnew file mode 100644 index 0000000000..d4f126f969 --- /dev/null +++ b/indra/newview/skins/contrast/textures/navbar/Favorite_Link_Over.png diff --git a/indra/newview/skins/contrast/textures/navbar/Favorite_Star_Active.png b/indra/newview/skins/contrast/textures/navbar/Favorite_Star_Active.png Binary files differnew file mode 100644 index 0000000000..6d42f52963 --- /dev/null +++ b/indra/newview/skins/contrast/textures/navbar/Favorite_Star_Active.png diff --git a/indra/newview/skins/contrast/textures/navbar/Favorite_Star_Off.png b/indra/newview/skins/contrast/textures/navbar/Favorite_Star_Off.png Binary files differnew file mode 100644 index 0000000000..82d044d817 --- /dev/null +++ b/indra/newview/skins/contrast/textures/navbar/Favorite_Star_Off.png diff --git a/indra/newview/skins/contrast/textures/navbar/Favorite_Star_Over.png b/indra/newview/skins/contrast/textures/navbar/Favorite_Star_Over.png Binary files differnew file mode 100644 index 0000000000..74861fdb58 --- /dev/null +++ b/indra/newview/skins/contrast/textures/navbar/Favorite_Star_Over.png diff --git a/indra/newview/skins/contrast/textures/navbar/Favorite_Star_Press.png b/indra/newview/skins/contrast/textures/navbar/Favorite_Star_Press.png Binary files differnew file mode 100644 index 0000000000..6670667022 --- /dev/null +++ b/indra/newview/skins/contrast/textures/navbar/Favorite_Star_Press.png diff --git a/indra/newview/skins/contrast/textures/navbar/FileMenu_Divider.png b/indra/newview/skins/contrast/textures/navbar/FileMenu_Divider.png Binary files differnew file mode 100644 index 0000000000..5ab4abc5b8 --- /dev/null +++ b/indra/newview/skins/contrast/textures/navbar/FileMenu_Divider.png diff --git a/indra/newview/skins/contrast/textures/navbar/Flag.png b/indra/newview/skins/contrast/textures/navbar/Flag.png Binary files differnew file mode 100644 index 0000000000..df53c89224 --- /dev/null +++ b/indra/newview/skins/contrast/textures/navbar/Flag.png diff --git a/indra/newview/skins/contrast/textures/navbar/Help_Press.png b/indra/newview/skins/contrast/textures/navbar/Help_Press.png Binary files differnew file mode 100644 index 0000000000..ed3695f9d5 --- /dev/null +++ b/indra/newview/skins/contrast/textures/navbar/Help_Press.png diff --git a/indra/newview/skins/contrast/textures/navbar/Home_Off.png b/indra/newview/skins/contrast/textures/navbar/Home_Off.png Binary files differnew file mode 100644 index 0000000000..fe3bc63b77 --- /dev/null +++ b/indra/newview/skins/contrast/textures/navbar/Home_Off.png diff --git a/indra/newview/skins/contrast/textures/navbar/Info_Off.png b/indra/newview/skins/contrast/textures/navbar/Info_Off.png Binary files differnew file mode 100644 index 0000000000..64722255a3 --- /dev/null +++ b/indra/newview/skins/contrast/textures/navbar/Info_Off.png diff --git a/indra/newview/skins/contrast/textures/navbar/Info_Over.png b/indra/newview/skins/contrast/textures/navbar/Info_Over.png Binary files differnew file mode 100644 index 0000000000..84f1d03129 --- /dev/null +++ b/indra/newview/skins/contrast/textures/navbar/Info_Over.png diff --git a/indra/newview/skins/contrast/textures/navbar/Info_Press.png b/indra/newview/skins/contrast/textures/navbar/Info_Press.png Binary files differnew file mode 100644 index 0000000000..169105829e --- /dev/null +++ b/indra/newview/skins/contrast/textures/navbar/Info_Press.png diff --git a/indra/newview/skins/contrast/textures/navbar/Landmarks.png b/indra/newview/skins/contrast/textures/navbar/Landmarks.png Binary files differnew file mode 100644 index 0000000000..2b35de913b --- /dev/null +++ b/indra/newview/skins/contrast/textures/navbar/Landmarks.png diff --git a/indra/newview/skins/contrast/textures/navbar/Lock.png b/indra/newview/skins/contrast/textures/navbar/Lock.png Binary files differnew file mode 100644 index 0000000000..cf569d6ad2 --- /dev/null +++ b/indra/newview/skins/contrast/textures/navbar/Lock.png diff --git a/indra/newview/skins/contrast/textures/navbar/NavBar_BG.png b/indra/newview/skins/contrast/textures/navbar/NavBar_BG.png Binary files differnew file mode 100644 index 0000000000..6a91700ae0 --- /dev/null +++ b/indra/newview/skins/contrast/textures/navbar/NavBar_BG.png diff --git a/indra/newview/skins/contrast/textures/navbar/NavBar_BG_NoFav_Bevel.png b/indra/newview/skins/contrast/textures/navbar/NavBar_BG_NoFav_Bevel.png Binary files differnew file mode 100644 index 0000000000..c61dcde58c --- /dev/null +++ b/indra/newview/skins/contrast/textures/navbar/NavBar_BG_NoFav_Bevel.png diff --git a/indra/newview/skins/contrast/textures/navbar/NavBar_BG_NoNav_Bevel.png b/indra/newview/skins/contrast/textures/navbar/NavBar_BG_NoNav_Bevel.png Binary files differnew file mode 100644 index 0000000000..9e3da34596 --- /dev/null +++ b/indra/newview/skins/contrast/textures/navbar/NavBar_BG_NoNav_Bevel.png diff --git a/indra/newview/skins/contrast/textures/navbar/Row_Selection.png b/indra/newview/skins/contrast/textures/navbar/Row_Selection.png Binary files differnew file mode 100644 index 0000000000..d3870fb640 --- /dev/null +++ b/indra/newview/skins/contrast/textures/navbar/Row_Selection.png diff --git a/indra/newview/skins/contrast/textures/navbar/Search.png b/indra/newview/skins/contrast/textures/navbar/Search.png Binary files differnew file mode 100644 index 0000000000..4c29e57f7b --- /dev/null +++ b/indra/newview/skins/contrast/textures/navbar/Search.png diff --git a/indra/newview/skins/contrast/textures/navbar/separator.png b/indra/newview/skins/contrast/textures/navbar/separator.png Binary files differnew file mode 100644 index 0000000000..c1d74e5a64 --- /dev/null +++ b/indra/newview/skins/contrast/textures/navbar/separator.png diff --git a/indra/newview/skins/contrast/textures/notify_caution_icon.tga b/indra/newview/skins/contrast/textures/notify_caution_icon.tga Binary files differnew file mode 100644 index 0000000000..abc23d1d7a --- /dev/null +++ b/indra/newview/skins/contrast/textures/notify_caution_icon.tga diff --git a/indra/newview/skins/contrast/textures/pixiesmall.j2c b/indra/newview/skins/contrast/textures/pixiesmall.j2c Binary files differnew file mode 100644 index 0000000000..a1ff64014b --- /dev/null +++ b/indra/newview/skins/contrast/textures/pixiesmall.j2c diff --git a/indra/newview/skins/contrast/textures/red_x.png b/indra/newview/skins/contrast/textures/red_x.png Binary files differnew file mode 100644 index 0000000000..a61202f09b --- /dev/null +++ b/indra/newview/skins/contrast/textures/red_x.png diff --git a/indra/newview/skins/contrast/textures/rounded_square.j2c b/indra/newview/skins/contrast/textures/rounded_square.j2c Binary files differnew file mode 100644 index 0000000000..c8bb572fa9 --- /dev/null +++ b/indra/newview/skins/contrast/textures/rounded_square.j2c diff --git a/indra/newview/skins/contrast/textures/script_error.j2c b/indra/newview/skins/contrast/textures/script_error.j2c Binary files differnew file mode 100644 index 0000000000..893cb642e7 --- /dev/null +++ b/indra/newview/skins/contrast/textures/script_error.j2c diff --git a/indra/newview/skins/contrast/textures/silhouette.j2c b/indra/newview/skins/contrast/textures/silhouette.j2c Binary files differnew file mode 100644 index 0000000000..3859d4cb34 --- /dev/null +++ b/indra/newview/skins/contrast/textures/silhouette.j2c diff --git a/indra/newview/skins/contrast/textures/slim_icon_16_viewer.tga b/indra/newview/skins/contrast/textures/slim_icon_16_viewer.tga Binary files differnew file mode 100644 index 0000000000..552181d36a --- /dev/null +++ b/indra/newview/skins/contrast/textures/slim_icon_16_viewer.tga diff --git a/indra/newview/skins/contrast/textures/snapshot_download.png b/indra/newview/skins/contrast/textures/snapshot_download.png Binary files differnew file mode 100644 index 0000000000..6aa1abded5 --- /dev/null +++ b/indra/newview/skins/contrast/textures/snapshot_download.png diff --git a/indra/newview/skins/contrast/textures/snapshot_email.png b/indra/newview/skins/contrast/textures/snapshot_email.png Binary files differnew file mode 100644 index 0000000000..dee784a9bf --- /dev/null +++ b/indra/newview/skins/contrast/textures/snapshot_email.png diff --git a/indra/newview/skins/contrast/textures/spacer24.tga b/indra/newview/skins/contrast/textures/spacer24.tga Binary files differnew file mode 100644 index 0000000000..c7cab6b38c --- /dev/null +++ b/indra/newview/skins/contrast/textures/spacer24.tga diff --git a/indra/newview/skins/contrast/textures/tabarea.tga b/indra/newview/skins/contrast/textures/tabarea.tga Binary files differnew file mode 100644 index 0000000000..5517aebfc8 --- /dev/null +++ b/indra/newview/skins/contrast/textures/tabarea.tga diff --git a/indra/newview/skins/contrast/textures/taskpanel/Activate_Checkmark.png b/indra/newview/skins/contrast/textures/taskpanel/Activate_Checkmark.png Binary files differnew file mode 100644 index 0000000000..213acbe87b --- /dev/null +++ b/indra/newview/skins/contrast/textures/taskpanel/Activate_Checkmark.png diff --git a/indra/newview/skins/contrast/textures/taskpanel/Sidebar_Icon_Dock_Foreground.png b/indra/newview/skins/contrast/textures/taskpanel/Sidebar_Icon_Dock_Foreground.png Binary files differnew file mode 100644 index 0000000000..4e59042e33 --- /dev/null +++ b/indra/newview/skins/contrast/textures/taskpanel/Sidebar_Icon_Dock_Foreground.png diff --git a/indra/newview/skins/contrast/textures/taskpanel/Sidebar_Icon_Dock_Press.png b/indra/newview/skins/contrast/textures/taskpanel/Sidebar_Icon_Dock_Press.png Binary files differnew file mode 100644 index 0000000000..be7b298bb8 --- /dev/null +++ b/indra/newview/skins/contrast/textures/taskpanel/Sidebar_Icon_Dock_Press.png diff --git a/indra/newview/skins/contrast/textures/taskpanel/Sidebar_Icon_Undock_Foreground.png b/indra/newview/skins/contrast/textures/taskpanel/Sidebar_Icon_Undock_Foreground.png Binary files differnew file mode 100644 index 0000000000..1e234ff09b --- /dev/null +++ b/indra/newview/skins/contrast/textures/taskpanel/Sidebar_Icon_Undock_Foreground.png diff --git a/indra/newview/skins/contrast/textures/taskpanel/Sidebar_Icon_Undock_Press.png b/indra/newview/skins/contrast/textures/taskpanel/Sidebar_Icon_Undock_Press.png Binary files differnew file mode 100644 index 0000000000..48c78b453d --- /dev/null +++ b/indra/newview/skins/contrast/textures/taskpanel/Sidebar_Icon_Undock_Press.png diff --git a/indra/newview/skins/contrast/textures/taskpanel/TabIcon_Close_Off.png b/indra/newview/skins/contrast/textures/taskpanel/TabIcon_Close_Off.png Binary files differnew file mode 100644 index 0000000000..bc4e00c646 --- /dev/null +++ b/indra/newview/skins/contrast/textures/taskpanel/TabIcon_Close_Off.png diff --git a/indra/newview/skins/contrast/textures/taskpanel/TabIcon_Home_Selected.png b/indra/newview/skins/contrast/textures/taskpanel/TabIcon_Home_Selected.png Binary files differnew file mode 100644 index 0000000000..293aeef5e6 --- /dev/null +++ b/indra/newview/skins/contrast/textures/taskpanel/TabIcon_Home_Selected.png diff --git a/indra/newview/skins/contrast/textures/taskpanel/TabIcon_Me_Off.png b/indra/newview/skins/contrast/textures/taskpanel/TabIcon_Me_Off.png Binary files differnew file mode 100644 index 0000000000..760db9360d --- /dev/null +++ b/indra/newview/skins/contrast/textures/taskpanel/TabIcon_Me_Off.png diff --git a/indra/newview/skins/contrast/textures/taskpanel/TabIcon_Open_Off.png b/indra/newview/skins/contrast/textures/taskpanel/TabIcon_Open_Off.png Binary files differnew file mode 100644 index 0000000000..4556602f58 --- /dev/null +++ b/indra/newview/skins/contrast/textures/taskpanel/TabIcon_Open_Off.png diff --git a/indra/newview/skins/contrast/textures/taskpanel/TabIcon_People_Off.png b/indra/newview/skins/contrast/textures/taskpanel/TabIcon_People_Off.png Binary files differnew file mode 100644 index 0000000000..691b600510 --- /dev/null +++ b/indra/newview/skins/contrast/textures/taskpanel/TabIcon_People_Off.png diff --git a/indra/newview/skins/contrast/textures/taskpanel/TabIcon_Places_Off.png b/indra/newview/skins/contrast/textures/taskpanel/TabIcon_Places_Off.png Binary files differnew file mode 100644 index 0000000000..f5a5f7a846 --- /dev/null +++ b/indra/newview/skins/contrast/textures/taskpanel/TabIcon_Places_Off.png diff --git a/indra/newview/skins/contrast/textures/taskpanel/TabIcon_Things_Off.png b/indra/newview/skins/contrast/textures/taskpanel/TabIcon_Things_Off.png Binary files differnew file mode 100644 index 0000000000..e56eda9802 --- /dev/null +++ b/indra/newview/skins/contrast/textures/taskpanel/TabIcon_Things_Off.png diff --git a/indra/newview/skins/contrast/textures/taskpanel/TaskPanel_Tab_Off.png b/indra/newview/skins/contrast/textures/taskpanel/TaskPanel_Tab_Off.png Binary files differnew file mode 100644 index 0000000000..4ed7a2b183 --- /dev/null +++ b/indra/newview/skins/contrast/textures/taskpanel/TaskPanel_Tab_Off.png diff --git a/indra/newview/skins/contrast/textures/taskpanel/TaskPanel_Tab_Selected.png b/indra/newview/skins/contrast/textures/taskpanel/TaskPanel_Tab_Selected.png Binary files differnew file mode 100644 index 0000000000..b3316386b9 --- /dev/null +++ b/indra/newview/skins/contrast/textures/taskpanel/TaskPanel_Tab_Selected.png diff --git a/indra/newview/skins/contrast/textures/tearoff_pressed.tga b/indra/newview/skins/contrast/textures/tearoff_pressed.tga Binary files differnew file mode 100644 index 0000000000..620d109de0 --- /dev/null +++ b/indra/newview/skins/contrast/textures/tearoff_pressed.tga diff --git a/indra/newview/skins/contrast/textures/tearoffbox.tga b/indra/newview/skins/contrast/textures/tearoffbox.tga Binary files differnew file mode 100644 index 0000000000..0670d2e91b --- /dev/null +++ b/indra/newview/skins/contrast/textures/tearoffbox.tga diff --git a/indra/newview/skins/contrast/textures/textures.xml b/indra/newview/skins/contrast/textures/textures.xml new file mode 100644 index 0000000000..f824816183 --- /dev/null +++ b/indra/newview/skins/contrast/textures/textures.xml @@ -0,0 +1,934 @@ +<!-- +This file contains metadata about how to load, display, and scale textures for rendering in the UI. +Images do *NOT* have to appear in this file in order to use them as textures in the UI...simply refer +to them by filename (relative to textures directory). +NOTE: if you want to reuse an image file with different metadata, simply create a new texture entry +with the same filename but different name + +<texture + name="MyTexture" (mandatory) + - this is the name you reference the texture by in XUI. For example, <button image_unselected="MyTexture"/> + file_name="images/my_texture.png" (optional) + - this is the path to the actual file asset, relative to the current skins "textures" directory. + If not supplied, the filename will be taken from the texture name itself, "MyTexture" in this case. + NOTE: you need to provide an extension on the filename (".png", ".tga", ".jpg") for us to decode the image properly + preload="true" (optional, false by default) + - If true, we will attempt to load the image before displaying any UI. + If false, we will load in the background after initializing the UI. + use_mips="true" (currently unused) + scale.left="1" + scale.bottom="1" + scale.top="15" + scale.right="31" + - Specifies the segmentation for 9-slice image scaling. Specifically, the pixel offsets from the LOWER LEFT corner + that define the region of the image that is stretched to make the whole image fit in the required space. + In this example, if the source image is 32x16 pixels, we have defined a center region that starts one pixel up + and to the right from the bottom left corner and extends to 31 pixels right and 15 pixels up from the bottom left + corner. The end result is that the image will keep a 1 pixel border all around while stretching to fit the required + region. +--> + +<textures version="101"> + <!-- Please add new files alphabetically to prevent merge conflicts. JC --> + <texture name="Accordion_ArrowClosed_Off" file_name="containers/Accordion_ArrowClosed_Off.png" preload="false" /> + <texture name="Accordion_ArrowClosed_Press" file_name="containers/Accordion_ArrowClosed_Press.png" preload="false" /> + <texture name="Accordion_ArrowOpened_Off" file_name="containers/Accordion_ArrowOpened_Off.png" preload="false" /> + <texture name="Accordion_ArrowOpened_Press" file_name="containers/Accordion_ArrowOpened_Press.png" preload="false" /> + <texture name="Accordion_Off" file_name="containers/Accordion_Off.png" preload="false" /> + <texture name="Accordion_Press" file_name="containers/Accordion_Press.png" preload="false" /> + <texture name="Accordion_Over" file_name="containers/Accordion_Over.png" preload="false" /> + <texture name="Accordion_Selected" file_name="containers/Accordion_Selected.png" preload="false" /> + + <texture name="Activate_Checkmark" file_name="taskpanel/Activate_Checkmark.png" preload="false" /> + + <texture name="AddItem_Disabled" file_name="icons/AddItem_Disabled.png" preload="false" /> + <texture name="AddItem_Off" file_name="icons/AddItem_Off.png" preload="false" /> + <texture name="AddItem_Press" file_name="icons/AddItem_Press.png" preload="false" /> + + <texture name="add_payment_image_center" file_name="windows/add_payment_image_center.png" preload="true" /> + <texture name="add_payment_image_left" file_name="windows/add_payment_image_left.png" preload="true" /> + <texture name="add_payment_image_right" file_name="windows/add_payment_image_right.png" preload="true" /> + + <texture name="Arrow_Left_Off" file_name="navbar/Arrow_Left_Off.png" preload="true" /> + <texture name="Arrow_Right_Off" file_name="navbar/Arrow_Right_Off.png" preload="true" /> + + <texture name="Arrow_Small_Up" file_name="widgets/Arrow_Small_Up.png" preload="true" /> + <texture name="Arrow_Small_Left" file_name="widgets/Arrow_Small_Left.png" preload="true" /> + <texture name="Arrow_Small_Right" file_name="widgets/Arrow_Small_Right.png" preload="true" /> + + <texture name="Arrow_Down" file_name="widgets/Arrow_Down.png" preload="true" /> + <texture name="Arrow_Up" file_name="widgets/Arrow_Up.png" preload="true" /> + <texture name="Arrow_Left" file_name="widgets/Arrow_Left.png" preload="true" /> + <texture name="Arrow_Right" file_name="widgets/Arrow_Right.png" preload="true" /> + + <texture name="AudioMute_Off" file_name="icons/AudioMute_Off.png" preload="false" /> + <texture name="AudioMute_Over" file_name="icons/AudioMute_Over.png" preload="false" /> + <texture name="VoiceMute_Off" file_name="icons/VoiceMute_Off.png" preload="false" /> + + <texture name="Audio_Off" file_name="icons/Audio_Off.png" preload="false" /> + <texture name="Audio_Press" file_name="icons/Audio_Press.png" preload="false" /> + + <texture name="BackArrow_Off" file_name="icons/BackArrow_Off.png" preload="false" /> + + <texture name="BackButton_Off" file_name="icons/back_arrow_off.png" preload="false" scale.left="22" scale.top="12" scale.right="25" scale.bottom="12" /> + <texture name="BackButton_Over" file_name="icons/back_arrow_over.png" preload="false" scale.left="22" scale.top="12" scale.right="25" scale.bottom="12" /> + <texture name="BackButton_Press" file_name="icons/back_arrow_press.png" preload="false" scale.left="22" scale.top="12" scale.right="25" scale.bottom="12" /> + + <texture name="Error_Tag_Background" file_name="widgets/Error_Tag_Background.png" preload="true" scale.left="12" scale.top="2" scale.right="36" scale.bottom="2" /> + <texture name="New_Tag_Background" file_name="widgets/New_Tag_Background.png" preload="true" scale.left="12" scale.top="2" scale.right="36" scale.bottom="2" /> + <texture name="New_Tag_Border" file_name="widgets/New_Tag_Border.png" preload="true" scale.left="12" scale.top="2" scale.right="36" scale.bottom="2" /> + + <texture name="Badge_Background" file_name="widgets/Badge_Background.png" preload="true" scale.left="9" scale.top="12" scale.right="248" scale.bottom="12" /> + <texture name="Badge_Border" file_name="widgets/Badge_Border.png" preload="true" scale.left="9" scale.top="12" scale.right="248" scale.bottom="12" /> + + <texture name="Blank" file_name="Blank.png" preload="false" /> + + <texture name="BreadCrumbBtn_Left_Disabled" file_name="widgets/BreadCrumbBtn_Left_Disabled.png" preload="false"/> + <texture name="BreadCrumbBtn_Left_Off" file_name="widgets/BreadCrumbBtn_Left_Off.png" preload="false"/> + <texture name="BreadCrumbBtn_Left_Over" file_name="widgets/BreadCrumbBtn_Left_Over.png" preload="false"/> + <texture name="BreadCrumbBtn_Left_Press" file_name="widgets/BreadCrumbBtn_Left_Press.png" preload="false"/> + + <texture name="BreadCrumbBtn_Middle_Disabled" file_name="widgets/BreadCrumbBtn_Middle_Disabled.png" preload="false"/> + <texture name="BreadCrumbBtn_Middle_Off" file_name="widgets/BreadCrumbBtn_Middle_Off.png" preload="false"/> + <texture name="BreadCrumbBtn_Middle_Over" file_name="widgets/BreadCrumbBtn_Middle_Over.png" preload="false"/> + <texture name="BreadCrumbBtn_Middle_Press" file_name="widgets/BreadCrumbBtn_Middle_Press.png" preload="false"/> + + <texture name="BreadCrumbBtn_Right_Disabled" file_name="widgets/BreadCrumbBtn_Right_Disabled.png" preload="false"/> + <texture name="BreadCrumbBtn_Right_Off" file_name="widgets/BreadCrumbBtn_Right_Off.png" preload="false"/> + <texture name="BreadCrumbBtn_Right_Over" file_name="widgets/BreadCrumbBtn_Right_Over.png" preload="false"/> + <texture name="BreadCrumbBtn_Right_Press" file_name="widgets/BreadCrumbBtn_Right_Press.png" preload="false"/> + + <texture name="BuyArrow_Over" file_name="navbar/BuyArrow_Over.png" preload="true" scale.left="0" scale.top="1" scale.right="0" scale.bottom="0" /> + <texture name="BuyArrow_Press" file_name="navbar/BuyArrow_Press.png" preload="true" scale.left="1" scale.top="1" scale.right="0" scale.bottom="0" /> + + <texture name="Cam_Avatar_Off" file_name="bottomtray/Cam_Avatar_Off.png" preload="true" /> + <texture name="Cam_FreeCam_Off" file_name="bottomtray/Cam_FreeCam_Off.png" preload="false" /> + <texture name="Cam_Orbit_Off" file_name="bottomtray/Cam_Orbit_Off.png" preload="false" /> + <texture name="Cam_Pan_Off" file_name="bottomtray/Cam_Pan_Off.png" preload="false" /> + + <texture name="Cam_Preset_Back_Off" file_name="bottomtray/Cam_Preset_Back_Off.png" preload="false" /> + <texture name="Cam_Preset_Back_On" file_name="bottomtray/Cam_Preset_Back_On.png" preload="false" /> + <texture name="Cam_Preset_Eye_Off" file_name="bottomtray/Cam_Preset_Eye_Off.png" preload="false" /> + <texture name="Cam_Preset_Front_Off" file_name="bottomtray/Cam_Preset_Front_Off.png" preload="false" /> + <texture name="Cam_Preset_Front_On" file_name="bottomtray/Cam_Preset_Front_On.png" preload="false" /> + <texture name="Cam_Preset_Side_Off" file_name="bottomtray/Cam_Preset_Side_Off.png" preload="false" /> + <texture name="Cam_Preset_Side_On" file_name="bottomtray/Cam_Preset_Side_On.png" preload="false" /> + + <texture name="Cam_Rotate_In" file_name="bottomtray/Cam_Rotate_In.png" preload="false" /> + <texture name="Cam_Rotate_Out" file_name="bottomtray/Cam_Rotate_Out.png" preload="false" /> + <texture name="Cam_Rotate_Center" file_name="bottomtray/Cam_Rotate_Center.png" preload="false" /> + <texture name="Cam_Tracking_In" file_name="bottomtray/Cam_Tracking_In.png" preload="false" /> + <texture name="Cam_Tracking_Out" file_name="bottomtray/Cam_Tracking_Out.png" preload="false" /> + <texture name="Cam_Tracking_Center" file_name="bottomtray/Cam_Tracking_Center.png" preload="false" /> + + <texture name="Checkbox_Off_Disabled" file_name="widgets/Checkbox_Disabled.png" preload="true" /> + <texture name="Checkbox_On_Disabled" file_name="widgets/Checkbox_On_Disabled.png" preload="true" /> + <texture name="Checkbox_Off" file_name="widgets/Checkbox_Off.png" preload="true" /> + <texture name="Checkbox_On" file_name="widgets/Checkbox_On.png" preload="true" /> + <texture name="Checkbox_On_Press" file_name="widgets/Checkbox_On_Press.png" preload="true" /> + <texture name="Checkbox_Press" file_name="widgets/Checkbox_Press.png" preload="true" /> + <texture name="Check_Mark" file_name="icons/check_mark.png" preload="true" /> + + <texture name="Checker" file_name="checker.png" preload="false" /> + + <texture name="Command_360_Capture_Icon" file_name="toolbar_icons/360_capture.png" preload="true" /> + <texture name="Command_AboutLand_Icon" file_name="toolbar_icons/land.png" preload="true" /> + <texture name="Command_Appearance_Icon" file_name="toolbar_icons/appearance.png" preload="true" /> + <texture name="Command_Avatar_Icon" file_name="toolbar_icons/avatars.png" preload="true" /> + <texture name="Command_Build_Icon" file_name="toolbar_icons/build.png" preload="true" /> + <texture name="Command_Chat_Icon" file_name="toolbar_icons/chat.png" preload="true" /> + <texture name="Command_Compass_Icon" file_name="toolbar_icons/land.png" preload="true" /> + <texture name="Command_Destinations_Icon" file_name="toolbar_icons/destinations.png" preload="true" /> + <texture name="Command_Gestures_Icon" file_name="toolbar_icons/gestures.png" preload="true" /> + <texture name="Command_Grid_Status_Icon" file_name="toolbar_icons/grid_status.png" preload="true" /> + <texture name="Command_HowTo_Icon" file_name="toolbar_icons/howto.png" preload="true" /> + <texture name="Command_Inventory_Icon" file_name="toolbar_icons/inventory.png" preload="true" /> + <texture name="Command_Map_Icon" file_name="toolbar_icons/map.png" preload="true" /> + <texture name="Command_Marketplace_Icon" file_name="toolbar_icons/marketplace.png" preload="true" /> + <texture name="Command_MktListings_Icon" file_name="toolbar_icons/mktlistings.png" preload="true" /> + <texture name="Command_MiniCart_Icon" file_name="toolbar_icons/mini_cart.png" preload="true" /> + <texture name="Command_MiniMap_Icon" file_name="toolbar_icons/mini_map.png" preload="true" /> + <texture name="Command_Move_Icon" file_name="toolbar_icons/move.png" preload="true" /> + <texture name="Command_Environments_Icon" file_name="toolbar_icons/environments.png" preload="true" /> + <texture name="Command_People_Icon" file_name="toolbar_icons/people.png" preload="true" /> + <texture name="Command_Performance_Icon" file_name="toolbar_icons/performance.png" preload="true" /> + <texture name="Command_Picks_Icon" file_name="toolbar_icons/picks.png" preload="true" /> + <texture name="Command_Places_Icon" file_name="toolbar_icons/places.png" preload="true" /> + <texture name="Command_Preferences_Icon" file_name="toolbar_icons/preferences.png" preload="true" /> + <texture name="Command_Profile_Icon" file_name="toolbar_icons/profile.png" preload="true" /> + <texture name="Command_Report_Abuse_Icon" file_name="toolbar_icons/report_abuse.png" preload="true" /> + <texture name="Command_Search_Icon" file_name="toolbar_icons/search.png" preload="true" /> + <texture name="Command_Snapshot_Icon" file_name="toolbar_icons/snapshot.png" preload="true" /> + <texture name="Command_Speak_Icon" file_name="toolbar_icons/speak.png" preload="true" /> + <texture name="Command_View_Icon" file_name="toolbar_icons/view.png" preload="true" /> + <texture name="Command_Voice_Icon" file_name="toolbar_icons/nearbyvoice.png" preload="true" /> + <texture name="Command_FavoriteFolder_Icon" file_name="toolbar_icons/favorite_folder.png" preload="true" /> + <texture name="Command_Resync_Animations" file_name="toolbar_icons/resync_animations.png" preload="true" /> + <texture name="Caret_Bottom_Icon" file_name="toolbar_icons/caret_bottom.png" preload="true" scale.left="1" scale.top="23" scale.right="15" scale.bottom="1" /> + <texture name="Caret_Right_Icon" file_name="toolbar_icons/caret_right.png" preload="true" scale.left="5" scale.top="15" scale.right="28" scale.bottom="1" /> + <texture name="Caret_Left_Icon" file_name="toolbar_icons/caret_left.png" preload="true" scale.left="1" scale.top="15" scale.right="23" scale.bottom="1" /> + + <texture name="ComboButton_Disabled" file_name="widgets/ComboButton_Disabled.png" preload="true" scale.left="2" scale.top="19" scale.right="18" scale.bottom="2" /> + <texture name="ComboButton_Selected" file_name="widgets/ComboButton_Selected.png" preload="true" scale.left="2" scale.top="19" scale.right="18" scale.bottom="2" /> + <texture name="ComboButton_UpSelected" file_name="widgets/ComboButton_UpSelected.png" preload="true" scale.left="2" scale.top="19" scale.right="18" scale.bottom="2" /> + <texture name="ComboButton_On" file_name="widgets/ComboButton_On.png" preload="true" scale.left="2" scale.top="19" scale.right="18" scale.bottom="2" /> + <texture name="ComboButton_Off" file_name="widgets/ComboButton_Off.png" preload="true" scale.left="2" scale.top="19" scale.right="18" scale.bottom="2" /> + <texture name="ComboButton_UpOff" file_name="widgets/ComboButton_UpOff.png" preload="true" scale.left="2" scale.top="19" scale.right="18" scale.bottom="2" /> + + <texture name="Container" file_name="containers/Container.png" preload="false" /> + + <texture name="Conv_toolbar_add_person" file_name="icons/Conv_toolbar_add_person.png" preload="false" /> + <texture name="Conv_toolbar_arrow_ne" file_name="icons/Conv_toolbar_arrow_ne.png" preload="false" /> + <texture name="Conv_toolbar_arrow_sw" file_name="icons/Conv_toolbar_arrow_sw.png" preload="false" /> + <texture name="Conv_toolbar_call_log" file_name="icons/Conv_toolbar_call_log.png" preload="false" /> + <texture name="Conv_toolbar_close" file_name="icons/Conv_toolbar_close.png" preload="false" /> + <texture name="Conv_toolbar_collapse" file_name="icons/Conv_toolbar_collapse.png" preload="false" /> + <texture name="Conv_collapse_to_one_line" file_name="icons/collapse_to_one_line.png" preload="false" /> + <texture name="Conv_expand_one_line" file_name="icons/expand_one_liner.png" preload="false" /> + <texture name="Conv_toolbar_expand" file_name="icons/Conv_toolbar_expand.png" preload="false" /> + <texture name="Conv_toolbar_hang_up" file_name="icons/Conv_toolbar_hang_up.png" preload="false" /> + <texture name="Conv_toolbar_open_call" file_name="icons/Conv_toolbar_open_call.png" preload="false" /> + <texture name="Conv_toolbar_plus" file_name="icons/Conv_toolbar_plus.png" preload="false" /> + <texture name="Conv_toolbar_sort" file_name="icons/Conv_toolbar_sort.png" preload="false" /> + <texture name="Conv_log_inbox" file_name="icons/Conv_log_inbox.png" preload="false" /> + + <texture name="Copy" file_name="icons/Copy.png" preload="false" /> + <texture name="CopyBright" file_name="icons/CopyBright.png" preload="false" /> + + <texture name="DisclosureArrow_Opened_Off" file_name="widgets/DisclosureArrow_Opened_Off.png" preload="true" /> + + <texture name="ChatBarHandle" file_name="bottomtray/ChatBarHandle.png" preload="false" /> + <texture name="DownArrow" file_name="bottomtray/DownArrow.png" preload="false" /> + <texture name="DownArrow_Off" file_name="icons/DownArrow_Off.png" preload="false" /> + <texture name="Dragbar" file_name="windows/Dragbar.png" preload="false" scale.left="35" scale.top="5" scale.right="29" scale.bottom="5" /> + + <texture name="DropDown_Disabled" file_name="widgets/DropDown_Disabled.png" preload="true" scale.left="4" scale.top="19" scale.right="99" scale.bottom="4" /> + <texture name="DropDown_Press" file_name="widgets/DropDown_Press.png" preload="true" scale.left="4" scale.top="19" scale.right="99" scale.bottom="4" /> + <texture name="DropDown_On" file_name="widgets/DropDown_On.png" preload="true" scale.left="4" scale.top="19" scale.right="99" scale.bottom="4" /> + <texture name="DropDown_Off" file_name="widgets/DropDown_Off.png" preload="true" scale.left="4" scale.top="19" scale.right="99" scale.bottom="4" /> + + <texture name="DropTarget" file_name="widgets/DropTarget.png" preload="false" /> + + <texture name="Emoji_Picker_Icon" file_name="icons/emoji_picker_icon.png" preload="true" /> + <texture name="ExternalBrowser_Off" file_name="icons/ExternalBrowser_Off.png" preload="false" /> + <texture name="Edit_Wrench" file_name="icons/Edit_Wrench.png" preload="false" /> + + <texture name="Presets_Icon" file_name="icons/Presets_Icon.png" preload="true" /> + + <texture name="Presets_Icon" file_name="icons/Presets_Icon.png" preload="true" /> + <texture name="Presets_Icon_Graphic" file_name="icons/Presets_Icon_Graphic.png" preload="true" /> + <texture name="Favorite_Star_Active" file_name="navbar/Favorite_Star_Active.png" preload="false" /> + <texture name="Favorite_Star_Off" file_name="navbar/Favorite_Star_Off.png" preload="false" /> + <texture name="Favorite_Star_Press" file_name="navbar/Favorite_Star_Press.png" preload="false" /> + <texture name="Favorite_Star_Over" file_name="navbar/Favorite_Star_Over.png" preload="false" /> + <texture name="Favorite_Link_Over" file_name="navbar/Favorite_Link_Over.png" preload="false" /> + + + <texture name="Flag" file_name="navbar/Flag.png" preload="false" /> + + <texture name="Flyout_Left" file_name="windows/Flyout_Left.png" preload="false" /> + <texture name="Flyout_Pointer" file_name="windows/Flyout_Pointer.png" preload="false" /> + <texture name="Flyout_Right" file_name="windows/Flyout_Right.png" preload="false" /> + + <texture name="Folder_Arrow" file_name="folder_arrow.tga" preload="false" /> + <texture name="ForSale_Badge" file_name="icons/ForSale_Badge.png" preload="false" /> + <texture name="ForwardArrow_Off" file_name="icons/ForwardArrow_Off.png" preload="false" /> + <texture name="ForwardArrow_Press" file_name="icons/ForwardArrow_Press.png" preload="false" /> + + <texture name="Generic_Experience" file_name="Blank.png" preload="false" /> + <texture name="Generic_Group" file_name="icons/Generic_Group.png" preload="false" /> + <texture name="Generic_Group_Large" file_name="icons/Generic_Group_Large.png" preload="false" /> + <texture name="icon_group.tga" file_name="icons/Generic_Group.png" preload="false" /> + <texture name="Generic_Object_Small" file_name="icons/Generic_Object_Small.png" preload="false" /> + <texture name="Generic_Person" file_name="icons/Generic_Person.png" preload="false" /> + <texture name="Generic_Person_Large" file_name="icons/Generic_Person_Large.png" preload="false" /> + + <texture name="Group_Notices" file_name="icons/Group_Notices.png" preload="false" /> + + <texture name="Hand" file_name="icons/hand.png" preload="false" /> + + <texture name="Help_Press" file_name="navbar/Help_Press.png" preload="false" /> + + <texture name="Hierarchy_View_Disabled" file_name="icons/Hierarchy_View_Disabled.png" preload="false" /> + <texture name="Hierarchy_View_On" file_name="icons/Hierarchy_View_On.png" preload="false" /> + + + <texture name="Home_Off" file_name="navbar/Home_Off.png" preload="false" /> + <texture name="Horizontal Drag Handle" file_name="widgets/horizontal_drag_handle.png" scale.left="8" scale.right="120" scale.bottom="1" scale.top="6" scale_type="scale_outer"/> + + <texture name="Icon_Close_Foreground" file_name="windows/Icon_Close_Foreground.png" preload="true" /> + <texture name="Icon_Close_Press" file_name="windows/Icon_Close_Press.png" preload="true" /> + <texture name="Icon_Close_Toast" file_name="windows/Icon_Close_Toast.png" preload="true" /> + + <texture name="Icon_Copy" file_name="icons/copy_clipboard.png" preload="true" /> + + <texture name="Icon_Delete" file_name="icons/delete_icon.png" preload="true" /> + + <texture name="Icon_Dock_Foreground" file_name="windows/Icon_Dock_Foreground.png" preload="true" /> + <texture name="Icon_Dock_Press" file_name="windows/Icon_Dock_Press.png" preload="true" /> + + <texture name="Icon_File_Upload" file_name="icons/file_upload.png" preload="true" /> + + <texture name="Icon_For_Sale" file_name="icons/Icon_For_Sale.png" preload="false" /> + + <texture name="Icon_Gear_Background" file_name="windows/Icon_Gear_Background.png" preload="false" /> + <texture name="Icon_Gear_Foreground" file_name="windows/Icon_Gear_Foreground.png" preload="false" /> + <texture name="Icon_Gear_Press" file_name="windows/Icon_Gear_Press.png" preload="false" /> + <texture name="Icon_Gear" file_name="windows/Icon_Gear.png" preload="false" /> + + <texture name="Icon_Help_Foreground" file_name="windows/Icon_Help_Foreground.png" preload="true" /> + <texture name="Icon_Help_Press" file_name="windows/Icon_Help_Press.png" preload="true" /> + + <texture name="Icon_Minimize_Foreground" file_name="windows/Icon_Minimize_Foreground.png" preload="true" /> + <texture name="Icon_Minimize_Press" file_name="windows/Icon_Minimize_Press.png" preload="true" /> + + <texture name="Icon_Paste" file_name="icons/paste_clipboard.png" preload="true" /> + + <texture name="Icon_Restore_Foreground" file_name="windows/Icon_Restore_Foreground.png" preload="false" /> + <texture name="Icon_Restore_Press" file_name="windows/Icon_Restore_Press.png" preload="false" /> + + <texture name="Icon_Snapshot" file_name="icons/snapshot_icon.png" preload="true" /> + + <texture name="Icon_Use_Texture" file_name="icons/texture_icon.png" preload="true" /> + + <texture name="Info" file_name="icons/Info.png" preload="false" /> + <texture name="Info_Small" file_name="icons/Info_Small.png" preload="false" /> + <texture name="Info_Off" file_name="navbar/Info_Off.png" preload="false" /> + <texture name="Info_Over" file_name="icons/Info_Over.png" preload="false" /> + <texture name="Info_Press" file_name="navbar/Info_Press.png" preload="false" /> + + <texture name="Inspector_Background" file_name="windows/Inspector_Background.png" preload="false" + scale.left="4" scale.top="28" scale.right="60" scale.bottom="4" /> + <texture name="Inspector_Hover" file_name="windows/Inspector_Hover.png" preload="false" /> + <texture name="Inspector_I" file_name="windows/Inspector_I.png" preload="false" /> + + <texture name="Inv_Alpha" file_name="icons/Inv_Alpha.png" preload="false" /> + <texture name="Inv_Animation" file_name="icons/Inv_Animation.png" preload="false" /> + <texture name="Inv_BodyShape" file_name="icons/Inv_BodyShape.png" preload="false" /> + <texture name="Inv_CallingCard" file_name="icons/Inv_CallingCard.png" preload="false" /> + <texture name="Inv_Clothing" file_name="icons/Inv_Clothing.png" preload="false" /> + <texture name="Inv_Eye" file_name="icons/Inv_Eye.png" preload="false" /> + <texture name="Inv_FolderClosed" file_name="icons/Inv_FolderClosed.png" preload="false" /> + <texture name="Inv_FolderOpen" file_name="icons/Inv_FolderOpen.png" preload="false" /> + <texture name="Inv_Gesture" file_name="icons/Inv_Gesture.png" preload="false" /> + <texture name="Inv_Gloves" file_name="icons/Inv_Gloves.png" preload="false" /> + <texture name="Inv_Hair" file_name="icons/Inv_Hair.png" preload="false" /> + <texture name="Inv_LinkItem" file_name="icons/Inv_LinkItem.png" preload="false" /> + <texture name="Inv_LinkFolder" file_name="icons/Inv_LinkFolder.png" preload="false" /> + <texture name="Inv_Jacket" file_name="icons/Inv_Jacket.png" preload="false" /> + <texture name="Inv_LookFolderOpen" file_name="icons/Inv_LookFolderOpen.png" preload="false" /> + <texture name="Inv_LookFolderClosed" file_name="icons/Inv_LookFolderClosed.png" preload="false" /> + <texture name="Inv_LostClosed" file_name="icons/Inv_LostClosed.png" preload="false" /> + <texture name="Inv_LostOpen" file_name="icons/Inv_LostOpen.png" preload="false" /> + <texture name="Inv_Landmark" file_name="icons/Inv_Landmark.png" preload="false" /> + <texture name="Inv_Material" file_name="icons/Inv_Material.png" preload="false" /> + <texture name="Inv_Mesh" file_name="icons/Inv_Mesh.png" preload="false" /> + <texture name="Inv_Notecard" file_name="icons/Inv_Notecard.png" preload="false" /> + <texture name="Inv_Object" file_name="icons/Inv_Object.png" preload="false" /> + <texture name="Inv_Object_Multi" file_name="icons/Inv_Object_Multi.png" preload="false" /> + <texture name="Inv_Pants" file_name="icons/Inv_Pants.png" preload="false" /> + <texture name="Inv_Script" file_name="icons/Inv_Script.png" preload="false" /> + <texture name="Inv_Shirt" file_name="icons/Inv_Shirt.png" preload="false" /> + <texture name="Inv_Shoe" file_name="icons/Inv_Shoe.png" preload="false" /> + <texture name="Inv_Skin" file_name="icons/Inv_Skin.png" preload="false" /> + <texture name="Inv_Skirt" file_name="icons/Inv_Skirt.png" preload="false" /> + <texture name="Inv_Snapshot" file_name="icons/Inv_Snapshot.png" preload="false" /> + <texture name="Inv_Socks" file_name="icons/Inv_Socks.png" preload="false" /> + <texture name="Inv_Sound" file_name="icons/Inv_Sound.png" preload="false" /> + <texture name="Inv_StockFolderClosed" file_name="icons/Inv_StockFolderClosed.png" preload="false" /> + <texture name="Inv_StockFolderOpen" file_name="icons/Inv_StockFolderOpen.png" preload="false" /> + <texture name="Inv_SysClosed" file_name="icons/Inv_SysClosed.png" preload="false" /> + <texture name="Inv_SysOpen" file_name="icons/Inv_SysOpen.png" preload="false" /> + <texture name="Inv_Tattoo" file_name="icons/Inv_Tattoo.png" preload="false" /> + <texture name="Inv_Universal" file_name="icons/Inv_Universal.png" preload="false" /> + <texture name="Inv_Physics" file_name="icons/Inv_Physics.png" preload="false" /> + <texture name="Inv_Texture" file_name="icons/Inv_Texture.png" preload="false" /> + <texture name="Inv_TrashClosed" file_name="icons/Inv_TrashClosed.png" preload="false" /> + <texture name="Inv_TrashOpen" file_name="icons/Inv_TrashOpen.png" preload="false" /> + <texture name="Inv_Underpants" file_name="icons/Inv_Underpants.png" preload="false" /> + <texture name="Inv_Undershirt" file_name="icons/Inv_Undershirt.png" preload="false" /> + <texture name="Inv_Link" file_name="icons/Inv_Link.png" preload="false" /> + <texture name="Inv_Settings" file_name="icons/Inv_Settings.png" preload="false" /> + <texture name="Inv_SettingsSky" file_name="icons/Inv_SettingsSky.png" preload="false" /> + <texture name="Inv_SettingsWater" file_name="icons/Inv_SettingsWater.png" preload="false" /> + <texture name="Inv_SettingsDay" file_name="icons/Inv_SettingsDay.png" preload="false" /> + + <texture name="Inv_Invalid" file_name="icons/Inv_Invalid.png" preload="false" /> + <texture name="Inv_Unknown" file_name="icons/Inv_UnknownObject.png" preload="false" /> + <texture name="Inv_VersionFolderClosed" file_name="icons/Inv_VersionFolderClosed.png" preload="false" /> + <texture name="Inv_VersionFolderOpen" file_name="icons/Inv_VersionFolderOpen.png" preload="false" /> + + <texture name="Inv_Toolbar_SearchVisibility" file_name="icons/Inv_Toolbar_SearchVisibility.png" preload="false" /> + + <texture name="Landmarks_overlay" file_name="navbar/Landmarks.png" preload="false" /> + + <texture name="Linden_Dollar_Alert" file_name="widgets/Linden_Dollar_Alert.png"/> + <texture name="Linden_Dollar_Background" file_name="widgets/Linden_Dollar_Background.png"/> + + <texture name="ListItem_Select" file_name="widgets/ListItem_Select.png" preload="true" scale.left="2" scale.bottom="2" scale.top="22" scale.right="278" /> + <texture name="ListItem_Over" file_name="widgets/ListItem_Over.png" preload="true" scale.left="2" scale.bottom="2" scale.top="22" scale.right="278" /> + + <texture name="List_View_Disabled" file_name="icons/List_View_Disabled.png" preload="false" /> + <texture name="List_View_On" file_name="icons/List_View_On.png" preload="false" /> + + <texture name="Lock" file_name="icons/Lock.png" preload="false" /> + <texture name="Lock2" file_name="navbar/Lock.png" preload="false" /> + + <texture name="Locked_Icon" file_name="icons/Locked_Icon.png" preload="false" /> + + <texture name="Map_Placeholder_Icon" file_name="icons/map_placeholder.png" preload="true" /> + + <texture name="Marketplace_Dropzone_Background" file_name="widgets/Marketplace_Dropzone_Background.png" preload="true" /> + <texture name="MarketplaceBtn_Off" file_name="widgets/MarketplaceBtn_Off.png" preload="true" scale.left="30" scale.top="19" scale.right="35" scale.bottom="4" /> + <texture name="MarketplaceBtn_Selected" file_name="widgets/MarketplaceBtn_Selected.png" preload="true" scale.left="30" scale.top="19" scale.right="35" scale.bottom="4" /> + + <texture name="Microphone_On" file_name="icons/Microphone_On.png" preload="false" /> + + <texture name="MinusItem_Disabled" file_name="icons/MinusItem_Disabled.png" preload="false" /> + <texture name="MinusItem_Off" file_name="icons/MinusItem_Off.png" preload="false" /> + <texture name="MinusItem_Press" file_name="icons/MinusItem_Press.png" preload="false" /> + + <texture name="menu_separator" file_name="navbar/FileMenu_Divider.png" scale.left="4" scale.top="166" scale.right="0" scale.bottom="0" /> + + <texture name="ModelImport_Status_Good" file_name="green_checkmark.png" preload="false"/> + <texture name="ModelImport_Status_Warning" file_name="lag_status_warning.tga" preload="false"/> + <texture name="ModelImport_Status_Error" file_name="red_x.png" preload="false"/> + + <texture name="MouseLook_View_Off" file_name="bottomtray/Mouselook_View_Off.png" preload="false" /> + <texture name="MouseLook_View_On" file_name="bottomtray/Mouselook_View_On.png" preload="false" /> + + <texture name="Move_Fly_Off" file_name="bottomtray/Move_Fly_Off.png" preload="false" /> + <texture name="Move_Run_Off" file_name="bottomtray/Move_Run_Off.png" preload="false" /> + <texture name="Move_Walk_Off" file_name="bottomtray/Move_Walk_Off.png" preload="false" /> + <texture name="Movement_Backward_Off" file_name="bottomtray/Movement_Backward_Off.png" preload="false" /> + <texture name="Movement_Backward_On" file_name="bottomtray/Movement_Backward_On.png" preload="false" /> + <texture name="Movement_Down_Off" file_name="bottomtray/Movement_Down_Off.png" preload="false" /> + <texture name="Movement_Down_On" file_name="bottomtray/Movement_Down_On.png" preload="false" /> + <texture name="Movement_Forward_Off" file_name="bottomtray/Movement_Forward_Off.png" preload="false" /> + <texture name="Movement_Forward_On" file_name="bottomtray/Movement_Forward_On.png" preload="false" /> + <texture name="Movement_Left_Off" file_name="bottomtray/Movement_Left_Off.png" preload="false" /> + <texture name="Movement_Left_On" file_name="bottomtray/Movement_Left_On.png" preload="false" /> + <texture name="Movement_Right_Off" file_name="bottomtray/Movement_Right_Off.png" preload="false" /> + <texture name="Movement_Right_On" file_name="bottomtray/Movement_Right_On.png" preload="false" /> + <texture name="Movement_TurnLeft_Off" file_name="bottomtray/Movement_TurnLeft_Off.png" preload="false" /> + <texture name="Movement_TurnLeft_On" file_name="bottomtray/Movement_TurnLeft_On.png" preload="false" /> + <texture name="Movement_TurnRight_Off" file_name="bottomtray/Movement_TurnRight_Off.png" preload="false" /> + <texture name="Movement_TurnRight_On" file_name="bottomtray/Movement_TurnRight_On.png" preload="false" /> + <texture name="Movement_Up_Off" file_name="bottomtray/Movement_Up_Off.png" preload="false" /> + <texture name="Movement_Up_On" file_name="bottomtray/Movement_Up_On.png" preload="false" /> + + <texture name="NavBar_BG" file_name="navbar/NavBar_BG.png" preload="true" scale.left="1" scale.top="1" scale.right="0" scale.bottom="0" /> + <texture name="NavBar_BG_NoFav_Bevel" file_name="navbar/NavBar_BG_NoFav_Bevel.png" preload="true" scale.left="1" scale.top="1" scale.right="0" scale.bottom="0" /> + <texture name="NavBar_BG_NoNav_Bevel" file_name="navbar/NavBar_BG_NoNav_Bevel.png" preload="true" scale.left="1" scale.top="1" scale.right="0" scale.bottom="0" /> + + <texture name="Nearby_chat_icon" file_name="icons/nearby_chat_icon.png" preload="false" /> + + <texture name="Notices_Unread" file_name="bottomtray/Notices_Unread.png" preload="true" /> + + <texture name="NoEntryLines" file_name="world/NoEntryLines.png" use_mips="true" preload="false" /> + <texture name="NoEntryPassLines" file_name="world/NoEntryPassLines.png" use_mips="true" preload="false" /> + + <texture name="Object_Cone" file_name="build/Object_Cone.png" preload="false" /> + <texture name="Object_Cone_Selected" file_name="build/Object_Cone_Selected.png" preload="false" /> + <texture name="Object_Cube" file_name="build/Object_Cube.png" preload="false" /> + <texture name="Object_Cube_Selected" file_name="build/Object_Cube_Selected.png" preload="false" /> + <texture name="Object_Cylinder" file_name="build/Object_Cylinder.png" preload="false" /> + <texture name="Object_Cylinder_Selected" file_name="build/Object_Cylinder_Selected.png" preload="false" /> + <texture name="Object_Grass" file_name="build/Object_Grass.png" preload="false" /> + <texture name="Object_Grass_Selected" file_name="build/Object_Grass_Selected.png" preload="false" /> + <texture name="Object_Hemi_Cone" file_name="build/Object_Hemi_Cone.png" preload="false" /> + <texture name="Object_Hemi_Cone_Selected" file_name="build/Object_Hemi_Cone_Selected.png" preload="false" /> + <texture name="Object_Hemi_Cylinder" file_name="build/Object_Hemi_Cylinder.png" preload="false" /> + <texture name="Object_Hemi_Cylinder_Selected" file_name="build/Object_Hemi_Cylinder_Selected.png" preload="false" /> + <texture name="Object_Hemi_Sphere" file_name="build/Object_Hemi_Sphere.png" preload="false" /> + <texture name="Object_Hemi_Sphere_Selected" file_name="build/Object_Hemi_Sphere_Selected.png" preload="false" /> + <texture name="Object_Prism" file_name="build/Object_Prism.png" preload="false" /> + <texture name="Object_Prism_Selected" file_name="build/Object_Prism_Selected.png" preload="false" /> + <texture name="Object_Pyramid" file_name="build/Object_Pyramid.png" preload="false" /> + <texture name="Object_Pyramid_Selected" file_name="build/Object_Pyramid_Selected.png" preload="false" /> + <texture name="Object_Ring" file_name="build/Object_Ring.png" preload="false" /> + <texture name="Object_Ring_Selected" file_name="build/Object_Ring_Selected.png" preload="false" /> + <texture name="Object_Sphere" file_name="build/Object_Sphere.png" preload="false" /> + <texture name="Object_Sphere_Selected" file_name="build/Object_Sphere_Selected.png" preload="false" /> + <texture name="Object_Tetrahedron" file_name="build/Object_Tetrahedron.png" preload="false" /> + <texture name="Object_Tetrahedron_Selected" file_name="build/Object_Tetrahedron_Selected.png" preload="false" /> + <texture name="Object_Torus" file_name="build/Object_Torus.png" preload="false" /> + <texture name="Object_Torus_Selected" file_name="build/Object_Torus_Selected.png" preload="false" /> + <texture name="Object_Tree" file_name="build/Object_Tree.png" preload="false" /> + <texture name="Object_Tree_Selected" file_name="build/Object_Tree_Selected.png" preload="false" /> + <texture name="Object_Tube" file_name="build/Object_Tube.png" preload="false" /> + <texture name="Object_Tube_Selected" file_name="build/Object_Tube_Selected.png" preload="false" /> + + <texture name="Object_View_Off" file_name="bottomtray/Object_View_Off.png" preload="false" /> + <texture name="Object_View_On" file_name="bottomtray/Object_View_On.png" preload="false" /> + + <texture name="OptionsMenu_Disabled" file_name="icons/OptionsMenu_Disabled.png" preload="false" /> + <texture name="OptionsMenu_Off" file_name="icons/OptionsMenu_Off.png" preload="false" /> + <texture name="OptionsMenu_Press" file_name="icons/OptionsMenu_Press.png" preload="false" /> + + <texture name="ClipboardSmallMenu_Disabled" file_name="icons/ClipboardSmallMenu_Disabled.png" preload="false" /> + <texture name="ClipboardSmallMenu_Off" file_name="icons/ClipboardSmallMenu_Off.png" preload="false" /> + <texture name="ClipboardSmallMenu_Press" file_name="icons/ClipboardSmallMenu_Press.png" preload="false" /> + <texture name="ClipboardMenu_Disabled" file_name="icons/ClipboardMenu_Disabled.png" preload="false" /> + <texture name="ClipboardMenu_Off" file_name="icons/ClipboardMenu_Off.png" preload="false" /> + <texture name="ClipboardMenu_Press" file_name="icons/ClipboardMenu_Press.png" preload="false" /> + + <texture name="OutboxStatus_Success" file_name="green_checkmark.png" preload="false" /> + <texture name="OutboxStatus_Warning" file_name="icons/pop_up_caution.png" preload="false" /> + <texture name="OutboxStatus_Error" file_name="red_x.png" preload="false" /> + + <texture name="PanOrbit_Off" file_name="bottomtray/PanOrbit_Off.png" preload="false" /> + + <texture name="Parcel_Exp_Color" file_name="icons/Parcel_Exp_Color.png" preload="false" /> + + <texture name="Parcel_Build_Dark" file_name="icons/Parcel_Build_Dark.png" preload="false" /> + <texture name="Parcel_BuildNo_Dark" file_name="icons/Parcel_BuildNo_Dark.png" preload="false" /> + <texture name="Parcel_Damage_Dark" file_name="icons/Parcel_Damage_Dark.png" preload="false" /> + <texture name="Parcel_DamageNo_Dark" file_name="icons/Parcel_DamageNo_Dark.png" preload="false" /> + <texture name="Parcel_Fly_Dark" file_name="icons/Parcel_Fly_Dark.png" preload="false" /> + <texture name="Parcel_FlyNo_Dark" file_name="icons/Parcel_FlyNo_Dark.png" preload="false" /> + <texture name="Parcel_Health_Dark" file_name="icons/Parcel_Health_Dark.png" preload="false" /> + <texture name="Parcel_M_Dark" file_name="icons/Parcel_M_Dark.png" preload="false" /> + <texture name="Parcel_PG_Dark" file_name="icons/Parcel_PG_Dark.png" preload="false" /> + <texture name="Parcel_Push_Dark" file_name="icons/Parcel_Push_Dark.png" preload="false" /> + <texture name="Parcel_PushNo_Dark" file_name="icons/Parcel_PushNo_Dark.png" preload="false" /> + <texture name="Parcel_R_Dark" file_name="icons/Parcel_R_Dark.png" preload="false" /> + <texture name="Parcel_Scripts_Dark" file_name="icons/Parcel_Scripts_Dark.png" preload="false" /> + <texture name="Parcel_ScriptsNo_Dark" file_name="icons/Parcel_ScriptsNo_Dark.png" preload="false" /> + <texture name="Parcel_Voice_Dark" file_name="icons/Parcel_Voice_Dark.png" preload="false" /> + <texture name="Parcel_VoiceNo_Dark" file_name="icons/Parcel_VoiceNo_Dark.png" preload="false" /> + <texture name="Parcel_SeeAVsOff_Dark" file_name="icons/Parcel_SeeAVsOff_Dark.png" preload="false" /> + <texture name="Parcel_SeeAVsOn_Dark" file_name="icons/Parcel_SeeAVsOn_Dark.png" preload="false" /> + <texture name="Parcel_SeeAVsOff_Light" file_name="icons/Parcel_SeeAVsOff_Light.png" preload="false" /> + <texture name="Parcel_SeeAVsOn_Light" file_name="icons/Parcel_SeeAVsOn_Light.png" preload="false" /> + + <texture name="Parcel_BuildNo_Light" file_name="icons/Parcel_BuildNo_Light.png" preload="false" /> + <texture name="Parcel_FlyNo_Light" file_name="icons/Parcel_FlyNo_Light.png" preload="false" /> + <texture name="Parcel_ForSale_Light" file_name="icons/Parcel_ForSale_Light.png" preload="false" /> + <texture name="Parcel_M_Light" file_name="icons/Parcel_M_Light.png" preload="false" /> + <texture name="Parcel_PG_Light" file_name="icons/Parcel_PG_Light.png" preload="false" /> + <texture name="Parcel_PushNo_Light" file_name="icons/Parcel_PushNo_Light.png" preload="false" /> + <texture name="Parcel_R_Light" file_name="icons/Parcel_R_Light.png" preload="false" /> + <texture name="Parcel_ScriptsNo_Light" file_name="icons/Parcel_ScriptsNo_Dark.png" preload="false" /> + <texture name="Parcel_Voice_Light" file_name="icons/Parcel_Voice_Light.png" preload="false" /> + <texture name="Parcel_VoiceNo_Light" file_name="icons/Parcel_VoiceNo_Light.png" preload="false" /> + + <texture name="Pathfinding_Dirty" file_name="icons/Pathfinding_Dirty.png" preload="false" /> + <texture name="Pathfinding_Disabled" file_name="icons/Pathfinding_Disabled.png" preload="false" /> + + <texture name="Pause_Off" file_name="icons/Pause_Off.png" preload="false" /> + <texture name="Pause_Over" file_name="icons/Pause_Over.png" preload="false" /> + <texture name="Pause_Press" file_name="icons/Pause_Press.png" preload="false" /> + <texture name="Person_Check" file_name="icons/Person_Check.png" preload="false" /> + <texture name="Person_Star" file_name="icons/Person_Star.png" preload="false" /> + + <texture name="Permission_Visible_Online" file_name="icons/see_me_online.png" preload="false" /> + <texture name="Permission_Visible_Map" file_name="icons/see_on_map.png" preload="false" /> + <texture name="Permission_Edit_Objects_Mine" file_name="icons/edit_mine.png" preload="false" /> + <texture name="Permission_Edit_Objects_Theirs" file_name="icons/edit_theirs.png" preload="false" /> + + <texture name="Play_Off" file_name="icons/Play_Off.png" preload="false" /> + <texture name="Play_Over" file_name="icons/Play_Over.png" preload="false" /> + <texture name="Play_Press" file_name="icons/Play_Press.png" preload="false" /> + + <texture name="Profile_Badge_Beta" file_name="icons/profile_badge_beta.png" preload="true"/> + <texture name="Profile_Badge_Beta_Lifetime" file_name="icons/profile_badge_beta_lifetime.png" preload="true"/> + <texture name="Profile_Badge_Lifetime" file_name="icons/profile_badge_lifetime.png" preload="true"/> + <texture name="Profile_Badge_Linden" file_name="icons/profile_badge_linden.png" preload="true"/> + <texture name="Profile_Badge_Pplus_Lifetime" file_name="icons/profile_badge_pplus_lifetime.png" preload="true"/> + <texture name="Profile_Badge_Premium_Lifetime" file_name="icons/profile_badge_premium_lifetime.png" preload="true"/> + <texture name="Profile_Group_Visibility_Off" file_name="icons/profile_group_visibility_eye_off.png" preload="true"/> + <texture name="Profile_Group_Visibility_Off_Pressed" file_name="icons/profile_group_visibility_eye_off_pressed.png" preload="true"/> + <texture name="Profile_Group_Visibility_On" file_name="icons/profile_group_visibility_eye_on.png" preload="true"/> + <texture name="Profile_Group_Visibility_On_Pressed" file_name="icons/profile_group_visibility_eye_on_pressed.png" preload="true"/> + <texture name="Profile_Friend_Offline" file_name="icons/Profile_Friend_Offline.png" preload="true"/> + <texture name="Profile_Friend_Online" file_name="icons/Profile_Friend_Online.png" preload="true"/> + <texture name="Profile_Perm_Find_Disabled" file_name="icons/Profile_Perm_Find_Disabled.png" preload="true"/> + <texture name="Profile_Perm_Find_Enabled" file_name="icons/Profile_Perm_Find_Enabled.png" preload="true"/> + <texture name="Profile_Perm_Objects_Disabled" file_name="icons/Profile_Perm_Objects_Disabled.png" preload="true"/> + <texture name="Profile_Perm_Objects_Enabled" file_name="icons/Profile_Perm_Objects_Enabled.png" preload="true"/> + <texture name="Profile_Perm_Online_Disabled" file_name="icons/Profile_Perm_Online_Disabled.png" preload="true"/> + <texture name="Profile_Perm_Online_Enabled" file_name="icons/Profile_Perm_Online_Enabled.png" preload="true"/> + + <texture name="ProgressBar" file_name="widgets/ProgressBar.png" preload="true" scale.left="4" scale.top="11" scale.right="48" scale.bottom="3" /> + <texture name="ProgressBarSolid" file_name="widgets/ProgressBarSolid.png" preload="true" scale.left="4" scale.top="11" scale.right="48" scale.bottom="3" /> + <texture name="ProgressTrack" file_name="widgets/ProgressTrack.png" preload="true" scale.left="4" scale.top="13" scale.right="148" scale.bottom="2" /> + + <texture name="PushButton_Disabled" file_name="widgets/PushButton_Disabled.png" preload="true" scale.left="4" scale.top="19" scale.right="28" scale.bottom="4" /> + <texture name="PushButton_Off" file_name="widgets/PushButton_Off.png" preload="true" scale.left="4" scale.top="19" scale.right="28" scale.bottom="4" /> + <texture name="PushButton_On" file_name="widgets/PushButton_On.png" preload="true" scale.left="4" scale.top="19" scale.right="28" scale.bottom="4" /> + <texture name="PushButton_On_Selected" file_name="widgets/PushButton_On_Selected.png" preload="true" scale.left="4" scale.top="19" scale.right="28" scale.bottom="4" /> + <texture name="PushButton_Over" file_name="widgets/PushButton_Over.png" preload="true" scale.left="4" scale.top="19" scale.right="28" scale.bottom="4" /> + <texture name="PushButton_Press" file_name="widgets/PushButton_Press.png" preload="true" scale.left="4" scale.top="19" scale.right="28" scale.bottom="4" /> + <texture name="PushButton_Selected" file_name="widgets/PushButton_Selected.png" preload="true" scale.left="4" scale.top="19" scale.right="28" scale.bottom="4" /> + <texture name="PushButton_Selected_Press" file_name="widgets/PushButton_Selected_Press.png" preload="true" scale.left="4" scale.top="19" scale.right="28" scale.bottom="4" /> + <texture name="PushButton_Selected_Disabled" file_name="widgets/PushButton_Selected_Disabled.png" preload="true" scale.left="4" scale.top="19" scale.right="28" scale.bottom="4" /> + + <texture name="PushButton_Login" file_name="widgets/PushButton_Login.png" preload="true" scale.left="4" scale.top="19" scale.right="28" scale.bottom="4" /> + <texture name="PushButton_Login_Over" file_name="widgets/PushButton_Login_Over.png" preload="true" scale.left="4" scale.top="19" scale.right="28" scale.bottom="4" /> + <texture name="PushButton_Login_Pressed" file_name="widgets/PushButton_Login_Pressed.png" preload="true" scale.left="4" scale.top="19" scale.right="28" scale.bottom="4" /> + + + <texture name="RadioButton_Press" file_name="widgets/RadioButton_Press.png" preload="true" /> + <texture name="RadioButton_On_Press" file_name="widgets/RadioButton_On_Press.png" preload="true" /> + <texture name="RadioButton_Off" file_name="widgets/RadioButton_Off.png" preload="true" /> + <texture name="RadioButton_On" file_name="widgets/RadioButton_On.png" preload="true" /> + <texture name="RadioButton_Disabled" file_name="widgets/RadioButton_Disabled.png" preload="true" /> + <texture name="RadioButton_On_Disabled" file_name="widgets/RadioButton_On_Disabled.png" preload="true" /> + + + <texture name="Refresh_Off" file_name="icons/Refresh_Off.png" preload="true" /> + + <texture name="Resize_Corner" file_name="windows/Resize_Corner.png" preload="true" /> + + <texture name="Rounded_Rect" file_name="Rounded_Rect.png" preload="true" scale.left="6" scale.top="26" scale.right="58" scale.bottom="6" /> + <texture name="Rounded_Rect_Top" file_name="Rounded_Rect.png" preload="true" scale.left="6" scale.top="8" scale.right="58" scale.bottom="0" clip.left="0" clip.right="64" clip.bottom="16" clip.top="32" /> + <texture name="Rounded_Rect_Bottom" file_name="Rounded_Rect.png" preload="true" scale.left="6" scale.top="16" scale.right="58" scale.bottom="8" clip.left="0" clip.right="64" clip.bottom="0" clip.top="16" /> + <texture name="Rounded_Rect_Left" file_name="Rounded_Rect.png" preload="true" scale.left="6" scale.top="26" scale.right="32" scale.bottom="6" clip.left="0" clip.right="32" clip.bottom="0" clip.top="32" /> + <texture name="Rounded_Rect_Right" file_name="Rounded_Rect.png" preload="true" scale.left="0" scale.top="26" scale.right="26" scale.bottom="6" clip.left="32" clip.right="64" clip.bottom="0" clip.top="32" /> + <texture name="Rounded_Square" file_name="rounded_square.j2c" preload="true" scale.left="16" scale.top="16" scale.right="112" scale.bottom="16" /> + <texture name="Row_Selection" file_name="navbar/Row_Selection.png" preload="false" /> + + <texture name="ScrollArrow_Down" file_name="widgets/ScrollArrow_Down.png" preload="true" scale.left="2" scale.top="13" scale.right="13" scale.bottom="2" /> + <texture name="ScrollArrow_Left" file_name="widgets/ScrollArrow_Left.png" preload="true" scale.left="2" scale.top="13" scale.right="13" scale.bottom="2" /> + <texture name="ScrollArrow_Right" file_name="widgets/ScrollArrow_Right.png" preload="true" scale.left="2" scale.top="13" scale.right="13" scale.bottom="2" /> + <texture name="ScrollArrow_Up" file_name="widgets/ScrollArrow_Up.png" preload="true" scale.left="2" scale.top="13" scale.right="13" scale.bottom="2" /> + + <texture name="ScrollThumb_Horiz" file_name="widgets/ScrollThumb_Horiz.png" preload="true" scale.left="4" scale.top="0" scale.bottom="0" scale.right="2" /> + <texture name="ScrollThumb_Vert" file_name="widgets/ScrollThumb_Vert.png" preload="true" scale.left="4" scale.top="53" scale.bottom="10" scale.right="4" /> + <texture name="ScrollTrack_Vert" file_name="widgets/ScrollTrack_Vert.png" preload="true" scale.left="2" scale.top="40" scale.bottom="13" scale.right="0" /> + <texture name="ScrollTrack_Horiz" file_name="widgets/ScrollTrack_Horiz.png" preload="true" scale.left="4" scale.top="0" scale.bottom="0" scale.right="2" /> + + + <texture name="Search" file_name="navbar/Search.png" preload="false" /> + + <texture name="Search_Icon" file_name="icons/Search_Icon.png" preload="false" /> + + <texture name="SegmentedBtn_Left_Off" file_name="widgets/SegmentedBtn_Left_Off.png" preload="true" scale.left="4" scale.top="19" scale.right="22" scale.bottom="4" /> + <texture name="SegmentedBtn_Left_Over" file_name="widgets/SegmentedBtn_Left_Over.png" preload="true" scale.left="4" scale.top="19" scale.right="22" scale.bottom="4" /> + <texture name="SegmentedBtn_Left_Press" file_name="widgets/SegmentedBtn_Left_Press.png" preload="true" scale.left="4" scale.top="19" scale.right="22" scale.bottom="4" /> + <texture name="SegmentedBtn_Left_Disabled" file_name="widgets/SegmentedBtn_Left_Disabled.png" preload="true" scale.left="4" scale.top="19" scale.right="22" scale.bottom="4" /> + <texture name="SegmentedBtn_Left_Selected" file_name="widgets/SegmentedBtn_Left_Selected.png" preload="true" scale.left="4" scale.top="19" scale.right="22" scale.bottom="4" /> + <texture name="SegmentedBtn_Left_Selected_Over" file_name="widgets/SegmentedBtn_Left_Selected_Over.png" preload="true" scale.left="4" scale.top="19" scale.right="22" scale.bottom="4" /> + <texture name="SegmentedBtn_Left_Selected_Press" file_name="widgets/SegmentedBtn_Left_Selected_Press.png" preload="true" scale.left="4" scale.top="19" scale.right="22" scale.bottom="4" /> + <texture name="SegmentedBtn_Left_Selected_Disabled" file_name="widgets/SegmentedBtn_Left_Selected_Disabled.png" preload="true" scale.left="4" scale.top="19" scale.right="22" scale.bottom="4" /> + + <texture name="SegmentedBtn_Middle_Disabled" file_name="widgets/SegmentedBtn_Middle_Disabled.png" preload="true" scale.left="4" scale.top="19" scale.right="22" scale.bottom="4" /> + <texture name="SegmentedBtn_Middle_Selected" file_name="widgets/SegmentedBtn_Middle_Selected.png" preload="true" scale.left="4" scale.top="19" scale.right="22" scale.bottom="4" /> + <texture name="SegmentedBtn_Middle_Selected_Press" file_name="widgets/SegmentedBtn_Middle_Selected_Press.png" preload="true" scale.left="4" scale.top="19" scale.right="22" scale.bottom="4" /> + <texture name="SegmentedBtn_Middle_Selected_Disabled" file_name="widgets/SegmentedBtn_Middle_Selected_Disabled.png" preload="true" scale.left="4" scale.top="19" scale.right="22" scale.bottom="4" /> + + <texture name="SegmentedBtn_Right_Off" file_name="widgets/SegmentedBtn_Right_Off.png" preload="true" scale.left="4" scale.top="19" scale.right="22" scale.bottom="4" /> + <texture name="SegmentedBtn_Right_Over" file_name="widgets/SegmentedBtn_Right_Over.png" preload="true" scale.left="4" scale.top="19" scale.right="22" scale.bottom="4" /> + <texture name="SegmentedBtn_Right_Press" file_name="widgets/SegmentedBtn_Right_Press.png" preload="true" scale.left="4" scale.top="19" scale.right="22" scale.bottom="4" /> + <texture name="SegmentedBtn_Right_Disabled" file_name="widgets/SegmentedBtn_Right_Disabled.png" preload="true" scale.left="4" scale.top="19" scale.right="22" scale.bottom="4" /> + <texture name="SegmentedBtn_Right_Selected" file_name="widgets/SegmentedBtn_Right_Selected.png" preload="true" scale.left="4" scale.top="19" scale.right="22" scale.bottom="4" /> + <texture name="SegmentedBtn_Right_Selected_Press" file_name="widgets/SegmentedBtn_Right_Selected_Press.png" preload="true" scale.left="4" scale.top="19" scale.right="22" scale.bottom="4" /> + <texture name="SegmentedBtn_Right_Selected_Disabled" file_name="widgets/SegmentedBtn_Right_Selected_Disabled.png" preload="true" scale.left="4" scale.top="19" scale.right="22" scale.bottom="4" /> + + <texture name="Shirt_Large" file_name="icons/Shirt_Large.png" preload="false" /> + + <texture name="Sidebar_Icon_Dock_Foreground" file_name="taskpanel/Sidebar_Icon_Dock_Foreground.png" preload="false" /> + <texture name="Sidebar_Icon_Dock_Press" file_name="taskpanel/Sidebar_Icon_Dock_Press.png" preload="false" /> + <texture name="Sidebar_Icon_Undock_Foreground" file_name="taskpanel/Sidebar_Icon_Undock_Foreground.png" preload="false" /> + <texture name="Sidebar_Icon_Undock_Press" file_name="taskpanel/Sidebar_Icon_Undock_Press.png" preload="false" /> + + <texture name="Shop" file_name="icons/Shop.png" preload="false" /> + + <texture name="SkipBackward_Off" file_name="icons/SkipBackward_Off.png" preload="false" /> + <texture name="SkipForward_Off" file_name="icons/SkipForward_Off.png" preload="false" /> + + <texture name="SliderTrack_Horiz" file_name="widgets/SliderTrack_Horiz.png" scale.left="4" scale.top="4" scale.right="100" scale.bottom="2" /> + <texture name="SliderTrack_Vert" file_name="widgets/SliderTrack_Vert.png" scale.left="2" scale.top="100" scale.right="4" scale.bottom="4" /> + <texture name="SliderThumb_Off" file_name="widgets/SliderThumb_Off.png" /> + <texture name="SliderThumb_Disabled" file_name="widgets/SliderThumb_Disabled.png" /> + <texture name="SliderThumb_Press" file_name="widgets/SliderThumb_Press.png" /> + + <texture name="SL_Logo" file_name="icons/MP_Logo.png" preload="true" /> + <texture name="OBJECT_Icon" file_name="icons/object_icon.png" preload="true" /> + <texture name="Unknown_Icon" file_name="icons/unknown_icon.png" preload="true" /> + + <texture name="Snapshot_Off" file_name="bottomtray/Snapshot_Off.png" preload="true" scale.left="4" scale.top="19" scale.right="22" scale.bottom="4" /> + <texture name="Snapshot_Download" file_name="snapshot_download.png" preload="false" /> + <texture name="Snapshot_Email" file_name="snapshot_email.png" preload="false" /> + <texture name="Snapshot_Inventory" file_name="toolbar_icons/inventory.png" preload="false" /> + <texture name="Snapshot_Profile" file_name="toolbar_icons/profile.png" preload="false" /> + <texture name="startup_logo" file_name="windows/startup_logo.png" preload="true" /> + + <texture name="login_mp_logo" file_name="windows/login_mp_logo.png" preload="true" /> + <texture name="login_mp_logo_small" file_name="windows/login_mp_logo_small.png" preload="true" /> + <texture name="first_login_image" file_name="windows/first_login_image.jpg" preload="true" /> + + <texture name="Stepper_Down_Off" file_name="widgets/Stepper_Down_Off.png" preload="false" /> + <texture name="Stepper_Down_Press" file_name="widgets/Stepper_Down_Press.png" preload="false" /> + <texture name="Stepper_Up_Off" file_name="widgets/Stepper_Up_Off.png" preload="false" /> + <texture name="Stepper_Up_Press" file_name="widgets/Stepper_Up_Press.png" preload="false" /> + + <texture name="Stop_Off" file_name="icons/Stop_Off.png" preload="true" /> + <texture name="StopReload_Off" file_name="icons/StopReload_Off.png" preload="false" /> + <texture name="StopReload_Over" file_name="icons/StopReload_Over.png" preload="false" /> + + <texture name="Sync_Disabled" file_name="icons/Sync_Disabled.png" preload="true" /> + <texture name="Sync_Enabled" file_name="icons/Sync_Enabled.png" preload="true" /> + <texture name="Sync_Progress_1" file_name="icons/Sync_Progress_1.png" preload="true" /> + <texture name="Sync_Progress_2" file_name="icons/Sync_Progress_2.png" preload="true" /> + <texture name="Sync_Progress_3" file_name="icons/Sync_Progress_3.png" preload="true" /> + <texture name="Sync_Progress_4" file_name="icons/Sync_Progress_4.png" preload="true" /> + <texture name="Sync_Progress_5" file_name="icons/Sync_Progress_5.png" preload="true" /> + <texture name="Sync_Progress_6" file_name="icons/Sync_Progress_6.png" preload="true" /> + + <texture name="TabIcon_Close_Off" file_name="taskpanel/TabIcon_Close_Off.png" preload="false" /> + <texture name="TabIcon_Home_Selected" file_name="taskpanel/TabIcon_Home_Selected.png" preload="false" /> + <texture name="TabIcon_Me_Off" file_name="taskpanel/TabIcon_Me_Off.png" preload="false" /> + <texture name="TabIcon_Open_Off" file_name="taskpanel/TabIcon_Open_Off.png" preload="false" /> + <texture name="TabIcon_People_Off" file_name="taskpanel/TabIcon_People_Off.png" preload="false" /> + <texture name="TabIcon_Places_Off" file_name="taskpanel/TabIcon_Places_Off.png" preload="false" /> + <texture name="TabIcon_Things_Off" file_name="taskpanel/TabIcon_Things_Off.png" preload="false" /> + + <texture name="TabTop_Right_Off" file_name="containers/TabTop_Right_Off.png" preload="false" scale.left="8" scale.top="8" scale.right="62" scale.bottom="9" /> + <texture name="TabTop_Right_Selected" file_name="containers/TabTop_Right_Selected.png" preload="false" scale.left="8" scale.top="8" scale.right="62" scale.bottom="9" /> + <texture name="TabTop_Right_Flashing" file_name="containers/TabTop_Right_Flashing.png" preload="false" scale.left="8" scale.top="8" scale.right="62" scale.bottom="9" /> + <texture name="TabTop_Middle_Off" file_name="containers/TabTop_Middle_Off.png" preload="false" scale.left="8" scale.top="8" scale.right="120" scale.bottom="9" /> + <texture name="TabTop_Middle_Selected" file_name="containers/TabTop_Middle_Selected.png" preload="false" scale.left="8" scale.top="8" scale.right="96" scale.bottom="9" /> + <texture name="TabTop_Left_Off" file_name="containers/TabTop_Left_Off.png" preload="false" scale.left="8" scale.top="8" scale.right="120" scale.bottom="9" /> + <texture name="TabTop_Left_Selected" file_name="containers/TabTop_Left_Selected.png" preload="false" scale.left="8" scale.top="8" scale.right="96" scale.bottom="9" /> + + <texture name="TaskPanel_Tab_Off" file_name="taskpanel/TaskPanel_Tab_Off.png" preload="false" scale.left="4" scale.top="29" scale.right="36" scale.bottom="4" /> + <texture name="TaskPanel_Tab_Selected" file_name="taskpanel/TaskPanel_Tab_Selected.png" preload="false" scale.left="5" scale.top="30" scale.right="36" scale.bottom="5" /> + + <texture name="TextField_Search_Disabled" file_name="widgets/TextField_Search_Disabled.png" preload="true" scale.left="9" scale.top="12" scale.right="248" scale.bottom="12" /> + <texture name="TextField_Off" file_name="widgets/TextField_Off.png" preload="true" scale.left="9" scale.top="12" scale.right="248" scale.bottom="12" /> + <texture name="TextField_Search_Active" file_name="widgets/TextField_Search_Active.png" preload="true" scale.left="9" scale.top="12" scale.right="248" scale.bottom="12" /> + <texture name="TextField_Search_Off" file_name="widgets/TextField_Search_Off.png" preload="true" scale.left="9" scale.top="12" scale.right="248" scale.bottom="12" /> + <texture name="TextField_Disabled" file_name="widgets/TextField_Disabled.png" preload="true" scale.left="9" scale.top="12" scale.right="248" scale.bottom="12" /> + <texture name="TextField_Active" file_name="widgets/TextField_Active.png" preload="true" scale.left="9" scale.top="12" scale.right="248" scale.bottom="12" /> + <texture name="TextField_Search_Highlight" file_name="widgets/TextField_Search_Highlight.png" preload="true" scale.left="9" scale.top="12" scale.right="248" scale.bottom="12" /> + + <texture name="Thumbnail_Fallback" file_name="icons/thumbnail_fallback_icon.png" preload="true" /> + + <texture name="Toast_CloseBtn" file_name="windows/Toast_CloseBtn.png" preload="true" /> + <texture name="Toast_Background" file_name="windows/Toast_Background.png" preload="true" + scale.left="4" scale.top="28" scale.right="60" scale.bottom="4" /> + <texture name="Toast_Over" file_name="windows/Toast_Over.png" preload="true" + scale.left="4" scale.top="28" scale.right="60" scale.bottom="4" /> + + <texture name="Tool_Create" file_name="build/Tool_Create.png" preload="false" /> + <texture name="Tool_Dozer" file_name="build/Tool_Dozer.png" preload="false" /> + <texture name="Tool_Face" file_name="build/Tool_Face.png" preload="false" /> + <texture name="Tool_Grab" file_name="build/Tool_Grab.png" preload="false" /> + <texture name="Tool_Zoom" file_name="build/Tool_Zoom.png" preload="false" /> + + <texture name="Toolbar_Left_Flash" file_name="containers/Toolbar_Left_Flash.png" preload="false" scale.left="5" scale.bottom="4" scale.top="24" scale.right="30" /> + <texture name="Toolbar_Left_Off" file_name="containers/Toolbar_Left_Off.png" preload="false" scale.left="5" scale.bottom="4" scale.top="24" scale.right="30" /> + <texture name="Toolbar_Left_Over" file_name="containers/Toolbar_Left_Over.png" preload="false" scale.left="5" scale.bottom="4" scale.top="24" scale.right="30" /> + <texture name="Toolbar_Left_Selected" file_name="containers/Toolbar_Left_Selected.png" preload="false" scale.left="5" scale.bottom="4" scale.top="24" scale.right="30" /> + <texture name="Toolbar_Middle_Off" file_name="containers/Toolbar_Middle_Off.png" preload="false" scale.left="1" scale.bottom="2" scale.top="24" scale.right="30" /> + <texture name="Toolbar_Middle_Over" file_name="containers/Toolbar_Middle_Over.png" preload="false" scale.left="1" scale.bottom="2" scale.top="24" scale.right="30" /> + <texture name="Toolbar_Middle_Selected" file_name="containers/Toolbar_Middle_Selected.png" preload="false" scale.left="1" scale.bottom="2" scale.top="24" scale.right="30" /> + <texture name="Toolbar_Middle_Flash" file_name="containers/Toolbar_Middle_Flash.png" preload="false" scale.left="5" scale.bottom="4" scale.top="24" scale.right="30" /> + <texture name="Toolbar_Right_Off" file_name="containers/Toolbar_Right_Off.png" preload="false" scale.left="1" scale.bottom="4" scale.top="24" scale.right="26" /> + <texture name="Toolbar_Right_Over" file_name="containers/Toolbar_Right_Over.png" preload="false" scale.left="1" scale.bottom="4" scale.top="24" scale.right="26" /> + <texture name="Toolbar_Right_Selected" file_name="containers/Toolbar_Right_Selected.png" preload="false" scale.left="1" scale.bottom="4" scale.top="24" scale.right="26" /> + <texture name="Toolbar_Right_Flash" file_name="containers/Toolbar_Right_Flash.png" preload="false" scale.left="1" scale.bottom="4" scale.top="24" scale.right="26" /> + + <texture name="Tooltip" file_name="widgets/Tooltip.png" preload="true" scale.left="2" scale.top="16" scale.right="100" scale.bottom="3" /> + + <texture name="TrashItem_Disabled" file_name="icons/TrashItem_Disabled.png" preload="false" /> + <texture name="TrashItem_Off" file_name="icons/TrashItem_Off.png" preload="false" /> + <texture name="TrashItem_Press" file_name="icons/TrashItem_Press.png" preload="false" /> + + <texture name="Unread_Chiclet" file_name="bottomtray/Unread_Chiclet.png" preload="false" /> + + <texture name="UpArrow_Off" file_name="icons/UpArrow_Off.png" preload="false" /> + + <texture name="Video_URL_Off" file_name="icons/Video_URL_Off.png" preload="true" /> + + <texture name="Vertical Drag Handle" file_name="widgets/vertical_drag_handle.png" scale.left="2" scale.right="7" scale.bottom="8" scale.top="120" scale_type="scale_outer"/> + + <texture name="VirtualTrackball_Moon_Back" file_name="widgets/track_control_moon_back.png" /> + <texture name="VirtualTrackball_Moon_Front" file_name="widgets/track_control_moon_front.png" /> + <texture name="VirtualTrackball_Rotate_Bottom" file_name="widgets/track_control_rotate_bottom.png" /> + <texture name="VirtualTrackball_Rotate_Left" file_name="widgets/track_control_rotate_left_side.png" /> + <texture name="VirtualTrackball_Rotate_Right" file_name="widgets/track_control_rotate_right_side.png" /> + <texture name="VirtualTrackball_Rotate_Top" file_name="widgets/track_control_rotate_top.png" /> + <texture name="VirtualTrackball_Rotate_Bottom_Active" file_name="widgets/track_control_rotate_bottom_active.png" /> + <texture name="VirtualTrackball_Rotate_Left_Active" file_name="widgets/track_control_rotate_left_side_active.png" /> + <texture name="VirtualTrackball_Rotate_Right_Active" file_name="widgets/track_control_rotate_right_side_active.png" /> + <texture name="VirtualTrackball_Rotate_Top_Active" file_name="widgets/track_control_rotate_top_active.png" /> + <texture name="VirtualTrackball_Sphere" file_name="widgets/track_control_sphere.png" /> + <texture name="VirtualTrackball_Sun_Back" file_name="widgets/track_control_sun_back.png" /> + <texture name="VirtualTrackball_Sun_Front" file_name="widgets/track_control_sun_front.png" /> + + <texture name="Volume_Background" file_name="windows/Volume_Background.png" preload="false" + scale.left="6" scale.top="33" scale.right="63" scale.bottom="10" /> + + <texture name="VoicePTT_Lvl1" file_name="bottomtray/VoicePTT_Lvl1.png" preload="false" /> + <texture name="VoicePTT_Lvl2" file_name="bottomtray/VoicePTT_Lvl2.png" preload="false" /> + <texture name="VoicePTT_Lvl3" file_name="bottomtray/VoicePTT_Lvl3.png" preload="false" /> + <texture name="VoicePTT_Off" file_name="bottomtray/VoicePTT_Off.png" preload="false" /> + <texture name="VoicePTT_On" file_name="bottomtray/VoicePTT_On.png" preload="false" /> + + <texture name="Wearables_Divider" file_name="windows/Wearables_Divider.png" preload="false" /> + + <texture name="Add_Icon" file_name="icons/add_icon.png" preload="false" /> + <texture name="Remove_Icon" file_name="icons/remove_icon.png" preload="false" /> + + <texture name="Web_Profile_Off" file_name="icons/Web_Profile_Off.png" preload="false" /> + + <texture name="WellButton_Lit" file_name="bottomtray/WellButton_Lit.png" preload="true" scale.left="4" scale.top="19" scale.right="28" scale.bottom="4" /> + <texture name="WellButton_Lit_Selected" file_name="bottomtray/WellButton_Lit_Selected.png" preload="true" scale.left="4" scale.top="19" scale.right="28" scale.bottom="4" /> + + <texture name="Window_Background" file_name="windows/Window_Background.png" preload="true" + scale.left="4" scale.top="24" scale.right="26" scale.bottom="4" /> + <texture name="Window_Foreground" file_name="windows/Window_Foreground.png" preload="true" + scale.left="4" scale.top="24" scale.right="26" scale.bottom="4" /> + <texture name="Window_NoTitle_Background" file_name="windows/Window_Background.png" preload="true" + scale.left="4" scale.top="24" scale.right="26" scale.bottom="4" /> + <texture name="Window_NoTitle_Foreground" file_name="windows/Window_Foreground.png" preload="true" + scale.left="4" scale.top="24" scale.right="26" scale.bottom="4" /> + + <texture name="YouAreHere_Badge" file_name="icons/YouAreHere_Badge.png" preload="false" /> + + <texture name="Zoom_Off" file_name="icons/Zoom_Off.png" preload="false" /> + <texture name="UnZoom_Off" file_name="icons/UnZoom_Off.png" preload="false" /> + + <texture name="pixiesmall.j2c" use_mips="true" /> + <texture name="script_error.j2c" use_mips="true" /> + <texture name="silhouette.j2c" use_mips="true" /> + <texture name="foot_shadow.j2c" use_mips="true" /> + <texture name="cloud-particle.j2c" use_mips="true" /> + <texture name="transparent.j2c" use_mips="true" /> + + <!--WARNING OLD ART BELOW *do not use*--> + <texture name="icn_media_web.tga" preload="true" /> + <texture name="icn_media_movie.tga" preload="true" /> + + <texture name="jump_left_out.tga" file_name="widgets/jump_left_out.png" /> + <texture name="jump_left_in.tga" file_name="widgets/jump_left_in.png" /> + <texture name="jump_right_out.tga" file_name="widgets/jump_right_out.png" /> + <texture name="jump_right_in.tga" file_name="widgets/jump_right_in.png" /> + + <texture name="scrollbutton_left_out_blue.tga" file_name="widgets/ScrollArrow_Left_Opaque.png" /> + <texture name="scrollbutton_left_in_blue.tga" file_name="widgets/ScrollArrow_Left_Over_Opaque.png" /> + <texture name="scrollbutton_right_out_blue.tga" file_name="widgets/ScrollArrow_Right_Opaque.png" /> + <texture name="scrollbutton_right_in_blue.tga" file_name="widgets/ScrollArrow_Right_Over_Opaque.png" /> + <texture name="scrollbutton_up_out_blue.tga" file_name="widgets/ScrollArrow_Up_Opaque.png" /> + <texture name="scrollbutton_up_in_blue.tga" file_name="widgets/ScrollArrow_Up_Over_Opaque.png" /> + <texture name="scrollbutton_down_out_blue.tga" file_name="widgets/ScrollArrow_Down_Opaque.png" /> + <texture name="scrollbutton_down_in_blue.tga" file_name="widgets/ScrollArrow_Down_Over_Opaque.png" /> + + <texture name="up_arrow.tga" file_name="up_arrow.png" /> + <texture name="down_arrow.tga" file_name="down_arrow.png" /> + <texture name="arrow_down.tga" /> + + <texture name="tearoffbox.tga" /> + <texture name="tearoff_pressed.tga" /> + + <texture name="color_swatch_alpha.tga" preload="true" /> + + <texture name="button_anim_pause.tga" /> + <texture name="button_anim_pause_selected.tga" /> + <texture name="button_anim_play.tga" /> + <texture name="button_anim_play_selected.tga" /> + <texture name="crosshairs.tga" /> + <texture name="direction_arrow.tga" file_name="world/BeaconArrow.png" /> + + <texture name="icon_avatar_offline.tga" /> + <texture name="icon_avatar_online.tga" /> + <texture name="icon_diurnal.tga" /> + <texture name="icon_for_sale.tga" file_name="icons/Icon_For_Sale.png" /> + <texture name="icon_top_pick.tga" /> + + <texture name="lag_status_critical.tga" /> + <texture name="lag_status_good.tga" /> + <texture name="lag_status_warning.tga" /> + + <texture name="legend.tga" /> + + <texture name="map_avatar_16.tga" /> + <texture name="map_avatar_8.tga" /> + <texture name="map_event.tga" /> + <texture name="map_home.tga" /> + <texture name="map_infohub.tga" /> + <texture name="map_telehub.tga" /> + <texture name="map_track_16.tga" /> + <texture name="map_ui_collapse_icon.png" /> + <texture name="map_ui_expand_icon.png" /> + + <texture name="notify_caution_icon.tga" /> + + <texture name="default_land_picture.j2c" /> + <texture name="default_profile_picture.j2c" /> + <texture name="locked_image.j2c" /> + <texture name="badge_note.j2c" /> + <texture name="badge_warn.j2c" /> + <texture name="badge_ok.j2c" /> + <texture name="materials_ui_x_24.png" /> + + <texture name="Progress_1" file_name="icons/Progress_1.png" preload="true" /> + <texture name="Progress_2" file_name="icons/Progress_2.png" preload="true" /> + <texture name="Progress_3" file_name="icons/Progress_3.png" preload="true" /> + <texture name="Progress_4" file_name="icons/Progress_4.png" preload="true" /> + <texture name="Progress_5" file_name="icons/Progress_5.png" preload="true" /> + <texture name="Progress_6" file_name="icons/Progress_6.png" preload="true" /> + <texture name="Progress_7" file_name="icons/Progress_7.png" preload="true" /> + <texture name="Progress_8" file_name="icons/Progress_8.png" preload="true" /> + <texture name="Progress_9" file_name="icons/Progress_9.png" preload="true" /> + <texture name="Progress_10" file_name="icons/Progress_10.png" preload="true" /> + <texture name="Progress_11" file_name="icons/Progress_11.png" preload="true" /> + <texture name="Progress_12" file_name="icons/Progress_12.png" preload="true" /> + + <texture name="bevel_background" file_name="widgets/bevel_background.png" preload="true" scale.left="12" scale.top="15" scale.right="108" scale.bottom="2"/> + <texture name="buy_off" file_name="widgets/buy_off.png" preload="true" scale.left="2" scale.top="15" scale.right="67" scale.bottom="4"/> + <texture name="buy_over" file_name="widgets/buy_over.png" preload="true" scale.left="2" scale.top="15" scale.right="67" scale.bottom="4"/> + <texture name="buy_press" file_name="widgets/buy_press.png" preload="true" scale.left="2" scale.top="15" scale.right="67" scale.bottom="4"/> + + <texture name="hint_background" file_name="windows/hint_background.png" preload="false" scale.left="8" scale.top="70" scale.right="195" scale.bottom="11"/> + <texture name="hint_arrow_left" file_name="windows/hint_arrow_left.png" preload="false"/> + <texture name="hint_arrow_right" file_name="windows/hint_arrow_right.png" preload="false"/> + <texture name="hint_arrow_up" file_name="windows/hint_arrow_up.png" preload="false"/> + <texture name="hint_arrow_down" file_name="windows/hint_arrow_down.png" preload="false"/> + <texture name="hint_arrow_lower_left" file_name="windows/hint_arrow_lower_left.png" preload="false"/> + + <texture name="Yellow_Gradient" file_name="windows/yellow_gradient.png"/> + <texture name="Popup_Caution" file_name="icons/pop_up_caution.png"/> + <texture name="Camera_Drag_Dot" file_name="world/CameraDragDot.png"/> + <texture name="NavBar Separator" file_name="navbar/separator.png"/> + + <texture name="Default_Outfit_Photo" file_name="icons/Default_Outfit_Photo.png" preload="true"/> + <texture name="Notification_Condense" file_name="icons/Icon_Notification_Condense.png" preload="true"/> + <texture name="Notification_Expand" file_name="icons/Icon_Notification_Expand.png" preload="true"/> + <texture name="System_Notification" file_name="icons/MP_Logo.png" preload="true"/> + <texture name="Icon_Attachment_Small" file_name="icons/Icon_Attachment_Small.png" preload="true"/> + <texture name="Icon_Attachment_Large" file_name="icons/Icon_Attachment_Large.png" preload="true"/> + + <texture name="Single_Folder_Mode" file_name="icons/single_folder_mode.png" preload="true"/> + <texture name="Multi_Folder_Mode" file_name="icons/multi_folder_mode.png" preload="true"/> + <texture name="Single_Folder_Back" file_name="icons/single_folder_back.png" preload="true"/> + <texture name="Single_Folder_Forward" file_name="icons/single_folder_forward.png" preload="true"/> + <texture name="Single_Folder_Up" file_name="icons/single_folder_up.png" preload="true"/> + <texture name="Icon_Color_Palette" file_name="icons/Icon_Color_Palette.png" preload="false"/> + <texture name="Icon_Font_Size" file_name="icons/Icon_Font_Size.png" preload="false"/> + + <texture name="Icon_Place" file_name="megapahit/icon_place.png" preload="false" /> + <texture name="Icon_Auction" file_name="megapahit/icon_land_auction.png" preload="false" /> + <texture name="Icon_For_Sale" file_name="megapahit/icon_land_forsale.png" preload="false" /> + <texture name="Icon_Group" file_name="megapahit/icon_group.png" preload="false" /> + <texture name="Icon_Legacy_Event_PG" file_name="icons/Parcel_PG_Dark.png" preload="false" /> + <texture name="Icon_Legacy_Event_Mature" file_name="icons/Parcel_M_Dark.png" preload="false" /> + <texture name="Icon_Legacy_Event_Adult" file_name="icons/Parcel_R_Dark.png" preload="false" /> + + <texture name="ProgressLarge_1" file_name="icons/ProgressLarge_1.png" preload="true" /> + <texture name="ProgressLarge_2" file_name="icons/ProgressLarge_2.png" preload="true" /> + <texture name="ProgressLarge_3" file_name="icons/ProgressLarge_3.png" preload="true" /> + <texture name="ProgressLarge_4" file_name="icons/ProgressLarge_4.png" preload="true" /> + <texture name="ProgressLarge_5" file_name="icons/ProgressLarge_5.png" preload="true" /> + <texture name="ProgressLarge_6" file_name="icons/ProgressLarge_6.png" preload="true" /> + <texture name="ProgressLarge_7" file_name="icons/ProgressLarge_7.png" preload="true" /> + <texture name="ProgressLarge_8" file_name="icons/ProgressLarge_8.png" preload="true" /> + <texture name="ProgressLarge_9" file_name="icons/ProgressLarge_9.png" preload="true" /> + <texture name="ProgressLarge_10" file_name="icons/ProgressLarge_10.png" preload="true" /> + <texture name="ProgressLarge_11" file_name="icons/ProgressLarge_11.png" preload="true" /> + <texture name="ProgressLarge_12" file_name="icons/ProgressLarge_12.png" preload="true" /> + +</textures> diff --git a/indra/newview/skins/contrast/textures/toolbar_icons/360_capture.png b/indra/newview/skins/contrast/textures/toolbar_icons/360_capture.png Binary files differnew file mode 100644 index 0000000000..163cebe29f --- /dev/null +++ b/indra/newview/skins/contrast/textures/toolbar_icons/360_capture.png diff --git a/indra/newview/skins/contrast/textures/toolbar_icons/appearance.png b/indra/newview/skins/contrast/textures/toolbar_icons/appearance.png Binary files differnew file mode 100644 index 0000000000..e6b1365388 --- /dev/null +++ b/indra/newview/skins/contrast/textures/toolbar_icons/appearance.png diff --git a/indra/newview/skins/contrast/textures/toolbar_icons/avatars.png b/indra/newview/skins/contrast/textures/toolbar_icons/avatars.png Binary files differnew file mode 100644 index 0000000000..8fa0600cee --- /dev/null +++ b/indra/newview/skins/contrast/textures/toolbar_icons/avatars.png diff --git a/indra/newview/skins/contrast/textures/toolbar_icons/build.png b/indra/newview/skins/contrast/textures/toolbar_icons/build.png Binary files differnew file mode 100644 index 0000000000..e21ab3f0e4 --- /dev/null +++ b/indra/newview/skins/contrast/textures/toolbar_icons/build.png diff --git a/indra/newview/skins/contrast/textures/toolbar_icons/caret_bottom.png b/indra/newview/skins/contrast/textures/toolbar_icons/caret_bottom.png Binary files differnew file mode 100644 index 0000000000..5f6a01eaa1 --- /dev/null +++ b/indra/newview/skins/contrast/textures/toolbar_icons/caret_bottom.png diff --git a/indra/newview/skins/contrast/textures/toolbar_icons/caret_left.png b/indra/newview/skins/contrast/textures/toolbar_icons/caret_left.png Binary files differnew file mode 100644 index 0000000000..0b8090314c --- /dev/null +++ b/indra/newview/skins/contrast/textures/toolbar_icons/caret_left.png diff --git a/indra/newview/skins/contrast/textures/toolbar_icons/caret_right.png b/indra/newview/skins/contrast/textures/toolbar_icons/caret_right.png Binary files differnew file mode 100644 index 0000000000..044751560f --- /dev/null +++ b/indra/newview/skins/contrast/textures/toolbar_icons/caret_right.png diff --git a/indra/newview/skins/contrast/textures/toolbar_icons/chat.png b/indra/newview/skins/contrast/textures/toolbar_icons/chat.png Binary files differnew file mode 100644 index 0000000000..e0dbac495f --- /dev/null +++ b/indra/newview/skins/contrast/textures/toolbar_icons/chat.png diff --git a/indra/newview/skins/contrast/textures/toolbar_icons/destinations.png b/indra/newview/skins/contrast/textures/toolbar_icons/destinations.png Binary files differnew file mode 100644 index 0000000000..e2325f083a --- /dev/null +++ b/indra/newview/skins/contrast/textures/toolbar_icons/destinations.png diff --git a/indra/newview/skins/contrast/textures/toolbar_icons/environments.png b/indra/newview/skins/contrast/textures/toolbar_icons/environments.png Binary files differnew file mode 100644 index 0000000000..620db9f793 --- /dev/null +++ b/indra/newview/skins/contrast/textures/toolbar_icons/environments.png diff --git a/indra/newview/skins/contrast/textures/toolbar_icons/facebook.png b/indra/newview/skins/contrast/textures/toolbar_icons/facebook.png Binary files differnew file mode 100644 index 0000000000..ae524b643f --- /dev/null +++ b/indra/newview/skins/contrast/textures/toolbar_icons/facebook.png diff --git a/indra/newview/skins/contrast/textures/toolbar_icons/favorite_folder.png b/indra/newview/skins/contrast/textures/toolbar_icons/favorite_folder.png Binary files differnew file mode 100644 index 0000000000..811efffc0b --- /dev/null +++ b/indra/newview/skins/contrast/textures/toolbar_icons/favorite_folder.png diff --git a/indra/newview/skins/contrast/textures/toolbar_icons/flickr.png b/indra/newview/skins/contrast/textures/toolbar_icons/flickr.png Binary files differnew file mode 100644 index 0000000000..7fce9f0df2 --- /dev/null +++ b/indra/newview/skins/contrast/textures/toolbar_icons/flickr.png diff --git a/indra/newview/skins/contrast/textures/toolbar_icons/gestures.png b/indra/newview/skins/contrast/textures/toolbar_icons/gestures.png Binary files differnew file mode 100644 index 0000000000..2404bb4e25 --- /dev/null +++ b/indra/newview/skins/contrast/textures/toolbar_icons/gestures.png diff --git a/indra/newview/skins/contrast/textures/toolbar_icons/grid_status.png b/indra/newview/skins/contrast/textures/toolbar_icons/grid_status.png Binary files differnew file mode 100644 index 0000000000..b92b93cfb4 --- /dev/null +++ b/indra/newview/skins/contrast/textures/toolbar_icons/grid_status.png diff --git a/indra/newview/skins/contrast/textures/toolbar_icons/highlighting.png b/indra/newview/skins/contrast/textures/toolbar_icons/highlighting.png Binary files differnew file mode 100644 index 0000000000..eeb43d165d --- /dev/null +++ b/indra/newview/skins/contrast/textures/toolbar_icons/highlighting.png diff --git a/indra/newview/skins/contrast/textures/toolbar_icons/highlighting_selected.png b/indra/newview/skins/contrast/textures/toolbar_icons/highlighting_selected.png Binary files differnew file mode 100644 index 0000000000..79d812ee3e --- /dev/null +++ b/indra/newview/skins/contrast/textures/toolbar_icons/highlighting_selected.png diff --git a/indra/newview/skins/contrast/textures/toolbar_icons/howto.png b/indra/newview/skins/contrast/textures/toolbar_icons/howto.png Binary files differnew file mode 100644 index 0000000000..8594d71113 --- /dev/null +++ b/indra/newview/skins/contrast/textures/toolbar_icons/howto.png diff --git a/indra/newview/skins/contrast/textures/toolbar_icons/inventory.png b/indra/newview/skins/contrast/textures/toolbar_icons/inventory.png Binary files differnew file mode 100644 index 0000000000..ab3191255e --- /dev/null +++ b/indra/newview/skins/contrast/textures/toolbar_icons/inventory.png diff --git a/indra/newview/skins/contrast/textures/toolbar_icons/land.png b/indra/newview/skins/contrast/textures/toolbar_icons/land.png Binary files differnew file mode 100644 index 0000000000..89ea7604a4 --- /dev/null +++ b/indra/newview/skins/contrast/textures/toolbar_icons/land.png diff --git a/indra/newview/skins/contrast/textures/toolbar_icons/map.png b/indra/newview/skins/contrast/textures/toolbar_icons/map.png Binary files differnew file mode 100644 index 0000000000..ed1049b7db --- /dev/null +++ b/indra/newview/skins/contrast/textures/toolbar_icons/map.png diff --git a/indra/newview/skins/contrast/textures/toolbar_icons/marketplace.png b/indra/newview/skins/contrast/textures/toolbar_icons/marketplace.png Binary files differnew file mode 100644 index 0000000000..62bad20be6 --- /dev/null +++ b/indra/newview/skins/contrast/textures/toolbar_icons/marketplace.png diff --git a/indra/newview/skins/contrast/textures/toolbar_icons/mini_cart.png b/indra/newview/skins/contrast/textures/toolbar_icons/mini_cart.png Binary files differnew file mode 100644 index 0000000000..9eeb1d4e09 --- /dev/null +++ b/indra/newview/skins/contrast/textures/toolbar_icons/mini_cart.png diff --git a/indra/newview/skins/contrast/textures/toolbar_icons/mini_map.png b/indra/newview/skins/contrast/textures/toolbar_icons/mini_map.png Binary files differnew file mode 100644 index 0000000000..ab0a654056 --- /dev/null +++ b/indra/newview/skins/contrast/textures/toolbar_icons/mini_map.png diff --git a/indra/newview/skins/contrast/textures/toolbar_icons/mktlistings.png b/indra/newview/skins/contrast/textures/toolbar_icons/mktlistings.png Binary files differnew file mode 100644 index 0000000000..a6f90461d7 --- /dev/null +++ b/indra/newview/skins/contrast/textures/toolbar_icons/mktlistings.png diff --git a/indra/newview/skins/contrast/textures/toolbar_icons/move.png b/indra/newview/skins/contrast/textures/toolbar_icons/move.png Binary files differnew file mode 100644 index 0000000000..5c2ced7375 --- /dev/null +++ b/indra/newview/skins/contrast/textures/toolbar_icons/move.png diff --git a/indra/newview/skins/contrast/textures/toolbar_icons/nearbyvoice.png b/indra/newview/skins/contrast/textures/toolbar_icons/nearbyvoice.png Binary files differnew file mode 100644 index 0000000000..77a7cd5f44 --- /dev/null +++ b/indra/newview/skins/contrast/textures/toolbar_icons/nearbyvoice.png diff --git a/indra/newview/skins/contrast/textures/toolbar_icons/outbox.png b/indra/newview/skins/contrast/textures/toolbar_icons/outbox.png Binary files differnew file mode 100644 index 0000000000..0f3db1c47c --- /dev/null +++ b/indra/newview/skins/contrast/textures/toolbar_icons/outbox.png diff --git a/indra/newview/skins/contrast/textures/toolbar_icons/people.png b/indra/newview/skins/contrast/textures/toolbar_icons/people.png Binary files differnew file mode 100644 index 0000000000..7228ae8e2f --- /dev/null +++ b/indra/newview/skins/contrast/textures/toolbar_icons/people.png diff --git a/indra/newview/skins/contrast/textures/toolbar_icons/performance.png b/indra/newview/skins/contrast/textures/toolbar_icons/performance.png Binary files differnew file mode 100644 index 0000000000..91baf849c8 --- /dev/null +++ b/indra/newview/skins/contrast/textures/toolbar_icons/performance.png diff --git a/indra/newview/skins/contrast/textures/toolbar_icons/picks.png b/indra/newview/skins/contrast/textures/toolbar_icons/picks.png Binary files differnew file mode 100644 index 0000000000..befda04b42 --- /dev/null +++ b/indra/newview/skins/contrast/textures/toolbar_icons/picks.png diff --git a/indra/newview/skins/contrast/textures/toolbar_icons/places.png b/indra/newview/skins/contrast/textures/toolbar_icons/places.png Binary files differnew file mode 100644 index 0000000000..97d9fa066c --- /dev/null +++ b/indra/newview/skins/contrast/textures/toolbar_icons/places.png diff --git a/indra/newview/skins/contrast/textures/toolbar_icons/preferences.png b/indra/newview/skins/contrast/textures/toolbar_icons/preferences.png Binary files differnew file mode 100644 index 0000000000..4ccd7b8ae1 --- /dev/null +++ b/indra/newview/skins/contrast/textures/toolbar_icons/preferences.png diff --git a/indra/newview/skins/contrast/textures/toolbar_icons/profile.png b/indra/newview/skins/contrast/textures/toolbar_icons/profile.png Binary files differnew file mode 100644 index 0000000000..32fe2bf8ac --- /dev/null +++ b/indra/newview/skins/contrast/textures/toolbar_icons/profile.png diff --git a/indra/newview/skins/contrast/textures/toolbar_icons/report_abuse.png b/indra/newview/skins/contrast/textures/toolbar_icons/report_abuse.png Binary files differnew file mode 100644 index 0000000000..d5cb6ca259 --- /dev/null +++ b/indra/newview/skins/contrast/textures/toolbar_icons/report_abuse.png diff --git a/indra/newview/skins/contrast/textures/toolbar_icons/resync_animations.png b/indra/newview/skins/contrast/textures/toolbar_icons/resync_animations.png Binary files differnew file mode 100644 index 0000000000..dc9ee9c428 --- /dev/null +++ b/indra/newview/skins/contrast/textures/toolbar_icons/resync_animations.png diff --git a/indra/newview/skins/contrast/textures/toolbar_icons/search.png b/indra/newview/skins/contrast/textures/toolbar_icons/search.png Binary files differnew file mode 100644 index 0000000000..bcb11e950d --- /dev/null +++ b/indra/newview/skins/contrast/textures/toolbar_icons/search.png diff --git a/indra/newview/skins/contrast/textures/toolbar_icons/snapshot.png b/indra/newview/skins/contrast/textures/toolbar_icons/snapshot.png Binary files differnew file mode 100644 index 0000000000..d26da9b1d2 --- /dev/null +++ b/indra/newview/skins/contrast/textures/toolbar_icons/snapshot.png diff --git a/indra/newview/skins/contrast/textures/toolbar_icons/speak.png b/indra/newview/skins/contrast/textures/toolbar_icons/speak.png Binary files differnew file mode 100644 index 0000000000..10cd354c5c --- /dev/null +++ b/indra/newview/skins/contrast/textures/toolbar_icons/speak.png diff --git a/indra/newview/skins/contrast/textures/toolbar_icons/twitter.png b/indra/newview/skins/contrast/textures/toolbar_icons/twitter.png Binary files differnew file mode 100644 index 0000000000..0ad56f7802 --- /dev/null +++ b/indra/newview/skins/contrast/textures/toolbar_icons/twitter.png diff --git a/indra/newview/skins/contrast/textures/toolbar_icons/view.png b/indra/newview/skins/contrast/textures/toolbar_icons/view.png Binary files differnew file mode 100644 index 0000000000..ddf0df7c26 --- /dev/null +++ b/indra/newview/skins/contrast/textures/toolbar_icons/view.png diff --git a/indra/newview/skins/contrast/textures/transparent.j2c b/indra/newview/skins/contrast/textures/transparent.j2c Binary files differnew file mode 100644 index 0000000000..1068e940b9 --- /dev/null +++ b/indra/newview/skins/contrast/textures/transparent.j2c diff --git a/indra/newview/skins/contrast/textures/up_arrow.png b/indra/newview/skins/contrast/textures/up_arrow.png Binary files differnew file mode 100644 index 0000000000..76f839510e --- /dev/null +++ b/indra/newview/skins/contrast/textures/up_arrow.png diff --git a/indra/newview/skins/contrast/textures/uv_test1.j2c b/indra/newview/skins/contrast/textures/uv_test1.j2c Binary files differnew file mode 100644 index 0000000000..3d5b541796 --- /dev/null +++ b/indra/newview/skins/contrast/textures/uv_test1.j2c diff --git a/indra/newview/skins/contrast/textures/uv_test2.tga b/indra/newview/skins/contrast/textures/uv_test2.tga Binary files differnew file mode 100644 index 0000000000..a16000d1e4 --- /dev/null +++ b/indra/newview/skins/contrast/textures/uv_test2.tga diff --git a/indra/newview/skins/contrast/textures/voice_meter_dot.j2c b/indra/newview/skins/contrast/textures/voice_meter_dot.j2c Binary files differnew file mode 100644 index 0000000000..e536c3338a --- /dev/null +++ b/indra/newview/skins/contrast/textures/voice_meter_dot.j2c diff --git a/indra/newview/skins/contrast/textures/voice_meter_rings.j2c b/indra/newview/skins/contrast/textures/voice_meter_rings.j2c Binary files differnew file mode 100644 index 0000000000..17e7c6c6a1 --- /dev/null +++ b/indra/newview/skins/contrast/textures/voice_meter_rings.j2c diff --git a/indra/newview/skins/contrast/textures/white.tga b/indra/newview/skins/contrast/textures/white.tga Binary files differnew file mode 100644 index 0000000000..9fe68631cf --- /dev/null +++ b/indra/newview/skins/contrast/textures/white.tga diff --git a/indra/newview/skins/contrast/textures/widgets/Arrow_Down.png b/indra/newview/skins/contrast/textures/widgets/Arrow_Down.png Binary files differnew file mode 100644 index 0000000000..8b592ed840 --- /dev/null +++ b/indra/newview/skins/contrast/textures/widgets/Arrow_Down.png diff --git a/indra/newview/skins/contrast/textures/widgets/Arrow_Left.png b/indra/newview/skins/contrast/textures/widgets/Arrow_Left.png Binary files differnew file mode 100644 index 0000000000..04416541b9 --- /dev/null +++ b/indra/newview/skins/contrast/textures/widgets/Arrow_Left.png diff --git a/indra/newview/skins/contrast/textures/widgets/Arrow_Right.png b/indra/newview/skins/contrast/textures/widgets/Arrow_Right.png Binary files differnew file mode 100644 index 0000000000..e57452a558 --- /dev/null +++ b/indra/newview/skins/contrast/textures/widgets/Arrow_Right.png diff --git a/indra/newview/skins/contrast/textures/widgets/Arrow_Small_Down.png b/indra/newview/skins/contrast/textures/widgets/Arrow_Small_Down.png Binary files differnew file mode 100644 index 0000000000..8694cdf2d4 --- /dev/null +++ b/indra/newview/skins/contrast/textures/widgets/Arrow_Small_Down.png diff --git a/indra/newview/skins/contrast/textures/widgets/Arrow_Small_Left.png b/indra/newview/skins/contrast/textures/widgets/Arrow_Small_Left.png Binary files differnew file mode 100644 index 0000000000..a1b82d5101 --- /dev/null +++ b/indra/newview/skins/contrast/textures/widgets/Arrow_Small_Left.png diff --git a/indra/newview/skins/contrast/textures/widgets/Arrow_Small_Right.png b/indra/newview/skins/contrast/textures/widgets/Arrow_Small_Right.png Binary files differnew file mode 100644 index 0000000000..0e05d76852 --- /dev/null +++ b/indra/newview/skins/contrast/textures/widgets/Arrow_Small_Right.png diff --git a/indra/newview/skins/contrast/textures/widgets/Arrow_Small_Up.png b/indra/newview/skins/contrast/textures/widgets/Arrow_Small_Up.png Binary files differnew file mode 100644 index 0000000000..348bc4c019 --- /dev/null +++ b/indra/newview/skins/contrast/textures/widgets/Arrow_Small_Up.png diff --git a/indra/newview/skins/contrast/textures/widgets/Arrow_Up.png b/indra/newview/skins/contrast/textures/widgets/Arrow_Up.png Binary files differnew file mode 100644 index 0000000000..8b3da09d79 --- /dev/null +++ b/indra/newview/skins/contrast/textures/widgets/Arrow_Up.png diff --git a/indra/newview/skins/contrast/textures/widgets/Badge_Background.png b/indra/newview/skins/contrast/textures/widgets/Badge_Background.png Binary files differnew file mode 100644 index 0000000000..5abc1bf489 --- /dev/null +++ b/indra/newview/skins/contrast/textures/widgets/Badge_Background.png diff --git a/indra/newview/skins/contrast/textures/widgets/Badge_Border.png b/indra/newview/skins/contrast/textures/widgets/Badge_Border.png Binary files differnew file mode 100644 index 0000000000..57d3be2320 --- /dev/null +++ b/indra/newview/skins/contrast/textures/widgets/Badge_Border.png diff --git a/indra/newview/skins/contrast/textures/widgets/BreadCrumbBtn_Left_Disabled.png b/indra/newview/skins/contrast/textures/widgets/BreadCrumbBtn_Left_Disabled.png Binary files differnew file mode 100644 index 0000000000..e18872b6f6 --- /dev/null +++ b/indra/newview/skins/contrast/textures/widgets/BreadCrumbBtn_Left_Disabled.png diff --git a/indra/newview/skins/contrast/textures/widgets/BreadCrumbBtn_Left_Off.png b/indra/newview/skins/contrast/textures/widgets/BreadCrumbBtn_Left_Off.png Binary files differnew file mode 100644 index 0000000000..699ddd9bf3 --- /dev/null +++ b/indra/newview/skins/contrast/textures/widgets/BreadCrumbBtn_Left_Off.png diff --git a/indra/newview/skins/contrast/textures/widgets/BreadCrumbBtn_Left_Over.png b/indra/newview/skins/contrast/textures/widgets/BreadCrumbBtn_Left_Over.png Binary files differnew file mode 100644 index 0000000000..12854bdb12 --- /dev/null +++ b/indra/newview/skins/contrast/textures/widgets/BreadCrumbBtn_Left_Over.png diff --git a/indra/newview/skins/contrast/textures/widgets/BreadCrumbBtn_Left_Press.png b/indra/newview/skins/contrast/textures/widgets/BreadCrumbBtn_Left_Press.png Binary files differnew file mode 100644 index 0000000000..1f04a1e9e8 --- /dev/null +++ b/indra/newview/skins/contrast/textures/widgets/BreadCrumbBtn_Left_Press.png diff --git a/indra/newview/skins/contrast/textures/widgets/BreadCrumbBtn_Middle_Disabled.png b/indra/newview/skins/contrast/textures/widgets/BreadCrumbBtn_Middle_Disabled.png Binary files differnew file mode 100644 index 0000000000..2cf3de24c0 --- /dev/null +++ b/indra/newview/skins/contrast/textures/widgets/BreadCrumbBtn_Middle_Disabled.png diff --git a/indra/newview/skins/contrast/textures/widgets/BreadCrumbBtn_Middle_Off.png b/indra/newview/skins/contrast/textures/widgets/BreadCrumbBtn_Middle_Off.png Binary files differnew file mode 100644 index 0000000000..52bcf88258 --- /dev/null +++ b/indra/newview/skins/contrast/textures/widgets/BreadCrumbBtn_Middle_Off.png diff --git a/indra/newview/skins/contrast/textures/widgets/BreadCrumbBtn_Middle_Over.png b/indra/newview/skins/contrast/textures/widgets/BreadCrumbBtn_Middle_Over.png Binary files differnew file mode 100644 index 0000000000..efdd13003a --- /dev/null +++ b/indra/newview/skins/contrast/textures/widgets/BreadCrumbBtn_Middle_Over.png diff --git a/indra/newview/skins/contrast/textures/widgets/BreadCrumbBtn_Middle_Press.png b/indra/newview/skins/contrast/textures/widgets/BreadCrumbBtn_Middle_Press.png Binary files differnew file mode 100644 index 0000000000..3c66b1f1cc --- /dev/null +++ b/indra/newview/skins/contrast/textures/widgets/BreadCrumbBtn_Middle_Press.png diff --git a/indra/newview/skins/contrast/textures/widgets/BreadCrumbBtn_Right_Disabled.png b/indra/newview/skins/contrast/textures/widgets/BreadCrumbBtn_Right_Disabled.png Binary files differnew file mode 100644 index 0000000000..d9c9692114 --- /dev/null +++ b/indra/newview/skins/contrast/textures/widgets/BreadCrumbBtn_Right_Disabled.png diff --git a/indra/newview/skins/contrast/textures/widgets/BreadCrumbBtn_Right_Off.png b/indra/newview/skins/contrast/textures/widgets/BreadCrumbBtn_Right_Off.png Binary files differnew file mode 100644 index 0000000000..4935dae42e --- /dev/null +++ b/indra/newview/skins/contrast/textures/widgets/BreadCrumbBtn_Right_Off.png diff --git a/indra/newview/skins/contrast/textures/widgets/BreadCrumbBtn_Right_Over.png b/indra/newview/skins/contrast/textures/widgets/BreadCrumbBtn_Right_Over.png Binary files differnew file mode 100644 index 0000000000..6eeec08248 --- /dev/null +++ b/indra/newview/skins/contrast/textures/widgets/BreadCrumbBtn_Right_Over.png diff --git a/indra/newview/skins/contrast/textures/widgets/BreadCrumbBtn_Right_Press.png b/indra/newview/skins/contrast/textures/widgets/BreadCrumbBtn_Right_Press.png Binary files differnew file mode 100644 index 0000000000..2d6d08522b --- /dev/null +++ b/indra/newview/skins/contrast/textures/widgets/BreadCrumbBtn_Right_Press.png diff --git a/indra/newview/skins/contrast/textures/widgets/Checkbox_Disabled.png b/indra/newview/skins/contrast/textures/widgets/Checkbox_Disabled.png Binary files differnew file mode 100644 index 0000000000..8439f82e29 --- /dev/null +++ b/indra/newview/skins/contrast/textures/widgets/Checkbox_Disabled.png diff --git a/indra/newview/skins/contrast/textures/widgets/Checkbox_Off.png b/indra/newview/skins/contrast/textures/widgets/Checkbox_Off.png Binary files differnew file mode 100644 index 0000000000..cb9a04d84f --- /dev/null +++ b/indra/newview/skins/contrast/textures/widgets/Checkbox_Off.png diff --git a/indra/newview/skins/contrast/textures/widgets/Checkbox_On.png b/indra/newview/skins/contrast/textures/widgets/Checkbox_On.png Binary files differnew file mode 100644 index 0000000000..0ec090504a --- /dev/null +++ b/indra/newview/skins/contrast/textures/widgets/Checkbox_On.png diff --git a/indra/newview/skins/contrast/textures/widgets/Checkbox_On_Disabled.png b/indra/newview/skins/contrast/textures/widgets/Checkbox_On_Disabled.png Binary files differnew file mode 100644 index 0000000000..5759f7de69 --- /dev/null +++ b/indra/newview/skins/contrast/textures/widgets/Checkbox_On_Disabled.png diff --git a/indra/newview/skins/contrast/textures/widgets/Checkbox_On_Press.png b/indra/newview/skins/contrast/textures/widgets/Checkbox_On_Press.png Binary files differnew file mode 100644 index 0000000000..ba46e91c55 --- /dev/null +++ b/indra/newview/skins/contrast/textures/widgets/Checkbox_On_Press.png diff --git a/indra/newview/skins/contrast/textures/widgets/Checkbox_Press.png b/indra/newview/skins/contrast/textures/widgets/Checkbox_Press.png Binary files differnew file mode 100644 index 0000000000..5f5a33d878 --- /dev/null +++ b/indra/newview/skins/contrast/textures/widgets/Checkbox_Press.png diff --git a/indra/newview/skins/contrast/textures/widgets/ComboButton_Disabled.png b/indra/newview/skins/contrast/textures/widgets/ComboButton_Disabled.png Binary files differnew file mode 100644 index 0000000000..ebeb813349 --- /dev/null +++ b/indra/newview/skins/contrast/textures/widgets/ComboButton_Disabled.png diff --git a/indra/newview/skins/contrast/textures/widgets/ComboButton_Hover.png b/indra/newview/skins/contrast/textures/widgets/ComboButton_Hover.png Binary files differnew file mode 100644 index 0000000000..1377d35e1a --- /dev/null +++ b/indra/newview/skins/contrast/textures/widgets/ComboButton_Hover.png diff --git a/indra/newview/skins/contrast/textures/widgets/ComboButton_Off.png b/indra/newview/skins/contrast/textures/widgets/ComboButton_Off.png Binary files differnew file mode 100644 index 0000000000..4f573cf6fa --- /dev/null +++ b/indra/newview/skins/contrast/textures/widgets/ComboButton_Off.png diff --git a/indra/newview/skins/contrast/textures/widgets/ComboButton_On.png b/indra/newview/skins/contrast/textures/widgets/ComboButton_On.png Binary files differnew file mode 100644 index 0000000000..1d1ea1bd87 --- /dev/null +++ b/indra/newview/skins/contrast/textures/widgets/ComboButton_On.png diff --git a/indra/newview/skins/contrast/textures/widgets/ComboButton_Selected.png b/indra/newview/skins/contrast/textures/widgets/ComboButton_Selected.png Binary files differnew file mode 100644 index 0000000000..d87e46aba7 --- /dev/null +++ b/indra/newview/skins/contrast/textures/widgets/ComboButton_Selected.png diff --git a/indra/newview/skins/contrast/textures/widgets/ComboButton_UpOff.png b/indra/newview/skins/contrast/textures/widgets/ComboButton_UpOff.png Binary files differnew file mode 100644 index 0000000000..5a067aca7c --- /dev/null +++ b/indra/newview/skins/contrast/textures/widgets/ComboButton_UpOff.png diff --git a/indra/newview/skins/contrast/textures/widgets/ComboButton_UpSelected.png b/indra/newview/skins/contrast/textures/widgets/ComboButton_UpSelected.png Binary files differnew file mode 100644 index 0000000000..34b0c70cb0 --- /dev/null +++ b/indra/newview/skins/contrast/textures/widgets/ComboButton_UpSelected.png diff --git a/indra/newview/skins/contrast/textures/widgets/DisclosureArrow_Opened_Off.png b/indra/newview/skins/contrast/textures/widgets/DisclosureArrow_Opened_Off.png Binary files differnew file mode 100644 index 0000000000..115ec7a11f --- /dev/null +++ b/indra/newview/skins/contrast/textures/widgets/DisclosureArrow_Opened_Off.png diff --git a/indra/newview/skins/contrast/textures/widgets/DropDown_Disabled.png b/indra/newview/skins/contrast/textures/widgets/DropDown_Disabled.png Binary files differnew file mode 100644 index 0000000000..908501149d --- /dev/null +++ b/indra/newview/skins/contrast/textures/widgets/DropDown_Disabled.png diff --git a/indra/newview/skins/contrast/textures/widgets/DropDown_Off.png b/indra/newview/skins/contrast/textures/widgets/DropDown_Off.png Binary files differnew file mode 100644 index 0000000000..e21cd20ba9 --- /dev/null +++ b/indra/newview/skins/contrast/textures/widgets/DropDown_Off.png diff --git a/indra/newview/skins/contrast/textures/widgets/DropDown_On.png b/indra/newview/skins/contrast/textures/widgets/DropDown_On.png Binary files differnew file mode 100644 index 0000000000..bfef85b457 --- /dev/null +++ b/indra/newview/skins/contrast/textures/widgets/DropDown_On.png diff --git a/indra/newview/skins/contrast/textures/widgets/DropDown_Press.png b/indra/newview/skins/contrast/textures/widgets/DropDown_Press.png Binary files differnew file mode 100644 index 0000000000..1e3abaa897 --- /dev/null +++ b/indra/newview/skins/contrast/textures/widgets/DropDown_Press.png diff --git a/indra/newview/skins/contrast/textures/widgets/DropTarget.png b/indra/newview/skins/contrast/textures/widgets/DropTarget.png Binary files differnew file mode 100644 index 0000000000..01e7a88861 --- /dev/null +++ b/indra/newview/skins/contrast/textures/widgets/DropTarget.png diff --git a/indra/newview/skins/contrast/textures/widgets/Error_Tag_Background.png b/indra/newview/skins/contrast/textures/widgets/Error_Tag_Background.png Binary files differnew file mode 100644 index 0000000000..439fce3dd3 --- /dev/null +++ b/indra/newview/skins/contrast/textures/widgets/Error_Tag_Background.png diff --git a/indra/newview/skins/contrast/textures/widgets/Linden_Dollar_Alert.png b/indra/newview/skins/contrast/textures/widgets/Linden_Dollar_Alert.png Binary files differnew file mode 100644 index 0000000000..76e078100f --- /dev/null +++ b/indra/newview/skins/contrast/textures/widgets/Linden_Dollar_Alert.png diff --git a/indra/newview/skins/contrast/textures/widgets/Linden_Dollar_Background.png b/indra/newview/skins/contrast/textures/widgets/Linden_Dollar_Background.png Binary files differnew file mode 100644 index 0000000000..6e71ef7b72 --- /dev/null +++ b/indra/newview/skins/contrast/textures/widgets/Linden_Dollar_Background.png diff --git a/indra/newview/skins/contrast/textures/widgets/ListItem_Over.png b/indra/newview/skins/contrast/textures/widgets/ListItem_Over.png Binary files differnew file mode 100644 index 0000000000..0ec8de776e --- /dev/null +++ b/indra/newview/skins/contrast/textures/widgets/ListItem_Over.png diff --git a/indra/newview/skins/contrast/textures/widgets/ListItem_Select.png b/indra/newview/skins/contrast/textures/widgets/ListItem_Select.png Binary files differnew file mode 100644 index 0000000000..6dd7b3c638 --- /dev/null +++ b/indra/newview/skins/contrast/textures/widgets/ListItem_Select.png diff --git a/indra/newview/skins/contrast/textures/widgets/MarketplaceBtn_Off.png b/indra/newview/skins/contrast/textures/widgets/MarketplaceBtn_Off.png Binary files differnew file mode 100644 index 0000000000..37cd0f6108 --- /dev/null +++ b/indra/newview/skins/contrast/textures/widgets/MarketplaceBtn_Off.png diff --git a/indra/newview/skins/contrast/textures/widgets/MarketplaceBtn_Selected.png b/indra/newview/skins/contrast/textures/widgets/MarketplaceBtn_Selected.png Binary files differnew file mode 100644 index 0000000000..3d9d474966 --- /dev/null +++ b/indra/newview/skins/contrast/textures/widgets/MarketplaceBtn_Selected.png diff --git a/indra/newview/skins/contrast/textures/widgets/Marketplace_Dropzone_Background.png b/indra/newview/skins/contrast/textures/widgets/Marketplace_Dropzone_Background.png Binary files differnew file mode 100644 index 0000000000..9eb4a5c55d --- /dev/null +++ b/indra/newview/skins/contrast/textures/widgets/Marketplace_Dropzone_Background.png diff --git a/indra/newview/skins/contrast/textures/widgets/New_Tag_Background.png b/indra/newview/skins/contrast/textures/widgets/New_Tag_Background.png Binary files differnew file mode 100644 index 0000000000..3631d90825 --- /dev/null +++ b/indra/newview/skins/contrast/textures/widgets/New_Tag_Background.png diff --git a/indra/newview/skins/contrast/textures/widgets/New_Tag_Border.png b/indra/newview/skins/contrast/textures/widgets/New_Tag_Border.png Binary files differnew file mode 100644 index 0000000000..d9b78eeea4 --- /dev/null +++ b/indra/newview/skins/contrast/textures/widgets/New_Tag_Border.png diff --git a/indra/newview/skins/contrast/textures/widgets/ProgressBar.png b/indra/newview/skins/contrast/textures/widgets/ProgressBar.png Binary files differnew file mode 100644 index 0000000000..7527aaf6b3 --- /dev/null +++ b/indra/newview/skins/contrast/textures/widgets/ProgressBar.png diff --git a/indra/newview/skins/contrast/textures/widgets/ProgressBarSolid.png b/indra/newview/skins/contrast/textures/widgets/ProgressBarSolid.png Binary files differnew file mode 100644 index 0000000000..59a798464d --- /dev/null +++ b/indra/newview/skins/contrast/textures/widgets/ProgressBarSolid.png diff --git a/indra/newview/skins/contrast/textures/widgets/ProgressTrack.png b/indra/newview/skins/contrast/textures/widgets/ProgressTrack.png Binary files differnew file mode 100644 index 0000000000..f4be9f5ccd --- /dev/null +++ b/indra/newview/skins/contrast/textures/widgets/ProgressTrack.png diff --git a/indra/newview/skins/contrast/textures/widgets/PushButton_Disabled.png b/indra/newview/skins/contrast/textures/widgets/PushButton_Disabled.png Binary files differnew file mode 100644 index 0000000000..e99ec4b14b --- /dev/null +++ b/indra/newview/skins/contrast/textures/widgets/PushButton_Disabled.png diff --git a/indra/newview/skins/contrast/textures/widgets/PushButton_Login.png b/indra/newview/skins/contrast/textures/widgets/PushButton_Login.png Binary files differnew file mode 100644 index 0000000000..8e7d932ab1 --- /dev/null +++ b/indra/newview/skins/contrast/textures/widgets/PushButton_Login.png diff --git a/indra/newview/skins/contrast/textures/widgets/PushButton_Login_Over.png b/indra/newview/skins/contrast/textures/widgets/PushButton_Login_Over.png Binary files differnew file mode 100644 index 0000000000..038ba23be2 --- /dev/null +++ b/indra/newview/skins/contrast/textures/widgets/PushButton_Login_Over.png diff --git a/indra/newview/skins/contrast/textures/widgets/PushButton_Login_Pressed.png b/indra/newview/skins/contrast/textures/widgets/PushButton_Login_Pressed.png Binary files differnew file mode 100644 index 0000000000..828aa1a139 --- /dev/null +++ b/indra/newview/skins/contrast/textures/widgets/PushButton_Login_Pressed.png diff --git a/indra/newview/skins/contrast/textures/widgets/PushButton_Off.png b/indra/newview/skins/contrast/textures/widgets/PushButton_Off.png Binary files differnew file mode 100644 index 0000000000..8d0b56ade0 --- /dev/null +++ b/indra/newview/skins/contrast/textures/widgets/PushButton_Off.png diff --git a/indra/newview/skins/contrast/textures/widgets/PushButton_On.png b/indra/newview/skins/contrast/textures/widgets/PushButton_On.png Binary files differnew file mode 100644 index 0000000000..b4c4e9319b --- /dev/null +++ b/indra/newview/skins/contrast/textures/widgets/PushButton_On.png diff --git a/indra/newview/skins/contrast/textures/widgets/PushButton_On_Selected.png b/indra/newview/skins/contrast/textures/widgets/PushButton_On_Selected.png Binary files differnew file mode 100644 index 0000000000..3e0c79fac6 --- /dev/null +++ b/indra/newview/skins/contrast/textures/widgets/PushButton_On_Selected.png diff --git a/indra/newview/skins/contrast/textures/widgets/PushButton_Over.png b/indra/newview/skins/contrast/textures/widgets/PushButton_Over.png Binary files differnew file mode 100644 index 0000000000..db8ad9d691 --- /dev/null +++ b/indra/newview/skins/contrast/textures/widgets/PushButton_Over.png diff --git a/indra/newview/skins/contrast/textures/widgets/PushButton_Press.png b/indra/newview/skins/contrast/textures/widgets/PushButton_Press.png Binary files differnew file mode 100644 index 0000000000..f6410313b8 --- /dev/null +++ b/indra/newview/skins/contrast/textures/widgets/PushButton_Press.png diff --git a/indra/newview/skins/contrast/textures/widgets/PushButton_Selected.png b/indra/newview/skins/contrast/textures/widgets/PushButton_Selected.png Binary files differnew file mode 100644 index 0000000000..6760bc7f58 --- /dev/null +++ b/indra/newview/skins/contrast/textures/widgets/PushButton_Selected.png diff --git a/indra/newview/skins/contrast/textures/widgets/PushButton_Selected_Disabled.png b/indra/newview/skins/contrast/textures/widgets/PushButton_Selected_Disabled.png Binary files differnew file mode 100644 index 0000000000..c44b0d2083 --- /dev/null +++ b/indra/newview/skins/contrast/textures/widgets/PushButton_Selected_Disabled.png diff --git a/indra/newview/skins/contrast/textures/widgets/PushButton_Selected_Press.png b/indra/newview/skins/contrast/textures/widgets/PushButton_Selected_Press.png Binary files differnew file mode 100644 index 0000000000..ba7a33a1a6 --- /dev/null +++ b/indra/newview/skins/contrast/textures/widgets/PushButton_Selected_Press.png diff --git a/indra/newview/skins/contrast/textures/widgets/RadioButton_Disabled.png b/indra/newview/skins/contrast/textures/widgets/RadioButton_Disabled.png Binary files differnew file mode 100644 index 0000000000..32ec25fe0e --- /dev/null +++ b/indra/newview/skins/contrast/textures/widgets/RadioButton_Disabled.png diff --git a/indra/newview/skins/contrast/textures/widgets/RadioButton_Off.png b/indra/newview/skins/contrast/textures/widgets/RadioButton_Off.png Binary files differnew file mode 100644 index 0000000000..5d267af5dc --- /dev/null +++ b/indra/newview/skins/contrast/textures/widgets/RadioButton_Off.png diff --git a/indra/newview/skins/contrast/textures/widgets/RadioButton_On.png b/indra/newview/skins/contrast/textures/widgets/RadioButton_On.png Binary files differnew file mode 100644 index 0000000000..e6bf0db157 --- /dev/null +++ b/indra/newview/skins/contrast/textures/widgets/RadioButton_On.png diff --git a/indra/newview/skins/contrast/textures/widgets/RadioButton_On_Disabled.png b/indra/newview/skins/contrast/textures/widgets/RadioButton_On_Disabled.png Binary files differnew file mode 100644 index 0000000000..72aae43618 --- /dev/null +++ b/indra/newview/skins/contrast/textures/widgets/RadioButton_On_Disabled.png diff --git a/indra/newview/skins/contrast/textures/widgets/RadioButton_On_Press.png b/indra/newview/skins/contrast/textures/widgets/RadioButton_On_Press.png Binary files differnew file mode 100644 index 0000000000..f3883b82b3 --- /dev/null +++ b/indra/newview/skins/contrast/textures/widgets/RadioButton_On_Press.png diff --git a/indra/newview/skins/contrast/textures/widgets/RadioButton_Press.png b/indra/newview/skins/contrast/textures/widgets/RadioButton_Press.png Binary files differnew file mode 100644 index 0000000000..0025256045 --- /dev/null +++ b/indra/newview/skins/contrast/textures/widgets/RadioButton_Press.png diff --git a/indra/newview/skins/contrast/textures/widgets/ScrollArrow_Down.png b/indra/newview/skins/contrast/textures/widgets/ScrollArrow_Down.png Binary files differnew file mode 100644 index 0000000000..768909d447 --- /dev/null +++ b/indra/newview/skins/contrast/textures/widgets/ScrollArrow_Down.png diff --git a/indra/newview/skins/contrast/textures/widgets/ScrollArrow_Down_Opaque.png b/indra/newview/skins/contrast/textures/widgets/ScrollArrow_Down_Opaque.png Binary files differnew file mode 100644 index 0000000000..1c57521e9e --- /dev/null +++ b/indra/newview/skins/contrast/textures/widgets/ScrollArrow_Down_Opaque.png diff --git a/indra/newview/skins/contrast/textures/widgets/ScrollArrow_Down_Over_Opaque.png b/indra/newview/skins/contrast/textures/widgets/ScrollArrow_Down_Over_Opaque.png Binary files differnew file mode 100644 index 0000000000..3db7be9ffa --- /dev/null +++ b/indra/newview/skins/contrast/textures/widgets/ScrollArrow_Down_Over_Opaque.png diff --git a/indra/newview/skins/contrast/textures/widgets/ScrollArrow_Left.png b/indra/newview/skins/contrast/textures/widgets/ScrollArrow_Left.png Binary files differnew file mode 100644 index 0000000000..9ef73f48a5 --- /dev/null +++ b/indra/newview/skins/contrast/textures/widgets/ScrollArrow_Left.png diff --git a/indra/newview/skins/contrast/textures/widgets/ScrollArrow_Left_Opaque.png b/indra/newview/skins/contrast/textures/widgets/ScrollArrow_Left_Opaque.png Binary files differnew file mode 100644 index 0000000000..0fb0671036 --- /dev/null +++ b/indra/newview/skins/contrast/textures/widgets/ScrollArrow_Left_Opaque.png diff --git a/indra/newview/skins/contrast/textures/widgets/ScrollArrow_Left_Over_Opaque.png b/indra/newview/skins/contrast/textures/widgets/ScrollArrow_Left_Over_Opaque.png Binary files differnew file mode 100644 index 0000000000..464130c359 --- /dev/null +++ b/indra/newview/skins/contrast/textures/widgets/ScrollArrow_Left_Over_Opaque.png diff --git a/indra/newview/skins/contrast/textures/widgets/ScrollArrow_Right.png b/indra/newview/skins/contrast/textures/widgets/ScrollArrow_Right.png Binary files differnew file mode 100644 index 0000000000..8a59274b8a --- /dev/null +++ b/indra/newview/skins/contrast/textures/widgets/ScrollArrow_Right.png diff --git a/indra/newview/skins/contrast/textures/widgets/ScrollArrow_Right_Opaque.png b/indra/newview/skins/contrast/textures/widgets/ScrollArrow_Right_Opaque.png Binary files differnew file mode 100644 index 0000000000..ab1f1ac90b --- /dev/null +++ b/indra/newview/skins/contrast/textures/widgets/ScrollArrow_Right_Opaque.png diff --git a/indra/newview/skins/contrast/textures/widgets/ScrollArrow_Right_Over_Opaque.png b/indra/newview/skins/contrast/textures/widgets/ScrollArrow_Right_Over_Opaque.png Binary files differnew file mode 100644 index 0000000000..e5a94429a3 --- /dev/null +++ b/indra/newview/skins/contrast/textures/widgets/ScrollArrow_Right_Over_Opaque.png diff --git a/indra/newview/skins/contrast/textures/widgets/ScrollArrow_Up.png b/indra/newview/skins/contrast/textures/widgets/ScrollArrow_Up.png Binary files differnew file mode 100644 index 0000000000..064580f0c8 --- /dev/null +++ b/indra/newview/skins/contrast/textures/widgets/ScrollArrow_Up.png diff --git a/indra/newview/skins/contrast/textures/widgets/ScrollArrow_Up_Opaque.png b/indra/newview/skins/contrast/textures/widgets/ScrollArrow_Up_Opaque.png Binary files differnew file mode 100644 index 0000000000..2cc4857d27 --- /dev/null +++ b/indra/newview/skins/contrast/textures/widgets/ScrollArrow_Up_Opaque.png diff --git a/indra/newview/skins/contrast/textures/widgets/ScrollArrow_Up_Over_Opaque.png b/indra/newview/skins/contrast/textures/widgets/ScrollArrow_Up_Over_Opaque.png Binary files differnew file mode 100644 index 0000000000..2018b53af9 --- /dev/null +++ b/indra/newview/skins/contrast/textures/widgets/ScrollArrow_Up_Over_Opaque.png diff --git a/indra/newview/skins/contrast/textures/widgets/ScrollThumb_Horiz.png b/indra/newview/skins/contrast/textures/widgets/ScrollThumb_Horiz.png Binary files differnew file mode 100644 index 0000000000..9afc907c1c --- /dev/null +++ b/indra/newview/skins/contrast/textures/widgets/ScrollThumb_Horiz.png diff --git a/indra/newview/skins/contrast/textures/widgets/ScrollThumb_Vert.png b/indra/newview/skins/contrast/textures/widgets/ScrollThumb_Vert.png Binary files differnew file mode 100644 index 0000000000..ede643e528 --- /dev/null +++ b/indra/newview/skins/contrast/textures/widgets/ScrollThumb_Vert.png diff --git a/indra/newview/skins/contrast/textures/widgets/ScrollTrack_Horiz.png b/indra/newview/skins/contrast/textures/widgets/ScrollTrack_Horiz.png Binary files differnew file mode 100644 index 0000000000..35da770073 --- /dev/null +++ b/indra/newview/skins/contrast/textures/widgets/ScrollTrack_Horiz.png diff --git a/indra/newview/skins/contrast/textures/widgets/ScrollTrack_Vert.png b/indra/newview/skins/contrast/textures/widgets/ScrollTrack_Vert.png Binary files differnew file mode 100644 index 0000000000..cf67c23133 --- /dev/null +++ b/indra/newview/skins/contrast/textures/widgets/ScrollTrack_Vert.png diff --git a/indra/newview/skins/contrast/textures/widgets/SegmentedBtn_Left_Disabled.png b/indra/newview/skins/contrast/textures/widgets/SegmentedBtn_Left_Disabled.png Binary files differnew file mode 100644 index 0000000000..ba63751690 --- /dev/null +++ b/indra/newview/skins/contrast/textures/widgets/SegmentedBtn_Left_Disabled.png diff --git a/indra/newview/skins/contrast/textures/widgets/SegmentedBtn_Left_Off.png b/indra/newview/skins/contrast/textures/widgets/SegmentedBtn_Left_Off.png Binary files differnew file mode 100644 index 0000000000..1a9f7e9d71 --- /dev/null +++ b/indra/newview/skins/contrast/textures/widgets/SegmentedBtn_Left_Off.png diff --git a/indra/newview/skins/contrast/textures/widgets/SegmentedBtn_Left_Over.png b/indra/newview/skins/contrast/textures/widgets/SegmentedBtn_Left_Over.png Binary files differnew file mode 100644 index 0000000000..e4fcf491ba --- /dev/null +++ b/indra/newview/skins/contrast/textures/widgets/SegmentedBtn_Left_Over.png diff --git a/indra/newview/skins/contrast/textures/widgets/SegmentedBtn_Left_Press.png b/indra/newview/skins/contrast/textures/widgets/SegmentedBtn_Left_Press.png Binary files differnew file mode 100644 index 0000000000..dbe6651dc8 --- /dev/null +++ b/indra/newview/skins/contrast/textures/widgets/SegmentedBtn_Left_Press.png diff --git a/indra/newview/skins/contrast/textures/widgets/SegmentedBtn_Left_Selected.png b/indra/newview/skins/contrast/textures/widgets/SegmentedBtn_Left_Selected.png Binary files differnew file mode 100644 index 0000000000..dbe6651dc8 --- /dev/null +++ b/indra/newview/skins/contrast/textures/widgets/SegmentedBtn_Left_Selected.png diff --git a/indra/newview/skins/contrast/textures/widgets/SegmentedBtn_Left_Selected_Disabled.png b/indra/newview/skins/contrast/textures/widgets/SegmentedBtn_Left_Selected_Disabled.png Binary files differnew file mode 100644 index 0000000000..2651029577 --- /dev/null +++ b/indra/newview/skins/contrast/textures/widgets/SegmentedBtn_Left_Selected_Disabled.png diff --git a/indra/newview/skins/contrast/textures/widgets/SegmentedBtn_Left_Selected_Over.png b/indra/newview/skins/contrast/textures/widgets/SegmentedBtn_Left_Selected_Over.png Binary files differnew file mode 100644 index 0000000000..1032cad8db --- /dev/null +++ b/indra/newview/skins/contrast/textures/widgets/SegmentedBtn_Left_Selected_Over.png diff --git a/indra/newview/skins/contrast/textures/widgets/SegmentedBtn_Left_Selected_Press.png b/indra/newview/skins/contrast/textures/widgets/SegmentedBtn_Left_Selected_Press.png Binary files differnew file mode 100644 index 0000000000..58cd154919 --- /dev/null +++ b/indra/newview/skins/contrast/textures/widgets/SegmentedBtn_Left_Selected_Press.png diff --git a/indra/newview/skins/contrast/textures/widgets/SegmentedBtn_Middle_Disabled.png b/indra/newview/skins/contrast/textures/widgets/SegmentedBtn_Middle_Disabled.png Binary files differnew file mode 100644 index 0000000000..d9f05d33ec --- /dev/null +++ b/indra/newview/skins/contrast/textures/widgets/SegmentedBtn_Middle_Disabled.png diff --git a/indra/newview/skins/contrast/textures/widgets/SegmentedBtn_Middle_Selected.png b/indra/newview/skins/contrast/textures/widgets/SegmentedBtn_Middle_Selected.png Binary files differnew file mode 100644 index 0000000000..d2342f6538 --- /dev/null +++ b/indra/newview/skins/contrast/textures/widgets/SegmentedBtn_Middle_Selected.png diff --git a/indra/newview/skins/contrast/textures/widgets/SegmentedBtn_Middle_Selected_Disabled.png b/indra/newview/skins/contrast/textures/widgets/SegmentedBtn_Middle_Selected_Disabled.png Binary files differnew file mode 100644 index 0000000000..26acf6fb65 --- /dev/null +++ b/indra/newview/skins/contrast/textures/widgets/SegmentedBtn_Middle_Selected_Disabled.png diff --git a/indra/newview/skins/contrast/textures/widgets/SegmentedBtn_Middle_Selected_Press.png b/indra/newview/skins/contrast/textures/widgets/SegmentedBtn_Middle_Selected_Press.png Binary files differnew file mode 100644 index 0000000000..f02ab3cc14 --- /dev/null +++ b/indra/newview/skins/contrast/textures/widgets/SegmentedBtn_Middle_Selected_Press.png diff --git a/indra/newview/skins/contrast/textures/widgets/SegmentedBtn_Right_Disabled.png b/indra/newview/skins/contrast/textures/widgets/SegmentedBtn_Right_Disabled.png Binary files differnew file mode 100644 index 0000000000..ecd2144d6d --- /dev/null +++ b/indra/newview/skins/contrast/textures/widgets/SegmentedBtn_Right_Disabled.png diff --git a/indra/newview/skins/contrast/textures/widgets/SegmentedBtn_Right_Off.png b/indra/newview/skins/contrast/textures/widgets/SegmentedBtn_Right_Off.png Binary files differnew file mode 100644 index 0000000000..1901d5e843 --- /dev/null +++ b/indra/newview/skins/contrast/textures/widgets/SegmentedBtn_Right_Off.png diff --git a/indra/newview/skins/contrast/textures/widgets/SegmentedBtn_Right_On_Selected.png b/indra/newview/skins/contrast/textures/widgets/SegmentedBtn_Right_On_Selected.png Binary files differnew file mode 100644 index 0000000000..5c4456a136 --- /dev/null +++ b/indra/newview/skins/contrast/textures/widgets/SegmentedBtn_Right_On_Selected.png diff --git a/indra/newview/skins/contrast/textures/widgets/SegmentedBtn_Right_Over.png b/indra/newview/skins/contrast/textures/widgets/SegmentedBtn_Right_Over.png Binary files differnew file mode 100644 index 0000000000..534c30cddc --- /dev/null +++ b/indra/newview/skins/contrast/textures/widgets/SegmentedBtn_Right_Over.png diff --git a/indra/newview/skins/contrast/textures/widgets/SegmentedBtn_Right_Press.png b/indra/newview/skins/contrast/textures/widgets/SegmentedBtn_Right_Press.png Binary files differnew file mode 100644 index 0000000000..a97612ce2f --- /dev/null +++ b/indra/newview/skins/contrast/textures/widgets/SegmentedBtn_Right_Press.png diff --git a/indra/newview/skins/contrast/textures/widgets/SegmentedBtn_Right_Selected.png b/indra/newview/skins/contrast/textures/widgets/SegmentedBtn_Right_Selected.png Binary files differnew file mode 100644 index 0000000000..a97612ce2f --- /dev/null +++ b/indra/newview/skins/contrast/textures/widgets/SegmentedBtn_Right_Selected.png diff --git a/indra/newview/skins/contrast/textures/widgets/SegmentedBtn_Right_Selected_Disabled.png b/indra/newview/skins/contrast/textures/widgets/SegmentedBtn_Right_Selected_Disabled.png Binary files differnew file mode 100644 index 0000000000..ca7551a267 --- /dev/null +++ b/indra/newview/skins/contrast/textures/widgets/SegmentedBtn_Right_Selected_Disabled.png diff --git a/indra/newview/skins/contrast/textures/widgets/SegmentedBtn_Right_Selected_Press.png b/indra/newview/skins/contrast/textures/widgets/SegmentedBtn_Right_Selected_Press.png Binary files differnew file mode 100644 index 0000000000..71fac19fbc --- /dev/null +++ b/indra/newview/skins/contrast/textures/widgets/SegmentedBtn_Right_Selected_Press.png diff --git a/indra/newview/skins/contrast/textures/widgets/SliderThumb_Disabled.png b/indra/newview/skins/contrast/textures/widgets/SliderThumb_Disabled.png Binary files differnew file mode 100644 index 0000000000..5cfa3ae4e1 --- /dev/null +++ b/indra/newview/skins/contrast/textures/widgets/SliderThumb_Disabled.png diff --git a/indra/newview/skins/contrast/textures/widgets/SliderThumb_Off.png b/indra/newview/skins/contrast/textures/widgets/SliderThumb_Off.png Binary files differnew file mode 100644 index 0000000000..66cdcbeb94 --- /dev/null +++ b/indra/newview/skins/contrast/textures/widgets/SliderThumb_Off.png diff --git a/indra/newview/skins/contrast/textures/widgets/SliderThumb_Press.png b/indra/newview/skins/contrast/textures/widgets/SliderThumb_Press.png Binary files differnew file mode 100644 index 0000000000..0bf8e43e81 --- /dev/null +++ b/indra/newview/skins/contrast/textures/widgets/SliderThumb_Press.png diff --git a/indra/newview/skins/contrast/textures/widgets/SliderTrack_Horiz.png b/indra/newview/skins/contrast/textures/widgets/SliderTrack_Horiz.png Binary files differnew file mode 100644 index 0000000000..720830f83f --- /dev/null +++ b/indra/newview/skins/contrast/textures/widgets/SliderTrack_Horiz.png diff --git a/indra/newview/skins/contrast/textures/widgets/SliderTrack_Vert.png b/indra/newview/skins/contrast/textures/widgets/SliderTrack_Vert.png Binary files differnew file mode 100644 index 0000000000..c01db44707 --- /dev/null +++ b/indra/newview/skins/contrast/textures/widgets/SliderTrack_Vert.png diff --git a/indra/newview/skins/contrast/textures/widgets/Stepper_Down_Off.png b/indra/newview/skins/contrast/textures/widgets/Stepper_Down_Off.png Binary files differnew file mode 100644 index 0000000000..ff21034095 --- /dev/null +++ b/indra/newview/skins/contrast/textures/widgets/Stepper_Down_Off.png diff --git a/indra/newview/skins/contrast/textures/widgets/Stepper_Down_Press.png b/indra/newview/skins/contrast/textures/widgets/Stepper_Down_Press.png Binary files differnew file mode 100644 index 0000000000..7349132503 --- /dev/null +++ b/indra/newview/skins/contrast/textures/widgets/Stepper_Down_Press.png diff --git a/indra/newview/skins/contrast/textures/widgets/Stepper_Up_Off.png b/indra/newview/skins/contrast/textures/widgets/Stepper_Up_Off.png Binary files differnew file mode 100644 index 0000000000..133845bdbc --- /dev/null +++ b/indra/newview/skins/contrast/textures/widgets/Stepper_Up_Off.png diff --git a/indra/newview/skins/contrast/textures/widgets/Stepper_Up_Press.png b/indra/newview/skins/contrast/textures/widgets/Stepper_Up_Press.png Binary files differnew file mode 100644 index 0000000000..3dce7733c2 --- /dev/null +++ b/indra/newview/skins/contrast/textures/widgets/Stepper_Up_Press.png diff --git a/indra/newview/skins/contrast/textures/widgets/TextField_Active.png b/indra/newview/skins/contrast/textures/widgets/TextField_Active.png Binary files differnew file mode 100644 index 0000000000..66c3867b81 --- /dev/null +++ b/indra/newview/skins/contrast/textures/widgets/TextField_Active.png diff --git a/indra/newview/skins/contrast/textures/widgets/TextField_Disabled.png b/indra/newview/skins/contrast/textures/widgets/TextField_Disabled.png Binary files differnew file mode 100644 index 0000000000..baf747f581 --- /dev/null +++ b/indra/newview/skins/contrast/textures/widgets/TextField_Disabled.png diff --git a/indra/newview/skins/contrast/textures/widgets/TextField_Off.png b/indra/newview/skins/contrast/textures/widgets/TextField_Off.png Binary files differnew file mode 100644 index 0000000000..a35562f950 --- /dev/null +++ b/indra/newview/skins/contrast/textures/widgets/TextField_Off.png diff --git a/indra/newview/skins/contrast/textures/widgets/TextField_Search_Active.png b/indra/newview/skins/contrast/textures/widgets/TextField_Search_Active.png Binary files differnew file mode 100644 index 0000000000..572535f1ab --- /dev/null +++ b/indra/newview/skins/contrast/textures/widgets/TextField_Search_Active.png diff --git a/indra/newview/skins/contrast/textures/widgets/TextField_Search_Disabled.png b/indra/newview/skins/contrast/textures/widgets/TextField_Search_Disabled.png Binary files differnew file mode 100644 index 0000000000..94b4b158f7 --- /dev/null +++ b/indra/newview/skins/contrast/textures/widgets/TextField_Search_Disabled.png diff --git a/indra/newview/skins/contrast/textures/widgets/TextField_Search_Highlight.png b/indra/newview/skins/contrast/textures/widgets/TextField_Search_Highlight.png Binary files differnew file mode 100644 index 0000000000..7768da04e8 --- /dev/null +++ b/indra/newview/skins/contrast/textures/widgets/TextField_Search_Highlight.png diff --git a/indra/newview/skins/contrast/textures/widgets/TextField_Search_Off.png b/indra/newview/skins/contrast/textures/widgets/TextField_Search_Off.png Binary files differnew file mode 100644 index 0000000000..fccd38c807 --- /dev/null +++ b/indra/newview/skins/contrast/textures/widgets/TextField_Search_Off.png diff --git a/indra/newview/skins/contrast/textures/widgets/Tooltip.png b/indra/newview/skins/contrast/textures/widgets/Tooltip.png Binary files differnew file mode 100644 index 0000000000..1be53bdaa2 --- /dev/null +++ b/indra/newview/skins/contrast/textures/widgets/Tooltip.png diff --git a/indra/newview/skins/contrast/textures/widgets/bevel_background.png b/indra/newview/skins/contrast/textures/widgets/bevel_background.png Binary files differnew file mode 100644 index 0000000000..6304124aec --- /dev/null +++ b/indra/newview/skins/contrast/textures/widgets/bevel_background.png diff --git a/indra/newview/skins/contrast/textures/widgets/buy_off.png b/indra/newview/skins/contrast/textures/widgets/buy_off.png Binary files differnew file mode 100644 index 0000000000..f623b501e2 --- /dev/null +++ b/indra/newview/skins/contrast/textures/widgets/buy_off.png diff --git a/indra/newview/skins/contrast/textures/widgets/buy_over.png b/indra/newview/skins/contrast/textures/widgets/buy_over.png Binary files differnew file mode 100644 index 0000000000..25d4173242 --- /dev/null +++ b/indra/newview/skins/contrast/textures/widgets/buy_over.png diff --git a/indra/newview/skins/contrast/textures/widgets/buy_press.png b/indra/newview/skins/contrast/textures/widgets/buy_press.png Binary files differnew file mode 100644 index 0000000000..3195431c84 --- /dev/null +++ b/indra/newview/skins/contrast/textures/widgets/buy_press.png diff --git a/indra/newview/skins/contrast/textures/widgets/horizontal_drag_handle.png b/indra/newview/skins/contrast/textures/widgets/horizontal_drag_handle.png Binary files differnew file mode 100644 index 0000000000..631d653968 --- /dev/null +++ b/indra/newview/skins/contrast/textures/widgets/horizontal_drag_handle.png diff --git a/indra/newview/skins/contrast/textures/widgets/jump_left_in.png b/indra/newview/skins/contrast/textures/widgets/jump_left_in.png Binary files differnew file mode 100644 index 0000000000..073606628c --- /dev/null +++ b/indra/newview/skins/contrast/textures/widgets/jump_left_in.png diff --git a/indra/newview/skins/contrast/textures/widgets/jump_left_out.png b/indra/newview/skins/contrast/textures/widgets/jump_left_out.png Binary files differnew file mode 100644 index 0000000000..71d5c5c36a --- /dev/null +++ b/indra/newview/skins/contrast/textures/widgets/jump_left_out.png diff --git a/indra/newview/skins/contrast/textures/widgets/jump_right_in.png b/indra/newview/skins/contrast/textures/widgets/jump_right_in.png Binary files differnew file mode 100644 index 0000000000..96f8501932 --- /dev/null +++ b/indra/newview/skins/contrast/textures/widgets/jump_right_in.png diff --git a/indra/newview/skins/contrast/textures/widgets/jump_right_out.png b/indra/newview/skins/contrast/textures/widgets/jump_right_out.png Binary files differnew file mode 100644 index 0000000000..9c02f5f649 --- /dev/null +++ b/indra/newview/skins/contrast/textures/widgets/jump_right_out.png diff --git a/indra/newview/skins/contrast/textures/widgets/track_control_moon_back.png b/indra/newview/skins/contrast/textures/widgets/track_control_moon_back.png Binary files differnew file mode 100644 index 0000000000..03d1e805e1 --- /dev/null +++ b/indra/newview/skins/contrast/textures/widgets/track_control_moon_back.png diff --git a/indra/newview/skins/contrast/textures/widgets/track_control_moon_front.png b/indra/newview/skins/contrast/textures/widgets/track_control_moon_front.png Binary files differnew file mode 100644 index 0000000000..cdc52fe08a --- /dev/null +++ b/indra/newview/skins/contrast/textures/widgets/track_control_moon_front.png diff --git a/indra/newview/skins/contrast/textures/widgets/track_control_rotate_bottom.png b/indra/newview/skins/contrast/textures/widgets/track_control_rotate_bottom.png Binary files differnew file mode 100644 index 0000000000..c08b54c269 --- /dev/null +++ b/indra/newview/skins/contrast/textures/widgets/track_control_rotate_bottom.png diff --git a/indra/newview/skins/contrast/textures/widgets/track_control_rotate_bottom_active.png b/indra/newview/skins/contrast/textures/widgets/track_control_rotate_bottom_active.png Binary files differnew file mode 100644 index 0000000000..a2b37d1b43 --- /dev/null +++ b/indra/newview/skins/contrast/textures/widgets/track_control_rotate_bottom_active.png diff --git a/indra/newview/skins/contrast/textures/widgets/track_control_rotate_left_side.png b/indra/newview/skins/contrast/textures/widgets/track_control_rotate_left_side.png Binary files differnew file mode 100644 index 0000000000..3439e8717f --- /dev/null +++ b/indra/newview/skins/contrast/textures/widgets/track_control_rotate_left_side.png diff --git a/indra/newview/skins/contrast/textures/widgets/track_control_rotate_left_side_active.png b/indra/newview/skins/contrast/textures/widgets/track_control_rotate_left_side_active.png Binary files differnew file mode 100644 index 0000000000..fa745175be --- /dev/null +++ b/indra/newview/skins/contrast/textures/widgets/track_control_rotate_left_side_active.png diff --git a/indra/newview/skins/contrast/textures/widgets/track_control_rotate_right_side.png b/indra/newview/skins/contrast/textures/widgets/track_control_rotate_right_side.png Binary files differnew file mode 100644 index 0000000000..f92fdb3d92 --- /dev/null +++ b/indra/newview/skins/contrast/textures/widgets/track_control_rotate_right_side.png diff --git a/indra/newview/skins/contrast/textures/widgets/track_control_rotate_right_side_active.png b/indra/newview/skins/contrast/textures/widgets/track_control_rotate_right_side_active.png Binary files differnew file mode 100644 index 0000000000..23571d6473 --- /dev/null +++ b/indra/newview/skins/contrast/textures/widgets/track_control_rotate_right_side_active.png diff --git a/indra/newview/skins/contrast/textures/widgets/track_control_rotate_top.png b/indra/newview/skins/contrast/textures/widgets/track_control_rotate_top.png Binary files differnew file mode 100644 index 0000000000..ae67084a7d --- /dev/null +++ b/indra/newview/skins/contrast/textures/widgets/track_control_rotate_top.png diff --git a/indra/newview/skins/contrast/textures/widgets/track_control_rotate_top_active.png b/indra/newview/skins/contrast/textures/widgets/track_control_rotate_top_active.png Binary files differnew file mode 100644 index 0000000000..4e1d0ad096 --- /dev/null +++ b/indra/newview/skins/contrast/textures/widgets/track_control_rotate_top_active.png diff --git a/indra/newview/skins/contrast/textures/widgets/track_control_sphere.png b/indra/newview/skins/contrast/textures/widgets/track_control_sphere.png Binary files differnew file mode 100644 index 0000000000..6ba8d3877f --- /dev/null +++ b/indra/newview/skins/contrast/textures/widgets/track_control_sphere.png diff --git a/indra/newview/skins/contrast/textures/widgets/track_control_sun_back.png b/indra/newview/skins/contrast/textures/widgets/track_control_sun_back.png Binary files differnew file mode 100644 index 0000000000..b3191ccc5d --- /dev/null +++ b/indra/newview/skins/contrast/textures/widgets/track_control_sun_back.png diff --git a/indra/newview/skins/contrast/textures/widgets/track_control_sun_front.png b/indra/newview/skins/contrast/textures/widgets/track_control_sun_front.png Binary files differnew file mode 100644 index 0000000000..1cdcbf7861 --- /dev/null +++ b/indra/newview/skins/contrast/textures/widgets/track_control_sun_front.png diff --git a/indra/newview/skins/contrast/textures/widgets/vertical_drag_handle.png b/indra/newview/skins/contrast/textures/widgets/vertical_drag_handle.png Binary files differnew file mode 100644 index 0000000000..d78e898a9c --- /dev/null +++ b/indra/newview/skins/contrast/textures/widgets/vertical_drag_handle.png diff --git a/indra/newview/skins/contrast/textures/windows/Dragbar.png b/indra/newview/skins/contrast/textures/windows/Dragbar.png Binary files differnew file mode 100644 index 0000000000..3a998abdc3 --- /dev/null +++ b/indra/newview/skins/contrast/textures/windows/Dragbar.png diff --git a/indra/newview/skins/contrast/textures/windows/Flyout_Left.png b/indra/newview/skins/contrast/textures/windows/Flyout_Left.png Binary files differnew file mode 100644 index 0000000000..3110d7f6b5 --- /dev/null +++ b/indra/newview/skins/contrast/textures/windows/Flyout_Left.png diff --git a/indra/newview/skins/contrast/textures/windows/Flyout_Pointer.png b/indra/newview/skins/contrast/textures/windows/Flyout_Pointer.png Binary files differnew file mode 100644 index 0000000000..4076bb393e --- /dev/null +++ b/indra/newview/skins/contrast/textures/windows/Flyout_Pointer.png diff --git a/indra/newview/skins/contrast/textures/windows/Flyout_Right.png b/indra/newview/skins/contrast/textures/windows/Flyout_Right.png Binary files differnew file mode 100644 index 0000000000..4c55cd6287 --- /dev/null +++ b/indra/newview/skins/contrast/textures/windows/Flyout_Right.png diff --git a/indra/newview/skins/contrast/textures/windows/Icon_Close_Foreground.png b/indra/newview/skins/contrast/textures/windows/Icon_Close_Foreground.png Binary files differnew file mode 100644 index 0000000000..cb516886a2 --- /dev/null +++ b/indra/newview/skins/contrast/textures/windows/Icon_Close_Foreground.png diff --git a/indra/newview/skins/contrast/textures/windows/Icon_Close_Press.png b/indra/newview/skins/contrast/textures/windows/Icon_Close_Press.png Binary files differnew file mode 100644 index 0000000000..283981f6ea --- /dev/null +++ b/indra/newview/skins/contrast/textures/windows/Icon_Close_Press.png diff --git a/indra/newview/skins/contrast/textures/windows/Icon_Close_Toast.png b/indra/newview/skins/contrast/textures/windows/Icon_Close_Toast.png Binary files differnew file mode 100644 index 0000000000..b08ffbc742 --- /dev/null +++ b/indra/newview/skins/contrast/textures/windows/Icon_Close_Toast.png diff --git a/indra/newview/skins/contrast/textures/windows/Icon_Dock_Foreground.png b/indra/newview/skins/contrast/textures/windows/Icon_Dock_Foreground.png Binary files differnew file mode 100644 index 0000000000..7508fcb25e --- /dev/null +++ b/indra/newview/skins/contrast/textures/windows/Icon_Dock_Foreground.png diff --git a/indra/newview/skins/contrast/textures/windows/Icon_Dock_Press.png b/indra/newview/skins/contrast/textures/windows/Icon_Dock_Press.png Binary files differnew file mode 100644 index 0000000000..3f2c560398 --- /dev/null +++ b/indra/newview/skins/contrast/textures/windows/Icon_Dock_Press.png diff --git a/indra/newview/skins/contrast/textures/windows/Icon_Gear.png b/indra/newview/skins/contrast/textures/windows/Icon_Gear.png Binary files differnew file mode 100644 index 0000000000..7cf85bece4 --- /dev/null +++ b/indra/newview/skins/contrast/textures/windows/Icon_Gear.png diff --git a/indra/newview/skins/contrast/textures/windows/Icon_Gear_Background.png b/indra/newview/skins/contrast/textures/windows/Icon_Gear_Background.png Binary files differnew file mode 100644 index 0000000000..09d83e62e4 --- /dev/null +++ b/indra/newview/skins/contrast/textures/windows/Icon_Gear_Background.png diff --git a/indra/newview/skins/contrast/textures/windows/Icon_Gear_Foreground.png b/indra/newview/skins/contrast/textures/windows/Icon_Gear_Foreground.png Binary files differnew file mode 100644 index 0000000000..fa998eee5d --- /dev/null +++ b/indra/newview/skins/contrast/textures/windows/Icon_Gear_Foreground.png diff --git a/indra/newview/skins/contrast/textures/windows/Icon_Gear_Press.png b/indra/newview/skins/contrast/textures/windows/Icon_Gear_Press.png Binary files differnew file mode 100644 index 0000000000..603fa2f388 --- /dev/null +++ b/indra/newview/skins/contrast/textures/windows/Icon_Gear_Press.png diff --git a/indra/newview/skins/contrast/textures/windows/Icon_Help_Foreground.png b/indra/newview/skins/contrast/textures/windows/Icon_Help_Foreground.png Binary files differnew file mode 100644 index 0000000000..1bde4c040a --- /dev/null +++ b/indra/newview/skins/contrast/textures/windows/Icon_Help_Foreground.png diff --git a/indra/newview/skins/contrast/textures/windows/Icon_Help_Press.png b/indra/newview/skins/contrast/textures/windows/Icon_Help_Press.png Binary files differnew file mode 100644 index 0000000000..f3b885283f --- /dev/null +++ b/indra/newview/skins/contrast/textures/windows/Icon_Help_Press.png diff --git a/indra/newview/skins/contrast/textures/windows/Icon_Minimize_Foreground.png b/indra/newview/skins/contrast/textures/windows/Icon_Minimize_Foreground.png Binary files differnew file mode 100644 index 0000000000..942efb40f7 --- /dev/null +++ b/indra/newview/skins/contrast/textures/windows/Icon_Minimize_Foreground.png diff --git a/indra/newview/skins/contrast/textures/windows/Icon_Minimize_Press.png b/indra/newview/skins/contrast/textures/windows/Icon_Minimize_Press.png Binary files differnew file mode 100644 index 0000000000..1fe37b7a2e --- /dev/null +++ b/indra/newview/skins/contrast/textures/windows/Icon_Minimize_Press.png diff --git a/indra/newview/skins/contrast/textures/windows/Icon_Restore_Foreground.png b/indra/newview/skins/contrast/textures/windows/Icon_Restore_Foreground.png Binary files differnew file mode 100644 index 0000000000..7840deccb8 --- /dev/null +++ b/indra/newview/skins/contrast/textures/windows/Icon_Restore_Foreground.png diff --git a/indra/newview/skins/contrast/textures/windows/Icon_Restore_Press.png b/indra/newview/skins/contrast/textures/windows/Icon_Restore_Press.png Binary files differnew file mode 100644 index 0000000000..33258a0bc5 --- /dev/null +++ b/indra/newview/skins/contrast/textures/windows/Icon_Restore_Press.png diff --git a/indra/newview/skins/contrast/textures/windows/Icon_Undock_Foreground.png b/indra/newview/skins/contrast/textures/windows/Icon_Undock_Foreground.png Binary files differnew file mode 100644 index 0000000000..df826226e6 --- /dev/null +++ b/indra/newview/skins/contrast/textures/windows/Icon_Undock_Foreground.png diff --git a/indra/newview/skins/contrast/textures/windows/Inspector_Background.png b/indra/newview/skins/contrast/textures/windows/Inspector_Background.png Binary files differnew file mode 100644 index 0000000000..3053269b84 --- /dev/null +++ b/indra/newview/skins/contrast/textures/windows/Inspector_Background.png diff --git a/indra/newview/skins/contrast/textures/windows/Inspector_Hover.png b/indra/newview/skins/contrast/textures/windows/Inspector_Hover.png Binary files differnew file mode 100644 index 0000000000..0cb846eba0 --- /dev/null +++ b/indra/newview/skins/contrast/textures/windows/Inspector_Hover.png diff --git a/indra/newview/skins/contrast/textures/windows/Inspector_I.png b/indra/newview/skins/contrast/textures/windows/Inspector_I.png Binary files differnew file mode 100644 index 0000000000..e5899c55a7 --- /dev/null +++ b/indra/newview/skins/contrast/textures/windows/Inspector_I.png diff --git a/indra/newview/skins/contrast/textures/windows/Resize_Corner.png b/indra/newview/skins/contrast/textures/windows/Resize_Corner.png Binary files differnew file mode 100644 index 0000000000..4a533011df --- /dev/null +++ b/indra/newview/skins/contrast/textures/windows/Resize_Corner.png diff --git a/indra/newview/skins/contrast/textures/windows/Toast_Background.png b/indra/newview/skins/contrast/textures/windows/Toast_Background.png Binary files differnew file mode 100644 index 0000000000..00676350ca --- /dev/null +++ b/indra/newview/skins/contrast/textures/windows/Toast_Background.png diff --git a/indra/newview/skins/contrast/textures/windows/Toast_CloseBtn.png b/indra/newview/skins/contrast/textures/windows/Toast_CloseBtn.png Binary files differnew file mode 100644 index 0000000000..f37d8d085d --- /dev/null +++ b/indra/newview/skins/contrast/textures/windows/Toast_CloseBtn.png diff --git a/indra/newview/skins/contrast/textures/windows/Toast_Over.png b/indra/newview/skins/contrast/textures/windows/Toast_Over.png Binary files differnew file mode 100644 index 0000000000..5191e0858d --- /dev/null +++ b/indra/newview/skins/contrast/textures/windows/Toast_Over.png diff --git a/indra/newview/skins/contrast/textures/windows/Volume_Background.png b/indra/newview/skins/contrast/textures/windows/Volume_Background.png Binary files differnew file mode 100644 index 0000000000..439e9fd2a1 --- /dev/null +++ b/indra/newview/skins/contrast/textures/windows/Volume_Background.png diff --git a/indra/newview/skins/contrast/textures/windows/Wearables_Divider.png b/indra/newview/skins/contrast/textures/windows/Wearables_Divider.png Binary files differnew file mode 100644 index 0000000000..8795ccd661 --- /dev/null +++ b/indra/newview/skins/contrast/textures/windows/Wearables_Divider.png diff --git a/indra/newview/skins/contrast/textures/windows/Window_Background.png b/indra/newview/skins/contrast/textures/windows/Window_Background.png Binary files differnew file mode 100644 index 0000000000..1df5943e1b --- /dev/null +++ b/indra/newview/skins/contrast/textures/windows/Window_Background.png diff --git a/indra/newview/skins/contrast/textures/windows/Window_Foreground.png b/indra/newview/skins/contrast/textures/windows/Window_Foreground.png Binary files differnew file mode 100644 index 0000000000..988ec48eb7 --- /dev/null +++ b/indra/newview/skins/contrast/textures/windows/Window_Foreground.png diff --git a/indra/newview/skins/contrast/textures/windows/add_payment_image_center.png b/indra/newview/skins/contrast/textures/windows/add_payment_image_center.png Binary files differnew file mode 100644 index 0000000000..0b99a72f32 --- /dev/null +++ b/indra/newview/skins/contrast/textures/windows/add_payment_image_center.png diff --git a/indra/newview/skins/contrast/textures/windows/add_payment_image_left.png b/indra/newview/skins/contrast/textures/windows/add_payment_image_left.png Binary files differnew file mode 100644 index 0000000000..a5b28d7023 --- /dev/null +++ b/indra/newview/skins/contrast/textures/windows/add_payment_image_left.png diff --git a/indra/newview/skins/contrast/textures/windows/add_payment_image_right.png b/indra/newview/skins/contrast/textures/windows/add_payment_image_right.png Binary files differnew file mode 100644 index 0000000000..5724d39744 --- /dev/null +++ b/indra/newview/skins/contrast/textures/windows/add_payment_image_right.png diff --git a/indra/newview/skins/contrast/textures/windows/first_login_image.jpg b/indra/newview/skins/contrast/textures/windows/first_login_image.jpg Binary files differnew file mode 100644 index 0000000000..860fed4ac7 --- /dev/null +++ b/indra/newview/skins/contrast/textures/windows/first_login_image.jpg diff --git a/indra/newview/skins/contrast/textures/windows/hint_arrow_down.png b/indra/newview/skins/contrast/textures/windows/hint_arrow_down.png Binary files differnew file mode 100644 index 0000000000..b449d3be7c --- /dev/null +++ b/indra/newview/skins/contrast/textures/windows/hint_arrow_down.png diff --git a/indra/newview/skins/contrast/textures/windows/hint_arrow_left.png b/indra/newview/skins/contrast/textures/windows/hint_arrow_left.png Binary files differnew file mode 100644 index 0000000000..d93d621067 --- /dev/null +++ b/indra/newview/skins/contrast/textures/windows/hint_arrow_left.png diff --git a/indra/newview/skins/contrast/textures/windows/hint_arrow_lower_left.png b/indra/newview/skins/contrast/textures/windows/hint_arrow_lower_left.png Binary files differnew file mode 100644 index 0000000000..5e8def5a5b --- /dev/null +++ b/indra/newview/skins/contrast/textures/windows/hint_arrow_lower_left.png diff --git a/indra/newview/skins/contrast/textures/windows/hint_arrow_right.png b/indra/newview/skins/contrast/textures/windows/hint_arrow_right.png Binary files differnew file mode 100644 index 0000000000..3524487fb3 --- /dev/null +++ b/indra/newview/skins/contrast/textures/windows/hint_arrow_right.png diff --git a/indra/newview/skins/contrast/textures/windows/hint_arrow_up.png b/indra/newview/skins/contrast/textures/windows/hint_arrow_up.png Binary files differnew file mode 100644 index 0000000000..aca440d712 --- /dev/null +++ b/indra/newview/skins/contrast/textures/windows/hint_arrow_up.png diff --git a/indra/newview/skins/contrast/textures/windows/hint_background.png b/indra/newview/skins/contrast/textures/windows/hint_background.png Binary files differnew file mode 100644 index 0000000000..d045bc5e29 --- /dev/null +++ b/indra/newview/skins/contrast/textures/windows/hint_background.png diff --git a/indra/newview/skins/contrast/textures/windows/login_mp_logo.png b/indra/newview/skins/contrast/textures/windows/login_mp_logo.png Binary files differnew file mode 100644 index 0000000000..7526374ba2 --- /dev/null +++ b/indra/newview/skins/contrast/textures/windows/login_mp_logo.png diff --git a/indra/newview/skins/contrast/textures/windows/login_mp_logo_small.png b/indra/newview/skins/contrast/textures/windows/login_mp_logo_small.png Binary files differnew file mode 100644 index 0000000000..779d8ff649 --- /dev/null +++ b/indra/newview/skins/contrast/textures/windows/login_mp_logo_small.png diff --git a/indra/newview/skins/contrast/textures/windows/login_sl_logo.png b/indra/newview/skins/contrast/textures/windows/login_sl_logo.png Binary files differnew file mode 100644 index 0000000000..e4d4eb3ebf --- /dev/null +++ b/indra/newview/skins/contrast/textures/windows/login_sl_logo.png diff --git a/indra/newview/skins/contrast/textures/windows/login_sl_logo_small.png b/indra/newview/skins/contrast/textures/windows/login_sl_logo_small.png Binary files differnew file mode 100644 index 0000000000..36fb15de08 --- /dev/null +++ b/indra/newview/skins/contrast/textures/windows/login_sl_logo_small.png diff --git a/indra/newview/skins/contrast/textures/windows/startup_logo.png b/indra/newview/skins/contrast/textures/windows/startup_logo.png Binary files differnew file mode 100644 index 0000000000..6a81a6451d --- /dev/null +++ b/indra/newview/skins/contrast/textures/windows/startup_logo.png diff --git a/indra/newview/skins/contrast/textures/windows/yellow_gradient.png b/indra/newview/skins/contrast/textures/windows/yellow_gradient.png Binary files differnew file mode 100644 index 0000000000..4a07282ecb --- /dev/null +++ b/indra/newview/skins/contrast/textures/windows/yellow_gradient.png diff --git a/indra/newview/skins/contrast/textures/world/BeaconArrow.png b/indra/newview/skins/contrast/textures/world/BeaconArrow.png Binary files differnew file mode 100644 index 0000000000..54934f738a --- /dev/null +++ b/indra/newview/skins/contrast/textures/world/BeaconArrow.png diff --git a/indra/newview/skins/contrast/textures/world/CameraDragDot.png b/indra/newview/skins/contrast/textures/world/CameraDragDot.png Binary files differnew file mode 100644 index 0000000000..2ccf098e0f --- /dev/null +++ b/indra/newview/skins/contrast/textures/world/CameraDragDot.png diff --git a/indra/newview/skins/contrast/textures/world/NoEntryLines.png b/indra/newview/skins/contrast/textures/world/NoEntryLines.png Binary files differnew file mode 100644 index 0000000000..b295ba1281 --- /dev/null +++ b/indra/newview/skins/contrast/textures/world/NoEntryLines.png diff --git a/indra/newview/skins/contrast/textures/world/NoEntryPassLines.png b/indra/newview/skins/contrast/textures/world/NoEntryPassLines.png Binary files differnew file mode 100644 index 0000000000..34900e2c02 --- /dev/null +++ b/indra/newview/skins/contrast/textures/world/NoEntryPassLines.png diff --git a/indra/newview/skins/default/colors.xml b/indra/newview/skins/default/colors.xml index 92f63a1820..bc9aef8974 100644 --- a/indra/newview/skins/default/colors.xml +++ b/indra/newview/skins/default/colors.xml @@ -4,13 +4,13 @@ <!-- Named Colors --> <color name="EmphasisColor" - value="0.38 0.694 0.573 1" /> + value="0.25 0.48 0.70 1" /> <color name="EmphasisColor_13" - value="0.38 0.694 0.573 0.13" /> + value="0.25 0.48 0.70 0.13" /> <color name="EmphasisColor_35" - value="0.38 0.694 0.573 0.35" /> + value="0.25 0.48 0.70 0.35" /> <color name="BeaconColor" value="0.749 0.298 0 1" /> @@ -70,7 +70,8 @@ value="0 0 0 0.5" /> <color name="FrogGreen" - value="0.26 0.345 0.263 1" /> + value="0.26 0.33 0.42 1" /> + <!-- ^(Not actually green) --> <color name="Red" value="1 0 0 1" /> @@ -338,7 +339,7 @@ reference="EmphasisColor" /> <color name="ConversationFriendColor" - value="0.42 0.85 0.71 1" /> + value="0.5 0.7 0.85 1" /> <color name="DefaultHighlightDark" reference="White_10" /> @@ -359,7 +360,7 @@ reference="Black" /> <color name="FilterTextColor" - value="0.38 0.69 0.57 1" /> + reference="EmphasisColor" /> <color name="FloaterButtonImageColor" reference="LtGray" /> @@ -380,7 +381,10 @@ reference="EmphasisColor" /> <color name="FolderViewLoadingMessageTextColor" - value="0.3344 0.5456 0.5159 1" /> + value="0.3344 0.545 0.645 1" /> + <color + name="FpsTextColor" + value="0.34 0.51 0.64 0.8" /> <color name="GridFocusPointColor" reference="White_50" /> @@ -407,7 +411,7 @@ value="0.43 0.06 0.06 1" /> <color name="HTMLLinkColor" - value="0.3 0.82 1 1" /> + reference="EmphasisColor" /> <color name="HealthTextColor" reference="White" /> @@ -437,7 +441,7 @@ value="1 0 1 1" /> <color name="HighlightParentColor" - value="0.67 0.83 0.96 1" /> + value="0.5 0.65 0.8 1" /> <color name="IMHistoryBgColor" reference="Unused?" /> @@ -503,10 +507,10 @@ reference="White" /> <color name="MapAvatarColor" - reference="Green" /> + reference="White" /> <color name="MapAvatarFriendColor" - reference="Yellow" /> + value="0.5 0.7 0.85 1" /> <color name="MapAvatarSelfColor" value="0.53125 0 0.498047 1" /> @@ -515,7 +519,7 @@ reference="White_10" /> <color name="MapParcelOutlineColor" - value="1 1 0 0.5" /> + value="1 1 1 0.5" /> <color name="MapTrackColor" reference="Red" /> @@ -527,7 +531,7 @@ value="0.5 0 0 1" /> <color name="MenuBarBgColor" - reference="DkGray" /> + reference="MouseGray" /> <color name="MenuBarGodBgColor" reference="FrogGreen" /> @@ -592,7 +596,7 @@ reference="White" /> <color name="NameTagFriend" - value="0.447 0.784 0.663 1" /> + value="0.5 0.7 0.85 1" /> <color name="NameTagLegacy" reference="White" /> @@ -640,7 +644,7 @@ reference="DkGray_66" /> <color name="ObjectChatColor" - reference="EmphasisColor" /> + reference="LtYellow" /> <color name="OverdrivenColor" reference="Red" /> @@ -759,6 +763,12 @@ name="SelectedOutfitTextColor" reference="EmphasisColor" /> <color + name="SearchableControlHighlightFontColor" + value="1 0 0 1" /> + <color + name="SearchableControlHighlightBgColor" + value="0.5 0.1 0.1 1" /> + <color name="SilhouetteChildColor" value="0.13 0.42 0.77 1" /> <color @@ -835,10 +845,10 @@ reference="LtGray" /> <color name="UserChatColor" - reference="Yellow" /> + reference="White" /> <color name="llOwnerSayChatColor" - reference="LtYellow" /> + reference="LtOrange" /> <!-- New Colors --> <color @@ -975,10 +985,10 @@ value="1 0.14 0 1" /> <color name="OutfitGalleryItemSelected" - value="0.22 0.45 0.35 1" /> + reference="EmphasisColor_35" /> <color name="OutfitGalleryItemWorn" - value="0.33 0.58 0.47 1" /> + reference="EmphasisColor_13" /> <color name="OutfitGalleryItemUnselected" value="0.4 0.4 0.4 1" /> diff --git a/indra/newview/skins/default/textures/3p_icons/fmod_logo.png b/indra/newview/skins/default/textures/3p_icons/fmod_logo.png Binary files differdeleted file mode 100644 index 5a50e0ad34..0000000000 --- a/indra/newview/skins/default/textures/3p_icons/fmod_logo.png +++ /dev/null diff --git a/indra/newview/skins/default/textures/3p_icons/havok_logo.png b/indra/newview/skins/default/textures/3p_icons/havok_logo.png Binary files differdeleted file mode 100644 index ff1ea3a72e..0000000000 --- a/indra/newview/skins/default/textures/3p_icons/havok_logo.png +++ /dev/null diff --git a/indra/newview/skins/default/textures/3p_icons/vivox_logo.png b/indra/newview/skins/default/textures/3p_icons/vivox_logo.png Binary files differdeleted file mode 100644 index 6f20e87b7a..0000000000 --- a/indra/newview/skins/default/textures/3p_icons/vivox_logo.png +++ /dev/null diff --git a/indra/newview/skins/default/textures/bottomtray/Cam_Rotate_Center.png b/indra/newview/skins/default/textures/bottomtray/Cam_Rotate_Center.png Binary files differindex ffc3c85ea2..5f25281518 100644 --- a/indra/newview/skins/default/textures/bottomtray/Cam_Rotate_Center.png +++ b/indra/newview/skins/default/textures/bottomtray/Cam_Rotate_Center.png diff --git a/indra/newview/skins/default/textures/bottomtray/Cam_Rotate_In.png b/indra/newview/skins/default/textures/bottomtray/Cam_Rotate_In.png Binary files differindex c8560c0869..1df7618a2b 100644 --- a/indra/newview/skins/default/textures/bottomtray/Cam_Rotate_In.png +++ b/indra/newview/skins/default/textures/bottomtray/Cam_Rotate_In.png diff --git a/indra/newview/skins/default/textures/bottomtray/Cam_Rotate_Out.png b/indra/newview/skins/default/textures/bottomtray/Cam_Rotate_Out.png Binary files differindex b09f7c64d3..cc4e6f99ff 100644 --- a/indra/newview/skins/default/textures/bottomtray/Cam_Rotate_Out.png +++ b/indra/newview/skins/default/textures/bottomtray/Cam_Rotate_Out.png diff --git a/indra/newview/skins/default/textures/bottomtray/Cam_Tracking_Center.png b/indra/newview/skins/default/textures/bottomtray/Cam_Tracking_Center.png Binary files differindex 2812d614e6..82e6806af6 100644 --- a/indra/newview/skins/default/textures/bottomtray/Cam_Tracking_Center.png +++ b/indra/newview/skins/default/textures/bottomtray/Cam_Tracking_Center.png diff --git a/indra/newview/skins/default/textures/bottomtray/Cam_Tracking_In.png b/indra/newview/skins/default/textures/bottomtray/Cam_Tracking_In.png Binary files differindex ae2c57c207..338062c083 100644 --- a/indra/newview/skins/default/textures/bottomtray/Cam_Tracking_In.png +++ b/indra/newview/skins/default/textures/bottomtray/Cam_Tracking_In.png diff --git a/indra/newview/skins/default/textures/bottomtray/Cam_Tracking_Out.png b/indra/newview/skins/default/textures/bottomtray/Cam_Tracking_Out.png Binary files differindex c5cd8cca92..cffead1703 100644 --- a/indra/newview/skins/default/textures/bottomtray/Cam_Tracking_Out.png +++ b/indra/newview/skins/default/textures/bottomtray/Cam_Tracking_Out.png diff --git a/indra/newview/skins/default/textures/bottomtray/Movement_Backward_On.png b/indra/newview/skins/default/textures/bottomtray/Movement_Backward_On.png Binary files differindex 9f31d461b5..a2ac8bd8c6 100644 --- a/indra/newview/skins/default/textures/bottomtray/Movement_Backward_On.png +++ b/indra/newview/skins/default/textures/bottomtray/Movement_Backward_On.png diff --git a/indra/newview/skins/default/textures/bottomtray/Movement_Down_On.png b/indra/newview/skins/default/textures/bottomtray/Movement_Down_On.png Binary files differindex f7ed4c25fb..0cb73798b3 100644 --- a/indra/newview/skins/default/textures/bottomtray/Movement_Down_On.png +++ b/indra/newview/skins/default/textures/bottomtray/Movement_Down_On.png diff --git a/indra/newview/skins/default/textures/bottomtray/Movement_Forward_On.png b/indra/newview/skins/default/textures/bottomtray/Movement_Forward_On.png Binary files differindex d0a825a682..83df78e8f3 100644 --- a/indra/newview/skins/default/textures/bottomtray/Movement_Forward_On.png +++ b/indra/newview/skins/default/textures/bottomtray/Movement_Forward_On.png diff --git a/indra/newview/skins/default/textures/bottomtray/Movement_Left_On.png b/indra/newview/skins/default/textures/bottomtray/Movement_Left_On.png Binary files differindex 2f81fb1588..be7366a2a8 100644 --- a/indra/newview/skins/default/textures/bottomtray/Movement_Left_On.png +++ b/indra/newview/skins/default/textures/bottomtray/Movement_Left_On.png diff --git a/indra/newview/skins/default/textures/bottomtray/Movement_Right_On.png b/indra/newview/skins/default/textures/bottomtray/Movement_Right_On.png Binary files differindex 4f86e81a15..32bdb8a034 100644 --- a/indra/newview/skins/default/textures/bottomtray/Movement_Right_On.png +++ b/indra/newview/skins/default/textures/bottomtray/Movement_Right_On.png diff --git a/indra/newview/skins/default/textures/bottomtray/Movement_TurnLeft_On.png b/indra/newview/skins/default/textures/bottomtray/Movement_TurnLeft_On.png Binary files differindex b211371e64..168af4bac5 100644 --- a/indra/newview/skins/default/textures/bottomtray/Movement_TurnLeft_On.png +++ b/indra/newview/skins/default/textures/bottomtray/Movement_TurnLeft_On.png diff --git a/indra/newview/skins/default/textures/bottomtray/Movement_TurnRight_On.png b/indra/newview/skins/default/textures/bottomtray/Movement_TurnRight_On.png Binary files differindex e937c3f012..803ce250e7 100644 --- a/indra/newview/skins/default/textures/bottomtray/Movement_TurnRight_On.png +++ b/indra/newview/skins/default/textures/bottomtray/Movement_TurnRight_On.png diff --git a/indra/newview/skins/default/textures/bottomtray/Movement_Up_On.png b/indra/newview/skins/default/textures/bottomtray/Movement_Up_On.png Binary files differindex ed4902f3ee..3b7f83fbab 100644 --- a/indra/newview/skins/default/textures/bottomtray/Movement_Up_On.png +++ b/indra/newview/skins/default/textures/bottomtray/Movement_Up_On.png diff --git a/indra/newview/skins/default/textures/bottomtray/VoicePTT_Lvl1.png b/indra/newview/skins/default/textures/bottomtray/VoicePTT_Lvl1.png Binary files differindex cd18ae310d..438b4912f8 100644 --- a/indra/newview/skins/default/textures/bottomtray/VoicePTT_Lvl1.png +++ b/indra/newview/skins/default/textures/bottomtray/VoicePTT_Lvl1.png diff --git a/indra/newview/skins/default/textures/bottomtray/VoicePTT_Lvl2.png b/indra/newview/skins/default/textures/bottomtray/VoicePTT_Lvl2.png Binary files differindex b0ed6ee8eb..693adc4781 100644 --- a/indra/newview/skins/default/textures/bottomtray/VoicePTT_Lvl2.png +++ b/indra/newview/skins/default/textures/bottomtray/VoicePTT_Lvl2.png diff --git a/indra/newview/skins/default/textures/bottomtray/VoicePTT_On.png b/indra/newview/skins/default/textures/bottomtray/VoicePTT_On.png Binary files differindex be4881b64c..818b34d40f 100644 --- a/indra/newview/skins/default/textures/bottomtray/VoicePTT_On.png +++ b/indra/newview/skins/default/textures/bottomtray/VoicePTT_On.png diff --git a/indra/newview/skins/default/textures/bottomtray/WellButton_Lit.png b/indra/newview/skins/default/textures/bottomtray/WellButton_Lit.png Binary files differindex 6cb33efb93..84711ddc29 100644 --- a/indra/newview/skins/default/textures/bottomtray/WellButton_Lit.png +++ b/indra/newview/skins/default/textures/bottomtray/WellButton_Lit.png diff --git a/indra/newview/skins/default/textures/bottomtray/WellButton_Lit_Selected.png b/indra/newview/skins/default/textures/bottomtray/WellButton_Lit_Selected.png Binary files differindex 6cb33efb93..9b9468c574 100644 --- a/indra/newview/skins/default/textures/bottomtray/WellButton_Lit_Selected.png +++ b/indra/newview/skins/default/textures/bottomtray/WellButton_Lit_Selected.png diff --git a/indra/newview/skins/default/textures/build/Object_Cone_Selected.png b/indra/newview/skins/default/textures/build/Object_Cone_Selected.png Binary files differindex d50dc69ffe..0f04cb2f28 100644 --- a/indra/newview/skins/default/textures/build/Object_Cone_Selected.png +++ b/indra/newview/skins/default/textures/build/Object_Cone_Selected.png diff --git a/indra/newview/skins/default/textures/build/Object_Cube_Selected.png b/indra/newview/skins/default/textures/build/Object_Cube_Selected.png Binary files differindex 3d6964530d..2a10237771 100644 --- a/indra/newview/skins/default/textures/build/Object_Cube_Selected.png +++ b/indra/newview/skins/default/textures/build/Object_Cube_Selected.png diff --git a/indra/newview/skins/default/textures/build/Object_Cylinder_Selected.png b/indra/newview/skins/default/textures/build/Object_Cylinder_Selected.png Binary files differindex 3ed0389961..ee6db5d64e 100644 --- a/indra/newview/skins/default/textures/build/Object_Cylinder_Selected.png +++ b/indra/newview/skins/default/textures/build/Object_Cylinder_Selected.png diff --git a/indra/newview/skins/default/textures/build/Object_Grass_Selected.png b/indra/newview/skins/default/textures/build/Object_Grass_Selected.png Binary files differindex 3ebd5ea7a1..37f35f9339 100644 --- a/indra/newview/skins/default/textures/build/Object_Grass_Selected.png +++ b/indra/newview/skins/default/textures/build/Object_Grass_Selected.png diff --git a/indra/newview/skins/default/textures/build/Object_Hemi_Cone_Selected.png b/indra/newview/skins/default/textures/build/Object_Hemi_Cone_Selected.png Binary files differindex 3bdc4d1fd5..ad6ba66bed 100644 --- a/indra/newview/skins/default/textures/build/Object_Hemi_Cone_Selected.png +++ b/indra/newview/skins/default/textures/build/Object_Hemi_Cone_Selected.png diff --git a/indra/newview/skins/default/textures/build/Object_Hemi_Cylinder_Selected.png b/indra/newview/skins/default/textures/build/Object_Hemi_Cylinder_Selected.png Binary files differindex 0912442e29..03a47494f5 100644 --- a/indra/newview/skins/default/textures/build/Object_Hemi_Cylinder_Selected.png +++ b/indra/newview/skins/default/textures/build/Object_Hemi_Cylinder_Selected.png diff --git a/indra/newview/skins/default/textures/build/Object_Hemi_Sphere_Selected.png b/indra/newview/skins/default/textures/build/Object_Hemi_Sphere_Selected.png Binary files differindex 33db4a2de8..daefae7389 100644 --- a/indra/newview/skins/default/textures/build/Object_Hemi_Sphere_Selected.png +++ b/indra/newview/skins/default/textures/build/Object_Hemi_Sphere_Selected.png diff --git a/indra/newview/skins/default/textures/build/Object_Prism_Selected.png b/indra/newview/skins/default/textures/build/Object_Prism_Selected.png Binary files differindex 9e80fe2b84..73470c7af9 100644 --- a/indra/newview/skins/default/textures/build/Object_Prism_Selected.png +++ b/indra/newview/skins/default/textures/build/Object_Prism_Selected.png diff --git a/indra/newview/skins/default/textures/build/Object_Pyramid_Selected.png b/indra/newview/skins/default/textures/build/Object_Pyramid_Selected.png Binary files differindex d36bfa55d4..361c915231 100644 --- a/indra/newview/skins/default/textures/build/Object_Pyramid_Selected.png +++ b/indra/newview/skins/default/textures/build/Object_Pyramid_Selected.png diff --git a/indra/newview/skins/default/textures/build/Object_Ring_Selected.png b/indra/newview/skins/default/textures/build/Object_Ring_Selected.png Binary files differindex 962f6efb93..49b76d137e 100644 --- a/indra/newview/skins/default/textures/build/Object_Ring_Selected.png +++ b/indra/newview/skins/default/textures/build/Object_Ring_Selected.png diff --git a/indra/newview/skins/default/textures/build/Object_Sphere_Selected.png b/indra/newview/skins/default/textures/build/Object_Sphere_Selected.png Binary files differindex 715d597144..473b90e867 100644 --- a/indra/newview/skins/default/textures/build/Object_Sphere_Selected.png +++ b/indra/newview/skins/default/textures/build/Object_Sphere_Selected.png diff --git a/indra/newview/skins/default/textures/build/Object_Tetrahedron_Selected.png b/indra/newview/skins/default/textures/build/Object_Tetrahedron_Selected.png Binary files differindex b2ea680f23..20278c8f6d 100644 --- a/indra/newview/skins/default/textures/build/Object_Tetrahedron_Selected.png +++ b/indra/newview/skins/default/textures/build/Object_Tetrahedron_Selected.png diff --git a/indra/newview/skins/default/textures/build/Object_Torus_Selected.png b/indra/newview/skins/default/textures/build/Object_Torus_Selected.png Binary files differindex 1fc22686eb..e6cad859fd 100644 --- a/indra/newview/skins/default/textures/build/Object_Torus_Selected.png +++ b/indra/newview/skins/default/textures/build/Object_Torus_Selected.png diff --git a/indra/newview/skins/default/textures/build/Object_Tree_Selected.png b/indra/newview/skins/default/textures/build/Object_Tree_Selected.png Binary files differindex 5bd87f8a2f..52b4f535f8 100644 --- a/indra/newview/skins/default/textures/build/Object_Tree_Selected.png +++ b/indra/newview/skins/default/textures/build/Object_Tree_Selected.png diff --git a/indra/newview/skins/default/textures/build/Object_Tube_Selected.png b/indra/newview/skins/default/textures/build/Object_Tube_Selected.png Binary files differindex a4c3f39e14..4469814e1a 100644 --- a/indra/newview/skins/default/textures/build/Object_Tube_Selected.png +++ b/indra/newview/skins/default/textures/build/Object_Tube_Selected.png diff --git a/indra/newview/skins/default/textures/containers/Accordion_Selected.png b/indra/newview/skins/default/textures/containers/Accordion_Selected.png Binary files differindex 0616dea6a3..2222954332 100644 --- a/indra/newview/skins/default/textures/containers/Accordion_Selected.png +++ b/indra/newview/skins/default/textures/containers/Accordion_Selected.png diff --git a/indra/newview/skins/default/textures/containers/TabTop_Left_Off.png b/indra/newview/skins/default/textures/containers/TabTop_Left_Off.png Binary files differindex 1951413f8d..c5b232d9ab 100644 --- a/indra/newview/skins/default/textures/containers/TabTop_Left_Off.png +++ b/indra/newview/skins/default/textures/containers/TabTop_Left_Off.png diff --git a/indra/newview/skins/default/textures/containers/TabTop_Left_Selected.png b/indra/newview/skins/default/textures/containers/TabTop_Left_Selected.png Binary files differindex 8364716e02..cd78651064 100644 --- a/indra/newview/skins/default/textures/containers/TabTop_Left_Selected.png +++ b/indra/newview/skins/default/textures/containers/TabTop_Left_Selected.png diff --git a/indra/newview/skins/default/textures/containers/TabTop_Middle_Off.png b/indra/newview/skins/default/textures/containers/TabTop_Middle_Off.png Binary files differindex 21f1c2d8a8..be624ab273 100644 --- a/indra/newview/skins/default/textures/containers/TabTop_Middle_Off.png +++ b/indra/newview/skins/default/textures/containers/TabTop_Middle_Off.png diff --git a/indra/newview/skins/default/textures/containers/TabTop_Middle_Selected.png b/indra/newview/skins/default/textures/containers/TabTop_Middle_Selected.png Binary files differindex 3946917c7c..dba61903a6 100644 --- a/indra/newview/skins/default/textures/containers/TabTop_Middle_Selected.png +++ b/indra/newview/skins/default/textures/containers/TabTop_Middle_Selected.png diff --git a/indra/newview/skins/default/textures/containers/TabTop_Right_Off.png b/indra/newview/skins/default/textures/containers/TabTop_Right_Off.png Binary files differindex eeef28e5a5..db28e9e13a 100644 --- a/indra/newview/skins/default/textures/containers/TabTop_Right_Off.png +++ b/indra/newview/skins/default/textures/containers/TabTop_Right_Off.png diff --git a/indra/newview/skins/default/textures/containers/TabTop_Right_Selected.png b/indra/newview/skins/default/textures/containers/TabTop_Right_Selected.png Binary files differindex b0f1f16398..4da3bc232c 100644 --- a/indra/newview/skins/default/textures/containers/TabTop_Right_Selected.png +++ b/indra/newview/skins/default/textures/containers/TabTop_Right_Selected.png diff --git a/indra/newview/skins/default/textures/containers/Toolbar_Left_Off.png b/indra/newview/skins/default/textures/containers/Toolbar_Left_Off.png Binary files differindex 41b5d24d87..f347505772 100644 --- a/indra/newview/skins/default/textures/containers/Toolbar_Left_Off.png +++ b/indra/newview/skins/default/textures/containers/Toolbar_Left_Off.png diff --git a/indra/newview/skins/default/textures/containers/Toolbar_Left_Over.png b/indra/newview/skins/default/textures/containers/Toolbar_Left_Over.png Binary files differindex 083acc0156..fd24e5b430 100644 --- a/indra/newview/skins/default/textures/containers/Toolbar_Left_Over.png +++ b/indra/newview/skins/default/textures/containers/Toolbar_Left_Over.png diff --git a/indra/newview/skins/default/textures/containers/Toolbar_Left_Selected.png b/indra/newview/skins/default/textures/containers/Toolbar_Left_Selected.png Binary files differindex ee4649a8f9..dccf543a9a 100644 --- a/indra/newview/skins/default/textures/containers/Toolbar_Left_Selected.png +++ b/indra/newview/skins/default/textures/containers/Toolbar_Left_Selected.png diff --git a/indra/newview/skins/default/textures/containers/Toolbar_Middle_Off.png b/indra/newview/skins/default/textures/containers/Toolbar_Middle_Off.png Binary files differindex 55c02160e3..cf30330f1c 100644 --- a/indra/newview/skins/default/textures/containers/Toolbar_Middle_Off.png +++ b/indra/newview/skins/default/textures/containers/Toolbar_Middle_Off.png diff --git a/indra/newview/skins/default/textures/containers/Toolbar_Middle_Over.png b/indra/newview/skins/default/textures/containers/Toolbar_Middle_Over.png Binary files differindex 2f6ea90196..6ac1ce3ffb 100644 --- a/indra/newview/skins/default/textures/containers/Toolbar_Middle_Over.png +++ b/indra/newview/skins/default/textures/containers/Toolbar_Middle_Over.png diff --git a/indra/newview/skins/default/textures/containers/Toolbar_Middle_Selected.png b/indra/newview/skins/default/textures/containers/Toolbar_Middle_Selected.png Binary files differindex 642113b135..8b40051c0b 100644 --- a/indra/newview/skins/default/textures/containers/Toolbar_Middle_Selected.png +++ b/indra/newview/skins/default/textures/containers/Toolbar_Middle_Selected.png diff --git a/indra/newview/skins/default/textures/containers/Toolbar_Right_Off.png b/indra/newview/skins/default/textures/containers/Toolbar_Right_Off.png Binary files differindex 01fd765c3d..d4881e21d3 100644 --- a/indra/newview/skins/default/textures/containers/Toolbar_Right_Off.png +++ b/indra/newview/skins/default/textures/containers/Toolbar_Right_Off.png diff --git a/indra/newview/skins/default/textures/containers/Toolbar_Right_Over.png b/indra/newview/skins/default/textures/containers/Toolbar_Right_Over.png Binary files differindex 74e00635f1..bf2a72d6f4 100644 --- a/indra/newview/skins/default/textures/containers/Toolbar_Right_Over.png +++ b/indra/newview/skins/default/textures/containers/Toolbar_Right_Over.png diff --git a/indra/newview/skins/default/textures/containers/Toolbar_Right_Selected.png b/indra/newview/skins/default/textures/containers/Toolbar_Right_Selected.png Binary files differindex 8a0d98a780..c3833ad7fa 100644 --- a/indra/newview/skins/default/textures/containers/Toolbar_Right_Selected.png +++ b/indra/newview/skins/default/textures/containers/Toolbar_Right_Selected.png diff --git a/indra/newview/skins/default/textures/icon_auction.tga b/indra/newview/skins/default/textures/icon_auction.tga Binary files differnew file mode 100644 index 0000000000..baf7d0d000 --- /dev/null +++ b/indra/newview/skins/default/textures/icon_auction.tga diff --git a/indra/newview/skins/default/textures/icon_group.tga b/indra/newview/skins/default/textures/icon_group.tga Binary files differnew file mode 100644 index 0000000000..79cd71689d --- /dev/null +++ b/indra/newview/skins/default/textures/icon_group.tga diff --git a/indra/newview/skins/default/textures/icon_legacy_event.tga b/indra/newview/skins/default/textures/icon_legacy_event.tga Binary files differnew file mode 100644 index 0000000000..7805dbce60 --- /dev/null +++ b/indra/newview/skins/default/textures/icon_legacy_event.tga diff --git a/indra/newview/skins/default/textures/icon_legacy_event_adult.tga b/indra/newview/skins/default/textures/icon_legacy_event_adult.tga Binary files differnew file mode 100644 index 0000000000..c344fb1e78 --- /dev/null +++ b/indra/newview/skins/default/textures/icon_legacy_event_adult.tga diff --git a/indra/newview/skins/default/textures/icon_legacy_event_mature.tga b/indra/newview/skins/default/textures/icon_legacy_event_mature.tga Binary files differnew file mode 100644 index 0000000000..61c879bc92 --- /dev/null +++ b/indra/newview/skins/default/textures/icon_legacy_event_mature.tga diff --git a/indra/newview/skins/default/textures/icon_place.tga b/indra/newview/skins/default/textures/icon_place.tga Binary files differnew file mode 100644 index 0000000000..e10655c6ec --- /dev/null +++ b/indra/newview/skins/default/textures/icon_place.tga diff --git a/indra/newview/skins/default/textures/icons/Icon_Attachment_Large.png b/indra/newview/skins/default/textures/icons/Icon_Attachment_Large.png Binary files differindex 74ec3d7e69..fb57265dac 100644 --- a/indra/newview/skins/default/textures/icons/Icon_Attachment_Large.png +++ b/indra/newview/skins/default/textures/icons/Icon_Attachment_Large.png diff --git a/indra/newview/skins/default/textures/icons/Icon_Attachment_Small.png b/indra/newview/skins/default/textures/icons/Icon_Attachment_Small.png Binary files differindex 9ea7c48871..907113cbb7 100644 --- a/indra/newview/skins/default/textures/icons/Icon_Attachment_Small.png +++ b/indra/newview/skins/default/textures/icons/Icon_Attachment_Small.png diff --git a/indra/newview/skins/default/textures/icons/Info_Over.png b/indra/newview/skins/default/textures/icons/Info_Over.png Binary files differindex 0efd596d3e..6399cd6715 100644 --- a/indra/newview/skins/default/textures/icons/Info_Over.png +++ b/indra/newview/skins/default/textures/icons/Info_Over.png diff --git a/indra/newview/skins/default/textures/icons/Inv_Shape.png b/indra/newview/skins/default/textures/icons/Inv_Shape.png Binary files differnew file mode 100644 index 0000000000..e5db447b36 --- /dev/null +++ b/indra/newview/skins/default/textures/icons/Inv_Shape.png diff --git a/indra/newview/skins/default/textures/icons/Inv_SysClosed.png b/indra/newview/skins/default/textures/icons/Inv_SysClosed.png Binary files differindex 9af3b60cbd..2550cae0d4 100644 --- a/indra/newview/skins/default/textures/icons/Inv_SysClosed.png +++ b/indra/newview/skins/default/textures/icons/Inv_SysClosed.png diff --git a/indra/newview/skins/default/textures/icons/Inv_SysOpen.png b/indra/newview/skins/default/textures/icons/Inv_SysOpen.png Binary files differindex 01e7dbff8f..5b56d86184 100644 --- a/indra/newview/skins/default/textures/icons/Inv_SysOpen.png +++ b/indra/newview/skins/default/textures/icons/Inv_SysOpen.png diff --git a/indra/newview/skins/default/textures/icons/MP_Logo.png b/indra/newview/skins/default/textures/icons/MP_Logo.png Binary files differnew file mode 100644 index 0000000000..e33a830d3b --- /dev/null +++ b/indra/newview/skins/default/textures/icons/MP_Logo.png diff --git a/indra/newview/skins/default/textures/icons/MusicNote.png b/indra/newview/skins/default/textures/icons/MusicNote.png Binary files differnew file mode 100644 index 0000000000..8d3534a94b --- /dev/null +++ b/indra/newview/skins/default/textures/icons/MusicNote.png diff --git a/indra/newview/skins/default/textures/icons/OutboxPush_Disabled.png b/indra/newview/skins/default/textures/icons/OutboxPush_Disabled.png Binary files differindex ab8983b545..1d2dbd6349 100644 --- a/indra/newview/skins/default/textures/icons/OutboxPush_Disabled.png +++ b/indra/newview/skins/default/textures/icons/OutboxPush_Disabled.png diff --git a/indra/newview/skins/default/textures/icons/OutboxPush_Off.png b/indra/newview/skins/default/textures/icons/OutboxPush_Off.png Binary files differindex 17e152a901..f8f3367c42 100644 --- a/indra/newview/skins/default/textures/icons/OutboxPush_Off.png +++ b/indra/newview/skins/default/textures/icons/OutboxPush_Off.png diff --git a/indra/newview/skins/default/textures/icons/OutboxPush_On.png b/indra/newview/skins/default/textures/icons/OutboxPush_On.png Binary files differindex 7ed854b9eb..b1fd734100 100644 --- a/indra/newview/skins/default/textures/icons/OutboxPush_On.png +++ b/indra/newview/skins/default/textures/icons/OutboxPush_On.png diff --git a/indra/newview/skins/default/textures/icons/OutboxPush_On_Over.png b/indra/newview/skins/default/textures/icons/OutboxPush_On_Over.png Binary files differindex 1b77ccdaaa..e234400b72 100644 --- a/indra/newview/skins/default/textures/icons/OutboxPush_On_Over.png +++ b/indra/newview/skins/default/textures/icons/OutboxPush_On_Over.png diff --git a/indra/newview/skins/default/textures/icons/OutboxPush_Over.png b/indra/newview/skins/default/textures/icons/OutboxPush_Over.png Binary files differindex 3d352af9a1..9e1b0e2dfc 100644 --- a/indra/newview/skins/default/textures/icons/OutboxPush_Over.png +++ b/indra/newview/skins/default/textures/icons/OutboxPush_Over.png diff --git a/indra/newview/skins/default/textures/icons/OutboxPush_Press.png b/indra/newview/skins/default/textures/icons/OutboxPush_Press.png Binary files differindex bf040e3662..14d9eacc52 100644 --- a/indra/newview/skins/default/textures/icons/OutboxPush_Press.png +++ b/indra/newview/skins/default/textures/icons/OutboxPush_Press.png diff --git a/indra/newview/skins/default/textures/icons/OutboxPush_Progress_1.png b/indra/newview/skins/default/textures/icons/OutboxPush_Progress_1.png Binary files differindex 0e1252082f..85015fc913 100644 --- a/indra/newview/skins/default/textures/icons/OutboxPush_Progress_1.png +++ b/indra/newview/skins/default/textures/icons/OutboxPush_Progress_1.png diff --git a/indra/newview/skins/default/textures/icons/OutboxPush_Progress_2.png b/indra/newview/skins/default/textures/icons/OutboxPush_Progress_2.png Binary files differindex 6684b70ca8..6158242b68 100644 --- a/indra/newview/skins/default/textures/icons/OutboxPush_Progress_2.png +++ b/indra/newview/skins/default/textures/icons/OutboxPush_Progress_2.png diff --git a/indra/newview/skins/default/textures/icons/OutboxPush_Progress_3.png b/indra/newview/skins/default/textures/icons/OutboxPush_Progress_3.png Binary files differindex b8d2a86662..7105380bff 100644 --- a/indra/newview/skins/default/textures/icons/OutboxPush_Progress_3.png +++ b/indra/newview/skins/default/textures/icons/OutboxPush_Progress_3.png diff --git a/indra/newview/skins/default/textures/icons/OutboxPush_Progress_4.png b/indra/newview/skins/default/textures/icons/OutboxPush_Progress_4.png Binary files differindex f93e844a00..0e65a60fc8 100644 --- a/indra/newview/skins/default/textures/icons/OutboxPush_Progress_4.png +++ b/indra/newview/skins/default/textures/icons/OutboxPush_Progress_4.png diff --git a/indra/newview/skins/default/textures/icons/OutboxPush_Progress_5.png b/indra/newview/skins/default/textures/icons/OutboxPush_Progress_5.png Binary files differindex 631b8475af..7acef05891 100644 --- a/indra/newview/skins/default/textures/icons/OutboxPush_Progress_5.png +++ b/indra/newview/skins/default/textures/icons/OutboxPush_Progress_5.png diff --git a/indra/newview/skins/default/textures/icons/OutboxPush_Progress_6.png b/indra/newview/skins/default/textures/icons/OutboxPush_Progress_6.png Binary files differindex 39283fa162..4f5b34a643 100644 --- a/indra/newview/skins/default/textures/icons/OutboxPush_Progress_6.png +++ b/indra/newview/skins/default/textures/icons/OutboxPush_Progress_6.png diff --git a/indra/newview/skins/default/textures/icons/OutboxPush_Selected.png b/indra/newview/skins/default/textures/icons/OutboxPush_Selected.png Binary files differindex c5576561d5..d58826da67 100644 --- a/indra/newview/skins/default/textures/icons/OutboxPush_Selected.png +++ b/indra/newview/skins/default/textures/icons/OutboxPush_Selected.png diff --git a/indra/newview/skins/default/textures/icons/OutboxPush_Selected_Disabled.png b/indra/newview/skins/default/textures/icons/OutboxPush_Selected_Disabled.png Binary files differindex 5899b766d6..cad9f118b1 100644 --- a/indra/newview/skins/default/textures/icons/OutboxPush_Selected_Disabled.png +++ b/indra/newview/skins/default/textures/icons/OutboxPush_Selected_Disabled.png diff --git a/indra/newview/skins/default/textures/icons/OutboxPush_Selected_Over.png b/indra/newview/skins/default/textures/icons/OutboxPush_Selected_Over.png Binary files differindex de290d8228..65d914c6b3 100644 --- a/indra/newview/skins/default/textures/icons/OutboxPush_Selected_Over.png +++ b/indra/newview/skins/default/textures/icons/OutboxPush_Selected_Over.png diff --git a/indra/newview/skins/default/textures/icons/OutboxPush_Selected_Press.png b/indra/newview/skins/default/textures/icons/OutboxPush_Selected_Press.png Binary files differindex 532cdff222..cd50d41903 100644 --- a/indra/newview/skins/default/textures/icons/OutboxPush_Selected_Press.png +++ b/indra/newview/skins/default/textures/icons/OutboxPush_Selected_Press.png diff --git a/indra/newview/skins/default/textures/icons/Permission_Ungranted.png b/indra/newview/skins/default/textures/icons/Permission_Ungranted.png Binary files differnew file mode 100644 index 0000000000..d206af4433 --- /dev/null +++ b/indra/newview/skins/default/textures/icons/Permission_Ungranted.png diff --git a/indra/newview/skins/default/textures/icons/ProgressLarge_1.png b/indra/newview/skins/default/textures/icons/ProgressLarge_1.png Binary files differnew file mode 100644 index 0000000000..ff277fc431 --- /dev/null +++ b/indra/newview/skins/default/textures/icons/ProgressLarge_1.png diff --git a/indra/newview/skins/default/textures/icons/ProgressLarge_10.png b/indra/newview/skins/default/textures/icons/ProgressLarge_10.png Binary files differnew file mode 100644 index 0000000000..1c94e21d89 --- /dev/null +++ b/indra/newview/skins/default/textures/icons/ProgressLarge_10.png diff --git a/indra/newview/skins/default/textures/icons/ProgressLarge_11.png b/indra/newview/skins/default/textures/icons/ProgressLarge_11.png Binary files differnew file mode 100644 index 0000000000..89bea9b474 --- /dev/null +++ b/indra/newview/skins/default/textures/icons/ProgressLarge_11.png diff --git a/indra/newview/skins/default/textures/icons/ProgressLarge_12.png b/indra/newview/skins/default/textures/icons/ProgressLarge_12.png Binary files differnew file mode 100644 index 0000000000..da38475ba4 --- /dev/null +++ b/indra/newview/skins/default/textures/icons/ProgressLarge_12.png diff --git a/indra/newview/skins/default/textures/icons/ProgressLarge_2.png b/indra/newview/skins/default/textures/icons/ProgressLarge_2.png Binary files differnew file mode 100644 index 0000000000..c024275ebe --- /dev/null +++ b/indra/newview/skins/default/textures/icons/ProgressLarge_2.png diff --git a/indra/newview/skins/default/textures/icons/ProgressLarge_3.png b/indra/newview/skins/default/textures/icons/ProgressLarge_3.png Binary files differnew file mode 100644 index 0000000000..87b931e72e --- /dev/null +++ b/indra/newview/skins/default/textures/icons/ProgressLarge_3.png diff --git a/indra/newview/skins/default/textures/icons/ProgressLarge_4.png b/indra/newview/skins/default/textures/icons/ProgressLarge_4.png Binary files differnew file mode 100644 index 0000000000..6dbef74361 --- /dev/null +++ b/indra/newview/skins/default/textures/icons/ProgressLarge_4.png diff --git a/indra/newview/skins/default/textures/icons/ProgressLarge_5.png b/indra/newview/skins/default/textures/icons/ProgressLarge_5.png Binary files differnew file mode 100644 index 0000000000..daccf9b375 --- /dev/null +++ b/indra/newview/skins/default/textures/icons/ProgressLarge_5.png diff --git a/indra/newview/skins/default/textures/icons/ProgressLarge_6.png b/indra/newview/skins/default/textures/icons/ProgressLarge_6.png Binary files differnew file mode 100644 index 0000000000..cafddcb88d --- /dev/null +++ b/indra/newview/skins/default/textures/icons/ProgressLarge_6.png diff --git a/indra/newview/skins/default/textures/icons/ProgressLarge_7.png b/indra/newview/skins/default/textures/icons/ProgressLarge_7.png Binary files differnew file mode 100644 index 0000000000..8acf6472d4 --- /dev/null +++ b/indra/newview/skins/default/textures/icons/ProgressLarge_7.png diff --git a/indra/newview/skins/default/textures/icons/ProgressLarge_8.png b/indra/newview/skins/default/textures/icons/ProgressLarge_8.png Binary files differnew file mode 100644 index 0000000000..df0e825cef --- /dev/null +++ b/indra/newview/skins/default/textures/icons/ProgressLarge_8.png diff --git a/indra/newview/skins/default/textures/icons/ProgressLarge_9.png b/indra/newview/skins/default/textures/icons/ProgressLarge_9.png Binary files differnew file mode 100644 index 0000000000..293a7b8f5c --- /dev/null +++ b/indra/newview/skins/default/textures/icons/ProgressLarge_9.png diff --git a/indra/newview/skins/default/textures/icons/SL_Logo.png b/indra/newview/skins/default/textures/icons/SL_Logo.png Binary files differindex 1eafc304f5..943265e240 100644 --- a/indra/newview/skins/default/textures/icons/SL_Logo.png +++ b/indra/newview/skins/default/textures/icons/SL_Logo.png diff --git a/indra/newview/skins/default/textures/icons/Sync_Enabled.png b/indra/newview/skins/default/textures/icons/Sync_Enabled.png Binary files differindex 43c8707995..0e7e5157cb 100644 --- a/indra/newview/skins/default/textures/icons/Sync_Enabled.png +++ b/indra/newview/skins/default/textures/icons/Sync_Enabled.png diff --git a/indra/newview/skins/default/textures/icons/VoicePTT_Lvl1.png b/indra/newview/skins/default/textures/icons/VoicePTT_Lvl1.png Binary files differindex 3ad6a5ba5b..cc3407b57d 100644 --- a/indra/newview/skins/default/textures/icons/VoicePTT_Lvl1.png +++ b/indra/newview/skins/default/textures/icons/VoicePTT_Lvl1.png diff --git a/indra/newview/skins/default/textures/icons/VoicePTT_Lvl2.png b/indra/newview/skins/default/textures/icons/VoicePTT_Lvl2.png Binary files differindex deae5cb989..49f58d7cd0 100644 --- a/indra/newview/skins/default/textures/icons/VoicePTT_Lvl2.png +++ b/indra/newview/skins/default/textures/icons/VoicePTT_Lvl2.png diff --git a/indra/newview/skins/default/textures/icons/VoicePTT_On.png b/indra/newview/skins/default/textures/icons/VoicePTT_On.png Binary files differindex f673671082..204c4a376e 100644 --- a/indra/newview/skins/default/textures/icons/VoicePTT_On.png +++ b/indra/newview/skins/default/textures/icons/VoicePTT_On.png diff --git a/indra/newview/skins/default/textures/icons/add_icon.png b/indra/newview/skins/default/textures/icons/add_icon.png Binary files differindex daedd49933..b5b09ae6e0 100644 --- a/indra/newview/skins/default/textures/icons/add_icon.png +++ b/indra/newview/skins/default/textures/icons/add_icon.png diff --git a/indra/newview/skins/default/textures/icons/back_arrow_off.png b/indra/newview/skins/default/textures/icons/back_arrow_off.png Binary files differindex ab82dfc0a7..c9c7bf5fec 100644 --- a/indra/newview/skins/default/textures/icons/back_arrow_off.png +++ b/indra/newview/skins/default/textures/icons/back_arrow_off.png diff --git a/indra/newview/skins/default/textures/icons/back_arrow_over.png b/indra/newview/skins/default/textures/icons/back_arrow_over.png Binary files differindex ad8c1f8d2c..ee6acc2653 100644 --- a/indra/newview/skins/default/textures/icons/back_arrow_over.png +++ b/indra/newview/skins/default/textures/icons/back_arrow_over.png diff --git a/indra/newview/skins/default/textures/icons/back_arrow_press.png b/indra/newview/skins/default/textures/icons/back_arrow_press.png Binary files differindex 8aecc3d876..9876b4eeb7 100644 --- a/indra/newview/skins/default/textures/icons/back_arrow_press.png +++ b/indra/newview/skins/default/textures/icons/back_arrow_press.png diff --git a/indra/newview/skins/default/textures/icons/check_mark.png b/indra/newview/skins/default/textures/icons/check_mark.png Binary files differindex 5431dd31c8..95ca9dbd6c 100644 --- a/indra/newview/skins/default/textures/icons/check_mark.png +++ b/indra/newview/skins/default/textures/icons/check_mark.png diff --git a/indra/newview/skins/default/textures/icons/copy_clipboard.png b/indra/newview/skins/default/textures/icons/copy_clipboard.png Binary files differindex c6f267e944..9ce67d8547 100644 --- a/indra/newview/skins/default/textures/icons/copy_clipboard.png +++ b/indra/newview/skins/default/textures/icons/copy_clipboard.png diff --git a/indra/newview/skins/default/textures/icons/delete_icon.png b/indra/newview/skins/default/textures/icons/delete_icon.png Binary files differindex 0700e52a8c..5a80155d8b 100644 --- a/indra/newview/skins/default/textures/icons/delete_icon.png +++ b/indra/newview/skins/default/textures/icons/delete_icon.png diff --git a/indra/newview/skins/default/textures/icons/file_upload.png b/indra/newview/skins/default/textures/icons/file_upload.png Binary files differindex 52f75172c1..78b75fdd72 100644 --- a/indra/newview/skins/default/textures/icons/file_upload.png +++ b/indra/newview/skins/default/textures/icons/file_upload.png diff --git a/indra/newview/skins/default/textures/icons/hand.png b/indra/newview/skins/default/textures/icons/hand.png Binary files differindex d8ef2e22fa..3f497eefbb 100644 --- a/indra/newview/skins/default/textures/icons/hand.png +++ b/indra/newview/skins/default/textures/icons/hand.png diff --git a/indra/newview/skins/default/textures/icons/multi_folder_mode.png b/indra/newview/skins/default/textures/icons/multi_folder_mode.png Binary files differindex 13762173a5..b363848aba 100644 --- a/indra/newview/skins/default/textures/icons/multi_folder_mode.png +++ b/indra/newview/skins/default/textures/icons/multi_folder_mode.png diff --git a/indra/newview/skins/default/textures/icons/paste_clipboard.png b/indra/newview/skins/default/textures/icons/paste_clipboard.png Binary files differindex 810e603ef0..ff8493d4ad 100644 --- a/indra/newview/skins/default/textures/icons/paste_clipboard.png +++ b/indra/newview/skins/default/textures/icons/paste_clipboard.png diff --git a/indra/newview/skins/default/textures/icons/profile_badge_beta.png b/indra/newview/skins/default/textures/icons/profile_badge_beta.png Binary files differindex e378eebf9a..95e277aab0 100644 --- a/indra/newview/skins/default/textures/icons/profile_badge_beta.png +++ b/indra/newview/skins/default/textures/icons/profile_badge_beta.png diff --git a/indra/newview/skins/default/textures/icons/profile_badge_beta_lifetime.png b/indra/newview/skins/default/textures/icons/profile_badge_beta_lifetime.png Binary files differindex f2fc8e0853..fb145901e2 100644 --- a/indra/newview/skins/default/textures/icons/profile_badge_beta_lifetime.png +++ b/indra/newview/skins/default/textures/icons/profile_badge_beta_lifetime.png diff --git a/indra/newview/skins/default/textures/icons/profile_badge_lifetime.png b/indra/newview/skins/default/textures/icons/profile_badge_lifetime.png Binary files differindex 85b8e688b4..3f7fd343b3 100644 --- a/indra/newview/skins/default/textures/icons/profile_badge_lifetime.png +++ b/indra/newview/skins/default/textures/icons/profile_badge_lifetime.png diff --git a/indra/newview/skins/default/textures/icons/profile_badge_linden.png b/indra/newview/skins/default/textures/icons/profile_badge_linden.png Binary files differindex 6ff3a97fdc..6ab9fcebea 100644 --- a/indra/newview/skins/default/textures/icons/profile_badge_linden.png +++ b/indra/newview/skins/default/textures/icons/profile_badge_linden.png diff --git a/indra/newview/skins/default/textures/icons/profile_badge_pplus_lifetime.png b/indra/newview/skins/default/textures/icons/profile_badge_pplus_lifetime.png Binary files differindex aebd10f4b3..5c68ad40ce 100644 --- a/indra/newview/skins/default/textures/icons/profile_badge_pplus_lifetime.png +++ b/indra/newview/skins/default/textures/icons/profile_badge_pplus_lifetime.png diff --git a/indra/newview/skins/default/textures/icons/profile_badge_premium_lifetime.png b/indra/newview/skins/default/textures/icons/profile_badge_premium_lifetime.png Binary files differindex 06669bb228..58957b7b96 100644 --- a/indra/newview/skins/default/textures/icons/profile_badge_premium_lifetime.png +++ b/indra/newview/skins/default/textures/icons/profile_badge_premium_lifetime.png diff --git a/indra/newview/skins/default/textures/icons/remove_icon.png b/indra/newview/skins/default/textures/icons/remove_icon.png Binary files differindex 0df57d6c64..d8a45cc21c 100644 --- a/indra/newview/skins/default/textures/icons/remove_icon.png +++ b/indra/newview/skins/default/textures/icons/remove_icon.png diff --git a/indra/newview/skins/default/textures/icons/see_me_online.png b/indra/newview/skins/default/textures/icons/see_me_online.png Binary files differindex 4059035b20..adc37f5528 100644 --- a/indra/newview/skins/default/textures/icons/see_me_online.png +++ b/indra/newview/skins/default/textures/icons/see_me_online.png diff --git a/indra/newview/skins/default/textures/icons/see_on_map.png b/indra/newview/skins/default/textures/icons/see_on_map.png Binary files differindex c9e8d721af..73415b9afe 100644 --- a/indra/newview/skins/default/textures/icons/see_on_map.png +++ b/indra/newview/skins/default/textures/icons/see_on_map.png diff --git a/indra/newview/skins/default/textures/icons/see_them_on_map.png b/indra/newview/skins/default/textures/icons/see_them_on_map.png Binary files differnew file mode 100644 index 0000000000..e5f2978dc0 --- /dev/null +++ b/indra/newview/skins/default/textures/icons/see_them_on_map.png diff --git a/indra/newview/skins/default/textures/icons/see_them_online.png b/indra/newview/skins/default/textures/icons/see_them_online.png Binary files differnew file mode 100644 index 0000000000..7ddd41f9a0 --- /dev/null +++ b/indra/newview/skins/default/textures/icons/see_them_online.png diff --git a/indra/newview/skins/default/textures/icons/single_folder_back.png b/indra/newview/skins/default/textures/icons/single_folder_back.png Binary files differindex 4ccea718c6..b93bb2525a 100644 --- a/indra/newview/skins/default/textures/icons/single_folder_back.png +++ b/indra/newview/skins/default/textures/icons/single_folder_back.png diff --git a/indra/newview/skins/default/textures/icons/single_folder_forward.png b/indra/newview/skins/default/textures/icons/single_folder_forward.png Binary files differindex 614ad18f48..12a21b2bba 100644 --- a/indra/newview/skins/default/textures/icons/single_folder_forward.png +++ b/indra/newview/skins/default/textures/icons/single_folder_forward.png diff --git a/indra/newview/skins/default/textures/icons/single_folder_mode.png b/indra/newview/skins/default/textures/icons/single_folder_mode.png Binary files differindex 1382e8750b..0fc8475917 100644 --- a/indra/newview/skins/default/textures/icons/single_folder_mode.png +++ b/indra/newview/skins/default/textures/icons/single_folder_mode.png diff --git a/indra/newview/skins/default/textures/icons/single_folder_up.png b/indra/newview/skins/default/textures/icons/single_folder_up.png Binary files differindex 55d55434d2..c1c8c63870 100644 --- a/indra/newview/skins/default/textures/icons/single_folder_up.png +++ b/indra/newview/skins/default/textures/icons/single_folder_up.png diff --git a/indra/newview/skins/default/textures/icons/snapshot_icon.png b/indra/newview/skins/default/textures/icons/snapshot_icon.png Binary files differindex 990a41e5b7..9b6ac6eeb0 100644 --- a/indra/newview/skins/default/textures/icons/snapshot_icon.png +++ b/indra/newview/skins/default/textures/icons/snapshot_icon.png diff --git a/indra/newview/skins/default/textures/icons/texture_icon.png b/indra/newview/skins/default/textures/icons/texture_icon.png Binary files differindex e87ba4ba99..f5c205208c 100644 --- a/indra/newview/skins/default/textures/icons/texture_icon.png +++ b/indra/newview/skins/default/textures/icons/texture_icon.png diff --git a/indra/newview/skins/default/textures/icons/thumbnail_fallback_icon.png b/indra/newview/skins/default/textures/icons/thumbnail_fallback_icon.png Binary files differindex 9199697375..19629aba04 100644 --- a/indra/newview/skins/default/textures/icons/thumbnail_fallback_icon.png +++ b/indra/newview/skins/default/textures/icons/thumbnail_fallback_icon.png diff --git a/indra/newview/skins/default/textures/megapahit/icon_group.png b/indra/newview/skins/default/textures/megapahit/icon_group.png Binary files differnew file mode 100644 index 0000000000..f3872dea3f --- /dev/null +++ b/indra/newview/skins/default/textures/megapahit/icon_group.png diff --git a/indra/newview/skins/default/textures/megapahit/icon_land_auction.png b/indra/newview/skins/default/textures/megapahit/icon_land_auction.png Binary files differnew file mode 100644 index 0000000000..550703968f --- /dev/null +++ b/indra/newview/skins/default/textures/megapahit/icon_land_auction.png diff --git a/indra/newview/skins/default/textures/megapahit/icon_land_forsale.png b/indra/newview/skins/default/textures/megapahit/icon_land_forsale.png Binary files differnew file mode 100644 index 0000000000..209bb868ea --- /dev/null +++ b/indra/newview/skins/default/textures/megapahit/icon_land_forsale.png diff --git a/indra/newview/skins/default/textures/megapahit/icon_place.png b/indra/newview/skins/default/textures/megapahit/icon_place.png Binary files differnew file mode 100644 index 0000000000..60cf42424a --- /dev/null +++ b/indra/newview/skins/default/textures/megapahit/icon_place.png diff --git a/indra/newview/skins/default/textures/model_wizard/progress_light.png b/indra/newview/skins/default/textures/model_wizard/progress_light.png Binary files differindex c8ab151c44..2e64604a4d 100644 --- a/indra/newview/skins/default/textures/model_wizard/progress_light.png +++ b/indra/newview/skins/default/textures/model_wizard/progress_light.png diff --git a/indra/newview/skins/default/textures/navbar/BuyArrow_Over.png b/indra/newview/skins/default/textures/navbar/BuyArrow_Over.png Binary files differindex 0b3f252ccf..3d9c758574 100644 --- a/indra/newview/skins/default/textures/navbar/BuyArrow_Over.png +++ b/indra/newview/skins/default/textures/navbar/BuyArrow_Over.png diff --git a/indra/newview/skins/default/textures/navbar/BuyArrow_Press.png b/indra/newview/skins/default/textures/navbar/BuyArrow_Press.png Binary files differindex 5c4c150bed..69b0d43900 100644 --- a/indra/newview/skins/default/textures/navbar/BuyArrow_Press.png +++ b/indra/newview/skins/default/textures/navbar/BuyArrow_Press.png diff --git a/indra/newview/skins/default/textures/navbar/Favorite_Star_Active.png b/indra/newview/skins/default/textures/navbar/Favorite_Star_Active.png Binary files differindex e27dbe2cad..fce54942d3 100644 --- a/indra/newview/skins/default/textures/navbar/Favorite_Star_Active.png +++ b/indra/newview/skins/default/textures/navbar/Favorite_Star_Active.png diff --git a/indra/newview/skins/default/textures/navbar/Favorite_Star_Over.png b/indra/newview/skins/default/textures/navbar/Favorite_Star_Over.png Binary files differindex 7909d54f2b..8cc3f02c5a 100644 --- a/indra/newview/skins/default/textures/navbar/Favorite_Star_Over.png +++ b/indra/newview/skins/default/textures/navbar/Favorite_Star_Over.png diff --git a/indra/newview/skins/default/textures/navbar/NavBar_BG.png b/indra/newview/skins/default/textures/navbar/NavBar_BG.png Binary files differindex 38eea783e6..6a91700ae0 100644 --- a/indra/newview/skins/default/textures/navbar/NavBar_BG.png +++ b/indra/newview/skins/default/textures/navbar/NavBar_BG.png diff --git a/indra/newview/skins/default/textures/navbar/NavBar_BG_NoFav_Bevel.png b/indra/newview/skins/default/textures/navbar/NavBar_BG_NoFav_Bevel.png Binary files differindex a79d999932..c61dcde58c 100644 --- a/indra/newview/skins/default/textures/navbar/NavBar_BG_NoFav_Bevel.png +++ b/indra/newview/skins/default/textures/navbar/NavBar_BG_NoFav_Bevel.png diff --git a/indra/newview/skins/default/textures/navbar/NavBar_BG_NoNav_Bevel.png b/indra/newview/skins/default/textures/navbar/NavBar_BG_NoNav_Bevel.png Binary files differindex b692ed92da..9e3da34596 100644 --- a/indra/newview/skins/default/textures/navbar/NavBar_BG_NoNav_Bevel.png +++ b/indra/newview/skins/default/textures/navbar/NavBar_BG_NoNav_Bevel.png diff --git a/indra/newview/skins/default/textures/navbar/Row_Selection.png b/indra/newview/skins/default/textures/navbar/Row_Selection.png Binary files differindex fc4f0c07ef..cfc31f8d32 100644 --- a/indra/newview/skins/default/textures/navbar/Row_Selection.png +++ b/indra/newview/skins/default/textures/navbar/Row_Selection.png diff --git a/indra/newview/skins/default/textures/textures.xml b/indra/newview/skins/default/textures/textures.xml index 97468c3b2e..f824816183 100644 --- a/indra/newview/skins/default/textures/textures.xml +++ b/indra/newview/skins/default/textures/textures.xml @@ -87,7 +87,7 @@ with the same filename but different name <texture name="BreadCrumbBtn_Left_Off" file_name="widgets/BreadCrumbBtn_Left_Off.png" preload="false"/> <texture name="BreadCrumbBtn_Left_Over" file_name="widgets/BreadCrumbBtn_Left_Over.png" preload="false"/> <texture name="BreadCrumbBtn_Left_Press" file_name="widgets/BreadCrumbBtn_Left_Press.png" preload="false"/> - + <texture name="BreadCrumbBtn_Middle_Disabled" file_name="widgets/BreadCrumbBtn_Middle_Disabled.png" preload="false"/> <texture name="BreadCrumbBtn_Middle_Off" file_name="widgets/BreadCrumbBtn_Middle_Off.png" preload="false"/> <texture name="BreadCrumbBtn_Middle_Over" file_name="widgets/BreadCrumbBtn_Middle_Over.png" preload="false"/> @@ -162,6 +162,8 @@ with the same filename but different name <texture name="Command_Speak_Icon" file_name="toolbar_icons/speak.png" preload="true" /> <texture name="Command_View_Icon" file_name="toolbar_icons/view.png" preload="true" /> <texture name="Command_Voice_Icon" file_name="toolbar_icons/nearbyvoice.png" preload="true" /> + <texture name="Command_FavoriteFolder_Icon" file_name="toolbar_icons/favorite_folder.png" preload="true" /> + <texture name="Command_Resync_Animations" file_name="toolbar_icons/resync_animations.png" preload="true" /> <texture name="Caret_Bottom_Icon" file_name="toolbar_icons/caret_bottom.png" preload="true" scale.left="1" scale.top="23" scale.right="15" scale.bottom="1" /> <texture name="Caret_Right_Icon" file_name="toolbar_icons/caret_right.png" preload="true" scale.left="5" scale.top="15" scale.right="28" scale.bottom="1" /> <texture name="Caret_Left_Icon" file_name="toolbar_icons/caret_left.png" preload="true" scale.left="1" scale.top="15" scale.right="23" scale.bottom="1" /> @@ -192,7 +194,7 @@ with the same filename but different name <texture name="Copy" file_name="icons/Copy.png" preload="false" /> <texture name="CopyBright" file_name="icons/CopyBright.png" preload="false" /> - + <texture name="DisclosureArrow_Opened_Off" file_name="widgets/DisclosureArrow_Opened_Off.png" preload="true" /> <texture name="ChatBarHandle" file_name="bottomtray/ChatBarHandle.png" preload="false" /> @@ -244,7 +246,7 @@ with the same filename but different name <texture name="Group_Notices" file_name="icons/Group_Notices.png" preload="false" /> <texture name="Hand" file_name="icons/hand.png" preload="false" /> - + <texture name="Help_Press" file_name="navbar/Help_Press.png" preload="false" /> <texture name="Hierarchy_View_Disabled" file_name="icons/Hierarchy_View_Disabled.png" preload="false" /> @@ -257,16 +259,16 @@ with the same filename but different name <texture name="Icon_Close_Foreground" file_name="windows/Icon_Close_Foreground.png" preload="true" /> <texture name="Icon_Close_Press" file_name="windows/Icon_Close_Press.png" preload="true" /> <texture name="Icon_Close_Toast" file_name="windows/Icon_Close_Toast.png" preload="true" /> - + <texture name="Icon_Copy" file_name="icons/copy_clipboard.png" preload="true" /> - + <texture name="Icon_Delete" file_name="icons/delete_icon.png" preload="true" /> <texture name="Icon_Dock_Foreground" file_name="windows/Icon_Dock_Foreground.png" preload="true" /> <texture name="Icon_Dock_Press" file_name="windows/Icon_Dock_Press.png" preload="true" /> <texture name="Icon_File_Upload" file_name="icons/file_upload.png" preload="true" /> - + <texture name="Icon_For_Sale" file_name="icons/Icon_For_Sale.png" preload="false" /> <texture name="Icon_Gear_Background" file_name="windows/Icon_Gear_Background.png" preload="false" /> @@ -279,14 +281,14 @@ with the same filename but different name <texture name="Icon_Minimize_Foreground" file_name="windows/Icon_Minimize_Foreground.png" preload="true" /> <texture name="Icon_Minimize_Press" file_name="windows/Icon_Minimize_Press.png" preload="true" /> - + <texture name="Icon_Paste" file_name="icons/paste_clipboard.png" preload="true" /> <texture name="Icon_Restore_Foreground" file_name="windows/Icon_Restore_Foreground.png" preload="false" /> <texture name="Icon_Restore_Press" file_name="windows/Icon_Restore_Press.png" preload="false" /> <texture name="Icon_Snapshot" file_name="icons/snapshot_icon.png" preload="true" /> - + <texture name="Icon_Use_Texture" file_name="icons/texture_icon.png" preload="true" /> <texture name="Info" file_name="icons/Info.png" preload="false" /> @@ -320,7 +322,7 @@ with the same filename but different name <texture name="Inv_LostOpen" file_name="icons/Inv_LostOpen.png" preload="false" /> <texture name="Inv_Landmark" file_name="icons/Inv_Landmark.png" preload="false" /> <texture name="Inv_Material" file_name="icons/Inv_Material.png" preload="false" /> - <texture name="Inv_Mesh" file_name="icons/Inv_Mesh.png" preload="false" /> + <texture name="Inv_Mesh" file_name="icons/Inv_Mesh.png" preload="false" /> <texture name="Inv_Notecard" file_name="icons/Inv_Notecard.png" preload="false" /> <texture name="Inv_Object" file_name="icons/Inv_Object.png" preload="false" /> <texture name="Inv_Object_Multi" file_name="icons/Inv_Object_Multi.png" preload="false" /> @@ -375,7 +377,7 @@ with the same filename but different name <texture name="Locked_Icon" file_name="icons/Locked_Icon.png" preload="false" /> <texture name="Map_Placeholder_Icon" file_name="icons/map_placeholder.png" preload="true" /> - + <texture name="Marketplace_Dropzone_Background" file_name="widgets/Marketplace_Dropzone_Background.png" preload="true" /> <texture name="MarketplaceBtn_Off" file_name="widgets/MarketplaceBtn_Off.png" preload="true" scale.left="30" scale.top="19" scale.right="35" scale.bottom="4" /> <texture name="MarketplaceBtn_Selected" file_name="widgets/MarketplaceBtn_Selected.png" preload="true" scale.left="30" scale.top="19" scale.right="35" scale.bottom="4" /> @@ -391,7 +393,7 @@ with the same filename but different name <texture name="ModelImport_Status_Good" file_name="green_checkmark.png" preload="false"/> <texture name="ModelImport_Status_Warning" file_name="lag_status_warning.tga" preload="false"/> <texture name="ModelImport_Status_Error" file_name="red_x.png" preload="false"/> - + <texture name="MouseLook_View_Off" file_name="bottomtray/Mouselook_View_Off.png" preload="false" /> <texture name="MouseLook_View_On" file_name="bottomtray/Mouselook_View_On.png" preload="false" /> @@ -547,7 +549,7 @@ with the same filename but different name <texture name="Profile_Perm_Objects_Enabled" file_name="icons/Profile_Perm_Objects_Enabled.png" preload="true"/> <texture name="Profile_Perm_Online_Disabled" file_name="icons/Profile_Perm_Online_Disabled.png" preload="true"/> <texture name="Profile_Perm_Online_Enabled" file_name="icons/Profile_Perm_Online_Enabled.png" preload="true"/> - + <texture name="ProgressBar" file_name="widgets/ProgressBar.png" preload="true" scale.left="4" scale.top="11" scale.right="48" scale.bottom="3" /> <texture name="ProgressBarSolid" file_name="widgets/ProgressBarSolid.png" preload="true" scale.left="4" scale.top="11" scale.right="48" scale.bottom="3" /> <texture name="ProgressTrack" file_name="widgets/ProgressTrack.png" preload="true" scale.left="4" scale.top="13" scale.right="148" scale.bottom="2" /> @@ -642,7 +644,7 @@ with the same filename but different name <texture name="SliderThumb_Disabled" file_name="widgets/SliderThumb_Disabled.png" /> <texture name="SliderThumb_Press" file_name="widgets/SliderThumb_Press.png" /> - <texture name="SL_Logo" file_name="icons/SL_Logo.png" preload="true" /> + <texture name="SL_Logo" file_name="icons/MP_Logo.png" preload="true" /> <texture name="OBJECT_Icon" file_name="icons/object_icon.png" preload="true" /> <texture name="Unknown_Icon" file_name="icons/unknown_icon.png" preload="true" /> @@ -653,8 +655,8 @@ with the same filename but different name <texture name="Snapshot_Profile" file_name="toolbar_icons/profile.png" preload="false" /> <texture name="startup_logo" file_name="windows/startup_logo.png" preload="true" /> - <texture name="login_sl_logo" file_name="windows/login_sl_logo.png" preload="true" /> - <texture name="login_sl_logo_small" file_name="windows/login_sl_logo_small.png" preload="true" /> + <texture name="login_mp_logo" file_name="windows/login_mp_logo.png" preload="true" /> + <texture name="login_mp_logo_small" file_name="windows/login_mp_logo_small.png" preload="true" /> <texture name="first_login_image" file_name="windows/first_login_image.jpg" preload="true" /> <texture name="Stepper_Down_Off" file_name="widgets/Stepper_Down_Off.png" preload="false" /> @@ -740,7 +742,7 @@ with the same filename but different name <texture name="UpArrow_Off" file_name="icons/UpArrow_Off.png" preload="false" /> <texture name="Video_URL_Off" file_name="icons/Video_URL_Off.png" preload="true" /> - + <texture name="Vertical Drag Handle" file_name="widgets/vertical_drag_handle.png" scale.left="2" scale.right="7" scale.bottom="8" scale.top="120" scale_type="scale_outer"/> <texture name="VirtualTrackball_Moon_Back" file_name="widgets/track_control_moon_back.png" /> @@ -756,7 +758,7 @@ with the same filename but different name <texture name="VirtualTrackball_Sphere" file_name="widgets/track_control_sphere.png" /> <texture name="VirtualTrackball_Sun_Back" file_name="widgets/track_control_sun_back.png" /> <texture name="VirtualTrackball_Sun_Front" file_name="widgets/track_control_sun_front.png" /> - + <texture name="Volume_Background" file_name="windows/Volume_Background.png" preload="false" scale.left="6" scale.top="33" scale.right="63" scale.bottom="10" /> @@ -765,7 +767,7 @@ with the same filename but different name <texture name="VoicePTT_Lvl3" file_name="bottomtray/VoicePTT_Lvl3.png" preload="false" /> <texture name="VoicePTT_Off" file_name="bottomtray/VoicePTT_Off.png" preload="false" /> <texture name="VoicePTT_On" file_name="bottomtray/VoicePTT_On.png" preload="false" /> - + <texture name="Wearables_Divider" file_name="windows/Wearables_Divider.png" preload="false" /> <texture name="Add_Icon" file_name="icons/add_icon.png" preload="false" /> @@ -780,9 +782,9 @@ with the same filename but different name scale.left="4" scale.top="24" scale.right="26" scale.bottom="4" /> <texture name="Window_Foreground" file_name="windows/Window_Foreground.png" preload="true" scale.left="4" scale.top="24" scale.right="26" scale.bottom="4" /> - <texture name="Window_NoTitle_Background" file_name="windows/Window_NoTitle_Background.png" preload="true" + <texture name="Window_NoTitle_Background" file_name="windows/Window_Background.png" preload="true" scale.left="4" scale.top="24" scale.right="26" scale.bottom="4" /> - <texture name="Window_NoTitle_Foreground" file_name="windows/Window_NoTitle_Foreground.png" preload="true" + <texture name="Window_NoTitle_Foreground" file_name="windows/Window_Foreground.png" preload="true" scale.left="4" scale.top="24" scale.right="26" scale.bottom="4" /> <texture name="YouAreHere_Badge" file_name="icons/YouAreHere_Badge.png" preload="false" /> @@ -880,7 +882,7 @@ with the same filename but different name <texture name="buy_off" file_name="widgets/buy_off.png" preload="true" scale.left="2" scale.top="15" scale.right="67" scale.bottom="4"/> <texture name="buy_over" file_name="widgets/buy_over.png" preload="true" scale.left="2" scale.top="15" scale.right="67" scale.bottom="4"/> <texture name="buy_press" file_name="widgets/buy_press.png" preload="true" scale.left="2" scale.top="15" scale.right="67" scale.bottom="4"/> - + <texture name="hint_background" file_name="windows/hint_background.png" preload="false" scale.left="8" scale.top="70" scale.right="195" scale.bottom="11"/> <texture name="hint_arrow_left" file_name="windows/hint_arrow_left.png" preload="false"/> <texture name="hint_arrow_right" file_name="windows/hint_arrow_right.png" preload="false"/> @@ -896,7 +898,7 @@ with the same filename but different name <texture name="Default_Outfit_Photo" file_name="icons/Default_Outfit_Photo.png" preload="true"/> <texture name="Notification_Condense" file_name="icons/Icon_Notification_Condense.png" preload="true"/> <texture name="Notification_Expand" file_name="icons/Icon_Notification_Expand.png" preload="true"/> - <texture name="System_Notification" file_name="icons/SL_Logo.png" preload="true"/> + <texture name="System_Notification" file_name="icons/MP_Logo.png" preload="true"/> <texture name="Icon_Attachment_Small" file_name="icons/Icon_Attachment_Small.png" preload="true"/> <texture name="Icon_Attachment_Large" file_name="icons/Icon_Attachment_Large.png" preload="true"/> @@ -907,4 +909,26 @@ with the same filename but different name <texture name="Single_Folder_Up" file_name="icons/single_folder_up.png" preload="true"/> <texture name="Icon_Color_Palette" file_name="icons/Icon_Color_Palette.png" preload="false"/> <texture name="Icon_Font_Size" file_name="icons/Icon_Font_Size.png" preload="false"/> + + <texture name="Icon_Place" file_name="megapahit/icon_place.png" preload="false" /> + <texture name="Icon_Auction" file_name="megapahit/icon_land_auction.png" preload="false" /> + <texture name="Icon_For_Sale" file_name="megapahit/icon_land_forsale.png" preload="false" /> + <texture name="Icon_Group" file_name="megapahit/icon_group.png" preload="false" /> + <texture name="Icon_Legacy_Event_PG" file_name="icons/Parcel_PG_Dark.png" preload="false" /> + <texture name="Icon_Legacy_Event_Mature" file_name="icons/Parcel_M_Dark.png" preload="false" /> + <texture name="Icon_Legacy_Event_Adult" file_name="icons/Parcel_R_Dark.png" preload="false" /> + + <texture name="ProgressLarge_1" file_name="icons/ProgressLarge_1.png" preload="true" /> + <texture name="ProgressLarge_2" file_name="icons/ProgressLarge_2.png" preload="true" /> + <texture name="ProgressLarge_3" file_name="icons/ProgressLarge_3.png" preload="true" /> + <texture name="ProgressLarge_4" file_name="icons/ProgressLarge_4.png" preload="true" /> + <texture name="ProgressLarge_5" file_name="icons/ProgressLarge_5.png" preload="true" /> + <texture name="ProgressLarge_6" file_name="icons/ProgressLarge_6.png" preload="true" /> + <texture name="ProgressLarge_7" file_name="icons/ProgressLarge_7.png" preload="true" /> + <texture name="ProgressLarge_8" file_name="icons/ProgressLarge_8.png" preload="true" /> + <texture name="ProgressLarge_9" file_name="icons/ProgressLarge_9.png" preload="true" /> + <texture name="ProgressLarge_10" file_name="icons/ProgressLarge_10.png" preload="true" /> + <texture name="ProgressLarge_11" file_name="icons/ProgressLarge_11.png" preload="true" /> + <texture name="ProgressLarge_12" file_name="icons/ProgressLarge_12.png" preload="true" /> + </textures> diff --git a/indra/newview/skins/default/textures/toolbar_icons/favorite_folder.png b/indra/newview/skins/default/textures/toolbar_icons/favorite_folder.png Binary files differnew file mode 100644 index 0000000000..811efffc0b --- /dev/null +++ b/indra/newview/skins/default/textures/toolbar_icons/favorite_folder.png diff --git a/indra/newview/skins/default/textures/toolbar_icons/highlighting_selected.png b/indra/newview/skins/default/textures/toolbar_icons/highlighting_selected.png Binary files differindex aa1bb26a56..ac75b22761 100644 --- a/indra/newview/skins/default/textures/toolbar_icons/highlighting_selected.png +++ b/indra/newview/skins/default/textures/toolbar_icons/highlighting_selected.png diff --git a/indra/newview/skins/default/textures/toolbar_icons/resync_animations.png b/indra/newview/skins/default/textures/toolbar_icons/resync_animations.png Binary files differnew file mode 100644 index 0000000000..dc9ee9c428 --- /dev/null +++ b/indra/newview/skins/default/textures/toolbar_icons/resync_animations.png diff --git a/indra/newview/skins/default/textures/toolbar_icons/twitter.png b/indra/newview/skins/default/textures/toolbar_icons/twitter.png Binary files differindex a99c490887..0ad56f7802 100644 --- a/indra/newview/skins/default/textures/toolbar_icons/twitter.png +++ b/indra/newview/skins/default/textures/toolbar_icons/twitter.png diff --git a/indra/newview/skins/default/textures/widgets/Arrow_Small_Down.png b/indra/newview/skins/default/textures/widgets/Arrow_Small_Down.png Binary files differnew file mode 100644 index 0000000000..8694cdf2d4 --- /dev/null +++ b/indra/newview/skins/default/textures/widgets/Arrow_Small_Down.png diff --git a/indra/newview/skins/default/textures/widgets/BreadCrumbBtn_Left_Off.png b/indra/newview/skins/default/textures/widgets/BreadCrumbBtn_Left_Off.png Binary files differindex 24bcfc4524..f7a6aaa275 100644 --- a/indra/newview/skins/default/textures/widgets/BreadCrumbBtn_Left_Off.png +++ b/indra/newview/skins/default/textures/widgets/BreadCrumbBtn_Left_Off.png diff --git a/indra/newview/skins/default/textures/widgets/BreadCrumbBtn_Left_Over.png b/indra/newview/skins/default/textures/widgets/BreadCrumbBtn_Left_Over.png Binary files differindex ca7ff3687a..48c21de265 100644 --- a/indra/newview/skins/default/textures/widgets/BreadCrumbBtn_Left_Over.png +++ b/indra/newview/skins/default/textures/widgets/BreadCrumbBtn_Left_Over.png diff --git a/indra/newview/skins/default/textures/widgets/BreadCrumbBtn_Left_Press.png b/indra/newview/skins/default/textures/widgets/BreadCrumbBtn_Left_Press.png Binary files differindex 6ae73ffcdd..3078c13d10 100644 --- a/indra/newview/skins/default/textures/widgets/BreadCrumbBtn_Left_Press.png +++ b/indra/newview/skins/default/textures/widgets/BreadCrumbBtn_Left_Press.png diff --git a/indra/newview/skins/default/textures/widgets/BreadCrumbBtn_Middle_Off.png b/indra/newview/skins/default/textures/widgets/BreadCrumbBtn_Middle_Off.png Binary files differindex 0147c4b9a7..fe2cfb3318 100644 --- a/indra/newview/skins/default/textures/widgets/BreadCrumbBtn_Middle_Off.png +++ b/indra/newview/skins/default/textures/widgets/BreadCrumbBtn_Middle_Off.png diff --git a/indra/newview/skins/default/textures/widgets/BreadCrumbBtn_Middle_Over.png b/indra/newview/skins/default/textures/widgets/BreadCrumbBtn_Middle_Over.png Binary files differindex 497642a620..e0e05b19d0 100644 --- a/indra/newview/skins/default/textures/widgets/BreadCrumbBtn_Middle_Over.png +++ b/indra/newview/skins/default/textures/widgets/BreadCrumbBtn_Middle_Over.png diff --git a/indra/newview/skins/default/textures/widgets/BreadCrumbBtn_Middle_Press.png b/indra/newview/skins/default/textures/widgets/BreadCrumbBtn_Middle_Press.png Binary files differindex 7bfe8e5d8d..2abb81e2b4 100644 --- a/indra/newview/skins/default/textures/widgets/BreadCrumbBtn_Middle_Press.png +++ b/indra/newview/skins/default/textures/widgets/BreadCrumbBtn_Middle_Press.png diff --git a/indra/newview/skins/default/textures/widgets/BreadCrumbBtn_Right_Off.png b/indra/newview/skins/default/textures/widgets/BreadCrumbBtn_Right_Off.png Binary files differindex dbf133cea6..f1effe6ad5 100644 --- a/indra/newview/skins/default/textures/widgets/BreadCrumbBtn_Right_Off.png +++ b/indra/newview/skins/default/textures/widgets/BreadCrumbBtn_Right_Off.png diff --git a/indra/newview/skins/default/textures/widgets/BreadCrumbBtn_Right_Over.png b/indra/newview/skins/default/textures/widgets/BreadCrumbBtn_Right_Over.png Binary files differindex f7990c37ae..f0109f1f78 100644 --- a/indra/newview/skins/default/textures/widgets/BreadCrumbBtn_Right_Over.png +++ b/indra/newview/skins/default/textures/widgets/BreadCrumbBtn_Right_Over.png diff --git a/indra/newview/skins/default/textures/widgets/BreadCrumbBtn_Right_Press.png b/indra/newview/skins/default/textures/widgets/BreadCrumbBtn_Right_Press.png Binary files differindex 71da02ae1d..3f2ea8737d 100644 --- a/indra/newview/skins/default/textures/widgets/BreadCrumbBtn_Right_Press.png +++ b/indra/newview/skins/default/textures/widgets/BreadCrumbBtn_Right_Press.png diff --git a/indra/newview/skins/default/textures/widgets/ComboButton_On.png b/indra/newview/skins/default/textures/widgets/ComboButton_On.png Binary files differindex 2739cb4684..368f907a1f 100644 --- a/indra/newview/skins/default/textures/widgets/ComboButton_On.png +++ b/indra/newview/skins/default/textures/widgets/ComboButton_On.png diff --git a/indra/newview/skins/default/textures/widgets/ComboButton_Selected.png b/indra/newview/skins/default/textures/widgets/ComboButton_Selected.png Binary files differindex 1a834bfbbc..15afcb04a1 100644 --- a/indra/newview/skins/default/textures/widgets/ComboButton_Selected.png +++ b/indra/newview/skins/default/textures/widgets/ComboButton_Selected.png diff --git a/indra/newview/skins/default/textures/widgets/ComboButton_UpSelected.png b/indra/newview/skins/default/textures/widgets/ComboButton_UpSelected.png Binary files differindex ff56367147..9583f05507 100644 --- a/indra/newview/skins/default/textures/widgets/ComboButton_UpSelected.png +++ b/indra/newview/skins/default/textures/widgets/ComboButton_UpSelected.png diff --git a/indra/newview/skins/default/textures/widgets/DropDown_On.png b/indra/newview/skins/default/textures/widgets/DropDown_On.png Binary files differindex 613a8c2ff6..3613e42a3f 100644 --- a/indra/newview/skins/default/textures/widgets/DropDown_On.png +++ b/indra/newview/skins/default/textures/widgets/DropDown_On.png diff --git a/indra/newview/skins/default/textures/widgets/DropDown_Press.png b/indra/newview/skins/default/textures/widgets/DropDown_Press.png Binary files differindex fa3a152df1..ec0ffc2e88 100644 --- a/indra/newview/skins/default/textures/widgets/DropDown_Press.png +++ b/indra/newview/skins/default/textures/widgets/DropDown_Press.png diff --git a/indra/newview/skins/default/textures/widgets/Linden_Dollar_Alert.png b/indra/newview/skins/default/textures/widgets/Linden_Dollar_Alert.png Binary files differindex 3b3f276e6d..76e078100f 100644 --- a/indra/newview/skins/default/textures/widgets/Linden_Dollar_Alert.png +++ b/indra/newview/skins/default/textures/widgets/Linden_Dollar_Alert.png diff --git a/indra/newview/skins/default/textures/widgets/Linden_Dollar_Background.png b/indra/newview/skins/default/textures/widgets/Linden_Dollar_Background.png Binary files differindex ba4ab2d0c9..6e71ef7b72 100644 --- a/indra/newview/skins/default/textures/widgets/Linden_Dollar_Background.png +++ b/indra/newview/skins/default/textures/widgets/Linden_Dollar_Background.png diff --git a/indra/newview/skins/default/textures/widgets/ListItem_Over.png b/indra/newview/skins/default/textures/widgets/ListItem_Over.png Binary files differindex e72c1c4020..8c80522232 100644 --- a/indra/newview/skins/default/textures/widgets/ListItem_Over.png +++ b/indra/newview/skins/default/textures/widgets/ListItem_Over.png diff --git a/indra/newview/skins/default/textures/widgets/ListItem_Select.png b/indra/newview/skins/default/textures/widgets/ListItem_Select.png Binary files differindex 0e16a8b454..b27e0ee787 100644 --- a/indra/newview/skins/default/textures/widgets/ListItem_Select.png +++ b/indra/newview/skins/default/textures/widgets/ListItem_Select.png diff --git a/indra/newview/skins/default/textures/widgets/MarketplaceBtn_Selected.png b/indra/newview/skins/default/textures/widgets/MarketplaceBtn_Selected.png Binary files differindex 8bfa3acb42..6020fadc5a 100644 --- a/indra/newview/skins/default/textures/widgets/MarketplaceBtn_Selected.png +++ b/indra/newview/skins/default/textures/widgets/MarketplaceBtn_Selected.png diff --git a/indra/newview/skins/default/textures/widgets/ProgressBar.png b/indra/newview/skins/default/textures/widgets/ProgressBar.png Binary files differindex 4d0d123987..492d9b6fc4 100644 --- a/indra/newview/skins/default/textures/widgets/ProgressBar.png +++ b/indra/newview/skins/default/textures/widgets/ProgressBar.png diff --git a/indra/newview/skins/default/textures/widgets/PushButton_Off.png b/indra/newview/skins/default/textures/widgets/PushButton_Off.png Binary files differindex 29eeed7c78..c74cea62d3 100644 --- a/indra/newview/skins/default/textures/widgets/PushButton_Off.png +++ b/indra/newview/skins/default/textures/widgets/PushButton_Off.png diff --git a/indra/newview/skins/default/textures/widgets/PushButton_On.png b/indra/newview/skins/default/textures/widgets/PushButton_On.png Binary files differindex 65d92a9d82..e387c7e313 100644 --- a/indra/newview/skins/default/textures/widgets/PushButton_On.png +++ b/indra/newview/skins/default/textures/widgets/PushButton_On.png diff --git a/indra/newview/skins/default/textures/widgets/PushButton_On_Selected.png b/indra/newview/skins/default/textures/widgets/PushButton_On_Selected.png Binary files differindex 8588576fb0..ee1329e842 100644 --- a/indra/newview/skins/default/textures/widgets/PushButton_On_Selected.png +++ b/indra/newview/skins/default/textures/widgets/PushButton_On_Selected.png diff --git a/indra/newview/skins/default/textures/widgets/PushButton_Over.png b/indra/newview/skins/default/textures/widgets/PushButton_Over.png Binary files differindex 819f27c0ba..34a64a3ade 100644 --- a/indra/newview/skins/default/textures/widgets/PushButton_Over.png +++ b/indra/newview/skins/default/textures/widgets/PushButton_Over.png diff --git a/indra/newview/skins/default/textures/widgets/PushButton_Press.png b/indra/newview/skins/default/textures/widgets/PushButton_Press.png Binary files differindex b0a92d8ffe..79fc601f27 100644 --- a/indra/newview/skins/default/textures/widgets/PushButton_Press.png +++ b/indra/newview/skins/default/textures/widgets/PushButton_Press.png diff --git a/indra/newview/skins/default/textures/widgets/PushButton_Selected.png b/indra/newview/skins/default/textures/widgets/PushButton_Selected.png Binary files differindex b0a92d8ffe..7d9cb29a7b 100644 --- a/indra/newview/skins/default/textures/widgets/PushButton_Selected.png +++ b/indra/newview/skins/default/textures/widgets/PushButton_Selected.png diff --git a/indra/newview/skins/default/textures/widgets/PushButton_Selected_Disabled.png b/indra/newview/skins/default/textures/widgets/PushButton_Selected_Disabled.png Binary files differindex 65d92a9d82..6332412692 100644 --- a/indra/newview/skins/default/textures/widgets/PushButton_Selected_Disabled.png +++ b/indra/newview/skins/default/textures/widgets/PushButton_Selected_Disabled.png diff --git a/indra/newview/skins/default/textures/widgets/PushButton_Selected_Press.png b/indra/newview/skins/default/textures/widgets/PushButton_Selected_Press.png Binary files differindex 8588576fb0..e2818da352 100644 --- a/indra/newview/skins/default/textures/widgets/PushButton_Selected_Press.png +++ b/indra/newview/skins/default/textures/widgets/PushButton_Selected_Press.png diff --git a/indra/newview/skins/default/textures/widgets/SegmentedBtn_Left_Selected_Disabled.png b/indra/newview/skins/default/textures/widgets/SegmentedBtn_Left_Selected_Disabled.png Binary files differindex 300a7d73cd..b78f2bc62e 100644 --- a/indra/newview/skins/default/textures/widgets/SegmentedBtn_Left_Selected_Disabled.png +++ b/indra/newview/skins/default/textures/widgets/SegmentedBtn_Left_Selected_Disabled.png diff --git a/indra/newview/skins/default/textures/widgets/SegmentedBtn_Left_Selected_Over.png b/indra/newview/skins/default/textures/widgets/SegmentedBtn_Left_Selected_Over.png Binary files differindex c7ee699210..f2abcb3ce0 100644 --- a/indra/newview/skins/default/textures/widgets/SegmentedBtn_Left_Selected_Over.png +++ b/indra/newview/skins/default/textures/widgets/SegmentedBtn_Left_Selected_Over.png diff --git a/indra/newview/skins/default/textures/widgets/SegmentedBtn_Left_Selected_Press.png b/indra/newview/skins/default/textures/widgets/SegmentedBtn_Left_Selected_Press.png Binary files differindex f9cb95ff4b..9a14e7c69d 100644 --- a/indra/newview/skins/default/textures/widgets/SegmentedBtn_Left_Selected_Press.png +++ b/indra/newview/skins/default/textures/widgets/SegmentedBtn_Left_Selected_Press.png diff --git a/indra/newview/skins/default/textures/widgets/SegmentedBtn_Middle_Selected_Disabled.png b/indra/newview/skins/default/textures/widgets/SegmentedBtn_Middle_Selected_Disabled.png Binary files differindex 6223ad8dfe..7b612ade9c 100644 --- a/indra/newview/skins/default/textures/widgets/SegmentedBtn_Middle_Selected_Disabled.png +++ b/indra/newview/skins/default/textures/widgets/SegmentedBtn_Middle_Selected_Disabled.png diff --git a/indra/newview/skins/default/textures/widgets/SegmentedBtn_Middle_Selected_Press.png b/indra/newview/skins/default/textures/widgets/SegmentedBtn_Middle_Selected_Press.png Binary files differindex 101d5a0930..eb08fed30e 100644 --- a/indra/newview/skins/default/textures/widgets/SegmentedBtn_Middle_Selected_Press.png +++ b/indra/newview/skins/default/textures/widgets/SegmentedBtn_Middle_Selected_Press.png diff --git a/indra/newview/skins/default/textures/widgets/SegmentedBtn_Right_On_Selected.png b/indra/newview/skins/default/textures/widgets/SegmentedBtn_Right_On_Selected.png Binary files differindex fd1dd4207c..ffcb2772e0 100644 --- a/indra/newview/skins/default/textures/widgets/SegmentedBtn_Right_On_Selected.png +++ b/indra/newview/skins/default/textures/widgets/SegmentedBtn_Right_On_Selected.png diff --git a/indra/newview/skins/default/textures/widgets/SegmentedBtn_Right_Selected_Disabled.png b/indra/newview/skins/default/textures/widgets/SegmentedBtn_Right_Selected_Disabled.png Binary files differindex fdf09e920d..d8f02b3730 100644 --- a/indra/newview/skins/default/textures/widgets/SegmentedBtn_Right_Selected_Disabled.png +++ b/indra/newview/skins/default/textures/widgets/SegmentedBtn_Right_Selected_Disabled.png diff --git a/indra/newview/skins/default/textures/widgets/SegmentedBtn_Right_Selected_Press.png b/indra/newview/skins/default/textures/widgets/SegmentedBtn_Right_Selected_Press.png Binary files differindex 144d23cc6c..3d93e5e73b 100644 --- a/indra/newview/skins/default/textures/widgets/SegmentedBtn_Right_Selected_Press.png +++ b/indra/newview/skins/default/textures/widgets/SegmentedBtn_Right_Selected_Press.png diff --git a/indra/newview/skins/default/textures/widgets/Stepper_Down_Off.png b/indra/newview/skins/default/textures/widgets/Stepper_Down_Off.png Binary files differindex 51d269bd45..ff21034095 100644 --- a/indra/newview/skins/default/textures/widgets/Stepper_Down_Off.png +++ b/indra/newview/skins/default/textures/widgets/Stepper_Down_Off.png diff --git a/indra/newview/skins/default/textures/widgets/Stepper_Down_Press.png b/indra/newview/skins/default/textures/widgets/Stepper_Down_Press.png Binary files differindex b4f19b7dbb..edd485afed 100644 --- a/indra/newview/skins/default/textures/widgets/Stepper_Down_Press.png +++ b/indra/newview/skins/default/textures/widgets/Stepper_Down_Press.png diff --git a/indra/newview/skins/default/textures/widgets/Stepper_Up_Off.png b/indra/newview/skins/default/textures/widgets/Stepper_Up_Off.png Binary files differindex a01d928aef..133845bdbc 100644 --- a/indra/newview/skins/default/textures/widgets/Stepper_Up_Off.png +++ b/indra/newview/skins/default/textures/widgets/Stepper_Up_Off.png diff --git a/indra/newview/skins/default/textures/widgets/Stepper_Up_Press.png b/indra/newview/skins/default/textures/widgets/Stepper_Up_Press.png Binary files differindex d5b672d943..dffd557bbd 100644 --- a/indra/newview/skins/default/textures/widgets/Stepper_Up_Press.png +++ b/indra/newview/skins/default/textures/widgets/Stepper_Up_Press.png diff --git a/indra/newview/skins/default/textures/widgets/TextField_Active.png b/indra/newview/skins/default/textures/widgets/TextField_Active.png Binary files differindex 9eb5b6a36e..66c3867b81 100644 --- a/indra/newview/skins/default/textures/widgets/TextField_Active.png +++ b/indra/newview/skins/default/textures/widgets/TextField_Active.png diff --git a/indra/newview/skins/default/textures/widgets/TextField_Disabled.png b/indra/newview/skins/default/textures/widgets/TextField_Disabled.png Binary files differindex 3b1ac6b9ed..baf747f581 100644 --- a/indra/newview/skins/default/textures/widgets/TextField_Disabled.png +++ b/indra/newview/skins/default/textures/widgets/TextField_Disabled.png diff --git a/indra/newview/skins/default/textures/widgets/TextField_Off.png b/indra/newview/skins/default/textures/widgets/TextField_Off.png Binary files differindex afe091d613..a35562f950 100644 --- a/indra/newview/skins/default/textures/widgets/TextField_Off.png +++ b/indra/newview/skins/default/textures/widgets/TextField_Off.png diff --git a/indra/newview/skins/default/textures/widgets/buy_off.png b/indra/newview/skins/default/textures/widgets/buy_off.png Binary files differindex 7af02357ac..517e6f9e54 100644 --- a/indra/newview/skins/default/textures/widgets/buy_off.png +++ b/indra/newview/skins/default/textures/widgets/buy_off.png diff --git a/indra/newview/skins/default/textures/widgets/buy_over.png b/indra/newview/skins/default/textures/widgets/buy_over.png Binary files differindex 5dafd9f47e..c17395d2e7 100644 --- a/indra/newview/skins/default/textures/widgets/buy_over.png +++ b/indra/newview/skins/default/textures/widgets/buy_over.png diff --git a/indra/newview/skins/default/textures/widgets/buy_press.png b/indra/newview/skins/default/textures/widgets/buy_press.png Binary files differindex 83db005fd7..96f818e69f 100644 --- a/indra/newview/skins/default/textures/widgets/buy_press.png +++ b/indra/newview/skins/default/textures/widgets/buy_press.png diff --git a/indra/newview/skins/default/textures/widgets/track_control_sphere.png b/indra/newview/skins/default/textures/widgets/track_control_sphere.png Binary files differindex 60a81d1fea..b6592b5992 100644 --- a/indra/newview/skins/default/textures/widgets/track_control_sphere.png +++ b/indra/newview/skins/default/textures/widgets/track_control_sphere.png diff --git a/indra/newview/skins/default/textures/windows/Inspector_I.png b/indra/newview/skins/default/textures/windows/Inspector_I.png Binary files differindex 843f6e9fbe..0d1719c66f 100644 --- a/indra/newview/skins/default/textures/windows/Inspector_I.png +++ b/indra/newview/skins/default/textures/windows/Inspector_I.png diff --git a/indra/newview/skins/default/textures/windows/Resize_Corner.png b/indra/newview/skins/default/textures/windows/Resize_Corner.png Binary files differindex f52b7ced4a..4a533011df 100644 --- a/indra/newview/skins/default/textures/windows/Resize_Corner.png +++ b/indra/newview/skins/default/textures/windows/Resize_Corner.png diff --git a/indra/newview/skins/default/textures/windows/Window_Background.png b/indra/newview/skins/default/textures/windows/Window_Background.png Binary files differindex 9864ec0db8..f19fb0300b 100644 --- a/indra/newview/skins/default/textures/windows/Window_Background.png +++ b/indra/newview/skins/default/textures/windows/Window_Background.png diff --git a/indra/newview/skins/default/textures/windows/Window_Foreground.png b/indra/newview/skins/default/textures/windows/Window_Foreground.png Binary files differindex a86b236504..15d2ff72b6 100644 --- a/indra/newview/skins/default/textures/windows/Window_Foreground.png +++ b/indra/newview/skins/default/textures/windows/Window_Foreground.png diff --git a/indra/newview/skins/default/textures/windows/Window_NoTitle_Background.png b/indra/newview/skins/default/textures/windows/Window_NoTitle_Background.png Binary files differdeleted file mode 100644 index d01f82a310..0000000000 --- a/indra/newview/skins/default/textures/windows/Window_NoTitle_Background.png +++ /dev/null diff --git a/indra/newview/skins/default/textures/windows/Window_NoTitle_Foreground.png b/indra/newview/skins/default/textures/windows/Window_NoTitle_Foreground.png Binary files differdeleted file mode 100644 index 1966400641..0000000000 --- a/indra/newview/skins/default/textures/windows/Window_NoTitle_Foreground.png +++ /dev/null diff --git a/indra/newview/skins/default/textures/windows/add_payment_image_center.png b/indra/newview/skins/default/textures/windows/add_payment_image_center.png Binary files differindex fa3575f53d..0b99a72f32 100644 --- a/indra/newview/skins/default/textures/windows/add_payment_image_center.png +++ b/indra/newview/skins/default/textures/windows/add_payment_image_center.png diff --git a/indra/newview/skins/default/textures/windows/add_payment_image_left.png b/indra/newview/skins/default/textures/windows/add_payment_image_left.png Binary files differindex a3c154477f..a5b28d7023 100644 --- a/indra/newview/skins/default/textures/windows/add_payment_image_left.png +++ b/indra/newview/skins/default/textures/windows/add_payment_image_left.png diff --git a/indra/newview/skins/default/textures/windows/add_payment_image_right.png b/indra/newview/skins/default/textures/windows/add_payment_image_right.png Binary files differindex 1edc10064d..5724d39744 100644 --- a/indra/newview/skins/default/textures/windows/add_payment_image_right.png +++ b/indra/newview/skins/default/textures/windows/add_payment_image_right.png diff --git a/indra/newview/skins/default/textures/windows/first_login_image.jpg b/indra/newview/skins/default/textures/windows/first_login_image.jpg Binary files differindex 30f31341ed..860fed4ac7 100644 --- a/indra/newview/skins/default/textures/windows/first_login_image.jpg +++ b/indra/newview/skins/default/textures/windows/first_login_image.jpg diff --git a/indra/newview/skins/default/textures/windows/login_mp_logo.png b/indra/newview/skins/default/textures/windows/login_mp_logo.png Binary files differnew file mode 100644 index 0000000000..7526374ba2 --- /dev/null +++ b/indra/newview/skins/default/textures/windows/login_mp_logo.png diff --git a/indra/newview/skins/default/textures/windows/login_mp_logo_small.png b/indra/newview/skins/default/textures/windows/login_mp_logo_small.png Binary files differnew file mode 100644 index 0000000000..779d8ff649 --- /dev/null +++ b/indra/newview/skins/default/textures/windows/login_mp_logo_small.png diff --git a/indra/newview/skins/default/textures/world/NoEntryLines.png b/indra/newview/skins/default/textures/world/NoEntryLines.png Binary files differindex d7496b8bd0..b295ba1281 100644 --- a/indra/newview/skins/default/textures/world/NoEntryLines.png +++ b/indra/newview/skins/default/textures/world/NoEntryLines.png diff --git a/indra/newview/skins/default/textures/world/NoEntryPassLines.png b/indra/newview/skins/default/textures/world/NoEntryPassLines.png Binary files differindex e4b8fc6ae2..34900e2c02 100644 --- a/indra/newview/skins/default/textures/world/NoEntryPassLines.png +++ b/indra/newview/skins/default/textures/world/NoEntryPassLines.png diff --git a/indra/newview/skins/default/xui/da/floater_avatar_textures.xml b/indra/newview/skins/default/xui/da/floater_avatar_textures.xml index d0d766eaab..e7fe66c73f 100644 --- a/indra/newview/skins/default/xui/da/floater_avatar_textures.xml +++ b/indra/newview/skins/default/xui/da/floater_avatar_textures.xml @@ -14,7 +14,7 @@ teksturer teksturer </text> <button label="Vis IDs på skærm" label_selected="Dump" name="Dump"/> - <panel name="scroll_content_panel"> + <panel name="scroll_content_panel2"> <texture_picker label="Hår" name="hair-baked"/> <texture_picker label="Hår" name="hair_grain"/> <texture_picker label="Alpha - hår" name="hair_alpha"/> diff --git a/indra/newview/skins/default/xui/da/language_settings.xml b/indra/newview/skins/default/xui/da/language_settings.xml index d31afb320a..d15a7c583a 100644 --- a/indra/newview/skins/default/xui/da/language_settings.xml +++ b/indra/newview/skins/default/xui/da/language_settings.xml @@ -8,6 +8,7 @@ <string name="macOSLocale">da_DK.UTF-8</string> <string name="DarwinLocale">da_DK.UTF-8</string> <string name="LinuxLocale">da_DK.UTF-8</string> + <string name="FreeBSDLocale">da_DK.UTF-8</string> <!-- datetimeToCodes["wkday"] = "%a"; // Thu diff --git a/indra/newview/skins/default/xui/da/strings.xml b/indra/newview/skins/default/xui/da/strings.xml index e4f99d14e9..a7dff91311 100644 --- a/indra/newview/skins/default/xui/da/strings.xml +++ b/indra/newview/skins/default/xui/da/strings.xml @@ -5,7 +5,7 @@ that are returned from one component and may appear in many places--> <strings> <string name="CAPITALIZED_APP_NAME"> - SECOND LIFE + MEGAPAHIT </string> <string name="SUPPORT_SITE"> Second Life Support Portal @@ -429,7 +429,7 @@ Prøv venligst om lidt igen. Noter om version </string> <string name="RELEASE_NOTES_BASE_URL"> - https://releasenotes.secondlife.com/viewer/ + https://megapahit.net/ </string> <string name="LoadingData"> Henter... diff --git a/indra/newview/skins/default/xui/de/floater_avatar_textures.xml b/indra/newview/skins/default/xui/de/floater_avatar_textures.xml index aed9aa6e78..915ef3067f 100644 --- a/indra/newview/skins/default/xui/de/floater_avatar_textures.xml +++ b/indra/newview/skins/default/xui/de/floater_avatar_textures.xml @@ -8,7 +8,7 @@ Texturen</text> <text name="composite_label">Zusammengesetzte Texturen</text> <button label="IDs an Konsole ausgeben" label_selected="Abladen" name="Dump"/> - <panel name="scroll_content_panel"> + <panel name="scroll_content_panel2"> <texture_picker label="Haare" name="hair-baked"/> <texture_picker label="Haare" name="hair_grain"/> <texture_picker label="Alpha: Haare" name="hair_alpha"/> diff --git a/indra/newview/skins/default/xui/de/language_settings.xml b/indra/newview/skins/default/xui/de/language_settings.xml index 57a327b345..bfd9ad60cd 100644 --- a/indra/newview/skins/default/xui/de/language_settings.xml +++ b/indra/newview/skins/default/xui/de/language_settings.xml @@ -8,6 +8,7 @@ <string name="macOSLocale">de_DE.UTF-8</string> <string name="DarwinLocale">de_DE.UTF-8</string> <string name="LinuxLocale">de_DE.UTF-8</string> + <string name="FreeBSDLocale">de_DE.UTF-8</string> <!-- datetimeToCodes["wkday"] = "%a"; // Thu diff --git a/indra/newview/skins/default/xui/de/panel_progress.xml b/indra/newview/skins/default/xui/de/panel_progress.xml index 8d1abdcac1..c9bed9fd9b 100644 --- a/indra/newview/skins/default/xui/de/panel_progress.xml +++ b/indra/newview/skins/default/xui/de/panel_progress.xml @@ -1,10 +1,8 @@ <?xml version="1.0" ?> <panel name="login_progress_panel"> - <layout_panel name="panel_icons"/> <layout_stack name="vertical_centering"/> <layout_panel name="panel4"/> <layout_panel name="center"/> <layout_stack name="horizontal_centering"> - <text name="logos_lbl">Second Life verwendet</text> </layout_stack> </panel> diff --git a/indra/newview/skins/default/xui/de/strings.xml b/indra/newview/skins/default/xui/de/strings.xml index a9e7626dc5..4bed43dd1d 100644 --- a/indra/newview/skins/default/xui/de/strings.xml +++ b/indra/newview/skins/default/xui/de/strings.xml @@ -1,8 +1,8 @@ <?xml version="1.0" ?> <strings> <string name="SECOND_LIFE">Second Life</string> - <string name="APP_NAME">Second Life</string> - <string name="CAPITALIZED_APP_NAME">SECOND LIFE</string> + <string name="APP_NAME">Megapahit</string> + <string name="CAPITALIZED_APP_NAME">MEGAPAHIT</string> <string name="SECOND_LIFE_GRID">Second Life-Grid:</string> <string name="SUPPORT_SITE">Second Life Support-Portal</string> <string name="StartupDetectingHardware">Hardware wird erfasst...</string> @@ -31,7 +31,6 @@ Sichtweite: [DRAW_DISTANCE] m Bandbreite: [NET_BANDWITH] kbit/s LOD-Faktor: [LOD_FACTOR] Darstellungsqualität: [RENDER_QUALITY] -Erweitertes Beleuchtungsmodell: [GPU_SHADERS] Texturspeicher: [TEXTURE_MEMORY] MB</string> <string name="AboutOSXHiDPI">HiDPI-Anzeigemodus: [HIDPI]</string> <string name="AboutLibs">J2C-Decoderversion: [J2C_VERSION] @@ -267,7 +266,7 @@ nächsten Eigentümer angehängt werden.</string> <string name="NoneFound">Nicht gefunden.</string> <string name="RetrievingData">Laden...</string> <string name="ReleaseNotes">Versionshinweise</string> - <string name="RELEASE_NOTES_BASE_URL">https://releasenotes.secondlife.com/viewer/</string> + <string name="RELEASE_NOTES_BASE_URL">https://megapahit.net/</string> <string name="LoadingData">Wird geladen...</string> <string name="AvatarNameNobody">(niemand)</string> <string name="AvatarNameWaiting">(wartet)</string> diff --git a/indra/newview/skins/default/xui/en/floater_about.xml b/indra/newview/skins/default/xui/en/floater_about.xml index 126cd84d56..89c6e41a85 100644 --- a/indra/newview/skins/default/xui/en/floater_about.xml +++ b/indra/newview/skins/default/xui/en/floater_about.xml @@ -2,7 +2,7 @@ <floater positioning="centered" legacy_header_height="18" - height="440" + height="520" layout="topleft" name="floater_about" help_topic="floater_about" @@ -14,7 +14,7 @@ follows="all" top="25" left="10" - height="405" + height="490" width="480" name="about_tab" tab_position="top"> @@ -27,7 +27,7 @@ parse_urls="true" follows="top|left" font="SansSerif" - height="343" + height="432" bg_readonly_color="Transparent" left="5" max_length="65536" @@ -46,17 +46,126 @@ </panel> <panel border="true" + has_border="true" label="Credits" help_topic="about_credits_tab" name="credits_panel"> + <accordion + fit_parent="false" + follows="all" + layout="topleft" + left="2" + name="credits_accordion" + single_expansion="true" + top="0" + right="-1"> + <accordion_tab + expanded="true" + fit_panel="false" + layout="topleft" + name="mp_credits_tab" + title="Megapahit"> + <panel + border="false" + follows="all" + left="10" + name="megapahit_credits_panel" + height="405" + top="10"> <text follows="top|left|right" + font.style="BOLD" + height="10" + layout="topleft" + left="5" + top="0" + width="435" + wrap="true"> +Megapahit is brought to you by (in order of appearance): + </text> + <text_editor + enabled="false" + follows="top|left" + height="245" + bg_readonly_color="Transparent" + left="5" + text_color="LtGray" + max_length="65536" + top_pad="5" + width="545" + word_wrap="true"> +Erik Kundiman +LinneNoir +milo (observeur) +Fritigern Gothly +Kou Ayashi +Hadet Sonnenkern +Remmy (Secret Foxtail) +Eris Ravenwood +gwigz (nya) +EmilyAmiee +Bavid Dailey +Aria (Tashia Redrose) +Cate (32a) +Hiroo Ono +Melodey +Keysin (scoutkeysin) +Yikes Lopez + </text_editor> + <text + follows="top|left" + font.style="BOLD" + height="10" + layout="topleft" + left="5" + top_pad="5" + width="465" + wrap="true"> +with special thanks to (in order of appearance): + </text> +<text_editor + enabled="false" + follows="top|left" + height="130" + bg_readonly_color="Transparent" + left="5" + text_color="LtGray" + max_length="65536" + name="megapahit_contributors" + top_pad="5" + width="450" + word_wrap="true"> +Chorazin Allen and Nicky Perian for involving Erik Kundiman in viewer developments; +JenniWindrider for the pre-MP donation that was used to help build the website; +Vir Linden for making it possible for the project to have a place (in every sense of the word) in SL; +nutsobvious for the early testing and video proof; +Soft Linden for the security testing; and +Kyle Linden for selling TPV parcel 2 to Erik Kundiman at L$0 price. + </text_editor> + </panel> + </accordion_tab> + <accordion_tab + expanded="true" + fit_panel="false" + layout="topleft" + name="sl_credits_tab" + title="Second Life"> + <panel + border="false" + follows="all" + left="10" + name="sl_credits_panel" + height="500" + top="10"> + <text + follows="top|left|right" + font.style="BOLD" height="20" layout="topleft" left="5" name="linden_intro" - top="10" - width="465" + top="0" + width="365" wrap="true"> Second Life is brought to you by the Lindens, with open source contributions from: @@ -64,18 +173,21 @@ with open source contributions from: <text_editor enabled="false" follows="top|left" - height="340" + height="375" bg_readonly_color="Transparent" left="5" text_color="LtGray" max_length="65536" name="contrib_names" top_pad="10" - width="465" + width="415" word_wrap="true"> Dummy Name replaced at run time </text_editor> </panel> + </accordion_tab> +</accordion> + </panel> <panel border="true" label="Licenses" @@ -97,30 +209,23 @@ Dummy Name replaced at run time APR Copyright (C) 2011 The Apache Software Foundation Collada DOM Copyright 2006 Sony Computer Entertainment Inc. cURL Copyright (C) 1996-2010, Daniel Stenberg, (daniel@haxx.se) - DBus/dbus-glib Copyright (C) 2002, 2003 CodeFactory AB / Copyright (C) 2003, 2004 Red Hat, Inc. expat Copyright (C) 1998, 1999, 2000 Thai Open Source Software Center Ltd. FreeType Copyright (C) 1996-2002, 2006 David Turner, Robert Wilhelm, and Werner Lemberg. GL Copyright (C) 1999-2004 Brian Paul. - google-perftools Copyright (c) 2005, Google Inc. - Havok.com(TM) Copyright (C) 1999-2001, Telekinesys Research Limited. - jpeg2000 Copyright (C) 2001, David Taubman, The University of New South Wales (UNSW) jpeglib Copyright (C) 1991-1998, Thomas G. Lane. + llphysicsextensions_tpv Copyright (c) 2010, Linden Research, Inc. meshoptimizer Copyright (c) 2016-2021 Arseny Kapoulkine ogg/vorbis Copyright (C) 2002, Xiphophorus OpenSSL Copyright (C) 1998-2008 The OpenSSL Project. PCRE Copyright (c) 1997-2012 University of Cambridge - SDL Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 Sam Lantinga + SDL Copyright (C) 1997-2024 Sam Lantinga SSLeay Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) xxHash Copyright (C) 2012-2020 Yann Collet. zlib Copyright (C) 1995-2012 Jean-loup Gailly and Mark Adler. - Second Life Viewer uses Havok (TM) Physics. (c)Copyright 1999-2010 Havok.com Inc. (and its Licensors). All Rights Reserved. See www.havok.com for details. - This software contains source code provided by NVIDIA Corporation. All rights reserved. See licenses.txt for details. - - Voice chat Audio coding: Polycom(R) Siren14(TM) (ITU-T Rec. G.722.1 Annex C) </text_editor> </panel> </tab_container> diff --git a/indra/newview/skins/default/xui/en/floater_avatar_textures.xml b/indra/newview/skins/default/xui/en/floater_avatar_textures.xml index 09026884b9..831368f4de 100644 --- a/indra/newview/skins/default/xui/en/floater_avatar_textures.xml +++ b/indra/newview/skins/default/xui/en/floater_avatar_textures.xml @@ -70,13 +70,13 @@ Textures width="150" /> <panel - name="scroll_content_panel" + name="scroll_content_panel2" follows="left|top" min_height="300" layout="topleft" - top="43" + top="60" background_visible="false" - height="930" + height="1113" left="0" width="1230"> @@ -86,7 +86,7 @@ Textures layout="topleft" left="10" name="hair-baked" - top="17" + top="3" width="92" /> <texture_picker height="103" diff --git a/indra/newview/skins/default/xui/en/floater_camera.xml b/indra/newview/skins/default/xui/en/floater_camera.xml index 93b306d7d7..4f45625828 100644 --- a/indra/newview/skins/default/xui/en/floater_camera.xml +++ b/indra/newview/skins/default/xui/en/floater_camera.xml @@ -5,9 +5,11 @@ bottom="-50" follows="left|bottom" legacy_header_height="18" - can_minimize="true" + can_minimize="false" + can_collapse="false" can_close="true" - height="135" + width="370" + height="114" layout="topleft" name="camera_floater" help_topic="camera_floater" @@ -15,8 +17,7 @@ single_instance="true" title="CAMERA CONTROLS" chrome="true" - save_rect="true" - width="400"> + save_rect="true"> <floater.string name="rotate_tooltip"> Rotate Camera Around Focus @@ -36,110 +37,137 @@ <string name="inactive_combo_text">Use preset</string> <panel border="false" - height="123" + width="168" + height="96" layout="topleft" left="2" - top="0" + top="18" mouse_opaque="false" name="controls" - width="220"> - <!--TODO: replace + - images --> + > <panel border="false" class="camera_zoom_panel" - height="123" + height="76" layout="topleft" left="0" mouse_opaque="false" name="zoom" top="0" - width="220"> + width="168"> <joystick_rotate follows="top|left" - height="78" + width="60" + height="60" layout="topleft" left="7" + top="8" name="cam_rotate_stick" quadrant="left" sound_flags="3" visible="true" + scale_image="true" tool_tip="Orbit camera around focus" - top="25" - width="78" /> - <button + /> + <joystick_track follows="top|left" - height="18" - image_disabled="AddItem_Disabled" - image_selected="AddItem_Press" - image_unselected="AddItem_Off" + width="60" + height="60" + left_pad="4" + image_selected="Cam_Tracking_In" + image_unselected="Cam_Tracking_Out" layout="topleft" - left_pad="14" - name="zoom_plus_btn" + name="cam_track_stick" + quadrant="left" + scale_image="true" + sound_flags="3" + tool_tip="Move camera up and down, left and right" + /> + <button + follows="top|left" + width="18" + height="18" + top="8" + left_pad="8" + layout="topleft" + name="collapse_btn" + > + </button> + <button + follows="top|left" + width="18" + height="18" + top_pad="4" + layout="topleft" + name="precise_btn" + image_disabled="Cam_FreeCam_Off" + image_selected="Cam_FreeCam_Off" + image_unselected="Cam_FreeCam_Off" + tool_tip="Use precise controls" + > + </button> + </panel> + <panel + border="false" + class="camera_zoom_panel" + height="18" + layout="topleft" + left="0" + mouse_opaque="false" + name="zoom" + top_pad="0" + width="150"> + <button + follows="top|left" width="18" - top="23"> + height="18" + left="2" + top="0" + layout="topleft" + image_disabled="MinusItem_Disabled" + image_selected="MinusItem_Press" + image_unselected="MinusItem_Off" + name="zoom_minus_btn" + > <commit_callback - function="Zoom.plus" /> + function="Zoom.minus" /> <mouse_held_callback - function="Zoom.plus" /> + function="Zoom.minus" /> </button> <slider_bar - height="50" + width="100" + height="18" + left_pad="2" layout="topleft" name="zoom_slider" - orientation="vertical" + orientation="horizontal" tool_tip="Zoom camera toward focus" - top_pad="0" min_val="0" - max_val="1" - width="18"> + max_val="1" + > <commit_callback function="Slider.value_changed"/> </slider_bar> <button - follows="top|left" + follows="bottom|left" + width="18" height="18" - image_disabled="MinusItem_Disabled" - image_selected="MinusItem_Press" - image_unselected="MinusItem_Off" + left_pad="2" layout="topleft" - name="zoom_minus_btn" - top_pad="0" - width="18"> + image_disabled="AddItem_Disabled" + image_selected="AddItem_Press" + image_unselected="AddItem_Off" + name="zoom_plus_btn" + > <commit_callback - function="Zoom.minus" /> + function="Zoom.plus" /> <mouse_held_callback - function="Zoom.minus" /> + function="Zoom.plus" /> </button> - <joystick_track - follows="top|left" - height="78" - image_selected="Cam_Tracking_In" - image_unselected="Cam_Tracking_Out" - layout="topleft" - left="133" - name="cam_track_stick" - quadrant="left" - scale_image="false" - sound_flags="3" - tool_tip="Move camera up and down, left and right" - top="25" - width="78"/> - <text - type="string" - length="1" - follows="left|top" - height="15" - layout="topleft" - left="41" - top_pad="9" - name="precise_ctrs_label" - width="200"> - Use precise controls - </text> </panel> </panel> <panel follows="left|top" - height="102" + height="110" layout="topleft" left_pad="2" right="-2" @@ -216,7 +244,7 @@ mouse_opaque="true" name="preset_combo" top_pad="10" - width="136"> + width="124"> <combo_list mouse_wheel_opaque="true"/> <combo_box.item @@ -226,13 +254,13 @@ </combo_box> <button height="16" - width="16" + width="16" layout="topleft" mouse_opaque="true" name="gear_btn" tool_tip="My Camera Presets" top_delta="3" - left_pad="10" + left_pad="10" image_selected="Icon_Gear" image_pressed="Icon_Gear" image_unselected="Icon_Gear" @@ -242,13 +270,16 @@ </button> <button follows="top|left" - height="25" - label="Save as preset..." + width="18" + height="18" + left_pad="4" + tooltip_text="Save as preset..." layout="topleft" - left="0" name="save_preset_btn" - top_pad="18" - width="150"> + image_disabled="Conv_toolbar_plus" + image_selected="Conv_toolbar_plus" + image_unselected="Conv_toolbar_plus" + > <button.commit_callback function="CameraPresets.Save"/> </button> @@ -259,7 +290,7 @@ top="135" width="400" height="150" - border="true" + border="false" visible="false" background_visible="true"/> <panel @@ -268,7 +299,7 @@ top="285" width="400" height="150" - border="true" + border="false" visible="false" background_visible="true"/> </floater> diff --git a/indra/newview/skins/default/xui/en/floater_emoji_picker.xml b/indra/newview/skins/default/xui/en/floater_emoji_picker.xml index e4b8f13df7..f642ca93b7 100644 --- a/indra/newview/skins/default/xui/en/floater_emoji_picker.xml +++ b/indra/newview/skins/default/xui/en/floater_emoji_picker.xml @@ -13,7 +13,6 @@ chrome="true" height="350" width="304"> - <floater.string name="title_for_recently_used" value="Recently used"/> <floater.string name="title_for_frequently_used" value="Frequently used"/> <floater.string name="text_no_emoji_for_filter" value="No emoji found for '[FILTER]'"/> <scroll_container diff --git a/indra/newview/skins/default/xui/en/floater_fast_timers.xml b/indra/newview/skins/default/xui/en/floater_fast_timers.xml index 00411ba20b..ae907bcb5f 100644 --- a/indra/newview/skins/default/xui/en/floater_fast_timers.xml +++ b/indra/newview/skins/default/xui/en/floater_fast_timers.xml @@ -75,7 +75,7 @@ step_size="16" doc_pos="0" doc_size="3000" - page_size="0" + page_size="50" /> </layout_panel> <layout_panel name="timers_panel" diff --git a/indra/newview/skins/default/xui/en/floater_fs_search.xml b/indra/newview/skins/default/xui/en/floater_fs_search.xml new file mode 100644 index 0000000000..2372bc03ba --- /dev/null +++ b/indra/newview/skins/default/xui/en/floater_fs_search.xml @@ -0,0 +1,337 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<floater + can_resize="true" + default_tab_group="1" + height="590" + help_topic="search" + layout="topleft" + legacy_header_height="0" + min_height="590" + min_width="660" + name="floater_search" + positioning="centered" + save_rect="true" + single_instance="true" + title="SEARCH" + width="780"> + <!-- Strings --> + <floater.string name="string.location"> + Location: [LOCATION] + </floater.string> + <floater.string name="string.traffic"> + Traffic: [DWELL] + </floater.string> + <floater.string name="string.area"> + Area: [AREA] + </floater.string> + <floater.string name="string.members"> + Members: [MEMBER_COUNT] + </floater.string> + <floater.string name="string.founder"> + Founder: [FOUNDER] + </floater.string> + <floater.string name="string.age"> + Age: [AGE] + </floater.string> + <floater.string name="string.partner"> + Partner: [PARTNER] + </floater.string> + <floater.string name="string.listing_price"> + Listing Price: [LISTING_PRICE] + </floater.string> + <floater.string name="string.slurl"> + [SLURL] + </floater.string> + <floater.string name="string.duration"> + Duration: [DURATION] + </floater.string> + <floater.string name="string.covercharge"> + Cover: [COVERCHARGE] + </floater.string> + <!-- Tab time --> + <tab_container + layout="topleft" + follows="all" + top="1" + left="0" + name="ls_tabs" + tab_min_width="90" + tab_position="top" + width="780" + height="585"> + <panel + class="panel_ls_web" + filename="panel_fs_search_legacy_web.xml" + label="Websearch" + layout="topleft" + name="panel_ls_web" /> + <panel + class="panel_ls_people" + filename="panel_fs_search_legacy_people.xml" + label="People" + layout="topleft" + name="panel_ls_people" /> + <panel + class="panel_ls_groups" + filename="panel_fs_search_legacy_groups.xml" + label="Groups" + layout="topleft" + name="panel_ls_groups" /> + <panel + class="panel_ls_places" + filename="panel_fs_search_legacy_places.xml" + label="Places" + layout="topleft" + name="panel_ls_places" /> + <panel + class="panel_ls_land" + filename="panel_fs_search_legacy_land.xml" + label="Land Sales" + layout="topleft" + name="panel_ls_land" /> + <panel + class="panel_ls_events" + filename="panel_fs_search_legacy_events.xml" + label="Events" + layout="topleft" + name="panel_ls_events" /> + <panel + class="panel_ls_classifieds" + filename="panel_fs_search_legacy_classifieds.xml" + label="Classifieds" + layout="topleft" + name="panel_ls_classifieds" /> + </tab_container> + <!-- Details/Action Panes --> + <panel + border="true" + follows="top|right|bottom" + height="508" + layout="topleft" + left="412" + top="80" + width="366" + name="panel_ls_details"> + <text_editor + left="12" + top="5" + height="24" + width="340" + layout="topleft" + follows="left|top|right" + name="title" + bg_visible="false" + border_visible="false" + allow_scroll="false" + h_pad="0" + v_pad="0" + halign="center" + enabled="false" + use_ellipses="true" + font="SansSerifHugeBold" + value="Undefined name" /> + <texture_picker + enabled="false" + fallback_image="Generic_Person_Large" + follows="left|top|right" + height="210" + layout="topleft" + left="78" + name="snapshot" + top_pad="4" + width="210"/> + <texture_picker + enabled="false" + fallback_image="default_land_picture.j2c" + follows="left|top|right" + height="210" + layout="topleft" + left_delta="0" + name="snapshot_parcel" + top_delta="0" + visible="false" + width="210"/> + <text_editor + left="20" + top_pad="2" + height="16" + width="180" + layout="topleft" + follows="left|top|right" + name="aux1" + bg_visible="false" + border_visible="false" + h_pad="0" + v_pad="0" + word_wrap="true" + enabled="false" + max_length="117" + allow_scroll="false" + parse_urls="true" + value="Auxilary info field 1"/> + <text_editor + left_pad="4" + top_delta="0" + height="16" + width="140" + layout="topleft" + follows="left|top|right" + name="aux2" + bg_visible="false" + border_visible="false" + h_pad="0" + v_pad="0" + word_wrap="true" + enabled="false" + max_length="117" + allow_scroll="false" + parse_urls="true" + value="Auxilary info field 2"/> + <icon + follows="top|right" + height="16" + image_name="Unknown_Icon" + layout="topleft" + left="20" + top_pad="2" + name="maturity_icon" + width="18" /> + <text_editor + left_pad="4" + top_delta="0" + height="28" + width="302" + layout="topleft" + follows="left|top|right" + name="location" + bg_visible="false" + border_visible="false" + h_pad="0" + v_pad="0" + word_wrap="true" + enabled="false" + max_length="117" + allow_scroll="false" + parse_urls="true" + value="Location info field"/> + <text_editor + left="20" + top_pad="12" + height="154" + width="324" + layout="topleft" + follows="left|top|right" + name="desc" + bg_visible="false" + border_visible="false" + h_pad="0" + v_pad="0" + word_wrap="true" + parse_urls="true" + enabled="false" + max_length="1000" + trusted_content="false" + value="You unlock this door with the key of imagination. Beyond it is another dimension: a dimension of sound, a dimension of sight, a dimension of mind. You're moving into a land of both shadow and substance, of things and ideas; you've just crossed over into the Twilight Zone. What you are about to see is real; the litigants on the screen are not actors. They are genuine citizens who, having filed their claims in a real small claims court, have been persuaded to drop their suits there and have them settled here, in this forum... the People's Court."/> + <button + layout="topleft" + follows="left|bottom" + height="23" + label="Open Profile" + name="people_profile_btn" + top="484" + left="3" + width="120" /> + <button + layout="topleft" + follows="left|bottom" + height="23" + label="Send Message" + name="people_message_btn" + width="120" + left_pad="1" /> + <button + layout="topleft" + follows="left|bottom" + height="23" + label="Add Friend" + name="people_friend_btn" + width="120" + left_pad="1" /> + <button + layout="topleft" + follows="left|bottom" + height="23" + label="Open Profile" + name="group_profile_btn" + top="484" + left="3" + width="120" /> + <button + layout="topleft" + follows="left|bottom" + height="23" + label="Join Chat" + name="group_message_btn" + width="120" + left_pad="1" /> + <button + layout="topleft" + follows="left|bottom" + height="23" + label="Join Group" + name="group_join_btn" + width="120" + left_pad="1" /> + <button + layout="topleft" + follows="left|bottom" + height="23" + label="Teleport" + name="teleport_btn" + top="484" + left="3" + width="120" /> + <button + layout="topleft" + follows="left|bottom" + height="23" + label="Show on Map" + name="map_btn" + width="120" + left_pad="1" /> + <button + layout="topleft" + follows="left|bottom" + height="23" + label="Remind me" + name="event_reminder_btn" + width="120" + left_pad="1" /> + <loading_indicator + left="134" + top="320" + follows="left|top|right" + mouse_opaque="false" + name="loading" + images_per_sec="1.0" + tab_stop="false" + height="100" + width="100" + visible="false" > + <images> + <image name="ProgressLarge_1"/> + <image name="ProgressLarge_2"/> + <image name="ProgressLarge_3"/> + <image name="ProgressLarge_4"/> + <image name="ProgressLarge_5"/> + <image name="ProgressLarge_6"/> + <image name="ProgressLarge_7"/> + <image name="ProgressLarge_8"/> + <image name="ProgressLarge_9"/> + <image name="ProgressLarge_10"/> + <image name="ProgressLarge_11"/> + <image name="ProgressLarge_12"/> + </images> + </loading_indicator> + </panel> +</floater> diff --git a/indra/newview/skins/default/xui/en/floater_gesture.xml b/indra/newview/skins/default/xui/en/floater_gesture.xml index 832716c600..7fce91a2c3 100644 --- a/indra/newview/skins/default/xui/en/floater_gesture.xml +++ b/indra/newview/skins/default/xui/en/floater_gesture.xml @@ -52,7 +52,7 @@ width="80" /> </scroll_list> <panel - background_visible="true" + background_visible="false" bevel_style="none" top_pad="0" follows="left|right|bottom" diff --git a/indra/newview/skins/default/xui/en/floater_im_session.xml b/indra/newview/skins/default/xui/en/floater_im_session.xml index 7b06bed0a3..1ceafaf82e 100644 --- a/indra/newview/skins/default/xui/en/floater_im_session.xml +++ b/indra/newview/skins/default/xui/en/floater_im_session.xml @@ -291,7 +291,6 @@ height="20" is_expandable="true" text_tentative_color="TextFgTentativeColor" - bg_writeable_color="ScriptBackground" name="chat_editor" max_length="1023" spellcheck="true" diff --git a/indra/newview/skins/default/xui/en/floater_live_material_editor.xml b/indra/newview/skins/default/xui/en/floater_live_material_editor.xml index 5b7dab6a52..fbd3c81bad 100644 --- a/indra/newview/skins/default/xui/en/floater_live_material_editor.xml +++ b/indra/newview/skins/default/xui/en/floater_live_material_editor.xml @@ -20,8 +20,8 @@ width="250" follows="all" layout="topleft" - color="DkGray2" - opaque="true" + color="Transparent" + opaque="false" tab_stop="true" border="false" reserve_scroll_corner="false"> diff --git a/indra/newview/skins/default/xui/en/floater_map.xml b/indra/newview/skins/default/xui/en/floater_map.xml index eba5684819..5e7af80e42 100644 --- a/indra/newview/skins/default/xui/en/floater_map.xml +++ b/indra/newview/skins/default/xui/en/floater_map.xml @@ -50,6 +50,7 @@ Mini-map </floater.string> <net_map + bg_color="Transparent" follows="top|left|bottom|right" layout="topleft" left="0" diff --git a/indra/newview/skins/default/xui/en/floater_mp_performance.xml b/indra/newview/skins/default/xui/en/floater_mp_performance.xml new file mode 100644 index 0000000000..1b5cf82dcb --- /dev/null +++ b/indra/newview/skins/default/xui/en/floater_mp_performance.xml @@ -0,0 +1,66 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater + positioning="cascading" + legacy_header_height="40" + top="12" + right="-334" + height="80" + min_height="120" + width="330" + min_width="330" + can_minimize="true" + can_close="true" + can_resize="false" + layout="topright" + name="mpv_performance" + single_instance="true" + save_rect="true" + save_visibility="true" + title="FPS Limiter"> + + <panel + name="panel_fps" + border="false" + width="320" + height="60" + left="10" + top="40" + follows="left|top|right|bottom" + layout="topleft" + > + + <slider + follows="left|top" + width="240" + height="15" + left="12" + layout="topleft" + name="fpsSlider" + enabled="true" + control_name="fpsSlider" + decimal_digits="0" + increment="12" + initial_value="0" + label="Max FPS:" + label_width="50" + text_width="2" + can_edit_text="false" + show_text="false" + > + </slider> + + <text + follows="left|top" + width="50" + height="15" + left_delta="252" + layout="topleft" + type="string" + name="fpsText" + > + no limit + </text> + +</panel> + +</floater> diff --git a/indra/newview/skins/default/xui/en/floater_my_environments.xml b/indra/newview/skins/default/xui/en/floater_my_environments.xml index 8c9c450d7c..dd0795305e 100644 --- a/indra/newview/skins/default/xui/en/floater_my_environments.xml +++ b/indra/newview/skins/default/xui/en/floater_my_environments.xml @@ -26,8 +26,8 @@ bottom="-5" orientation="vertical"> <layout_panel - border="true" - bevel_style="in" + border="false" + bevel_style="none" auto_resize="false" tab_group="1" height="54" @@ -147,7 +147,7 @@ name="pnl_control" font="SansSerifBold"> <panel - background_visible="true" + background_visible="false" bevel_style="none" top_pad="1" follows="top|left|right" diff --git a/indra/newview/skins/default/xui/en/floater_preferences_graphics_advanced.xml b/indra/newview/skins/default/xui/en/floater_preferences_graphics_advanced.xml index 65b98c65cf..88d6ae1bc2 100644 --- a/indra/newview/skins/default/xui/en/floater_preferences_graphics_advanced.xml +++ b/indra/newview/skins/default/xui/en/floater_preferences_graphics_advanced.xml @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="utf-8" standalone="yes" ?> <floater - height="430" + height="492" layout="topleft" name="prefs_graphics_advanced" help_topic="Preferences_Graphics_Advanced" @@ -29,13 +29,13 @@ decimal_digits="0" follows="left|top" height="16" - increment="8" + increment="32" initial_value="160" label="Draw distance:" label_width="185" layout="topleft" left="30" - min_val="64" + min_val="32" max_val="512" name="DrawDistance" top_delta="16" @@ -52,7 +52,7 @@ left_delta="330" width="20"> m - </text> + </text> <slider control_name="RenderMaxPartCount" decimal_digits="0" @@ -118,6 +118,41 @@ name="MaxLights" top_delta="16" width="336" /> + <text + type="string" + length="1" + follows="left|top" + height="16" + layout="topleft" + top_delta="16" + left="30" + width="160" + name="MaxTextureResolutionLabel" + text_readonly_color="LabelDisabledColor"> + Maximum LOD resolution: + </text> + <combo_box + control_name="RenderMaxTextureResolution" + height="19" + layout="topleft" + left_pad="10" + top_delta="0" + name="MaxTextureResolution" + tool_tip="Maximum resolution for 'level of detail' textures" + width="90"> + <combo_box.item + label="512" + name="512" + value="512"/> + <combo_box.item + label="1024" + name="1024" + value="1024"/> + <combo_box.item + label="2048" + name="2048" + value="2048"/> + </combo_box> <check_box control_name="RenderVSyncEnable" @@ -152,7 +187,7 @@ layout="topleft" left="30" top_delta="16" - width="128" + width="130" name="AvatarComplexityModeLabel" text_readonly_color="LabelDisabledColor"> Avatar display: @@ -160,10 +195,10 @@ <combo_box control_name="RenderAvatarComplexityMode" - height="18" + height="19" layout="topleft" - left_delta="130" - top_delta="0" + left_pad="40" + top_delta="-1" name="AvatarComplexityMode" width="150"> <combo_box.item @@ -195,7 +230,7 @@ max_val="101" name="IndirectMaxComplexity" show_text="false" - top_delta="16" + top_delta="19" width="300"> <slider.commit_callback function="Pref.UpdateIndirectMaxComplexity" @@ -222,7 +257,7 @@ height="16" increment="1" initial_value="12" - label="Max. # of non-impostors:" + label="Max. # animated avatars:" label_width="185" layout="topleft" left="30" @@ -368,7 +403,7 @@ left="30" name="antialiasing label" top_delta="20" - width="120"> + width="130"> Antialiasing: </text> <combo_box @@ -403,7 +438,7 @@ left="30" name="antialiasing quality label" top_delta="20" - width="120"> + width="130"> Antialiasing Quality: </text> <combo_box @@ -591,9 +626,9 @@ layout="topleft" left="385" name="vert_border" - top="16" + top="16" width="0"/> - + <text type="string" length="1" @@ -697,7 +732,7 @@ <check_box.commit_callback function="Pref.RenderOptionUpdate" /> </check_box> - + <text type="string" length="1" @@ -709,14 +744,14 @@ text_readonly_color="LabelDisabledColor" top_delta="22" width="128"> - Shadows: + Shadows source: </text> <combo_box control_name="RenderShadowDetail" height="18" layout="topleft" left_delta="130" - top_delta="0" + top_delta="0" name="ShadowDetail" width="150"> <combo_box.item @@ -733,6 +768,86 @@ value="2"/> </combo_box> + <text + type="string" + length="1" + follows="left|top" + height="16" + layout="topleft" + left="420" + name="RenderShadowQualityText" + text_readonly_color="LabelDisabledColor" + top_delta="22" + width="128"> + Shadows Optimisations + </text> + + <combo_box + control_name="MPRenderShadowOpti" + height="18" + layout="topleft" + left_delta="130" + top_delta="0" + name="MPShadowQuality" + width="150"> + <combo_box.item + label="No optimisation" + name="0" + value="0"/> + <combo_box.item + label="Medium" + name="1" + value="1"/> + <combo_box.item + label="Faster" + name="2" + value="2"/> + <combo_box.item + label="Fastest" + name="3" + value="3"/> + </combo_box> + + <text + type="string" + length="1" + follows="left|top" + height="16" + layout="topleft" + left="420" + name="RenderShadowResolutionScaleText" + text_readonly_color="LabelDisabledColor" + top_delta="22" + width="128"> + Shadows Resolution + </text> + + <combo_box + control_name="RenderShadowResolutionScale" + height="18" + layout="topleft" + left_delta="130" + top_delta="0" + name="RenderShadowResolutionScale" + width="150"> + <combo_box.item + label="Default" + name="Default" + value="1.0"/> + <combo_box.item + label="High" + name="High" + value="1.5"/> + <combo_box.item + label="Ultra" + name="Ultra" + value="2.0"/> + <combo_box.item + label="Crazy" + name="Crazy" + value="3.0"/> + </combo_box> + <check_box control_name="RenderScreenSpaceReflections" height="16" @@ -746,7 +861,7 @@ <check_box.commit_callback function="Pref.RenderOptionUpdate" /> </check_box> - + <text type="string" length="1" @@ -823,6 +938,51 @@ value="3"/> </combo_box> + <text + type="string" + length="1" + follows="left|top" + height="16" + layout="topleft" + left="420" + name="ReflectionProbeCount" + text_readonly_color="LabelDisabledColor" + top_delta="22" + width="128"> + Max Reflection Probes: + </text> + + <combo_box + control_name="RenderReflectionProbeCount" + height="18" + layout="topleft" + label="Max. Reflection Probes:" + left_delta="130" + top_delta="0" + name="ProbeCount" + width="150"> + <combo_box.item + label="None" + name="1" + value="1"/> + <combo_box.item + label="Low" + name="32" + value="32"/> + <combo_box.item + label="Medium" + name="64" + value="64"/> + <combo_box.item + label="High" + name="128" + value="128"/> + <combo_box.item + label="Ultra" + name="256" + value="256"/> + </combo_box> + <slider control_name="RenderExposure" decimal_digits="1" @@ -1015,7 +1175,7 @@ layout="topleft" left="13" name="horiz_border" - top="393" + top="448" top_delta="5" width="774"/> <button diff --git a/indra/newview/skins/default/xui/en/floater_script.xml b/indra/newview/skins/default/xui/en/floater_script.xml index ae6e68de17..900319620d 100644 --- a/indra/newview/skins/default/xui/en/floater_script.xml +++ b/indra/newview/skins/default/xui/en/floater_script.xml @@ -7,7 +7,8 @@ name="script_floater" can_dock="true" can_minimize="true" - visible="false" + save_rect="true" + visible="false" width="350" can_resize="false" min_width="350" diff --git a/indra/newview/skins/default/xui/en/floater_test_slapp.xml b/indra/newview/skins/default/xui/en/floater_test_slapp.xml new file mode 100644 index 0000000000..dd2720816a --- /dev/null +++ b/indra/newview/skins/default/xui/en/floater_test_slapp.xml @@ -0,0 +1,123 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater + legacy_header_height="18" + height="300" + layout="topleft" + name="slapp_test" + title="SLAPP TEST" + width="500"> + <floater.string + name="remove_folder_slapp"> + secondlife://app/remove_folder/?folder_id= + </floater.string> + <text + type="string" + length="1" + top="20" + follows="left|top|right" + height="16" + name="trusted_txt" + font="SansSerifMedium" + text_color="white" + layout="topleft" + left="16"> + Trusted source + </text> + <text + type="string" + length="1" + top_pad="8" + follows="left|top|right" + height="16" + layout="topleft" + left="16"> + /wear_folder + </text> + <text + type="string" + length="1" + top_pad="5" + follows="left|top|right" + height="16" + width="450" + layout="topleft" + left="16"> + secondlife://app/wear_folder/?folder_name=Daisy + </text> + <text + type="string" + length="1" + top_pad="8 " + follows="left|top|right" + height="16" + layout="topleft" + left="16"> + /add_folder + </text> + <text + type="string" + length="1" + top_pad="5" + follows="left|top|right" + height="16" + width="450" + layout="topleft" + left="16"> + secondlife://app/add_folder/?folder_name=Cardboard%20Boxbot + </text> + <text + type="string" + length="1" + top_pad="5" + follows="left|top|right" + height="16" + width="450" + layout="topleft"> + secondlife://app/add_folder/?folder_id=59219db2-c260-87d3-213d-bb3bc298a3d8 + </text> + <text + type="string" + length="1" + top_pad="8 " + follows="left|top|right" + height="16" + layout="topleft" + left="16"> + /remove_folder + </text> + <text + type="string" + length="1" + top_pad="5" + follows="left|top|right" + height="16" + layout="topleft" + left="16"> + Folder ID: + </text> + <line_editor + border_style="line" + border_thickness="1" + follows="left|top" + font="SansSerif" + height="18" + layout="topleft" + left="75" + max_length_bytes="50" + prevalidate_callback="ascii" + name="remove_folder_id" + top_delta="-2" + width="270" /> + <text + type="string" + length="1" + top_pad="5" + follows="left|top|right" + height="16" + width="450" + name="remove_folder_txt" + layout="topleft" + left="16"> + secondlife://app/remove_folder/?folder_id= + </text> +</floater> diff --git a/indra/newview/skins/default/xui/en/floater_tools.xml b/indra/newview/skins/default/xui/en/floater_tools.xml index d3a872c9d5..dba323a9e1 100644 --- a/indra/newview/skins/default/xui/en/floater_tools.xml +++ b/indra/newview/skins/default/xui/en/floater_tools.xml @@ -1194,7 +1194,7 @@ even though the user gets a free copy. follows="left|top" layout="topleft" mouse_opaque="false" - background_visible="true" + background_visible="false" bg_alpha_color="DkGray" name="perms_build" left="0" diff --git a/indra/newview/skins/default/xui/en/floater_world_map.xml b/indra/newview/skins/default/xui/en/floater_world_map.xml index b0b818cde5..08cc9ae19e 100644 --- a/indra/newview/skins/default/xui/en/floater_world_map.xml +++ b/indra/newview/skins/default/xui/en/floater_world_map.xml @@ -37,7 +37,8 @@ top="16" left="0" right="-1" - bottom="-1"> + bottom="-1" + orientation="horizontal"> <layout_panel name="map_lp" width="385" @@ -88,8 +89,8 @@ height="22" width="238" follows="right|top" - top="6" - background_visible="true" + top="6" + background_visible="false" bg_alpha_color="DkGray2"> <text text_color="White" @@ -432,7 +433,7 @@ height="22" top_pad="0" width="238" - background_visible="true" + background_visible="false" bg_alpha_color="DkGray2" name="layout_panel_3"> <text @@ -573,7 +574,7 @@ </button> <scroll_list draw_stripes="false" - bg_writeable_color="MouseGray" + bg_writeable_color="0.75 0.75 0.75 0.15" follows="all" height="145" layout="topleft" @@ -607,7 +608,7 @@ Location: </text> <spinner - control_name="Teleport_Coordinate_X" + control_name="teleport_coordinate_x" decimal_digits="0" follows="right|bottom" height="23" @@ -619,11 +620,11 @@ min_val="0" name="teleport_coordinate_x" width="44" > - <spinner.commit_callback + <spinner.commit_callback function="WMap.Coordinates" /> </spinner> <spinner - control_name="Teleport_Coordinate_Y" + control_name="teleport_coordinate_y" decimal_digits="0" follows="right|bottom" height="23" @@ -639,7 +640,7 @@ function="WMap.Coordinates" /> </spinner> <spinner - control_name="Teleport_Coordinate_Z" + control_name="teleport_coordinate_z" decimal_digits="0" follows="right|bottom" height="23" @@ -700,7 +701,7 @@ height="22" top_pad="0" width="238" - background_visible="true" + background_visible="false" bg_alpha_color="DkGray2" name="layout_panel_5"> <text diff --git a/indra/newview/skins/default/xui/en/language_settings.xml b/indra/newview/skins/default/xui/en/language_settings.xml index 12a1b52a84..129ca5344c 100644 --- a/indra/newview/skins/default/xui/en/language_settings.xml +++ b/indra/newview/skins/default/xui/en/language_settings.xml @@ -8,6 +8,7 @@ <string name="macOSLocale">C</string> <string name="DarwinLocale">C</string> <string name="LinuxLocale">C</string> + <string name="FreeBSDLocale">C</string> <!-- Note: for plural nouns, see strings.xml. For example: AgeYearsA = singular, @@ -37,6 +38,7 @@ <string name="TimeHour">hour,datetime,slt</string> <string name="TimeMin">min,datetime,slt</string> + <string name="TimeSec">second,datetime,slt</string> <string name="TimeYear">year,datetime,slt</string> <string name="TimeDay">day,datetime,slt</string> <string name="TimeMonth">mthnum,datetime,slt</string> diff --git a/indra/newview/skins/default/xui/en/menu_gallery_inventory.xml b/indra/newview/skins/default/xui/en/menu_gallery_inventory.xml index 16907d3577..99f84fe808 100644 --- a/indra/newview/skins/default/xui/en/menu_gallery_inventory.xml +++ b/indra/newview/skins/default/xui/en/menu_gallery_inventory.xml @@ -715,6 +715,16 @@ function="Inventory.CanSetUploadLocation" /> </menu_item_call> </menu> + <menu_item_call + label="Use as favorite folder" + layout="topleft" + name="Set favorite folder"> + <menu_item_call.on_click + function="Inventory.SetFavoriteFolder" + parameter="favorite" /> + <menu_item_call.on_visible + function="Inventory.CanSetFavoriteFolder" /> + </menu_item_call> <menu_item_separator layout="topleft" name="Marketplace Separator" /> diff --git a/indra/newview/skins/default/xui/en/menu_im_session_showmodes.xml b/indra/newview/skins/default/xui/en/menu_im_session_showmodes.xml index 94022ef1e3..f1cf8b9995 100644 --- a/indra/newview/skins/default/xui/en/menu_im_session_showmodes.xml +++ b/indra/newview/skins/default/xui/en/menu_im_session_showmodes.xml @@ -46,4 +46,12 @@ function="IMSession.Menu.ShowModes.Enable" parameter="IMShowNamesForP2PConv" /> </menu_item_check> + <menu_item_check name="IMShowArrivalsDepartures" label="Show arrivals and departures"> + <menu_item_check.on_click + function="IMSession.Menu.Action" + parameter="IMShowArrivalsDepartures" /> + <menu_item_check.on_check + function="IMSession.Menu.ShowModes.CheckItem" + parameter="IMShowArrivalsDepartures" /> + </menu_item_check> </toggleable_menu> diff --git a/indra/newview/skins/default/xui/en/menu_inventory.xml b/indra/newview/skins/default/xui/en/menu_inventory.xml index d8aac71dd5..e0f380e074 100644 --- a/indra/newview/skins/default/xui/en/menu_inventory.xml +++ b/indra/newview/skins/default/xui/en/menu_inventory.xml @@ -371,6 +371,14 @@ parameter="copy_uuid" /> </menu_item_call> <menu_item_call + label="Copy UUID" + layout="topleft" + name="Copy UUID"> + <menu_item_call.on_click + function="Inventory.DoToSelected" + parameter="copy_folder_uuid" /> + </menu_item_call> + <menu_item_call label="Show in Main Panel" layout="topleft" name="Show in Main Panel"> @@ -996,6 +1004,13 @@ parameter="pbr_material" /> </menu_item_call> </menu> + <menu_item_call + label="Use as favorite folder" + layout="topleft" + name="Set favorite folder"> + <menu_item_call.on_click + function="Inventory.SetFavoriteFolder" /> + </menu_item_call> <menu_item_separator layout="topleft" name="Marketplace Separator" /> diff --git a/indra/newview/skins/default/xui/en/menu_login.xml b/indra/newview/skins/default/xui/en/menu_login.xml index 1d1b81e31a..5fff9b7bc0 100644 --- a/indra/newview/skins/default/xui/en/menu_login.xml +++ b/indra/newview/skins/default/xui/en/menu_login.xml @@ -95,18 +95,11 @@ </menu_item_call> <menu_item_separator/> <menu_item_call - label="[SECOND_LIFE] News" - name="Second Life News"> - <menu_item_call.on_click - function="Advanced.ShowURL" - parameter="http://community.secondlife.com/t5/Featured-News/bg-p/blog_feature_news"/> - </menu_item_call> - <menu_item_call label="[SECOND_LIFE] Blogs" name="Second Life Blogs"> <menu_item_call.on_click function="Advanced.ShowURL" - parameter="http://community.secondlife.com/t5/Blogs/ct-p/Blogs"/> + parameter="https://community.secondlife.com/news/"/> </menu_item_call> <menu_item_separator/> <menu_item_call diff --git a/indra/newview/skins/default/xui/en/menu_participant_view.xml b/indra/newview/skins/default/xui/en/menu_participant_view.xml index 7591e6e02f..91c9a378f0 100644 --- a/indra/newview/skins/default/xui/en/menu_participant_view.xml +++ b/indra/newview/skins/default/xui/en/menu_participant_view.xml @@ -61,6 +61,19 @@ </menu_item_check> <menu_item_separator layout="topleft" /> + <menu_item_check + label="Put nearby session always first" + layout="topleft" + name="put_nearby_session_first"> + <on_click + function="IMFloaterContainer.Action" + parameter="put_nearby_session_first" /> + <on_check + function="IMFloaterContainer.Check" + parameter="put_nearby_session_first" /> + </menu_item_check> + <menu_item_separator + layout="topleft" /> <menu_item_call label="Chat preferences..." name="chat_preferences"> diff --git a/indra/newview/skins/default/xui/en/menu_people_nearby.xml b/indra/newview/skins/default/xui/en/menu_people_nearby.xml index 7bd2c845a6..b7a296bf31 100644 --- a/indra/newview/skins/default/xui/en/menu_people_nearby.xml +++ b/indra/newview/skins/default/xui/en/menu_people_nearby.xml @@ -101,6 +101,16 @@ parameter="can_zoom_in"/> </menu_item_call> <menu_item_call + label="Teleport To" + layout="topleft" + name="teleport_to"> + <menu_item_call.on_click + function="Avatar.TeleportTo" /> + <menu_item_call.on_enable + function="Avatar.EnableItem" + parameter="can_zoom_in"/> + </menu_item_call> + <menu_item_call label="Map" layout="topleft" name="map"> diff --git a/indra/newview/skins/default/xui/en/menu_profile_other.xml b/indra/newview/skins/default/xui/en/menu_profile_other.xml index 101ae33778..a505b38087 100644 --- a/indra/newview/skins/default/xui/en/menu_profile_other.xml +++ b/indra/newview/skins/default/xui/en/menu_profile_other.xml @@ -168,4 +168,12 @@ function="Profile.Commit" parameter="copy_user_id"/> </menu_item_call> + <menu_item_call + label="Copy Profile Link" + layout="topleft" + name="copy_link"> + <menu_item_call.on_click + function="Profile.Commit" + parameter="copy_profile_link"/> + </menu_item_call> </toggleable_menu> diff --git a/indra/newview/skins/default/xui/en/menu_profile_self.xml b/indra/newview/skins/default/xui/en/menu_profile_self.xml index 1b21c7ae61..0a03d7ac2b 100644 --- a/indra/newview/skins/default/xui/en/menu_profile_self.xml +++ b/indra/newview/skins/default/xui/en/menu_profile_self.xml @@ -82,4 +82,12 @@ function="Profile.Commit" parameter="copy_user_id"/> </menu_item_call> + <menu_item_call + label="Copy Profile Link" + layout="topleft" + name="copy_link"> + <menu_item_call.on_click + function="Profile.Commit" + parameter="copy_profile_link"/> + </menu_item_call> </toggleable_menu> diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml index e0e9fdcc32..3de2473927 100644 --- a/indra/newview/skins/default/xui/en/menu_viewer.xml +++ b/indra/newview/skins/default/xui/en/menu_viewer.xml @@ -37,6 +37,13 @@ parameter="" /> </menu_item_call> <menu_item_call + label="Favorite Inventory Folder" + layout="topleft" + name="Favorite Folder"> + <menu_item_call.on_click + function="Inventory.OpenFavoriteFolder" /> + </menu_item_call> + <menu_item_call label="Places..." name="Places" shortcut="control|L"> @@ -493,6 +500,13 @@ function="Avatar.ResetSelfSkeletonAndAnimations" /> </menu_item_call> <menu_item_call + label="Refresh attachments" + name="Refresh attachments" + shortcut="alt|shift|R"> + <menu_item_call.on_click + function="Advanced.RefreshAttachments" /> + </menu_item_call> + <menu_item_call label="Attachment scripts..." name="MyScripts"> <menu_item_call.on_click @@ -633,6 +647,14 @@ name="World" tear_off="true"> <menu_item_call + label="Resync Animations" + name="Resync Animations" + shortcut="control|S"> + <menu_item_call.on_click + function="Tools.ResyncAnimations" /> + </menu_item_call> + <menu_item_separator/> + <menu_item_call label="Landmark This Place" name="Create Landmark Here"> <menu_item_call.on_click @@ -987,6 +1009,7 @@ </menu_item_check> <menu_item_check label="Use Shared Environment" + shortcut="control|shift|X" name="Use Shared Environment"> <menu_item_check.on_click function="World.EnvSettings" @@ -1773,18 +1796,11 @@ function="World.EnvPreset" </menu_item_call> <menu_item_separator/> <menu_item_call - label="[SECOND_LIFE] News" - name="Second Life News"> - <menu_item_call.on_click - function="Advanced.ShowURL" - parameter="http://community.secondlife.com/t5/Featured-News/bg-p/blog_feature_news"/> - </menu_item_call> - <menu_item_call label="[SECOND_LIFE] Blogs" name="Second Life Blogs"> <menu_item_call.on_click function="Advanced.ShowURL" - parameter="http://community.secondlife.com/t5/Blogs/ct-p/Blogs"/> + parameter="https://community.secondlife.com/news/"/> </menu_item_call> <menu_item_separator/> @@ -2795,7 +2811,7 @@ function="World.EnvPreset" function="Advanced.ForceErrorOSException" /> <menu_item_call.on_visible function="Advanced.EnableErrorOSException" /> - </menu_item_call> + </menu_item_call> <menu_item_call label="Force a Crash in a Coroutine" name="Force a Crash in a Coroutine"> @@ -2803,6 +2819,18 @@ function="World.EnvPreset" function="Advanced.ForceErrorCoroutineCrash" /> </menu_item_call> <menu_item_call + label="Force a Crash in a Coroprocedure" + name="Force a Crash in a Coroprocedure"> + <menu_item_call.on_click + function="Advanced.ForceErrorCoroprocedureCrash" /> + </menu_item_call> + <menu_item_call + label="Force a Crash in a Work Queue" + name="Force a Crash in a Work Queue"> + <menu_item_call.on_click + function="Advanced.ForceErrorWorkQueueCrash" /> + </menu_item_call> + <menu_item_call label="Force a Crash in a Thread" name="Force a Crash in a Thread"> <menu_item_call.on_click @@ -3884,6 +3912,13 @@ function="World.EnvPreset" function="Floater.Show" parameter="font_test" /> </menu_item_call> + <menu_item_call + label="Show SLapps Test" + name="Show SLapps Test"> + <menu_item_call.on_click + function="Floater.Show" + parameter="slapp_test" /> + </menu_item_call> <menu_item_check label="Show XUI Names" name="Show XUI Names"> @@ -4209,16 +4244,6 @@ function="World.EnvPreset" <menu_item_separator/> - <menu_item_check - label="HTTP Textures" - name="HTTP Textures"> - <menu_item_check.on_check - function="CheckControl" - parameter="ImagePipelineUseHTTP" /> - <menu_item_check.on_click - function="ToggleControl" - parameter="ImagePipelineUseHTTP" /> - </menu_item_check> <menu_item_call label="Compress Images" name="Compress Images"> diff --git a/indra/newview/skins/default/xui/en/mime_types_linux.xml b/indra/newview/skins/default/xui/en/mime_types_linux.xml index d0ecd0a11c..e5c33809c8 100644 --- a/indra/newview/skins/default/xui/en/mime_types_linux.xml +++ b/indra/newview/skins/default/xui/en/mime_types_linux.xml @@ -7,7 +7,7 @@ none </defaultwidget> <defaultimpl> - media_plugin_webkit + media_plugin_cef </defaultimpl> <widgetset name="web"> <label name="web_label"> @@ -141,7 +141,7 @@ none </widgettype> <impl> - media_plugin_webkit + media_plugin_cef </impl> </mimetype> <mimetype name="none/none"> @@ -152,7 +152,7 @@ none </widgettype> <impl> - media_plugin_webkit + media_plugin_cef </impl> </mimetype> <mimetype name="audio/*"> @@ -185,7 +185,7 @@ image </widgettype> <impl> - media_plugin_webkit + media_plugin_cef </impl> </mimetype> <mimetype menu="1" name="video/vnd.secondlife.qt.legacy"> @@ -207,7 +207,7 @@ web </widgettype> <impl> - media_plugin_webkit + media_plugin_cef </impl> </mimetype> <mimetype name="application/ogg"> @@ -229,7 +229,7 @@ image </widgettype> <impl> - media_plugin_webkit + media_plugin_cef </impl> </mimetype> <mimetype name="application/postscript"> @@ -240,7 +240,7 @@ image </widgettype> <impl> - media_plugin_webkit + media_plugin_cef </impl> </mimetype> <mimetype name="application/rtf"> @@ -251,7 +251,7 @@ image </widgettype> <impl> - media_plugin_webkit + media_plugin_cef </impl> </mimetype> <mimetype name="application/smil"> @@ -262,7 +262,7 @@ movie </widgettype> <impl> - media_plugin_webkit + media_plugin_cef </impl> </mimetype> <mimetype name="application/xhtml+xml"> @@ -273,7 +273,7 @@ web </widgettype> <impl> - media_plugin_webkit + media_plugin_cef </impl> </mimetype> <mimetype name="application/x-director"> @@ -284,7 +284,7 @@ image </widgettype> <impl> - media_plugin_webkit + media_plugin_cef </impl> </mimetype> <mimetype name="audio/mid"> @@ -339,7 +339,7 @@ image </widgettype> <impl> - media_plugin_webkit + media_plugin_cef </impl> </mimetype> <mimetype menu="1" name="image/gif"> @@ -350,7 +350,7 @@ image </widgettype> <impl> - media_plugin_webkit + media_plugin_cef </impl> </mimetype> <mimetype menu="1" name="image/jpeg"> @@ -361,7 +361,7 @@ image </widgettype> <impl> - media_plugin_webkit + media_plugin_cef </impl> </mimetype> <mimetype menu="1" name="image/png"> @@ -372,7 +372,7 @@ image </widgettype> <impl> - media_plugin_webkit + media_plugin_cef </impl> </mimetype> <mimetype name="image/svg+xml"> @@ -383,7 +383,7 @@ image </widgettype> <impl> - media_plugin_webkit + media_plugin_cef </impl> </mimetype> <mimetype menu="1" name="image/tiff"> @@ -394,7 +394,7 @@ image </widgettype> <impl> - media_plugin_webkit + media_plugin_cef </impl> </mimetype> <mimetype menu="1" name="text/html"> @@ -405,7 +405,7 @@ web </widgettype> <impl> - media_plugin_webkit + media_plugin_cef </impl> </mimetype> <mimetype menu="1" name="text/plain"> @@ -416,7 +416,7 @@ text </widgettype> <impl> - media_plugin_webkit + media_plugin_cef </impl> </mimetype> <mimetype name="text/xml"> @@ -427,7 +427,7 @@ text </widgettype> <impl> - media_plugin_webkit + media_plugin_cef </impl> </mimetype> <mimetype menu="1" name="video/mpeg"> diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml index b5f742e5fb..4245b22e88 100644 --- a/indra/newview/skins/default/xui/en/notifications.xml +++ b/indra/newview/skins/default/xui/en/notifications.xml @@ -2408,6 +2408,16 @@ Unable to upload snapshot. File might be too big, try reducing resolution or try again later. <tag>fail</tag> </notification> + + <notification + icon="alertmodal.tga" + name="CannotOpenFileTooBig" + type="alertmodal"> +Unable to open file. + +Viewer run out of memory while opening file. File might be too big. + <tag>fail</tag> + </notification> <notification icon="notifytip.tga" @@ -12580,4 +12590,28 @@ are wearing now. name="okbutton" yestext="OK"/> </notification> + <notification + icon="alertmodal.tga" + name="MissingFavoriteFolder" + type="alertmodal"> +Favorite folder is missing. + +Select the "use as favorite folder" from a folder's menu to set it as the favorite folder. + <tag>fail</tag> + <usetemplate + name="okbutton" + yestext="OK"/> + </notification> + + <notification + icon="alertmodal.tga" + name="WaterExclusionSurfacesWarning" + type="alertmodal"> + Checking the hide water box will overwrite the texture, bumpiness, and shininess choices. + <tag>confirm</tag> + <usetemplate + name="okcancelbuttons" + notext="Cancel" + yestext="Continue"/> + </notification> </notifications> diff --git a/indra/newview/skins/default/xui/en/panel_avatar_list_item.xml b/indra/newview/skins/default/xui/en/panel_avatar_list_item.xml index ca6e94397d..970c6ad2f5 100644 --- a/indra/newview/skins/default/xui/en/panel_avatar_list_item.xml +++ b/indra/newview/skins/default/xui/en/panel_avatar_list_item.xml @@ -64,7 +64,31 @@ top="6" use_ellipses="true" value="(loading)" - width="180" /> + width="0" /> + <text + follows="right" + font="SansSerifSmall" + height="15" + layout="topleft" + left_pad="5" + right="-47" + name="avatar_arrival_time" + top="5" + text_color="LtGray_50" + value="0s" + width="200" /> + <text + follows="right" + font="SansSerifSmall" + height="15" + layout="topleft" + left_pad="5" + right="-132" + name="avatar_distance" + top="6" + text_color="LtGray_50" + value="0m" + width="60" /> <text follows="right" font="SansSerifSmall" diff --git a/indra/newview/skins/default/xui/en/panel_edit_alpha.xml b/indra/newview/skins/default/xui/en/panel_edit_alpha.xml index ab0e447028..f4ec27c027 100644 --- a/indra/newview/skins/default/xui/en/panel_edit_alpha.xml +++ b/indra/newview/skins/default/xui/en/panel_edit_alpha.xml @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <panel - background_visible="true" + background_visible="false" follows="all" height="400" layout="topleft" @@ -23,8 +23,8 @@ border="false" bg_alpha_color="DkGray2" bg_opaque_color="DkGray2" - background_visible="true" - background_opaque="true" + background_visible="false" + background_opaque="false" follows="top|left|right" height="400" left="0" diff --git a/indra/newview/skins/default/xui/en/panel_edit_eyes.xml b/indra/newview/skins/default/xui/en/panel_edit_eyes.xml index f1b2653340..89fa69bcef 100644 --- a/indra/newview/skins/default/xui/en/panel_edit_eyes.xml +++ b/indra/newview/skins/default/xui/en/panel_edit_eyes.xml @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <panel - background_visible="true" + background_visible="false" follows="all" height="400" layout="topleft" @@ -12,8 +12,8 @@ border="false" bg_alpha_color="DkGray2" bg_opaque_color="DkGray2" - background_visible="true" - background_opaque="true" + background_visible="false" + background_opaque="false" follows="top|left|right" height="90" left="10" @@ -41,8 +41,8 @@ border="false" bg_alpha_color="DkGray2" bg_opaque_color="DkGray2" - background_visible="true" - background_opaque="true" + background_visible="false" + background_opaque="false" follows="all" height="300" layout="topleft" diff --git a/indra/newview/skins/default/xui/en/panel_edit_gloves.xml b/indra/newview/skins/default/xui/en/panel_edit_gloves.xml index 6ae21e1273..14b20c7ba1 100644 --- a/indra/newview/skins/default/xui/en/panel_edit_gloves.xml +++ b/indra/newview/skins/default/xui/en/panel_edit_gloves.xml @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <panel - background_visible="true" + background_visible="false" follows="all" height="400" layout="topleft" @@ -12,8 +12,8 @@ border="false" bg_alpha_color="DkGray2" bg_opaque_color="DkGray2" - background_visible="true" - background_opaque="true" + background_visible="false" + background_opaque="false" follows="top|left|right" height="90" left="10" diff --git a/indra/newview/skins/default/xui/en/panel_edit_hair.xml b/indra/newview/skins/default/xui/en/panel_edit_hair.xml index 25f7d8a572..9eec1120e3 100644 --- a/indra/newview/skins/default/xui/en/panel_edit_hair.xml +++ b/indra/newview/skins/default/xui/en/panel_edit_hair.xml @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <panel - background_visible="true" + background_visible="false" follows="all" height="400" layout="topleft" @@ -12,8 +12,8 @@ border="false" bg_alpha_color="DkGray2" bg_opaque_color="DkGray2" - background_visible="true" - background_opaque="true" + background_visible="false" + background_opaque="false" follows="top|left|right" height="90" left="10" @@ -41,8 +41,8 @@ border="false" bg_alpha_color="DkGray2" bg_opaque_color="DkGray2" - background_visible="true" - background_opaque="true" + background_visible="false" + background_opaque="false" follows="all" height="300" layout="topleft" diff --git a/indra/newview/skins/default/xui/en/panel_edit_jacket.xml b/indra/newview/skins/default/xui/en/panel_edit_jacket.xml index 62ee69b43c..c76a04ccf0 100644 --- a/indra/newview/skins/default/xui/en/panel_edit_jacket.xml +++ b/indra/newview/skins/default/xui/en/panel_edit_jacket.xml @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <panel - background_visible="true" + background_visible="false" follows="all" height="400" layout="topleft" @@ -12,8 +12,8 @@ border="false" bg_alpha_color="DkGray2" bg_opaque_color="DkGray2" - background_visible="true" - background_opaque="true" + background_visible="false" + background_opaque="false" follows="top|left|right" height="90" left="10" diff --git a/indra/newview/skins/default/xui/en/panel_edit_pants.xml b/indra/newview/skins/default/xui/en/panel_edit_pants.xml index d2ba71f905..2f4d47f334 100644 --- a/indra/newview/skins/default/xui/en/panel_edit_pants.xml +++ b/indra/newview/skins/default/xui/en/panel_edit_pants.xml @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <panel - background_visible="true" + background_visible="false" follows="all" height="400" layout="topleft" @@ -12,8 +12,8 @@ border="false" bg_alpha_color="DkGray2" bg_opaque_color="DkGray2" - background_visible="true" - background_opaque="true" + background_visible="false" + background_opaque="false" follows="top|left|right" height="90" left="10" diff --git a/indra/newview/skins/default/xui/en/panel_edit_physics.xml b/indra/newview/skins/default/xui/en/panel_edit_physics.xml index 837fb83b64..235025b1ef 100644 --- a/indra/newview/skins/default/xui/en/panel_edit_physics.xml +++ b/indra/newview/skins/default/xui/en/panel_edit_physics.xml @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <panel - background_visible="true" + background_visible="false" follows="all" height="400" layout="topleft" @@ -12,8 +12,8 @@ border="false" bg_alpha_color="DkGray2" bg_opaque_color="DkGray2" - background_visible="true" - background_opaque="true" + background_visible="false" + background_opaque="false" follows="all" height="388" label="" diff --git a/indra/newview/skins/default/xui/en/panel_edit_shape.xml b/indra/newview/skins/default/xui/en/panel_edit_shape.xml index c1d743c3da..bd0335df6e 100644 --- a/indra/newview/skins/default/xui/en/panel_edit_shape.xml +++ b/indra/newview/skins/default/xui/en/panel_edit_shape.xml @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <panel - background_visible="true" + background_visible="false" follows="all" height="400" layout="topleft" diff --git a/indra/newview/skins/default/xui/en/panel_edit_shirt.xml b/indra/newview/skins/default/xui/en/panel_edit_shirt.xml index 059103e233..faca0ab2e7 100644 --- a/indra/newview/skins/default/xui/en/panel_edit_shirt.xml +++ b/indra/newview/skins/default/xui/en/panel_edit_shirt.xml @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <panel - background_visible="true" + background_visible="false" follows="all" height="400" layout="topleft" @@ -12,8 +12,8 @@ border="false" bg_alpha_color="DkGray2" bg_opaque_color="DkGray2" - background_visible="true" - background_opaque="true" + background_visible="false" + background_opaque="false" follows="top|left|right" height="90" left="10" diff --git a/indra/newview/skins/default/xui/en/panel_edit_shoes.xml b/indra/newview/skins/default/xui/en/panel_edit_shoes.xml index 199b143719..2068f48327 100644 --- a/indra/newview/skins/default/xui/en/panel_edit_shoes.xml +++ b/indra/newview/skins/default/xui/en/panel_edit_shoes.xml @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <panel - background_visible="true" + background_visible="false" follows="all" height="400" layout="topleft" @@ -12,8 +12,8 @@ border="false" bg_alpha_color="DkGray2" bg_opaque_color="DkGray2" - background_visible="true" - background_opaque="true" + background_visible="false" + background_opaque="false" follows="top|left|right" height="90" left="10" diff --git a/indra/newview/skins/default/xui/en/panel_edit_skin.xml b/indra/newview/skins/default/xui/en/panel_edit_skin.xml index f3a5791ef8..8e80283bbb 100644 --- a/indra/newview/skins/default/xui/en/panel_edit_skin.xml +++ b/indra/newview/skins/default/xui/en/panel_edit_skin.xml @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <panel - background_visible="true" + background_visible="false" follows="all" height="400" layout="topleft" @@ -12,8 +12,8 @@ border="false" bg_alpha_color="DkGray2" bg_opaque_color="DkGray2" - background_visible="true" - background_opaque="true" + background_visible="false" + background_opaque="false" follows="top|left|right" height="90" left="10" diff --git a/indra/newview/skins/default/xui/en/panel_edit_skirt.xml b/indra/newview/skins/default/xui/en/panel_edit_skirt.xml index adb7632e0a..ef93c8d8d2 100644 --- a/indra/newview/skins/default/xui/en/panel_edit_skirt.xml +++ b/indra/newview/skins/default/xui/en/panel_edit_skirt.xml @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <panel - background_visible="true" + background_visible="false" follows="all" height="400" layout="topleft" @@ -12,8 +12,8 @@ border="false" bg_alpha_color="DkGray2" bg_opaque_color="DkGray2" - background_visible="true" - background_opaque="true" + background_visible="false" + background_opaque="false" follows="top|left|right" height="90" left="10" diff --git a/indra/newview/skins/default/xui/en/panel_edit_socks.xml b/indra/newview/skins/default/xui/en/panel_edit_socks.xml index 1658e5707b..8fb19c34bb 100644 --- a/indra/newview/skins/default/xui/en/panel_edit_socks.xml +++ b/indra/newview/skins/default/xui/en/panel_edit_socks.xml @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <panel - background_visible="true" + background_visible="false" follows="all" height="400" layout="topleft" @@ -12,8 +12,8 @@ border="false" bg_alpha_color="DkGray2" bg_opaque_color="DkGray2" - background_visible="true" - background_opaque="true" + background_visible="false" + background_opaque="false" follows="top|left|right" height="90" left="10" diff --git a/indra/newview/skins/default/xui/en/panel_edit_tattoo.xml b/indra/newview/skins/default/xui/en/panel_edit_tattoo.xml index b4f09e262f..9cb2157896 100644 --- a/indra/newview/skins/default/xui/en/panel_edit_tattoo.xml +++ b/indra/newview/skins/default/xui/en/panel_edit_tattoo.xml @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <panel - background_visible="true" + background_visible="false" follows="all" height="400" layout="topleft" @@ -22,8 +22,8 @@ border="false" bg_alpha_color="DkGray2" bg_opaque_color="DkGray2" - background_visible="true" - background_opaque="true" + background_visible="false" + background_opaque="false" follows="all" height="800" left="10" diff --git a/indra/newview/skins/default/xui/en/panel_edit_underpants.xml b/indra/newview/skins/default/xui/en/panel_edit_underpants.xml index 9ca67ed562..6376787b3c 100644 --- a/indra/newview/skins/default/xui/en/panel_edit_underpants.xml +++ b/indra/newview/skins/default/xui/en/panel_edit_underpants.xml @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <panel - background_visible="true" + background_visible="false" follows="all" height="400" layout="topleft" @@ -12,8 +12,8 @@ border="false" bg_alpha_color="DkGray2" bg_opaque_color="DkGray2" - background_visible="true" - background_opaque="true" + background_visible="false" + background_opaque="false" follows="top|left|right" height="90" left="10" diff --git a/indra/newview/skins/default/xui/en/panel_edit_undershirt.xml b/indra/newview/skins/default/xui/en/panel_edit_undershirt.xml index 4a340fe340..88e1d9bc3b 100644 --- a/indra/newview/skins/default/xui/en/panel_edit_undershirt.xml +++ b/indra/newview/skins/default/xui/en/panel_edit_undershirt.xml @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <panel - background_visible="true" + background_visible="false" follows="all" height="400" layout="topleft" @@ -12,8 +12,8 @@ border="false" bg_alpha_color="DkGray2" bg_opaque_color="DkGray2" - background_visible="true" - background_opaque="true" + background_visible="false" + background_opaque="false" follows="top|left|right" height="90" left="10" diff --git a/indra/newview/skins/default/xui/en/panel_edit_universal.xml b/indra/newview/skins/default/xui/en/panel_edit_universal.xml index a71f6c6c2e..3a84f1733f 100644 --- a/indra/newview/skins/default/xui/en/panel_edit_universal.xml +++ b/indra/newview/skins/default/xui/en/panel_edit_universal.xml @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <panel - background_visible="true" + background_visible="false" follows="all" height="400" layout="topleft" @@ -22,8 +22,8 @@ border="false" bg_alpha_color="DkGray2" bg_opaque_color="DkGray2" - background_visible="true" - background_opaque="true" + background_visible="false" + background_opaque="false" follows="all" height="800" left="10" diff --git a/indra/newview/skins/default/xui/en/panel_edit_wearable.xml b/indra/newview/skins/default/xui/en/panel_edit_wearable.xml index 4d2069c9fe..df67f6ad46 100644 --- a/indra/newview/skins/default/xui/en/panel_edit_wearable.xml +++ b/indra/newview/skins/default/xui/en/panel_edit_wearable.xml @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <panel - background_visible="true" + background_visible="false" bevel_style="in" follows="all" height="570" @@ -178,8 +178,8 @@ use_ellipses="true" width="274" /> <panel - background_opaque="true" - background_visible="true" + background_opaque="false" + background_visible="false" bg_alpha_color="DkGray2" bg_opaque_color="DkGray2" border="false" diff --git a/indra/newview/skins/default/xui/en/panel_fs_search_legacy_classifieds.xml b/indra/newview/skins/default/xui/en/panel_fs_search_legacy_classifieds.xml new file mode 100644 index 0000000000..66c35558b1 --- /dev/null +++ b/indra/newview/skins/default/xui/en/panel_fs_search_legacy_classifieds.xml @@ -0,0 +1,169 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<panel + border="false" + follows="all" + height="566" + layout="topleft" + left="1" + width="780" + label="Classifieds" + name="panel_ls_classifieds"> + <panel + border="false" + follows="top|left|right" + height="53" + layout="topleft" + left="0" + width="780" + name="panel_ls_input"> + <text + type="string" + length="1" + follows="left|top" + top_pad="5" + layout="topleft" + left="6" + name="search_text" + top="12" + height="16" + width="156"> + Enter search terms: + </text> + <search_combo_box + layout="topleft" + follows="left|top|right" + height="23" + left_delta="0" + name="classifieds_edit" + top="29" + width="651" /> + <combo_box + follows="right|top" + layout="topleft" + height="23" + allow_text_entry="false" + top_delta="0" + left_pad="2" + name="classifieds_category" + width="122"> + <combo_box.commit_callback + function="CommitSearch" /> + </combo_box> + <check_box + control_name="ShowPGClassifieds" + follows="right|top" + height="16" + label="" + layout="topleft" + left="660" + name="pg_all" + top="12" + width="15"> + <check_box.commit_callback + function="CommitSearch" /> + </check_box> + <icon + follows="right|top" + height="16" + image_name="Parcel_PG_Dark" + layout="topleft" + left_pad="2" + name="rating_icon_general" + top_delta="-1" + width="18"/> + <check_box + control_name="ShowMatureClassifieds" + follows="right|top" + height="16" + label="" + layout="topleft" + left_pad="2" + name="mature_all" + top_delta="1" + width="15"> + <check_box.commit_callback + function="CommitSearch" /> + </check_box> + <icon + follows="right|top" + height="16" + image_name="Parcel_M_Dark" + layout="topleft" + left_pad="2" + name="rating_icon_moderate" + top_delta="-1" + width="18"/> + <check_box + control_name="ShowAdultClassifieds" + follows="right|top" + height="16" + label="" + layout="topleft" + left_pad="2" + name="adult_all" + top_delta="1" + width="15"> + <check_box.commit_callback + function="CommitSearch" /> + </check_box> + <icon + follows="right|top" + height="16" + image_name="Parcel_R_Dark" + layout="topleft" + left_pad="2" + name="rating_icon_adult" + top_delta="-1" + width="18"/> + </panel> + <!-- Search Pane --> + <panel + border="true" + follows="all" + height="510" + layout="topleft" + left="1" + width="410" + top_pad="1" + name="panel_ls_scrolllist"> + <scroll_list + draw_heading="true" + follows="all" + height="485" + layout="topleft" + left="0" + name="search_results_classifieds" + top="0" + width="410"> + <columns + label="" + name="icon" + width="20" /> + <columns + label="Name" + name="classified_name" + relwidth="0.70" /> + <columns + label="Listing Price" + name="price" + relwidth="0.3"/> + </scroll_list> + <button + layout="topleft" + follows="left|bottom" + height="23" + label="Back" + name="classifieds_back" + top_pad="2" + left="3" + width="100" /> + <button + layout="topleft" + follows="left|bottom" + height="23" + label="Next" + name="classifieds_next" + width="100" + left_pad="1" /> + </panel> +</panel> diff --git a/indra/newview/skins/default/xui/en/panel_fs_search_legacy_events.xml b/indra/newview/skins/default/xui/en/panel_fs_search_legacy_events.xml new file mode 100644 index 0000000000..57cb4990e4 --- /dev/null +++ b/indra/newview/skins/default/xui/en/panel_fs_search_legacy_events.xml @@ -0,0 +1,258 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<panel + border="false" + follows="all" + height="566" + layout="topleft" + left="1" + width="780" + label="Events" + name="panel_ls_events"> + <panel + border="false" + follows="top|left|right" + height="53" + layout="topleft" + left="0" + width="780" + name="panel_ls_input"> + <text + type="string" + length="1" + follows="left|top" + top_pad="5" + layout="topleft" + left="6" + name="search_text" + top="12" + height="16" + width="156"> + Enter search terms: + </text> + <radio_group + left_pad="20" + height="16" + width="300" + layout="topleft" + name="events_search_mode"> + <radio_item + height="16" + label="Ongoing and Upcoming" + layout="topleft" + name="current" + value="current" + top_pad="0" + width="120" /> + <radio_item + height="16" + label="By Date" + layout="topleft" + name="date" + value="date" + left_pad="70" + width="120" /> + <radio_group.commit_callback + function="CommitSearch" /> + </radio_group> + <text + type="string" + length="1" + follows="left|top" + top_delta="0" + layout="topleft" + left_pad="5" + name="events_date" + font.style="BOLD" + height="16" + width="80"> + 4/20 + </text> + <search_combo_box + layout="topleft" + follows="left|top|right" + height="23" + left="6" + name="events_edit" + top="29" + width="651" /> + <combo_box + follows="right|top" + layout="topleft" + height="23" + top_delta="0" + left_pad="2" + name="events_category" + width="122"> + <combo_box.item label="Any Category" name="any" value="0" /> + <combo_box.item label="" value="filter_separator" enabled="false" /> + <combo_box.item label="Discussion" name="discussion" value="18" /> + <combo_box.item label="Sports" name="sports" value="19" /> + <combo_box.item label="Live DJ" name="dj" value="30" /> + <combo_box.item label="Live Music" name="music" value="20" /> + <!-- <combo_box.item label="???" name="mystery_category" value="21" /> --> + <combo_box.item label="Commercial" name="commercial" value="22" /> + <combo_box.item label="Nightlife/Entertainment" name="nightlife" value="23" /> + <combo_box.item label="Games/Contests" name="games" value="24" /> + <combo_box.item label="Pageants" name="pageants" value="25" /> + <combo_box.item label="Education" name="education" value="26" /> + <combo_box.item label="Arts and Culture" name="arts" value="27" /> + <combo_box.item label="Charity/Support Groups" name="charity" value="28" /> + <combo_box.item label="Miscellaneous" name="misc" value="29" /> + <combo_box.commit_callback + function="CommitSearch" /> + </combo_box> + <check_box + control_name="ShowPGEvents" + follows="right|top" + height="16" + label="" + layout="topleft" + left="660" + name="pg_all" + top="12" + width="15" > + <check_box.commit_callback + function="CommitSearch" /> + </check_box> + <icon + follows="right|top" + height="16" + image_name="Parcel_PG_Dark" + layout="topleft" + left_pad="2" + name="rating_icon_general" + top_delta="-1" + width="18"/> + <check_box + control_name="ShowMatureEvents" + follows="right|top" + height="16" + label="" + layout="topleft" + left_pad="2" + name="mature_all" + top_delta="1" + width="15"> + <check_box.commit_callback + function="CommitSearch" /> + </check_box> + <icon + follows="right|top" + height="16" + image_name="Parcel_M_Dark" + layout="topleft" + left_pad="2" + name="rating_icon_moderate" + top_delta="-1" + width="18"/> + <check_box + control_name="ShowAdultEvents" + follows="right|top" + height="16" + label="" + layout="topleft" + left_pad="2" + name="adult_all" + top_delta="1" + width="15"> + <check_box.commit_callback + function="CommitSearch" /> + </check_box> + <icon + follows="right|top" + height="16" + image_name="Parcel_R_Dark" + layout="topleft" + left_pad="2" + name="rating_icon_adult" + top_delta="-1" + width="18"/> + </panel> + <!-- Search Pane --> + <panel + border="true" + follows="all" + height="510" + layout="topleft" + left="1" + width="410" + top_pad="1" + name="panel_ls_scrolllist"> + <scroll_list + draw_heading="true" + follows="all" + height="485" + layout="topleft" + left="0" + name="search_results_events" + sort_ascending="true" + sort_column="3" + top="0" + width="410"> + <columns + label="" + name="icon" + width="20" /> + <columns + label="Event Name" + name="name" + relwidth="0.72" /> + <columns + label="Date/Time" + name="date" + sort_column="time" + relwidth="0.28" /> + <columns + label="Time" + name="time" + width="0"/> + </scroll_list> + <button + layout="topleft" + follows="left|bottom" + height="23" + label="Yesterday" + name="events_yesterday" + top_pad="2" + left="3" + width="100" /> + <button + layout="topleft" + follows="left|bottom" + height="23" + label="Today" + name="events_today" + width="100" + left_pad="1" /> + <button + layout="topleft" + follows="left|bottom" + height="23" + label="Tomorrow" + name="events_tomorrow" + width="100" + left_pad="1" /> + <button + layout="topleft" + follows="left|bottom" + height="23" + image_bottom_pad="2" + image_overlay="Arrow_Left_Off" + image_overlay_alignment="left" + label="Back" + name="events_back" + width="25" + left_pad="1" /> + <button + layout="topleft" + follows="left|bottom" + height="23" + image_bottom_pad="2" + image_overlay="Arrow_Right_Off" + image_overlay_alignment="left" + label="Next" + name="events_next" + width="25" + left_pad="1" /> + </panel> +</panel> diff --git a/indra/newview/skins/default/xui/en/panel_fs_search_legacy_groups.xml b/indra/newview/skins/default/xui/en/panel_fs_search_legacy_groups.xml new file mode 100644 index 0000000000..90001952f7 --- /dev/null +++ b/indra/newview/skins/default/xui/en/panel_fs_search_legacy_groups.xml @@ -0,0 +1,159 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<panel + border="false" + follows="all" + height="566" + layout="topleft" + left="1" + width="780" + label="Groups" + name="panel_ls_groups"> + <panel + border="false" + follows="top|left|right" + height="53" + layout="topleft" + left="0" + width="780" + name="panel_ls_input"> + <text + type="string" + length="1" + follows="left|top" + top_pad="5" + layout="topleft" + left="6" + name="search_text" + top="12" + height="16" + width="156"> + Enter search terms: + </text> + <search_combo_box + layout="topleft" + follows="left|top|right" + height="23" + left_delta="0" + name="groups_edit" + top="29" + width="770"> + </search_combo_box> + <check_box + control_name="ShowPGGroups" + follows="right|top" + height="16" + label="" + layout="topleft" + left="660" + name="pg_all" + top="12" + width="15" + visible="false"/> + <icon + follows="right|top" + height="16" + image_name="Parcel_PG_Dark" + layout="topleft" + left_pad="2" + name="rating_icon_general" + top_delta="-1" + width="18" + visible="false"/> + <check_box + control_name="ShowMatureGroups" + follows="right|top" + height="16" + label="" + layout="topleft" + left_pad="2" + name="mature_all" + top_delta="1" + width="15" + visible="false"/> + <icon + follows="right|top" + height="16" + image_name="Parcel_M_Dark" + layout="topleft" + left_pad="2" + name="rating_icon_moderate" + top_delta="-1" + width="18" + visible="false"/> + <check_box + control_name="ShowAdultGroups" + follows="right|top" + height="16" + label="" + layout="topleft" + left_pad="2" + name="adult_all" + top_delta="1" + width="15" + visible="false"/> + <icon + follows="right|top" + height="16" + image_name="Parcel_R_Dark" + layout="topleft" + left_pad="2" + name="rating_icon_adult" + top_delta="-1" + width="18" + visible="false"/> + </panel> + <!-- Search Pane --> + <panel + border="true" + follows="all" + height="510" + layout="topleft" + left="1" + width="410" + top_pad="1" + name="panel_ls_scrolllist"> + <scroll_list + draw_heading="true" + follows="all" + height="485" + layout="topleft" + left="0" + name="search_results_groups" + top="0" + width="410"> + <columns + label="" + name="icon" + width="20" /> + <columns + label="Group Name" + name="group_name" + relwidth="0.72" /> + <columns + label="Members" + name="members" + relwidth="0.25" /> + <columns + label="Score" + name="score" + width="0" /> + </scroll_list> + <button + layout="topleft" + follows="left|bottom" + height="23" + label="Back" + name="groups_back" + top_pad="2" + left="3" + width="100" /> + <button + layout="topleft" + follows="left|bottom" + height="23" + label="Next" + name="groups_next" + width="100" + left_pad="1" /> + </panel> +</panel> diff --git a/indra/newview/skins/default/xui/en/panel_fs_search_legacy_land.xml b/indra/newview/skins/default/xui/en/panel_fs_search_legacy_land.xml new file mode 100644 index 0000000000..bb03a1e999 --- /dev/null +++ b/indra/newview/skins/default/xui/en/panel_fs_search_legacy_land.xml @@ -0,0 +1,281 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<panel + border="false" + follows="all" + height="566" + layout="topleft" + left="1" + width="780" + label="Land Sales" + name="panel_ls_land"> + <panel + border="false" + follows="top|left|right" + height="53" + layout="topleft" + left="0" + width="780" + name="panel_ls_input"> + <check_box + control_name="ShowPGLand" + follows="right|top" + height="16" + label="" + layout="topleft" + left="660" + name="pg_all" + top="12" + width="15"> + <check_box.commit_callback + function="CommitSearch" /> + </check_box> + <icon + follows="right|top" + height="16" + image_name="Parcel_PG_Dark" + layout="topleft" + left_pad="2" + name="rating_icon_general" + top_delta="-1" + width="18"/> + <check_box + control_name="ShowMatureLand" + follows="right|top" + height="16" + label="" + layout="topleft" + left_pad="2" + name="mature_all" + top_delta="1" + width="15"> + <check_box.commit_callback + function="CommitSearch" /> + </check_box> + <icon + follows="right|top" + height="16" + image_name="Parcel_M_Dark" + layout="topleft" + left_pad="2" + name="rating_icon_moderate" + top_delta="-1" + width="18"/> + <check_box + control_name="ShowAdultLand" + follows="right|top" + height="16" + label="" + layout="topleft" + left_pad="2" + name="adult_all" + top_delta="1" + width="15"> + <check_box.commit_callback + function="CommitSearch" /> + </check_box> + <icon + follows="right|top" + height="16" + image_name="Parcel_R_Dark" + layout="topleft" + left_pad="2" + name="rating_icon_adult" + top_delta="-1" + width="18"/> + <text + type="string" + length="1" + follows="left|top" + layout="topleft" + left="6" + name="search_text" + top="12" + height="16" + width="256"> + Enter search terms: + </text> + <combo_box + control_name="FindLandType" + follows="left|top" + layout="topleft" + height="23" + allow_text_entry="false" + top_pad="2" + left="6" + name="land_category" + width="122"> + <combo_box.item label="All Categories" name="All" value="All"/> + <combo_box.item label="Auction" name="Auction" value="Auction"/> + <combo_box.item label="Mainland Sales" name="Mainland" value="Mainland"/> + <combo_box.item label="Estate Sales" name="Estate" value="Estate"/> + <combo_box.commit_callback + function="CommitSearch" /> + </combo_box> + <check_box + control_name="FindLandPrice" + follows="left|top" + height="16" + label="Price <" + layout="topleft" + left_pad="3" + name="price_check" + top_delta="3" + width="40" > + <check_box.commit_callback + function="CommitSearch" /> + </check_box> + <line_editor + enabled_control="FindLandPrice" + bevel_style="none" + border_style="line" + border.border_thickness="0" + commit_on_focus_lost="false" + follows="left|top" + height="18" + left_pad="20" + name="edit_price" + top_delta="-1" + width="40" > + <line_editor.commit_callback + function="CommitSearch" /> + </line_editor> + <check_box + control_name="FindLandArea" + follows="left|top" + height="16" + label="Area >" + layout="topleft" + left_pad="3" + name="area_check" + top_delta="1" + width="40" > + <check_box.commit_callback + function="CommitSearch" /> + </check_box> + <line_editor + enabled_control="FindLandArea" + bevel_style="none" + border_style="line" + border.border_thickness="0" + commit_on_focus_lost="false" + follows="left|top" + height="18" + left_pad="20" + name="edit_area" + top_delta="-1" + width="40" > + <line_editor.commit_callback + function="CommitSearch" /> + </line_editor> + <text + type="string" + length="1" + follows="left|top" + layout="topleft" + left="365" + name="sort_text" + top="12" + height="16" + width="98"> + Sort results by: + </text> + <check_box + follows="left|top" + height="16" + label="Ascending" + layout="topleft" + left_pad="3" + name="ascending_check" + width="100" > + <check_box.commit_callback + function="CommitSearch" /> + </check_box> + <combo_box + follows="left|top" + layout="topleft" + height="23" + allow_text_entry="false" + left_delta="-102" + top_pad="1" + name="land_sort_combo" + width="118"> + <combo_box.item label="Name" name="Name_item" value="Name"/> + <combo_box.item label="Price" name="Price_item" value="Price"/> + <combo_box.item label="Price per meter" name="PPM_item" value="PPM"/> + <combo_box.item label="Area" name="Area_item" value="Area"/> + <combo_box.commit_callback + function="CommitSearch" /> + </combo_box> + <button + follows="top|right" + height="23" + label="Search" + layout="topleft" + left="678" + top_delta="0" + name="land_find" + width="100" /> + </panel> + <!-- Search Pane --> + <panel + border="true" + follows="all" + height="510" + layout="topleft" + left="1" + width="410" + top_pad="1" + name="panel_ls_scrolllist"> + <scroll_list + draw_heading="true" + follows="all" + height="485" + layout="topleft" + left="0" + name="search_results_land" + top="0" + width="410"> + <columns + label="" + name="icon" + width="20" /> + <columns + label="Name" + name="land_name" + relwidth="0.45" /> + <columns + label="Price" + name="price" + relwidth="0.1" /> + <columns + label="Area" + name="area" + relwidth="0.1" /> + <columns + label="L$/m" + name="ppm" + relwidth="0.1" /> + <columns + label="Type" + name="land_type" + relwidth="0.2" /> + </scroll_list> + <button + layout="topleft" + follows="left|bottom" + height="23" + label="Back" + name="land_back" + top_pad="2" + left="3" + width="100" /> + <button + layout="topleft" + follows="left|bottom" + height="23" + label="Next" + name="land_next" + width="100" + left_pad="1" /> + </panel> +</panel> diff --git a/indra/newview/skins/default/xui/en/panel_fs_search_legacy_people.xml b/indra/newview/skins/default/xui/en/panel_fs_search_legacy_people.xml new file mode 100644 index 0000000000..28df02a7e3 --- /dev/null +++ b/indra/newview/skins/default/xui/en/panel_fs_search_legacy_people.xml @@ -0,0 +1,89 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<panel + border="false" + follows="all" + height="566" + layout="topleft" + left="1" + width="780" + label="People" + name="panel_ls_people"> + <panel + border="false" + follows="top|left|right" + height="53" + layout="topleft" + left="0" + width="780" + name="panel_ls_input"> + <text + type="string" + length="1" + follows="left|top" + top_pad="5" + layout="topleft" + left="6" + name="search_text" + top="12" + height="16" + width="156"> + Enter search terms: + </text> + <search_combo_box + layout="topleft" + follows="left|top|right" + height="23" + left_delta="0" + name="people_edit" + top="29" + width="770"> + </search_combo_box> + </panel> + <!-- Search Pane --> + <panel + border="true" + follows="all" + height="510" + layout="topleft" + left="1" + width="410" + top_pad="1" + name="panel_ls_scrolllist"> + <scroll_list + content_type="Agents" + draw_heading="true" + follows="all" + height="485" + layout="topleft" + left="0" + name="search_results_people" + top="0" + width="410"> + <columns + label="" + name="icon" + width="20" /> + <columns + label="Name" + name="username" + relwidth="1" /> + </scroll_list> + <button + layout="topleft" + follows="left|bottom" + height="23" + label="Back" + name="people_back" + top_pad="2" + left="3" + width="100" /> + <button + layout="topleft" + follows="left|bottom" + height="23" + label="Next" + name="people_next" + width="100" + left_pad="1" /> + </panel> +</panel>
\ No newline at end of file diff --git a/indra/newview/skins/default/xui/en/panel_fs_search_legacy_places.xml b/indra/newview/skins/default/xui/en/panel_fs_search_legacy_places.xml new file mode 100644 index 0000000000..09c142b8fc --- /dev/null +++ b/indra/newview/skins/default/xui/en/panel_fs_search_legacy_places.xml @@ -0,0 +1,169 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<panel + border="false" + follows="all" + height="566" + layout="topleft" + left="1" + width="780" + label="Places" + name="panel_ls_places"> + <panel + border="false" + follows="top|left|right" + height="53" + layout="topleft" + left="0" + width="780" + name="panel_ls_input"> + <text + type="string" + length="1" + follows="left|top" + top_pad="5" + layout="topleft" + left="6" + name="search_text" + top="12" + height="16" + width="156"> + Enter search terms: + </text> + <search_combo_box + layout="topleft" + follows="left|top|right" + height="23" + left_delta="0" + name="places_edit" + top="29" + width="651" /> + <combo_box + follows="right|top" + layout="topleft" + height="23" + allow_text_entry="false" + top_delta="0" + left_pad="2" + name="places_category" + width="122"> + <combo_box.commit_callback + function="CommitSearch" /> + </combo_box> + <check_box + control_name="ShowPGSims" + follows="right|top" + height="16" + label="" + layout="topleft" + left="660" + name="pg_all" + top="12" + width="15"> + <check_box.commit_callback + function="CommitSearch" /> + </check_box> + <icon + follows="right|top" + height="16" + image_name="Parcel_PG_Dark" + layout="topleft" + left_pad="2" + name="rating_icon_general" + top_delta="-1" + width="18"/> + <check_box + control_name="ShowMatureSims" + follows="right|top" + height="16" + label="" + layout="topleft" + left_pad="2" + name="mature_all" + top_delta="1" + width="15"> + <check_box.commit_callback + function="CommitSearch" /> + </check_box> + <icon + follows="right|top" + height="16" + image_name="Parcel_M_Dark" + layout="topleft" + left_pad="2" + name="rating_icon_moderate" + top_delta="-1" + width="18"/> + <check_box + control_name="ShowAdultSims" + follows="right|top" + height="16" + label="" + layout="topleft" + left_pad="2" + name="adult_all" + top_delta="1" + width="15"> + <check_box.commit_callback + function="CommitSearch" /> + </check_box> + <icon + follows="right|top" + height="16" + image_name="Parcel_R_Dark" + layout="topleft" + left_pad="2" + name="rating_icon_adult" + top_delta="-1" + width="18"/> + </panel> + <!-- Search Pane --> + <panel + border="true" + follows="all" + height="510" + layout="topleft" + left="1" + width="410" + top_pad="1" + name="panel_ls_scrolllist"> + <scroll_list + draw_heading="true" + follows="all" + height="485" + layout="topleft" + left="0" + name="search_results_places" + top="0" + width="410"> + <columns + label="" + name="icon" + width="20" /> + <columns + label="Name" + name="place_name" + relwidth="0.81" /> + <columns + label="Traffic" + name="dwell" + relwidth="0.16" /> + </scroll_list> + <button + layout="topleft" + follows="left|bottom" + height="23" + label="Back" + name="places_back" + top_pad="2" + left="3" + width="100" /> + <button + layout="topleft" + follows="left|bottom" + height="23" + label="Next" + name="places_next" + width="100" + left_pad="1" /> + </panel> +</panel> diff --git a/indra/newview/skins/default/xui/en/panel_fs_search_legacy_web.xml b/indra/newview/skins/default/xui/en/panel_fs_search_legacy_web.xml new file mode 100644 index 0000000000..382a5e8945 --- /dev/null +++ b/indra/newview/skins/default/xui/en/panel_fs_search_legacy_web.xml @@ -0,0 +1,21 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<panel +border="false" +follows="all" +height="566" +layout="topleft" +left="1" +width="780" +label="Websearch" +name="panel_ls_web"> + <web_browser + top="5" + bottom="-1" + left="5" + right="-5" + layout="topleft" + follows="all" + name="search_browser" + trusted_content="true" + start_url="about:blank" /> +</panel>
\ No newline at end of file diff --git a/indra/newview/skins/default/xui/en/panel_group_general.xml b/indra/newview/skins/default/xui/en/panel_group_general.xml index 7290cbb5c6..aac4037bb3 100644 --- a/indra/newview/skins/default/xui/en/panel_group_general.xml +++ b/indra/newview/skins/default/xui/en/panel_group_general.xml @@ -145,6 +145,18 @@ Hover your mouse over the options for more help. tool_tip="Sets whether you want to receive Notices from this group. Uncheck this box if this group is spamming you." top_pad="5" width="300" /> + <!-- <exodus> --> + <check_box + height="16" + font="SansSerifSmall" + label="Receive group instant messages" + layout="topleft" + left="10" + name="receive_chat" + tool_tip="Sets whether you want to participate in group chat for this group." + top_pad="5" + width="300" /> + <!-- </exodus> --> <check_box height="16" label="Show in my profile" diff --git a/indra/newview/skins/default/xui/en/panel_group_info_sidetray.xml b/indra/newview/skins/default/xui/en/panel_group_info_sidetray.xml index ad9dbd1156..da900c783b 100644 --- a/indra/newview/skins/default/xui/en/panel_group_info_sidetray.xml +++ b/indra/newview/skins/default/xui/en/panel_group_info_sidetray.xml @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <panel -background_visible="true" +background_visible="false" follows="all" height="570" label="Group Profile" diff --git a/indra/newview/skins/default/xui/en/panel_landmark_info.xml b/indra/newview/skins/default/xui/en/panel_landmark_info.xml index af68bd7fee..e25145dd2a 100644 --- a/indra/newview/skins/default/xui/en/panel_landmark_info.xml +++ b/indra/newview/skins/default/xui/en/panel_landmark_info.xml @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <panel - background_visible="true" + background_visible="false" follows="all" height="570" layout="topleft" @@ -83,7 +83,7 @@ value="Place Profile" width="280" /> <scroll_container - color="DkGray2" + color="Transparent" follows="all" height="534" layout="topleft" @@ -93,7 +93,7 @@ top_pad="9" width="324"> <panel - bg_alpha_color="DkGray2" + bg_alpha_color="Transparent" follows="left|top|right" height="654" layout="topleft" @@ -280,8 +280,8 @@ <line_editor text_readonly_color="white" enabled="false" - use_bg_color="true" - bg_color="DkGray0" + use_bg_color="false" + bg_color="Transparent" follows="left|top|right" height="22" layout="topleft" @@ -322,7 +322,7 @@ value="My notes:" width="290" /> <text_editor - bg_readonly_color="DkGray0" + bg_readonly_color="Transparent" follows="all" height="75" layout="topleft" diff --git a/indra/newview/skins/default/xui/en/panel_login.xml b/indra/newview/skins/default/xui/en/panel_login.xml index 27b74a46ce..0682a5d680 100644 --- a/indra/newview/skins/default/xui/en/panel_login.xml +++ b/indra/newview/skins/default/xui/en/panel_login.xml @@ -6,7 +6,7 @@ name="panel_login" focus_root="true" background_visible="true" - bg_opaque_color="0.16 0.16 0.16 1" + bg_opaque_color="0.0 0.0 0.0 1" background_opaque="true" width="1024"> <panel.string @@ -41,7 +41,7 @@ <icon height="73" width="165" - image_name="login_sl_logo" + image_name="login_mp_logo" left="0" top="25" name="sl_logo_small" /> diff --git a/indra/newview/skins/default/xui/en/panel_login_first.xml b/indra/newview/skins/default/xui/en/panel_login_first.xml index c906e2f96c..0a8ae48b02 100644 --- a/indra/newview/skins/default/xui/en/panel_login_first.xml +++ b/indra/newview/skins/default/xui/en/panel_login_first.xml @@ -6,7 +6,7 @@ name="panel_login" focus_root="true" background_visible="true" - bg_opaque_color="0.16 0.16 0.16 1" + bg_opaque_color="0.0 0.0 0.0 1" background_opaque="true" width="1024"> <panel.string @@ -61,7 +61,7 @@ height="105"> <icon height="94" - image_name="login_sl_logo" + image_name="login_mp_logo" left="0" name="sl_logo" top="0" /> @@ -179,7 +179,6 @@ control_name="RememberPassword" follows="left|top" font="SansSerifLarge" - text_color="EmphasisColor" height="24" left="262" bottom_delta="0" diff --git a/indra/newview/skins/default/xui/en/panel_navigation_bar.xml b/indra/newview/skins/default/xui/en/panel_navigation_bar.xml index 85cf4419a3..95787c16c5 100644 --- a/indra/newview/skins/default/xui/en/panel_navigation_bar.xml +++ b/indra/newview/skins/default/xui/en/panel_navigation_bar.xml @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <panel - background_opaque="true" - background_visible="true" + background_opaque="false" + background_visible="false" bg_opaque_color="MouseGray" follows="left|top|right" height="34" @@ -19,18 +19,18 @@ left="0" top="0" height="34" - width="600"/> + width="800"/> <icon follows="all" image_name="NavBar_BG_NoFav_Bevel" mouse_opaque="false" name="bg_icon_no_fav_bevel" scale_image="true" - visible="false" + visible="true" left="0" top="0" height="34" - width="600"/> + width="800"/> <icon follows="all" image_name="NavBar_BG_NoNav_Bevel" @@ -41,7 +41,7 @@ left="0" top="0" height="34" - width="600"/> + width="800"/> <icon follows="all" image_name="NavBar Separator" diff --git a/indra/newview/skins/default/xui/en/panel_notify_textbox.xml b/indra/newview/skins/default/xui/en/panel_notify_textbox.xml index 27d0f7d383..544d90a84f 100644 --- a/indra/newview/skins/default/xui/en/panel_notify_textbox.xml +++ b/indra/newview/skins/default/xui/en/panel_notify_textbox.xml @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <panel - background_visible="true" + background_visible="false" height="215" label="instant_message" layout="topleft" diff --git a/indra/newview/skins/default/xui/en/panel_outfit_edit.xml b/indra/newview/skins/default/xui/en/panel_outfit_edit.xml index a0e3344304..dc8ac425b6 100644 --- a/indra/newview/skins/default/xui/en/panel_outfit_edit.xml +++ b/indra/newview/skins/default/xui/en/panel_outfit_edit.xml @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <!-- Side tray Outfit Edit panel --> <panel - background_visible="true" + background_visible="false" border="false" height="600" follows="all" @@ -87,8 +87,8 @@ <!-- "HEADER WITH ICON, STATUS TEXT AND OUTFIT NAME" --> <panel - background_visible="true" - bg_alpha_color="DkGray2" + background_visible="false" + bg_alpha_color="MouseGray" bevel_style="none" follows="top|left|right" height="40" @@ -360,7 +360,7 @@ It is calculated as border_size + 2*UIResizeBarOverlap <!-- BUTTON BAR --> <panel - background_visible="true" + background_visible="false" bevel_style="none" follows="bottom|left|right" height="27" @@ -407,7 +407,7 @@ It is calculated as border_size + 2*UIResizeBarOverlap <!-- BUTTON BAR - WEARABLES ADDING MODE --> <panel - background_visible="true" + background_visible="false" bevel_style="none" follows="left|right|bottom" height="27" diff --git a/indra/newview/skins/default/xui/en/panel_outfit_gallery.xml b/indra/newview/skins/default/xui/en/panel_outfit_gallery.xml index 6bd491f7a3..6166268206 100644 --- a/indra/newview/skins/default/xui/en/panel_outfit_gallery.xml +++ b/indra/newview/skins/default/xui/en/panel_outfit_gallery.xml @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <panel - background_visible="true" + background_visible="false" bg_alpha_color="DkGray" border="false" follows="all" @@ -46,7 +46,7 @@ top_pad="0"> </scroll_container> <panel - background_visible="true" + background_visible="false" follows="bottom|left|right" height="28" layout="topleft" diff --git a/indra/newview/skins/default/xui/en/panel_outfits_inventory.xml b/indra/newview/skins/default/xui/en/panel_outfits_inventory.xml index d58c2ec2e9..8e21b4d5fe 100644 --- a/indra/newview/skins/default/xui/en/panel_outfits_inventory.xml +++ b/indra/newview/skins/default/xui/en/panel_outfits_inventory.xml @@ -1,9 +1,9 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <panel name="Outfits" - bg_alpha_color="DkGray" - bg_opaque_color="DkGray" - background_opaque="true" - background_visible="true" + bg_alpha_color="MouseGray" + bg_opaque_color="MouseGray" + background_opaque="false" + background_visible="false" follows="all" height="575" label="Things" @@ -37,7 +37,7 @@ filename="panel_outfit_gallery.xml" height="520" name="outfit_gallery_tab" - background_visible="true" + background_visible="false" help_topic="outfit_gallery_tab" follows="all" label="OUTFIT GALLERY" @@ -48,15 +48,15 @@ filename="panel_outfits_list.xml" height="520" name="outfitslist_tab" - background_visible="true" + background_visible="false" help_topic="my_outfits_tab" follows="all" label="MY OUTFITS" layout="topleft" width="315" /> <panel - background_visible="true" - bg_alpha_color="DkGray" + background_visible="false" + bg_alpha_color="MouseGray" class="panel_wearing" filename="panel_outfits_wearing.xml" follows="all" @@ -69,7 +69,7 @@ </tab_container> <panel - background_visible="true" + background_visible="false" follows="bottom|left|right" height="27" layout="topleft" diff --git a/indra/newview/skins/default/xui/en/panel_outfits_list.xml b/indra/newview/skins/default/xui/en/panel_outfits_list.xml index 9281a21fbf..e8d8e8f3e2 100644 --- a/indra/newview/skins/default/xui/en/panel_outfits_list.xml +++ b/indra/newview/skins/default/xui/en/panel_outfits_list.xml @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <panel - background_visible="true" + background_visible="false" bg_alpha_color="DkGray" border="false" follows="all" @@ -11,7 +11,7 @@ top="0" width="312"> <accordion - background_visible="true" + background_visible="false" bg_alpha_color="DkGray2" bg_opaque_color="DkGray2" @@ -31,7 +31,7 @@ value="You don't have any outfits yet. Try [secondlife:///app/search/all/ Search]"/> </accordion> <panel - background_visible="true" + background_visible="false" follows="bottom|left|right" height="28" layout="topleft" diff --git a/indra/newview/skins/default/xui/en/panel_outfits_wearing.xml b/indra/newview/skins/default/xui/en/panel_outfits_wearing.xml index a486c03ac7..559917ec0a 100644 --- a/indra/newview/skins/default/xui/en/panel_outfits_wearing.xml +++ b/indra/newview/skins/default/xui/en/panel_outfits_wearing.xml @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <panel - background_visible="true" + background_visible="false" bg_alpha_color="DkGray" follows="all" height="430" @@ -22,7 +22,7 @@ single_expansion="true" top="0" name="wearables_accordion" - background_visible="true" + background_visible="false" bg_alpha_color="DkGray2" width="309"> <accordion_tab @@ -63,7 +63,7 @@ </accordion_tab> </accordion> <panel - background_visible="true" + background_visible="false" follows="bottom|left|right" height="28" layout="topleft" diff --git a/indra/newview/skins/default/xui/en/panel_people.xml b/indra/newview/skins/default/xui/en/panel_people.xml index c31e6c94ea..f1c03fdaa8 100644 --- a/indra/newview/skins/default/xui/en/panel_people.xml +++ b/indra/newview/skins/default/xui/en/panel_people.xml @@ -223,6 +223,8 @@ Learn about [https://community.secondlife.com/knowledgebase/joining-and-particip keep_one_selected="false" multi_select="true" name="avatar_list" + show_avatar_arrival_time="true" + show_avatar_distance="true" right="-1" top="2" /> </layout_panel> diff --git a/indra/newview/skins/default/xui/en/panel_performance_preferences.xml b/indra/newview/skins/default/xui/en/panel_performance_preferences.xml index 7ba7b1d579..ece9bb2552 100644 --- a/indra/newview/skins/default/xui/en/panel_performance_preferences.xml +++ b/indra/newview/skins/default/xui/en/panel_performance_preferences.xml @@ -209,11 +209,11 @@ follows="left|top" top_delta="-1" height="16" - increment="8" - initial_value="160" + increment="16" + initial_value="128" label_width="90" layout="topleft" - min_val="64" + min_val="32" max_val="512" name="draw_distance" left_pad="5" @@ -427,6 +427,16 @@ layout="topleft" top="80" left="213" + name="0_lbl" + width="7"> + 0 + </text> + <text + follows="left|top" + font="SansSerifSmall" + height="18" + layout="topleft" + left_pad="31" name="1_lbl" width="7"> 1 @@ -436,7 +446,7 @@ font="SansSerifSmall" height="18" layout="topleft" - left_pad="31" + left_pad="30" name="2_lbl" width="7"> 2 @@ -479,16 +489,6 @@ left_pad="30" name="6_lbl" width="7"> - 6 - </text> - <text - follows="left|top" - font="SansSerifSmall" - height="18" - layout="topleft" - left_pad="30" - name="7_lbl" - width="7"> - 7 + 6 </text> </panel> diff --git a/indra/newview/skins/default/xui/en/panel_place_profile.xml b/indra/newview/skins/default/xui/en/panel_place_profile.xml index 8f5292c531..9aa0907a38 100644 --- a/indra/newview/skins/default/xui/en/panel_place_profile.xml +++ b/indra/newview/skins/default/xui/en/panel_place_profile.xml @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <panel - background_visible="true" + background_visible="false" follows="all" height="610" layout="topleft" @@ -188,17 +188,18 @@ value="Place Profile" width="280" /> <scroll_container - color="DkGray2" + color="Transparent" follows="all" height="575" layout="topleft" left="9" name="place_scroll" - opaque="true" + opaque="false" top_pad="9" width="324"> <panel - bg_alpha_color="DkGray2" + bg_alpha_color="Transparent" + background_visible="false" follows="left|top|right|bottom" height="597" layout="topleft" diff --git a/indra/newview/skins/default/xui/en/panel_places.xml b/indra/newview/skins/default/xui/en/panel_places.xml index a3a2f7c47e..4d9a03823e 100644 --- a/indra/newview/skins/default/xui/en/panel_places.xml +++ b/indra/newview/skins/default/xui/en/panel_places.xml @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <panel -background_visible="true" +background_visible="false" default_tab_group="1" follows="all" height="570" diff --git a/indra/newview/skins/default/xui/en/panel_preferences_colors.xml b/indra/newview/skins/default/xui/en/panel_preferences_colors.xml index 44df5354aa..b6fdef3475 100644 --- a/indra/newview/skins/default/xui/en/panel_preferences_colors.xml +++ b/indra/newview/skins/default/xui/en/panel_preferences_colors.xml @@ -390,4 +390,46 @@ show_text="true" top_pad="5" width="415" /> + +<text + type="string" + length="1" + follows="left|top" + height="15" + layout="topleft" + left="30" + name="skin_selection_label" + top_pad="10" + width="400"> + Skin + </text> + <radio_group + control_name="skin_selection" + height="20" + layout="topleft" + left="35" + top_pad="0" + name="skin_selection"> + <radio_item + label="default" + name="radio" + top_delta="20" + layout="topleft" + height="16" + left="0" + value="default" + width="75" /> + <radio_item + label="contrast" + left_pad="0" + layout="topleft" + top_delta="0" + height="16" + name="radio2" + value="contrast" + width="75" /> + <radio_group.commit_callback + function="Pref.SelectSkin" /> + </radio_group> + </panel> diff --git a/indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml b/indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml index 248cb04e6f..fa692d7200 100644 --- a/indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml +++ b/indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml @@ -39,7 +39,7 @@ layout="topleft" left="10" name="QualitySpeed" - top_delta="35" + top_delta="35" width="400"> Quality & speed: </text> @@ -207,29 +207,63 @@ decimal_digits="0" follows="left|top" height="16" - increment="8" + increment="32" initial_value="160" label="Draw distance:" - label_width="90" + label_width="187" layout="topleft" left="30" - min_val="64" + min_val="32" max_val="512" name="DrawDistance" top_delta="40" - width="330" /> + width="427" /> <text type="string" length="1" follows="left|top" height="12" layout="topleft" - left_delta="330" + left_delta="427" name="DrawDistanceMeterText2" top_delta="0" width="128"> m </text> + <slider + control_name="IndirectMaxNonImpostors" + name="IndirectMaxNonImpostors" + decimal_digits="0" + increment="1" + initial_value="12" + show_text="false" + min_val="1" + max_val="66" + label="Maximum number of animated avatars:" + follows="left|top" + layout="topleft" + height="16" + label_width="240" + left="30" + top_delta="40" + width="393"> + <slider.commit_callback + function="Pref.UpdateIndirectMaxNonImpostors" + parameter="IndirectNonImpostorsText" /> + </slider> + <text + type="string" + length="1" + follows="left|top" + height="16" + layout="topleft" + top_delta="0" + left_delta="397" + text_readonly_color="LabelDisabledColor" + name="IndirectMaxNonImpostorsText" + width="65"> + 0 + </text> <button height="23" @@ -277,7 +311,7 @@ name="2" value="2"/> </combo_box> - + <slider control_name="IndirectMaxComplexity" tool_tip="Controls at what point a visually complex avatar is drawn as a JellyDoll" diff --git a/indra/newview/skins/default/xui/en/panel_preferences_move.xml b/indra/newview/skins/default/xui/en/panel_preferences_move.xml index 0412466b4f..8202bb9de3 100644 --- a/indra/newview/skins/default/xui/en/panel_preferences_move.xml +++ b/indra/newview/skins/default/xui/en/panel_preferences_move.xml @@ -268,6 +268,15 @@ name="sound_on_collisions" top_pad="10" width="200" /> + <check_box + control_name="DoubleClickZoomIn" + height="20" + label="Double click on nearby list to zoom in on avatar" + layout="topleft" + left="83" + name="double_click_zoom_in" + top_pad="10" + width="200" /> <button height="23" label="Other Devices" diff --git a/indra/newview/skins/default/xui/en/panel_preferences_setup.xml b/indra/newview/skins/default/xui/en/panel_preferences_setup.xml index 28c2d2af6e..258c49785e 100644 --- a/indra/newview/skins/default/xui/en/panel_preferences_setup.xml +++ b/indra/newview/skins/default/xui/en/panel_preferences_setup.xml @@ -202,7 +202,7 @@ follows="left|top" height="14" control_name="UpdaterWillingToTest" - label="Willing to update to release candidates" + label="Willing to update to Beta" left_delta="0" mouse_opaque="true" name="update_willing_to_test" diff --git a/indra/newview/skins/default/xui/en/panel_preferences_sound.xml b/indra/newview/skins/default/xui/en/panel_preferences_sound.xml index d909a56733..53ae764ba6 100644 --- a/indra/newview/skins/default/xui/en/panel_preferences_sound.xml +++ b/indra/newview/skins/default/xui/en/panel_preferences_sound.xml @@ -340,7 +340,7 @@ follows="left|top" top_delta="-6" layout="topleft" - left_pad="10" + left_pad="5" width="360" height="40" name="media_ear_location"> @@ -360,7 +360,45 @@ name="1" top_delta ="18" width="200" /> - </radio_group> + </radio_group> + <text + type="string" + length="1" + follows="left|top" + layout="topleft" + left="270" + top_delta="6" + name="Listen from" + width="112"> + Hear voice from: + </text> + <radio_group + enabled_control="EnableVoiceChat" + control_name="VoiceEarLocation" + follows="left|top" + layout="topleft" + left_pad="2" + top_delta="-6" + width="360" + height="40" + name="ear_location"> + <radio_item + height="19" + label="Camera position" + follows="left|top" + layout="topleft" + name="0" + width="200"/> + <radio_item + height="19" + follows="left|top" + label="Avatar position" + layout="topleft" + left_delta="0" + name="1" + top_delta ="18" + width="200" /> + </radio_group> <check_box name="media_show_on_others_btn" control_name="MediaShowOnOthers" @@ -406,14 +444,41 @@ name="autoplay_ask" value="2"/> </combo_box> + <check_box + control_name="StreamNotificationChannelEnabled" + height="30" + label="Custom stream notification channel" + layout="topleft" + left="20" + name="stream_notification_channel_enabled" + top_pad="-10" + width="256"> + </check_box> + <spinner + control_name="StreamNotificationChannel" + enabled_control="StreamNotificationChannelEnabled" + decimal_digits="0" + follows="left|top" + height="30" + increment="1" + initial_value="751751" + label="Channel number:" + label_width="105" + layout="topleft" + left_pad="0" + max_val="2147483647" + min_val="-2147483648" + name="stream_notification_channel" + top_pad="-20" + width="170" /> <text layout="topleft" height="15" left="260" - top_pad="-18" + top_pad="-48" width="100" name="noise_suppression_label"> - Noise Suppression + Noise suppression </text> <combo_box control_name="VoiceNoiseSuppressionLevel" @@ -444,47 +509,12 @@ name="noise_suppression_max" value="4"/> </combo_box> - <text - type="string" - length="1" - follows="left|top" - layout="topleft" - left="23" - top_delta="30" - name="Listen from" - width="112"> - Hear voice from: + <text> +<!-- spacer --> </text> - <radio_group - enabled_control="EnableVoiceChat" - control_name="VoiceEarLocation" - follows="left|top" - layout="topleft" - left_pad="10" - top_delta="-6" - width="360" - height="40" - name="ear_location"> - <radio_item - height="19" - label="Camera position" - follows="left|top" - layout="topleft" - name="0" - width="200"/> - <radio_item - height="19" - follows="left|top" - label="Avatar position" - layout="topleft" - left_delta="0" - name="1" - top_delta ="18" - width="200" /> - </radio_group> <check_box control_name="LipSyncEnabled" - follows="left|top" + follows="top|left" height="15" label="Move avatar lips when speaking" layout="topleft" diff --git a/indra/newview/skins/default/xui/en/panel_progress.xml b/indra/newview/skins/default/xui/en/panel_progress.xml index 242b96b695..6b19907372 100644 --- a/indra/newview/skins/default/xui/en/panel_progress.xml +++ b/indra/newview/skins/default/xui/en/panel_progress.xml @@ -33,7 +33,7 @@ layout="topleft" left="0" orientation="vertical" - name="vertical_centering" + name="vertical_centering1" top="0" width="670"> <layout_panel @@ -44,40 +44,32 @@ width="670" /> <layout_panel auto_resize="false" - height="275" + height="220" layout="topleft" - min_height="275" + min_height="220" name="panel4" width="670"> <icon color="LoginProgressBoxCenterColor" follows="left|right|bottom|top" - height="275" image_name="Rounded_Square" layout="topleft" left="0" top="0" + height="220" width="670" /> <layout_stack follows="left|right|top|bottom" - height="275" + height="220" layout="topleft" left="0" orientation="vertical" - name="vertical_centering" + name="vertical_centering2" animate="false" top="0" width="670"> <layout_panel auto_resize="false" - height="30" - layout="topleft" - min_height="30" - name="panel_top_spacer" - width="670"> - </layout_panel> - <layout_panel - auto_resize="false" height="100" layout="topleft" min_height="100" @@ -121,9 +113,9 @@ </layout_panel> <layout_panel auto_resize="false" - height="110" + height="90" layout="topleft" - min_height="110" + min_height="90" name="panel_motd" width="670"> <text @@ -132,7 +124,7 @@ font_shadow="none" halign="left" valign="center" - height="100" + height="80" layout="topleft" left="45" line_spacing.pixels="2" @@ -142,30 +134,6 @@ right="-90" word_wrap="true"/> </layout_panel> - <layout_panel - auto_resize="false" - height="40" - layout="topleft" - min_height="40" - name="panel_icons" - width="670"> - <!--Logos are tied to following label from code--> - <text - follows="left|right|top" - layout="topleft" - font="SansSerifLarge" - font_shadow="none" - halign="left" - height="16" - width="240" - left="47" - top="6" - line_spacing.pixels="2" - name="logos_lbl" - text_color="LoginProgressBoxTextColor"> - Second Life uses - </text> - </layout_panel> </layout_stack> </layout_panel> <layout_panel diff --git a/indra/newview/skins/default/xui/en/panel_region_environment.xml b/indra/newview/skins/default/xui/en/panel_region_environment.xml index 6d23592948..6531233696 100644 --- a/indra/newview/skins/default/xui/en/panel_region_environment.xml +++ b/indra/newview/skins/default/xui/en/panel_region_environment.xml @@ -264,8 +264,7 @@ top_pad="1" halign="right" name="txt_alt1"> - Sky [INDEX] - [ALTITUDE]m + Sky [INDEX]
[ALTITUDE]m </text> <line_editor follows="left|top" @@ -310,8 +309,7 @@ top_pad="1" halign="right" name="txt_alt2"> - Sky [INDEX] - [ALTITUDE]m + Sky [INDEX]
[ALTITUDE]m </text> <line_editor follows="left|top" @@ -356,8 +354,7 @@ top_pad="1" halign="right" name="txt_alt3"> - Sky [INDEX] - [ALTITUDE]m + Sky [INDEX]
[ALTITUDE]m </text> <line_editor follows="left|top" diff --git a/indra/newview/skins/default/xui/en/panel_status_bar.xml b/indra/newview/skins/default/xui/en/panel_status_bar.xml index 4501e0df3a..5e05eb2837 100644 --- a/indra/newview/skins/default/xui/en/panel_status_bar.xml +++ b/indra/newview/skins/default/xui/en/panel_status_bar.xml @@ -185,4 +185,19 @@ top="2" name="volume_btn" width="16" /> + <button + type="string" + font="SansSerif" + label_color="FpsTextColor" + follows="right|top" + halign="center" + valign="center" + height="18" + top="1" + left_pad="4" + name="FpsText" + tool_tip="fps" + width="32"> + 60 + </button> </panel> diff --git a/indra/newview/skins/default/xui/en/panel_tools_texture.xml b/indra/newview/skins/default/xui/en/panel_tools_texture.xml index e80f315259..9a19d06432 100644 --- a/indra/newview/skins/default/xui/en/panel_tools_texture.xml +++ b/indra/newview/skins/default/xui/en/panel_tools_texture.xml @@ -123,6 +123,14 @@ name="checkbox fullbright" top_pad="4" width="81" /> + <check_box + height="19" + label="Hide water" + layout="topleft" + left="172" + top_delta="0" + name="checkbox_hide_water" + width="81" /> <view_border bevel_style="none" follows="top|left" diff --git a/indra/newview/skins/default/xui/en/sidepanel_appearance.xml b/indra/newview/skins/default/xui/en/sidepanel_appearance.xml index c898b0989e..c03fac4aad 100644 --- a/indra/newview/skins/default/xui/en/sidepanel_appearance.xml +++ b/indra/newview/skins/default/xui/en/sidepanel_appearance.xml @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <panel -background_visible="true" +background_visible="false" default_tab_group="1" follows="all" height="570" @@ -25,8 +25,8 @@ width="333"> name="Changing outfits" value="Changing outfits" /> <panel - background_opaque="true" - background_visible="true" + background_opaque="false" + background_visible="false" bg_opaque_color="DkGray2" left="10" top="5" diff --git a/indra/newview/skins/default/xui/en/sidepanel_task_info.xml b/indra/newview/skins/default/xui/en/sidepanel_task_info.xml index 45bc73a0b7..471886aa0d 100644 --- a/indra/newview/skins/default/xui/en/sidepanel_task_info.xml +++ b/indra/newview/skins/default/xui/en/sidepanel_task_info.xml @@ -93,7 +93,7 @@ name="properties_panel" top="45" width="313" - background_visible="true" + background_visible="false" bg_alpha_color="DkGray2"> <text type="string" @@ -299,7 +299,7 @@ follows="left|top" layout="topleft" mouse_opaque="false" - background_visible="true" + background_visible="false" bg_alpha_color="DkGray" name="perms_inv" left="0" diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml index f0a26f9c56..44da9a8dac 100644 --- a/indra/newview/skins/default/xui/en/strings.xml +++ b/indra/newview/skins/default/xui/en/strings.xml @@ -7,8 +7,8 @@ <!-- Default Args - these arguments will be replaced in all strings --> <string name="SECOND_LIFE">Second Life</string> - <string name="APP_NAME">Second Life</string> - <string name="CAPITALIZED_APP_NAME">SECOND LIFE</string> + <string name="APP_NAME">Megapahit</string> + <string name="CAPITALIZED_APP_NAME">MEGAPAHIT</string> <string name="SECOND_LIFE_GRID">Second Life Grid</string> <string name="SUPPORT_SITE">Second Life Support Portal</string> @@ -71,7 +71,7 @@ Voice Server Version: [VOICE_VERSION] <string name="LocalTime">[month, datetime, local] [day, datetime, local] [year, datetime, local] [hour, datetime, local]:[min, datetime, local]:[second,datetime, local]</string> <string name="ErrorFetchingServerReleaseNotesURL">Error fetching server release notes URL.</string> <string name="BuildConfiguration">Build Configuration</string> - + <!-- progress --> <string name="ProgressRestoring">Restoring...</string> <string name="ProgressChangingResolution">Changing resolution...</string> @@ -114,10 +114,10 @@ Voice Server Version: [VOICE_VERSION] <string name="LoginFailedHeader">Login failed.</string> <string name="Quit">Quit</string> <string name="create_account_url">http://join.secondlife.com/?sourceid=[sourceid]</string> - + <string name="AgniGridLabel">Second Life Main Grid (Agni)</string> <string name="AditiGridLabel">Second Life Beta Test Grid (Aditi)</string> - + <string name="ViewerDownloadURL">http://secondlife.com/download</string> <string name="LoginFailedViewerNotPermitted"> The viewer you are using can no longer access Second Life. Please visit the following page to download a new viewer: @@ -209,7 +209,7 @@ If you feel this is an error, please contact support@secondlife.com</string> <string name="YouHaveBeenDisconnected">You have been disconnected from the region you were in.</string> <string name="SentToInvalidRegion">You were sent to an invalid region.</string> <string name="TestingDisconnect">Testing viewer disconnect</string> - + <!-- SLShare: User Friendly Filter Names Translation --> <string name="BlackAndWhite">Black & White</string> <string name="Colors1970">1970's Colors</string> @@ -222,7 +222,7 @@ If you feel this is an error, please contact support@secondlife.com</string> <string name="LensFlare">Lens Flare</string> <string name="Miniature">Miniature</string> <string name="Toycamera">Toy Camera</string> - + <!-- Tooltip --> <string name="TooltipPerson">Person</string><!-- Object under mouse pointer is an avatar --> <string name="TooltipNoName">(no name)</string> <!-- No name on an object --> @@ -259,10 +259,10 @@ If you feel this is an error, please contact support@secondlife.com</string> <string name="TooltipOutboxMixedStock">All items in a stock folder must have the same type and permission</string> <string name="TooltipOutfitNotInInventory">You can only put items or outfits from your personal inventory into "My outfits"</string> <string name="TooltipCantCreateOutfit">One or more items can't be used inside "My outfits"</string> - + <string name="TooltipDragOntoOwnChild">You can't move a folder into its child</string> <string name="TooltipDragOntoSelf">You can't move a folder into itself</string> - + <!-- tooltips for Urls --> <string name="TooltipHttpUrl">Click to view this web page</string> <string name="TooltipSLURL">Click to view this location's information</string> @@ -333,7 +333,7 @@ are allowed. <string name="ReleaseNotes">Release Notes</string> <!-- Always mark translate="false" for strings that are nothing but URLs, as they don't need translation. --> - <string name="RELEASE_NOTES_BASE_URL" translate="false">https://releasenotes.secondlife.com/viewer/</string> + <string name="RELEASE_NOTES_BASE_URL" translate="false">https://megapahit.net/</string> <!-- Indicates something is being loaded. Maybe should be merged with RetrievingData --> <string name="LoadingData">Loading...</string> @@ -370,7 +370,7 @@ are allowed. <string name="AssetUploadServerDifficulties">The server is experiencing unexpected difficulties.</string> <string name="AssetUploadServerUnavaliable">Service not available or upload timeout was reached.</string> <string name="AssetUploadRequestInvalid"> -Error in upload request. Please visit +Error in upload request. Please visit http://secondlife.com/support for help fixing this problem. </string> @@ -534,7 +534,7 @@ http://secondlife.com/support for help fixing this problem. <string name="ChangeYourDefaultAnimations">Change your default animations</string> <string name="ForceSitAvatar">Force your avatar to sit</string> <string name="ChangeEnvSettings">Change your environment settings</string> - + <string name="NotConnected">Not Connected</string> <string name="AgentNameSubst">(You)</string> <!-- Substitution for agent name --> <string name="JoinAnExperience"/><!-- intentionally blank --> @@ -2320,7 +2320,7 @@ For AI Character: Get the closest navigable point to the point provided. <!-- inventory --> <string name="InventoryNoMatchingItems">Didn't find what you're looking for? Try [secondlife:///app/search/all/[SEARCH_TERM] Search].</string> - <string name="InventoryNoMatchingRecentItems">Didn't find what you're looking for? Try [secondlife:///app/inventory/filters Show filters].</string> + <string name="InventoryNoMatchingRecentItems">Didn't find what you're looking for? Try [secondlife:///app/inventory/filters Show filters].</string> <string name="PlacesNoMatchingItems">To add a place to your landmarks, click the star to the right of the location name.</string> <string name="FavoritesNoMatchingItems">To add a place to your favorites, click the star to the right of the location name, then save the landmark to "Favorites bar".</string> <string name="MarketplaceNoListing">You have no listings yet.</string> @@ -2503,7 +2503,7 @@ If you continue to receive this message, please contact Second Life support for <string name="InvFolder Materials">Materials</string> <!-- are used for Friends and Friends/All folders in Inventory "Calling cards" folder. See EXT-694--> - <string name="InvFolder Friends">Friends</string> + <string name="InvFolder Friends">Friends</string> <string name="InvFolder All">All</string> <string name="no_attachments">No attachments worn</string> @@ -2672,7 +2672,7 @@ If you continue to receive this message, please contact Second Life support for <string name="UploadFailed">File upload failed: </string> <string name="ObjectOutOfRange">Script (object out of range)</string> <string name="ScriptWasDeleted">Script (deleted from inventory)</string> - + <!-- god tools --> <string name="GodToolsObjectOwnedBy">Object [OBJECT] owned by [OWNER]</string> @@ -2942,12 +2942,14 @@ Expected .wav, .tga, .bmp, .jpg, .jpeg, or .anim <string name="Linden Location">Linden Location</string> <string name="Adult">Adult</string> <string name="Arts&Culture">Arts & Culture</string> + <string name="Arts and Culture">Arts & Culture</string> <string name="Business">Business</string> <string name="Educational">Educational</string> <string name="Gaming">Gaming</string> <string name="Hangout">Hangout</string> <string name="Newcomer Friendly">Newcomer Friendly</string> <string name="Parks&Nature">Parks & Nature</string> + <string name="Parks and Nature">Parks & Nature</string> <string name="Residential">Residential</string> <!--<string name="Shopping">Shopping</string> --> <string name="Stage">Stage</string> @@ -3849,7 +3851,7 @@ Please reinstall viewer from https://secondlife.com/support/downloads/ and cont <string name="uploading_costs">Uploading costs L$ [AMOUNT]</string> <string name="this_costs">This costs L$ [AMOUNT]</string> - + <string name="buying_selected_land">This land costs</string> <string name="this_object_costs">This item costs</string> <string name="giving">You want to give</string> @@ -3930,7 +3932,7 @@ Abuse Report</string> <string name="New Daycycle">New Daycycle</string> <string name="New Water">New Water</string> <string name="New Sky">New Sky</string> - + <string name="/bow">/bow</string> <string name="/clap">/clap</string> @@ -4012,7 +4014,7 @@ Please check http://status.secondlifegrid.net to see if there is a known problem <string name="Accounting">Accounting</string> <string name="Notices">Notices</string> <string name="Chat">Chat</string> - + <!-- SL Membership --> <string name="BaseMembership">Base</string> <string name="PremiumMembership">Premium</string> @@ -4178,7 +4180,7 @@ Try enclosing path to the editor with double quotes. <!-- commands --> - <string + <string name="Command_360_Capture_Label">360 snapshot</string> <string name="Command_AboutLand_Label">About land</string> <string name="Command_Appearance_Label">Outfits</string> @@ -4210,8 +4212,10 @@ name="Command_360_Capture_Label">360 snapshot</string> <string name="Command_Speak_Label">Speak</string> <string name="Command_View_Label">Camera controls</string> <string name="Command_Voice_Label">Voice settings</string> + <string name="Command_FavoriteFolder_Label">Favorite folder</string> + <string name="Command_ResyncAnimations_Label">Resync animations</string> - <string + <string name="Command_360_Capture_Tooltip">Capture a 360 equirectangular image</string> <string name="Command_AboutLand_Tooltip">Information about the land you're visiting</string> <string name="Command_Appearance_Tooltip">Change your avatar</string> @@ -4243,6 +4247,8 @@ name="Command_360_Capture_Tooltip">Capture a 360 equirectangular image</string> <string name="Command_Speak_Tooltip">Speak with people nearby using your microphone</string> <string name="Command_View_Tooltip">Changing camera angle</string> <string name="Command_Voice_Tooltip">Volume controls for calls and people near you in world</string> + <string name="Command_FavoriteFolder_Tooltip">Open your favorite inventory folder</string> + <string name="Command_ResyncAnimations_Tooltip">Synchronizes avatar animations</string> <string name="Toolbar_Bottom_Tooltip">currently in your bottom toolbar</string> <string name="Toolbar_Left_Tooltip" >currently in your left toolbar</string> @@ -4276,7 +4282,7 @@ name="Command_360_Capture_Tooltip">Capture a 360 equirectangular image</string> <!-- Spell check settings floater --> <string name="UserDictionary">[User]</string> - + <!-- Experience Tools strings --> <string name="experience_tools_experience">Experience</string> <string name="ExperienceNameNull">(no experience)</string> @@ -4338,7 +4344,7 @@ name="Command_360_Capture_Tooltip">Capture a 360 equirectangular image</string> <string name="Default">Default</string> <string name="none_paren_cap">(None)</string> <string name="no_limit">No limit</string> - + <string name="Mav_Details_MAV_FOUND_DEGENERATE_TRIANGLES"> The physics shape contains triangles which are too small. Try simplifying the physics model. </string> @@ -4378,4 +4384,20 @@ and report the problem. [https://community.secondlife.com/knowledgebase/english/error-messages-r520/#Section__3 Knowledge Base] </string> + <!-- megapahit strings --> + <string name="not_found">'[TEXT]' not found</string> + <string name="no_results">No results</string> + <string name="searching">Searching...</string> + <string name="all_categories">All Categories</string> + <string name="search_banned">Some terms in your search query were excluded due to content restrictions as clarified in the Community Standards.</string> + <string name="search_short">Your search terms were too short so no search was performed.</string> + <string name="search_disabled">Legacy Search has been disabled in this region.</string> + <string name="NotifyIncomingMessage">Incoming message from [NAME]...</string> + <string name="NearbyChatTitleChannel">Nearby chat (on channel [CHANNEL])</string> + <string name="AvatarTyping">Typing</string> + <string name="UnknownAvatar">Unknown Avatar</string> + <string name="NotAvailableOnPlatform">Not available on this platform</string> + <string name="NowPlaying">Now Playing</string> + <string name="GridInfoTitle">GRID INFO</string> + </strings> diff --git a/indra/newview/skins/default/xui/en/widgets/tab_container.xml b/indra/newview/skins/default/xui/en/widgets/tab_container.xml index 22955fe73d..f565161794 100644 --- a/indra/newview/skins/default/xui/en/widgets/tab_container.xml +++ b/indra/newview/skins/default/xui/en/widgets/tab_container.xml @@ -10,7 +10,7 @@ label_pad_left - padding to the left of tab button labels use_custom_icon_ctrl="false" halign="center" font="SansSerifSmall" - tab_height="21" + tab_height="22" label_pad_bottom="1" label_pad_left="4"> <!-- diff --git a/indra/newview/skins/default/xui/en/widgets/toolbar.xml b/indra/newview/skins/default/xui/en/widgets/toolbar.xml index 8345911525..51852dd6dd 100644 --- a/indra/newview/skins/default/xui/en/widgets/toolbar.xml +++ b/indra/newview/skins/default/xui/en/widgets/toolbar.xml @@ -9,9 +9,9 @@ read_only="false"> <button_panel name="button_panel" bg_opaque_image="Rounded_Rect" - background_visible="true" + background_visible="false" bg_opaque_image_overlay="MouseGray" - background_opaque="true"/> + background_opaque="false"/> <button_icon_and_text imgoverlay_label_space="7" label_color_selected="White" halign="left" diff --git a/indra/newview/skins/default/xui/es/floater_avatar_textures.xml b/indra/newview/skins/default/xui/es/floater_avatar_textures.xml index 0a52a70ff1..b043662975 100644 --- a/indra/newview/skins/default/xui/es/floater_avatar_textures.xml +++ b/indra/newview/skins/default/xui/es/floater_avatar_textures.xml @@ -6,7 +6,7 @@ <text name="label">Texturas obtenidas mediante bake</text> <text name="composite_label">Texturas compuestas</text> <button label="Volcar IDs a la consola" label_selected="Volcado" name="Dump"/> - <panel name="scroll_content_panel"> + <panel name="scroll_content_panel2"> <texture_picker label="Pelo" name="hair-baked"/> <texture_picker label="Pelo" name="hair_grain"/> <texture_picker label="Alfa del pelo" name="hair_alpha"/> diff --git a/indra/newview/skins/default/xui/es/language_settings.xml b/indra/newview/skins/default/xui/es/language_settings.xml index 7a52f7cdae..45ddacaf77 100644 --- a/indra/newview/skins/default/xui/es/language_settings.xml +++ b/indra/newview/skins/default/xui/es/language_settings.xml @@ -8,6 +8,7 @@ <string name="macOSLocale">es_ES.UTF-8</string> <string name="DarwinLocale">es_ES.UTF-8</string> <string name="LinuxLocale">es_ES.UTF-8</string> + <string name="FreeBSDLocale">es_ES.UTF-8</string> <!-- datetimeToCodes["wkday"] = "%a"; // Thu diff --git a/indra/newview/skins/default/xui/es/panel_progress.xml b/indra/newview/skins/default/xui/es/panel_progress.xml index 64aaf246f8..c9bed9fd9b 100644 --- a/indra/newview/skins/default/xui/es/panel_progress.xml +++ b/indra/newview/skins/default/xui/es/panel_progress.xml @@ -1,10 +1,8 @@ <?xml version="1.0" ?> <panel name="login_progress_panel"> - <layout_panel name="panel_icons"/> <layout_stack name="vertical_centering"/> <layout_panel name="panel4"/> <layout_panel name="center"/> <layout_stack name="horizontal_centering"> - <text name="logos_lbl">Usos de Second Life</text> </layout_stack> </panel> diff --git a/indra/newview/skins/default/xui/es/strings.xml b/indra/newview/skins/default/xui/es/strings.xml index cd8e7687ae..cf86427477 100644 --- a/indra/newview/skins/default/xui/es/strings.xml +++ b/indra/newview/skins/default/xui/es/strings.xml @@ -1,6 +1,6 @@ <?xml version="1.0" ?> <strings> - <string name="CAPITALIZED_APP_NAME">SECOND LIFE</string> + <string name="CAPITALIZED_APP_NAME">MEGAPAHIT</string> <string name="SUPPORT_SITE">Portal de Soporte de Second Life</string> <string name="StartupDetectingHardware">Identificando el hardware...</string> <string name="StartupLoading">Instalando [APP_NAME]...</string> @@ -29,7 +29,6 @@ Distancia de dibujo: [DRAW_DISTANCE]m Ancho de banda: [NET_BANDWITH]kbit/s Factor LOD: [LOD_FACTOR] Calidad de renderización: [RENDER_QUALITY] -Modelo de iluminación avanzado: [GPU_SHADERS] Memoria de textura: [TEXTURE_MEMORY]MB</string> <string name="AboutOSXHiDPI">Modo de visualización HiDPi: [HIDPI]</string> <string name="AboutLibs">Versión de descodificador J2C: [J2C_VERSION] @@ -265,7 +264,7 @@ pueden adjuntarse a las notas.</string> <string name="NoneFound">No se ha encontrado.</string> <string name="RetrievingData">Reintentando...</string> <string name="ReleaseNotes">Notas de la versión</string> - <string name="RELEASE_NOTES_BASE_URL">https://releasenotes.secondlife.com/viewer/</string> + <string name="RELEASE_NOTES_BASE_URL">https://megapahit.net/</string> <string name="LoadingData">Cargando...</string> <string name="AvatarNameNobody">(nadie)</string> <string name="AvatarNameWaiting">(esperando)</string> diff --git a/indra/newview/skins/default/xui/fr/floater_avatar_textures.xml b/indra/newview/skins/default/xui/fr/floater_avatar_textures.xml index a1f6d85836..e910632e50 100644 --- a/indra/newview/skins/default/xui/fr/floater_avatar_textures.xml +++ b/indra/newview/skins/default/xui/fr/floater_avatar_textures.xml @@ -6,7 +6,7 @@ <text name="label">Textures figées</text> <text name="composite_label">Textures composites</text> <button label="Vider les ID dans la console" label_selected="Vider" name="Dump"/> - <panel name="scroll_content_panel"> + <panel name="scroll_content_panel2"> <texture_picker label="Cheveux" name="hair-baked"/> <texture_picker label="Cheveux" name="hair_grain"/> <texture_picker label="Alpha cheveux" name="hair_alpha"/> diff --git a/indra/newview/skins/default/xui/fr/language_settings.xml b/indra/newview/skins/default/xui/fr/language_settings.xml index fdb119ec69..b84430bf13 100644 --- a/indra/newview/skins/default/xui/fr/language_settings.xml +++ b/indra/newview/skins/default/xui/fr/language_settings.xml @@ -8,6 +8,7 @@ <string name="macOSLocale">fr_FR.UTF-8</string> <string name="DarwinLocale">fr_FR.UTF-8</string> <string name="LinuxLocale">fr_FR.UTF-8</string> + <string name="FreeBSDLocale">fr_FR.UTF-8</string> <!-- datetimeToCodes["wkday"] = "%a"; // Thu diff --git a/indra/newview/skins/default/xui/fr/panel_progress.xml b/indra/newview/skins/default/xui/fr/panel_progress.xml index 673ec63642..c9bed9fd9b 100644 --- a/indra/newview/skins/default/xui/fr/panel_progress.xml +++ b/indra/newview/skins/default/xui/fr/panel_progress.xml @@ -1,10 +1,8 @@ <?xml version="1.0" ?> <panel name="login_progress_panel"> - <layout_panel name="panel_icons"/> <layout_stack name="vertical_centering"/> <layout_panel name="panel4"/> <layout_panel name="center"/> <layout_stack name="horizontal_centering"> - <text name="logos_lbl">Second Life utilise</text> </layout_stack> </panel> diff --git a/indra/newview/skins/default/xui/fr/strings.xml b/indra/newview/skins/default/xui/fr/strings.xml index 0a3fbeb603..3889e26aee 100644 --- a/indra/newview/skins/default/xui/fr/strings.xml +++ b/indra/newview/skins/default/xui/fr/strings.xml @@ -1,8 +1,8 @@ <?xml version="1.0" ?> <strings> <string name="SECOND_LIFE">Second Life</string> - <string name="APP_NAME">Second Life</string> - <string name="CAPITALIZED_APP_NAME">SECOND LIFE</string> + <string name="APP_NAME">Megapahit</string> + <string name="CAPITALIZED_APP_NAME">MEGAPAHIT</string> <string name="SECOND_LIFE_GRID">Grille de Second Life</string> <string name="SUPPORT_SITE">Portail Assistance Second Life</string> <string name="StartupDetectingHardware">Détection du matériel...</string> @@ -32,7 +32,6 @@ Distance de dessin : [DRAW_DISTANCE]m Bande passante : [NET_BANDWITH] kbit/s Facteur LOD (niveau de détail) : [LOD_FACTOR] Qualité de rendu : [RENDER_QUALITY] -Modèle d’éclairage avancé : [GPU_SHADERS] Mémoire textures : [TEXTURE_MEMORY] Mo</string> <string name="AboutOSXHiDPI">Mode d'affichage HiDPI : [HIDPI]</string> <string name="AboutLibs">J2C Decoder Version: [J2C_VERSION] @@ -268,7 +267,7 @@ peuvent être joints aux notes.</string> <string name="NoneFound">Aucun résultat.</string> <string name="RetrievingData">En cours d'extraction...</string> <string name="ReleaseNotes">Notes de version</string> - <string name="RELEASE_NOTES_BASE_URL">https://releasenotes.secondlife.com/viewer/</string> + <string name="RELEASE_NOTES_BASE_URL">https://megapahit.net/</string> <string name="LoadingData">Chargement...</string> <string name="AvatarNameNobody">(personne)</string> <string name="AvatarNameWaiting">(en attente)</string> diff --git a/indra/newview/skins/default/xui/it/floater_avatar_textures.xml b/indra/newview/skins/default/xui/it/floater_avatar_textures.xml index 288b0a2fea..c0e56805f3 100644 --- a/indra/newview/skins/default/xui/it/floater_avatar_textures.xml +++ b/indra/newview/skins/default/xui/it/floater_avatar_textures.xml @@ -8,7 +8,7 @@ texture</text> <text name="composite_label">Composito Texture</text> <button label="Memorizza gli ID sulla console" label_selected="Dump" name="Dump"/> - <panel name="scroll_content_panel"> + <panel name="scroll_content_panel2"> <texture_picker label="Capigliature" name="hair-baked"/> <texture_picker label="Capigliature" name="hair_grain"/> <texture_picker label="Alpha dei capelli" name="hair_alpha"/> diff --git a/indra/newview/skins/default/xui/it/language_settings.xml b/indra/newview/skins/default/xui/it/language_settings.xml index 7eb1b560bd..763e32e5d0 100644 --- a/indra/newview/skins/default/xui/it/language_settings.xml +++ b/indra/newview/skins/default/xui/it/language_settings.xml @@ -8,6 +8,7 @@ <string name="macOSLocale">it_IT.UTF-8</string> <string name="DarwinLocale">it_IT.UTF-8</string> <string name="LinuxLocale">it_IT.UTF-8</string> + <string name="FreeBSDLocale">it_IT.UTF-8</string> <!-- datetimeToCodes["wkday"] = "%a"; // Thu diff --git a/indra/newview/skins/default/xui/it/panel_progress.xml b/indra/newview/skins/default/xui/it/panel_progress.xml index fd2892a88f..c9bed9fd9b 100644 --- a/indra/newview/skins/default/xui/it/panel_progress.xml +++ b/indra/newview/skins/default/xui/it/panel_progress.xml @@ -1,10 +1,8 @@ <?xml version="1.0" ?> <panel name="login_progress_panel"> - <layout_panel name="panel_icons"/> <layout_stack name="vertical_centering"/> <layout_panel name="panel4"/> <layout_panel name="center"/> <layout_stack name="horizontal_centering"> - <text name="logos_lbl">Utilizzi di Second Life</text> </layout_stack> </panel> diff --git a/indra/newview/skins/default/xui/it/strings.xml b/indra/newview/skins/default/xui/it/strings.xml index 178bb90ca6..270e7ac3a1 100644 --- a/indra/newview/skins/default/xui/it/strings.xml +++ b/indra/newview/skins/default/xui/it/strings.xml @@ -1,8 +1,8 @@ <?xml version="1.0" ?> <strings> <string name="SECOND_LIFE">Second Life</string> - <string name="APP_NAME">Second Life</string> - <string name="CAPITALIZED_APP_NAME">SECOND LIFE</string> + <string name="APP_NAME">Megapahit</string> + <string name="CAPITALIZED_APP_NAME">MEGAPAHIT</string> <string name="SUPPORT_SITE">Portale di supporto di Second Life</string> <string name="StartupDetectingHardware">Ricerca hardware...</string> <string name="StartupLoading">Caricamento di [APP_NAME]...</string> @@ -31,7 +31,6 @@ Distanza visualizzazione: [DRAW_DISTANCE]m Larghezza banda: [NET_BANDWITH]kbit/s Fattore livello di dettaglio: [LOD_FACTOR] Qualità di rendering: [RENDER_QUALITY] -Modello illuminazione avanzato: [GPU_SHADERS] Memoria texture: [TEXTURE_MEMORY]MB</string> <string name="AboutOSXHiDPI">Modalità display HiDPI: [HIDPI]</string> <string name="AboutLibs">J2C Versione decoder: [J2C_VERSION] @@ -266,7 +265,7 @@ possono essere allegati ai biglietti.</string> <string name="NoneFound">Nessun risultato.</string> <string name="RetrievingData">Recupero dati in corso...</string> <string name="ReleaseNotes">Note sulla versione</string> - <string name="RELEASE_NOTES_BASE_URL">https://releasenotes.secondlife.com/viewer/</string> + <string name="RELEASE_NOTES_BASE_URL">https://megapahit.net/</string> <string name="LoadingData">In caricamento...</string> <string name="AvatarNameNobody">(nessuno)</string> <string name="AvatarNameWaiting">(in attesa)</string> diff --git a/indra/newview/skins/default/xui/ja/floater_avatar_textures.xml b/indra/newview/skins/default/xui/ja/floater_avatar_textures.xml index e71ed5c599..5de3486ea1 100644 --- a/indra/newview/skins/default/xui/ja/floater_avatar_textures.xml +++ b/indra/newview/skins/default/xui/ja/floater_avatar_textures.xml @@ -13,7 +13,7 @@ 合成テクスチャ </text> <button label="IDをコンソールにダンプ" label_selected="ダンプ" name="Dump"/> - <panel name="scroll_content_panel"> + <panel name="scroll_content_panel2"> <texture_picker label="髪" name="hair-baked"/> <texture_picker label="髪" name="hair_grain"/> <texture_picker label="髪のアルファ" name="hair_alpha"/> diff --git a/indra/newview/skins/default/xui/ja/language_settings.xml b/indra/newview/skins/default/xui/ja/language_settings.xml index c94a16cee0..af45065d58 100644 --- a/indra/newview/skins/default/xui/ja/language_settings.xml +++ b/indra/newview/skins/default/xui/ja/language_settings.xml @@ -15,6 +15,9 @@ <string name="LinuxLocale"> ja_JP.UTF-8 </string> + <string name="FreeBSDLocale"> + ja_JP.UTF-8 + </string> <string name="TimeHour"> hour,datetime,slt </string> diff --git a/indra/newview/skins/default/xui/ja/panel_performance_preferences.xml b/indra/newview/skins/default/xui/ja/panel_performance_preferences.xml index a031cd7176..40e7800adc 100644 --- a/indra/newview/skins/default/xui/ja/panel_performance_preferences.xml +++ b/indra/newview/skins/default/xui/ja/panel_performance_preferences.xml @@ -96,25 +96,4 @@ <text name="photo_desc"> (0.0~4.0の値を入れてください) </text> - <text name="1_lbl"> - 1 - </text> - <text name="2_lbl"> - 2 - </text> - <text name="3_lbl"> - 3 - </text> - <text name="4_lbl"> - 4 - </text> - <text name="5_lbl"> - 5 - </text> - <text name="6_lbl"> - 6 - </text> - <text name="7_lbl"> - 7 - </text> </panel> diff --git a/indra/newview/skins/default/xui/ja/panel_preferences_setup.xml b/indra/newview/skins/default/xui/ja/panel_preferences_setup.xml index f487bc32a9..959f827a61 100644 --- a/indra/newview/skins/default/xui/ja/panel_preferences_setup.xml +++ b/indra/newview/skins/default/xui/ja/panel_preferences_setup.xml @@ -30,7 +30,7 @@ <combo_box.item label="オプションのアップデートのインストール準備ができたら通知する" name="Install_ask"/> <combo_box.item label="必須アップデートのみインストールする" name="Install_manual"/> </combo_box> - <check_box label="release candidate にアップグレードします" name="update_willing_to_test"/> + <check_box label="Beta にアップグレードします" name="update_willing_to_test"/> <check_box label="更新後にリリースノートを表示する" name="update_show_release_notes"/> <text name="Proxy Settings:"> プロキシ設定: diff --git a/indra/newview/skins/default/xui/ja/panel_progress.xml b/indra/newview/skins/default/xui/ja/panel_progress.xml index 7fd7d5ab5c..1edada6098 100644 --- a/indra/newview/skins/default/xui/ja/panel_progress.xml +++ b/indra/newview/skins/default/xui/ja/panel_progress.xml @@ -1,12 +1,8 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <panel name="login_progress_panel"> - <layout_panel name="panel_icons"/> <layout_stack name="vertical_centering"/> <layout_panel name="panel4"/> <layout_panel name="center"/> <layout_stack name="horizontal_centering"> - <text name="logos_lbl"> - セカンドライフ使用 - </text> </layout_stack> </panel> diff --git a/indra/newview/skins/default/xui/ja/strings.xml b/indra/newview/skins/default/xui/ja/strings.xml index fa6c329fe7..106bf91d0c 100644 --- a/indra/newview/skins/default/xui/ja/strings.xml +++ b/indra/newview/skins/default/xui/ja/strings.xml @@ -4,10 +4,10 @@ Second Life </string> <string name="APP_NAME"> - Second Life + Megapahit </string> <string name="CAPITALIZED_APP_NAME"> - SECOND LIFE + MEGAPAHIT </string> <string name="SECOND_LIFE_GRID"> Second Lifeグリッド @@ -66,7 +66,6 @@ SLURL:<nolink>[SLURL]</nolink> 帯域幅:[NET_BANDWITH]kbit/秒 LOD係数:[LOD_FACTOR] 描画の質:[RENDER_QUALITY] -高度な光源モデル:[GPU_SHADERS] テクスチャメモリ:[TEXTURE_MEMORY]㎆ </string> <string name="AboutOSXHiDPI"> @@ -617,7 +616,7 @@ support@secondlife.com にお問い合わせください。 リリースノート </string> <string name="RELEASE_NOTES_BASE_URL" translate="false"> - https://releasenotes.secondlife.com/viewer/ + https://megapahit.net/ </string> <string name="LoadingData"> 読み込んでいます… diff --git a/indra/newview/skins/default/xui/pl/floater_avatar_textures.xml b/indra/newview/skins/default/xui/pl/floater_avatar_textures.xml index 18f5a40ea5..ee5e4d277c 100644 --- a/indra/newview/skins/default/xui/pl/floater_avatar_textures.xml +++ b/indra/newview/skins/default/xui/pl/floater_avatar_textures.xml @@ -14,7 +14,7 @@ prerenderowane kompozytowe </text> <button label="Zrzuć ID do Konsoli" label_selected="Zrzuć" name="Dump" /> - <panel name="scroll_content_panel"> + <panel name="scroll_content_panel2"> <texture_picker label="Włosy" name="hair-baked" /> <texture_picker label="Włosy" name="hair_grain" /> <texture_picker label="Alpha włosów" name="hair_alpha" /> diff --git a/indra/newview/skins/default/xui/pl/language_settings.xml b/indra/newview/skins/default/xui/pl/language_settings.xml index 9993062487..b719edc20f 100644 --- a/indra/newview/skins/default/xui/pl/language_settings.xml +++ b/indra/newview/skins/default/xui/pl/language_settings.xml @@ -5,6 +5,7 @@ <string name="macOSLocale">pl_PL.UTF-8</string> <string name="DarwinLocale">pl_PL.UTF-8</string> <string name="LinuxLocale">pl_PL.UTF-8</string> + <string name="FreeBSDLocale">pl_PL.UTF-8</string> <string name="TimeHour">hour,datetime,slt</string> <string name="TimeMin">min,datetime,slt</string> <string name="TimeSec">second,datetime,slt</string> diff --git a/indra/newview/skins/default/xui/pl/panel_progress.xml b/indra/newview/skins/default/xui/pl/panel_progress.xml index 22b6a8fcf5..8da982cc3f 100644 --- a/indra/newview/skins/default/xui/pl/panel_progress.xml +++ b/indra/newview/skins/default/xui/pl/panel_progress.xml @@ -2,14 +2,9 @@ <panel name="login_progress_panel"> <layout_stack name="horizontal_centering"> <layout_panel name="center"> - <layout_stack name="vertical_centering"> + <layout_stack name="vertical_centering1"> <layout_panel name="panel4"> - <layout_stack name="vertical_centering"> - <layout_panel name="panel_icons"> - <text name="logos_lbl"> - Second Life używa - </text> - </layout_panel> + <layout_stack name="vertical_centering2"> </layout_stack> </layout_panel> </layout_stack> diff --git a/indra/newview/skins/default/xui/pl/strings.xml b/indra/newview/skins/default/xui/pl/strings.xml index 26ec6cc9dc..8032443020 100644 --- a/indra/newview/skins/default/xui/pl/strings.xml +++ b/indra/newview/skins/default/xui/pl/strings.xml @@ -49,7 +49,6 @@ Pole widzenia (Draw Distance): [DRAW_DISTANCE]m Przepustowość (Bandwidth): [NET_BANDWITH]kbit/s Mnożnik poziomu detali (LOD Factor): [LOD_FACTOR] Jakość wyświetlania (Render quality): [RENDER_QUALITY] -Zaawansowane oświetlenie (Advanced Lighting Model): [GPU_SHADERS] Pamięć tekstur (Texture memory): [TEXTURE_MEMORY]MB Pamięć podręczna dysku (Disk cache): [DISK_CACHE_INFO] </string> diff --git a/indra/newview/skins/default/xui/pt/floater_avatar_textures.xml b/indra/newview/skins/default/xui/pt/floater_avatar_textures.xml index 6cdf66cb14..3a0c2febd7 100644 --- a/indra/newview/skins/default/xui/pt/floater_avatar_textures.xml +++ b/indra/newview/skins/default/xui/pt/floater_avatar_textures.xml @@ -8,7 +8,7 @@ Texturas</text> <text name="composite_label">Compósito: Texturas</text> <button label="Enviar IDs para painel" label_selected="Dump" name="Dump"/> - <panel name="scroll_content_panel"> + <panel name="scroll_content_panel2"> <texture_picker label="Cabelo" name="hair-baked"/> <texture_picker label="Cabelo" name="hair_grain"/> <texture_picker label="Cabelo alpha" name="hair_alpha"/> diff --git a/indra/newview/skins/default/xui/pt/language_settings.xml b/indra/newview/skins/default/xui/pt/language_settings.xml index d5be208eb3..721e74aaff 100644 --- a/indra/newview/skins/default/xui/pt/language_settings.xml +++ b/indra/newview/skins/default/xui/pt/language_settings.xml @@ -8,6 +8,7 @@ <string name="macOSLocale">pt_PT.UTF-8</string> <string name="DarwinLocale">pt_PT.UTF-8</string> <string name="LinuxLocale">pt_PT.UTF-8</string> + <string name="FreeBSDLocale">pt_PT.UTF-8</string> <!-- datetimeToCodes["wkday"] = "%a"; // Thu diff --git a/indra/newview/skins/default/xui/pt/panel_progress.xml b/indra/newview/skins/default/xui/pt/panel_progress.xml index 63bb663cfc..c9bed9fd9b 100644 --- a/indra/newview/skins/default/xui/pt/panel_progress.xml +++ b/indra/newview/skins/default/xui/pt/panel_progress.xml @@ -1,10 +1,8 @@ <?xml version="1.0" ?> <panel name="login_progress_panel"> - <layout_panel name="panel_icons"/> <layout_stack name="vertical_centering"/> <layout_panel name="panel4"/> <layout_panel name="center"/> <layout_stack name="horizontal_centering"> - <text name="logos_lbl">Usos do Second Life</text> </layout_stack> </panel> diff --git a/indra/newview/skins/default/xui/pt/strings.xml b/indra/newview/skins/default/xui/pt/strings.xml index 6db5da2e89..3e33744b85 100644 --- a/indra/newview/skins/default/xui/pt/strings.xml +++ b/indra/newview/skins/default/xui/pt/strings.xml @@ -1,6 +1,6 @@ <?xml version="1.0" ?> <strings> - <string name="CAPITALIZED_APP_NAME">SECOND LIFE</string> + <string name="CAPITALIZED_APP_NAME">MEGAPAHIT</string> <string name="SUPPORT_SITE">Portal de Supporte Second Life</string> <string name="StartupDetectingHardware">Detectando hardware...</string> <string name="StartupLoading">Carregando [APP_NAME]...</string> @@ -29,7 +29,6 @@ Estabelecer a distância: [DRAW_DISTANCE]m Largura da banda: [NET_BANDWITH]kbit/s LOD fator: [LOD_FACTOR] Qualidade de renderização: [RENDER_QUALITY] -Modelo avançado de luzes: [GPU_SHADERS] Memória de textura: [TEXTURE_MEMORY]MB</string> <string name="AboutOSXHiDPI">HiDPI modo de exibição: [HIDPI]</string> <string name="AboutLibs">Versão do J2C Decoder: [J2C_VERSION] @@ -230,7 +229,7 @@ ser anexado às anotações.</string> <string name="NoneFound">Não encontrado.</string> <string name="RetrievingData">Buscando...</string> <string name="ReleaseNotes">Notas de versão</string> - <string name="RELEASE_NOTES_BASE_URL">https://releasenotes.secondlife.com/viewer/</string> + <string name="RELEASE_NOTES_BASE_URL">https://megapahit.net/</string> <string name="LoadingData">Carregando...</string> <string name="AvatarNameNobody">(ninguém)</string> <string name="AvatarNameWaiting">(aguardando)</string> diff --git a/indra/newview/skins/default/xui/ru/floater_avatar_textures.xml b/indra/newview/skins/default/xui/ru/floater_avatar_textures.xml index cb39f66247..b8906eebbd 100644 --- a/indra/newview/skins/default/xui/ru/floater_avatar_textures.xml +++ b/indra/newview/skins/default/xui/ru/floater_avatar_textures.xml @@ -14,7 +14,7 @@ Текстуры </text> <button label="Вывод ID на консоль" label_selected="Вывод" name="Dump"/> - <panel name="scroll_content_panel"> + <panel name="scroll_content_panel2"> <texture_picker label="Волосы" name="hair-baked"/> <texture_picker label="Волосы" name="hair_grain"/> <texture_picker label="Альфа волос" name="hair_alpha"/> diff --git a/indra/newview/skins/default/xui/ru/strings.xml b/indra/newview/skins/default/xui/ru/strings.xml index 61d836a2d1..10b0d3578f 100644 --- a/indra/newview/skins/default/xui/ru/strings.xml +++ b/indra/newview/skins/default/xui/ru/strings.xml @@ -8,10 +8,10 @@ Second Life </string> <string name="APP_NAME"> - Second Life + Megapahit </string> <string name="CAPITALIZED_APP_NAME"> - SECOND LIFE + MEGAPAHIT </string> <string name="SECOND_LIFE_GRID"> Сетка Second Life @@ -69,7 +69,6 @@ SLURL: <nolink>[SLURL]</nolink> Ширина канала: [NET_BANDWITH] кбит/с Коэффициент детализации: [LOD_FACTOR] Качество визуализации: [RENDER_QUALITY] -Расширенная модель освещения: [GPU_SHADERS] Память текстур: [TEXTURE_MEMORY] МБ </string> <string name="AboutOSXHiDPI"> diff --git a/indra/newview/skins/default/xui/tr/floater_avatar_textures.xml b/indra/newview/skins/default/xui/tr/floater_avatar_textures.xml index b519cfa1a9..2dabab2bca 100644 --- a/indra/newview/skins/default/xui/tr/floater_avatar_textures.xml +++ b/indra/newview/skins/default/xui/tr/floater_avatar_textures.xml @@ -14,7 +14,7 @@ Dokular Dokular </text> <button label="Kimlikleri Konsole Yığ" label_selected="Yığ" name="Dump"/> - <panel name="scroll_content_panel"> + <panel name="scroll_content_panel2"> <texture_picker label="Saç" name="hair-baked"/> <texture_picker label="Saç" name="hair_grain"/> <texture_picker label="Saç Alfası" name="hair_alpha"/> diff --git a/indra/newview/skins/default/xui/tr/strings.xml b/indra/newview/skins/default/xui/tr/strings.xml index e709a4c5d6..d992788e13 100644 --- a/indra/newview/skins/default/xui/tr/strings.xml +++ b/indra/newview/skins/default/xui/tr/strings.xml @@ -8,10 +8,10 @@ Second Life </string> <string name="APP_NAME"> - Second Life + Megapahit </string> <string name="CAPITALIZED_APP_NAME"> - SECOND LIFE + MEGAPAHIT </string> <string name="SECOND_LIFE_GRID"> Second Life Ağı @@ -69,7 +69,6 @@ UI Ölçeklendirme: [UI_SCALE] Bant genişliği: [NET_BANDWITH]kbit/s LOD faktörü: [LOD_FACTOR] İşleme kalitesi: [RENDER_QUALITY] -Gelişmiş Aydınlatma Modeli: [GPU_SHADERS] Doku belleği: [TEXTURE_MEMORY]MB </string> <string name="AboutOSXHiDPI"> diff --git a/indra/newview/skins/default/xui/zh/floater_avatar_textures.xml b/indra/newview/skins/default/xui/zh/floater_avatar_textures.xml index 69309c96de..260216fb15 100644 --- a/indra/newview/skins/default/xui/zh/floater_avatar_textures.xml +++ b/indra/newview/skins/default/xui/zh/floater_avatar_textures.xml @@ -14,7 +14,7 @@ 材質 </text> <button label="傾印 ID 到控制臺" label_selected="傾印" name="Dump"/> - <panel name="scroll_content_panel"> + <panel name="scroll_content_panel2"> <texture_picker label="頭髮" name="hair-baked"/> <texture_picker label="頭髮" name="hair_grain"/> <texture_picker label="頭髮半透明" name="hair_alpha"/> diff --git a/indra/newview/skins/default/xui/zh/strings.xml b/indra/newview/skins/default/xui/zh/strings.xml index bdb16c9bf1..d053d2b30d 100644 --- a/indra/newview/skins/default/xui/zh/strings.xml +++ b/indra/newview/skins/default/xui/zh/strings.xml @@ -69,7 +69,6 @@ 頻寬:[NET_BANDWITH]千位元/秒 細節層次率:[LOD_FACTOR] 呈像品質:[RENDER_QUALITY] -進階照明模型:[GPU_SHADERS] 材質記憶體:[TEXTURE_MEMORY]MB </string> <string name="AboutOSXHiDPI"> diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py index f9aaeabbfb..e9112694d9 100755 --- a/indra/newview/viewer_manifest.py +++ b/indra/newview/viewer_manifest.py @@ -65,6 +65,8 @@ class ViewerManifest(LLManifest): self.path(src="../../scripts/messages/message_template.msg", dst="app_settings/message_template.msg") self.path(src="../../etc/message.xml", dst="app_settings/message.xml") + os.environ["XZ_DEFAULTS"] = "-T0" + if self.is_packaging_viewer(): with self.prefix(src_dst="app_settings"): self.exclude("logcontrol.xml") @@ -1027,6 +1029,387 @@ class Darwin_x86_64_Manifest(ViewerManifest): ): dylibs += path_optional(os.path.join(relpkgdir, libfile), libfile) + oldpath = os.path.join("@rpath", libfile) + self.run_command( + ['install_name_tool', '-change', oldpath, + '@executable_path/../Resources/%s' % libfile, + executable]) + + # our apps + executable_path = {} + embedded_apps = [ (os.path.join("llplugin", "slplugin"), "SLPlugin.app") ] + for app_bld_dir, app in embedded_apps: + self.path2basename(os.path.join(os.pardir, + app_bld_dir, self.args['configuration']), + app) + executable_path[app] = \ + self.dst_path_of(os.path.join(app, "Contents", "MacOS")) + + # our apps dependencies on shared libs + # for each app, for each dylib we collected in dylibs, + # create a symlink to the real copy of the dylib. + with self.prefix(dst=os.path.join(app, "Contents", "Resources")): + for libfile in dylibs: + self.relsymlinkf(os.path.join(libfile_parent, libfile)) + + # Dullahan helper apps go inside SLPlugin.app + with self.prefix(dst=os.path.join( + "SLPlugin.app", "Contents", "Frameworks")): + + frameworkname = 'Chromium Embedded Framework' + + # This code constructs a relative symlink from the + # target framework folder back to the real CEF framework. + # It needs to be relative so that the symlink still works when + # (as is normal) the user moves the app bundle out of the DMG + # and into the /Applications folder. Note we pass catch=False, + # letting the uncaught exception terminate the process, since + # without this symlink, Second Life web media can't possibly work. + + # It might seem simpler just to symlink Frameworks back to + # the parent of Chromimum Embedded Framework.framework. But + # that would create a symlink cycle, which breaks our + # packaging step. So make a symlink from Chromium Embedded + # Framework.framework to the directory of the same name, which + # is NOT an ancestor of the symlink. + + # from SLPlugin.app/Contents/Frameworks/Chromium Embedded + # Framework.framework back to + # $viewer_app/Contents/Frameworks/Chromium Embedded Framework.framework + SLPlugin_framework = self.relsymlinkf(CEF_framework, catch=False) + + # for all the multiple CEF/Dullahan (as of CEF 76) helper app bundles we need: + for helper in ( + "DullahanHelper", + "DullahanHelper (GPU)", + "DullahanHelper (Renderer)", + "DullahanHelper (Plugin)", + ): + # app is the directory name of the app bundle, with app/Contents/MacOS/helper as the executable + app = helper + ".app" + + # copy DullahanHelper.app + self.path2basename(relpkgdir, app) + + # and fix that up with a Frameworks/CEF symlink too + with self.prefix(dst=os.path.join( + app, 'Contents', 'Frameworks')): + # from Dullahan Helper *.app/Contents/Frameworks/Chromium Embedded + # Framework.framework back to + # SLPlugin.app/Contents/Frameworks/Chromium Embedded Framework.framework + # Since SLPlugin_framework is itself a + # symlink, don't let relsymlinkf() resolve -- + # explicitly call relpath(symlink=True) and + # create that symlink here. + helper_framework = \ + self.symlinkf(self.relpath(SLPlugin_framework, symlink=True), catch=False) + + # change_command includes install_name_tool, the + # -change subcommand and the old framework rpath + # stamped into the executable. To use it with + # run_command(), we must still append the new + # framework path and the pathname of the + # executable to change. + change_command = [ + 'install_name_tool', '-change', + '@rpath/Frameworks/Chromium Embedded Framework.framework/Chromium Embedded Framework'] + + with self.prefix(dst=os.path.join( + app, 'Contents', 'MacOS')): + # Now self.get_dst_prefix() is, at runtime, + # @executable_path. Locate the helper app + # framework (which is a symlink) from here. + newpath = os.path.join( + '@executable_path', + self.relpath(helper_framework, symlink=True), + frameworkname) + # and restamp the Dullahan Helper executable itself + self.run_command( + change_command + + [newpath, self.dst_path_of(helper)]) + + # SLPlugin plugins + with self.prefix(dst="llplugin"): + dylibexecutable = 'media_plugin_cef.dylib' + self.path2basename("../media_plugins/cef/" + self.args['configuration'], + dylibexecutable) + + # Do this install_name_tool *after* media plugin is copied over. + # Locate the framework lib executable -- relative to + # SLPlugin.app/Contents/MacOS, which will be our + # @executable_path at runtime! + newpath = os.path.join( + '@executable_path', + self.relpath(SLPlugin_framework, executable_path["SLPlugin.app"], + symlink=True), + frameworkname) + # restamp media_plugin_cef.dylib + self.run_command( + change_command + + [newpath, self.dst_path_of(dylibexecutable)]) + + # copy LibVLC plugin itself + dylibexecutable = 'media_plugin_libvlc.dylib' + self.path2basename("../media_plugins/libvlc/" + self.args['configuration'], dylibexecutable) + # add @rpath for the correct LibVLC subfolder + self.run_command(['install_name_tool', '-add_rpath', '@loader_path/lib', self.dst_path_of(dylibexecutable)]) + + # copy LibVLC dynamic libraries + with self.prefix(src=relpkgdir, dst="lib"): + self.path( "libvlc*.dylib*" ) + # copy LibVLC plugins folder + with self.prefix(src='plugins', dst=""): + self.path( "*.dylib" ) + self.path( "plugins.dat" ) + + def package_finish(self): + imagename = self.installer_base_name() + self.set_github_output('imagename', imagename) + finalname = imagename + ".dmg" + self.package_file = finalname + + RUNNER_TEMP = os.getenv('RUNNER_TEMP') + # When running as a GitHub Action job, RUNNER_TEMP is the recommended + # temp directory. If we're not running on GitHub, don't create this + # temp directory or this tarball: we don't clean them up, trusting + # that the runner is itself transient. On a dev machine, that would + # result in temp-directory clutter. + if RUNNER_TEMP: + # Per GitHub's actions/upload-artifact documentation + # https://github.com/actions/upload-artifact#maintaining-file-permissions-and-case-sensitive-files + # we must package the app bundle with tar before posting as an + # artifact. Posting individual files follows symlinks, which + # causes problems, especially with frameworks: a framework's top + # level must contain symlinks into its Versions/Current, which + # must itself be a symlink to some specific Versions subdir. + tarpath = os.path.join(RUNNER_TEMP, "viewer.tar.xz") + print(f'Creating {tarpath} from {self.get_dst_prefix()}') + with tarfile.open(tarpath, mode="w:xz") as tarball: + # Store in the tarball as just 'Second Life Mumble.app' + # instead of 'Users/someone/.../newview/Release/Second...' + # It's at this point that we rename 'Second Life Release.app' + # to 'Second Life Viewer.app'. + tarball.add(self.get_dst_prefix(), + arcname=self.app_name() + ".app") + self.set_github_output_path('viewer_app', tarpath) + + +class Darwin_arm64_Manifest(ViewerManifest): + build_data_json_platform = 'mac' + address_size = 64 + + def finish_build_data_dict(self, build_data_dict): + build_data_dict.update({'Bundle Id':self.args['bundleid']}) + return build_data_dict + + def is_packaging_viewer(self): + # darwin requires full app bundle packaging even for debugging. + return True + + def is_rearranging(self): + # That said, some stuff should still only be performed once. + # Are either of these actions in 'actions'? Is the set intersection + # non-empty? + return bool(set(["package", "unpacked"]).intersection(self.args['actions'])) + + def construct(self): + # copy over the build result (this is a no-op if run within the xcode + # script) + self.path(os.path.join(self.args['configuration'], self.channel() + ".app"), dst="") + + pkgdir = os.path.join(self.args['build'], os.pardir, 'packages') + relpkgdir = os.path.join(pkgdir, "lib", "release") + debpkgdir = os.path.join(pkgdir, "lib", "debug") + + with self.prefix(src="", dst="Contents"): # everything goes in Contents + bugsplat_db = self.args.get('bugsplat') + if bugsplat_db: + # Inject BugsplatServerURL into Info.plist if provided. + Info_plist = self.dst_path_of("Info.plist") + with open(Info_plist, 'rb') as f: + Info = plistlib.load(f) + # https://www.bugsplat.com/docs/platforms/os-x#configuration + Info["BugsplatServerURL"] = \ + "https://{}.bugsplat.com/".format(bugsplat_db) + self.put_in_file( + plistlib.dumps(Info), + os.path.basename(Info_plist), + "Info.plist") + + # CEF framework goes inside Contents/Frameworks. + # Remember where we parked this car. + with self.prefix(src="", dst="Frameworks"): + CEF_framework = "Chromium Embedded Framework.framework" + self.path2basename(relpkgdir, CEF_framework) + CEF_framework = self.dst_path_of(CEF_framework) + + if self.args.get('bugsplat'): + self.path2basename(relpkgdir, "BugsplatMac.framework") + + with self.prefix(dst="MacOS"): + executable = self.dst_path_of(self.channel()) + if self.args.get('bugsplat'): + # According to Apple Technical Note TN2206: + # https://developer.apple.com/library/archive/technotes/tn2206/_index.html#//apple_ref/doc/uid/DTS40007919-CH1-TNTAG207 + # "If an app uses @rpath or an absolute path to link to a + # dynamic library outside of the app, the app will be + # rejected by Gatekeeper. ... Neither the codesign nor the + # spctl tool will show the error." + # (Thanks, Apple. Maybe fix spctl to warn?) + # The BugsplatMac framework embeds @rpath, which is + # causing scary Gatekeeper popups at viewer start. Work + # around this by changing the reference baked into our + # viewer. The install_name_tool -change option needs the + # previous value. Instead of guessing -- which might + # silently be defeated by a BugSplat SDK update that + # changes their baked-in @rpath -- ask for the path + # stamped into the framework. + # Let exception, if any, propagate -- if this doesn't + # work, we need the build to noisily fail! + oldpath = subprocess.check_output( + ['objdump', '--macho', '--dylib-id', '--non-verbose', + os.path.join(relpkgdir, "BugsplatMac.framework", "BugsplatMac")], + text=True + ).splitlines()[-1] # take the last line of output + self.run_command( + ['install_name_tool', '-change', oldpath, + '@executable_path/../Frameworks/BugsplatMac.framework/BugsplatMac', + executable]) + + # NOTE: the -S argument to strip causes it to keep + # enough info for annotated backtraces (i.e. function + # names in the crash log). 'strip' with no arguments + # yields a slightly smaller binary but makes crash + # logs mostly useless. This may be desirable for the + # final release. Or not. + if ("package" in self.args['actions'] or + "unpacked" in self.args['actions']): + self.run_command( + ['strip', '-S', executable]) + + with self.prefix(dst="Resources"): + # defer cross-platform file copies until we're in the + # nested Resources directory + super().construct() + + # need .icns file referenced by Info.plist + with self.prefix(src=self.icon_path(), dst="") : + self.path("secondlife.icns") + + # Copy in the updater script and helper modules + self.path(src=os.path.join(pkgdir, 'VMP'), dst="updater") + + with self.prefix(src="", dst=os.path.join("updater", "icons")): + self.path2basename(self.icon_path(), "secondlife.ico") + with self.prefix(src="vmp_icons", dst=""): + self.path("*.png") + self.path("*.gif") + + with self.prefix(src=relpkgdir, dst=""): + self.path("libndofdev.dylib") + self.path("libhunspell-*.dylib") + + with self.prefix(src_dst="cursors_mac"): + self.path("*.tif") + + self.path("licenses-mac.txt", dst="licenses.txt") + self.path("featuretable_mac.txt") + self.path("cube.dae") + self.path("SecondLife.nib") + + with self.prefix(src=pkgdir,dst=""): + self.path("ca-bundle.crt") + + # Translations + self.path("English.lproj/language.txt") + self.replace_in(src="English.lproj/InfoPlist.strings", + dst="English.lproj/InfoPlist.strings", + searchdict={'%%VERSION%%':'.'.join(self.args['version'])} + ) + self.path("German.lproj") + self.path("Japanese.lproj") + self.path("Korean.lproj") + self.path("da.lproj") + self.path("es.lproj") + self.path("fr.lproj") + self.path("hu.lproj") + self.path("it.lproj") + self.path("nl.lproj") + self.path("pl.lproj") + self.path("pt.lproj") + self.path("ru.lproj") + self.path("tr.lproj") + self.path("uk.lproj") + self.path("zh-Hans.lproj") + + def path_optional(src, dst): + """ + For a number of our self.path() calls, not only do we want + to deal with the absence of src, we also want to remember + which were present. Return either an empty list (absent) + or a list containing dst (present). Concatenate these + return values to get a list of all libs that are present. + """ + # This was simple before we started needing to pass + # wildcards. Fortunately, self.path() ends up appending a + # (source, dest) pair to self.file_list for every expanded + # file processed. Remember its size before the call. + oldlen = len(self.file_list) + try: + self.path(src, dst) + # The dest appended to self.file_list has been prepended + # with self.get_dst_prefix(). Strip it off again. + added = [os.path.relpath(d, self.get_dst_prefix()) + for s, d in self.file_list[oldlen:]] + except MissingError as err: + print("Warning: "+err.msg, file=sys.stderr) + added = [] + if not added: + print("Skipping %s" % dst) + return added + + # dylibs is a list of all the .dylib files we expect to need + # in our bundled sub-apps. For each of these we'll create a + # symlink from sub-app/Contents/Resources to the real .dylib. + # Need to get the llcommon dll from any of the build directories as well. + libfile_parent = self.get_dst_prefix() + dylibs=[] + for libfile in ( + "libapr-1.0.dylib", + "libaprutil-1.0.dylib", + "libexpat.1.dylib", + # libnghttp2.dylib is a symlink to + # libnghttp2.major.dylib, which is a symlink to + # libnghttp2.version.dylib. Get all of them. + "libnghttp2.*dylib", + "liburiparser.*dylib", + ): + dylibs += path_optional(os.path.join(relpkgdir, libfile), libfile) + + # SLVoice executable + with self.prefix(src=os.path.join(pkgdir, 'bin', 'release')): + self.path("SLVoice") + + # Vivox libraries + for libfile in ( + 'libortp.dylib', + 'libvivoxsdk.dylib', + ): + self.path2basename(relpkgdir, libfile) + + # Fmod studio dylibs (vary based on configuration) + if self.args['fmodstudio'] == 'ON': + if self.args['buildtype'].lower() == 'debug': + for libfile in ( + "libfmodL.dylib", + ): + dylibs += path_optional(os.path.join(debpkgdir, libfile), libfile) + else: + for libfile in ( + "libfmod.dylib", + ): + dylibs += path_optional(os.path.join(relpkgdir, libfile), libfile) + # our apps executable_path = {} embedded_apps = [ (os.path.join("llplugin", "slplugin"), "SLPlugin.app") ] @@ -1193,6 +1576,9 @@ class LinuxManifest(ViewerManifest): super(LinuxManifest, self).construct() pkgdir = os.path.join(self.args['build'], os.pardir, 'packages') + if "package_dir" in self.args: + pkgdir = self.args['package_dir'] + relpkgdir = os.path.join(pkgdir, "lib", "release") debpkgdir = os.path.join(pkgdir, "lib", "debug") @@ -1211,49 +1597,123 @@ class LinuxManifest(ViewerManifest): with self.prefix(dst="bin"): self.path("secondlife-bin","do-not-directly-run-secondlife-bin") - self.path("../linux_crash_logger/linux-crash-logger","linux-crash-logger.bin") + #self.path("../linux_crash_logger/linux-crash-logger","linux-crash-logger.bin") self.path2basename("../llplugin/slplugin", "SLPlugin") #this copies over the python wrapper script, associated utilities and required libraries, see SL-321, SL-322 and SL-323 - with self.prefix(src="../viewer_components/manager", dst=""): - self.path("*.py") + #with self.prefix(src="../viewer_components/manager", dst=""): + # self.path("*.py") # recurses, packaged again self.path("res-sdl") + # We copy ll_icon.BMP in CMakeLists.txt to newview/res-sdl and this will let the above self.path step take care of copying + # the correct branded icon # Get the icons based on the channel type icon_path = self.icon_path() - print("DEBUG: icon_path '%s'" % icon_path) + #print("DEBUG: icon_path '%s'" % icon_path) with self.prefix(src=icon_path) : self.path("secondlife_256.png","secondlife_icon.png") with self.prefix(dst="res-sdl") : self.path("secondlife_256.BMP","ll_icon.BMP") # plugins - with self.prefix(src="../media_plugins", dst="bin/llplugin"): - self.path("gstreamer010/libmedia_plugin_gstreamer010.so", - "libmedia_plugin_gstreamer.so") - self.path2basename("libvlc", "libmedia_plugin_libvlc.so") - - with self.prefix(src=os.path.join(pkgdir, 'lib', 'vlc', 'plugins'), dst="bin/llplugin/vlc/plugins"): - self.path( "plugins.dat" ) - self.path( "*/*.so" ) - - with self.prefix(src=os.path.join(pkgdir, 'lib' ), dst="lib"): - self.path( "libvlc*.so*" ) - - # llcommon - if not self.path("../llcommon/libllcommon.so", "lib/libllcommon.so"): - print("Skipping llcommon.so (assuming llcommon was linked statically)") + with self.prefix(src=os.path.join(self.args['build'], os.pardir, 'media_plugins'), dst="bin/llplugin"): + self.path("gstreamer10/libmedia_plugin_gstreamer10.so", "libmedia_plugin_gstreamer.so") + + + with self.prefix(src=os.path.join(self.args['build'], os.pardir, 'media_plugins'), dst="bin/llplugin"): + self.path("cef/libmedia_plugin_cef.so", "libmedia_plugin_cef.so" ) + with self.prefix(src=os.path.join(pkgdir, 'lib', 'release'), dst="lib"): + self.path( "libcef.so" ) + + self.path( "libEGL*" ) + self.path( "libvulkan*" ) + self.path( "libvk_swiftshader*" ) + self.path( "libGLESv2*" ) + self.path( "vk_swiftshader_icd.json") + + with self.prefix(src=os.path.join(pkgdir, 'bin', 'release'), dst="bin"): + self.path( "chrome-sandbox" ) + self.path( "dullahan_host" ) + self.path( "snapshot_blob.bin" ) + self.path( "v8_context_snapshot.bin" ) + with self.prefix(src=os.path.join(pkgdir, 'bin', 'release'), dst="lib"): + self.path( "snapshot_blob.bin" ) + self.path( "v8_context_snapshot.bin" ) + + with self.prefix(src=os.path.join(pkgdir, 'resources'), dst="lib"): + self.path( "chrome_100_percent.pak" ) + self.path( "chrome_200_percent.pak" ) + self.path( "resources.pak" ) + self.path( "icudtl.dat" ) + + with self.prefix(src=os.path.join(pkgdir, 'resources', 'locales'), dst=os.path.join('lib', 'locales')): + self.path("am.pak") + self.path("ar.pak") + self.path("bg.pak") + self.path("bn.pak") + self.path("ca.pak") + self.path("cs.pak") + self.path("da.pak") + self.path("de.pak") + self.path("el.pak") + self.path("en-GB.pak") + self.path("en-US.pak") + self.path("es-419.pak") + self.path("es.pak") + self.path("et.pak") + self.path("fa.pak") + self.path("fi.pak") + self.path("fil.pak") + self.path("fr.pak") + self.path("gu.pak") + self.path("he.pak") + self.path("hi.pak") + self.path("hr.pak") + self.path("hu.pak") + self.path("id.pak") + self.path("it.pak") + self.path("ja.pak") + self.path("kn.pak") + self.path("ko.pak") + self.path("lt.pak") + self.path("lv.pak") + self.path("ml.pak") + self.path("mr.pak") + self.path("ms.pak") + self.path("nb.pak") + self.path("nl.pak") + self.path("pl.pak") + self.path("pt-BR.pak") + self.path("pt-PT.pak") + self.path("ro.pak") + self.path("ru.pak") + self.path("sk.pak") + self.path("sl.pak") + self.path("sr.pak") + self.path("sv.pak") + self.path("sw.pak") + self.path("ta.pak") + self.path("te.pak") + self.path("th.pak") + self.path("tr.pak") + self.path("uk.pak") + self.path("vi.pak") + self.path("zh-CN.pak") + self.path("zh-TW.pak") self.path("featuretable_linux.txt") self.path("cube.dae") - with self.prefix(src=pkgdir): + with self.prefix(src=pkgdir, dst="bin"): self.path("ca-bundle.crt") def package_finish(self): installer_name = self.installer_base_name() + # When running as a GitHub Action job, RUNNER_TEMP is defined as the tmp dir + RUNNER_TEMP = os.getenv('RUNNER_TEMP') + self.strip_binaries() # Fix access permissions @@ -1268,39 +1728,64 @@ class LinuxManifest(ViewerManifest): # temporarily move directory tree so that it has the right # name in the tarfile realname = self.get_dst_prefix() - tempname = self.build_path_of(installer_name) - self.run_command(["mv", realname, tempname]) + versionedName = self.build_path_of(installer_name) + + tarName = versionedName + ".tar.xz" + + # If using a github runner we divert packaging a little. Considering this wil be a VM/docker image + # we can just pack the final installer into RUNNER_TEMP and not into the usual stop we'd pick when + # not building a GHA release + if RUNNER_TEMP: + tarName = os.path.join(RUNNER_TEMP, self.package_file) + + self.run_command(["mv", realname, versionedName]) + try: # only create tarball if it's a release build. if self.args['buildtype'].lower() == 'release': - # --numeric-owner hides the username of the builder for - # security etc. self.run_command(['tar', '-C', self.get_build_prefix(), '--numeric-owner', '-cJf', - tempname + '.tar.xz', installer_name]) + tarName, installer_name]) + self.set_github_output_path('viewer_app', tarName) else: print("Skipping %s.tar.xz for non-Release build (%s)" % \ (installer_name, self.args['buildtype'])) finally: - self.run_command(["mv", tempname, realname]) + self.run_command(["mv", versionedName, realname]) def strip_binaries(self): + doStrip = False if self.args['buildtype'].lower() == 'release' and self.is_packaging_viewer(): - print("* Going strip-crazy on the packaged binaries, since this is a RELEASE build") + doStrip = True + # In case of flatpak flatpak-build will call strip, disable doStrip here to get a flatpak symbol package. Increases flatpak size by about 1G + if "FLATPAK_DEST" in os.environ: + doStrip = True + + if doStrip: + print("* Going strip-crazy on the packaged binaries, since this is a Release build") # makes some small assumptions about our packaged dir structure self.run_command( ["find"] + [os.path.join(self.get_dst_prefix(), dir) for dir in ('bin', 'lib')] + ['-type', 'f', '!', '-name', '*.py', + '!', '-name', '*.pak', + '!', '-name', '*.bin', + '!', '-name', '*.dat', + '!', '-name', '*.crt', + '!', '-name', '*.dll', + '!', '-name', '*.lib', '!', '-name', 'update_install', '-exec', 'strip', '-S', '{}', ';']) -class Linux_i686_Manifest(LinuxManifest): - address_size = 32 +class Linux_x86_64_Manifest(LinuxManifest): + address_size = 64 def construct(self): - super(Linux_i686_Manifest, self).construct() + super(Linux_x86_64_Manifest, self).construct() pkgdir = os.path.join(self.args['build'], os.pardir, 'packages') + if "package_dir" in self.args: + pkgdir = self.args['package_dir'] + relpkgdir = os.path.join(pkgdir, "lib", "release") debpkgdir = os.path.join(pkgdir, "lib", "debug") @@ -1357,17 +1842,6 @@ class Linux_i686_Manifest(LinuxManifest): self.path("libvivoxsdk.so") self.strip_binaries() - - -class Linux_x86_64_Manifest(LinuxManifest): - address_size = 64 - - def construct(self): - super(Linux_x86_64_Manifest, self).construct() - - # support file for valgrind debug tool - self.path("secondlife-i686.supp") - ################################################################ if __name__ == "__main__": diff --git a/indra/test/lltut.h b/indra/test/lltut.h index e56b4e8d1c..581a08654d 100644 --- a/indra/test/lltut.h +++ b/indra/test/lltut.h @@ -135,7 +135,7 @@ namespace tut inline void ensure_memory_matches(const void* actual, U32 actual_len, const void* expected,U32 expected_len) { - ensure_memory_matches(NULL, actual, actual_len, expected, expected_len); + ensure_memory_matches("", actual, actual_len, expected, expected_len); } template <class T,class Q> diff --git a/indra/test/test.cpp b/indra/test/test.cpp index 172b6e3542..6e280819df 100644 --- a/indra/test/test.cpp +++ b/indra/test/test.cpp @@ -36,6 +36,7 @@ #include "linden_common.h" #include "llerrorcontrol.h" +#include "llexception.h" #include "lltut.h" #include "chained_callback.h" #include "stringize.h" @@ -164,10 +165,6 @@ public: LLTestCallback(bool verbose_mode, std::ostream *stream, std::shared_ptr<LLReplayLog> replayer) : mVerboseMode(verbose_mode), - mTotalTests(0), - mPassedTests(0), - mFailedTests(0), - mSkippedTests(0), // By default, capture a shared_ptr to std::cout, with a no-op "deleter" // so that destroying the shared_ptr makes no attempt to delete std::cout. mStream(std::shared_ptr<std::ostream>(&std::cout, [](std::ostream*){})), @@ -203,6 +200,8 @@ public: virtual void group_started(const std::string& name) { LL_INFOS("TestRunner")<<"Unit test group_started name=" << name << LL_ENDL; *mStream << "Unit test group_started name=" << name << std::endl; + mGroup = name; + mGroupTests = 0; super::group_started(name); } @@ -215,6 +214,7 @@ public: virtual void test_completed(const tut::test_result& tr) { ++mTotalTests; + ++mGroupTests; // If this test failed, dump requested log messages BEFORE stating the // test result. @@ -302,12 +302,15 @@ public: super::run_completed(); } + std::string mGroup; + int mGroupTests{ 0 }; + protected: - bool mVerboseMode; - int mTotalTests; - int mPassedTests; - int mFailedTests; - int mSkippedTests; + bool mVerboseMode{ false }; + int mTotalTests{ 0 }; + int mPassedTests{ 0 }; + int mFailedTests{ 0 }; + int mSkippedTests{ 0 }; std::shared_ptr<std::ostream> mStream; std::shared_ptr<LLReplayLog> mReplayer; }; @@ -635,14 +638,47 @@ int main(int argc, char **argv) // a chained_callback subclass must be linked with previous mycallback->link(); - if(test_group.empty()) - { - tut::runner.get().run_tests(); - } - else - { - tut::runner.get().run_tests(test_group); - } + LL::seh::catcher( + // __try + [test_group] + { + if(test_group.empty()) + { + tut::runner.get().run_tests(); + } + else + { + tut::runner.get().run_tests(test_group); + } + }, + // __except + [mycallback](U32 code, const std::string& /*stacktrace*/) + { + static std::map<U32, const char*> codes = { + { 0xC0000005, "Access Violation" }, + { 0xC00000FD, "Stack Overflow" }, + // ... continue filling in as desired + }; + + auto found{ codes.find(code) }; + const char* name = ((found == codes.end())? "unknown" : found->second); + auto msg{ stringize("test threw ", std::hex, code, " (", name, ")") }; + + // Instead of bombing the whole test run, report this as a test + // failure. Arguably, catching structured exceptions should be + // hacked into TUT itself. + mycallback->test_completed(tut::test_result( + mycallback->mGroup, + mycallback->mGroupTests+1, // test within group + "unknown", // test name + tut::test_result::ex, // result: exception + // we don't have to throw this exception subclass to use it to + // populate the test_result struct + Windows_SEH_exception(msg))); + // we've left the TUT framework -- finish up by hand + mycallback->group_completed(mycallback->mGroup); + mycallback->run_completed(); + }); bool success = (mycallback->getFailedTests() == 0); diff --git a/indra/viewer_components/login/CMakeLists.txt b/indra/viewer_components/login/CMakeLists.txt index 8381803b03..d33b6d78f7 100644 --- a/indra/viewer_components/login/CMakeLists.txt +++ b/indra/viewer_components/login/CMakeLists.txt @@ -1,6 +1,6 @@ # -*- cmake -*- -project(login) +project(lllogin) include(00-Common) if(LL_TESTS) @@ -9,21 +9,21 @@ endif(LL_TESTS) include(LLCommon) include(LLCoreHttp) -set(login_SOURCE_FILES +set(lllogin_SOURCE_FILES lllogin.cpp ) -set(login_HEADER_FILES +set(lllogin_HEADER_FILES lllogin.h ) list(APPEND - login_SOURCE_FILES - ${login_HEADER_FILES} + lllogin_SOURCE_FILES + ${lllogin_HEADER_FILES} ) add_library(lllogin - ${login_SOURCE_FILES} + ${lllogin_SOURCE_FILES} ) target_include_directories( lllogin INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}) @@ -35,6 +35,8 @@ target_link_libraries(lllogin llxml ) +include(LibraryInstall) + if(LL_TESTS) SET(lllogin_TEST_SOURCE_FILES lllogin.cpp diff --git a/indra/viewer_components/login/lllogin.cpp b/indra/viewer_components/login/lllogin.cpp index feebecf4cb..425df0e0f9 100644 --- a/indra/viewer_components/login/lllogin.cpp +++ b/indra/viewer_components/login/lllogin.cpp @@ -128,7 +128,7 @@ void LLLogin::Impl::connect(const std::string& uri, const LLSD& login_params) // Launch a coroutine with our login_() method. Run the coroutine until // its first wait; at that point, return here. std::string coroname = - LLCoros::instance().launch("LLLogin::Impl::login_", [=]() { loginCoro(uri, login_params); }); + LLCoros::instance().launch("LLLogin::Impl::login_", [=, this]() { loginCoro(uri, login_params); }); LL_DEBUGS("LLLogin") << " connected with uri '" << uri << "', login_params " << login_params << LL_ENDL; } diff --git a/patches/collada-dom-v2.3-r8.patch b/patches/collada-dom-v2.3-r8.patch new file mode 100644 index 0000000000..b24ae2746b --- /dev/null +++ b/patches/collada-dom-v2.3-r8.patch @@ -0,0 +1,531 @@ +diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml +index d1833f4..ba137f9 100644 +--- a/.github/workflows/build.yaml ++++ b/.github/workflows/build.yaml +@@ -8,10 +8,10 @@ jobs: + build: + strategy: + matrix: +- os: [windows-2022, macos-12, ubuntu-22.04] ++ os: [windows-2022, macos-15, ubuntu-22.04] + runs-on: ${{ matrix.os }} + steps: +- - uses: secondlife/action-autobuild@v4 ++ - uses: secondlife/action-autobuild@v5 + release: + needs: build + runs-on: [ubuntu-latest] +diff --git a/CMakeLists.txt b/CMakeLists.txt +index b1c1993..91313e7 100644 +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -1,14 +1,25 @@ +-include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include) +-set(COLLADA14_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/include/1.4) +-set(COLLADA15_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/include/1.5) ++cmake_minimum_required(VERSION 3.17) ++project(colladadom) ++ ++include(FindPkgConfig) ++ ++find_package(Boost REQUIRED CONFIG) ++pkg_check_modules(LIBXML2 libxml-2.0) ++pkg_check_modules(MINIZIP minizip) ++pkg_check_modules(ZLIB zlib) ++ ++set(COLLADA_DOM_SOVERSION "0") ++set(COLLADA_DOM_VERSION "2.3") ++ + file(GLOB dae_files ${CMAKE_CURRENT_SOURCE_DIR}/src/dae/*.cpp) + file(GLOB libxmlplugin_files ${CMAKE_CURRENT_SOURCE_DIR}/src/modules/LIBXMLPlugin/*.cpp) + file(GLOB stddatabase_files ${CMAKE_CURRENT_SOURCE_DIR}/src/modules/STLDatabase/*.cpp) + file(GLOB stderrplugin_files ${CMAKE_CURRENT_SOURCE_DIR}/src/modules/stdErrPlugin/*.cpp) + + set(COLLADA_BASE_SOURCES ${dae_files} ${libxmlplugin_files} ${stddatabase_files} ${stderrplugin_files}) +-set(COLLADA_LIBS minizip ${ZLIB_LIBRARIES} ${Boost_FILESYSTEM_LIBRARY} ${Boost_SYSTEM_LIBRARY}) +-set(COLLADA_COMPILE_FLAGS "${EXTRA_COMPILE_FLAGS} ${Boost_CFLAGS} -DDOM_INCLUDE_LIBXML") ++set(COLLADA_LIBS ${LIBXML2_LIBRARIES} ${MINIZIP_LIBRARIES} ${ZLIB_LIBRARIES} ${Boost_FILESYSTEM_LIBRARY} ${Boost_SYSTEM_LIBRARY} ${Boost_REGEX_LIBRARY}) ++list(JOIN MINIZIP_CFLAGS " " VAR_MINIZIP_CFLAGS) ++set(COLLADA_COMPILE_FLAGS "${EXTRA_COMPILE_FLAGS} ${VAR_MINIZIP_CFLAGS} ${Boost_CFLAGS} -DDOM_INCLUDE_LIBXML") + + if( OPT_COLLADA15 ) + add_subdirectory(src/1.5) +@@ -17,8 +28,8 @@ if( OPT_COLLADA14 ) + add_subdirectory(src/1.4) + endif() + +-install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/include/1.4 DESTINATION ${COLLADA_DOM_INCLUDE_INSTALL_DIR} PATTERN ".svn" EXCLUDE PATTERN ".~" EXCLUDE) +-install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/include/1.5 DESTINATION ${COLLADA_DOM_INCLUDE_INSTALL_DIR} PATTERN ".svn" EXCLUDE PATTERN ".~" EXCLUDE) +-install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/include/dae DESTINATION ${COLLADA_DOM_INCLUDE_INSTALL_DIR} PATTERN ".svn" EXCLUDE PATTERN ".~" EXCLUDE) +-install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/include/modules DESTINATION ${COLLADA_DOM_INCLUDE_INSTALL_DIR} PATTERN ".svn" EXCLUDE PATTERN ".~" EXCLUDE) +-install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/include/dae.h ${CMAKE_CURRENT_SOURCE_DIR}/include/dae.h DESTINATION ${COLLADA_DOM_INCLUDE_INSTALL_DIR}) ++# install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/include/1.4 DESTINATION ${COLLADA_DOM_INCLUDE_INSTALL_DIR} PATTERN ".svn" EXCLUDE PATTERN ".~" EXCLUDE) ++# install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/include/1.5 DESTINATION ${COLLADA_DOM_INCLUDE_INSTALL_DIR} PATTERN ".svn" EXCLUDE PATTERN ".~" EXCLUDE) ++# install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/include/dae DESTINATION ${COLLADA_DOM_INCLUDE_INSTALL_DIR} PATTERN ".svn" EXCLUDE PATTERN ".~" EXCLUDE) ++# install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/include/modules DESTINATION ${COLLADA_DOM_INCLUDE_INSTALL_DIR} PATTERN ".svn" EXCLUDE PATTERN ".~" EXCLUDE) ++# install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/include/dae.h ${CMAKE_CURRENT_SOURCE_DIR}/include/dae.h DESTINATION ${COLLADA_DOM_INCLUDE_INSTALL_DIR}) +diff --git a/Makefile b/Makefile +index f317973..441caf1 100755 +--- a/Makefile ++++ b/Makefile +@@ -59,7 +59,7 @@ ifneq ($(shell uname -p | grep -i powerpc),) + nativeArch := ppc + endif + +-# arch: x86 (or i386), x64 (or x86_64), ppc, ppc64 ++# arch: x86 (or i386), x64 (or x86_64), ppc, ppc64, arm64 + arch ?= i386 + + # project: 'dom', 'domTest', or 'all' +@@ -103,7 +103,7 @@ $(error Invalid setting os=$(os)) + endif + + archs := $(sort $(subst i386,x86,$(arch))) +-ifneq ($(filter-out x86 ppc x86_64,$(archs)),) ++ifneq ($(filter-out x86 ppc x86_64 arm64,$(archs)),) + $(error Invalid setting arch=$(arch)) + endif + +diff --git a/autobuild.xml b/autobuild.xml +index 21a28c7..96436a9 100755 +--- a/autobuild.xml ++++ b/autobuild.xml +@@ -21,11 +21,11 @@ + <key>archive</key> + <map> + <key>hash</key> +- <string>6bf5f4afddf87d48c069d781b5ef2d44d6ddf2d5</string> ++ <string>a4553df5b8fde2e9cd54ebb94c6efb8eb5fe3c38</string> + <key>hash_algorithm</key> + <string>sha1</string> + <key>url</key> +- <string>https://github.com/secondlife/3p-boost/releases/download/v1.86.0-e2bee1e/boost-1.86-darwin64-10475904468.tar.zst</string> ++ <string>https://github.com/secondlife/3p-boost/releases/download/v1.86.0-be1a669/boost-1.86-darwin64-13246092114.tar.zst</string> + </map> + <key>name</key> + <string>darwin64</string> +@@ -35,11 +35,11 @@ + <key>archive</key> + <map> + <key>hash</key> +- <string>3c0ba2a87e78d76c81da95fa87579bf4964242e1</string> ++ <string>4a2a19dc5cb555e157ad894ba917f5a83a35b20d</string> + <key>hash_algorithm</key> + <string>sha1</string> + <key>url</key> +- <string>https://github.com/secondlife/3p-boost/releases/download/v1.86.0-e2bee1e/boost-1.86-linux64-10475904468.tar.zst</string> ++ <string>https://github.com/secondlife/3p-boost/releases/download/v1.86.0-be1a669/boost-1.86-linux64-13246092114.tar.zst</string> + </map> + <key>name</key> + <string>linux64</string> +@@ -49,11 +49,11 @@ + <key>archive</key> + <map> + <key>hash</key> +- <string>d1dd5d629b254d1b361c5a0fa210b5f3283e8a20</string> ++ <string>8a1fa9366bfe49009286e4805d7aaedb7c3df82e</string> + <key>hash_algorithm</key> + <string>sha1</string> + <key>url</key> +- <string>https://github.com/secondlife/3p-boost/releases/download/v1.86.0-e2bee1e/boost-1.86-windows64-10475904468.tar.zst</string> ++ <string>https://github.com/secondlife/3p-boost/releases/download/v1.86.0-be1a669/boost-1.86-windows64-13246092114.tar.zst</string> + </map> + <key>name</key> + <string>windows64</string> +@@ -81,11 +81,11 @@ + <key>archive</key> + <map> + <key>hash</key> +- <string>b2bf9adc84841b6fcf48d4c00787b221607cdea3</string> ++ <string>372c92936d940b1cfb5ba34310691d4bb435c161</string> + <key>hash_algorithm</key> + <string>sha1</string> + <key>url</key> +- <string>https://github.com/secondlife/3p-libxml2/releases/download/v2.13.3-r1/libxml2-2.13.3-r1-darwin64-10329675166.tar.zst</string> ++ <string>https://github.com/secondlife/3p-libxml2/releases/download/v2.13.5-r2/libxml2-2.13.5-r2-darwin64-13246071272.tar.zst</string> + </map> + <key>name</key> + <string>darwin64</string> +@@ -95,11 +95,11 @@ + <key>archive</key> + <map> + <key>hash</key> +- <string>6ab8108ea0a42e0bd462568c495e5ce5c4cdc0ff</string> ++ <string>ba6fbc34112b1acab1c8615dcd13de983f3678d3</string> + <key>hash_algorithm</key> + <string>sha1</string> + <key>url</key> +- <string>https://github.com/secondlife/3p-libxml2/releases/download/v2.13.3-r1/libxml2-2.13.3-r1-linux64-10329675166.tar.zst</string> ++ <string>https://github.com/secondlife/3p-libxml2/releases/download/v2.13.5-r2/libxml2-2.13.5-r2-linux64-13246071272.tar.zst</string> + </map> + <key>name</key> + <string>linux64</string> +@@ -109,18 +109,18 @@ + <key>archive</key> + <map> + <key>hash</key> +- <string>5181bd267de3ad4466227f91c7e2cbed7e8b85d9</string> ++ <string>71968c4b621636e8ae0c5680e631f4aa67561944</string> + <key>hash_algorithm</key> + <string>sha1</string> + <key>url</key> +- <string>https://github.com/secondlife/3p-libxml2/releases/download/v2.13.3-r1/libxml2-2.13.3-r1-windows64-10329675166.tar.zst</string> ++ <string>https://github.com/secondlife/3p-libxml2/releases/download/v2.13.5-r2/libxml2-2.13.5-r2-windows64-13246071272.tar.zst</string> + </map> + <key>name</key> + <string>windows64</string> + </map> + </map> + <key>version</key> +- <string>2.13.3-r1</string> ++ <string>2.13.5-r2</string> + </map> + <key>minizip-ng</key> + <map> +@@ -143,11 +143,11 @@ + <key>archive</key> + <map> + <key>hash</key> +- <string>6bedaa9d770ef0ae6147f49a26fc3209fde9cb80</string> ++ <string>b628d088e1f368a0cd51a6b66292aaf9a025e2d4</string> + <key>hash_algorithm</key> + <string>sha1</string> + <key>url</key> +- <string>https://github.com/secondlife/3p-minizip-ng/releases/download/v4.0.7-r1/minizip_ng-4.0.7-r1-darwin64-10324657515.tar.zst</string> ++ <string>https://github.com/secondlife/3p-minizip-ng/releases/download/v4.0.7-r3/minizip_ng-4.0.7-r3-darwin64-13246046977.tar.zst</string> + </map> + <key>name</key> + <string>darwin64</string> +@@ -157,11 +157,11 @@ + <key>archive</key> + <map> + <key>hash</key> +- <string>ce2c91b8c4f89af252ce1b6a96af6985fe54f509</string> ++ <string>492ce9175b730d43df63821c4481685e035af623</string> + <key>hash_algorithm</key> + <string>sha1</string> + <key>url</key> +- <string>https://github.com/secondlife/3p-minizip-ng/releases/download/v4.0.7-r1/minizip_ng-4.0.7-r1-linux64-10324657515.tar.zst</string> ++ <string>https://github.com/secondlife/3p-minizip-ng/releases/download/v4.0.7-r3/minizip_ng-4.0.7-r3-linux64-13246046977.tar.zst</string> + </map> + <key>name</key> + <string>linux64</string> +@@ -171,18 +171,18 @@ + <key>archive</key> + <map> + <key>hash</key> +- <string>9cee9d85f9a7c6fb051125775f0122a926da5cc9</string> ++ <string>58773e707ff3490822b7b8217d7729ade2186632</string> + <key>hash_algorithm</key> + <string>sha1</string> + <key>url</key> +- <string>https://github.com/secondlife/3p-minizip-ng/releases/download/v4.0.7-r1/minizip_ng-4.0.7-r1-windows64-10324657515.tar.zst</string> ++ <string>https://github.com/secondlife/3p-minizip-ng/releases/download/v4.0.7-r3/minizip_ng-4.0.7-r3-windows64-13246046977.tar.zst</string> + </map> + <key>name</key> + <string>windows64</string> + </map> + </map> + <key>version</key> +- <string>4.0.7-r1</string> ++ <string>4.0.7-r3</string> + </map> + <key>zlib-ng</key> + <map> +@@ -205,11 +205,11 @@ + <key>archive</key> + <map> + <key>hash</key> +- <string>3a6593c71c59ace76d1349483759fcde4b719a76</string> ++ <string>e363e3b889c52fda7601d7aeaa9832307034651e</string> + <key>hash_algorithm</key> + <string>sha1</string> + <key>url</key> +- <string>https://github.com/secondlife/3p-zlib-ng/releases/download/v2.2.1-r2/zlib_ng-2.2.1-r2-darwin64-10324415171.tar.zst</string> ++ <string>https://github.com/secondlife/3p-zlib-ng/releases/download/v2.2.3-r1/zlib_ng-2.2.3-dev0.g8aa13e3.d20250206-darwin64-13183604450.tar.zst</string> + </map> + <key>name</key> + <string>darwin64</string> +@@ -219,11 +219,11 @@ + <key>archive</key> + <map> + <key>hash</key> +- <string>fbadeb0b8c771cb06c0055c9fab6d40c6764dacd</string> ++ <string>3cdd52f7fb3691789d50f0b40ed6f5642321ff32</string> + <key>hash_algorithm</key> + <string>sha1</string> + <key>url</key> +- <string>https://github.com/secondlife/3p-zlib-ng/releases/download/v2.2.1-r2/zlib_ng-2.2.1-r2-linux64-10324415171.tar.zst</string> ++ <string>https://github.com/secondlife/3p-zlib-ng/releases/download/v2.2.3-r1/zlib_ng-2.2.3-dev0.g8aa13e3.d20250206-linux64-13183604450.tar.zst</string> + </map> + <key>name</key> + <string>linux64</string> +@@ -233,18 +233,18 @@ + <key>archive</key> + <map> + <key>hash</key> +- <string>0094031715662be626f5106ff6c814f4fc3dacfa</string> ++ <string>e802a28139328bb2421ad39e13d996d350d8106d</string> + <key>hash_algorithm</key> + <string>sha1</string> + <key>url</key> +- <string>https://github.com/secondlife/3p-zlib-ng/releases/download/v2.2.1-r2/zlib_ng-2.2.1-r2-windows64-10324415171.tar.zst</string> ++ <string>https://github.com/secondlife/3p-zlib-ng/releases/download/v2.2.3-r1/zlib_ng-2.2.3-dev0.g8aa13e3.d20250206-windows64-13183604450.tar.zst</string> + </map> + <key>name</key> + <string>windows64</string> + </map> + </map> + <key>version</key> +- <string>2.2.1-r2</string> ++ <string>2.2.3-dev0.g8aa13e3.d20250206</string> + </map> + </map> + <key>package_description</key> +diff --git a/build-cmd.sh b/build-cmd.sh +index ee706ed..df5fa53 100755 +--- a/build-cmd.sh ++++ b/build-cmd.sh +@@ -96,7 +96,7 @@ case "$AUTOBUILD_PLATFORM" in + then + "build/$versub/domTest.exe" -all + else +- # 64 bit exe ends up in different location to 32 bit hard coded ++ # 64 bit exe ends up in different location to 32 bit hard coded + # path to data directory - source code suggests it looks in a dir + # called domTestData first so we make one + mkdir -p "$projdir/x64/Release/domTestData" +@@ -111,7 +111,7 @@ case "$AUTOBUILD_PLATFORM" in + libname="libcollada${collada_shortver}dom${dom_shortver}-s.lib" + if [ "$AUTOBUILD_ADDRSIZE" = 32 ] + then cp -a "build/$versub/$libname" "$stage"/lib/release/ +- else cp -a "$projdir/x64/Release/$libname" "$stage"/lib/release/ ++ else cp -a "$projdir/x64/Release/$libname" "$stage"/lib/release/ + fi + ;; + +@@ -126,15 +126,13 @@ case "$AUTOBUILD_PLATFORM" in + # repo root run_tests suffix + export MACOSX_DEPLOYMENT_TARGET="$LL_BUILD_DARWIN_DEPLOY_TARGET" + +- opts="${TARGET_OPTS:--arch $AUTOBUILD_CONFIGURE_ARCH $LL_BUILD_RELEASE}" ++ opts="${TARGET_OPTS:--arch arm64 -arch x86_64 $LL_BUILD_RELEASE}" + + nproc=$(sysctl -n hw.physicalcpu) + + libdir="$top/stage" + mkdir -p "$libdir"/lib/release + +- make clean arch="$AUTOBUILD_CONFIGURE_ARCH" # Hide 'arch' env var +- + # Without the -Wno-etc flag, incredible spam is produced + make \ + conf=release \ +@@ -142,7 +140,7 @@ case "$AUTOBUILD_PLATFORM" in + CFLAGS="$opts" \ + CXXFLAGS="$opts -Wno-unused-local-typedef" \ + LDFLAGS="-Wl,-headerpad_max_install_names" \ +- arch="$AUTOBUILD_CONFIGURE_ARCH" \ ++ arch="x86_64 arm64" \ + printCommands=yes \ + printMessages=yes + +diff --git a/include/dae/daeArray.h b/include/dae/daeArray.h +index 81e0fa7..941257e 100644 +--- a/include/dae/daeArray.h ++++ b/include/dae/daeArray.h +@@ -415,7 +415,7 @@ public: + * @param other A reference to the other array. + * @return true if the arrays are equal, false otherwise. + */ +- bool operator==(const daeTArray<T>& other) { ++ bool operator==(const daeTArray<T>& other) const { + if (getCount() != other.getCount()) + return false; + for (size_t i = 0; i < getCount(); i++) +diff --git a/make/common.mk b/make/common.mk +index ea87d36..6105abc 100644 +--- a/make/common.mk ++++ b/make/common.mk +@@ -15,12 +15,14 @@ ifeq ($(conf),debug) + ccFlags += -g -D_DEBUG + debugSuffix := -d + else +-ccFlags += -O2 -DNDEBUG ++ccFlags += -O3 -DNDEBUG + debugSuffix := + endif + + ifeq ($(arch),x86_64) + archsupport := -x64 ++else ifeq ($(arch),arm64) ++archsupport := -a64 + else + archsupport := + endif +diff --git a/make/rules.mk b/make/rules.mk +index eb55234..1b976a8 100644 +--- a/make/rules.mk ++++ b/make/rules.mk +@@ -41,7 +41,7 @@ ifneq ($(obj),) + # any values we use in rule commands. This is the reason for all the target-specific variables. + $(obj): cc := $(cc) + $(obj): ccFlags := $(ccFlags) +-$(obj): ccFlagsNoArch := $(filter-out -arch ppc ppc64 i386 x86_64,$(ccFlags)) ++$(obj): ccFlagsNoArch := $(filter-out -arch ppc ppc64 i386 x86_64 arm64,$(ccFlags)) + $(obj): includeOpts := $(includeOpts) + + # Call createObjRule with a source file path +diff --git a/make/rulesC.mk b/make/rulesC.mk +index 15b1e6a..023814d 100644 +--- a/make/rulesC.mk ++++ b/make/rulesC.mk +@@ -52,7 +52,7 @@ ifneq ($(obj),) + #$(obj): cc := $(cc) + $(obj): cc := $(CC) + $(obj): ccFlags := $(ccFlags) +-$(obj): ccFlagsNoArch := $(filter-out -arch ppc ppc64 i386 x86_64,$(ccFlags)) ++$(obj): ccFlagsNoArch := $(filter-out -arch ppc ppc64 i386 x86_64 arm64,$(ccFlags)) + $(obj): includeOpts := $(includeOpts) + + # Call createObjRule with a source file path +diff --git a/src/1.4/CMakeLists.txt b/src/1.4/CMakeLists.txt +index 17fbaea..d0d5939 100644 +--- a/src/1.4/CMakeLists.txt ++++ b/src/1.4/CMakeLists.txt +@@ -1,10 +1,31 @@ + file(GLOB dom_files ${CMAKE_CURRENT_SOURCE_DIR}/dom/*.cpp) +-include_directories(${COLLADA14_INCLUDE_DIR}) +-add_library(collada14dom SHARED ${COLLADA_BASE_SOURCES} ${dom_files}) ++add_library(collada14dom STATIC ${COLLADA_BASE_SOURCES} ${dom_files}) ++if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU") ++ target_compile_options(collada14dom PRIVATE ++ "-pedantic" "-Wno-error=unused-result" "-Wno-cast-user-defined" "-Wno-nonnull") ++elseif(CMAKE_CXX_COMPILER_ID STREQUAL "Clang") ++ target_compile_options(collada14dom PRIVATE ++ "-Wno-error=unused-result" ++ ) ++endif() ++target_include_directories(collada14dom PRIVATE ++ ${colladadom_SOURCE_DIR}/include ++ ${colladadom_SOURCE_DIR}/include/1.4 ++ ${Boost_INCLUDE_DIRS} ++ ${LIBXML2_INCLUDE_DIRS} ++ ${MINIZIP_INCLUDE_DIRS} ++ ${ZLIB_INCLUDE_DIRS} ++) ++target_link_directories(collada14dom INTERFACE ++ ${Boost_LIBRARY_DIRS} ++ ${LIBXML2_LIBRARY_DIRS} ++ ${MINIZIP_LIBRARY_DIRS} ++ ${ZLIB_LIBRARY_DIRS} ++) + target_link_libraries(collada14dom ${COLLADA_LIBS}) + set_target_properties(collada14dom PROPERTIES + COMPILE_FLAGS "${COLLADA_COMPILE_FLAGS}" + CLEAN_DIRECT_OUTPUT 1 + SOVERSION ${COLLADA_DOM_SOVERSION} + VERSION ${COLLADA_DOM_VERSION}) +-install(TARGETS collada14dom DESTINATION lib${LIB_SUFFIX}) ++# install(TARGETS collada14dom DESTINATION ${COLLADA_DOM_LIBS_INSTALL_DIR}) +diff --git a/src/1.5/CMakeLists.txt b/src/1.5/CMakeLists.txt +index e061a01..fb73a70 100644 +--- a/src/1.5/CMakeLists.txt ++++ b/src/1.5/CMakeLists.txt +@@ -1,10 +1,10 @@ + file(GLOB dom_files ${CMAKE_CURRENT_SOURCE_DIR}/dom/*.cpp) + include_directories(${COLLADA15_INCLUDE_DIR}) +-add_library(collada15dom SHARED ${COLLADA_BASE_SOURCES} ${dom_files}) ++add_library(collada15dom STATIC ${COLLADA_BASE_SOURCES} ${dom_files}) + target_link_libraries(collada15dom ${COLLADA_LIBS}) + set_target_properties(collada15dom PROPERTIES + COMPILE_FLAGS "${COLLADA_COMPILE_FLAGS}" + CLEAN_DIRECT_OUTPUT 1 + SOVERSION ${COLLADA_DOM_SOVERSION} + VERSION ${COLLADA_DOM_VERSION}) +-install(TARGETS collada15dom DESTINATION lib${LIB_SUFFIX}) ++install(TARGETS collada15dom DESTINATION ${COLLADA_DOM_LIBS_INSTALL_DIR}) +diff --git a/src/dae/daeMetaElement.cpp b/src/dae/daeMetaElement.cpp +index 55a57f5..5dc4657 100644 +--- a/src/dae/daeMetaElement.cpp ++++ b/src/dae/daeMetaElement.cpp +@@ -107,8 +107,8 @@ daeMetaElement::addContentsOrder(daeInt offset) + meaa->setOffset(offset); + meaa->setContainer( this); + +- if (_metaContentsOrder) +- delete _metaContentsOrder; ++ if (_metaContentsOrder) ++ delete _metaContentsOrder; + + _metaContentsOrder = meaa; + } +@@ -121,8 +121,8 @@ void daeMetaElement::addCMDataArray(daeInt offset, daeUInt numChoices) + meaa->setOffset(offset); + meaa->setContainer( this); + +- if (_metaCMData) +- delete _metaCMData; ++ if (_metaCMData) ++ delete _metaCMData; + + _metaCMData = meaa; + +@@ -175,7 +175,7 @@ daeMetaElement::appendAttribute(daeMetaAttribute* attr) + else + _metaAttributes.append(attr); + +- if ((attr->getName() != NULL) && ++ if ((daeString(attr->getName()) != NULL) && + (strcmp(attr->getName(),"id") == 0)) { + _metaID = attr; + _isTrackableForQueries = true; +diff --git a/src/dae/daeUtils.cpp b/src/dae/daeUtils.cpp +index 682692c..71b1f12 100644 +--- a/src/dae/daeUtils.cpp ++++ b/src/dae/daeUtils.cpp +@@ -19,6 +19,8 @@ + + #ifndef NO_BOOST + #include <boost/filesystem.hpp> // THIS WAS NOT COMMENTED. ++#include <boost/uuid/uuid_generators.hpp> ++#include <boost/uuid/uuid_io.hpp> + #endif + + #include <cstdio> // for tmpnam +@@ -118,7 +120,7 @@ list<string> cdom::makeStringList(const char* s, ...) { + va_end(args); + return result; + } +-#endif 0 ++#endif // 0 + + string cdom::getCurrentDir() { + #ifdef __CELLOS_LV2__ +@@ -154,7 +156,7 @@ char cdom::getFileSeparator() { + const string& cdom::getSystemTmpDir() { + #ifdef WIN32 + static string tmpDir = string(getenv("TMP")) + getFileSeparator(); +-#elif defined(__linux__) || defined(__linux) ++#elif defined(__linux__) || defined(__linux) || defined(__FreeBSD__) + static string tmpDir = "/tmp/"; + #elif defined __APPLE_CC__ + static string tmpDir = string(getenv("TMPDIR")); +@@ -169,11 +171,16 @@ static string tmpDir = string(getenv("TMPDIR")); + string cdom::getRandomFileName() { + std::string randomSegment; + // have to createa a buffer in order to make it multi-thread safe ++#ifdef NO_BOOST + std::string tmpbuffer; tmpbuffer.resize(L_tmpnam*2+1); + std::string tmp(tmpnam(&tmpbuffer[0])); ++#else ++ boost::uuids::uuid uuid = boost::uuids::random_generator()(); ++ std::string tmp(boost::uuids::to_string(uuid)); ++#endif + #ifdef WIN32 + randomSegment = tmp.substr(tmp.find_last_of('\\')+1); +-#elif defined(__linux__) || defined(__linux) ++#elif defined(__linux__) || defined(__linux) || defined(__FreeBSD__) + randomSegment = tmp.substr(tmp.find_last_of('/')+1); + #elif defined __APPLE_CC__ + randomSegment = tmp.substr(tmp.find_last_of('/')+1); |