diff options
51 files changed, 1246 insertions, 198 deletions
@@ -292,12 +292,89 @@ then end_section WaitParallel fi +# build debian package +if [ "$arch" == "Linux" ] +then + if $succeeded + then + if $build_viewer_deb && [ "$last_built_variant" == "Release" ] + then + begin_section "Build Debian Package" + # mangle the changelog + dch --force-bad-version \ + --distribution unstable \ + --newversion "${VIEWER_VERSION}" \ + "Automated build #$build_id, repository $branch revision $revision." \ + >> "$build_log" 2>&1 + + # build the debian package + $pkg_default_debuild_command >>"$build_log" 2>&1 || record_failure "\"$pkg_default_debuild_command\" failed." + + # Unmangle the changelog file + hg revert debian/changelog + + end_section "Build Debian Package" + + # upload debian package and create repository + begin_section "Upload Debian Repository" + for deb_file in ../*.deb; do + upload_item debian $deb_file binary/octet-stream + done + if [ -d "$build_log_dir/debian_repo" ] + then + pushd "$build_log_dir/debian_repo" + cat > Release <<EOF +Archive: stable +Component: main +Origin: Teamcity +Label: Teamcity built .debs +Architecture: i386 amd64 any +EOF + if dpkg-scanpackages . /dev/null | gzip -9c > Packages.gz \ + && dpkg-scansources . /dev/null | gzip -9c > Sources.gz + then + begin_section Packages.gz + gunzip --stdout Packages.gz + for file in *.deb + do + stat "$file" | sed 2q + md5sum "$file" + done + end_section Packages.gz + + for file in * + do + upload_item debian_repo "$file" binary/octet-stream + done + else + record_failure 'Unable to generate Packages.gz or Sources.gz' + fi + popd + + process_pending_uploads + + # Rename the local debian_repo directory so that the master buildscript + # doesn't make a remote repo again. + + mv $build_log_dir/debian_repo $build_log_dir/debian_repo_pushed + fi + end_section "Upload Debian Repository" + + else + echo skipping debian build + fi + else + echo skipping debian build due to failed build. + fi +fi + + # check status and upload results to S3 if $succeeded then if $build_viewer then - begin_section Upload + begin_section Upload Installer # Upload installer - note that ONLY THE FIRST ITEM uploaded as "installer" # will appear in the version manager. package=$(installer_$arch) @@ -335,12 +412,12 @@ then # Upload stub installers upload_stub_installers "$build_dir_stubs" fi - end_section Upload + end_section Upload Installer else - echo skipping viewer + echo skipping upload of installer fi else - echo skipping upload of build results due to failed build. + echo skipping upload of installer due to failed build. fi # The branch independent build.sh script invoking this script will finish processing diff --git a/debian/changelog b/debian/changelog new file mode 100644 index 0000000000..ce54b54c6f --- /dev/null +++ b/debian/changelog @@ -0,0 +1,18 @@ +secondlife-viewer (0.3) unstable; urgency=low + + * Initial debian configuration + + -- Don Kjer <don@lindenlab.com> Wed, 04 Jul 2012 00:43:03 +0000 + +secondlife-viewer (0.2) unstable; urgency=low + + * Adding default LSB headers for squeeze + + -- Tyler Kohler <tyler@lindenlab.com> Thu, 24 Mar 2011 09:43:36 -0700 + +secondlife-viewer (0.1) unstable; urgency=low + + * Cloned from debian package skeleton. + + -- Lex Linden <lex@lindenlab.com> Mon, 20 Sep 2010 08:01:59 -0700 + diff --git a/debian/compat b/debian/compat new file mode 100644 index 0000000000..7ed6ff82de --- /dev/null +++ b/debian/compat @@ -0,0 +1 @@ +5 diff --git a/debian/control b/debian/control new file mode 100644 index 0000000000..50b9ed9a26 --- /dev/null +++ b/debian/control @@ -0,0 +1,16 @@ +Source: secondlife-viewer +Section: unknown +Priority: extra +Maintainer: Don Linden <don@lindenlab.com> +Build-Depends: debhelper (>= 5) +Homepage: http://secondlife.com +Standards-Version: 3.7.2 + +Package: secondlife-viewer +Architecture: any +Depends: ${shlibs:Depends}, ${misc:Depends}, + ia32-libs, + ia32-libs-gtk +Description: Second Life Viewer + Second Life is an online virtual world developed by Linden Lab. + diff --git a/debian/copyright b/debian/copyright new file mode 100644 index 0000000000..ecfceb3927 --- /dev/null +++ b/debian/copyright @@ -0,0 +1,7 @@ +Copyright: 2012 Linden Research, Inc. + +License: + +No license to distribute, copy, modify, or make derivitave works of this +software is granted unless specifically granted in writing by Linden Research, +Inc. diff --git a/debian/postinst b/debian/postinst new file mode 100644 index 0000000000..2c4f8ea858 --- /dev/null +++ b/debian/postinst @@ -0,0 +1,43 @@ +#!/bin/sh +# postinst script for secondlife-viewer +# +# Delete this file if you don't need it. +# +# see: dh_installdeb(1) + +set -e + +# summary of how this script can be called: +# * <postinst> `configure' <most-recently-configured-version> +# * <old-postinst> `abort-upgrade' <new version> +# * <conflictor's-postinst> `abort-remove' `in-favour' <package> +# <new-version> +# * <postinst> `abort-remove' +# * <deconfigured's-postinst> `abort-deconfigure' `in-favour' +# <failed-install-package> <version> `removing' +# <conflicting-package> <version> +# for details, see http://www.debian.org/doc/debian-policy/ or +# the debian-policy package + + +case "$1" in + configure) + ;; + + abort-upgrade|abort-remove|abort-deconfigure) + ;; + + *) + echo "postinst called with unknown argument \`$1'" >&2 + exit 1 + ;; +esac + +# dh_installdeb will replace this with shell code automatically +# generated by other debhelper scripts. Don't delete this! + +#DEBHELPER# + +exit 0 + + diff --git a/debian/postrm b/debian/postrm new file mode 100644 index 0000000000..a575936ab0 --- /dev/null +++ b/debian/postrm @@ -0,0 +1,41 @@ +#!/bin/sh +# postrm script for secondlife-viewer +# +# Delete this file if you don't need it. +# +# see: dh_installdeb(1) + +set -e + +# summary of how this script can be called: +# * <postrm> `remove' +# * <postrm> `purge' +# * <old-postrm> `upgrade' <new-version> +# * <new-postrm> `failed-upgrade' <old-version> +# * <new-postrm> `abort-install' +# * <new-postrm> `abort-install' <old-version> +# * <new-postrm> `abort-upgrade' <old-version> +# * <disappearer's-postrm> `disappear' <overwriter> +# <overwriter-version> +# for details, see http://www.debian.org/doc/debian-policy/ or +# the debian-policy package + + +case "$1" in + purge|remove|upgrade|failed-upgrade|abort-install|abort-upgrade|disappear) + ;; + + *) + echo "postrm called with unknown argument \`$1'" >&2 + exit 1 + ;; +esac + +# dh_installdeb will replace this with shell code automatically +# generated by other debhelper scripts. Don't delete this! + +#DEBHELPER# + +exit 0 + + diff --git a/debian/preinst b/debian/preinst new file mode 100644 index 0000000000..f62243440f --- /dev/null +++ b/debian/preinst @@ -0,0 +1,39 @@ +#!/bin/sh +# preinst script for secondlife-viewer +# +# Delete this file if you don't need it. +# +# see: dh_installdeb(1) + +set -e + +# summary of how this script can be called: +# * <new-preinst> `install' +# * <new-preinst> `install' <old-version> +# * <new-preinst> `upgrade' <old-version> +# * <old-preinst> `abort-upgrade' <new-version> +# for details, see http://www.debian.org/doc/debian-policy/ or +# the debian-policy package + + +case "$1" in + install|upgrade) + ;; + + abort-upgrade) + ;; + + *) + echo "preinst called with unknown argument \`$1'" >&2 + exit 1 + ;; +esac + +# dh_installdeb will replace this with shell code automatically +# generated by other debhelper scripts. Don't delete this! + +#DEBHELPER# + +exit 0 + + diff --git a/debian/prerm b/debian/prerm new file mode 100644 index 0000000000..405b8f9c87 --- /dev/null +++ b/debian/prerm @@ -0,0 +1,42 @@ +#!/bin/sh +# prerm script for secondlife-viewer +# +# Delete this file if you don't need it. +# +# see: dh_installdeb(1) + +set -e + +# summary of how this script can be called: +# * <prerm> `remove' +# * <old-prerm> `upgrade' <new-version> +# * <new-prerm> `failed-upgrade' <old-version> +# * <conflictor's-prerm> `remove' `in-favour' <package> <new-version> +# * <deconfigured's-prerm> `deconfigure' `in-favour' +# <package-being-installed> <version> `removing' +# <conflicting-package> <version> +# for details, see http://www.debian.org/doc/debian-policy/ or +# the debian-policy package + + +case "$1" in + remove|upgrade|deconfigure) + ;; + + failed-upgrade) + ;; + + *) + echo "prerm called with unknown argument \`$1'" >&2 + exit 1 + ;; +esac + +# dh_installdeb will replace this with shell code automatically +# generated by other debhelper scripts. Don't delete this! + +#DEBHELPER# + +exit 0 + + diff --git a/debian/rules b/debian/rules new file mode 100755 index 0000000000..c41f02d4fb --- /dev/null +++ b/debian/rules @@ -0,0 +1,116 @@ +#!/usr/bin/make -f +# -*- makefile -*- +# Sample debian/rules that uses debhelper. +# This file was originally written by Joey Hess and Craig Small. +# As a special exception, when this file is copied by dh-make into a +# dh-make output file, you may use that output file without restriction. +# This special exception was added by Craig Small in version 0.37 of dh-make. + +# Uncomment this to turn on verbose mode. +#export DH_VERBOSE=1 + +SRCDIR=build-linux-i686/newview/packaged +DESTDIR=$(CURDIR)/debian/secondlife-viewer +BASEDIR=opt/linden/viewer +VIEWER_VERSION:=$(shell dpkg-parsechangelog | grep ^Version | sed 's/^Version: //') +INSTALLDIR:=$(BASEDIR)/SecondLife-i686-$(VIEWER_VERSION) + +configure: configure-stamp +configure-stamp: + dh_testdir + # Add here commands to configure the package. + + touch configure-stamp + +build: build-stamp + +build-stamp: configure-stamp + dh_testdir + + # Add here commands to compile the package. + #$(MAKE) + #docbook-to-man debian/secondlife-viewer.sgml > secondlife-viewer.1 + + touch $@ + +clean: + dh_testdir + dh_testroot + rm -f build-stamp configure-stamp + + # Add here commands to clean up after the build process. + #-$(MAKE) clean + + dh_clean + +install: build + dh_testdir + dh_testroot + dh_clean -k + dh_installdirs + + # Add here commands to install the package into debian/secondlife-viewer. + for file in $$(find $(SRCDIR) -type f -o -type l | sed 's~$(SRCDIR)/~~'); do \ + # create containing directory \ + install -v -m 755 -o root -g root -d "$$(dirname "$(DESTDIR)/$(INSTALLDIR)/$$file")"; \ + PERM=644; \ + if [ -x "$(SRCDIR)/$$file" ]; then \ + PERM=755; \ + fi; \ + if [ -L "$(SRCDIR)/$$file" ]; then \ + REAL="$$( readlink -f $(SRCDIR)/$$file )"; \ + RELATIVE="$$( echo $$REAL | sed 's~$(CURDIR)/$(SRCDIR)/~~' )"; \ + echo dh_link "$(INSTALLDIR)/$$RELATIVE" "$(INSTALLDIR)/$$file" ; \ + dh_link "$(INSTALLDIR)/$$RELATIVE" "$(INSTALLDIR)/$$file" ; \ + else \ + install -v -m $$PERM -o root -g root "$(SRCDIR)/$$file" "$(DESTDIR)/$(INSTALLDIR)/$$file"; \ + fi; \ + done + dh_link /$(INSTALLDIR)/secondlife /usr/bin/secondlife + dh_link $(BASEDIR)/SecondLife-i686-$(VIEWER_VERSION) $(BASEDIR)/SecondLife + + +# Build architecture-independent files here. +binary-indep: build install +# We have nothing to do by default. + +# Build architecture-dependent files here. +binary-arch: build install + dh_testdir + dh_testroot + dh_installchangelogs + dh_installdocs + dh_installexamples +# dh_install +# dh_installmenu +# dh_installdebconf +# dh_installlogrotate +# dh_installemacsen +# dh_installpam +# dh_installmime +# dh_python + +# To add an init script, uncomment this line and edit debian/init.d and +# customize debian/secondlife-viewer.default to suit your needs. +# dh_installinit + +# To add cron jobs, uncomment this line and make a crontab file named +# debian/cron.d, and it will be installed in /etc/cron.d/ +# dh_installcron + +# dh_installinfo + dh_installman + dh_link +# dh_strip + dh_compress +# dh_fixperms +# dh_perl +# dh_makeshlibs + dh_installdeb +# dh_shlibdeps + dh_gencontrol + dh_md5sums + dh_builddeb + +binary: binary-indep binary-arch +.PHONY: build clean binary-indep binary-arch binary install configure diff --git a/indra/llcommon/imageids.cpp b/indra/llcommon/imageids.cpp index fe11465221..7d647e5c36 100644..100755 --- a/indra/llcommon/imageids.cpp +++ b/indra/llcommon/imageids.cpp @@ -68,3 +68,6 @@ const LLUUID TERRAIN_MOUNTAIN_DETAIL ("303cd381-8560-7579-23f1-f0a880799740"); / const LLUUID TERRAIN_ROCK_DETAIL ("53a2f406-4895-1d13-d541-d2e3b86bc19c"); // VIEWER const LLUUID DEFAULT_WATER_NORMAL ("822ded49-9a6c-f61c-cb89-6df54f42cdf4"); // VIEWER + +const LLUUID IMG_CHECKERBOARD_RGBA ("2585a0f3-4163-6dd1-0f34-ad48cb909e25"); // dataserver + diff --git a/indra/llcommon/imageids.h b/indra/llcommon/imageids.h index e0c2683fdc..18c8ecb074 100644..100755 --- a/indra/llcommon/imageids.h +++ b/indra/llcommon/imageids.h @@ -66,4 +66,5 @@ LL_COMMON_API extern const LLUUID TERRAIN_ROCK_DETAIL; LL_COMMON_API extern const LLUUID DEFAULT_WATER_NORMAL; +LL_COMMON_API extern const LLUUID IMG_CHECKERBOARD_RGBA; #endif diff --git a/indra/llmessage/message_prehash.cpp b/indra/llmessage/message_prehash.cpp index d7658862da..c3fa7ff048 100644 --- a/indra/llmessage/message_prehash.cpp +++ b/indra/llmessage/message_prehash.cpp @@ -1376,3 +1376,6 @@ char const* const _PREHASH_ProductSKU = LLMessageStringTable::getInstance()->get char const* const _PREHASH_SeeAVs = LLMessageStringTable::getInstance()->getString("SeeAVs"); char const* const _PREHASH_AnyAVSounds = LLMessageStringTable::getInstance()->getString("AnyAVSounds"); char const* const _PREHASH_GroupAVSounds = LLMessageStringTable::getInstance()->getString("GroupAVSounds"); +char const* const _PREHASH_AppearanceData = LLMessageStringTable::getInstance()->getString("AppearanceData"); +char const* const _PREHASH_AppearanceVersion = LLMessageStringTable::getInstance()->getString("AppearanceVersion"); +char const* const _PREHASH_CofVersion = LLMessageStringTable::getInstance()->getString("CofVersion"); diff --git a/indra/llmessage/message_prehash.h b/indra/llmessage/message_prehash.h index da2b613f53..9214682003 100644 --- a/indra/llmessage/message_prehash.h +++ b/indra/llmessage/message_prehash.h @@ -1376,4 +1376,7 @@ extern char const* const _PREHASH_ProductSKU; extern char const* const _PREHASH_SeeAVs; extern char const* const _PREHASH_AnyAVSounds; extern char const* const _PREHASH_GroupAVSounds; +extern char const* const _PREHASH_AppearanceData; +extern char const* const _PREHASH_AppearanceVersion; +extern char const* const _PREHASH_CofVersion; #endif diff --git a/indra/llprimitive/llprimitive.cpp b/indra/llprimitive/llprimitive.cpp index 6dee192783..b765ed60c4 100755 --- a/indra/llprimitive/llprimitive.cpp +++ b/indra/llprimitive/llprimitive.cpp @@ -39,6 +39,7 @@ #include "lldatapacker.h" #include "llsdutil_math.h" #include "llprimtexturelist.h" +#include "imageids.h" /** * exported constants @@ -1234,94 +1235,77 @@ BOOL LLPrimitive::packTEMessage(LLDataPacker &dp) const return FALSE; } -S32 LLPrimitive::unpackTEMessage(LLMessageSystem* mesgsys, char const* block_name) +S32 LLPrimitive::parseTEMessage(LLMessageSystem* mesgsys, char const* block_name, const S32 block_num, LLTEContents& tec) { - return(unpackTEMessage(mesgsys,block_name,-1)); -} - -S32 LLPrimitive::unpackTEMessage(LLMessageSystem* mesgsys, char const* block_name, const S32 block_num) -{ - // use a negative block_num to indicate a single-block read (a non-variable block) S32 retval = 0; - const U32 MAX_TES = 32; - - // Avoid construction of 32 UUIDs per call. JC - - U8 image_data[MAX_TES*16]; - U8 colors[MAX_TES*4]; - F32 scale_s[MAX_TES]; - F32 scale_t[MAX_TES]; - S16 offset_s[MAX_TES]; - S16 offset_t[MAX_TES]; - S16 image_rot[MAX_TES]; - U8 bump[MAX_TES]; - U8 media_flags[MAX_TES]; - U8 glow[MAX_TES]; - - const U32 MAX_TE_BUFFER = 4096; - U8 packed_buffer[MAX_TE_BUFFER]; - U8 *cur_ptr = packed_buffer; - - U32 size; - U32 face_count = 0; if (block_num < 0) { - size = mesgsys->getSizeFast(block_name, _PREHASH_TextureEntry); + tec.size = mesgsys->getSizeFast(block_name, _PREHASH_TextureEntry); } else { - size = mesgsys->getSizeFast(block_name, block_num, _PREHASH_TextureEntry); + tec.size = mesgsys->getSizeFast(block_name, block_num, _PREHASH_TextureEntry); } - if (size == 0) + if (tec.size == 0) { return retval; } if (block_num < 0) { - mesgsys->getBinaryDataFast(block_name, _PREHASH_TextureEntry, packed_buffer, 0, 0, MAX_TE_BUFFER); + mesgsys->getBinaryDataFast(block_name, _PREHASH_TextureEntry, tec.packed_buffer, 0, 0, LLTEContents::MAX_TE_BUFFER); } else { - mesgsys->getBinaryDataFast(block_name, _PREHASH_TextureEntry, packed_buffer, 0, block_num, MAX_TE_BUFFER); + mesgsys->getBinaryDataFast(block_name, _PREHASH_TextureEntry, tec.packed_buffer, 0, block_num, LLTEContents::MAX_TE_BUFFER); } - face_count = getNumTEs(); + tec.face_count = getNumTEs(); - cur_ptr += unpackTEField(cur_ptr, packed_buffer+size, (U8 *)image_data, 16, face_count, MVT_LLUUID); + U8 *cur_ptr = tec.packed_buffer; + cur_ptr += unpackTEField(cur_ptr, tec.packed_buffer+tec.size, (U8 *)tec.image_data, 16, tec.face_count, MVT_LLUUID); cur_ptr++; - cur_ptr += unpackTEField(cur_ptr, packed_buffer+size, (U8 *)colors, 4, face_count, MVT_U8); + cur_ptr += unpackTEField(cur_ptr, tec.packed_buffer+tec.size, (U8 *)tec.colors, 4, tec.face_count, MVT_U8); cur_ptr++; - cur_ptr += unpackTEField(cur_ptr, packed_buffer+size, (U8 *)scale_s, 4, face_count, MVT_F32); + cur_ptr += unpackTEField(cur_ptr, tec.packed_buffer+tec.size, (U8 *)tec.scale_s, 4, tec.face_count, MVT_F32); cur_ptr++; - cur_ptr += unpackTEField(cur_ptr, packed_buffer+size, (U8 *)scale_t, 4, face_count, MVT_F32); + cur_ptr += unpackTEField(cur_ptr, tec.packed_buffer+tec.size, (U8 *)tec.scale_t, 4, tec.face_count, MVT_F32); cur_ptr++; - cur_ptr += unpackTEField(cur_ptr, packed_buffer+size, (U8 *)offset_s, 2, face_count, MVT_S16Array); + cur_ptr += unpackTEField(cur_ptr, tec.packed_buffer+tec.size, (U8 *)tec.offset_s, 2, tec.face_count, MVT_S16Array); cur_ptr++; - cur_ptr += unpackTEField(cur_ptr, packed_buffer+size, (U8 *)offset_t, 2, face_count, MVT_S16Array); + cur_ptr += unpackTEField(cur_ptr, tec.packed_buffer+tec.size, (U8 *)tec.offset_t, 2, tec.face_count, MVT_S16Array); cur_ptr++; - cur_ptr += unpackTEField(cur_ptr, packed_buffer+size, (U8 *)image_rot, 2, face_count, MVT_S16Array); + cur_ptr += unpackTEField(cur_ptr, tec.packed_buffer+tec.size, (U8 *)tec.image_rot, 2, tec.face_count, MVT_S16Array); cur_ptr++; - cur_ptr += unpackTEField(cur_ptr, packed_buffer+size, (U8 *)bump, 1, face_count, MVT_U8); + cur_ptr += unpackTEField(cur_ptr, tec.packed_buffer+tec.size, (U8 *)tec.bump, 1, tec.face_count, MVT_U8); cur_ptr++; - cur_ptr += unpackTEField(cur_ptr, packed_buffer+size, (U8 *)media_flags, 1, face_count, MVT_U8); + cur_ptr += unpackTEField(cur_ptr, tec.packed_buffer+tec.size, (U8 *)tec.media_flags, 1, tec.face_count, MVT_U8); cur_ptr++; - cur_ptr += unpackTEField(cur_ptr, packed_buffer+size, (U8 *)glow, 1, face_count, MVT_U8); - + cur_ptr += unpackTEField(cur_ptr, tec.packed_buffer+tec.size, (U8 *)tec.glow, 1, tec.face_count, MVT_U8); + + retval = 1; + return retval; +} + +S32 LLPrimitive::applyParsedTEMessage(LLTEContents& tec) +{ + S32 retval = 0; + LLColor4 color; LLColor4U coloru; - for (U32 i = 0; i < face_count; i++) - { - retval |= setTETexture(i, ((LLUUID*)image_data)[i]); - retval |= setTEScale(i, scale_s[i], scale_t[i]); - retval |= setTEOffset(i, (F32)offset_s[i] / (F32)0x7FFF, (F32) offset_t[i] / (F32) 0x7FFF); - retval |= setTERotation(i, ((F32)image_rot[i] / TEXTURE_ROTATION_PACK_FACTOR) * F_TWO_PI); - retval |= setTEBumpShinyFullbright(i, bump[i]); - retval |= setTEMediaTexGen(i, media_flags[i]); - retval |= setTEGlow(i, (F32)glow[i] / (F32)0xFF); - coloru = LLColor4U(colors + 4*i); + for (U32 i = 0; i < tec.face_count; i++) + { + LLUUID& req_id = ((LLUUID*)tec.image_data)[i]; + retval |= setTETexture(i, req_id); + retval |= setTEScale(i, tec.scale_s[i], tec.scale_t[i]); + retval |= setTEOffset(i, (F32)tec.offset_s[i] / (F32)0x7FFF, (F32) tec.offset_t[i] / (F32) 0x7FFF); + retval |= setTERotation(i, ((F32)tec.image_rot[i] / TEXTURE_ROTATION_PACK_FACTOR) * F_TWO_PI); + retval |= setTEBumpShinyFullbright(i, tec.bump[i]); + retval |= setTEMediaTexGen(i, tec.media_flags[i]); + retval |= setTEGlow(i, (F32)tec.glow[i] / (F32)0xFF); + coloru = LLColor4U(tec.colors + 4*i); // Note: This is an optimization to send common colors (1.f, 1.f, 1.f, 1.f) // as all zeros. However, the subtraction and addition must be done in unsigned @@ -1338,6 +1322,15 @@ S32 LLPrimitive::unpackTEMessage(LLMessageSystem* mesgsys, char const* block_nam return retval; } +S32 LLPrimitive::unpackTEMessage(LLMessageSystem* mesgsys, char const* block_name, const S32 block_num) +{ + LLTEContents tec; + S32 retval = parseTEMessage(mesgsys, block_name, block_num, tec); + if (!retval) + return retval; + return applyParsedTEMessage(tec); +} + S32 LLPrimitive::unpackTEMessage(LLDataPacker &dp) { // use a negative block_num to indicate a single-block read (a non-variable block) diff --git a/indra/llprimitive/llprimitive.h b/indra/llprimitive/llprimitive.h index 8dcaa8c740..6a8b59c81c 100644..100755 --- a/indra/llprimitive/llprimitive.h +++ b/indra/llprimitive/llprimitive.h @@ -289,6 +289,34 @@ public: }; +// This code is not naming-standards compliant. Leaving it like this for +// now to make the connection to code in +// BOOL packTEMessage(LLDataPacker &dp) const; +// more obvious. This should be refactored to remove the duplication, at which +// point we can fix the names as well. +// - Vir +struct LLTEContents +{ + static const U32 MAX_TES = 32; + + U8 image_data[MAX_TES*16]; + U8 colors[MAX_TES*4]; + F32 scale_s[MAX_TES]; + F32 scale_t[MAX_TES]; + S16 offset_s[MAX_TES]; + S16 offset_t[MAX_TES]; + S16 image_rot[MAX_TES]; + U8 bump[MAX_TES]; + U8 media_flags[MAX_TES]; + U8 glow[MAX_TES]; + + static const U32 MAX_TE_BUFFER = 4096; + U8 packed_buffer[MAX_TE_BUFFER]; + + U32 size; + U32 face_count; +}; + class LLPrimitive : public LLXform { public: @@ -360,9 +388,10 @@ public: S32 unpackTEField(U8 *cur_ptr, U8 *buffer_end, U8 *data_ptr, U8 data_size, U8 face_count, EMsgVariableType type); BOOL packTEMessage(LLMessageSystem *mesgsys) const; BOOL packTEMessage(LLDataPacker &dp) const; - S32 unpackTEMessage(LLMessageSystem* mesgsys, char const* block_name); S32 unpackTEMessage(LLMessageSystem* mesgsys, char const* block_name, const S32 block_num); // Variable num of blocks BOOL unpackTEMessage(LLDataPacker &dp); + S32 parseTEMessage(LLMessageSystem* mesgsys, char const* block_name, const S32 block_num, LLTEContents& tec); + S32 applyParsedTEMessage(LLTEContents& tec); #ifdef CHECK_FOR_FINITE inline void setPosition(const LLVector3& pos); diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index 753dbd7438..2c9952cbc8 100755 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -437,6 +437,7 @@ set(viewer_SOURCE_FILES llpathfindingpathtool.cpp llphysicsmotion.cpp llphysicsshapebuilderutil.cpp + llpipelinelistener.cpp llplacesinventorybridge.cpp llplacesinventorypanel.cpp llpopupview.cpp @@ -1002,6 +1003,7 @@ set(viewer_HEADER_FILES llpathfindingpathtool.h llphysicsmotion.h llphysicsshapebuilderutil.h + llpipelinelistener.h llplacesinventorybridge.h llplacesinventorypanel.h llpolymesh.h diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 5e42fc29f7..32213a07a8 100755 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -71,6 +71,17 @@ <key>Value</key> <integer>0</integer> </map> + <key>AgentAppearanceServiceURL</key> + <map> + <key>Comment</key> + <string>Current Session Agent Appearance Service URL</string> + <key>Persist</key> + <integer>0</integer> + <key>Type</key> + <string>String</string> + <key>Value</key> + <string></string> + </map> <key>AlertedUnsupportedHardware</key> <map> <key>Comment</key> @@ -8716,6 +8727,28 @@ <key>Value</key> <integer>1</integer> </map> + <key>DisableAllRenderTypes</key> + <map> + <key>Comment</key> + <string>Disables all rendering types.</string> + <key>Persist</key> + <integer>0</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>0</integer> + </map> + <key>DisableAllRenderFeatures</key> + <map> + <key>Comment</key> + <string>Disables all rendering features.</string> + <key>Persist</key> + <integer>0</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>0</integer> + </map> <key>RenderHUDInSnapshot</key> <map> <key>Comment</key> @@ -12351,6 +12384,17 @@ <key>Value</key> <integer>1</integer> </map> + <key>UseServerTextureBaking</key> + <map> + <key>Comment</key> + <string>Update appearance via the ServerTextureBaking cap, if available</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>1</integer> + </map> <key>RenderSynchronousOcclusion</key> <map> <key>Comment</key> @@ -13098,6 +13142,28 @@ <key>Value</key> <integer>-1</integer> </map> + <key>MaxFPS</key> + <map> + <key>Comment</key> + <string>Yield some time to the local host if we reach a threshold framerate.</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>F32</string> + <key>Value</key> + <integer>-1.0</integer> + </map> + <key>ForcePeriodicRenderingTime</key> + <map> + <key>Comment</key> + <string>Periodically enable all rendering masks for a single frame.</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>F32</string> + <key>Value</key> + <integer>-1.0</integer> + </map> <key>ZoomDirect</key> <map> <key>Comment</key> diff --git a/indra/newview/character/avatar_lad.xml b/indra/newview/character/avatar_lad.xml index 99dbfcae51..2b090c4fa4 100644..100755 --- a/indra/newview/character/avatar_lad.xml +++ b/indra/newview/character/avatar_lad.xml @@ -12291,6 +12291,17 @@ render_pass="bump"> <param_driver /> </param> + <param + id="11000" + group="0" + name="AppearanceMessage_Version" + label="AppearanceMessage Version" + value_default="0" + value_min="0" + value_max="255"> + <param_driver /> + </param> + </driver_parameters> <morph_masks> diff --git a/indra/newview/linux_tools/wrapper.sh b/indra/newview/linux_tools/wrapper.sh index 20936c6460..fa9ce703a8 100755 --- a/indra/newview/linux_tools/wrapper.sh +++ b/indra/newview/linux_tools/wrapper.sh @@ -117,18 +117,32 @@ export LD_LIBRARY_PATH="$PWD/lib:${LD_LIBRARY_PATH}" # Simply embedding $(<etc/gridargs.dat) into a command line treats each of # Second, Life and Developer as separate args -- no good. We need bash to # process quotes using eval. -# First read it without scanning, then scan that string. Break quoted words +# First, check if we have been instructed to skip reading in gridargs.dat: +skip_gridargs=false +argnum=0 +for ARG in "$@"; do + if [ "--skip-gridargs" == "$ARG" ]; then + skip_gridargs=true + else + ARGS[$argnum]="$ARG" + argnum=$(($argnum+1)) + fi +done + +# Second, read it without scanning, then scan that string. Break quoted words # into a bash array. Note that if gridargs.dat is empty, or contains only # whitespace, the resulting gridargs array will be empty -- zero entries -- # therefore "${gridargs[@]}" entirely vanishes from the command line below, # just as we want. -eval gridargs=("$(<etc/gridargs.dat)") +if ! $skip_gridargs ; then + eval gridargs=("$(<etc/gridargs.dat)") +fi # Run the program. # Don't quote $LL_WRAPPER because, if empty, it should simply vanish from the # command line. But DO quote "$@": preserve separate args as individually # quoted. Similar remarks about the contents of gridargs. -$LL_WRAPPER bin/do-not-directly-run-secondlife-bin "${gridargs[@]}" "$@" +$LL_WRAPPER bin/do-not-directly-run-secondlife-bin "${gridargs[@]}" "${ARGS[@]}" LL_RUN_ERR=$? # Handle any resulting errors diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp index 447836910d..2379c23969 100755 --- a/indra/newview/llagent.cpp +++ b/indra/newview/llagent.cpp @@ -35,6 +35,7 @@ #include "llagentlistener.h" #include "llagentwearables.h" #include "llagentui.h" +#include "llappearancemgr.h" #include "llanimationstates.h" #include "llcallingcard.h" #include "llcapabilitylistener.h" @@ -4259,7 +4260,7 @@ void LLAgent::requestLeaveGodMode() //----------------------------------------------------------------------------- void LLAgent::sendAgentSetAppearance() { - if (!isAgentAvatarValid()) return; + if (!isAgentAvatarValid() || (getRegion() && getRegion()->getCentralBakeVersion())) return; if (gAgentQueryManager.mNumPendingQueries > 0 && (isAgentAvatarValid() && gAgentAvatarp->isUsingBakedTextures())) { diff --git a/indra/newview/llagentcamera.cpp b/indra/newview/llagentcamera.cpp index 751b73e1eb..a544909e66 100644 --- a/indra/newview/llagentcamera.cpp +++ b/indra/newview/llagentcamera.cpp @@ -2251,7 +2251,7 @@ void LLAgentCamera::changeCameraToThirdPerson(BOOL animate) //----------------------------------------------------------------------------- void LLAgentCamera::changeCameraToCustomizeAvatar() { - if (LLViewerJoystick::getInstance()->getOverrideCamera()) + if (LLViewerJoystick::getInstance()->getOverrideCamera() || !isAgentAvatarValid()) { return; } @@ -2275,29 +2275,21 @@ void LLAgentCamera::changeCameraToCustomizeAvatar() gFocusMgr.setKeyboardFocus( NULL ); gFocusMgr.setMouseCapture( NULL ); - LLVOAvatarSelf::onCustomizeStart(); - - if (isAgentAvatarValid()) - { - // Remove any pitch or rotation from the avatar - LLVector3 at = gAgent.getAtAxis(); - at.mV[VZ] = 0.f; - at.normalize(); - gAgent.resetAxes(at); - - gAgent.sendAnimationRequest(ANIM_AGENT_CUSTOMIZE, ANIM_REQUEST_START); - gAgent.setCustomAnim(TRUE); - gAgentAvatarp->startMotion(ANIM_AGENT_CUSTOMIZE); - LLMotion* turn_motion = gAgentAvatarp->findMotion(ANIM_AGENT_CUSTOMIZE); + // Remove any pitch or rotation from the avatar + LLVector3 at = gAgent.getAtAxis(); + at.mV[VZ] = 0.f; + at.normalize(); + gAgent.resetAxes(at); - if (turn_motion) - { - // delay camera animation long enough to play through turn animation - setAnimationDuration(turn_motion->getDuration() + CUSTOMIZE_AVATAR_CAMERA_ANIM_SLOP); - } + gAgent.sendAnimationRequest(ANIM_AGENT_CUSTOMIZE, ANIM_REQUEST_START); + gAgent.setCustomAnim(TRUE); + gAgentAvatarp->startMotion(ANIM_AGENT_CUSTOMIZE); + LLMotion* turn_motion = gAgentAvatarp->findMotion(ANIM_AGENT_CUSTOMIZE); - gAgentAvatarp->invalidateAll(); - gAgentAvatarp->updateMeshTextures(); + if (turn_motion) + { + // delay camera animation long enough to play through turn animation + setAnimationDuration(turn_motion->getDuration() + CUSTOMIZE_AVATAR_CAMERA_ANIM_SLOP); } } diff --git a/indra/newview/llagentwearables.cpp b/indra/newview/llagentwearables.cpp index e441f21f90..e44b27c6af 100755 --- a/indra/newview/llagentwearables.cpp +++ b/indra/newview/llagentwearables.cpp @@ -1597,7 +1597,7 @@ void LLAgentWearables::setWearableFinal(LLInventoryItem* new_item, LLWearable* n void LLAgentWearables::queryWearableCache() { - if (!areWearablesLoaded()) + if (!areWearablesLoaded() || (gAgent.getRegion() && gAgent.getRegion()->getCentralBakeVersion())) { return; } diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp index 6d67e098a6..3e02f98933 100755 --- a/indra/newview/llappearancemgr.cpp +++ b/indra/newview/llappearancemgr.cpp @@ -926,6 +926,18 @@ const LLUUID LLAppearanceMgr::getCOF() const return gInventory.findCategoryUUIDForType(LLFolderType::FT_CURRENT_OUTFIT); } +S32 LLAppearanceMgr::getCOFVersion() const +{ + LLViewerInventoryCategory *cof = gInventory.getCategory(getCOF()); + if (cof) + { + return cof->getVersion(); + } + else + { + return LLViewerInventoryCategory::VERSION_UNKNOWN; + } +} const LLViewerInventoryItem* LLAppearanceMgr::getBaseOutfitLink() { @@ -1731,6 +1743,12 @@ void LLAppearanceMgr::updateAppearanceFromCOF(bool update_base_outfit_ordering) // the saved outfit stored as a folder link updateIsDirty(); + // Send server request for appearance update + if (gAgent.getRegion() && gAgent.getRegion()->getCentralBakeVersion()) + { + requestServerAppearanceUpdate(); + } + //dumpCat(getCOF(),"COF, start"); bool follow_folder_links = true; @@ -2582,8 +2600,35 @@ void LLAppearanceMgr::updateClothingOrderingInfo(LLUUID cat_id, bool update_base if (inventory_changed) gInventory.notifyObservers(); } +class RequestAgentUpdateAppearanceResponder: public LLHTTPClient::Responder +{ +public: + RequestAgentUpdateAppearanceResponder() {} + /*virtual*/ void error(U32 status, const std::string& reason) + { + llwarns << "appearance update request failed, reason: " << reason << llendl; + } +}; - +void LLAppearanceMgr::requestServerAppearanceUpdate() +{ + if (!gAgent.getRegion()) + { + llwarns << "Region not set, cannot request server appearance update" << llendl; + } + std::string url = gAgent.getRegion()->getCapability("UpdateAvatarAppearance"); + if (url.empty()) + { + llwarns << "no cap for UpdateAvatarAppearance" << llendl; + } + + LLSD body; + S32 cof_version = getCOFVersion(); + body["cof_version"] = cof_version; + LLHTTPClient::post(url, body, new RequestAgentUpdateAppearanceResponder); + llassert(cof_version >= mLastUpdateRequestCOFVersion); + mLastUpdateRequestCOFVersion = cof_version; +} class LLShowCreatedOutfit: public LLInventoryCallback { @@ -2795,7 +2840,8 @@ LLAppearanceMgr::LLAppearanceMgr(): mAttachmentInvLinkEnabled(false), mOutfitIsDirty(false), mOutfitLocked(false), - mIsInUpdateAppearanceFromCOF(false) + mIsInUpdateAppearanceFromCOF(false), + mLastUpdateRequestCOFVersion(LLViewerInventoryCategory::VERSION_UNKNOWN) { LLOutfitObserver& outfit_observer = LLOutfitObserver::instance(); diff --git a/indra/newview/llappearancemgr.h b/indra/newview/llappearancemgr.h index c1d561781d..742833211a 100644..100755 --- a/indra/newview/llappearancemgr.h +++ b/indra/newview/llappearancemgr.h @@ -93,6 +93,9 @@ public: // Find the Current Outfit folder. const LLUUID getCOF() const; + S32 getCOFVersion() const; + + S32 mLastUpdateRequestCOFVersion; // Finds the folder link to the currently worn outfit const LLViewerInventoryItem *getBaseOutfitLink(); @@ -182,6 +185,8 @@ public: bool isInUpdateAppearanceFromCOF() { return mIsInUpdateAppearanceFromCOF; } + void requestServerAppearanceUpdate(); + protected: LLAppearanceMgr(); ~LLAppearanceMgr(); diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index c9458857d1..6ca77ba4dd 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -636,7 +636,6 @@ LLAppViewer::LLAppViewer() : mForceGraphicsDetail(false), mQuitRequested(false), mLogoutRequestSent(false), - mYieldTime(-1), mMainloopTimeout(NULL), mAgentRegionLastAlive(false), mRandomizeFramerate(LLCachedControl<bool>(gSavedSettings,"Randomize Framerate", FALSE)), @@ -1207,7 +1206,7 @@ bool LLAppViewer::mainLoop() LLVoiceChannel::initClass(); LLVoiceClient::getInstance()->init(gServicePump); LLVoiceChannel::setCurrentVoiceChannelChangedCallback(boost::bind(&LLCallFloater::sOnCurrentChannelChanged, _1), true); - LLTimer frameTimer,idleTimer; + LLTimer frameTimer,idleTimer,periodicRenderingTimer; LLTimer debugTime; LLViewerJoystick* joystick(LLViewerJoystick::getInstance()); joystick->setNeedsReset(true); @@ -1219,6 +1218,8 @@ bool LLAppViewer::mainLoop() // point of posting. LLSD newFrame; + BOOL restore_rendering_masks = FALSE; + //LLPrivateMemoryPoolTester::getInstance()->run(false) ; //LLPrivateMemoryPoolTester::getInstance()->run(true) ; //LLPrivateMemoryPoolTester::destroy() ; @@ -1236,6 +1237,28 @@ bool LLAppViewer::mainLoop() try { + // Check if we need to restore rendering masks. + if (restore_rendering_masks) + { + gPipeline.popRenderDebugFeatureMask(); + gPipeline.popRenderTypeMask(); + } + // Check if we need to temporarily enable rendering. + F32 periodic_rendering = gSavedSettings.getF32("ForcePeriodicRenderingTime"); + if (periodic_rendering > F_APPROXIMATELY_ZERO && periodicRenderingTimer.getElapsedTimeF64() > periodic_rendering) + { + periodicRenderingTimer.reset(); + restore_rendering_masks = TRUE; + gPipeline.pushRenderTypeMask(); + gPipeline.pushRenderDebugFeatureMask(); + gPipeline.setAllRenderTypes(); + gPipeline.setAllRenderDebugFeatures(); + } + else + { + restore_rendering_masks = FALSE; + } + pingMainloopTimeout("Main:MiscNativeWindowEvents"); if (gViewerWindow) @@ -1358,10 +1381,11 @@ bool LLAppViewer::mainLoop() LLFastTimer t2(FTM_SLEEP); // yield some time to the os based on command line option - if(mYieldTime >= 0) + S32 yield_time = gSavedSettings.getS32("YieldTime"); + if(yield_time >= 0) { LLFastTimer t(FTM_YIELD); - ms_sleep(mYieldTime); + ms_sleep(yield_time); } // yield cooperatively when not running as foreground window @@ -1473,6 +1497,26 @@ bool LLAppViewer::mainLoop() { gFrameStalls++; } + + // Limit FPS + F32 max_fps = gSavedSettings.getF32("MaxFPS"); + // Only limit FPS when we are actually rendering something. Otherwise + // logins, logouts and teleports take much longer to complete. + if (max_fps > F_APPROXIMATELY_ZERO && + LLStartUp::getStartupState() == STATE_STARTED && + !gTeleportDisplay && + !logoutRequestSent()) + { + // Sleep a while to limit frame rate. + F32 min_frame_time = 1.f / max_fps; + S32 milliseconds_to_sleep = llclamp((S32)((min_frame_time - frameTimer.getElapsedTimeF64()) * 1000.f), 0, 1000); + if (milliseconds_to_sleep > 0) + { + LLFastTimer t(FTM_YIELD); + ms_sleep(milliseconds_to_sleep); + } + } + frameTimer.reset(); resumeMainloopTimeout(); @@ -2587,8 +2631,6 @@ bool LLAppViewer::initConfiguration() } } - mYieldTime = gSavedSettings.getS32("YieldTime"); - // Read skin/branding settings if specified. //if (! gDirUtilp->getSkinDir().empty() ) //{ diff --git a/indra/newview/llappviewer.h b/indra/newview/llappviewer.h index ae3c795d1e..043893020b 100644 --- a/indra/newview/llappviewer.h +++ b/indra/newview/llappviewer.h @@ -253,7 +253,6 @@ private: bool mQuitRequested; // User wants to quit, may have modified documents open. bool mLogoutRequestSent; // Disconnect message sent to simulator, no longer safe to send messages to the sim. - S32 mYieldTime; struct SettingsFiles* mSettingsLocationList; LLWatchdogTimeout* mMainloopTimeout; diff --git a/indra/newview/lldynamictexture.cpp b/indra/newview/lldynamictexture.cpp index fa42b157a7..fa42b157a7 100644..100755 --- a/indra/newview/lldynamictexture.cpp +++ b/indra/newview/lldynamictexture.cpp diff --git a/indra/newview/llmorphview.cpp b/indra/newview/llmorphview.cpp index eaa044cb59..252d1b78ea 100644 --- a/indra/newview/llmorphview.cpp +++ b/indra/newview/llmorphview.cpp @@ -99,8 +99,6 @@ void LLMorphView::initialize() //----------------------------------------------------------------------------- void LLMorphView::shutdown() { - LLVOAvatarSelf::onCustomizeEnd(); - if (isAgentAvatarValid()) { gAgentAvatarp->startMotion( ANIM_AGENT_BODY_NOISE ); diff --git a/indra/newview/llpipelinelistener.cpp b/indra/newview/llpipelinelistener.cpp new file mode 100644 index 0000000000..20759239bf --- /dev/null +++ b/indra/newview/llpipelinelistener.cpp @@ -0,0 +1,216 @@ +/** + * @file llpipelinelistener.h + * @author Don Kjer + * @date 2012-07-09 + * @brief Implementation for LLPipelineListener + * + * $LicenseInfo:firstyear=2012&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2012, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +// Precompiled header +#include "llviewerprecompiledheaders.h" + +#include "llpipelinelistener.h" + +#include "pipeline.h" +#include "stringize.h" +#include <sstream> +#include "llviewermenu.h" + + +namespace { + // Render Types + void toggle_render_types_wrapper(LLSD const& request) + { + for (LLSD::array_const_iterator iter = request["types"].beginArray(); + iter != request["types"].endArray(); + ++iter) + { + U32 render_type = render_type_from_string( iter->asString() ); + if ( render_type != 0 ) + { + LLPipeline::toggleRenderTypeControl( (void*) render_type ); + } + } + } + + void has_render_type_wrapper(LLSD const& request) + { + LLEventAPI::Response response(LLSD(), request); + U32 render_type = render_type_from_string( request["type"].asString() ); + if ( render_type != 0 ) + { + response["value"] = LLPipeline::hasRenderTypeControl( (void*) render_type ); + } + else + { + response.error(STRINGIZE("unknown type '" << request["type"].asString() << "'")); + } + } + + void disable_all_render_types_wrapper(LLSD const& request) + { + gPipeline.clearAllRenderTypes(); + } + + void enable_all_render_types_wrapper(LLSD const& request) + { + gPipeline.setAllRenderTypes(); + } + + // Render Features + void toggle_render_features_wrapper(LLSD const& request) + { + for (LLSD::array_const_iterator iter = request["features"].beginArray(); + iter != request["features"].endArray(); + ++iter) + { + U32 render_feature = feature_from_string( iter->asString() ); + if ( render_feature != 0 ) + { + LLPipeline::toggleRenderDebugControl( (void*) render_feature ); + } + } + } + + void has_render_feature_wrapper(LLSD const& request) + { + LLEventAPI::Response response(LLSD(), request); + U32 render_feature = feature_from_string( request["feature"].asString() ); + if ( render_feature != 0 ) + { + response["value"] = gPipeline.hasRenderDebugFeatureMask(render_feature); + } + else + { + response.error(STRINGIZE("unknown feature '" << request["feature"].asString() << "'")); + } + } + + void disable_all_render_features_wrapper(LLSD const& request) + { + gPipeline.clearAllRenderDebugFeatures(); + } + + void enable_all_render_features_wrapper(LLSD const& request) + { + gPipeline.setAllRenderDebugFeatures(); + } + + // Render Info Displays + void toggle_info_displays_wrapper(LLSD const& request) + { + for (LLSD::array_const_iterator iter = request["displays"].beginArray(); + iter != request["displays"].endArray(); + ++iter) + { + U32 info_display = info_display_from_string( iter->asString() ); + if ( info_display != 0 ) + { + LLPipeline::toggleRenderDebug( (void*) info_display ); + } + } + } + + void has_info_display_wrapper(LLSD const& request) + { + LLEventAPI::Response response(LLSD(), request); + U32 info_display = info_display_from_string( request["display"].asString() ); + if ( info_display != 0 ) + { + response["value"] = gPipeline.hasRenderDebugMask(info_display); + } + else + { + response.error(STRINGIZE("unknown display '" << request["display"].asString() << "'")); + } + } + + void disable_all_info_displays_wrapper(LLSD const& request) + { + gPipeline.clearAllRenderDebugDisplays(); + } + + void enable_all_info_displays_wrapper(LLSD const& request) + { + gPipeline.setAllRenderDebugDisplays(); + } + +} + + +LLPipelineListener::LLPipelineListener(): + LLEventAPI("LLPipeline", + "API to te rendering pipeline.") +{ + // Render Types + add("toggleRenderTypes", + "Toggle rendering [\"types\"]:\n" + "See: llviewermenu.cpp:render_type_from_string for list of available types.", + &toggle_render_types_wrapper); + add("hasRenderType", + "Check if rendering [\"type\"] is enabled:\n" + "See: llviewermenu.cpp:render_type_from_string for list of available types.", + &has_render_type_wrapper, + LLSDMap("reply", LLSD())); + add("disableAllRenderTypes", + "Turn off all rendering types.", + &disable_all_render_types_wrapper); + add("enableAllRenderTypes", + "Turn on all rendering types.", + &enable_all_render_types_wrapper); + + // Render Features + add("toggleRenderFeatures", + "Toggle rendering [\"features\"]:\n" + "See: llviewermenu.cpp:feature_from_string for list of available features.", + &toggle_render_features_wrapper); + add("hasRenderFeature", + "Check if rendering [\"feature\"] is enabled:\n" + "See: llviewermenu.cpp:render_feature_from_string for list of available features.", + &has_render_feature_wrapper, + LLSDMap("reply", LLSD())); + add("disableAllRenderFeatures", + "Turn off all rendering features.", + &disable_all_render_features_wrapper); + add("enableAllRenderFeatures", + "Turn on all rendering features.", + &enable_all_render_features_wrapper); + + // Render Info Displays + add("toggleRenderInfoDisplays", + "Toggle info [\"displays\"]:\n" + "See: llviewermenu.cpp:info_display_from_string for list of available displays.", + &toggle_info_displays_wrapper); + add("hasRenderInfoDisplay", + "Check if info [\"display\"] is enabled:\n" + "See: llviewermenu.cpp:info_display_from_string for list of available displays.", + &has_info_display_wrapper, + LLSDMap("reply", LLSD())); + add("disableAllRenderInfoDisplays", + "Turn off all info displays.", + &disable_all_info_displays_wrapper); + add("enableAllRenderInfoDisplays", + "Turn on all info displays.", + &enable_all_info_displays_wrapper); +} + diff --git a/indra/newview/llpipelinelistener.h b/indra/newview/llpipelinelistener.h new file mode 100644 index 0000000000..da1898e57b --- /dev/null +++ b/indra/newview/llpipelinelistener.h @@ -0,0 +1,41 @@ +/** + * @file llpipelinelistener.h + * @author Don Kjer + * @date 2012-07-09 + * @brief Wrap subset of LLPipeline API in event API + * + * $LicenseInfo:firstyear=2012&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 ! defined(LL_LLPIPELINELISTENER_H) +#define LL_LLPIPELINELISTENER_H + +#include "lleventapi.h" + +/// Listen on an LLEventPump with specified name for LLPipeline request events. +class LLPipelineListener: public LLEventAPI +{ +public: + LLPipelineListener(); +}; + +#endif /* ! defined(LL_LLPIPELINELISTENER_H) */ diff --git a/indra/newview/llsidepanelappearance.cpp b/indra/newview/llsidepanelappearance.cpp index 853656905c..9267444534 100644 --- a/indra/newview/llsidepanelappearance.cpp +++ b/indra/newview/llsidepanelappearance.cpp @@ -206,12 +206,9 @@ void LLSidepanelAppearance::updateToVisibility(const LLSD &new_visibility) } // Disable camera switch is currently just for WT_PHYSICS type since we don't want to freeze the avatar // when editing its physics. - const BOOL disable_camera_motion = LLWearableType::getDisableCameraSwitch(wearable_ptr->getType()); - if (!gAgentCamera.cameraCustomizeAvatar() && - !disable_camera_motion && - gSavedSettings.getBOOL("AppearanceCameraMovement")) + if (!gAgentCamera.cameraCustomizeAvatar()) { - gAgentCamera.changeCameraToCustomizeAvatar(); + LLVOAvatarSelf::onCustomizeStart(LLWearableType::getDisableCameraSwitch(wearable_ptr->getType())); } if (is_wearable_edit_visible) { @@ -283,7 +280,7 @@ void LLSidepanelAppearance::onEditAppearanceButtonClicked() { if (gAgentWearables.areWearablesLoaded()) { - gAgentCamera.changeCameraToCustomizeAvatar(); + LLVOAvatarSelf::onCustomizeStart(); } } @@ -371,15 +368,14 @@ void LLSidepanelAppearance::toggleOutfitEditPanel(BOOL visible, BOOL disable_cam if (visible) { mOutfitEdit->onOpen(LLSD()); - if (!disable_camera_switch && gSavedSettings.getBOOL("AppearanceCameraMovement") ) - { - gAgentCamera.changeCameraToCustomizeAvatar(); - } + LLVOAvatarSelf::onCustomizeStart(disable_camera_switch); } - else if (!disable_camera_switch && gSavedSettings.getBOOL("AppearanceCameraMovement") ) + else { - gAgentCamera.changeCameraToDefault(); - gAgentCamera.resetView(); + if (!disable_camera_switch) // if we're just switching between outfit and wearable editing, don't end customization. + { + LLVOAvatarSelf::onCustomizeEnd(disable_camera_switch); + } } } @@ -405,10 +401,7 @@ void LLSidepanelAppearance::toggleWearableEditPanel(BOOL visible, LLWearable *we if (visible) { - if (!disable_camera_switch && gSavedSettings.getBOOL("AppearanceCameraMovement") ) - { - gAgentCamera.changeCameraToCustomizeAvatar(); - } + LLVOAvatarSelf::onCustomizeStart(disable_camera_switch); mEditWearable->setWearable(wearable, disable_camera_switch); mEditWearable->onOpen(LLSD()); // currently no-op, just for consistency } @@ -416,10 +409,9 @@ void LLSidepanelAppearance::toggleWearableEditPanel(BOOL visible, LLWearable *we { // Save changes if closing. mEditWearable->saveChanges(); - if (!disable_camera_switch && gSavedSettings.getBOOL("AppearanceCameraMovement") ) + if (!disable_camera_switch) // if we're just switching between outfit and wearable editing, don't end customization. { - gAgentCamera.changeCameraToDefault(); - gAgentCamera.resetView(); + LLVOAvatarSelf::onCustomizeEnd(disable_camera_switch); } } } diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp index 42648b82c2..6782e3ef8a 100755 --- a/indra/newview/llstartup.cpp +++ b/indra/newview/llstartup.cpp @@ -3452,6 +3452,14 @@ bool process_login_success_response() } + // set the location of the Agent Appearance service, from which we can request + // avatar baked textures if they are supported by the current region + std::string agent_appearance_url = response["agent_appearance_service"]; + if (!agent_appearance_url.empty()) + { + gSavedSettings.setString("AgentAppearanceServiceURL", agent_appearance_url); + } + // Set the location of the snapshot sharing config endpoint std::string snapshot_config_url = response["snapshot_config_url"]; if(!snapshot_config_url.empty()) diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp index d58ee05fb6..3b486efd7e 100644 --- a/indra/newview/llviewerdisplay.cpp +++ b/indra/newview/llviewerdisplay.cpp @@ -1063,7 +1063,7 @@ void render_hud_attachments() gPipeline.pushRenderTypeMask(); // turn off everything - gPipeline.andRenderTypeMask(LLPipeline::END_RENDER_TYPES); + gPipeline.clearAllRenderTypes(); // turn on HUD gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_HUD); // turn on HUD particles diff --git a/indra/newview/llviewermenu.h b/indra/newview/llviewermenu.h index 3515aa4302..885a0721c0 100644 --- a/indra/newview/llviewermenu.h +++ b/indra/newview/llviewermenu.h @@ -139,6 +139,11 @@ bool handle_go_to(); // Export to XML or Collada void handle_export_selected( void * ); +// Convert strings to internal types +U32 render_type_from_string(std::string render_type); +U32 feature_from_string(std::string feature); +U32 info_display_from_string(std::string info_display); + class LLViewerMenuHolderGL : public LLMenuHolderGL { public: diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp index 4ad0547379..fe0141e307 100644 --- a/indra/newview/llviewerobject.cpp +++ b/indra/newview/llviewerobject.cpp @@ -4056,6 +4056,23 @@ void LLViewerObject::setTEImage(const U8 te, LLViewerTexture *imagep) } +S32 LLViewerObject::setTETextureCore(const U8 te, const LLUUID& uuid, const std::string &url ) +{ + S32 retval = 0; + if (uuid != getTE(te)->getID() || + uuid == LLUUID::null) + { + retval = LLPrimitive::setTETexture(te, uuid); + mTEImages[te] = LLViewerTextureManager::getFetchedTextureFromUrl (url, TRUE, LLViewerTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE, 0, 0, uuid); + setChanged(TEXTURE); + if (mDrawable.notNull()) + { + gPipeline.markTextured(mDrawable); + } + } + return retval; +} + S32 LLViewerObject::setTETextureCore(const U8 te, const LLUUID& uuid, LLHost host) { S32 retval = 0; diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h index e60c8a8d52..dc8c7deea9 100644 --- a/indra/newview/llviewerobject.h +++ b/indra/newview/llviewerobject.h @@ -301,6 +301,7 @@ public: /*virtual*/ void setTE(const U8 te, const LLTextureEntry &texture_entry); /*virtual*/ S32 setTETexture(const U8 te, const LLUUID &uuid); S32 setTETextureCore(const U8 te, const LLUUID& uuid, LLHost host); + S32 setTETextureCore(const U8 te, const LLUUID& uuid, const std::string &url ); /*virtual*/ S32 setTEColor(const U8 te, const LLColor3 &color); /*virtual*/ S32 setTEColor(const U8 te, const LLColor4 &color); /*virtual*/ S32 setTEScale(const U8 te, const F32 s, const F32 t); diff --git a/indra/newview/llviewerobjectlist.cpp b/indra/newview/llviewerobjectlist.cpp index e399b45cba..c036fcc114 100644 --- a/indra/newview/llviewerobjectlist.cpp +++ b/indra/newview/llviewerobjectlist.cpp @@ -1524,6 +1524,7 @@ static LLFastTimer::DeclareTimer FTM_REGION_SHIFT("Region Shift"); void LLViewerObjectList::shiftObjects(const LLVector3 &offset) { + if (gHeadlessClient) return; // This is called when we shift our origin when we cross region boundaries... // We need to update many object caches, I'll document this more as I dig through the code // cleaning things out... diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp index 05c7ef5381..c6f1be4483 100644 --- a/indra/newview/llviewerregion.cpp +++ b/indra/newview/llviewerregion.cpp @@ -1450,6 +1450,18 @@ void LLViewerRegion::unpackRegionHandshake() mProductName = productName; } + + mCentralBakeVersion = (S32)gSavedSettings.getBOOL("UseServerTextureBaking"); + /* + if (msg->getSize("RegionInfo4", "CentralBakesVersion") > 0) + { + msg->getS32("RegionInfo4", "CentralBakesVersion", mCentralBakeVersion); + } + else + { + mCentralBakeVersion = 0; + } + */ LLVLComposition *compp = getComposition(); if (compp) { @@ -1578,6 +1590,7 @@ void LLViewerRegionImpl::buildCapabilityNames(LLSD& capabilityNames) capabilityNames.append("UntrustedSimulatorMessage"); capabilityNames.append("UpdateAgentInformation"); capabilityNames.append("UpdateAgentLanguage"); + capabilityNames.append("UpdateAvatarAppearance"); capabilityNames.append("UpdateGestureAgentInventory"); capabilityNames.append("UpdateNotecardAgentInventory"); capabilityNames.append("UpdateScriptAgent"); diff --git a/indra/newview/llviewerregion.h b/indra/newview/llviewerregion.h index c9fffaf30e..2ddb17f171 100644 --- a/indra/newview/llviewerregion.h +++ b/indra/newview/llviewerregion.h @@ -278,6 +278,8 @@ public: F32 getLandHeightRegion(const LLVector3& region_pos); + U8 getCentralBakeVersion() { return mCentralBakeVersion; } + void getInfo(LLSD& info); bool meshRezEnabled() const; @@ -395,6 +397,7 @@ private: F32 mBillableFactor; U32 mMaxTasks; // max prim count F32 mCameraDistanceSquared; // updated once per frame + U8 mCentralBakeVersion; // Information for Homestead / CR-53 S32 mClassID; diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index 1798d554b9..4aabbd6bb6 100755 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -1717,6 +1717,7 @@ LLViewerWindow::LLViewerWindow(const Params& p) void LLViewerWindow::initGLDefaults() { + if (gHeadlessClient) return; gGL.setSceneBlendType(LLRender::BT_ALPHA); if (!LLGLSLShader::sNoFixedFunction) diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index 366b6004be..4894f21e67 100755 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -688,12 +688,13 @@ LLVOAvatar::LLVOAvatar(const LLUUID& id, mFullyLoaded(FALSE), mPreviousFullyLoaded(FALSE), mFullyLoadedInitialized(FALSE), - mSupportsAlphaLayers(FALSE), mLoadedCallbacksPaused(FALSE), mHasPelvisOffset( FALSE ), mRenderUnloadedAvatar(LLCachedControl<bool>(gSavedSettings, "RenderUnloadedAvatar")), - mLastRezzedStatus(-1) - + mLastRezzedStatus(-1), + mIsEditingAppearance(FALSE), + mUseLocalAppearance(FALSE), + mUseServerBakes(TRUE) { LLMemType mt(LLMemType::MTYPE_AVATAR); //VTResume(); // VTune @@ -2381,6 +2382,12 @@ S32 LLVOAvatar::setTETexture(const U8 te, const LLUUID& uuid) // to redirect certain avatar texture requests to different sims. if (isIndexBakedTexture((ETextureIndex)te)) { + const std::string url = getImageURL(te,uuid); + if (!url.empty()) + { + return setTETextureCore(te, uuid, url); + } + LLHost target_host = getObjectHost(); return setTETextureCore(te, uuid, target_host); } @@ -4149,7 +4156,7 @@ void LLVOAvatar::updateVisibility() // private bool LLVOAvatar::shouldAlphaMask() { - const bool should_alpha_mask = mSupportsAlphaLayers && !LLDrawPoolAlpha::sShowDebugAlpha // Don't alpha mask if "Highlight Transparent" checked + const bool should_alpha_mask = !LLDrawPoolAlpha::sShowDebugAlpha // Don't alpha mask if "Highlight Transparent" checked && !LLDrawPoolAvatar::sSkipTransparent; return should_alpha_mask; @@ -4588,6 +4595,7 @@ void LLVOAvatar::updateTextures() if (isIndexBakedTexture((ETextureIndex)texture_index) && imagep->getID() != IMG_DEFAULT_AVATAR && imagep->getID() != IMG_INVISIBLE + && !mUseServerBakes && !imagep->getTargetHost().isOk()) { LL_WARNS_ONCE("Texture") << "LLVOAvatar::updateTextures No host for texture " @@ -4682,7 +4690,10 @@ void LLVOAvatar::addBakedTextureStats( LLViewerFetchedTexture* imagep, F32 pixel //the texture pipeline will stop fetching this texture. imagep->resetTextureStats(); - imagep->setCanUseHTTP(false) ; //turn off http fetching for baked textures. + // TODO: currently default to HTTP texture and fall back to UDP if cannot be found there. + // Once server messaging is in place, we should call setCanUseHTTP(false) for old style + // appearance requests + imagep->setCanUseHTTP(true); imagep->setMaxVirtualSizeResetInterval(MAX_TEXTURE_VIRTURE_SIZE_RESET_INTERVAL); imagep->resetMaxVirtualSizeResetCounter() ; @@ -4724,6 +4735,21 @@ void LLVOAvatar::setTexEntry(const U8 index, const LLTextureEntry &te) setTE(index, te); } +const std::string LLVOAvatar::getImageURL(const U8 te, const LLUUID &uuid) +{ + std::string url = ""; + if (mUseServerBakes && !gSavedSettings.getString("AgentAppearanceServiceURL").empty()) + { + const LLVOAvatarDictionary::TextureEntry* texture_entry = LLVOAvatarDictionary::getInstance()->getTexture((ETextureIndex)te); + if (texture_entry != NULL) + { + url = gSavedSettings.getString("AgentAppearanceServiceURL") + "texture/" + getID().asString() + "/" + texture_entry->mDefaultImageName + "/" + uuid.asString(); + //llinfos << "baked texture url: " << url << llendl; + } + } + return url; +} + //----------------------------------------------------------------------------- // resolveHeight() //----------------------------------------------------------------------------- @@ -6669,7 +6695,6 @@ void LLVOAvatar::updateMeshTextures() } } - const BOOL self_customizing = isSelf() && gAgentCamera.cameraCustomizeAvatar(); // During face edit mode, we don't use baked textures const BOOL other_culled = !isSelf() && mCulled; LLLoadedCallbackEntry::source_callback_list_t* src_callback_list = NULL ; BOOL paused = FALSE; @@ -6709,36 +6734,39 @@ void LLVOAvatar::updateMeshTextures() { use_lkg_baked_layer[i] = (!is_layer_baked[i] && mBakedTextureDatas[i].mLastTextureIndex != IMG_DEFAULT_AVATAR); - if (mBakedTextureDatas[i].mTexLayerSet) - { - mBakedTextureDatas[i].mTexLayerSet->destroyComposite(); - } } } - - // Turn on alpha masking correctly for yourself and other avatars on 1.23+ - mSupportsAlphaLayers = isSelf() || is_layer_baked[BAKED_HAIR]; - - // Baked textures should be requested from the sim this avatar is on. JC - const LLHost target_host = getObjectHost(); - if (!target_host.isOk()) - { - llwarns << "updateMeshTextures: invalid host for object: " << getID() << llendl; - } for (U32 i=0; i < mBakedTextureDatas.size(); i++) { - if (use_lkg_baked_layer[i] && !self_customizing ) + if (use_lkg_baked_layer[i] && !mUseLocalAppearance ) { - LLViewerFetchedTexture* baked_img = LLViewerTextureManager::getFetchedTextureFromHost( mBakedTextureDatas[i].mLastTextureIndex, target_host ); + LLViewerFetchedTexture* baked_img; + const std::string url = getImageURL(i, mBakedTextureDatas[i].mLastTextureIndex); + if (!url.empty()) + { + baked_img = LLViewerTextureManager::getFetchedTextureFromUrl(url, TRUE, LLViewerTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE, 0, 0, mBakedTextureDatas[i].mLastTextureIndex); + } + else + { + // Baked textures should be requested from the sim this avatar is on. JC + const LLHost target_host = getObjectHost(); + if (!target_host.isOk()) + { + llwarns << "updateMeshTextures: invalid host for object: " << getID() << llendl; + } + + baked_img = LLViewerTextureManager::getFetchedTextureFromHost( mBakedTextureDatas[i].mLastTextureIndex, target_host ); + } + mBakedTextureDatas[i].mIsUsed = TRUE; for (U32 k=0; k < mBakedTextureDatas[i].mMeshes.size(); k++) { mBakedTextureDatas[i].mMeshes[k]->setTexture( baked_img ); } } - else if (!self_customizing && is_layer_baked[i]) + else if (!mUseLocalAppearance && is_layer_baked[i]) { LLViewerFetchedTexture* baked_img = LLViewerTextureManager::staticCastToFetchedTexture(getImage( mBakedTextureDatas[i].mTextureIndex, 0 ), TRUE) ; if( baked_img->getID() == mBakedTextureDatas[i].mLastTextureIndex ) @@ -6758,8 +6786,7 @@ void LLVOAvatar::updateMeshTextures() src_callback_list, paused ); } } - else if (mBakedTextureDatas[i].mTexLayerSet - && !other_culled) + else if (mBakedTextureDatas[i].mTexLayerSet && mUseLocalAppearance) { mBakedTextureDatas[i].mTexLayerSet->createComposite(); mBakedTextureDatas[i].mTexLayerSet->setUpdatesEnabled( TRUE ); @@ -6774,7 +6801,7 @@ void LLVOAvatar::updateMeshTextures() // set texture and color of hair manually if we are not using a baked image. // This can happen while loading hair for yourself, or for clients that did not // bake a hair texture. Still needed for yourself after 1.22 is depricated. - if (!is_layer_baked[BAKED_HAIR] || self_customizing) + if (!is_layer_baked[BAKED_HAIR] || mIsEditingAppearance) { const LLColor4 color = mTexHairColor ? mTexHairColor->getColor() : LLColor4(1,1,1,1); LLViewerTexture* hair_img = getImage( TEX_HAIR, 0 ); @@ -7309,7 +7336,7 @@ void LLVOAvatar::processAvatarAppearance( LLMessageSystem* mesgsys ) if( isSelf() ) { llwarns << avString() << "Received AvatarAppearance for self" << llendl; - if( mFirstTEMessageReceived ) + if( mFirstTEMessageReceived && !mUseServerBakes) { // llinfos << "processAvatarAppearance end " << mID << llendl; return; @@ -7320,9 +7347,44 @@ void LLVOAvatar::processAvatarAppearance( LLMessageSystem* mesgsys ) // llinfos << "LLVOAvatar::processAvatarAppearance()" << llendl; // dumpAvatarTEs( "PRE processAvatarAppearance()" ); - unpackTEMessage(mesgsys, _PREHASH_ObjectData); + LLTEContents tec; + parseTEMessage(mesgsys, _PREHASH_ObjectData, -1, tec); // dumpAvatarTEs( "POST processAvatarAppearance()" ); + U8 appearance_version = 0; + S32 this_update_cof_version = LLViewerInventoryCategory::VERSION_UNKNOWN; + S32 last_update_request_cof_version = LLAppearanceMgr::instance().mLastUpdateRequestCOFVersion; + // For future use: + //U32 appearance_flags = 0; + + if (mesgsys->has(_PREHASH_AppearanceData)) + { + mesgsys->getU8Fast(_PREHASH_AppearanceData, _PREHASH_AppearanceVersion, appearance_version, 0); + mesgsys->getS32Fast(_PREHASH_AppearanceData, _PREHASH_CofVersion, this_update_cof_version, 0); + // For future use: + //mesgsys->getU32Fast(_PREHASH_AppearanceData, _PREHASH_Flags, appearance_flags, 0); + } + + if (appearance_version > 0) + { + mUseServerBakes = true; + } + else + { + mUseServerBakes = false; + } + + // Check for stale update. + if (mUseServerBakes && isSelf() + && this_update_cof_version >= LLViewerInventoryCategory::VERSION_INITIAL + && this_update_cof_version < last_update_request_cof_version) + { + llwarns << "Stale appearance update, wanted version " << last_update_request_cof_version + << ", got " << this_update_cof_version << llendl; + return; + } + applyParsedTEMessage(tec); + // prevent the overwriting of valid baked textures with invalid baked textures for (U8 baked_index = 0; baked_index < mBakedTextureDatas.size(); baked_index++) { @@ -7345,16 +7407,8 @@ void LLVOAvatar::processAvatarAppearance( LLMessageSystem* mesgsys ) } setCompositeUpdatesEnabled( FALSE ); - mMeshTexturesDirty = TRUE; gPipeline.markGLRebuild(this); - // ! BACKWARDS COMPATIBILITY ! - // Non-self avatars will no longer have component textures - if (!isSelf()) - { - releaseComponentTextures(); - } - // parse visual params S32 num_blocks = mesgsys->getNumberOfBlocksFast(_PREHASH_VisualParam); bool drop_visual_params_debug = gSavedSettings.getBOOL("BlockSomeAvatarAppearanceVisualParams") && (ll_rand(2) == 0); // pretend that ~12% of AvatarAppearance messages arrived without a VisualParam block, for testing @@ -7464,6 +7518,13 @@ void LLVOAvatar::processAvatarAppearance( LLMessageSystem* mesgsys ) // If all of the avatars are completely baked, release the global image caches to conserve memory. LLVOAvatar::cullAvatarsByPixelArea(); + if (isSelf()) + { + mUseLocalAppearance = false; + } + + updateMeshTextures(); + // llinfos << "processAvatarAppearance end " << mID << llendl; } diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h index 1adb680962..3f65dec11c 100755 --- a/indra/newview/llvoavatar.h +++ b/indra/newview/llvoavatar.h @@ -227,9 +227,6 @@ public: private: //aligned members LL_ALIGN_16(LLVector4a mImpostorExtents[2]); -private: - BOOL mSupportsAlphaLayers; // For backwards compatibility, TRUE for 1.23+ clients - //-------------------------------------------------------------------- // Updates //-------------------------------------------------------------------- @@ -617,6 +614,7 @@ protected: private: virtual void setImage(const U8 te, LLViewerTexture *imagep, const U32 index); virtual LLViewerTexture* getImage(const U8 te, const U32 index) const; + const std::string getImageURL(const U8 te, const LLUUID &uuid); virtual const LLTextureEntry* getTexEntry(const U8 te_num) const; virtual void setTexEntry(const U8 index, const LLTextureEntry &te); @@ -712,10 +710,14 @@ public: //-------------------------------------------------------------------- public: BOOL getIsAppearanceAnimating() const { return mAppearanceAnimating; } + BOOL isUsingBakedTextures() const { return mUseServerBakes; } // e.g. false if in appearance edit mode private: BOOL mAppearanceAnimating; LLFrameTimer mAppearanceMorphTimer; F32 mLastAppearanceBlendTime; + BOOL mIsEditingAppearance; // flag for if we're actively in appearance editing mode + BOOL mUseLocalAppearance; // flag for if we're using a local composite + BOOL mUseServerBakes; // flag for if baked textures should be fetched from baking service (false if they're temporary uploads) //-------------------------------------------------------------------- // Clothing colors (convenience functions to access visual parameters) diff --git a/indra/newview/llvoavatardefines.cpp b/indra/newview/llvoavatardefines.cpp index 1ed4e3b61c..ef96a9e923 100644 --- a/indra/newview/llvoavatardefines.cpp +++ b/indra/newview/llvoavatardefines.cpp @@ -66,12 +66,12 @@ LLVOAvatarDictionary::Textures::Textures() addEntry(TEX_UPPER_TATTOO, new TextureEntry("upper_tattoo", TRUE, BAKED_NUM_INDICES, "", LLWearableType::WT_TATTOO)); addEntry(TEX_LOWER_TATTOO, new TextureEntry("lower_tattoo", TRUE, BAKED_NUM_INDICES, "", LLWearableType::WT_TATTOO)); - addEntry(TEX_HEAD_BAKED, new TextureEntry("head-baked", FALSE, BAKED_HEAD)); - addEntry(TEX_UPPER_BAKED, new TextureEntry("upper-baked", FALSE, BAKED_UPPER)); - addEntry(TEX_LOWER_BAKED, new TextureEntry("lower-baked", FALSE, BAKED_LOWER)); - addEntry(TEX_EYES_BAKED, new TextureEntry("eyes-baked", FALSE, BAKED_EYES)); - addEntry(TEX_HAIR_BAKED, new TextureEntry("hair-baked", FALSE, BAKED_HAIR)); - addEntry(TEX_SKIRT_BAKED, new TextureEntry("skirt-baked", FALSE, BAKED_SKIRT)); + addEntry(TEX_HEAD_BAKED, new TextureEntry("head-baked", FALSE, BAKED_HEAD, "head")); + addEntry(TEX_UPPER_BAKED, new TextureEntry("upper-baked", FALSE, BAKED_UPPER, "upper")); + addEntry(TEX_LOWER_BAKED, new TextureEntry("lower-baked", FALSE, BAKED_LOWER, "lower")); + addEntry(TEX_EYES_BAKED, new TextureEntry("eyes-baked", FALSE, BAKED_EYES, "eyes")); + addEntry(TEX_HAIR_BAKED, new TextureEntry("hair-baked", FALSE, BAKED_HAIR, "hair")); + addEntry(TEX_SKIRT_BAKED, new TextureEntry("skirt-baked", FALSE, BAKED_SKIRT, "skirt")); } LLVOAvatarDictionary::BakedTextures::BakedTextures() diff --git a/indra/newview/llvoavatarself.cpp b/indra/newview/llvoavatarself.cpp index 7a81063f83..3604a373ad 100755 --- a/indra/newview/llvoavatarself.cpp +++ b/indra/newview/llvoavatarself.cpp @@ -812,7 +812,7 @@ U32 LLVOAvatarSelf::processUpdateMessage(LLMessageSystem *mesgsys, updateMeshTextures(); // unpack the texture UUIDs to the texture slots - retval = unpackTEMessage(mesgsys, _PREHASH_ObjectData, block_num); + retval = unpackTEMessage(mesgsys, _PREHASH_ObjectData, (S32) block_num); // need to trigger a few operations to get the avatar to use the new bakes for (U32 i = 0; i < mBakedTextureDatas.size(); i++) @@ -885,7 +885,10 @@ void LLVOAvatarSelf::removeMissingBakedTextures() invalidateComposite(mBakedTextureDatas[i].mTexLayerSet, FALSE); } updateMeshTextures(); - requestLayerSetUploads(); + if (getRegion() && !getRegion()->getCentralBakeVersion()) + { + requestLayerSetUploads(); + } } } @@ -1628,7 +1631,7 @@ void LLVOAvatarSelf::invalidateComposite( LLTexLayerSet* layerset, BOOL upload_r layerset->requestUpdate(); layerset->invalidateMorphMasks(); - if( upload_result ) + if( upload_result && (getRegion() && !getRegion()->getCentralBakeVersion())) { llassert(isSelf()); @@ -2611,15 +2614,6 @@ void LLVOAvatarSelf::processRebakeAvatarTextures(LLMessageSystem* msg, void**) } } -BOOL LLVOAvatarSelf::isUsingBakedTextures() const -{ - // Composite textures are used during appearance mode. - if (gAgentCamera.cameraCustomizeAvatar()) - return FALSE; - - return TRUE; -} - void LLVOAvatarSelf::forceBakeAllTextures(bool slam_for_debug) { @@ -2700,19 +2694,44 @@ LLTexLayerSet* LLVOAvatarSelf::getLayerSet(EBakedTextureIndex baked_index) const // static -void LLVOAvatarSelf::onCustomizeStart() +void LLVOAvatarSelf::onCustomizeStart(bool disable_camera_switch) { - // We're no longer doing any baking or invalidating on entering - // appearance editing mode. Leaving function in place in case - // further changes require us to do something at this point - Nyx + if (isAgentAvatarValid()) + { + gAgentAvatarp->mIsEditingAppearance = true; + gAgentAvatarp->mUseLocalAppearance = true; + + if (gSavedSettings.getBOOL("AppearanceCameraMovement") && !disable_camera_switch) + { + gAgentCamera.changeCameraToCustomizeAvatar(); + } + + gAgentAvatarp->invalidateAll(); + gAgentAvatarp->updateMeshTextures(); + } } // static -void LLVOAvatarSelf::onCustomizeEnd() +void LLVOAvatarSelf::onCustomizeEnd(bool disable_camera_switch) { + if (isAgentAvatarValid()) { + gAgentAvatarp->mIsEditingAppearance = false; + if (gAgentAvatarp->getRegion() && !gAgentAvatarp->getRegion()->getCentralBakeVersion()) + { + gAgentAvatarp->mUseLocalAppearance = false; + } + gAgentAvatarp->invalidateAll(); + + if (gSavedSettings.getBOOL("AppearanceCameraMovement") && !disable_camera_switch) + { + gAgentCamera.changeCameraToDefault(); + gAgentCamera.resetView(); + } + + LLAppearanceMgr::instance().updateAppearanceFromCOF(); } } diff --git a/indra/newview/llvoavatarself.h b/indra/newview/llvoavatarself.h index 7bd0c0bf93..92d59dc9e1 100755 --- a/indra/newview/llvoavatarself.h +++ b/indra/newview/llvoavatarself.h @@ -239,7 +239,6 @@ public: void setCachedBakedTexture(LLVOAvatarDefines::ETextureIndex i, const LLUUID& uuid); void forceBakeAllTextures(bool slam_for_debug = false); static void processRebakeAvatarTextures(LLMessageSystem* msg, void**); - BOOL isUsingBakedTextures() const; // e.g. false if in appearance edit mode protected: /*virtual*/ void removeMissingBakedTextures(); @@ -340,8 +339,8 @@ private: **/ public: - static void onCustomizeStart(); - static void onCustomizeEnd(); + static void onCustomizeStart(bool disable_camera_switch = false); + static void onCustomizeEnd(bool disable_camera_switch = false); //-------------------------------------------------------------------- // Visibility diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index 9c36cfee59..b43bdb69f8 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -370,7 +370,7 @@ U32 LLVOVolume::processUpdateMessage(LLMessageSystem *mesgsys, // Unpack texture entry data // - S32 result = unpackTEMessage(mesgsys, _PREHASH_ObjectData, block_num); + S32 result = unpackTEMessage(mesgsys, _PREHASH_ObjectData, (S32) block_num); if (result & teDirtyBits) { updateTEData(); diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 75eb8c460e..0b98119b19 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -72,6 +72,7 @@ #include "llhudtext.h" #include "lllightconstants.h" #include "llmeshrepository.h" +#include "llpipelinelistener.h" #include "llresmgr.h" #include "llselectmgr.h" #include "llsky.h" @@ -378,6 +379,8 @@ BOOL LLPipeline::sMemAllocationThrottled = FALSE; S32 LLPipeline::sVisibleLightCount = 0; F32 LLPipeline::sMinRenderSize = 0.f; +// EventHost API LLPipeline listener. +static LLPipelineListener sPipelineListener; static LLCullResult* sCull = NULL; @@ -494,19 +497,29 @@ void LLPipeline::init() LLViewerStats::getInstance()->mTrianglesDrawnStat.reset(); resetFrameStats(); - for (U32 i = 0; i < NUM_RENDER_TYPES; ++i) + if (gSavedSettings.getBOOL("DisableAllRenderFeatures")) { - mRenderTypeEnabled[i] = TRUE; //all rendering types start enabled + clearAllRenderDebugFeatures(); } + else + { + setAllRenderDebugFeatures(); // By default, all debugging features on + } + clearAllRenderDebugDisplays(); // All debug displays off - mRenderDebugFeatureMask = 0xffffffff; // All debugging features on - mRenderDebugMask = 0; // All debug starts off - - // Don't turn on ground when this is set - // Mac Books with intel 950s need this - if(!gSavedSettings.getBOOL("RenderGround")) + if (gSavedSettings.getBOOL("DisableAllRenderTypes")) + { + clearAllRenderTypes(); + } + else { - toggleRenderType(RENDER_TYPE_GROUND); + setAllRenderTypes(); // By default, all rendering types start enabled + // Don't turn on ground when this is set + // Mac Books with intel 950s need this + if(!gSavedSettings.getBOOL("RenderGround")) + { + toggleRenderType(RENDER_TYPE_GROUND); + } } // make sure RenderPerformanceTest persists (hackity hack hack) @@ -1126,6 +1139,7 @@ void LLPipeline::releaseScreenBuffers() void LLPipeline::createGLBuffers() { + if (gHeadlessClient) return; stop_glerror(); LLMemType mt_cb(LLMemType::MTYPE_PIPELINE_CREATE_BUFFERS); assertInitialized(); @@ -6412,6 +6426,22 @@ void LLPipeline::setRenderDebugFeatureControl(U32 bit, bool value) } } +void LLPipeline::pushRenderDebugFeatureMask() +{ + mRenderDebugFeatureStack.push(mRenderDebugFeatureMask); +} + +void LLPipeline::popRenderDebugFeatureMask() +{ + if (mRenderDebugFeatureStack.empty()) + { + llerrs << "Depleted render feature stack." << llendl; + } + + mRenderDebugFeatureMask = mRenderDebugFeatureStack.top(); + mRenderDebugFeatureStack.pop(); +} + // static void LLPipeline::setRenderScriptedBeacons(BOOL val) { @@ -10387,6 +10417,22 @@ void LLPipeline::clearRenderTypeMask(U32 type, ...) } } +void LLPipeline::setAllRenderTypes() +{ + for (U32 i = 0; i < NUM_RENDER_TYPES; ++i) + { + mRenderTypeEnabled[i] = TRUE; + } +} + +void LLPipeline::clearAllRenderTypes() +{ + for (U32 i = 0; i < NUM_RENDER_TYPES; ++i) + { + mRenderTypeEnabled[i] = FALSE; + } +} + void LLPipeline::addDebugBlip(const LLVector3& position, const LLColor4& color) { DebugBlip blip(position, color); diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h index 0ecae40d49..68ae1e7050 100644 --- a/indra/newview/pipeline.h +++ b/indra/newview/pipeline.h @@ -305,20 +305,28 @@ public: BOOL hasRenderDebugFeatureMask(const U32 mask) const { return (mRenderDebugFeatureMask & mask) ? TRUE : FALSE; } BOOL hasRenderDebugMask(const U32 mask) const { return (mRenderDebugMask & mask) ? TRUE : FALSE; } - - + void setAllRenderDebugFeatures() { mRenderDebugFeatureMask = 0xffffffff; } + void clearAllRenderDebugFeatures() { mRenderDebugFeatureMask = 0x0; } + void setAllRenderDebugDisplays() { mRenderDebugMask = 0xffffffff; } + void clearAllRenderDebugDisplays() { mRenderDebugMask = 0x0; } BOOL hasRenderType(const U32 type) const; BOOL hasAnyRenderType(const U32 type, ...) const; void setRenderTypeMask(U32 type, ...); - void orRenderTypeMask(U32 type, ...); + // This is equivalent to 'setRenderTypeMask' + //void orRenderTypeMask(U32 type, ...); void andRenderTypeMask(U32 type, ...); void clearRenderTypeMask(U32 type, ...); + void setAllRenderTypes(); + void clearAllRenderTypes(); void pushRenderTypeMask(); void popRenderTypeMask(); + void pushRenderDebugFeatureMask(); + void popRenderDebugFeatureMask(); + static void toggleRenderType(U32 type); // For UI control of render features @@ -615,6 +623,7 @@ protected: U32 mRenderDebugFeatureMask; U32 mRenderDebugMask; + std::stack<U32> mRenderDebugFeatureStack; U32 mOldRenderDebugMask; diff --git a/scripts/messages/message_template.msg b/scripts/messages/message_template.msg index 2cb0a833d4..5b147db084 100644 --- a/scripts/messages/message_template.msg +++ b/scripts/messages/message_template.msg @@ -3571,6 +3571,12 @@ version 2.0 VisualParam Variable { ParamValue U8 } } + { + AppearanceData Variable + { AppearanceVersion U8 } + { CofVersion S32 } + { Flags U32 } + } } // AvatarSitResponse - response to a request to sit on an object diff --git a/scripts/messages/message_template.msg.sha1 b/scripts/messages/message_template.msg.sha1 index 6486d92851..9e3dd21fb0 100644 --- a/scripts/messages/message_template.msg.sha1 +++ b/scripts/messages/message_template.msg.sha1 @@ -1 +1 @@ -465164e1a07f63d68c4ad1f00c19805dfb6ee2d7
\ No newline at end of file +ac4e232bd595c8dd31bc67fd77bcf68d8e9e837c
\ No newline at end of file |