# Conflicts:
#	autobuild.xml
#	doc/contributions.txt
#	indra/llcommon/tests/llprocess_test.cpp
#	indra/newview/lldrawpoolavatar.cpp
#	indra/newview/llfloatermodelpreview.cpp
#	indra/newview/llmodelpreview.cpp
#	indra/newview/llviewertexturelist.cpp
#	indra/newview/llvovolume.cpp
#	indra/newview/viewer_manifest.py
master
Ansariel 2022-03-02 10:12:19 +01:00
commit ef88337eef
265 changed files with 4821 additions and 2708 deletions

View File

@ -16,6 +16,9 @@ build_Linux_Doxygen = true
# Need viewer-build-variables as well as other shared repositories
buildscripts_shared_more_NAMEs="build_secrets build_variables git_hooks"
# Python 3 / SL-15742
BUILDSCRIPTS_PY3 = "true"
################################################################
#### Examples of how to set the viewer_channel ####
#
@ -36,6 +39,7 @@ buildscripts_shared_more_NAMEs="build_secrets build_variables git_hooks"
################################################################
viewer_channel = "Second Life Test"
################################################################
# Special packaging parameters.
# These parameters can be used to create additional packages

View File

@ -2401,18 +2401,18 @@
<key>archive</key>
<map>
<key>hash</key>
<string>35f42f538f4dc3abdfc2b2c4a915d004</string>
<string>95cb09a712b7b61e992fe68ab7bf8c72</string>
<key>hash_algorithm</key>
<string>md5</string>
<key>url</key>
<string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/87228/802959/llca-202109010216.563493-common-563493.tar.bz2</string>
<string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/92744/837149/llca-202201010217.567162-common-567162.tar.bz2</string>
</map>
<key>name</key>
<string>common</string>
</map>
</map>
<key>version</key>
<string>202109010216.563493</string>
<string>202201010217.567162</string>
</map>
<key>llphysicsextensions_source</key>
<map>
@ -2431,9 +2431,9 @@
<key>archive</key>
<map>
<key>hash</key>
<string>14fac452271ebfba37ba5ddcf5bffa54</string>
<string>da57838d80cf332f4a3026713a13f086</string>
<key>url</key>
<string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/54842/510078/llphysicsextensions_source-1.0.538972-darwin64-538972.tar.bz2</string>
<string>https://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/90708/824484/llphysicsextensions_source-1.0.565754-darwin64-565754.tar.bz2</string>
</map>
<key>name</key>
<string>darwin64</string>
@ -2455,16 +2455,16 @@
<key>archive</key>
<map>
<key>hash</key>
<string>f3c066c1aebed8a6519a3e5ce64b9a3c</string>
<string>28ad884012aa0bb70cf4101853af2f9a</string>
<key>url</key>
<string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/54982/511796/llphysicsextensions_source-1.0.538972-windows-538972.tar.bz2</string>
<string>https://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/90733/824570/llphysicsextensions_source-1.0.565768-windows-565768.tar.bz2</string>
</map>
<key>name</key>
<string>windows</string>
</map>
</map>
<key>version</key>
<string>1.0.538972</string>
<string>1.0.565768</string>
</map>
<key>llphysicsextensions_stub</key>
<map>
@ -3502,9 +3502,9 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
<key>archive</key>
<map>
<key>hash</key>
<string>c42575ac8997de979eadb082c33a578e</string>
<string>b97d0f6570104277de92d0d3f2d1111d</string>
<key>url</key>
<string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/81322/765512/uriparser-0.9.4-darwin64-559132.tar.bz2</string>
<string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/89474/816487/uriparser-0.9.4-darwin64-564957.tar.bz2</string>
</map>
<key>name</key>
<string>darwin64</string>
@ -3538,9 +3538,9 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
<key>archive</key>
<map>
<key>hash</key>
<string>901b1063556fc6b2575e745eef2bf744</string>
<string>e2600c798e220cc98c1cc77341aee00d</string>
<key>url</key>
<string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/81323/765528/uriparser-0.9.4-windows-559132.tar.bz2</string>
<string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/89476/816496/uriparser-0.9.4-windows-564957.tar.bz2</string>
</map>
<key>name</key>
<string>windows</string>
@ -3550,9 +3550,9 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
<key>archive</key>
<map>
<key>hash</key>
<string>962c01d553f286c430102998129fb0d6</string>
<string>50d857117d31844fc8b84b07b795fd00</string>
<key>url</key>
<string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/81324/765527/uriparser-0.9.4-windows64-559132.tar.bz2</string>
<string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/89475/816497/uriparser-0.9.4-windows64-564957.tar.bz2</string>
</map>
<key>name</key>
<string>windows64</string>
@ -3580,9 +3580,9 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
<key>archive</key>
<map>
<key>hash</key>
<string>33438e15e609794233d88f2ca6f8e476</string>
<string>33ed1bb3e24fbd3462da04fb3e917e94</string>
<key>url</key>
<string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/92307/834951/viewer_manager-2.0.566853-darwin64-566853.tar.bz2</string>
<string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/94814/850320/viewer_manager-3.0.568552-darwin64-568552.tar.bz2</string>
</map>
<key>name</key>
<string>darwin64</string>
@ -3616,9 +3616,9 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
<key>archive</key>
<map>
<key>hash</key>
<string>f83512f0ed35abf8b24ce66586099842</string>
<string>2ad8e04965ac8bddb7d351abe09bee07</string>
<key>url</key>
<string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/92304/834942/viewer_manager-2.0.566853-windows-566853.tar.bz2</string>
<string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/94813/850316/viewer_manager-3.0.568552-windows-568552.tar.bz2</string>
</map>
<key>name</key>
<string>windows</string>
@ -3629,7 +3629,7 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
<key>source_type</key>
<string>hg</string>
<key>version</key>
<string>2.0.566853</string>
<string>3.0.568552</string>
</map>
<key>vlc-bin</key>
<map>

View File

@ -1114,6 +1114,7 @@ Nicky Dasmijn
OPEN-187
STORM-1937
OPEN-187
SL-15234
STORM-2010
STORM-2082
MAINT-6665
@ -1123,6 +1124,7 @@ Nicky Dasmijn
SL-11072
SL-13141
SL-13642
SL-16438
Nicky Perian
OPEN-1
STORM-1087

View File

@ -164,6 +164,10 @@ endif (USE_BUGSPLAT)
add_subdirectory(${VIEWER_PREFIX}newview)
add_dependencies(viewer firestorm-bin)
set_target_properties(
firestorm-bin PROPERTIES
VS_DEBUGGER_WORKING_DIRECTORY "..\\..\\indra\\newview")
add_subdirectory(${VIEWER_PREFIX}doxygen EXCLUDE_FROM_ALL)
if (LL_TESTS)

View File

@ -19,34 +19,23 @@ if (NOT DEFINED VIEWER_SHORT_VERSION) # will be true in indra/, false in indra/n
message(STATUS "Revision (from autobuild environment): ${VIEWER_VERSION_REVISION}")
else (DEFINED ENV{revision})
find_program(MERCURIAL hg)
find_program(SED sed)
if (DEFINED MERCURIAL AND DEFINED SED)
find_program(GIT git)
if (DEFINED GIT )
execute_process(
# <FS:TS> FIRE-11737: Reverting to old revisions shows tip in build string
# This command gets the revision number of the current
# repository tip. This leads to confusion when
# building an earlier revision. Instead, we use
# "hg identify -n" to get the local revision number
# of the actual state of the repository.
#COMMAND ${MERCURIAL} log -r tip:0 --template '\\n'
#COMMAND ${WORDCOUNT} -l
#COMMAND ${SED} "s/ //g"
COMMAND ${MERCURIAL} identify -n
COMMAND ${SED} "s/+//" # [CR] Strip off any + from the revision number
COMMAND ${GIT} rev-list --count HEAD
OUTPUT_VARIABLE VIEWER_VERSION_REVISION
OUTPUT_STRIP_TRAILING_WHITESPACE
)
if ("${VIEWER_VERSION_REVISION}" MATCHES "^[0-9]+$")
message(STATUS "Revision (from hg) ${VIEWER_VERSION_REVISION}")
message(STATUS "Revision (from git) ${VIEWER_VERSION_REVISION}")
else ("${VIEWER_VERSION_REVISION}" MATCHES "^[0-9]+$")
message(STATUS "Revision not set (repository not found?); using 0")
set(VIEWER_VERSION_REVISION 0 )
endif ("${VIEWER_VERSION_REVISION}" MATCHES "^[0-9]+$")
else (DEFINED MERCURIAL AND DEFINED SED)
message(STATUS "Revision not set: 'hg' or 'sed' not found; using 0")
else (DEFINED GIT )
message(STATUS "Revision not set: 'git' found; using 0")
set(VIEWER_VERSION_REVISION 0)
endif (DEFINED MERCURIAL AND DEFINED SED)
endif (DEFINED GIT)
endif (DEFINED ENV{revision})
message(STATUS "Building '${VIEWER_CHANNEL}' Version ${VIEWER_SHORT_VERSION}.${VIEWER_VERSION_REVISION}")
else ( EXISTS ${VIEWER_VERSION_BASE_FILE} )

View File

@ -14,51 +14,28 @@ if (WINDOWS)
)
else()
find_program(PYTHON_EXECUTABLE
NAMES python25.exe python23.exe python.exe
NAMES python.exe
NO_DEFAULT_PATH # added so that cmake does not find cygwin python
PATHS
[HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\2.8\\InstallPath]
[HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\2.7\\InstallPath]
[HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\2.6\\InstallPath]
[HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\2.5\\InstallPath]
[HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\2.4\\InstallPath]
[HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\2.3\\InstallPath]
[HKEY_CURRENT_USER\\SOFTWARE\\Python\\PythonCore\\2.8\\InstallPath]
[HKEY_CURRENT_USER\\SOFTWARE\\Python\\PythonCore\\2.7\\InstallPath]
[HKEY_CURRENT_USER\\SOFTWARE\\Python\\PythonCore\\2.6\\InstallPath]
[HKEY_CURRENT_USER\\SOFTWARE\\Python\\PythonCore\\2.5\\InstallPath]
[HKEY_CURRENT_USER\\SOFTWARE\\Python\\PythonCore\\2.4\\InstallPath]
[HKEY_CURRENT_USER\\SOFTWARE\\Python\\PythonCore\\2.3\\InstallPath]
[HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\3.7\\InstallPath]
[HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\3.8\\InstallPath]
[HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\3.9\\InstallPath]
[HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\3.10\\InstallPath]
[HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\3.11\\InstallPath]
[HKEY_CURRENT_USER\\SOFTWARE\\Python\\PythonCore\\3.7\\InstallPath]
[HKEY_CURRENT_USER\\SOFTWARE\\Python\\PythonCore\\3.8\\InstallPath]
[HKEY_CURRENT_USER\\SOFTWARE\\Python\\PythonCore\\3.9\\InstallPath]
[HKEY_CURRENT_USER\\SOFTWARE\\Python\\PythonCore\\3.10\\InstallPath]
[HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\3.11\\InstallPath]
)
endif()
elseif (EXISTS /etc/debian_version)
# On Debian and Ubuntu, avoid Python 2.4 if possible.
find_program(PYTHON_EXECUTABLE python PATHS /usr/bin)
include(FindPythonInterp)
else()
find_program(PYTHON_EXECUTABLE python3)
if (PYTHON_EXECUTABLE)
set(PYTHONINTERP_FOUND ON)
endif (PYTHON_EXECUTABLE)
elseif (${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
# On MAC OS X be sure to search standard locations first
string(REPLACE ":" ";" PATH_LIST "$ENV{PATH}")
find_program(PYTHON_EXECUTABLE
NAMES python python25 python24 python23
NO_DEFAULT_PATH # Avoid searching non-standard locations first
PATHS
/bin
/usr/bin
/usr/local/bin
${PATH_LIST}
)
if (PYTHON_EXECUTABLE)
set(PYTHONINTERP_FOUND ON)
endif (PYTHON_EXECUTABLE)
else (WINDOWS)
include(FindPython2)
set( PYTHON_EXECUTABLE ${Python2_EXECUTABLE})
endif (WINDOWS)
if (NOT PYTHON_EXECUTABLE)

View File

@ -35,8 +35,10 @@ if (USE_BUGSPLAT)
set(BUGSPLAT_DB "" CACHE STRING "BugSplat crash database name")
if( LINUX )
set(BUGSPLAT_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/include/breakpad)
add_compile_definitions(__STDC_FORMAT_MACROS)
set(BUGSPLAT_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/include/breakpad)
# <FS:ND/> Sadly we cannot have the nice things yet and need add_definitions for older cmake
#add_compile_definitions(__STDC_FORMAT_MACROS)
add_definitions(-D__STDC_FORMAT_MACROS)
else()
set(BUGSPLAT_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/include/bugsplat)
endif()

View File

@ -1,4 +1,4 @@
#!/usr/bin/env python2
#!/usr/bin/env python3
"""\
@file run_build_test.py
@author Nat Goodspeed
@ -17,7 +17,7 @@ line.
Example:
python run_build_test.py -DFOO=bar myprog somearg otherarg
python3 run_build_test.py -DFOO=bar myprog somearg otherarg
sets environment variable FOO=bar, then runs:
myprog somearg otherarg
@ -47,7 +47,7 @@ $/LicenseInfo$
import os
import sys
import errno
import HTMLParser
import html.parser
import re
import signal
import subprocess
@ -111,10 +111,10 @@ def main(command, arguments=[], libpath=[], vars={}):
# Now handle arbitrary environment variables. The tricky part is ensuring
# that all the keys and values we try to pass are actually strings.
if vars:
for key, value in vars.items():
for key, value in list(vars.items()):
# As noted a few lines above, facilitate copy-paste rerunning.
log.info("%s='%s' \\" % (key, value))
os.environ.update(dict([(str(key), str(value)) for key, value in vars.iteritems()]))
os.environ.update(dict([(str(key), str(value)) for key, value in vars.items()]))
# Run the child process.
command_list = [command]
command_list.extend(arguments)
@ -194,7 +194,7 @@ def translate_rc(rc):
strc = str(rc)
return "terminated by signal %s" % strc
class TableParser(HTMLParser.HTMLParser):
class TableParser(html.parser.HTMLParser):
"""
This HTMLParser subclass is designed to parse the table we know exists
in windows-rcs.html, hopefully without building in too much knowledge of
@ -204,9 +204,7 @@ class TableParser(HTMLParser.HTMLParser):
whitespace = re.compile(r'\s*$')
def __init__(self):
# Because Python 2.x's HTMLParser is an old-style class, we must use
# old-style syntax to forward the __init__() call -- not super().
HTMLParser.HTMLParser.__init__(self)
super().__init__()
# this will collect all the data, eventually
self.table = []
# Stack whose top (last item) indicates where to append current

View File

@ -1,4 +1,4 @@
#!/usr/bin/env python
#!/usr/bin/env python3
"""\
@file start-client.py
@ -28,12 +28,12 @@ import os
import llstart
def usage():
print """start-client.py
print("""start-client.py
--grid <grid>
--farm <grid>
--region <starting region name>
"""
""")
def start_client(grid, slurl, build_config, my_args):
login_url = "https://login.%s.lindenlab.com/cgi-bin/login.cgi" % (grid)
@ -42,7 +42,7 @@ def start_client(grid, slurl, build_config, my_args):
"--loginuri" : login_url }
viewer_args.update(my_args)
# *sigh* We must put --url at the end of the argument list.
if viewer_args.has_key("--url"):
if "--url" in viewer_args:
slurl = viewer_args["--url"]
del(viewer_args["--url"])
viewer_args = llstart.get_args_from_dict(viewer_args)
@ -54,7 +54,7 @@ def start_client(grid, slurl, build_config, my_args):
# but the exe is at indra/build-<xxx>/newview/<target>
build_path = os.path.dirname(os.getcwd());
f = open("start-client.log", "w")
print >>f, "Viewer startup arguments:"
print("Viewer startup arguments:", file=f)
llstart.start("viewer", "../../newview",
"%s/newview/%s/firestorm-bin.exe" % (build_path, build_config),
viewer_args, f)

View File

@ -1,4 +1,4 @@
#!/usr/bin/env python
#!/usr/bin/env python3
##
## $LicenseInfo:firstyear=2011&license=viewerlgpl$
## Second Life Viewer Source Code
@ -27,7 +27,7 @@ import glob
def delete_file_types(path, filetypes):
if os.path.exists(path):
print 'Cleaning: ' + path
print('Cleaning: ' + path)
orig_dir = os.getcwd();
os.chdir(path)
filelist = []

View File

@ -26,8 +26,8 @@ THE SOFTWARE.
$/LicenseInfo$
"""
from compatibility import Incompatible, Older, Newer, Same
from tokenstream import TokenStream
from .compatibility import Incompatible, Older, Newer, Same
from .tokenstream import TokenStream
###
### Message Template
@ -42,8 +42,8 @@ class Template:
def compatibleWithBase(self, base):
messagenames = (
frozenset(self.messages.keys())
| frozenset(base.messages.keys())
frozenset(list(self.messages.keys()))
| frozenset(list(base.messages.keys()))
)
compatibility = Same()
@ -142,7 +142,7 @@ class Message:
baselen = len(base.blocks)
samelen = min(selflen, baselen)
for i in xrange(0, samelen):
for i in range(0, samelen):
selfblock = self.blocks[i]
baseblock = base.blocks[i]
@ -196,7 +196,7 @@ class Block(object):
selflen = len(self.variables)
baselen = len(base.variables)
for i in xrange(0, min(selflen, baselen)):
for i in range(0, min(selflen, baselen)):
selfvar = self.variables[i]
basevar = base.variables[i]

View File

@ -60,7 +60,7 @@ class ParseError(Exception):
return "line %d: %s @ ... %s" % (
self.line, self.reason, self._contextString())
def __nonzero__(self):
def __bool__(self):
return False

View File

@ -28,7 +28,7 @@ $/LicenseInfo$
"""
from collections import namedtuple, defaultdict
import commands
import subprocess
import errno
import filecmp
import fnmatch
@ -85,6 +85,7 @@ def proper_windows_path(path, current_platform = sys.platform):
def get_default_platform(dummy):
return {'linux2':'linux',
'linux1':'linux',
'linux':'linux',
'cygwin':'windows',
'win32':'windows',
'darwin':'darwin'
@ -164,20 +165,20 @@ BASE_ARGUMENTS=[
def usage(arguments, srctree=""):
nd = {'name':sys.argv[0]}
print """Usage:
print("""Usage:
%(name)s [options] [destdir]
Options:
""" % nd
""" % nd)
for arg in arguments:
default = arg['default']
if hasattr(default, '__call__'):
default = "(computed value) \"" + str(default(srctree)) + '"'
elif default is not None:
default = '"' + default + '"'
print "\t--%s Default: %s\n\t%s\n" % (
print("\t--%s Default: %s\n\t%s\n" % (
arg['name'],
default,
arg['description'] % nd)
arg['description'] % nd))
def main(extra=[]):
## print ' '.join((("'%s'" % item) if ' ' in item else item)
@ -202,10 +203,10 @@ def main(extra=[]):
for k in 'artwork build dest source'.split():
args[k] = os.path.normpath(args[k])
print "Source tree:", args['source']
print "Artwork tree:", args['artwork']
print "Build tree:", args['build']
print "Destination tree:", args['dest']
print("Source tree:", args['source'])
print("Artwork tree:", args['artwork'])
print("Build tree:", args['build'])
print("Destination tree:", args['dest'])
# early out for help
if 'help' in args:
@ -228,7 +229,7 @@ def main(extra=[]):
vf = open(args['versionfile'], 'r')
args['version'] = vf.read().strip().split('.')
except:
print "Unable to read versionfile '%s'" % args['versionfile']
print("Unable to read versionfile '%s'" % args['versionfile'])
# <FS:ND> This will break copy_w_viewer_manifest on Windows 32 and 64 bit builds, the versionfile will not create until the firestorm project.
# As copy_w_viewer_manifest does not seem to need the version attribute, we supress the exception for now.
# raise
@ -242,7 +243,7 @@ def main(extra=[]):
# debugging
for opt in args:
print "Option:", opt, "=", args[opt]
print("Option:", opt, "=", args[opt])
# pass in sourceid as an argument now instead of an environment variable
args['sourceid'] = os.environ.get("sourceid", "")
@ -250,18 +251,18 @@ def main(extra=[]):
# Build base package.
touch = args.get('touch')
if touch:
print '================ Creating base package'
print('================ Creating base package')
else:
print '================ Starting base copy'
print('================ Starting base copy')
wm = LLManifest.for_platform(args['platform'], args.get('arch'))(args)
wm.do(*args['actions'])
# Store package file for later if making touched file.
base_package_file = ""
if touch:
print '================ Created base package ', wm.package_file
print('================ Created base package ', wm.package_file)
base_package_file = "" + wm.package_file
else:
print '================ Finished base copy'
print('================ Finished base copy')
# handle multiple packages if set
# ''.split() produces empty list
@ -288,26 +289,26 @@ def main(extra=[]):
args['sourceid'] = os.environ.get(package_id + "_sourceid")
args['dest'] = base_dest_template.format(package_id)
if touch:
print '================ Creating additional package for "', package_id, '" in ', args['dest']
print('================ Creating additional package for "', package_id, '" in ', args['dest'])
else:
print '================ Starting additional copy for "', package_id, '" in ', args['dest']
print('================ Starting additional copy for "', package_id, '" in ', args['dest'])
try:
wm = LLManifest.for_platform(args['platform'], args.get('arch'))(args)
wm.do(*args['actions'])
except Exception as err:
sys.exit(str(err))
if touch:
print '================ Created additional package ', wm.package_file, ' for ', package_id
print('================ Created additional package ', wm.package_file, ' for ', package_id)
with open(base_touch_template.format(package_id), 'w') as fp:
fp.write('set package_file=%s\n' % wm.package_file)
else:
print '================ Finished additional copy "', package_id, '" in ', args['dest']
print('================ Finished additional copy "', package_id, '" in ', args['dest'])
# Write out the package file in this format, so that it can easily be called
# and used in a .bat file - yeah, it sucks, but this is the simplest...
if touch:
with open(touch, 'w') as fp:
fp.write('set package_file=%s\n' % base_package_file)
print 'touched', touch
print('touched', touch)
return 0
class LLManifestRegistry(type):
@ -319,8 +320,7 @@ class LLManifestRegistry(type):
MissingFile = namedtuple("MissingFile", ("pattern", "tried"))
class LLManifest(object):
__metaclass__ = LLManifestRegistry
class LLManifest(object, metaclass=LLManifestRegistry):
manifests = {}
def for_platform(self, platform, arch = None):
if arch:
@ -412,8 +412,8 @@ class LLManifest(object):
def display_stacks(self):
width = 1 + max(len(stack) for stack in self.PrefixManager.stacks)
for stack in self.PrefixManager.stacks:
print "{} {}".format((stack + ':').ljust(width),
os.path.join(*getattr(self, stack)))
print("{} {}".format((stack + ':').ljust(width),
os.path.join(*getattr(self, stack))))
class PrefixManager(object):
# stack attributes we manage in this LLManifest (sub)class
@ -430,7 +430,7 @@ class LLManifest(object):
self.prevlen = { stack: len(getattr(self.manifest, stack)) - 1
for stack in self.stacks }
def __nonzero__(self):
def __bool__(self):
# If the caller wrote:
# if self.prefix(...):
# then a value of this class had better evaluate as 'True'.
@ -456,7 +456,7 @@ class LLManifest(object):
# if we restore the length of each stack to what it was before the
# current prefix() block, it doesn't matter whether end_prefix()
# was called or not.
for stack, prevlen in self.prevlen.items():
for stack, prevlen in list(self.prevlen.items()):
# find the attribute in 'self.manifest' named by 'stack', and
# truncate that list back to 'prevlen'
del getattr(self.manifest, stack)[prevlen:]
@ -475,7 +475,7 @@ class LLManifest(object):
build = self.build_prefix.pop()
dst = self.dst_prefix.pop()
if descr and not(src == descr or build == descr or dst == descr):
raise ValueError, "End prefix '" + descr + "' didn't match '" +src+ "' or '" +dst + "'"
raise ValueError("End prefix '" + descr + "' didn't match '" +src+ "' or '" +dst + "'")
def get_src_prefix(self):
""" Returns the current source prefix."""
@ -542,7 +542,7 @@ class LLManifest(object):
Runs an external command.
Raises ManifestError exception if the command returns a nonzero status.
"""
print "Running command:", command
print("Running command:", command)
sys.stdout.flush()
try:
subprocess.check_call(command)
@ -556,7 +556,7 @@ class LLManifest(object):
Runs an external command.
Raises ManifestError exception if the command returns a nonzero status.
"""
print "Running command:", command
print("Running command:", command)
sys.stdout.flush()
try:
subprocess.check_call(command, shell=True)
@ -570,18 +570,15 @@ class LLManifest(object):
a) verify that you really have created it
b) schedule it for cleanup"""
if not os.path.exists(path):
raise ManifestError, "Should be something at path " + path
raise ManifestError("Should be something at path " + path)
self.created_paths.append(path)
def put_in_file(self, contents, dst, src=None):
# write contents as dst
dst_path = self.dst_path_of(dst)
self.cmakedirs(os.path.dirname(dst_path))
f = open(dst_path, "wb")
try:
with open(dst_path, 'wb') as f:
f.write(contents)
finally:
f.close()
# Why would we create a file in the destination tree if not to include
# it in the installer? The default src=None (plus the fact that the
@ -594,13 +591,12 @@ class LLManifest(object):
if dst == None:
dst = src
# read src
f = open(self.src_path_of(src), "rbU")
contents = f.read()
f.close()
with open(self.src_path_of(src), "r") as f:
contents = f.read()
# apply dict replacements
for old, new in searchdict.iteritems():
for old, new in searchdict.items():
contents = contents.replace(old, new)
self.put_in_file(contents, dst)
self.put_in_file(contents.encode(), dst)
self.created_paths.append(dst)
def copy_action(self, src, dst):
@ -610,7 +606,7 @@ class LLManifest(object):
self.created_paths.append(dst)
self.ccopymumble(src, dst)
else:
print "Doesn't exist:", src
print("Doesn't exist:", src)
def package_action(self, src, dst):
pass
@ -628,8 +624,8 @@ class LLManifest(object):
# file error until all were resolved. This way permits the developer
# to resolve them all at once.
if self.missing:
print '*' * 72
print "Missing files:"
print('*' * 72)
print("Missing files:")
# Instead of just dumping each missing file and all the places we
# looked for it, group by common sets of places we looked. Use a
# set to store the 'tried' directories, to avoid mismatches due to
@ -640,13 +636,13 @@ class LLManifest(object):
organize[frozenset(missingfile.tried)].add(missingfile.pattern)
# Now dump all the patterns sought in each group of 'tried'
# directories.
for tried, patterns in organize.items():
print " Could not find in:"
for tried, patterns in list(organize.items()):
print(" Could not find in:")
for dir in sorted(tried):
print " %s" % dir
print(" %s" % dir)
for pattern in sorted(patterns):
print " %s" % pattern
print '*' * 72
print(" %s" % pattern)
print('*' * 72)
raise MissingError('%s patterns could not be found' % len(self.missing))
def copy_finish(self):
@ -659,7 +655,7 @@ class LLManifest(object):
unpacked_file_name = "unpacked_%(plat)s_%(vers)s.tar" % {
'plat':self.args['platform'],
'vers':'_'.join(self.args['version'])}
print "Creating unpacked file:", unpacked_file_name
print("Creating unpacked file:", unpacked_file_name)
# could add a gz here but that doubles the time it takes to do this step
tf = tarfile.open(self.src_path_of(unpacked_file_name), 'w:')
# add the entire installation package, at the very top level
@ -670,7 +666,7 @@ class LLManifest(object):
""" Delete paths that were specified to have been created by this script"""
for c in self.created_paths:
# *TODO is this gonna be useful?
print "Cleaning up " + c
print("Cleaning up " + c)
def process_either(self, src, dst):
# If it's a real directory, recurse through it --
@ -719,7 +715,7 @@ class LLManifest(object):
def remove(self, *paths):
for path in paths:
if os.path.exists(path):
print "Removing path", path
print("Removing path", path)
if os.path.isdir(path):
shutil.rmtree(path)
else:
@ -781,7 +777,7 @@ class LLManifest(object):
except (IOError, os.error) as why:
errors.append((srcname, dstname, why))
if errors:
raise ManifestError, errors
raise ManifestError(errors)
def cmakedirs(self, path):
@ -893,13 +889,13 @@ class LLManifest(object):
break
else:
# no more prefixes left to try
print("\nunable to find '%s'; looked in:\n %s" % (src, '\n '.join(try_prefixes)))
print(("\nunable to find '%s'; looked in:\n %s" % (src, '\n '.join(try_prefixes))))
self.missing.append(MissingFile(pattern=src, tried=try_prefixes))
# At this point 'count' might never have been successfully
# assigned! Even if it was, though, we can be sure it is 0.
return 0
print "%d files" % count
print("%d files" % count)
# Let caller check whether we processed as many files as expected. In
# particular, let caller notice 0.

View File

@ -1,4 +1,4 @@
#!/usr/bin/env python
#!/usr/bin/env python3
"""\
@file test_win32_manifest.py
@brief Test an assembly binding version and uniqueness in a windows dll or exe.
@ -44,10 +44,10 @@ class NoMatchingAssemblyException(AssemblyTestException):
pass
def get_HKLM_registry_value(key_str, value_str):
import _winreg
reg = _winreg.ConnectRegistry(None, _winreg.HKEY_LOCAL_MACHINE)
key = _winreg.OpenKey(reg, key_str)
value = _winreg.QueryValueEx(key, value_str)[0]
import winreg
reg = winreg.ConnectRegistry(None, winreg.HKEY_LOCAL_MACHINE)
key = winreg.OpenKey(reg, key_str)
value = winreg.QueryValueEx(key, value_str)[0]
#print 'Found: %s' % value
return value
@ -64,12 +64,12 @@ def find_vc_dir():
(product, version))
try:
return get_HKLM_registry_value(key_str, value_str)
except WindowsError, err:
except WindowsError as err:
x64_key_str = (r'SOFTWARE\Wow6432Node\Microsoft\%s\%s\Setup\VC' % (product, version))
try:
return get_HKLM_registry_value(x64_key_str, value_str)
except:
print >> sys.stderr, "Didn't find MS %s version %s " % (product,version)
print("Didn't find MS %s version %s " % (product,version), file=sys.stderr)
raise
@ -79,7 +79,7 @@ def find_mt_path():
return mt_path
def test_assembly_binding(src_filename, assembly_name, assembly_ver):
print "checking %s dependency %s..." % (src_filename, assembly_name)
print("checking %s dependency %s..." % (src_filename, assembly_name))
(tmp_file_fd, tmp_file_name) = tempfile.mkstemp(suffix='.xml')
tmp_file = os.fdopen(tmp_file_fd)
@ -90,10 +90,10 @@ def test_assembly_binding(src_filename, assembly_name, assembly_ver):
if os.path.splitext(src_filename)[1].lower() == ".dll":
resource_id = ";#2"
system_call = '%s -nologo -inputresource:%s%s -out:%s > NUL' % (mt_path, src_filename, resource_id, tmp_file_name)
print "Executing: %s" % system_call
print("Executing: %s" % system_call)
mt_result = os.system(system_call)
if mt_result == 31:
print "No manifest found in %s" % src_filename
print("No manifest found in %s" % src_filename)
raise NoManifestException()
manifest_dom = parse(tmp_file_name)
@ -105,30 +105,30 @@ def test_assembly_binding(src_filename, assembly_name, assembly_ver):
versions.append(node.getAttribute('version'))
if len(versions) == 0:
print "No matching assemblies found in %s" % src_filename
print("No matching assemblies found in %s" % src_filename)
raise NoMatchingAssemblyException()
#elif len(versions) > 1:
# print "Multiple bindings to %s found:" % assembly_name
# print versions
# print
# print("Multiple bindings to %s found:" % assembly_name)
# print(versions)
# print()
# raise MultipleBindingsException(versions)
#elif versions[0] != assembly_ver:
# print "Unexpected version found for %s:" % assembly_name
# print "Wanted %s, found %s" % (assembly_ver, versions[0])
# print
# print("Unexpected version found for %s:" % assembly_name)
# print("Wanted %s, found %s" % (assembly_ver, versions[0]))
# print()
# raise UnexpectedVersionException(assembly_ver, versions[0])
os.remove(tmp_file_name)
print "SUCCESS: %s OK!" % src_filename
print
print("SUCCESS: %s OK!" % src_filename)
print()
if __name__ == '__main__':
print
print "Running test_win32_manifest.py..."
print()
print("Running test_win32_manifest.py...")
usage = 'test_win32_manfest <srcFileName> <assemblyName> <assemblyVersion>'
@ -137,9 +137,9 @@ if __name__ == '__main__':
assembly_name = sys.argv[2]
assembly_ver = sys.argv[3]
except:
print "Usage:"
print usage
print
print("Usage:")
print(usage)
print()
raise
test_assembly_binding(src_filename, assembly_name, assembly_ver)

View File

@ -551,8 +551,6 @@ namespace
protected:
Globals();
public:
std::ostringstream messageStream;
bool messageStreamInUse;
std::string mFatalMessage;
void addCallSite(LLError::CallSite&);
@ -569,7 +567,9 @@ namespace
};
Globals::Globals()
: mSettingsConfig(new SettingsConfig())
:
callSites(),
mSettingsConfig(new SettingsConfig())
{
}
@ -1459,7 +1459,10 @@ namespace LLError
if (site.mLevel == LEVEL_ERROR)
{
g->mFatalMessage = message;
s->mCrashFunction(message);
if (s->mCrashFunction)
{
s->mCrashFunction(message);
}
}
}
}

View File

@ -86,7 +86,7 @@ public:
// notice Python specially: we provide Python LLSD serialization
// support, so there's a pretty good reason to implement plugins
// in that language.
if (cparams.args.size() && (desclower == "python" || desclower == "python.exe"))
if (cparams.args.size() && (desclower == "python" || desclower == "python3" || desclower == "python.exe"))
{
mDesc = LLProcess::basename(cparams.args()[0]);
}

View File

@ -189,7 +189,6 @@ LLMetricPerformanceTesterBasic::~LLMetricPerformanceTesterBasic()
void LLMetricPerformanceTesterBasic::preOutputTestResults(LLSD* sd)
{
incrementCurrentCount() ;
(*sd)[getCurrentLabelName()]["Name"] = mName ;
}
void LLMetricPerformanceTesterBasic::postOutputTestResults(LLSD* sd)

View File

@ -107,7 +107,7 @@ LLOSInfo::LLOSInfo() :
#if LL_WINDOWS
if (IsWindows10OrGreater())
if (IsWindows10OrGreater())
{
mMajorVer = 10;
mMinorVer = 0;
@ -248,13 +248,24 @@ LLOSInfo::LLOSInfo() :
}
}
// <FS:Ansariel> Windows 11 detection
if (mBuild >= 22000)
{
mMajorVer = 11;
LLStringUtil::replaceString(mOSStringSimple, "10", "11");
}
// </FS:Ansariel>
if (mBuild >= 22000)
{
// At release Windows 11 version was 10.0.22000.194
// Windows 10 version was 10.0.19043.1266
// There is no warranty that Win10 build won't increase,
// so until better solution is found or Microsoft updates
// SDK with IsWindows11OrGreater(), indicate "10/11"
//
// Current alternatives:
// Query WMI's Win32_OperatingSystem for OS string. Slow
// and likely to return 'compatibility' string.
// Check presence of dlls/libs or may be their version.
// <FS:Ansariel> Windows 11 detection
//mOSStringSimple = "Microsoft Windows 10/11";
mMajorVer = 11;
LLStringUtil::replaceString(mOSStringSimple, "10", "11");
// </FS:Ansariel>
}
}
mOSString = mOSStringSimple;
@ -1261,18 +1272,12 @@ BOOL gunzip_file(const std::string& srcfile, const std::string& dstfile)
LLFILE *dst = NULL;
S32 bytes = 0;
tmpfile = dstfile + ".t";
// <FS:ND> Proper UTF8->UTF16 handling for Windows
// src = gzopen(srcfile.c_str(), "rb");
#if LL_WINDOWS
std::string utf8filename = srcfile;
llutf16string utf16filename = utf8str_to_utf16str(utf8filename);
src = gzopen_w(utf16filename.c_str(), "rb");
#ifdef LL_WINDOWS
llutf16string utf16filename = utf8str_to_utf16str(srcfile);
src = gzopen_w(utf16filename.c_str(), "rb");
#else
src = gzopen(srcfile.c_str(), "rb");/* Flawfinder: ignore */
src = gzopen(srcfile.c_str(), "rb");
#endif
// </FS:ND>
if (! src) goto err;
dst = LLFile::fopen(tmpfile, "wb"); /* Flawfinder: ignore */
if (! dst) goto err;
@ -1307,17 +1312,13 @@ BOOL gzip_file(const std::string& srcfile, const std::string& dstfile)
S32 bytes = 0;
tmpfile = dstfile + ".t";
// <FS:ND> Proper UTF8->UTF16 handling for Windows
// dst = gzopen(tmpfile.c_str(), "wb"); /* Flawfinder: ignore */
#if LL_WINDOWS
std::string utf8filename = tmpfile;
llutf16string utf16filename = utf8str_to_utf16str(utf8filename);
dst = gzopen_w(utf16filename.c_str(), "wb");
#ifdef LL_WINDOWS
llutf16string utf16filename = utf8str_to_utf16str(tmpfile);
dst = gzopen_w(utf16filename.c_str(), "wb");
#else
dst = gzopen(tmpfile.c_str(), "wb");/* Flawfinder: ignore */
dst = gzopen(tmpfile.c_str(), "wb");
#endif
// </FS:ND>
if (! dst) goto err;
src = LLFile::fopen(srcfile, "rb"); /* Flawfinder: ignore */
if (! src) goto err;

View File

@ -145,13 +145,13 @@ namespace tut
" data = ''.join(parts)\n"
" assert len(data) == length\n"
" try:\n"
" return llsd.parse(data)\n"
" return llsd.parse(data.encode())\n"
// Seems the old indra.base.llsd module didn't properly
// convert IndexError (from running off end of string) to
// LLSDParseError.
" except (IndexError, llsd.LLSDParseError), e:\n"
" except (IndexError, llsd.LLSDParseError) as e:\n"
" msg = 'Bad received packet (%s)' % e\n"
" print >>sys.stderr, '%s, %s bytes:' % (msg, len(data))\n"
" print('%s, %s bytes:' % (msg, len(data)), file=sys.stderr)\n"
" showmax = 40\n"
// We've observed failures with very large packets;
// dumping the entire packet wastes time and space.
@ -167,12 +167,12 @@ namespace tut
" data = data[:trunc]\n"
" ellipsis = '... (%s more)' % (length - trunc)\n"
" offset = -showmax\n"
" for offset in xrange(0, len(data)-showmax, showmax):\n"
" print >>sys.stderr, '%04d: %r +' % \\\n"
" (offset, data[offset:offset+showmax])\n"
" for offset in range(0, len(data)-showmax, showmax):\n"
" print('%04d: %r +' % \\\n"
" (offset, data[offset:offset+showmax]), file=sys.stderr)\n"
" offset += showmax\n"
" print >>sys.stderr, '%04d: %r%s' % \\\n"
" (offset, data[offset:], ellipsis)\n"
" print('%04d: %r%s' % \\\n"
" (offset, data[offset:], ellipsis), file=sys.stderr)\n"
" raise ParseError(msg, data)\n"
"\n"
"# deal with initial stdin message\n"
@ -189,7 +189,7 @@ namespace tut
" sys.stdout.flush()\n"
"\n"
"def send(pump, data):\n"
" put(llsd.format_notation(dict(pump=pump, data=data)))\n"
" put(llsd.format_notation(dict(pump=pump, data=data)).decode())\n"
"\n"
"def request(pump, data):\n"
" # we expect 'data' is a dict\n"
@ -253,7 +253,7 @@ namespace tut
{
set_test_name("bad stdout protocol");
NamedTempFile script("py",
"print 'Hello from Python!'\n");
"print('Hello from Python!')\n");
CaptureLog log(LLError::LEVEL_WARN);
waitfor(LLLeap::create(get_test_name(),
sv(list_of(PYTHON)(script.getName()))));
@ -438,8 +438,8 @@ namespace tut
// guess how many messages it will take to
// accumulate BUFFERED_LENGTH
"count = int(" << BUFFERED_LENGTH << "/samplen)\n"
"print >>sys.stderr, 'Sending %s requests' % count\n"
"for i in xrange(count):\n"
"print('Sending %s requests' % count, file=sys.stderr)\n"
"for i in range(count):\n"
" request('" << api.getName() << "', dict(reqid=i))\n"
// The assumption in this specific test that
// replies will arrive in the same order as
@ -450,7 +450,7 @@ namespace tut
// arbitrary order, and we'd have to tick them
// off from a set.
"result = ''\n"
"for i in xrange(count):\n"
"for i in range(count):\n"
" resp = get()\n"
" if resp['data']['reqid'] != i:\n"
" result = 'expected reqid=%s in %s' % (i, resp)\n"
@ -476,13 +476,13 @@ namespace tut
"desired = int(sys.argv[1])\n"
// 7 chars per item: 6 digits, 1 comma
"count = int((desired - 50)/7)\n"
"large = ''.join('%06d,' % i for i in xrange(count))\n"
"large = ''.join('%06d,' % i for i in range(count))\n"
// Pass 'large' as reqid because we know the API
// will echo reqid, and we want to receive it back.
"request('" << api.getName() << "', dict(reqid=large))\n"
"try:\n"
" resp = get()\n"
"except ParseError, e:\n"
"except ParseError as e:\n"
" # try to find where e.data diverges from expectation\n"
// Normally we'd expect a 'pump' key in there,
// too, with value replypump(). But Python
@ -493,17 +493,18 @@ namespace tut
// strange.
" expect = llsd.format_notation(dict(data=dict(reqid=large)))\n"
" chunk = 40\n"
" for offset in xrange(0, max(len(e.data), len(expect)), chunk):\n"
" for offset in range(0, max(len(e.data), len(expect)), chunk):\n"
" if e.data[offset:offset+chunk] != \\\n"
" expect[offset:offset+chunk]:\n"
" print >>sys.stderr, 'Offset %06d: expect %r,\\n'\\\n"
" print('Offset %06d: expect %r,\\n'\\\n"
" ' get %r' %\\\n"
" (offset,\n"
" expect[offset:offset+chunk],\n"
" e.data[offset:offset+chunk])\n"
" e.data[offset:offset+chunk]),\n"
" file=sys.stderr)\n"
" break\n"
" else:\n"
" print >>sys.stderr, 'incoming data matches expect?!'\n"
" print('incoming data matches expect?!', file=sys.stderr)\n"
" send('" << result.getName() << "', '%s: %s' % (e.__class__.__name__, e))\n"
" sys.exit(1)\n"
"\n"
@ -512,7 +513,7 @@ namespace tut
" send('" << result.getName() << "', '')\n"
" sys.exit(0)\n"
// Here we know echoed did NOT match; try to find where
"for i in xrange(count):\n"
"for i in range(count):\n"
" start = 7*i\n"
" end = 7*(i+1)\n"
" if end > len(echoed)\\\n"

View File

@ -382,7 +382,11 @@ namespace tut
std::vector<const char*> argv;
apr_proc_t child;
#if defined(LL_WINDOWS)
argv.push_back("python");
#else
argv.push_back("python3");
#endif
// Have to have a named copy of this std::string so its c_str() value
// will persist.
std::string scriptname(script.getName());
@ -743,7 +747,7 @@ namespace tut
"with open(sys.argv[1], 'w') as f:\n"
" f.write('ok')\n"
"# wait for 'go' from test program\n"
"for i in xrange(60):\n"
"for i in range(60):\n"
" time.sleep(1)\n"
" with open(sys.argv[2]) as f:\n"
" go = f.read()\n"
@ -805,7 +809,7 @@ namespace tut
"with open(sys.argv[1], 'w') as f:\n"
" f.write('ok')\n"
"# wait for 'go' from test program\n"
"for i in xrange(60):\n"
"for i in range(60):\n"
" time.sleep(1)\n"
" with open(sys.argv[2]) as f:\n"
" go = f.read()\n"

View File

@ -1795,7 +1795,7 @@ namespace tut
set_test_name("verify NamedTempFile");
python("platform",
"import sys\n"
"print 'Running on', sys.platform\n");
"print('Running on', sys.platform)\n");
}
// helper for test<3>
@ -1825,14 +1825,14 @@ namespace tut
const char pydata[] =
"def verify(iterable):\n"
" it = iter(iterable)\n"
" assert it.next() == 17\n"
" assert abs(it.next() - 3.14) < 0.01\n"
" assert it.next() == '''\\\n"
" assert next(it) == 17\n"
" assert abs(next(it) - 3.14) < 0.01\n"
" assert next(it) == '''\\\n"
"This string\n"
"has several\n"
"lines.'''\n"
" try:\n"
" it.next()\n"
" next(it)\n"
" except StopIteration:\n"
" pass\n"
" else:\n"
@ -1855,7 +1855,7 @@ namespace tut
" yield llsd.parse(item)\n" <<
pydata <<
// Don't forget raw-string syntax for Windows pathnames.
"verify(parse_each(open(r'" << file.getName() << "')))\n");
"verify(parse_each(open(r'" << file.getName() << "', 'rb')))\n");
}
template<> template<>
@ -1870,7 +1870,6 @@ namespace tut
python("write Python notation",
placeholders::arg1 <<
"from __future__ import with_statement\n" <<
import_llsd <<
"DATA = [\n"
" 17,\n"
@ -1884,7 +1883,7 @@ namespace tut
// N.B. Using 'print' implicitly adds newlines.
"with open(r'" << file.getName() << "', 'w') as f:\n"
" for item in DATA:\n"
" print >>f, llsd.format_notation(item)\n");
" print(llsd.format_notation(item).decode(), file=f)\n");
std::ifstream inf(file.getName().c_str());
LLSD item;

View File

@ -135,7 +135,9 @@ public:
}
}
std::ostringstream str;
str << "Required header # " << i << " found in response";
str << "Required header #" << i << " "
<< mHeadersRequired[i].first << "=" << mHeadersRequired[i].second
<< " not found in response";
ensure(str.str(), found);
}
}
@ -154,7 +156,9 @@ public:
mHeadersDisallowed[i].second))
{
std::ostringstream str;
str << "Disallowed header # " << i << " not found in response";
str << "Disallowed header #" << i << " "
<< mHeadersDisallowed[i].first << "=" << mHeadersDisallowed[i].second
<< " found in response";
ensure(str.str(), false);
}
}
@ -2127,6 +2131,17 @@ void HttpRequestTestObjectType::test<18>()
template <> template <>
void HttpRequestTestObjectType::test<19>()
{
// It appears that HttpRequest is fully capable of sending duplicate header values in violation of
// this test's expectations. Something needs to budge: is sending duplicate header values desired?
//
// Test server /reflect/ response headers (mirrored from request)
//
// X-Reflect-content-type: text/plain
// X-Reflect-content-type: text/html
// X-Reflect-content-type: application/llsd+xml
//
skip("FIXME: Bad assertions or broken functionality.");
ScopedCurlInit ready;
// Warmup boost::regex to pre-alloc memory for memory size tests
@ -2307,6 +2322,17 @@ void HttpRequestTestObjectType::test<19>()
template <> template <>
void HttpRequestTestObjectType::test<20>()
{
// It appears that HttpRequest is fully capable of sending duplicate header values in violation of
// this test's expectations. Something needs to budge: is sending duplicate header values desired?
//
// Test server /reflect/ response headers (mirrored from request)
//
// X-Reflect-content-type: text/plain
// X-Reflect-content-type: text/html
// X-Reflect-content-type: application/llsd+xml
//
skip("FIXME: Bad assertions or broken functionality.");
ScopedCurlInit ready;
// Warmup boost::regex to pre-alloc memory for memory size tests
@ -2512,6 +2538,17 @@ void HttpRequestTestObjectType::test<20>()
template <> template <>
void HttpRequestTestObjectType::test<21>()
{
// It appears that HttpRequest is fully capable of sending duplicate header values in violation of
// this test's expectations. Something needs to budge: is sending duplicate header values desired?
//
// Test server /reflect/ response headers (mirrored from request)
//
// X-Reflect-content-type: text/plain
// X-Reflect-content-type: text/html
// X-Reflect-content-type: application/llsd+xml
//
skip("FIXME: Bad assertions or broken functionality.");
ScopedCurlInit ready;
// Warmup boost::regex to pre-alloc memory for memory size tests

View File

@ -1,4 +1,4 @@
#!/usr/bin/env python
#!/usr/bin/env python3
"""\
@file test_llsdmessage_peer.py
@author Nat Goodspeed
@ -34,11 +34,9 @@ import sys
import time
import select
import getopt
try:
from cStringIO import StringIO
except ImportError:
from StringIO import StringIO
from BaseHTTPServer import HTTPServer, BaseHTTPRequestHandler
from io import StringIO
from http.server import HTTPServer, BaseHTTPRequestHandler
from llbase.fastest_elementtree import parse as xml_parse
from llbase import llsd
@ -97,13 +95,13 @@ class TestHTTPRequestHandler(BaseHTTPRequestHandler):
except (KeyError, ValueError):
return ""
max_chunk_size = 10*1024*1024
L = []
L = bytes()
while size_remaining:
chunk_size = min(size_remaining, max_chunk_size)
chunk = self.rfile.read(chunk_size)
L.append(chunk)
L += chunk
size_remaining -= len(chunk)
return ''.join(L)
return L.decode("utf-8")
# end of swiped read() logic
def read_xml(self):
@ -127,8 +125,8 @@ class TestHTTPRequestHandler(BaseHTTPRequestHandler):
try:
self.answer(dict(reply="success", status=200,
reason="Your GET operation worked"))
except self.ignore_exceptions, e:
print >> sys.stderr, "Exception during GET (ignoring): %s" % str(e)
except self.ignore_exceptions as e:
print("Exception during GET (ignoring): %s" % str(e), file=sys.stderr)
def do_POST(self):
# Read the provided POST data.
@ -136,8 +134,8 @@ class TestHTTPRequestHandler(BaseHTTPRequestHandler):
try:
self.answer(dict(reply="success", status=200,
reason=self.read()))
except self.ignore_exceptions, e:
print >> sys.stderr, "Exception during POST (ignoring): %s" % str(e)
except self.ignore_exceptions as e:
print("Exception during POST (ignoring): %s" % str(e), file=sys.stderr)
def do_PUT(self):
# Read the provided PUT data.
@ -145,8 +143,8 @@ class TestHTTPRequestHandler(BaseHTTPRequestHandler):
try:
self.answer(dict(reply="success", status=200,
reason=self.read()))
except self.ignore_exceptions, e:
print >> sys.stderr, "Exception during PUT (ignoring): %s" % str(e)
except self.ignore_exceptions as e:
print("Exception during PUT (ignoring): %s" % str(e), file=sys.stderr)
def answer(self, data, withdata=True):
debug("%s.answer(%s): self.path = %r", self.__class__.__name__, data, self.path)
@ -221,7 +219,7 @@ class TestHTTPRequestHandler(BaseHTTPRequestHandler):
self.send_header("Content-type", "text/plain")
self.end_headers()
if body:
self.wfile.write(body)
self.wfile.write(body.encode("utf-8"))
elif "fail" not in self.path:
data = data.copy() # we're going to modify
# Ensure there's a "reply" key in data, even if there wasn't before
@ -255,9 +253,9 @@ class TestHTTPRequestHandler(BaseHTTPRequestHandler):
self.end_headers()
def reflect_headers(self):
for name in self.headers.keys():
# print "Header: %s: %s" % (name, self.headers[name])
self.send_header("X-Reflect-" + name, self.headers[name])
for (name, val) in self.headers.items():
# print("Header: %s %s" % (name, val), file=sys.stderr)
self.send_header("X-Reflect-" + name, val)
if not VERBOSE:
# When VERBOSE is set, skip both these overrides because they exist to
@ -283,10 +281,10 @@ class Server(HTTPServer):
# default behavior which *shouldn't* cause the program to return
# a failure status.
def handle_error(self, request, client_address):
print '-'*40
print 'Ignoring exception during processing of request from',
print client_address
print '-'*40
print('-'*40)
print('Ignoring exception during processing of request from %' % (client_address))
print('-'*40)
if __name__ == "__main__":
do_valgrind = False
@ -307,7 +305,7 @@ if __name__ == "__main__":
# "Then there's Windows"
# Instantiate a Server(TestHTTPRequestHandler) on the first free port
# in the specified port range.
httpd, port = freeport(xrange(8000, 8020), make_server)
httpd, port = freeport(range(8000, 8020), make_server)
# Pass the selected port number to the subject test program via the
# environment. We don't want to impose requirements on the test program's

View File

@ -37,15 +37,22 @@
struct FolderEntry : public LLDictionaryEntry
{
FolderEntry(const std::string &type_name, // 8 character limit!
bool is_protected) // can the viewer change categories of this type?
bool is_protected, // can the viewer change categories of this type?
bool is_automatic, // always made before first login?
bool is_singleton // should exist as a unique copy under root
)
:
LLDictionaryEntry(type_name),
mIsProtected(is_protected)
mIsProtected(is_protected),
mIsAutomatic(is_automatic),
mIsSingleton(is_singleton)
{
llassert(type_name.length() <= 8);
}
const bool mIsProtected;
const bool mIsAutomatic;
const bool mIsSingleton;
};
class LLFolderDictionary : public LLSingleton<LLFolderDictionary>,
@ -59,52 +66,66 @@ protected:
}
};
// Folder types
//
// PROTECTED means that folders of this type can't be moved, deleted
// or otherwise modified by the viewer.
//
// SINGLETON means that there should always be exactly one folder of
// this type, and it should be the root or a child of the root. This
// is true for most types of folders.
//
// AUTOMATIC means that a copy of this folder should be created under
// the root before the user ever logs in, and should never be created
// from the viewer. A missing AUTOMATIC folder should be treated as a
// fatal error by the viewer, since it indicates either corrupted
// inventory or a failure in the inventory services.
//
LLFolderDictionary::LLFolderDictionary()
{
// TYPE NAME PROTECTED
// |-----------|---------|
addEntry(LLFolderType::FT_TEXTURE, new FolderEntry("texture", TRUE));
addEntry(LLFolderType::FT_SOUND, new FolderEntry("sound", TRUE));
addEntry(LLFolderType::FT_CALLINGCARD, new FolderEntry("callcard", TRUE));
addEntry(LLFolderType::FT_LANDMARK, new FolderEntry("landmark", TRUE));
addEntry(LLFolderType::FT_CLOTHING, new FolderEntry("clothing", TRUE));
addEntry(LLFolderType::FT_OBJECT, new FolderEntry("object", TRUE));
addEntry(LLFolderType::FT_NOTECARD, new FolderEntry("notecard", TRUE));
addEntry(LLFolderType::FT_ROOT_INVENTORY, new FolderEntry("root_inv", TRUE));
addEntry(LLFolderType::FT_LSL_TEXT, new FolderEntry("lsltext", TRUE));
addEntry(LLFolderType::FT_BODYPART, new FolderEntry("bodypart", TRUE));
addEntry(LLFolderType::FT_TRASH, new FolderEntry("trash", TRUE));
addEntry(LLFolderType::FT_SNAPSHOT_CATEGORY, new FolderEntry("snapshot", TRUE));
addEntry(LLFolderType::FT_LOST_AND_FOUND, new FolderEntry("lstndfnd", TRUE));
addEntry(LLFolderType::FT_ANIMATION, new FolderEntry("animatn", TRUE));
addEntry(LLFolderType::FT_GESTURE, new FolderEntry("gesture", TRUE));
addEntry(LLFolderType::FT_FAVORITE, new FolderEntry("favorite", TRUE));
// TYPE NAME, PROTECTED, AUTOMATIC, SINGLETON
addEntry(LLFolderType::FT_TEXTURE, new FolderEntry("texture", TRUE, TRUE, TRUE));
addEntry(LLFolderType::FT_SOUND, new FolderEntry("sound", TRUE, TRUE, TRUE));
addEntry(LLFolderType::FT_CALLINGCARD, new FolderEntry("callcard", TRUE, TRUE, FALSE));
addEntry(LLFolderType::FT_LANDMARK, new FolderEntry("landmark", TRUE, FALSE, FALSE));
addEntry(LLFolderType::FT_CLOTHING, new FolderEntry("clothing", TRUE, TRUE, TRUE));
addEntry(LLFolderType::FT_OBJECT, new FolderEntry("object", TRUE, TRUE, TRUE));
addEntry(LLFolderType::FT_NOTECARD, new FolderEntry("notecard", TRUE, TRUE, TRUE));
addEntry(LLFolderType::FT_ROOT_INVENTORY, new FolderEntry("root_inv", TRUE, TRUE, TRUE));
addEntry(LLFolderType::FT_LSL_TEXT, new FolderEntry("lsltext", TRUE, TRUE, TRUE));
addEntry(LLFolderType::FT_BODYPART, new FolderEntry("bodypart", TRUE, TRUE, TRUE));
addEntry(LLFolderType::FT_TRASH, new FolderEntry("trash", TRUE, FALSE, TRUE));
addEntry(LLFolderType::FT_SNAPSHOT_CATEGORY, new FolderEntry("snapshot", TRUE, TRUE, TRUE));
addEntry(LLFolderType::FT_LOST_AND_FOUND, new FolderEntry("lstndfnd", TRUE, TRUE, TRUE));
addEntry(LLFolderType::FT_ANIMATION, new FolderEntry("animatn", TRUE, TRUE, TRUE));
addEntry(LLFolderType::FT_GESTURE, new FolderEntry("gesture", TRUE, TRUE, TRUE));
addEntry(LLFolderType::FT_FAVORITE, new FolderEntry("favorite", TRUE, FALSE, TRUE));
for (S32 ensemble_num = S32(LLFolderType::FT_ENSEMBLE_START); ensemble_num <= S32(LLFolderType::FT_ENSEMBLE_END); ensemble_num++)
{
addEntry(LLFolderType::EType(ensemble_num), new FolderEntry("ensemble", FALSE));
addEntry(LLFolderType::EType(ensemble_num), new FolderEntry("ensemble", FALSE, FALSE, FALSE)); // Not used
}
addEntry(LLFolderType::FT_CURRENT_OUTFIT, new FolderEntry("current", TRUE));
addEntry(LLFolderType::FT_OUTFIT, new FolderEntry("outfit", FALSE));
addEntry(LLFolderType::FT_MY_OUTFITS, new FolderEntry("my_otfts", TRUE));
addEntry(LLFolderType::FT_CURRENT_OUTFIT, new FolderEntry("current", TRUE, FALSE, TRUE));
addEntry(LLFolderType::FT_OUTFIT, new FolderEntry("outfit", FALSE, FALSE, FALSE));
addEntry(LLFolderType::FT_MY_OUTFITS, new FolderEntry("my_otfts", TRUE, FALSE, TRUE));
addEntry(LLFolderType::FT_MESH, new FolderEntry("mesh", TRUE));
addEntry(LLFolderType::FT_MESH, new FolderEntry("mesh", TRUE, FALSE, FALSE)); // Not used?
addEntry(LLFolderType::FT_INBOX, new FolderEntry("inbox", TRUE));
addEntry(LLFolderType::FT_OUTBOX, new FolderEntry("outbox", FALSE)); // <FS:Ansariel> Make obsolete Merchant Outbox folder deletable
addEntry(LLFolderType::FT_INBOX, new FolderEntry("inbox", TRUE, FALSE, TRUE));
addEntry(LLFolderType::FT_OUTBOX, new FolderEntry("outbox", FALSE, FALSE, FALSE)); // <FS:Ansariel> Make obsolete Merchant Outbox folder deletable
addEntry(LLFolderType::FT_BASIC_ROOT, new FolderEntry("basic_rt", TRUE));
addEntry(LLFolderType::FT_BASIC_ROOT, new FolderEntry("basic_rt", TRUE, FALSE, FALSE));
addEntry(LLFolderType::FT_MARKETPLACE_LISTINGS, new FolderEntry("merchant", FALSE));
addEntry(LLFolderType::FT_MARKETPLACE_STOCK, new FolderEntry("stock", FALSE));
addEntry(LLFolderType::FT_MARKETPLACE_VERSION, new FolderEntry("version", FALSE));
addEntry(LLFolderType::FT_MARKETPLACE_LISTINGS, new FolderEntry("merchant", FALSE, FALSE, FALSE));
addEntry(LLFolderType::FT_MARKETPLACE_STOCK, new FolderEntry("stock", FALSE, FALSE, FALSE));
addEntry(LLFolderType::FT_MARKETPLACE_VERSION, new FolderEntry("version", FALSE, FALSE, FALSE));
addEntry(LLFolderType::FT_SETTINGS, new FolderEntry("settings", TRUE));
addEntry(LLFolderType::FT_SETTINGS, new FolderEntry("settings", TRUE, FALSE, TRUE));
addEntry(LLFolderType::FT_MY_SUITCASE, new FolderEntry("suitcase", TRUE)); // <FS:Ansariel> OpenSim HG-support
addEntry(LLFolderType::FT_MY_SUITCASE, new FolderEntry("suitcase", TRUE, FALSE, TRUE)); // <FS:Ansariel> OpenSim HG-support
addEntry(LLFolderType::FT_NONE, new FolderEntry("-1", FALSE));
addEntry(LLFolderType::FT_NONE, new FolderEntry("-1", FALSE, FALSE, FALSE));
};
// static
@ -128,8 +149,8 @@ const std::string &LLFolderType::lookup(LLFolderType::EType folder_type)
}
// static
// Only ensembles and plain folders aren't protected. "Protected" means
// you can't change certain properties such as their type.
// Only plain folders and a few other types aren't protected. "Protected" means
// you can't move, deleted, or change certain properties such as their type.
bool LLFolderType::lookupIsProtectedType(EType folder_type)
{
const LLFolderDictionary *dict = LLFolderDictionary::getInstance();
@ -140,6 +161,32 @@ bool LLFolderType::lookupIsProtectedType(EType folder_type)
}
return true;
}
// static
// Is this folder type automatically created outside the viewer?
bool LLFolderType::lookupIsAutomaticType(EType folder_type)
{
const LLFolderDictionary *dict = LLFolderDictionary::getInstance();
const FolderEntry *entry = dict->lookup(folder_type);
if (entry)
{
return entry->mIsAutomatic;
}
return true;
}
// static
// Should this folder always exist as a single copy under (or as) the root?
bool LLFolderType::lookupIsSingletonType(EType folder_type)
{
const LLFolderDictionary *dict = LLFolderDictionary::getInstance();
const FolderEntry *entry = dict->lookup(folder_type);
if (entry)
{
return entry->mIsSingleton;
}
return true;
}
// static
bool LLFolderType::lookupIsEnsembleType(EType folder_type)

View File

@ -110,6 +110,8 @@ public:
static const std::string& lookup(EType folder_type);
static bool lookupIsProtectedType(EType folder_type);
static bool lookupIsAutomaticType(EType folder_type);
static bool lookupIsSingletonType(EType folder_type);
static bool lookupIsEnsembleType(EType folder_type);
static LLAssetType::EType folderTypeToAssetType(LLFolderType::EType folder_type);

View File

@ -2469,7 +2469,14 @@ bool LLVolume::unpackVolumeFacesInternal(const LLSD& mdl)
//copy out indices
face.resizeIndices(idx.size()/2);
S32 num_indices = idx.size() / 2;
face.resizeIndices(num_indices);
if (num_indices > 2 && !face.mIndices)
{
LL_WARNS() << "Failed to allocate " << num_indices << " indices for face index: " << i << " Total: " << face_count << LL_ENDL;
continue;
}
if (idx.empty() || face.mNumIndices < 3)
{ //why is there an empty index list?
@ -2488,6 +2495,13 @@ bool LLVolume::unpackVolumeFacesInternal(const LLSD& mdl)
U32 num_verts = pos.size()/(3*2);
face.resizeVertices(num_verts);
if (num_verts > 0 && !face.mPositions)
{
LL_WARNS() << "Failed to allocate " << num_verts << " vertices for face index: " << i << " Total: " << face_count << LL_ENDL;
face.resizeIndices(0);
continue;
}
LLVector3 minp;
LLVector3 maxp;
LLVector2 min_tc;
@ -2589,6 +2603,13 @@ bool LLVolume::unpackVolumeFacesInternal(const LLSD& mdl)
if (mdl[i].has("Weights"))
{
face.allocateWeights(num_verts);
if (!face.mWeights && num_verts)
{
LL_WARNS() << "Failed to allocate " << num_verts << " weights for face index: " << i << " Total: " << face_count << LL_ENDL;
face.resizeIndices(0);
face.resizeVertices(0);
continue;
}
LLSD::Binary weights = mdl[i]["Weights"];
@ -5393,22 +5414,23 @@ bool LLVolumeFace::cacheOptimize()
{
triangle_data.resize(mNumIndices / 3);
vertex_data.resize(mNumVertices);
}
catch (std::bad_alloc&)
{
LL_WARNS("LLVOLUME") << "Resize failed" << LL_ENDL;
return false;
}
for (U32 i = 0; i < mNumIndices; i++)
{ //populate vertex data and triangle data arrays
U16 idx = mIndices[i];
U32 tri_idx = i/3;
for (U32 i = 0; i < mNumIndices; i++)
{ //populate vertex data and triangle data arrays
U16 idx = mIndices[i];
U32 tri_idx = i / 3;
vertex_data[idx].mTriangles.push_back(&(triangle_data[tri_idx]));
vertex_data[idx].mIdx = idx;
triangle_data[tri_idx].mVertex[i%3] = &(vertex_data[idx]);
}
vertex_data[idx].mTriangles.push_back(&(triangle_data[tri_idx]));
vertex_data[idx].mIdx = idx;
triangle_data[tri_idx].mVertex[i % 3] = &(vertex_data[idx]);
}
}
catch (std::bad_alloc&)
{
// resize or push_back failed
LL_WARNS("LLVOLUME") << "Resize for " << mNumVertices << " vertices failed" << LL_ENDL;
return false;
}
/*F32 pre_acmr = 1.f;
//measure cache misses from before rebuild
@ -6456,8 +6478,18 @@ void LLVolumeFace::resizeVertices(S32 num_verts)
mTexCoords = NULL;
}
mNumVertices = num_verts;
mNumAllocatedVertices = num_verts;
if (mPositions)
{
mNumVertices = num_verts;
mNumAllocatedVertices = num_verts;
}
else
{
// Either num_verts is zero or allocation failure
mNumVertices = 0;
mNumAllocatedVertices = 0;
}
// Force update
mJointRiggingInfoTab.clear();
@ -6558,7 +6590,15 @@ void LLVolumeFace::resizeIndices(S32 num_indices)
mIndices = NULL;
}
mNumIndices = num_indices;
if (mIndices)
{
mNumIndices = num_indices;
}
else
{
// Either num_indices is zero or allocation failure
mNumIndices = 0;
}
}
void LLVolumeFace::pushIndex(const U16& idx)

View File

@ -1,4 +1,4 @@
#!/usr/bin/env python
#!/usr/bin/env python3
"""\
@file test_llsdmessage_peer.py
@author Nat Goodspeed
@ -31,7 +31,7 @@ $/LicenseInfo$
import os
import sys
from BaseHTTPServer import HTTPServer, BaseHTTPRequestHandler
from http.server import HTTPServer, BaseHTTPRequestHandler
from llbase.fastest_elementtree import parse as xml_parse
from llbase import llsd
@ -165,7 +165,7 @@ if __name__ == "__main__":
# "Then there's Windows"
# Instantiate a Server(TestHTTPRequestHandler) on the first free port
# in the specified port range.
httpd, port = freeport(xrange(8000, 8020), make_server)
httpd, port = freeport(range(8000, 8020), make_server)
# Pass the selected port number to the subject test program via the
# environment. We don't want to impose requirements on the test program's

View File

@ -1,4 +1,4 @@
#!/usr/bin/env python
#!/usr/bin/env python3
"""\
@file testrunner.py
@author Nat Goodspeed
@ -41,7 +41,7 @@ VERBOSE = not re.match(r"(0|off|false|quiet)$", VERBOSE, re.IGNORECASE)
if VERBOSE:
def debug(fmt, *args):
print fmt % args
print(fmt % args)
sys.stdout.flush()
else:
debug = lambda *args: None
@ -99,14 +99,14 @@ def freeport(portlist, expr):
# error because we can't return meaningful values. We have no 'port',
# therefore no 'expr(port)'.
portiter = iter(portlist)
port = portiter.next()
port = next(portiter)
while True:
try:
# If this value of port works, return as promised.
value = expr(port)
except socket.error, err:
except socket.error as err:
# Anything other than 'Address already in use', propagate
if err.args[0] != errno.EADDRINUSE:
raise
@ -117,9 +117,9 @@ def freeport(portlist, expr):
type, value, tb = sys.exc_info()
try:
try:
port = portiter.next()
port = next(portiter)
except StopIteration:
raise type, value, tb
raise type(value).with_traceback(tb)
finally:
# Clean up local traceback, see docs for sys.exc_info()
del tb
@ -138,7 +138,7 @@ def freeport(portlist, expr):
# If we've actually arrived at this point, portiter.next() delivered a
# new port value. Loop back to pass that to expr(port).
except Exception, err:
except Exception as err:
debug("*** freeport() raising %s: %s", err.__class__.__name__, err)
raise
@ -227,13 +227,13 @@ def test_freeport():
def exc(exception_class, *args):
try:
yield
except exception_class, err:
except exception_class as err:
for i, expected_arg in enumerate(args):
assert expected_arg == err.args[i], \
"Raised %s, but args[%s] is %r instead of %r" % \
(err.__class__.__name__, i, err.args[i], expected_arg)
print "Caught expected exception %s(%s)" % \
(err.__class__.__name__, ', '.join(repr(arg) for arg in err.args))
print("Caught expected exception %s(%s)" % \
(err.__class__.__name__, ', '.join(repr(arg) for arg in err.args)))
else:
assert False, "Failed to raise " + exception_class.__class__.__name__
@ -270,18 +270,18 @@ def test_freeport():
# This is the magic exception that should prompt us to retry
inuse = socket.error(errno.EADDRINUSE, 'Address already in use')
# Get the iterator to our ports list so we can check later if we've used all
ports = iter(xrange(5))
ports = iter(range(5))
with exc(socket.error, errno.EADDRINUSE):
freeport(ports, lambda port: raiser(inuse))
# did we entirely exhaust 'ports'?
with exc(StopIteration):
ports.next()
next(ports)
ports = iter(xrange(2))
ports = iter(range(2))
# Any exception but EADDRINUSE should quit immediately
with exc(SomeError):
freeport(ports, lambda port: raiser(SomeError()))
assert_equals(ports.next(), 1)
assert_equals(next(ports), 1)
# ----------- freeport() with platform-dependent socket stuff ------------
# This is what we should've had unit tests to begin with (see CHOP-661).
@ -290,14 +290,14 @@ def test_freeport():
sock.bind(('127.0.0.1', port))
return sock
bound0, port0 = freeport(xrange(7777, 7780), newbind)
bound0, port0 = freeport(range(7777, 7780), newbind)
assert_equals(port0, 7777)
bound1, port1 = freeport(xrange(7777, 7780), newbind)
bound1, port1 = freeport(range(7777, 7780), newbind)
assert_equals(port1, 7778)
bound2, port2 = freeport(xrange(7777, 7780), newbind)
bound2, port2 = freeport(range(7777, 7780), newbind)
assert_equals(port2, 7779)
with exc(socket.error, errno.EADDRINUSE):
bound3, port3 = freeport(xrange(7777, 7780), newbind)
bound3, port3 = freeport(range(7777, 7780), newbind)
if __name__ == "__main__":
test_freeport()

View File

@ -82,8 +82,29 @@ protected:
};
class LLPluginProcessCreationThread : public LLThread
{
public:
LLPluginProcessCreationThread(LLPluginProcessParent *parent) :
LLThread("LLPluginProcessCreationThread", gAPRPoolp),
pParent(parent)
{
}
protected:
// Inherited from LLThread, should run once
/*virtual*/ void run(void)
{
pParent->createPluginProcess();
}
private:
LLPluginProcessParent *pParent;
};
LLPluginProcessParent::LLPluginProcessParent(LLPluginProcessParentOwner *owner):
mIncomingQueueMutex()
mIncomingQueueMutex(),
pProcessCreationThread(NULL)
{
if(!sInstancesMutex)
{
@ -112,6 +133,18 @@ LLPluginProcessParent::LLPluginProcessParent(LLPluginProcessParentOwner *owner):
LLPluginProcessParent::~LLPluginProcessParent()
{
LL_DEBUGS("Plugin") << "destructor" << LL_ENDL;
if (pProcessCreationThread)
{
if (!pProcessCreationThread->isStopped())
{
// Shouldn't happen at this stage
LL_WARNS("Plugin") << "Shutting down active pProcessCreationThread" << LL_ENDL;
pProcessCreationThread->shutdown();
ms_sleep(20);
}
delete pProcessCreationThread;
pProcessCreationThread = NULL;
}
// Destroy any remaining shared memory regions
sharedMemoryRegionsType::iterator iter;
@ -162,6 +195,7 @@ void LLPluginProcessParent::shutdown()
&& state != STATE_ERROR)
{
(*it).second->setState(STATE_GOODBYE);
(*it).second->mOwner = NULL;
}
if (state != STATE_DONE)
{
@ -321,6 +355,35 @@ bool LLPluginProcessParent::accept()
return result;
}
bool LLPluginProcessParent::createPluginProcess()
{
if (!mProcess)
{
// Only argument to the launcher is the port number we're listening on
mProcessParams.args.add(stringize(mBoundPort));
mProcess = LLProcess::create(mProcessParams);
return mProcess != NULL;
}
return false;
}
void LLPluginProcessParent::clearProcessCreationThread()
{
if (pProcessCreationThread)
{
if (!pProcessCreationThread->isStopped())
{
pProcessCreationThread->shutdown();
}
else
{
delete pProcessCreationThread;
pProcessCreationThread = NULL;
}
}
}
void LLPluginProcessParent::idle(void)
{
bool idle_again;
@ -328,8 +391,9 @@ void LLPluginProcessParent::idle(void)
do
{
// process queued messages
mIncomingQueueMutex.lock();
while(!mIncomingQueue.empty())
// Inside main thread, it is preferable not to block it on mutex.
bool locked = mIncomingQueueMutex.trylock();
while(locked && !mIncomingQueue.empty())
{
LLPluginMessage message = mIncomingQueue.front();
mIncomingQueue.pop();
@ -337,10 +401,13 @@ void LLPluginProcessParent::idle(void)
receiveMessage(message);
mIncomingQueueMutex.lock();
locked = mIncomingQueueMutex.trylock();
}
mIncomingQueueMutex.unlock();
if (locked)
{
mIncomingQueueMutex.unlock();
}
// Give time to network processing
if(mMessagePipe)
@ -349,7 +416,10 @@ void LLPluginProcessParent::idle(void)
mMessagePipe->pumpOutput();
// Only do input processing here if this instance isn't in a pollset.
if(!mPolledInput)
// If viewer and plugin are both shutting down, don't process further
// input, viewer won't be able to handle it.
if(!mPolledInput
&& !(mState >= STATE_GOODBYE && LLApp::isExiting()))
{
mMessagePipe->pumpInput();
}
@ -488,15 +558,30 @@ void LLPluginProcessParent::idle(void)
case STATE_LISTENING:
{
// Launch the plugin process.
if (mDebug && !pProcessCreationThread)
{
createPluginProcess();
if (!mProcess)
{
errorState();
}
}
else if (pProcessCreationThread == NULL)
{
// exe plugin process allocation can be hindered by a number
// of factors, don't hold whole viewer because of it, use thread
pProcessCreationThread = new LLPluginProcessCreationThread(this);
pProcessCreationThread->start();
}
else if (!mProcess && pProcessCreationThread->isStopped())
{
delete pProcessCreationThread;
pProcessCreationThread = NULL;
errorState();
}
// Only argument to the launcher is the port number we're listening on
mProcessParams.args.add(stringize(mBoundPort));
if (! (mProcess = LLProcess::create(mProcessParams)))
{
errorState();
}
else
if (mProcess)
{
if(mDebug)
{
@ -525,6 +610,15 @@ void LLPluginProcessParent::idle(void)
// This will allow us to time out if the process never starts.
mHeartbeat.start();
mHeartbeat.setTimerExpirySec(mPluginLaunchTimeout);
// pProcessCreationThread should have stopped by this point,
// but check just in case it paused on statistics sync
if (pProcessCreationThread && pProcessCreationThread->isStopped())
{
delete pProcessCreationThread;
pProcessCreationThread = NULL;
}
setState(STATE_LAUNCHED);
}
}
@ -627,6 +721,7 @@ void LLPluginProcessParent::idle(void)
killSockets();
setState(STATE_DONE);
dirtyPollSet();
clearProcessCreationThread();
break;
case STATE_DONE:

View File

@ -69,6 +69,11 @@ public:
const std::string &plugin_filename,
bool debug);
// Creates a process
// returns true if process already exists or if created,
// false if failed to create
bool createPluginProcess();
void idle(void);
// returns true if the plugin is on its way to steady state
@ -163,12 +168,15 @@ private:
bool accept();
void clearProcessCreationThread();
LLSocket::ptr_t mListenSocket;
LLSocket::ptr_t mSocket;
U32 mBoundPort;
LLProcess::Params mProcessParams;
LLProcessPtr mProcess;
LLThread *pProcessCreationThread;
std::string mPluginFile;
std::string mPluginDir;

View File

@ -252,6 +252,17 @@ LLModel::EModelStatus load_face_from_dom_triangles(
}
LLVolumeFace::VertexMapData::PointMap point_map;
if (idx_stride <= 0
|| (pos_source && pos_offset >= idx_stride)
|| (tc_source && tc_offset >= idx_stride)
|| (norm_source && norm_offset >= idx_stride))
{
// Looks like these offsets should fit inside idx_stride
// Might be good idea to also check idx.getCount()%idx_stride != 0
LL_WARNS() << "Invalid pos_offset " << pos_offset << ", tc_offset " << tc_offset << " or norm_offset " << norm_offset << LL_ENDL;
return LLModel::BAD_ELEMENT;
}
for (U32 i = 0; i < idx.getCount(); i += idx_stride)
{

View File

@ -606,6 +606,58 @@ void LLFloaterReg::toggleInstanceOrBringToFront(const LLSD& sdname, const LLSD&
}
}
// static
// Same as toggleInstanceOrBringToFront but does not close floater.
// unlike showInstance() does not trigger onOpen() if already open
void LLFloaterReg::showInstanceOrBringToFront(const LLSD& sdname, const LLSD& key)
{
std::string name = sdname.asString();
LLFloater* instance = getInstance(name, key);
if (!instance)
{
LL_DEBUGS() << "Unable to get instance of floater '" << name << "'" << LL_ENDL;
return;
}
// If hosted, we need to take that into account
LLFloater* host = instance->getHost();
if (host)
{
if (host->isMinimized() || !host->isShown() || !host->isFrontmost())
{
host->setMinimized(FALSE);
instance->openFloater(key);
instance->setVisibleAndFrontmost(true, key);
}
else if (!instance->getVisible())
{
instance->openFloater(key);
instance->setVisibleAndFrontmost(true, key);
instance->setFocus(TRUE);
}
}
else
{
if (instance->isMinimized())
{
instance->setMinimized(FALSE);
instance->setVisibleAndFrontmost(true, key);
}
else if (!instance->isShown())
{
instance->openFloater(key);
instance->setVisibleAndFrontmost(true, key);
}
else if (!instance->isFrontmost())
{
instance->setVisibleAndFrontmost(true, key);
}
}
}
// static
U32 LLFloaterReg::getVisibleFloaterInstanceCount()
{

View File

@ -158,6 +158,7 @@ public:
// Callback wrappers
static void toggleInstanceOrBringToFront(const LLSD& sdname, const LLSD& key = LLSD());
static void showInstanceOrBringToFront(const LLSD& sdname, const LLSD& key = LLSD());
// Typed find / get / show
template <class T>

View File

@ -260,6 +260,8 @@ LLFolderView::LLFolderView(const Params& p)
mPopupMenuHandle = menu->getHandle();
mViewModelItem->openItem();
mAreChildrenInited = true; // root folder is a special case due to not being loaded normally, assume that it's inited.
}
// Destroys the object

View File

@ -139,7 +139,6 @@ LLFolderViewItem::LLFolderViewItem(const LLFolderViewItem::Params& p)
mCutGeneration(0),
mLabelStyle( LLFontGL::NORMAL ),
mHasVisibleChildren(FALSE),
mIsFolderComplete(true),
mLocalIndentation(p.folder_indentation),
mIndentation(0),
mItemHeight(p.item_height),
@ -1118,11 +1117,11 @@ LLFolderViewFolder::LLFolderViewFolder( const LLFolderViewItem::Params& p ):
mCurHeight(0.f),
mTargetHeight(0.f),
mAutoOpenCountdown(0.f),
mIsFolderComplete(false), // folder might have children that are not loaded yet.
mAreChildrenInited(false), // folder might have children that are not built yet.
mLastArrangeGeneration( -1 ),
mLastCalculatedWidth(0)
{
// folder might have children that are not loaded yet. Mark it as incomplete until chance to check it.
mIsFolderComplete = false;
}
void LLFolderViewFolder::updateLabelRotation()
@ -1178,13 +1177,16 @@ S32 LLFolderViewFolder::arrange( S32* width, S32* height )
{
// Sort before laying out contents
// Note that we sort from the root (CHUI-849)
getRoot()->getFolderViewModel()->sort(this);
if (mAreChildrenInited)
{
getRoot()->getFolderViewModel()->sort(this);
}
LL_RECORD_BLOCK_TIME(FTM_ARRANGE);
// evaluate mHasVisibleChildren
mHasVisibleChildren = false;
if (getViewModelItem()->descendantsPassedFilter())
if (mAreChildrenInited && getViewModelItem()->descendantsPassedFilter())
{
// We have to verify that there's at least one child that's not filtered out
bool found = false;
@ -1210,7 +1212,7 @@ S32 LLFolderViewFolder::arrange( S32* width, S32* height )
mHasVisibleChildren = found;
}
if (!mIsFolderComplete)
if (!mIsFolderComplete && mAreChildrenInited)
{
mIsFolderComplete = getFolderViewModel()->isFolderComplete(this);
}

View File

@ -120,7 +120,6 @@ protected:
F32 mControlLabelRotation;
LLFolderView* mRoot;
bool mHasVisibleChildren,
mIsFolderComplete, // indicates that some children were not loaded/added yet
mIsCurSelection,
mDragAndDropTarget,
mIsMouseOverTitle,
@ -229,7 +228,10 @@ public:
BOOL hasVisibleChildren() { return mHasVisibleChildren; }
// true if object can't have children
BOOL isFolderComplete() { return mIsFolderComplete; }
virtual bool isFolderComplete() { return true; }
// true if object can't have children
virtual bool areChildrenInited() { return true; }
virtual void setChildrenInited(bool inited) { }
// Call through to the viewed object and return true if it can be
// removed. Returns true if it's removed.
@ -349,6 +351,8 @@ protected:
S32 mLastArrangeGeneration;
S32 mLastCalculatedWidth;
// bool mNeedsSort; <FS:ND/> Unused.
bool mIsFolderComplete; // indicates that some children were not loaded/added yet
bool mAreChildrenInited; // indicates that no children were initialized
public:
typedef enum e_recurse_type
@ -400,6 +404,13 @@ public:
// destroys this folder, and all children
virtual void destroyView();
// whether known children are fully loaded (arrange sets to true)
virtual bool isFolderComplete() { return mIsFolderComplete; }
// whether known children are fully built
virtual bool areChildrenInited() { return mAreChildrenInited; }
virtual void setChildrenInited(bool inited) { mAreChildrenInited = inited; }
// extractItem() removes the specified item from the folder, but
// doesn't delete it.
virtual void extractItem( LLFolderViewItem* item, bool deparent_model = true);

View File

@ -500,8 +500,7 @@ LLNotification::LLNotification(const LLSDParamAdapter<Params>& p) :
mResponderObj(NULL),
mId(p.id.isProvided() ? p.id : LLUUID::generateNewID()),
mOfferFromAgent(p.offer_from_agent),
mIsDND(p.is_dnd),
mIsFromStorage(false)// <FS:Ansariel> FIRE-11339: Persisted group notifications get logged to IM on each login
mIsDND(p.is_dnd)
{
if (p.functor.name.isChosen())
{
@ -1710,6 +1709,20 @@ void LLNotifications::add(const LLNotificationPtr pNotif)
updateItem(LLSD().with("sigtype", "add").with("id", pNotif->id()), pNotif);
}
void LLNotifications::load(const LLNotificationPtr pNotif)
{
if (pNotif == NULL) return;
// first see if we already have it -- if so, that's a problem
LLNotificationSet::iterator it=mItems.find(pNotif);
if (it != mItems.end())
{
LL_ERRS() << "Notification loaded a second time to the master notification channel." << LL_ENDL;
}
updateItem(LLSD().with("sigtype", "load").with("id", pNotif->id()), pNotif);
}
void LLNotifications::cancel(LLNotificationPtr pNotif)
{
if (pNotif == NULL || pNotif->isCancelled()) return;

View File

@ -399,7 +399,6 @@ private:
LLNotificationResponderPtr mResponder;
bool mOfferFromAgent;
bool mIsDND;
bool mIsFromStorage; // <FS:Ansariel> FIRE-11339: Persisted group notifications get logged to IM on each login
// a reference to the template
LLNotificationTemplatePtr mTemplatep;
@ -557,18 +556,6 @@ public:
mIsDND = flag;
}
// <FS:Ansariel> FIRE-11339: Persisted group notifications get logged to IM on each login
bool isFromStorage() const
{
return mIsFromStorage;
}
void setIsFromStorage(bool logged)
{
mIsFromStorage = logged;
}
// </FS:Ansariel>
std::string getType() const;
std::string getMessage() const;
std::string getFooter() const;
@ -936,6 +923,7 @@ public:
LLNotificationPtr add(const LLNotification::Params& p);
void add(const LLNotificationPtr pNotif);
void load(const LLNotificationPtr pNotif);
void cancel(LLNotificationPtr pNotif);
void cancelByName(const std::string& name);
void cancelByOwner(const LLUUID ownerId);
@ -1139,6 +1127,11 @@ private:
mHistory.push_back(p);
}
void onLoad(LLNotificationPtr p)
{
mHistory.push_back(p);
}
std::vector<LLNotificationPtr> mHistory;
};

View File

@ -83,6 +83,14 @@ const LLSD LLScrollListCell::getValue() const
return LLStringUtil::null;
}
// virtual
const LLSD LLScrollListCell::getAltValue() const
{
return LLStringUtil::null;
}
//
// LLScrollListIcon
//
@ -245,6 +253,7 @@ U32 LLScrollListText::sCount = 0;
LLScrollListText::LLScrollListText(const LLScrollListCell::Params& p)
: LLScrollListCell(p),
mText(p.label.isProvided() ? p.label() : p.value().asString()),
mAltText(p.alt_value().asString()),
mFont(p.font),
mColor(p.color),
mUseColor(p.color.isProvided()),
@ -347,10 +356,22 @@ void LLScrollListText::setValue(const LLSD& text)
setText(text.asString());
}
//virtual
void LLScrollListText::setAltValue(const LLSD& text)
{
mAltText = text.asString();
}
//virtual
const LLSD LLScrollListText::getValue() const
{
return LLSD(mText.getString());
return LLSD(mText.getString());
}
//virtual
const LLSD LLScrollListText::getAltValue() const
{
return LLSD(mAltText.getString());
}

View File

@ -61,6 +61,7 @@ public:
Optional<void*> userdata;
Optional<LLSD> value; // state of checkbox, icon id/name, date
Optional<LLSD> alt_value;
Optional<std::string> label; // description or text
Optional<std::string> tool_tip;
@ -77,6 +78,7 @@ public:
enabled("enabled", true),
visible("visible", true),
value("value"),
alt_value("alt_value", ""),
label("label"),
tool_tip("tool_tip", ""),
font("font", LLFontGL::getFontSansSerifSmall()),
@ -99,7 +101,9 @@ public:
virtual S32 getContentWidth() const { return 0; }
virtual S32 getHeight() const { return 0; }
virtual const LLSD getValue() const;
virtual const LLSD getAltValue() const;
virtual void setValue(const LLSD& value) { }
virtual void setAltValue(const LLSD& value) { }
virtual const std::string &getToolTip() const { return mToolTip; }
virtual void setToolTip(const std::string &str) { mToolTip = str; }
virtual BOOL getVisible() const { return TRUE; }
@ -139,7 +143,9 @@ public:
/*virtual*/ S32 getContentWidth() const;
/*virtual*/ S32 getHeight() const;
/*virtual*/ void setValue(const LLSD& value);
/*virtual*/ void setAltValue(const LLSD& value);
/*virtual*/ const LLSD getValue() const;
/*virtual*/ const LLSD getAltValue() const;
/*virtual*/ BOOL getVisible() const;
/*virtual*/ void highlightText(S32 offset, S32 num_chars);
@ -158,6 +164,7 @@ public:
protected:
LLUIString mText;
LLUIString mAltText;
S32 mTextWidth;
const LLFontGL* mFont;
LLColor4 mColor;

View File

@ -68,9 +68,10 @@ static LLDefaultChildRegistry::Register<LLScrollListCtrl> r("scroll_list");
// local structures & classes.
struct SortScrollListItem
{
SortScrollListItem(const std::vector<std::pair<S32, BOOL> >& sort_orders,const LLScrollListCtrl::sort_signal_t* sort_signal)
SortScrollListItem(const std::vector<std::pair<S32, BOOL> >& sort_orders,const LLScrollListCtrl::sort_signal_t* sort_signal, bool alternate_sort)
: mSortOrders(sort_orders)
, mSortSignal(sort_signal)
, mAltSort(alternate_sort)
{}
bool operator()(const LLScrollListItem* i1, const LLScrollListItem* i2)
@ -95,7 +96,14 @@ struct SortScrollListItem
}
else
{
sort_result = order * LLStringUtil::compareDict(cell1->getValue().asString(), cell2->getValue().asString());
if (mAltSort && !cell1->getAltValue().asString().empty() && !cell2->getAltValue().asString().empty())
{
sort_result = order * LLStringUtil::compareDict(cell1->getAltValue().asString(), cell2->getAltValue().asString());
}
else
{
sort_result = order * LLStringUtil::compareDict(cell1->getValue().asString(), cell2->getValue().asString());
}
}
if (sort_result != 0)
{
@ -111,6 +119,7 @@ struct SortScrollListItem
typedef std::vector<std::pair<S32, BOOL> > sort_order_t;
const LLScrollListCtrl::sort_signal_t* mSortSignal;
const sort_order_t& mSortOrders;
const bool mAltSort;
};
//---------------------------------------------------------------------------
@ -219,6 +228,7 @@ LLScrollListCtrl::LLScrollListCtrl(const LLScrollListCtrl::Params& p)
mSearchColumn(p.search_column),
mColumnPadding(p.column_padding),
mRowPadding(p.row_padding),
mAlternateSort(false),
mContextMenuType(MENU_NONE),
mIsFriendSignal(NULL),
// <FS:Ansariel> Fix for FS-specific people list (radar)
@ -400,8 +410,7 @@ LLScrollListCtrl::~LLScrollListCtrl()
std::for_each(mItemList.begin(), mItemList.end(), DeletePointer());
mItemList.clear();
std::for_each(mColumns.begin(), mColumns.end(), DeletePairedPointer());
mColumns.clear();
clearColumns(); //clears columns and deletes headers
delete mIsFriendSignal;
}
@ -3098,7 +3107,7 @@ void LLScrollListCtrl::updateSort() const
std::stable_sort(
mItemList.begin(),
mItemList.end(),
SortScrollListItem(mSortColumns,mSortCallback));
SortScrollListItem(mSortColumns,mSortCallback, mAlternateSort));
mSorted = true;
}
@ -3114,7 +3123,7 @@ void LLScrollListCtrl::sortOnce(S32 column, BOOL ascending)
std::stable_sort(
mItemList.begin(),
mItemList.end(),
SortScrollListItem(sort_column,mSortCallback));
SortScrollListItem(sort_column,mSortCallback,mAlternateSort));
}
void LLScrollListCtrl::dirtyColumns()
@ -3480,6 +3489,8 @@ void LLScrollListCtrl::clearColumns()
// <FS:Ansariel> Reset number of dynamic columns, too
mNumDynamicWidthColumns = 0;
dirtyColumns(); // Clears mColumnsIndexed
}
void LLScrollListCtrl::setColumnLabel(const std::string& column, const std::string& label)

View File

@ -421,6 +421,8 @@ public:
BOOL hasSortOrder() const;
void clearSortOrder();
void setAlternateSort() { mAlternateSort = true; }
S32 selectMultiple( uuid_vec_t ids );
// conceptually const, but mutates mItemList
void updateSort() const;
@ -519,6 +521,8 @@ private:
bool mColumnsDirty;
bool mColumnWidthsDirty;
bool mAlternateSort;
mutable item_list mItemList;
LLScrollListItem *mLastSelected;

View File

@ -44,7 +44,8 @@ LLScrollListItem::LLScrollListItem( const Params& p )
mSelectedIndex(-1),
mEnabled(p.enabled),
mUserdata(p.userdata),
mItemValue(p.value)
mItemValue(p.value),
mItemAltValue(p.alt_value)
{
}

View File

@ -55,6 +55,7 @@ public:
Optional<bool> enabled;
Optional<void*> userdata;
Optional<LLSD> value;
Optional<LLSD> alt_value;
Ignored name; // use for localization tools
Ignored type;
@ -65,6 +66,7 @@ public:
Params()
: enabled("enabled", true),
value("value"),
alt_value("alt_value"),
name("name"),
type("type"),
length("length"),
@ -97,6 +99,7 @@ public:
virtual LLUUID getUUID() const { return mItemValue.asUUID(); }
LLSD getValue() const { return mItemValue; }
LLSD getAltValue() const { return mItemAltValue; }
void setRect(LLRect rect) { mRectangle = rect; }
LLRect getRect() const { return mRectangle; }
@ -131,6 +134,7 @@ private:
BOOL mEnabled;
void* mUserdata;
LLSD mItemValue;
LLSD mItemAltValue;
std::vector<LLScrollListCell *> mColumns;
LLRect mRectangle;
};

View File

@ -1661,11 +1661,14 @@ void LLTextBase::reflow()
{
// find first element whose end comes after start_index
line_list_t::iterator iter = std::upper_bound(mLineInfoList.begin(), mLineInfoList.end(), start_index, line_end_compare());
line_start_index = iter->mDocIndexStart;
line_count = iter->mLineNum;
cur_top = iter->mRect.mTop;
getSegmentAndOffset(iter->mDocIndexStart, &seg_iter, &seg_offset);
mLineInfoList.erase(iter, mLineInfoList.end());
if (iter != mLineInfoList.end())
{
line_start_index = iter->mDocIndexStart;
line_count = iter->mLineNum;
cur_top = iter->mRect.mTop;
getSegmentAndOffset(iter->mDocIndexStart, &seg_iter, &seg_offset);
mLineInfoList.erase(iter, mLineInfoList.end());
}
}
S32 line_height = 0;

View File

@ -1177,7 +1177,8 @@ LLToolBarButton* LLToolBar::createButton(const LLCommandId& id)
else
{
button->setFunctionName(commandp->executeFunctionName());
LL_DEBUGS("UIUsage") << "button function name b -> " << commandp->executeFunctionName() << LL_ENDL; // <FS:Ansariel> Check enabled state of button before executing!
LL_DEBUGS("UIUsage") << "button function name b -> " << commandp->executeFunctionName() << LL_ENDL;
// <FS:Ansariel> Check enabled state of button before executing!
//button->setCommitCallback(executeParam);
LLUICtrl::commit_callback_t execute_func = initCommitCallback(executeParam);
button->setCommitCallback(boost::bind(&LLToolBarButton::callIfEnabled, button, execute_func, _1, _2));

View File

@ -197,6 +197,7 @@ mHelpImpl(NULL)
reg.add("Floater.Toggle", boost::bind(&LLFloaterReg::toggleInstance, _2, LLSD()));
reg.add("Floater.ToggleOrBringToFront", boost::bind(&LLFloaterReg::toggleInstanceOrBringToFront, _2, LLSD()));
reg.add("Floater.Show", boost::bind(&LLFloaterReg::showInstance, _2, LLSD(), FALSE));
reg.add("Floater.ShowOrBringToFront", boost::bind(&LLFloaterReg::showInstanceOrBringToFront, _2, LLSD()));
reg.add("Floater.Hide", boost::bind(&LLFloaterReg::hideInstance, _2, LLSD()));
// Button initialization callback for toggle buttons

View File

@ -42,6 +42,7 @@ ECursorType getCursorFromString(const std::string& cursor_string)
cursor_string_table["UI_CURSOR_SIZENESW"] = UI_CURSOR_SIZENESW;
cursor_string_table["UI_CURSOR_SIZEWE"] = UI_CURSOR_SIZEWE;
cursor_string_table["UI_CURSOR_SIZENS"] = UI_CURSOR_SIZENS;
cursor_string_table["UI_CURSOR_SIZEALL"] = UI_CURSOR_SIZEALL;
cursor_string_table["UI_CURSOR_NO"] = UI_CURSOR_NO;
cursor_string_table["UI_CURSOR_WORKING"] = UI_CURSOR_WORKING;
cursor_string_table["UI_CURSOR_TOOLGRAB"] = UI_CURSOR_TOOLGRAB;
@ -61,6 +62,7 @@ ECursorType getCursorFromString(const std::string& cursor_string)
cursor_string_table["UI_CURSOR_TOOLCAMERA"] = UI_CURSOR_TOOLCAMERA;
cursor_string_table["UI_CURSOR_TOOLPAN"] = UI_CURSOR_TOOLPAN;
cursor_string_table["UI_CURSOR_TOOLZOOMIN"] = UI_CURSOR_TOOLZOOMIN;
cursor_string_table["UI_CURSOR_TOOLZOOMOUT"] = UI_CURSOR_TOOLZOOMOUT;
cursor_string_table["UI_CURSOR_TOOLPICKOBJECT3"] = UI_CURSOR_TOOLPICKOBJECT3;
cursor_string_table["UI_CURSOR_TOOLPLAY"] = UI_CURSOR_TOOLPLAY;
cursor_string_table["UI_CURSOR_TOOLPAUSE"] = UI_CURSOR_TOOLPAUSE;

View File

@ -38,6 +38,7 @@ enum ECursorType {
UI_CURSOR_SIZENESW,
UI_CURSOR_SIZEWE,
UI_CURSOR_SIZENS,
UI_CURSOR_SIZEALL,
UI_CURSOR_NO,
UI_CURSOR_WORKING,
UI_CURSOR_TOOLGRAB,
@ -57,6 +58,7 @@ enum ECursorType {
UI_CURSOR_TOOLCAMERA,
UI_CURSOR_TOOLPAN,
UI_CURSOR_TOOLZOOMIN,
UI_CURSOR_TOOLZOOMOUT,
UI_CURSOR_TOOLPICKOBJECT3,
UI_CURSOR_TOOLPLAY,
UI_CURSOR_TOOLPAUSE,

View File

@ -1433,6 +1433,7 @@ const char* cursorIDToName(int id)
case UI_CURSOR_SIZENESW: return "UI_CURSOR_SIZENESW";
case UI_CURSOR_SIZEWE: return "UI_CURSOR_SIZEWE";
case UI_CURSOR_SIZENS: return "UI_CURSOR_SIZENS";
case UI_CURSOR_SIZEALL: return "UI_CURSOR_SIZEALL";
case UI_CURSOR_NO: return "UI_CURSOR_NO";
case UI_CURSOR_WORKING: return "UI_CURSOR_WORKING";
case UI_CURSOR_TOOLGRAB: return "UI_CURSOR_TOOLGRAB";
@ -1452,6 +1453,7 @@ const char* cursorIDToName(int id)
case UI_CURSOR_TOOLCAMERA: return "UI_CURSOR_TOOLCAMERA";
case UI_CURSOR_TOOLPAN: return "UI_CURSOR_TOOLPAN";
case UI_CURSOR_TOOLZOOMIN: return "UI_CURSOR_TOOLZOOMIN";
case UI_CURSOR_TOOLZOOMOUT: return "UI_CURSOR_TOOLZOOMOUT";
case UI_CURSOR_TOOLPICKOBJECT3: return "UI_CURSOR_TOOLPICKOBJECT3";
case UI_CURSOR_TOOLPLAY: return "UI_CURSOR_TOOLPLAY";
case UI_CURSOR_TOOLPAUSE: return "UI_CURSOR_TOOLPAUSE";
@ -1630,6 +1632,7 @@ void LLWindowMacOSX::initCursors(BOOL useLegacyCursors)
initPixmapCursor(UI_CURSOR_TOOLCAMERA, 7, 6);
initPixmapCursor(UI_CURSOR_TOOLPAN, 7, 6);
initPixmapCursor(UI_CURSOR_TOOLZOOMIN, 7, 6);
initPixmapCursor(UI_CURSOR_TOOLZOOMOUT, 7, 6);
initPixmapCursor(UI_CURSOR_TOOLPICKOBJECT3, 1, 1);
initPixmapCursor(UI_CURSOR_TOOLPLAY, 1, 1);
initPixmapCursor(UI_CURSOR_TOOLPAUSE, 1, 1);
@ -1664,6 +1667,7 @@ void LLWindowMacOSX::initCursors(BOOL useLegacyCursors)
initPixmapCursor(UI_CURSOR_SIZENESW, 10, 10);
initPixmapCursor(UI_CURSOR_SIZEWE, 10, 10);
initPixmapCursor(UI_CURSOR_SIZENS, 10, 10);
initPixmapCursor(UI_CURSOR_SIZEALL, 10, 10);
}

View File

@ -2369,6 +2369,7 @@ void LLWindowSDL::initCursors(BOOL useLegacyCursors) // <FS:LO> Legacy cursor se
mSDLCursors[UI_CURSOR_SIZENESW] = makeSDLCursorFromBMP("sizenesw.BMP",17,17);
mSDLCursors[UI_CURSOR_SIZEWE] = makeSDLCursorFromBMP("sizewe.BMP",16,14);
mSDLCursors[UI_CURSOR_SIZENS] = makeSDLCursorFromBMP("sizens.BMP",17,16);
mSDLCursors[UI_CURSOR_SIZEALL] = makeSDLCursorFromBMP("sizeall.BMP", 17, 17);
mSDLCursors[UI_CURSOR_NO] = makeSDLCursorFromBMP("llno.BMP",8,8);
mSDLCursors[UI_CURSOR_WORKING] = makeSDLCursorFromBMP("working.BMP",12,15);
mSDLCursors[UI_CURSOR_TOOLGRAB] = makeSDLCursorFromBMP("lltoolgrab.BMP",2,13);
@ -2388,6 +2389,7 @@ void LLWindowSDL::initCursors(BOOL useLegacyCursors) // <FS:LO> Legacy cursor se
mSDLCursors[UI_CURSOR_TOOLCAMERA] = makeSDLCursorFromBMP("lltoolcamera.BMP",7,5);
mSDLCursors[UI_CURSOR_TOOLPAN] = makeSDLCursorFromBMP("lltoolpan.BMP",7,5);
mSDLCursors[UI_CURSOR_TOOLZOOMIN] = makeSDLCursorFromBMP("lltoolzoomin.BMP",7,5);
mSDLCursors[UI_CURSOR_TOOLZOOMOUT] = makeSDLCursorFromBMP("lltoolzoomout.BMP", 7, 5);
mSDLCursors[UI_CURSOR_TOOLPICKOBJECT3] = makeSDLCursorFromBMP("toolpickobject3.BMP",0,0);
mSDLCursors[UI_CURSOR_TOOLPLAY] = makeSDLCursorFromBMP("toolplay.BMP",0,0);
mSDLCursors[UI_CURSOR_TOOLPAUSE] = makeSDLCursorFromBMP("toolpause.BMP",0,0);

View File

@ -2028,8 +2028,9 @@ void LLWindowWin32::initCursors(BOOL useLegacyCursors) // <FS:LO> Legacy cursor
mCursor[ UI_CURSOR_CROSS ] = LoadCursor(NULL, IDC_CROSS);
mCursor[ UI_CURSOR_SIZENWSE ] = LoadCursor(NULL, IDC_SIZENWSE);
mCursor[ UI_CURSOR_SIZENESW ] = LoadCursor(NULL, IDC_SIZENESW);
mCursor[ UI_CURSOR_SIZEWE ] = LoadCursor(NULL, IDC_SIZEWE);
mCursor[ UI_CURSOR_SIZENS ] = LoadCursor(NULL, IDC_SIZENS);
mCursor[ UI_CURSOR_SIZEWE ] = LoadCursor(NULL, IDC_SIZEWE);
mCursor[ UI_CURSOR_SIZENS ] = LoadCursor(NULL, IDC_SIZENS);
mCursor[ UI_CURSOR_SIZEALL ] = LoadCursor(NULL, IDC_SIZEALL);
mCursor[ UI_CURSOR_NO ] = LoadCursor(NULL, IDC_NO);
mCursor[ UI_CURSOR_WORKING ] = LoadCursor(NULL, IDC_APPSTARTING);
@ -2051,6 +2052,7 @@ void LLWindowWin32::initCursors(BOOL useLegacyCursors) // <FS:LO> Legacy cursor
mCursor[ UI_CURSOR_TOOLCAMERA ] = LoadCursor(module, TEXT("TOOLCAMERA"));
mCursor[ UI_CURSOR_TOOLPAN ] = LoadCursor(module, TEXT("TOOLPAN"));
mCursor[ UI_CURSOR_TOOLZOOMIN ] = LoadCursor(module, TEXT("TOOLZOOMIN"));
mCursor[ UI_CURSOR_TOOLZOOMOUT ] = LoadCursor(module, TEXT("TOOLZOOMOUT"));
mCursor[ UI_CURSOR_TOOLPICKOBJECT3 ] = LoadCursor(module, TEXT("TOOLPICKOBJECT3"));
mCursor[ UI_CURSOR_PIPETTE ] = LoadCursor(module, TEXT("TOOLPIPETTE"));
/*<FS:LO> Legacy cursor setting from main program

View File

@ -87,6 +87,9 @@ private:
bool mCookiesEnabled;
bool mPluginsEnabled;
bool mJavascriptEnabled;
bool mProxyEnabled;
std::string mProxyHost;
int mProxyPort;
bool mDisableGPU;
bool mDisableNetworkService;
bool mUseMockKeyChain;
@ -124,6 +127,9 @@ MediaPluginBase(host_send_func, host_user_data)
mCookiesEnabled = true;
mPluginsEnabled = false;
mJavascriptEnabled = true;
mProxyEnabled = false;
mProxyHost = "";
mProxyPort = 0;
mDisableGPU = false;
mDisableNetworkService = true;
mUseMockKeyChain = true;
@ -397,21 +403,86 @@ void MediaPluginCEF::onCursorChangedCallback(dullahan::ECursorType type)
switch (type)
{
case dullahan::CT_POINTER:
name = "arrow";
break;
case dullahan::CT_POINTER:
name = "UI_CURSOR_ARROW";
break;
case dullahan::CT_CROSS:
name = "UI_CURSOR_CROSS";
break;
case dullahan::CT_HAND:
name = "UI_CURSOR_HAND";
break;
case dullahan::CT_IBEAM:
name = "ibeam";
break;
case dullahan::CT_NORTHSOUTHRESIZE:
name = "splitv";
break;
case dullahan::CT_EASTWESTRESIZE:
name = "splith";
break;
case dullahan::CT_HAND:
name = "hand";
name = "UI_CURSOR_IBEAM";
break;
case dullahan::CT_WAIT:
name = "UI_CURSOR_WAIT";
break;
//case dullahan::CT_HELP:
case dullahan::CT_ROWRESIZE:
case dullahan::CT_NORTHRESIZE:
case dullahan::CT_SOUTHRESIZE:
case dullahan::CT_NORTHSOUTHRESIZE:
name = "UI_CURSOR_SIZENS";
break;
case dullahan::CT_COLUMNRESIZE:
case dullahan::CT_EASTRESIZE:
case dullahan::CT_WESTRESIZE:
case dullahan::CT_EASTWESTRESIZE:
name = "UI_CURSOR_SIZEWE";
break;
case dullahan::CT_NORTHEASTRESIZE:
case dullahan::CT_SOUTHWESTRESIZE:
case dullahan::CT_NORTHEASTSOUTHWESTRESIZE:
name = "UI_CURSOR_SIZENESW";
break;
case dullahan::CT_SOUTHEASTRESIZE:
case dullahan::CT_NORTHWESTRESIZE:
case dullahan::CT_NORTHWESTSOUTHEASTRESIZE:
name = "UI_CURSOR_SIZENWSE";
break;
case dullahan::CT_MOVE:
name = "UI_CURSOR_SIZEALL";
break;
//case dullahan::CT_MIDDLEPANNING:
//case dullahan::CT_EASTPANNING:
//case dullahan::CT_NORTHPANNING:
//case dullahan::CT_NORTHEASTPANNING:
//case dullahan::CT_NORTHWESTPANNING:
//case dullahan::CT_SOUTHPANNING:
//case dullahan::CT_SOUTHEASTPANNING:
//case dullahan::CT_SOUTHWESTPANNING:
//case dullahan::CT_WESTPANNING:
//case dullahan::CT_VERTICALTEXT:
//case dullahan::CT_CELL:
//case dullahan::CT_CONTEXTMENU:
case dullahan::CT_ALIAS:
name = "UI_CURSOR_TOOLMEDIAOPEN";
break;
case dullahan::CT_PROGRESS:
name = "UI_CURSOR_WORKING";
break;
case dullahan::CT_COPY:
name = "UI_CURSOR_ARROWCOPY";
break;
case dullahan::CT_NONE:
name = "UI_CURSOR_NO";
break;
case dullahan::CT_NODROP:
case dullahan::CT_NOTALLOWED:
name = "UI_CURSOR_NOLOCKED";
break;
case dullahan::CT_ZOOMIN:
name = "UI_CURSOR_TOOLZOOMIN";
break;
case dullahan::CT_ZOOMOUT:
name = "UI_CURSOR_TOOLZOOMOUT";
break;
case dullahan::CT_GRAB:
name = "UI_CURSOR_TOOLGRAB";
break;
//case dullahan::CT_GRABING:
//case dullahan::CT_CUSTOM:
default:
LL_WARNS() << "Unknown cursor ID: " << (int)type << LL_ENDL;
@ -518,50 +589,60 @@ void MediaPluginCEF::receiveMessage(const char* message_string)
}
else if (message_class == LLPLUGIN_MESSAGE_CLASS_MEDIA)
{
if (message_name == "init")
{
// event callbacks from Dullahan
mCEFLib->setOnPageChangedCallback(std::bind(&MediaPluginCEF::onPageChangedCallback, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4, std::placeholders::_5));
mCEFLib->setOnCustomSchemeURLCallback(std::bind(&MediaPluginCEF::onCustomSchemeURLCallback, this, std::placeholders::_1));
mCEFLib->setOnConsoleMessageCallback(std::bind(&MediaPluginCEF::onConsoleMessageCallback, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
mCEFLib->setOnStatusMessageCallback(std::bind(&MediaPluginCEF::onStatusMessageCallback, this, std::placeholders::_1));
mCEFLib->setOnTitleChangeCallback(std::bind(&MediaPluginCEF::onTitleChangeCallback, this, std::placeholders::_1));
mCEFLib->setOnTooltipCallback(std::bind(&MediaPluginCEF::onTooltipCallback, this, std::placeholders::_1));
mCEFLib->setOnLoadStartCallback(std::bind(&MediaPluginCEF::onLoadStartCallback, this));
mCEFLib->setOnLoadEndCallback(std::bind(&MediaPluginCEF::onLoadEndCallback, this, std::placeholders::_1, std::placeholders::_2));
mCEFLib->setOnLoadErrorCallback(std::bind(&MediaPluginCEF::onLoadError, this, std::placeholders::_1, std::placeholders::_2));
mCEFLib->setOnAddressChangeCallback(std::bind(&MediaPluginCEF::onAddressChangeCallback, this, std::placeholders::_1));
mCEFLib->setOnOpenPopupCallback(std::bind(&MediaPluginCEF::onOpenPopupCallback, this, std::placeholders::_1, std::placeholders::_2));
mCEFLib->setOnHTTPAuthCallback(std::bind(&MediaPluginCEF::onHTTPAuthCallback, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4));
mCEFLib->setOnFileDialogCallback(std::bind(&MediaPluginCEF::onFileDialog, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4, std::placeholders::_5));
mCEFLib->setOnCursorChangedCallback(std::bind(&MediaPluginCEF::onCursorChangedCallback, this, std::placeholders::_1));
mCEFLib->setOnRequestExitCallback(std::bind(&MediaPluginCEF::onRequestExitCallback, this));
mCEFLib->setOnJSDialogCallback(std::bind(&MediaPluginCEF::onJSDialogCallback, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
mCEFLib->setOnJSBeforeUnloadCallback(std::bind(&MediaPluginCEF::onJSBeforeUnloadCallback, this));
dullahan::dullahan_settings settings;
if (message_name == "init")
{
// event callbacks from Dullahan
mCEFLib->setOnPageChangedCallback(std::bind(&MediaPluginCEF::onPageChangedCallback, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4, std::placeholders::_5));
mCEFLib->setOnCustomSchemeURLCallback(std::bind(&MediaPluginCEF::onCustomSchemeURLCallback, this, std::placeholders::_1));
mCEFLib->setOnConsoleMessageCallback(std::bind(&MediaPluginCEF::onConsoleMessageCallback, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
mCEFLib->setOnStatusMessageCallback(std::bind(&MediaPluginCEF::onStatusMessageCallback, this, std::placeholders::_1));
mCEFLib->setOnTitleChangeCallback(std::bind(&MediaPluginCEF::onTitleChangeCallback, this, std::placeholders::_1));
mCEFLib->setOnTooltipCallback(std::bind(&MediaPluginCEF::onTooltipCallback, this, std::placeholders::_1));
mCEFLib->setOnLoadStartCallback(std::bind(&MediaPluginCEF::onLoadStartCallback, this));
mCEFLib->setOnLoadEndCallback(std::bind(&MediaPluginCEF::onLoadEndCallback, this, std::placeholders::_1, std::placeholders::_2));
mCEFLib->setOnLoadErrorCallback(std::bind(&MediaPluginCEF::onLoadError, this, std::placeholders::_1, std::placeholders::_2));
mCEFLib->setOnAddressChangeCallback(std::bind(&MediaPluginCEF::onAddressChangeCallback, this, std::placeholders::_1));
mCEFLib->setOnOpenPopupCallback(std::bind(&MediaPluginCEF::onOpenPopupCallback, this, std::placeholders::_1, std::placeholders::_2));
mCEFLib->setOnHTTPAuthCallback(std::bind(&MediaPluginCEF::onHTTPAuthCallback, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4));
mCEFLib->setOnFileDialogCallback(std::bind(&MediaPluginCEF::onFileDialog, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4, std::placeholders::_5));
mCEFLib->setOnCursorChangedCallback(std::bind(&MediaPluginCEF::onCursorChangedCallback, this, std::placeholders::_1));
mCEFLib->setOnRequestExitCallback(std::bind(&MediaPluginCEF::onRequestExitCallback, this));
mCEFLib->setOnJSDialogCallback(std::bind(&MediaPluginCEF::onJSDialogCallback, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
mCEFLib->setOnJSBeforeUnloadCallback(std::bind(&MediaPluginCEF::onJSBeforeUnloadCallback, this));
dullahan::dullahan_settings settings;
#if LL_WINDOWS
// As of CEF version 83+, for Windows versions, we need to tell CEF
// where the host helper process is since this DLL is not in the same
// dir as the executable that loaded it (SLPlugin.exe). The code in
// Dullahan that tried to figure out the location automatically uses
// the location of the exe which isn't helpful so we tell it explicitly.
char cur_dir_str[MAX_PATH];
GetCurrentDirectoryA(MAX_PATH, cur_dir_str);
settings.host_process_path = std::string(cur_dir_str);
// As of CEF version 83+, for Windows versions, we need to tell CEF
// where the host helper process is since this DLL is not in the same
// dir as the executable that loaded it (SLPlugin.exe). The code in
// Dullahan that tried to figure out the location automatically uses
// the location of the exe which isn't helpful so we tell it explicitly.
char cur_dir_str[MAX_PATH];
GetCurrentDirectoryA(MAX_PATH, cur_dir_str);
settings.host_process_path = std::string(cur_dir_str);
#endif
settings.accept_language_list = mHostLanguage;
settings.accept_language_list = mHostLanguage;
// SL-15560: Product team overruled my change to set the default
// embedded background color to match the floater background
// and set it to white
settings.background_color = 0xffffffff; // white
// SL-15560: Product team overruled my change to set the default
// embedded background color to match the floater background
// and set it to white
settings.background_color = 0xffffffff; // white
settings.cache_enabled = true;
settings.root_cache_path = mRootCachePath;
settings.cache_path = mCachePath;
settings.context_cache_path = mContextCachePath;
settings.cookies_enabled = mCookiesEnabled;
settings.cache_enabled = true;
settings.root_cache_path = mRootCachePath;
settings.cache_path = mCachePath;
settings.context_cache_path = mContextCachePath;
settings.cookies_enabled = mCookiesEnabled;
#ifndef LL_LINUX
// configure proxy argument if enabled and valid
if (mProxyEnabled && mProxyHost.length())
{
std::ostringstream proxy_url;
proxy_url << mProxyHost << ":" << mProxyPort;
settings.proxy_host_port = proxy_url.str();
}
#endif
settings.disable_gpu = mDisableGPU;
#if LL_DARWIN
settings.disable_network_service = mDisableNetworkService;
@ -909,6 +990,12 @@ void MediaPluginCEF::receiveMessage(const char* message_string)
{
mDisableGPU = message_in.getValueBoolean("disable");
}
else if (message_name == "proxy_setup")
{
mProxyEnabled = message_in.getValueBoolean("enable");
mProxyHost = message_in.getValue("host");
mProxyPort = message_in.getValueS32("port");
}
else if (message_name == "web_security_disabled")
{
mDisableWebSecurity = message_in.getValueBoolean("disabled");

View File

@ -1859,6 +1859,8 @@ if (WINDOWS)
COMPILE_DEFINITIONS "${VIEWER_CHANNEL_VERSION_DEFINES}"
)
set_source_files_properties( llappviewer.cpp llviewermenu.cpp PROPERTIES COMPILE_FLAGS /bigobj )
list(APPEND viewer_HEADER_FILES
llappviewerwin32.h
llwindebug.h
@ -2561,28 +2563,30 @@ if (LINUX)
set(product Firestorm-${ARCH}-${VIEWER_SHORT_VERSION}.${VIEWER_VERSION_REVISION})
# These are the generated targets that are copied to package/
if (NOT ENABLE_MEDIA_PLUGINS)
set(COPY_INPUT_DEPENDENCIES
${VIEWER_BINARY_NAME}
SLPlugin
media_plugin_cef
media_plugin_gstreamer10
#media_plugin_libvlc
llcommon
linux-crash-logger
)
else (NOT ENABLE_MEDIA_PLUGINS)
set(COPY_INPUT_DEPENDENCIES
${VIEWER_BINARY_NAME}
#linux-crash-logger
SLPlugin
media_plugin_cef
media_plugin_gstreamer10
llcommon
linux-crash-logger
)
endif (NOT ENABLE_MEDIA_PLUGINS)
if (NOT ENABLE_MEDIA_PLUGINS)
set(COPY_INPUT_DEPENDENCIES
${VIEWER_BINARY_NAME}
SLPlugin
media_plugin_cef
media_plugin_gstreamer10
#media_plugin_libvlc
llcommon
linux-crash-logger
)
else (NOT ENABLE_MEDIA_PLUGINS)
set(COPY_INPUT_DEPENDENCIES
${VIEWER_BINARY_NAME}
#linux-crash-logger
SLPlugin
media_plugin_cef
media_plugin_gstreamer10
llcommon
linux-crash-logger
)
endif (NOT ENABLE_MEDIA_PLUGINS)
add_dependencies(${VIEWER_BINARY_NAME} SLPlugin media_plugin_gstreamer10 media_plugin_cef linux-crash-logger)
add_custom_command(
OUTPUT ${product}.tar.bz2
COMMAND ${PYTHON_EXECUTABLE}
@ -2608,7 +2612,6 @@ endif (NOT ENABLE_MEDIA_PLUGINS)
${COPY_INPUT_DEPENDENCIES}
)
add_custom_command(
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/.${product}.copy_touched
COMMAND ${PYTHON_EXECUTABLE}

View File

@ -340,7 +340,7 @@
<string key="NSMaxSize">{10000000000000, 10000000000000}</string>
<string key="NSFrameAutosaveName">Second Life</string>
<int key="NSWindowCollectionBehavior">128</int>
<bool key="NSWindowIsRestorable">YES</bool>
<bool key="NSWindowIsRestorable">NO</bool>
</object>
<object class="NSWindowTemplate" id="979091056">
<int key="NSWindowStyleMask">31</int>

View File

@ -11156,7 +11156,7 @@ Change of this parameter will affect the layout of buttons in notification toast
<key>PushToTalkToggle</key>
<map>
<key>Comment</key>
<string>Should the push-to-talk button behave as a toggle</string>
<string>Should the push-to-talk toolbar button behave as a toggle</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
@ -11200,7 +11200,7 @@ Change of this parameter will affect the layout of buttons in notification toast
<key>QAModeMetrics</key>
<map>
<key>Comment</key>
<string>"Enables QA features (logging, faster cycling) for metrics collector"</string>
<string>Enables QA features (logging, faster cycling) for metrics collector</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
@ -11210,8 +11210,18 @@ Change of this parameter will affect the layout of buttons in notification toast
<key>Backup</key>
<integer>0</integer>
</map>
<key>QuitAfterSeconds</key>
<key>QAModeFakeSystemFolderIssues</key>
<map>
<key>Comment</key>
<string>Simulates system folder issues in inventory</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
<integer>0</integer>
</map>
<key>QuitAfterSeconds</key>
<map>
<key>Comment</key>
<string>The duration allowed before quitting.</string>
@ -15710,6 +15720,17 @@ Change of this parameter will affect the layout of buttons in notification toast
<key>Backup</key>
<integer>0</integer>
</map>
<key>TextureFetchMinTimeToLog</key>
<map>
<key>Comment</key>
<string>If texture fetching time exceeds this value, texture fetch tester will log info</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>F32</string>
<key>Value</key>
<real>2.0</real>
</map>
<key>TextureFetchFakeFailureRate</key>
<map>
<key>Comment</key>
@ -15812,6 +15833,17 @@ Change of this parameter will affect the layout of buttons in notification toast
<key>Backup</key>
<integer>0</integer>
</map>
<key>TextureListFetchingThreshold</key>
<map>
<key>Comment</key>
<string>If the ratio between fetched and all textures in the list is greater than this threshold, which we assume that almost all textures are fetched</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>F32</string>
<key>Value</key>
<real>0.97</real>
</map>
<key>TextureLoadFullRes</key>
<map>
<key>Comment</key>
@ -25915,6 +25947,17 @@ Change of this parameter will affect the layout of buttons in notification toast
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
<integer>0</integer>
</map>
<key>FSAutoTuneLock</key>
<map>
<key>Comment</key>
<string>When enabled the viewer will dynamically change settings until auto tune is explicitly turned off.</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
<integer>1</integer>
</map>
<key>FSAllowSelfImpostor</key>
@ -25994,6 +26037,17 @@ Change of this parameter will affect the layout of buttons in notification toast
<key>Value</key>
<integer>0</integer>
</map>
<key>FSUserTargetReflections</key>
<map>
<key>Comment</key>
<string>Set by auto tune floater on build</string>
<key>Persist</key>
<integer>0</integer>
<key>Type</key>
<string>S32</string>
<key>Value</key>
<integer>4</integer>
</map>
<key>FSReportRegionRestartToChat</key>
<map>
<key>Comment</key>

View File

@ -38,7 +38,7 @@ def munge_binding_redirect_version(src_manifest_name, src_config_name, dst_confi
comment = config_dom.createComment("This file is automatically generated by the build. see indra/newview/build_win32_appConfig.py")
config_dom.insertBefore(comment, config_dom.childNodes[0])
print "Writing: " + dst_config_name
print("Writing: " + dst_config_name)
f = open(dst_config_name, 'w')
config_dom.writexml(f)
f.close()

Binary file not shown.

Binary file not shown.

View File

@ -9,7 +9,7 @@ class FSViewerManifest:
def fs_splice_grid_substitution_strings( self, subst_strings ):
ret = subst_strings
if self.args.has_key( 'grid' ) and self.args['grid'] != None:
if 'grid' in self.args and self.args['grid'] != None:
ret[ 'grid' ] = self.args['grid']
ret[ 'grid_caps' ] = self.args['grid'].upper()
else:
@ -51,15 +51,15 @@ class FSViewerManifest:
stderr=subprocess.PIPE,stdout=subprocess.PIPE)
subprocess.check_call(["signtool.exe","sign","/n","Phoenix","/d","Firestorm","/du","http://www.phoenixviewer.com","/t","http://timestamp.verisign.com/scripts/timstamp.dll",self.args['configuration']+"\\"+self.final_exe()],
stderr=subprocess.PIPE,stdout=subprocess.PIPE)
except Exception, e:
print "Couldn't sign final binary. Tried to sign %s" % self.args['configuration']+"\\"+self.final_exe()
except Exception as e:
print("Couldn't sign final binary. Tried to sign %s" % self.args['configuration']+"\\"+self.final_exe())
def fs_sign_win_installer( self, substitution_strings ):
try:
subprocess.check_call(["signtool.exe","sign","/n","Phoenix","/d","Firestorm","/du","http://www.phoenixviewer.com",self.args['configuration']+"\\"+substitution_strings['installer_file']],stderr=subprocess.PIPE,stdout=subprocess.PIPE)
except Exception, e:
print "Working directory: %s" % os.getcwd()
print "Couldn't sign windows installer. Tried to sign %s" % self.args['configuration']+"\\"+substitution_strings['installer_file']
except Exception as e:
print("Working directory: %s" % os.getcwd())
print("Couldn't sign windows installer. Tried to sign %s" % self.args['configuration']+"\\"+substitution_strings['installer_file'])
def fs_delete_linux_symbols( self ):
debugDir = os.path.join( self.get_dst_prefix(), "bin", ".debug" )
@ -76,7 +76,7 @@ class FSViewerManifest:
def fs_save_linux_symbols( self ):
#AO: Try to package up symbols
# New Method, for reading cross platform stack traces on a linux/mac host
print( "Packaging symbols" )
print("Packaging symbols")
self.fs_save_symbols("linux")
@ -97,7 +97,7 @@ class FSViewerManifest:
], stderr=subprocess.PIPE,stdout=subprocess.PIPE )
pdbName = "firestorm-bin-public.pdb"
except:
print( "Cannot run pdbcopy, packaging private symbols" )
print("Cannot run pdbcopy, packaging private symbols")
# Store windows symbols we want to keep for debugging in a tar file, this will be later compressed with xz (lzma)
# Using tat+xz gives far superior compression than zip (~half the size of the zip archive).

View File

@ -51,8 +51,12 @@
#include "pipeline.h"
#include "llviewercontrol.h"
#include "fsavatarrenderpersistence.h"
#include "llpresetsmanager.h"
#include "fsperfstats.h" // <FS:Beq> performance stats support
#include "fslslbridge.h"
#include <llbutton.h>
extern F32 gSavedDrawDistance;
const F32 REFRESH_INTERVAL = 1.0f;
const S32 BAR_LEFT_PAD = 2;
@ -119,8 +123,11 @@ BOOL FSFloaterPerformance::postBuild()
auto tgt_panel = findChild<LLPanel>("target_subpanel");
if (tgt_panel)
{
tgt_panel->getChild<LLButton>("target_btn")->setCommitCallback(boost::bind(&FSFloaterPerformance::showSelectedPanel, this, mAutoTunePanel));
tgt_panel->getChild<LLComboBox>("FSTuningFPSStrategy")->setCurrentByIndex(gSavedSettings.getU32("FSTuningFPSStrategy"));
tgt_panel->getChild<LLButton>("target_btn")->setCommitCallback(boost::bind(&FSFloaterPerformance::showSelectedPanel, this, mAutoTunePanel));
tgt_panel->getChild<LLComboBox>("FSTuningFPSStrategy")->setCurrentByIndex(gSavedSettings.getU32("FSTuningFPSStrategy"));
tgt_panel->getChild<LLButton>("PrefSaveButton")->setCommitCallback(boost::bind(&FSFloaterPerformance::savePreset, this));
tgt_panel->getChild<LLButton>("PrefLoadButton")->setCommitCallback(boost::bind(&FSFloaterPerformance::loadPreset, this));
tgt_panel->getChild<LLButton>("Defaults")->setCommitCallback(boost::bind(&FSFloaterPerformance::setHardwareDefaults, this));
}
initBackBtn(mNearbyPanel);
@ -146,6 +153,7 @@ BOOL FSFloaterPerformance::postBuild()
mNearbyPanel->getChild<LLCheckBoxCtrl>("hide_avatars")->set(!LLPipeline::hasRenderTypeControl(LLPipeline::RENDER_TYPE_AVATAR));
mNearbyList = mNearbyPanel->getChild<LLNameListCtrl>("nearby_list");
mNearbyList->setRightMouseDownCallback(boost::bind(&FSFloaterPerformance::onAvatarListRightClick, this, _1, _2, _3));
updateComplexityText();
mComplexityChangedSignal = gSavedSettings.getControl("RenderAvatarMaxComplexity")->getCommitSignal()->connect(boost::bind(&FSFloaterPerformance::updateComplexityText, this));
@ -155,10 +163,53 @@ BOOL FSFloaterPerformance::postBuild()
mNearbyPanel->getChild<LLSliderCtrl>("FSRenderAvatarMaxART")->setCommitCallback(boost::bind(&FSFloaterPerformance::updateMaxRenderTime, this));
LLAvatarComplexityControls::setIndirectMaxArc();
// store the current setting as the users desired reflection detail and DD
gSavedSettings.setS32("FSUserTargetReflections", LLPipeline::RenderReflectionDetail);
if(!FSPerfStats::tunables.userAutoTuneEnabled)
{
if (gSavedDrawDistance)
{
gSavedSettings.setF32("FSAutoTuneRenderFarClipTarget", gSavedDrawDistance);
}
else
{
gSavedSettings.setF32("FSAutoTuneRenderFarClipTarget", LLPipeline::RenderFarClip);
}
}
return TRUE;
}
void FSFloaterPerformance::resetMaxArtSlider()
{
FSPerfStats::renderAvatarMaxART_ns = 0;
FSPerfStats::tunables.updateSettingsFromRenderCostLimit();
FSPerfStats::tunables.applyUpdates();
updateMaxRenderTime();
}
void FSFloaterPerformance::savePreset()
{
LLFloaterReg::showInstance("save_pref_preset", "graphic" );
}
void FSFloaterPerformance::loadPreset()
{
LLFloaterReg::showInstance("load_pref_preset", "graphic");
resetMaxArtSlider();
}
void FSFloaterPerformance::setHardwareDefaults()
{
LLFeatureManager::getInstance()->applyRecommendedSettings();
// reset indirects before refresh because we may have changed what they control
LLAvatarComplexityControls::setIndirectControls();
gSavedSettings.setString("PresetGraphicActive", "");
LLPresetsManager::getInstance()->triggerChangeSignal();
resetMaxArtSlider();
}
void FSFloaterPerformance::showSelectedPanel(LLPanel* selected_panel)
{
hidePanels();
@ -284,7 +335,7 @@ void FSFloaterPerformance::draw()
textbox->setColor(LLUIColorTable::instance().getColor("DrYellow"));
unreliable = true;
}
else if (FSPerfStats::autoTune)
else if (FSPerfStats::tunables.userAutoTuneEnabled)
{
textbox->setVisible(true);
textbox->setText(getString("tuning_fps", args));
@ -295,7 +346,12 @@ void FSFloaterPerformance::draw()
textbox->setVisible(false);
}
if (FSPerfStats::autoTune && !unreliable )
auto button = getChild<LLButton>("AutoTuneFPS");
if((bool)button->getToggleState() != FSPerfStats::tunables.userAutoTuneEnabled)
{
button->toggleState();
}
if (FSPerfStats::tunables.userAutoTuneEnabled && !unreliable )
{
// the tuning itself is managed from another thread but we can report progress here

View File

@ -55,6 +55,10 @@ public:
void onCustomAction (const LLSD& userdata, const LLUUID& av_id);
bool isActionChecked(const LLSD& userdata, const LLUUID& av_id);
void onExtendedAction(const LLSD& userdata, const LLUUID& av_id);
void resetMaxArtSlider();
void savePreset();
void loadPreset();
void setHardwareDefaults();
private:
void initBackBtn(LLPanel* panel);

View File

@ -32,6 +32,7 @@
#include "llagentcamera.h"
#include "llvoavatar.h"
#include "llworld.h"
#include <llthread.h>
extern LLControlGroup gSavedSettings;
@ -47,11 +48,10 @@ namespace FSPerfStats
#endif
std::atomic<int64_t> tunedAvatars{0};
U32 targetFPS; // desired FPS
U64 renderAvatarMaxART_ns{(U64)(ART_UNLIMITED_NANOS)}; // highest render time we'll allow without culling features
std::atomic<U64> renderAvatarMaxART_ns{(U64)(ART_UNLIMITED_NANOS)}; // highest render time we'll allow without culling features
bool belowTargetFPS{false};
U32 lastGlobalPrefChange{0};
std::mutex bufferToggleLock{};
bool autoTune{false};
Tunables tunables;
@ -65,9 +65,69 @@ namespace FSPerfStats
void Tunables::applyUpdates()
{
assert_main_thread();
if( tuningFlag & NonImposters ){ gSavedSettings.setU32("IndirectMaxNonImpostors", nonImposters); };
// these following variables are proxies for pipeline statics we do not need a two way update (no llviewercontrol handler)
if( tuningFlag & NonImpostors ){ gSavedSettings.setU32("IndirectMaxNonImpostors", nonImpostors); };
if( tuningFlag & ReflectionDetail ){ gSavedSettings.setS32("RenderReflectionDetail", reflectionDetail); };
if( tuningFlag & FarClip ){ gSavedSettings.setF32("RenderFarClip", farClip); };
if( tuningFlag & UserMinDrawDistance ){ gSavedSettings.setF32("FSAutoTuneRenderFarClipMin", userMinDrawDistance); };
if( tuningFlag & UserTargetDrawDistance ){ gSavedSettings.setF32("FSAutoTuneRenderFarClipTarget", userTargetDrawDistance); };
if( tuningFlag & UserImpostorDistance ){ gSavedSettings.setF32("FSAutoTuneImpostorFarAwayDistance", userImpostorDistance); };
if( tuningFlag & UserImpostorDistanceTuningEnabled ){ gSavedSettings.setBOOL("FSAutoTuneImpostorByDistEnabled", userImpostorDistanceTuningEnabled); };
if( tuningFlag & UserFPSTuningStrategy ){ gSavedSettings.setU32("FSTuningFPSStrategy", userFPSTuningStrategy); };
if( tuningFlag & UserAutoTuneEnabled ){ gSavedSettings.setBOOL("FSAutoTuneFPS", userAutoTuneEnabled); };
if( tuningFlag & UserAutoTuneLock ){ gSavedSettings.setBOOL("FSAutoTuneLock", userAutoTuneLock); };
if( tuningFlag & UserTargetFPS ){ gSavedSettings.setU32("FSTargetFPS", userTargetFPS); };
if( tuningFlag & UserTargetReflections ){ gSavedSettings.setS32("FSUserTargetReflections", userTargetReflections); };
// Note: The Max ART slider is logarithmic and thus we have an intermediate proxy value
if( tuningFlag & UserARTCutoff ){ gSavedSettings.setF32("FSRenderAvatarMaxART", userARTCutoffSliderValue); };
resetChanges();
}
void Tunables::updateRenderCostLimitFromSettings()
{
assert_main_thread();
const auto newval = gSavedSettings.getF32("FSRenderAvatarMaxART");
if(newval < log10(FSPerfStats::ART_UNLIMITED_NANOS/1000))
{
FSPerfStats::renderAvatarMaxART_ns = pow(10,newval)*1000;
}
else
{
FSPerfStats::renderAvatarMaxART_ns = 0;
};
}
// static
void Tunables::updateSettingsFromRenderCostLimit()
{
if( userARTCutoffSliderValue != log10( ( (F32)FSPerfStats::renderAvatarMaxART_ns )/1000 ) )
{
if( FSPerfStats::renderAvatarMaxART_ns != 0 )
{
updateUserARTCutoffSlider(log10( ( (F32)FSPerfStats::renderAvatarMaxART_ns )/1000 ) );
}
else
{
updateUserARTCutoffSlider(log10( (F32)FSPerfStats::ART_UNLIMITED_NANOS/1000 ) );
}
}
}
void Tunables::initialiseFromSettings()
{
assert_main_thread();
// the following variables are two way and have "push" in llviewercontrol
FSPerfStats::tunables.userMinDrawDistance = gSavedSettings.getF32("FSAutoTuneRenderFarClipMin");
FSPerfStats::tunables.userTargetDrawDistance = gSavedSettings.getF32("FSAutoTuneRenderFarClipTarget");
FSPerfStats::tunables.userImpostorDistance = gSavedSettings.getF32("FSAutoTuneImpostorFarAwayDistance");
FSPerfStats::tunables.userImpostorDistanceTuningEnabled = gSavedSettings.getBOOL("FSAutoTuneImpostorByDistEnabled");
FSPerfStats::tunables.userFPSTuningStrategy = gSavedSettings.getU32("FSTuningFPSStrategy");
FSPerfStats::tunables.userTargetFPS = gSavedSettings.getU32("FSTargetFPS");
FSPerfStats::tunables.userTargetReflections = gSavedSettings.getU32("FSUserTargetReflections");
FSPerfStats::tunables.userAutoTuneEnabled = gSavedSettings.getBOOL("FSAutoTuneFPS");
FSPerfStats::tunables.userAutoTuneLock = gSavedSettings.getBOOL("FSAutoTuneLock");
// Note: The Max ART slider is logarithmic and thus we have an intermediate proxy value
updateRenderCostLimitFromSettings();
resetChanges();
}
@ -75,12 +135,7 @@ namespace FSPerfStats
{
// create a queue
// create a thread to consume from the queue
FSPerfStats::targetFPS = gSavedSettings.getU32("FSTargetFPS");
FSPerfStats::autoTune = gSavedSettings.getBOOL("FSAutoTuneFPS");
updateRenderCostLimitFromSettings();
tunables.initialiseFromSettings();
t.detach();
}
@ -91,8 +146,7 @@ namespace FSPerfStats
using ST = StatType_t;
bool unreliable{false};
static LLCachedControl<U32> smoothingPeriods(gSavedSettings, "FSPerfFloaterSmoothingPeriods");
FSPerfStats::StatsRecorder::getSceneStat(FSPerfStats::StatType_t::RENDER_FRAME);
auto& sceneStats = statsDoubleBuffer[writeBuffer][static_cast<size_t>(ObjType_t::OT_GENERAL)][LLUUID::null];
auto& lastStats = statsDoubleBuffer[writeBuffer ^ 1][static_cast<size_t>(ObjType_t::OT_GENERAL)][LLUUID::null];
@ -129,7 +183,7 @@ namespace FSPerfStats
{
auto avg = lastStats[static_cast<size_t>(statEntry)];
auto val = sceneStats[static_cast<size_t>(statEntry)];
sceneStats[static_cast<size_t>(statEntry)] = avg + (val/smoothingPeriods) - (avg/smoothingPeriods);
sceneStats[static_cast<size_t>(statEntry)] = avg + (val / SMOOTHING_PERIODS) - (avg / SMOOTHING_PERIODS);
// LL_INFOS("scenestats") << "Scenestat: " << static_cast<size_t>(statEntry) << " before=" << avg << " new=" << val << " newavg=" << statsDoubleBuffer[writeBuffer][static_cast<size_t>(ObjType_t::OT_GENERAL)][LLUUID::null][static_cast<size_t>(statEntry)] << LL_ENDL;
}
@ -137,9 +191,9 @@ namespace FSPerfStats
for(auto& stat_entry : statsMap)
{
auto val = stat_entry.second[static_cast<size_t>(ST::RENDER_COMBINED)];
if(val>smoothingPeriods){
if(val > SMOOTHING_PERIODS){
auto avg = statsDoubleBuffer[writeBuffer ^ 1][static_cast<size_t>(ObjType_t::OT_ATTACHMENT)][stat_entry.first][static_cast<size_t>(ST::RENDER_COMBINED)];
stat_entry.second[static_cast<size_t>(ST::RENDER_COMBINED)] = avg + (val/smoothingPeriods) - (avg/smoothingPeriods);
stat_entry.second[static_cast<size_t>(ST::RENDER_COMBINED)] = avg + (val / SMOOTHING_PERIODS) - (avg / SMOOTHING_PERIODS);
}
}
@ -150,10 +204,10 @@ namespace FSPerfStats
for(auto& stat : avatarStatsToAvg)
{
auto val = stat_entry.second[static_cast<size_t>(stat)];
if(val>smoothingPeriods)
if(val > SMOOTHING_PERIODS)
{
auto avg = statsDoubleBuffer[writeBuffer ^ 1][static_cast<size_t>(ObjType_t::OT_AVATAR)][stat_entry.first][static_cast<size_t>(stat)];
stat_entry.second[static_cast<size_t>(stat)] = avg + (val/smoothingPeriods) - (avg/smoothingPeriods);
stat_entry.second[static_cast<size_t>(stat)] = avg + (val / SMOOTHING_PERIODS) - (avg / SMOOTHING_PERIODS);
}
}
}
@ -185,7 +239,7 @@ namespace FSPerfStats
}
// and now adjust the proxy vars so that the main thread can adjust the visuals.
if(autoTune)
if(tunables.userAutoTuneEnabled)
{
updateAvatarParams();
}
@ -238,37 +292,6 @@ namespace FSPerfStats
}
}
// static
void StatsRecorder::updateSettingsFromRenderCostLimit()
{
static LLCachedControl<F32> maxRenderCost_us(gSavedSettings, "FSRenderAvatarMaxART");
if( (F32)maxRenderCost_us != log10( ( (F32)FSPerfStats::renderAvatarMaxART_ns )/1000 ) )
{
if( FSPerfStats::renderAvatarMaxART_ns != 0 )
{
gSavedSettings.setF32( "FSRenderAvatarMaxART", log10( ( (F32)FSPerfStats::renderAvatarMaxART_ns )/1000 ) );
}
else
{
gSavedSettings.setF32( "FSRenderAvatarMaxART",log10( FSPerfStats::ART_UNLIMITED_NANOS/1000 ) );
}
}
}
// static
void StatsRecorder::updateRenderCostLimitFromSettings()
{
const auto newval = gSavedSettings.getF32("FSRenderAvatarMaxART");
if(newval < log10(FSPerfStats::ART_UNLIMITED_NANOS/1000))
{
FSPerfStats::renderAvatarMaxART_ns = pow(10,newval)*1000;
}
else
{
FSPerfStats::renderAvatarMaxART_ns = 0;
};
}
//static
int StatsRecorder::countNearbyAvatars(S32 distance)
{
@ -283,23 +306,16 @@ namespace FSPerfStats
// static
void StatsRecorder::updateAvatarParams()
{
static LLCachedControl<F32> drawDistance(gSavedSettings, "RenderFarClip");
static LLCachedControl<F32> userMinDrawDistance(gSavedSettings, "FSAutoTuneRenderFarClipMin");
static LLCachedControl<F32> userTargetDrawDistance(gSavedSettings, "FSAutoTuneRenderFarClipTarget");
static LLCachedControl<F32> impostorDistance(gSavedSettings, "FSAutoTuneImpostorFarAwayDistance");
static LLCachedControl<bool> impostorDistanceTuning(gSavedSettings, "FSAutoTuneImpostorByDistEnabled");
static LLCachedControl<U32> maxNonImpostors (gSavedSettings, "IndirectMaxNonImpostors");
static LLCachedControl<U32> fpsTuningStrategy (gSavedSettings, "FSTuningFPSStrategy");
if(impostorDistanceTuning)
if(tunables.userImpostorDistanceTuningEnabled)
{
// if we have less than the user's "max Non-Impostors" avatars within the desired range then adjust the limit.
// also adjusts back up again for nearby crowds.
auto count = countNearbyAvatars(std::min(drawDistance, impostorDistance));
if( count != maxNonImpostors )
auto count = countNearbyAvatars(std::min(LLPipeline::RenderFarClip, tunables.userImpostorDistance));
if( count != tunables.nonImpostors )
{
tunables.updateNonImposters( (count < LLVOAvatar::NON_IMPOSTORS_MAX_SLIDER)?count : LLVOAvatar::NON_IMPOSTORS_MAX_SLIDER );
LL_DEBUGS("AutoTune") << "There are " << count << "avatars within " << std::min(drawDistance, impostorDistance) << "m of the camera" << LL_ENDL;
LL_DEBUGS("AutoTune") << "There are " << count << "avatars within " << std::min(LLPipeline::RenderFarClip, tunables.userImpostorDistance) << "m of the camera" << LL_ENDL;
}
}
@ -326,44 +342,51 @@ namespace FSPerfStats
}
// The frametime budget we have based on the target FPS selected
auto target_frame_time_raw = (U64)llround((F64)LLTrace::BlockTimer::countsPerSecond()/(targetFPS==0?1:targetFPS));
auto target_frame_time_raw = (U64)llround((F64)LLTrace::BlockTimer::countsPerSecond()/(tunables.userTargetFPS==0?1:tunables.userTargetFPS));
// LL_INFOS() << "Effective FPS(raw):" << tot_frame_time_raw << " Target:" << target_frame_time_raw << LL_ENDL;
auto inferredFPS{1000/(U32)std::max(raw_to_ms(tot_frame_time_raw),1.0)};
U32 settingsChangeFrequency{inferredFPS > 25?inferredFPS:25};
if( tot_limit_time_raw != 0)
{
// This could be problematic.
tot_frame_time_raw -= tot_limit_time_raw;
}
// 1) Is the target frame tim lower than current?
// 1) Is the target frame time lower than current?
if( target_frame_time_raw <= tot_frame_time_raw )
{
if(belowTargetFPS == false)
{
// this is the first frame under. hold fire to add a little hysteresis
belowTargetFPS = true;
FSPerfStats::lastGlobalPrefChange = gFrameCount;
}
// if so we've got work to do
// how much of the frame was spent on non avatar related work?
U32 non_avatar_time_raw = tot_frame_time_raw - tot_avatar_time_raw;
// If the target frame time < non avatar frame time thne adjusting avatars is only goin gto get us so far.
// If the target frame time < scene time (estimated as non_avatar time)
U64 target_avatar_time_raw;
if(target_frame_time_raw < non_avatar_time_raw)
{
// we cannnot do this by avatar adjustment alone.
if((gFrameCount - FSPerfStats::lastGlobalPrefChange) > 10) // give changes a short time to take effect.
if((gFrameCount - FSPerfStats::lastGlobalPrefChange) > settingsChangeFrequency) // give changes a short time to take effect.
{
if(fpsTuningStrategy == 1)
if(tunables.userFPSTuningStrategy == TUNE_SCENE_AND_AVATARS)
{
// 1 - hack the water to opaque. all non opaque have a significant hit, this is a big boost for (arguably) a minor visual hit.
// the other reflection options make comparatively little change and iof this overshoots we'll be stepping back up later
// the other reflection options make comparatively little change and if this overshoots we'll be stepping back up later
if(LLPipeline::RenderReflectionDetail != -2)
{
FSPerfStats::tunables.updateReflectionDetail(-2);
FSPerfStats::lastGlobalPrefChange = gFrameCount;
return;
}
else // deliberately "else" here so we only do these in steps
else // deliberately "else" here so we only do one of these in any given frame
{
// step down the DD by 10m per update
auto new_dd = (drawDistance-10>userMinDrawDistance)?(drawDistance - 10) : userMinDrawDistance;
if(new_dd != drawDistance)
auto new_dd = (LLPipeline::RenderFarClip - DD_STEP > tunables.userMinDrawDistance)?(LLPipeline::RenderFarClip - DD_STEP) : tunables.userMinDrawDistance;
if(new_dd != LLPipeline::RenderFarClip)
{
FSPerfStats::tunables.updateFarClip( new_dd );
FSPerfStats::lastGlobalPrefChange = gFrameCount;
@ -371,26 +394,28 @@ namespace FSPerfStats
}
}
}
// if we reach here, we've no more changes to make to tune scenery so we'll resort to agressive Avatar tuning
// Note: moved from outside "if changefrequency elapsed" to stop fallthrough and allow scenery changes time to take effect.
target_avatar_time_raw = 0;
}
else
{
// we made a settings change recently so let's give it time.
return;
}
target_avatar_time_raw = 0;
}
else
{
// desired avatar budget.
// set desired avatar budget.
target_avatar_time_raw = target_frame_time_raw - non_avatar_time_raw;
}
if( target_avatar_time_raw < tot_avatar_time_raw )
{
// we need to spend less time drawing avatars to meet our budget
// Note: working in usecs now cos reasons.
auto new_render_limit_ns {renderAvatarMaxART_ns};
auto new_render_limit_ns {FSPerfStats::raw_to_ns(av_render_max_raw)};
// max render this frame may be higher than the last (cos new entrants and jitter) so make sure we are heading in the right direction
if(FSPerfStats::raw_to_ns(av_render_max_raw) < renderAvatarMaxART_ns)
{
new_render_limit_ns = FSPerfStats::raw_to_ns(av_render_max_raw);
}
else
if( new_render_limit_ns > renderAvatarMaxART_ns )
{
new_render_limit_ns = renderAvatarMaxART_ns;
}
@ -400,30 +425,55 @@ namespace FSPerfStats
new_render_limit_ns = std::max((U64)new_render_limit_ns, (U64)FSPerfStats::ART_MINIMUM_NANOS);
// assign the new value
renderAvatarMaxART_ns = new_render_limit_ns;
if(renderAvatarMaxART_ns != new_render_limit_ns)
{
renderAvatarMaxART_ns = new_render_limit_ns;
tunables.updateSettingsFromRenderCostLimit();
}
// LL_DEBUGS() << "AUTO_TUNE: avatar_budget adjusted to:" << new_render_limit_ns << LL_ENDL;
}
// LL_DEBUGS() << "AUTO_TUNE: Target frame time:"<< FSPerfStats::raw_to_us(target_frame_time_raw) << "usecs (non_avatar is " << FSPerfStats::raw_to_us(non_avatar_time_raw) << "usecs) Max cost limited=" << renderAvatarMaxART_ns << LL_ENDL;
}
else if( FSPerfStats::raw_to_ns(target_frame_time_raw) > (FSPerfStats::raw_to_ns(tot_frame_time_raw) + renderAvatarMaxART_ns) )
{
if( FSPerfStats::tunedAvatars >= 0 )
if(belowTargetFPS == true)
{
// if we have more time to spare let's shift up little in the hope we'll restore an avatar.
renderAvatarMaxART_ns += FSPerfStats::ART_MIN_ADJUST_UP_NANOS;
// we reached target, force a pause
lastGlobalPrefChange = gFrameCount;
belowTargetFPS = false;
}
if( drawDistance < userTargetDrawDistance )
// once we're over the FPS target we slow down further
if((gFrameCount - lastGlobalPrefChange) > settingsChangeFrequency*3)
{
FSPerfStats::tunables.updateFarClip( drawDistance + 10. );
}
if( (target_frame_time_raw * 1.5) > tot_frame_time_raw &&
FSPerfStats::tunedAvatars == 0 &&
drawDistance >= userTargetDrawDistance)
{
// if everything else is "max" and we have 50% headroom let's knock the water quality up a notch at a time.
FSPerfStats::tunables.updateReflectionDetail( gSavedSettings.getS32("RenderReflectionDetail") + 1 );
if(!tunables.userAutoTuneLock)
{
// we've reached the target and stayed long enough to consider stable.
// turn off if we are not locked.
tunables.updateUserAutoTuneEnabled(false);
}
if( FSPerfStats::tunedAvatars > 0 )
{
// if we have more time to spare let's shift up little in the hope we'll restore an avatar.
renderAvatarMaxART_ns += FSPerfStats::ART_MIN_ADJUST_UP_NANOS;
tunables.updateSettingsFromRenderCostLimit();
return;
}
if(tunables.userFPSTuningStrategy == TUNE_SCENE_AND_AVATARS)
{
if( LLPipeline::RenderFarClip < tunables.userTargetDrawDistance )
{
FSPerfStats::tunables.updateFarClip( std::min(LLPipeline::RenderFarClip + DD_STEP, tunables.userTargetDrawDistance) );
FSPerfStats::lastGlobalPrefChange = gFrameCount;
return;
}
if( (tot_frame_time_raw * 1.5) < target_frame_time_raw )
{
// if everything else is "max" and we have >50% headroom let's knock the water quality up a notch at a time.
FSPerfStats::tunables.updateReflectionDetail( std::min(LLPipeline::RenderReflectionDetail + 1, tunables.userTargetReflections) );
}
}
}
}
updateSettingsFromRenderCostLimit();
}
}

View File

@ -64,19 +64,23 @@ namespace FSPerfStats
extern std::atomic<int64_t> inUseAttachmentUnRigged;
#endif
// Note if changing these, they should correspond with the log range of the correpsonding sliders
constexpr U64 ART_UNLIMITED_NANOS{50000000};
constexpr U64 ART_MINIMUM_NANOS{100000};
constexpr U64 ART_MIN_ADJUST_UP_NANOS{10000};
constexpr U64 ART_MIN_ADJUST_DOWN_NANOS{10000};
static constexpr U64 ART_UNLIMITED_NANOS{50000000};
static constexpr U64 ART_MINIMUM_NANOS{100000};
static constexpr U64 ART_MIN_ADJUST_UP_NANOS{10000};
static constexpr U64 ART_MIN_ADJUST_DOWN_NANOS{10000};
constexpr F32 PREFERRED_DD{180};
static constexpr F32 PREFERRED_DD{180};
static constexpr U32 SMOOTHING_PERIODS{50};
static constexpr U32 DD_STEP{10};
static constexpr U32 TUNE_AVATARS_ONLY{0};
static constexpr U32 TUNE_SCENE_AND_AVATARS{1};
extern std::atomic<int64_t> tunedAvatars;
extern U32 targetFPS; // desired FPS
extern U64 renderAvatarMaxART_ns;
extern std::atomic<U64> renderAvatarMaxART_ns;
extern bool belowTargetFPS;
extern U32 lastGlobalPrefChange;
extern std::mutex bufferToggleLock;
extern bool autoTune;
enum class ObjType_t{
OT_GENERAL=0, // Also Unknown. Used for n/a type stats such as scenery
@ -118,21 +122,56 @@ namespace FSPerfStats
struct Tunables
{
static constexpr U32 Nothing{0};
static constexpr U32 NonImposters{1};
static constexpr U32 NonImpostors{1};
static constexpr U32 ReflectionDetail{2};
static constexpr U32 FarClip{4};
static constexpr U32 UserMinDrawDistance{8};
static constexpr U32 UserTargetDrawDistance{16};
static constexpr U32 UserImpostorDistance{32};
static constexpr U32 UserImpostorDistanceTuningEnabled{64};
static constexpr U32 UserFPSTuningStrategy{128};
static constexpr U32 UserAutoTuneEnabled{256};
static constexpr U32 UserTargetFPS{512};
static constexpr U32 UserARTCutoff{1024};
static constexpr U32 UserTargetReflections{2048};
static constexpr U32 UserAutoTuneLock{4096};
U32 tuningFlag{0};
U32 nonImposters;
S32 reflectionDetail;
F32 farClip;
U32 tuningFlag{0}; // bit mask for changed settings
void updateFarClip(F32 nv){farClip=nv; tuningFlag |= FarClip;};
void updateNonImposters(U32 nv){nonImposters=nv; tuningFlag |= NonImposters;};
// proxy variables, used to pas the new value to be set via the mainthread
U32 nonImpostors{0};
S32 reflectionDetail{0};
F32 farClip{0.0};
F32 userMinDrawDistance{0.0};
F32 userTargetDrawDistance{0.0};
F32 userImpostorDistance{0.0};
bool userImpostorDistanceTuningEnabled{false};
U32 userFPSTuningStrategy{0};
bool userAutoTuneEnabled{false};
bool userAutoTuneLock{true};
U32 userTargetFPS{0};
F32 userARTCutoffSliderValue{0};
S32 userTargetReflections{0};
void updateNonImposters(U32 nv){nonImpostors=nv; tuningFlag |= NonImpostors;};
void updateReflectionDetail(S32 nv){reflectionDetail=nv; tuningFlag |= ReflectionDetail;};
void updateFarClip(F32 nv){farClip=nv; tuningFlag |= FarClip;};
void updateUserMinDrawDistance(F32 nv){userMinDrawDistance=nv; tuningFlag |= UserMinDrawDistance;};
void updateUserTargetDrawDistance(F32 nv){userTargetDrawDistance=nv; tuningFlag |= UserTargetDrawDistance;};
void updateImposterDistance(F32 nv){userImpostorDistance=nv; tuningFlag |= UserImpostorDistance;};
void updateImposterDistanceTuningEnabled(bool nv){userImpostorDistanceTuningEnabled=nv; tuningFlag |= UserImpostorDistanceTuningEnabled;};
void updateUserFPSTuningStrategy(U32 nv){userFPSTuningStrategy=nv; tuningFlag |= UserFPSTuningStrategy;};
void updateTargetFps(U32 nv){userTargetFPS=nv; tuningFlag |= UserTargetFPS;};
void updateUserARTCutoffSlider(F32 nv){userARTCutoffSliderValue=nv; tuningFlag |= UserARTCutoff;};
void updateUserAutoTuneEnabled(bool nv){userAutoTuneEnabled=nv; tuningFlag |= UserAutoTuneEnabled;};
void updateUserAutoTuneLock(bool nv){userAutoTuneLock=nv; tuningFlag |= UserAutoTuneLock;};
void updateUserTargetReflections(S32 nv){userTargetReflections=nv; tuningFlag |= UserTargetReflections;};
void applyUpdates();
void resetChanges(){tuningFlag=Nothing;};
void initialiseFromSettings();
void updateRenderCostLimitFromSettings();
void updateSettingsFromRenderCostLimit();
void applyUpdates();
};
extern Tunables tunables;
@ -177,8 +216,6 @@ namespace FSPerfStats
{
return max[getReadBufferIndex()][static_cast<size_t>(otype)][static_cast<size_t>(type)];
}
static void updateSettingsFromRenderCostLimit();
static void updateRenderCostLimitFromSettings();
static void updateAvatarParams();
private:
StatsRecorder();

View File

@ -5,12 +5,12 @@ if [[ $SKIP_NOTARIZATION == "true" ]]; then
fi
CONFIG_FILE="$build_secrets_checkout/code-signing-osx/notarize_creds.sh"
if [ -f "$CONFIG_FILE" ]; then
source $CONFIG_FILE
if [[ -f "$CONFIG_FILE" ]]; then
source "$CONFIG_FILE"
app_file="$1"
zip_file=${app_file/app/zip}
ditto -c -k --keepParent "$app_file" "$zip_file"
if [ -f "$zip_file" ]; then
if [[ -f "$zip_file" ]]; then
res=$(xcrun altool --notarize-app --primary-bundle-id "com.secondlife.viewer" \
--username $USERNAME \
--password $PASSWORD \
@ -19,37 +19,39 @@ if [ -f "$CONFIG_FILE" ]; then
echo $res
requestUUID=$(echo $res | awk '/RequestUUID/ { print $NF; }')
echo "Apple Notarization RequestUUID: $requestUUID"
if [[ -n $requestUUID ]]; then
status="in progress"
while [[ "$status" == "in progress" ]]; do
in_progress=1
while [[ $in_progress -eq 1 ]]; do
sleep 30
status=$(xcrun altool --notarization-info "$requestUUID" \
res=$(xcrun altool --notarization-info "$requestUUID" \
--username $USERNAME \
--password $PASSWORD 2>&1 \
| awk -F ': ' '/Status:/ { print $2; }' )
echo "$status"
--password $PASSWORD 2>&1)
if [[ $res != *"in progress"* ]]; then
in_progress=0
fi
echo "."
done
# log results
xcrun altool --notarization-info "$requestUUID" \
--username $USERNAME \
--password $PASSWORD
echo $res
#remove temporary file
rm "$zip_file"
if [["$status" == "success"]]; then
if [[ $res == *"success"* ]]; then
xcrun stapler staple "$app_file"
elif [["$status" == "invalid"]]; then
exit 0
elif [[ $res == *"invalid"* ]]; then
echo "Notarization error: failed to process the app file"
exit 1
else
echo "Notarization error: unknown response status"
fi
else
echo "Notarization error: couldn't get request UUID"
echo $res
exit 1
fi
else
echo "Notarization error: ditto failed"
exit 1
fi
fi

View File

@ -3,6 +3,8 @@
SCRIPT_PATH=`readlink -f $0`
SCRIPT_PATH=`dirname $SCRIPT_PATH`
echo "Trying to build AppImage in directory $1 into file $3"
# All hope is lost if there is no lsb_release command
command -v lsb_release >/dev/null 2>/dev/null || exit 0
@ -45,3 +47,8 @@ chmod a+x appimagetool-x86_64.AppImage
./appimagetool-x86_64.AppImage --appimage-extract
rm appimagetool-x86_64.AppImage
ARCH=x86_64 squashfs-root/AppRun packaged
if [ -f $2 ]
then
mv $2 $3
fi

View File

@ -660,10 +660,17 @@ Function CloseSecondLife
LOOP:
FindWindow $0 "Second Life" ""
IntCmp $0 0 DONE
IntCmp $0 0 SLEEP
Sleep 500
Goto LOOP
SLEEP:
# Second life window just closed, but program might not be fully done yet
# and OS might have not released some locks, wait a bit more to make sure
# all file handles were released.
# If something still isn't unlocked, it will trigger a notification from
# RemoveProgFilesOnInst
Sleep 1000
DONE:
Pop $0
Return
@ -704,6 +711,18 @@ FunctionEnd
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Function RemoveProgFilesOnInst
# We do not remove whole pervious install folder on install, since
# there is a chance that viewer was installed into some important
# folder by intent or accident
# RMDir /r $INSTDIR is especially unsafe if user installed somewhere
# like Program Files
# Set retry counter. All integers are strings.
Push $0
StrCpy $0 0
PREINSTALLREMOVE:
# Remove old SecondLife.exe to invalidate any old shortcuts to it that may be in non-standard locations. See MAINT-3575
# <FS:Ansariel> Remove VMP
#Delete "$INSTDIR\$INSTEXE"
@ -712,13 +731,35 @@ Delete "$INSTDIR\$VIEWER_EXE"
# Remove old shader files first so fallbacks will work. See DEV-5663
RMDir /r "$INSTDIR\app_settings\shaders"
# Remove skins folder to clean up files removed during development
# Remove folders to clean up files removed during development
RMDir /r "$INSTDIR\app_settings"
RMDir /r "$INSTDIR\skins"
RMDir /r "$INSTDIR\vmp_icons"
# Remove llplugin, plugins can crash or malfunction if they
# find modules from different versions
RMDir /r "$INSTDIR\llplugin"
IntOp $0 $0 + 1
IfErrors 0 PREINSTALLDONE
IntCmp $0 1 PREINSTALLREMOVE #try again once
StrCmp $SKIP_DIALOGS "true" PREINSTALLDONE
MessageBox MB_ABORTRETRYIGNORE $(CloseSecondLifeInstRM) IDABORT PREINSTALLFAIL IDRETRY PREINSTALLREMOVE
# MB_ABORTRETRYIGNORE does not accept IDIGNORE
Goto PREINSTALLDONE
PREINSTALLFAIL:
Quit
PREINSTALLDONE:
# We are no longer including release notes with the viewer, so remove them.
;Delete "$SMPROGRAMS\$INSTSHORTCUT\SL Release Notes.lnk"
;Delete "$INSTDIR\releasenotes.txt"
Pop $0
FunctionEnd
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

View File

@ -4678,16 +4678,6 @@ bool LLAgent::teleportCore(bool is_local)
// hide the Region/Estate floater
LLFloaterReg::hideInstance("region_info");
// minimize the Search floater (STORM-1474)
{
LLFloater* instance = LLFloaterReg::getInstance("search");
if (instance && instance->getVisible())
{
instance->setMinimized(TRUE);
}
}
LLViewerParcelMgr::getInstance()->deselectLand();
LLViewerMediaFocus::getInstance()->clearFocus();

View File

@ -535,6 +535,11 @@ void LLAppCoreHttp::refreshSettings(bool initial)
LLCore::HttpStatus LLAppCoreHttp::sslVerify(const std::string &url,
const LLCore::HttpHandler::ptr_t &handler, void *appdata)
{
if (gDisconnected)
{
return LLCore::HttpStatus(LLCore::HttpStatus::EXT_CURL_EASY, CURLE_OPERATION_TIMEDOUT);
}
LLCore::HttpStatus result;
try
{

View File

@ -1331,47 +1331,45 @@ bool LLAppViewer::init()
gGLActive = FALSE;
// <FS:Ansariel> Disable updater
//#if LL_RELEASE_FOR_DOWNLOAD
// if (!gSavedSettings.getBOOL("CmdLineSkipUpdater"))
// {
// LLProcess::Params updater;
// updater.desc = "updater process";
// // Because it's the updater, it MUST persist beyond the lifespan of the
// // viewer itself.
// updater.autokill = false;
// std::string updater_file;
// <FS:Ansariel> Disable updater
//#if LL_RELEASE_FOR_DOWNLOAD
// if (!gSavedSettings.getBOOL("CmdLineSkipUpdater"))
// {
// LLProcess::Params updater;
// updater.desc = "updater process";
// // Because it's the updater, it MUST persist beyond the lifespan of the
// // viewer itself.
// updater.autokill = false;
// std::string updater_file;
//#if LL_WINDOWS
// updater_file = "SLVersionChecker.exe";
// updater.executable = gDirUtilp->getExpandedFilename(LL_PATH_EXECUTABLE, updater_file);
// updater_file = "SLVersionChecker.exe";
// updater.executable = gDirUtilp->getExpandedFilename(LL_PATH_EXECUTABLE, updater_file);
//#elif LL_DARWIN
// // explicitly run the system Python interpreter on SLVersionChecker.py
// updater.executable = "python";
// updater_file = "SLVersionChecker.py";
// updater.args.add(gDirUtilp->add(gDirUtilp->getAppRODataDir(), "updater", updater_file));
// updater_file = "SLVersionChecker";
// updater.executable = gDirUtilp->add(gDirUtilp->getAppRODataDir(), "updater", updater_file);
//#else
// updater_file = "SLVersionChecker";
// updater.executable = gDirUtilp->getExpandedFilename(LL_PATH_EXECUTABLE, updater_file);
// updater_file = "SLVersionChecker";
// updater.executable = gDirUtilp->getExpandedFilename(LL_PATH_EXECUTABLE, updater_file);
//#endif
// // add LEAP mode command-line argument to whichever of these we selected
// updater.args.add("leap");
// // UpdaterServiceSettings
// if (gSavedSettings.getBOOL("FirstLoginThisInstall"))
// {
// // Befor first login, treat this as 'manual' updates,
// // updater won't install anything, but required updates
// updater.args.add("0");
// }
// else
// {
// updater.args.add(stringize(gSavedSettings.getU32("UpdaterServiceSetting")));
// }
// // channel
// updater.args.add(LLVersionInfo::instance().getChannel());
// // testok
// updater.args.add(stringize(gSavedSettings.getBOOL("UpdaterWillingToTest")));
// // ForceAddressSize
// updater.args.add(stringize(gSavedSettings.getU32("ForceAddressSize")));
// // add LEAP mode command-line argument to whichever of these we selected
// updater.args.add("leap");
// // UpdaterServiceSettings
// if (gSavedSettings.getBOOL("FirstLoginThisInstall"))
// {
// // Befor first login, treat this as 'manual' updates,
// // updater won't install anything, but required updates
// updater.args.add("0");
// }
// else
// {
// updater.args.add(stringize(gSavedSettings.getU32("UpdaterServiceSetting")));
// }
// // channel
// updater.args.add(LLVersionInfo::instance().getChannel());
// // testok
// updater.args.add(stringize(gSavedSettings.getBOOL("UpdaterWillingToTest")));
// // ForceAddressSize
// updater.args.add(stringize(gSavedSettings.getU32("ForceAddressSize")));
//
// try
// {
@ -1389,11 +1387,11 @@ bool LLAppViewer::init()
// OSMB_OK);
// mUpdaterNotFound = true;
// }
// }
// else
// {
// LL_WARNS("InitInfo") << "Skipping updater check." << LL_ENDL;
// }
// }
// else
// {
// LL_WARNS("InitInfo") << "Skipping updater check." << LL_ENDL;
// }
//
// if (mUpdaterNotFound)
// {
@ -1426,14 +1424,14 @@ bool LLAppViewer::init()
// }
// }
//
// if (gSavedSettings.getBOOL("QAMode") && gSavedSettings.getS32("QAModeEventHostPort") > 0)
// {
// LL_WARNS("InitInfo") << "QAModeEventHostPort DEPRECATED: "
// << "lleventhost no longer supported as a dynamic library"
// << LL_ENDL;
// }
// if (gSavedSettings.getBOOL("QAMode") && gSavedSettings.getS32("QAModeEventHostPort") > 0)
// {
// LL_WARNS("InitInfo") << "QAModeEventHostPort DEPRECATED: "
// << "lleventhost no longer supported as a dynamic library"
// << LL_ENDL;
// }
//#endif //LL_RELEASE_FOR_DOWNLOAD
// </FS:Ansariel>
// </FS:Ansariel>
LLTextUtil::TextHelpers::iconCallbackCreationFunction = create_text_segment_icon_from_url_match;
@ -1604,7 +1602,7 @@ bool LLAppViewer::doFrame()
// <FS:Beq> Perfstats collection Frame boundary
{
// and now adjust the visuals from previous frame.
if(FSPerfStats::autoTune && FSPerfStats::tunables.tuningFlag != FSPerfStats::Tunables::Nothing)
if(FSPerfStats::tunables.userAutoTuneEnabled && FSPerfStats::tunables.tuningFlag != FSPerfStats::Tunables::Nothing)
{
FSPerfStats::tunables.applyUpdates();
}
@ -2049,12 +2047,14 @@ 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
// remove any old breakpad minidump files from the log directory
if (! isError())
{
std::string logdir = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "");
gDirUtilp->deleteFilesInDir(logdir, "*-*-*-*-*.dmp");
}
#endif
// Kill off LLLeap objects. We can find them all because LLLeap is derived
// from LLInstanceTracker.
@ -2180,6 +2180,8 @@ bool LLAppViewer::cleanup()
if (gAudiop)
{
LL_INFOS() << "Shutting down audio" << LL_ENDL;
// be sure to stop the internet stream cleanly BEFORE destroying the interface to stop it.
gAudiop->stopInternetStream();
// shut down the streaming audio sub-subsystem first, in case it relies on not outliving the general audio subsystem.
@ -5198,120 +5200,6 @@ void LLAppViewer::addOnIdleCallback(const boost::function<void()>& cb)
void LLAppViewer::loadKeyBindings()
{
std::string key_bindings_file = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, "key_bindings.xml");
#if 1
// Legacy support
// Remove #if-#endif section half a year after DRTVWR-501 releases.
// Mouse actions are part of keybinding file since DRTVWR-501 instead of being stored in
// settings.xml. To support legacy viewers that were storing in settings.xml we need to
// transfer old variables to new format.
// Also part of backward compatibility is present in LLKeyConflictHandler to modify
// legacy variables on changes in new system (to make sure we won't enforce
// legacy values again if user dropped to defaults in new system)
if (LLVersionInfo::getInstance()->getChannelAndVersion() != gLastRunVersion
|| !gDirUtilp->fileExists(key_bindings_file)) // if file is missing, assume that there were no changes by user yet
{
// copy mouse actions and voice key changes to new file
LL_INFOS("InitInfo") << "Converting legacy mouse bindings to new format" << LL_ENDL;
// Load settings from file
LLKeyConflictHandler third_person_view(LLKeyConflictHandler::MODE_THIRD_PERSON);
LLKeyConflictHandler sitting_view(LLKeyConflictHandler::MODE_SITTING);
// Since we are only modifying keybindings if personal file doesn't exist yet,
// it should be safe to just overwrite the value
// If key is already in use somewhere by default, LLKeyConflictHandler should resolve it.
BOOL value = gSavedSettings.getBOOL("DoubleClickAutoPilot");
third_person_view.registerControl("walk_to",
0,
value ? EMouseClickType::CLICK_DOUBLELEFT : EMouseClickType::CLICK_NONE,
KEY_NONE,
MASK_NONE,
value);
U32 index = value ? 1 : 0; // we can store multiple combinations per action, so if first is in use by doubleclick, go to second
value = gSavedSettings.getBOOL("ClickToWalk");
third_person_view.registerControl("walk_to",
index,
value ? EMouseClickType::CLICK_LEFT : EMouseClickType::CLICK_NONE,
KEY_NONE,
MASK_NONE,
value);
value = gSavedSettings.getBOOL("DoubleClickTeleport");
third_person_view.registerControl("teleport_to",
0,
value ? EMouseClickType::CLICK_DOUBLELEFT : EMouseClickType::CLICK_NONE,
KEY_NONE,
MASK_NONE,
value);
// sitting also supports teleport
sitting_view.registerControl("teleport_to",
0,
value ? EMouseClickType::CLICK_DOUBLELEFT : EMouseClickType::CLICK_NONE,
KEY_NONE,
MASK_NONE,
value);
std::string key_string = gSavedSettings.getString("PushToTalkButton");
EMouseClickType mouse = EMouseClickType::CLICK_NONE;
KEY key = KEY_NONE;
if (key_string == "MiddleMouse")
{
mouse = EMouseClickType::CLICK_MIDDLE;
}
else if (key_string == "MouseButton4")
{
mouse = EMouseClickType::CLICK_BUTTON4;
}
else if (key_string == "MouseButton5")
{
mouse = EMouseClickType::CLICK_BUTTON5;
}
else
{
LLKeyboard::keyFromString(key_string, &key);
}
value = gSavedSettings.getBOOL("PushToTalkToggle");
std::string control_name = value ? "toggle_voice" : "voice_follow_key";
third_person_view.registerControl(control_name, 0, mouse, key, MASK_NONE, true);
sitting_view.registerControl(control_name, 0, mouse, key, MASK_NONE, true);
if (third_person_view.hasUnsavedChanges())
{
// calls loadBindingsXML()
third_person_view.saveToSettings();
}
if (sitting_view.hasUnsavedChanges())
{
// calls loadBindingsXML()
sitting_view.saveToSettings();
}
// in case of voice we need to repeat this in other modes
for (U32 i = 0; i < LLKeyConflictHandler::MODE_COUNT - 1; ++i)
{
// edit and first person modes; MODE_SAVED_SETTINGS not in use at the moment
if (i != LLKeyConflictHandler::MODE_THIRD_PERSON && i != LLKeyConflictHandler::MODE_SITTING)
{
LLKeyConflictHandler handler((LLKeyConflictHandler::ESourceMode)i);
handler.registerControl(control_name, 0, mouse, key, MASK_NONE, true);
if (handler.hasUnsavedChanges())
{
// calls loadBindingsXML()
handler.saveToSettings();
}
}
}
}
// since something might have gone wrong or there might have been nothing to save
// (and because otherwise following code will have to be encased in else{}),
// load everything one last time
#endif
if (!gDirUtilp->fileExists(key_bindings_file) || !gViewerInput.loadBindingsXML(key_bindings_file))
{
// Failed to load custom bindings, try default ones
@ -5669,6 +5557,10 @@ void LLAppViewer::idle()
//
// Special case idle if still starting up
//
if (LLStartUp::getStartupState() >= STATE_WORLD_INIT)
{
update_texture_time();
}
if (LLStartUp::getStartupState() < STATE_STARTED)
{
// Skip rest if idle startup returns false (essentially, no world yet)

View File

@ -154,22 +154,22 @@ void LLAttachmentsMgr::onIdle()
return;
}
if (LLApp::isExiting())
{
return;
}
if (LLApp::isExiting())
{
return;
}
requestPendingAttachments();
linkRecentlyArrivedAttachments();
linkRecentlyArrivedAttachments();
expireOldAttachmentRequests();
expireOldAttachmentRequests();
expireOldDetachRequests();
expireOldDetachRequests();
// checkInvalidCOFLinks();
spamStatusInfo();
//checkInvalidCOFLinks();
spamStatusInfo();
}
void LLAttachmentsMgr::requestPendingAttachments()
@ -581,51 +581,55 @@ bool LLAttachmentsMgr::isAttachmentStateComplete() const
//
//void LLAttachmentsMgr::checkInvalidCOFLinks()
//{
// LLInventoryModel::cat_array_t cat_array;
// LLInventoryModel::item_array_t item_array;
// gInventory.collectDescendents(LLAppearanceMgr::instance().getCOF(),
// cat_array,item_array,LLInventoryModel::EXCLUDE_TRASH);
// for (S32 i=0; i<item_array.size(); i++)
// {
// const LLViewerInventoryItem* inv_item = item_array.at(i).get();
// const LLUUID& item_id = inv_item->getLinkedUUID();
// if (inv_item->getType() == LLAssetType::AT_OBJECT)
// {
// LLTimer timer;
// bool is_flagged_questionable = mQuestionableCOFLinks.getTime(item_id,timer);
// bool is_wearing_attachment = isAgentAvatarValid() && gAgentAvatarp->isWearingAttachment(item_id);
// if (is_wearing_attachment && is_flagged_questionable)
// {
// LL_DEBUGS("Avatar") << "ATT was flagged questionable but is now "
// << (is_wearing_attachment ? "attached " : "")
// <<"removing flag after "
// << timer.getElapsedTimeF32() << " item "
// << inv_item->getName() << " id " << item_id << LL_ENDL;
// mQuestionableCOFLinks.removeTime(item_id);
// }
// }
// }
//
// for(LLItemRequestTimes::iterator it = mQuestionableCOFLinks.begin();
// it != mQuestionableCOFLinks.end(); )
// {
// LLItemRequestTimes::iterator curr_it = it;
// ++it;
// const LLUUID& item_id = curr_it->first;
// LLViewerInventoryItem *inv_item = gInventory.getItem(item_id);
// if (curr_it->second.getElapsedTimeF32() > MAX_BAD_COF_TIME)
// {
// if (LLAppearanceMgr::instance().isLinkedInCOF(item_id))
// {
// LL_DEBUGS("Avatar") << "ATT Linked in COF but not attached or requested, deleting link after "
// << curr_it->second.getElapsedTimeF32() << " seconds for "
// << (inv_item ? inv_item->getName() : "UNKNOWN") << " id " << item_id << LL_ENDL;
// LLAppearanceMgr::instance().removeCOFItemLinks(item_id);
// }
// mQuestionableCOFLinks.erase(curr_it);
// continue;
// }
// }
// if (!gInventory.isInventoryUsable())
// {
// return;
// }
// LLInventoryModel::cat_array_t cat_array;
// LLInventoryModel::item_array_t item_array;
// gInventory.collectDescendents(LLAppearanceMgr::instance().getCOF(),
// cat_array,item_array,LLInventoryModel::EXCLUDE_TRASH);
// for (S32 i=0; i<item_array.size(); i++)
// {
// const LLViewerInventoryItem* inv_item = item_array.at(i).get();
// const LLUUID& item_id = inv_item->getLinkedUUID();
// if (inv_item->getType() == LLAssetType::AT_OBJECT)
// {
// LLTimer timer;
// bool is_flagged_questionable = mQuestionableCOFLinks.getTime(item_id,timer);
// bool is_wearing_attachment = isAgentAvatarValid() && gAgentAvatarp->isWearingAttachment(item_id);
// if (is_wearing_attachment && is_flagged_questionable)
// {
// LL_DEBUGS("Avatar") << "ATT was flagged questionable but is now "
// << (is_wearing_attachment ? "attached " : "")
// <<"removing flag after "
// << timer.getElapsedTimeF32() << " item "
// << inv_item->getName() << " id " << item_id << LL_ENDL;
// mQuestionableCOFLinks.removeTime(item_id);
// }
// }
// }
// for(LLItemRequestTimes::iterator it = mQuestionableCOFLinks.begin();
// it != mQuestionableCOFLinks.end(); )
// {
// LLItemRequestTimes::iterator curr_it = it;
// ++it;
// const LLUUID& item_id = curr_it->first;
// LLViewerInventoryItem *inv_item = gInventory.getItem(item_id);
// if (curr_it->second.getElapsedTimeF32() > MAX_BAD_COF_TIME)
// {
// if (LLAppearanceMgr::instance().isLinkedInCOF(item_id))
// {
// LL_DEBUGS("Avatar") << "ATT Linked in COF but not attached or requested, deleting link after "
// << curr_it->second.getElapsedTimeF32() << " seconds for "
// << (inv_item ? inv_item->getName() : "UNKNOWN") << " id " << item_id << LL_ENDL;
// LLAppearanceMgr::instance().removeCOFItemLinks(item_id);
// }
// mQuestionableCOFLinks.erase(curr_it);
// continue;
// }
// }
//}
void LLAttachmentsMgr::spamStatusInfo()

View File

@ -40,7 +40,7 @@ LLBrowserNotification::LLBrowserNotification()
{
}
bool LLBrowserNotification::processNotification(const LLNotificationPtr& notification)
bool LLBrowserNotification::processNotification(const LLNotificationPtr& notification, bool should_log)
{
LLUUID media_id = notification->getPayload()["media_id"].asUUID();
auto media_instance = LLMediaCtrl::getInstance(media_id);

View File

@ -911,6 +911,7 @@ protected:
static bool filterNotification(LLNotificationPtr notify);
// connect counter updaters to the corresponding signals
/*virtual*/ void onAdd(LLNotificationPtr p) { mChiclet->setCounter(++mChiclet->mUreadSystemNotifications); }
/*virtual*/ void onLoad(LLNotificationPtr p) { mChiclet->setCounter(++mChiclet->mUreadSystemNotifications); }
/*virtual*/ void onDelete(LLNotificationPtr p) { mChiclet->setCounter(--mChiclet->mUreadSystemNotifications); }
LLNotificationChiclet* const mChiclet;

View File

@ -91,6 +91,7 @@ LLConversationViewSession::LLConversationViewSession(const LLConversationViewSes
mFlashStarted(false)
{
mFlashTimer = new LLFlashTimer();
mAreChildrenInited = true; // inventory only
}
LLConversationViewSession::~LLConversationViewSession()

View File

@ -969,7 +969,7 @@ BOOL LLDrawable::updateGeometry(BOOL priority)
LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWABLE
llassert(mVObjp.notNull());
BOOL res = mVObjp->updateGeometry(this);
BOOL res = mVObjp && mVObjp->updateGeometry(this);
return res;
}

View File

@ -36,6 +36,7 @@
#include "llfloaterevent.h"
#include "llagent.h"
#include "llcommandhandler.h" // secondlife:///app/... support
#include "lltrans.h"
// <FS:CR> FIRE-6310 - Legacy Search
#include "fsfloatersearch.h"
#include "llviewerfloaterreg.h"
@ -269,8 +270,40 @@ void LLEventNotifier::load(const LLSD& event_options)
end = event_options.endArray(); resp_it != end; ++resp_it)
{
LLSD response = *resp_it;
LLDate date;
bool is_iso8601_date = false;
add(response["event_id"].asInteger(), response["event_date_ut"], response["event_date"].asString(), response["event_name"].asString());
if (response["event_date"].isDate())
{
date = response["event_date"].asDate();
is_iso8601_date = true;
}
else if (date.fromString(response["event_date"].asString()))
{
is_iso8601_date = true;
}
if (is_iso8601_date)
{
std::string dateStr;
dateStr = "[" + LLTrans::getString("LTimeYear") + "]-["
+ LLTrans::getString("LTimeMthNum") + "]-["
+ LLTrans::getString("LTimeDay") + "] ["
+ LLTrans::getString("LTimeHour") + "]:["
+ LLTrans::getString("LTimeMin") + "]:["
+ LLTrans::getString("LTimeSec") + "]";
LLSD substitution;
substitution["datetime"] = date;
LLStringUtil::format(dateStr, substitution);
add(response["event_id"].asInteger(), response["event_date_ut"], dateStr, response["event_name"].asString());
}
else
{
add(response["event_id"].asInteger(), response["event_date_ut"], response["event_date"].asString(), response["event_name"].asString());
}
}
}

View File

@ -2121,9 +2121,17 @@ BOOL LLFavoritesOrderStorage::saveFavoritesRecord(bool pref_changed)
pref_changed |= mRecreateFavoriteStorage;
mRecreateFavoriteStorage = false;
// Can get called before inventory is done initializing.
if (!gInventory.isInventoryUsable())
{
return FALSE;
}
LLUUID favorite_folder= gInventory.findCategoryUUIDForType(LLFolderType::FT_FAVORITE);
if (favorite_folder.isNull())
return FALSE;
{
return FALSE;
}
LLInventoryModel::item_array_t items;
LLInventoryModel::cat_array_t cats;

View File

@ -730,11 +730,14 @@ void LLVolumeImplFlexible::preRebuild()
void LLVolumeImplFlexible::doFlexibleRebuild(bool rebuild_volume)
{
LLVolume* volume = mVO->getVolume();
if(rebuild_volume)
{
volume->setDirty();
}
volume->regen();
if (volume)
{
if (rebuild_volume)
{
volume->setDirty();
}
volume->regen();
}
mUpdated = TRUE;
}

View File

@ -102,6 +102,7 @@ BOOL LLFloater360Capture::postBuild()
mWebBrowser = getChild<LLMediaCtrl>("360capture_contents");
mWebBrowser->addObserver(this);
mWebBrowser->setAllowFileDownload(true);
// There is a group of radio buttons that define the quality
// by each having a 'value' that is returns equal to the pixel

View File

@ -107,7 +107,7 @@ protected:
void onAssetLoaded(LLUUID asset_id, LLSettingsBase::ptr_t settins, S32 status);
private:
protected:
LLUUID mExpectingAssetId; // for asset load confirmation
};

View File

@ -1596,7 +1596,8 @@ void LLFloaterEditExtDayCycle::onIdlePlay(void* user_data)
F32 new_frame = fmod(self->mPlayStartFrame + prcnt_played, 1.f);
self->mTimeSlider->setCurSliderValue(new_frame); // will do the rounding
self->mSkyBlender->setPosition(new_frame);
self->mWaterBlender->setPosition(new_frame);
self->synchronizeTabs();
self->updateTimeAndLabel();
self->updateButtons();

View File

@ -194,8 +194,6 @@ private:
std::string mLastFrameSlider;
bool mShiftCopyEnabled;
LLUUID mExpectingAssetId;
LLButton* mAddFrameButton;
LLButton* mDeleteFrameButton;
LLButton* mImportButton;

View File

@ -1703,7 +1703,7 @@ BOOL LLFloaterIMContainer::selectConversationPair(const LLUUID& session_id, bool
/* floater processing */
if (NULL != session_floater)
if (NULL != session_floater && !session_floater->isDead())
{
if (session_id != getSelectedSession())
{
@ -1875,11 +1875,14 @@ bool LLFloaterIMContainer::removeConversationListItem(const LLUUID& uuid, bool c
if (widget)
{
is_widget_selected = widget->isSelected();
new_selection = mConversationsRoot->getNextFromChild(widget, FALSE);
if (!new_selection)
{
new_selection = mConversationsRoot->getPreviousFromChild(widget, FALSE);
}
if (mConversationsRoot)
{
new_selection = mConversationsRoot->getNextFromChild(widget, FALSE);
if (!new_selection)
{
new_selection = mConversationsRoot->getPreviousFromChild(widget, FALSE);
}
}
// Will destroy views and delete models that are not assigned to any views
widget->destroyView();

View File

@ -386,13 +386,16 @@ void LLFloaterIMSessionTab::draw()
void LLFloaterIMSessionTab::enableDisableCallBtn()
{
mVoiceButton->setEnabled(
mSessionID.notNull()
&& mSession
&& mSession->mSessionInitialized
&& LLVoiceClient::getInstance()->voiceEnabled()
&& LLVoiceClient::getInstance()->isVoiceWorking()
&& mSession->mCallBackEnabled);
if (LLVoiceClient::instanceExists())
{
mVoiceButton->setEnabled(
mSessionID.notNull()
&& mSession
&& mSession->mSessionInitialized
&& LLVoiceClient::getInstance()->voiceEnabled()
&& LLVoiceClient::getInstance()->isVoiceWorking()
&& mSession->mCallBackEnabled);
}
}
void LLFloaterIMSessionTab::onFocusReceived()

View File

@ -2682,6 +2682,7 @@ BOOL LLPanelLandAccess::postBuild()
//mListBanned->setContextMenu(LLScrollListCtrl::MENU_AVATAR);
mListBanned->setContextMenu(&gFSNameListAvatarMenu);
// </FS:Ansariel>
mListBanned->setAlternateSort();
}
return TRUE;
@ -2784,11 +2785,12 @@ void LLPanelLandAccess::refresh()
{
const LLAccessEntry& entry = (*cit).second;
std::string duration;
S32 seconds = -1;
if (entry.mTime != 0)
{
LLStringUtil::format_map_t args;
S32 now = time(NULL);
S32 seconds = entry.mTime - now;
seconds = entry.mTime - now;
if (seconds < 0) seconds = 0;
if (seconds >= 7200)
@ -2825,6 +2827,7 @@ void LLPanelLandAccess::refresh()
columns[0]["column"] = "name"; // to be populated later
columns[1]["column"] = "duration";
columns[1]["value"] = duration;
columns[1]["alt_value"] = entry.mTime != 0 ? std::to_string(seconds) : "Always";
mListBanned->addElement(item);
}
mListBanned->sortByName(TRUE);

View File

@ -108,6 +108,9 @@ LLFloaterLandHoldings::~LLFloaterLandHoldings()
void LLFloaterLandHoldings::onOpen(const LLSD& key)
{
LLScrollListCtrl *list = getChild<LLScrollListCtrl>("parcel list");
list->clearRows();
// query_id null is known to be us
const LLUUID& query_id = LLUUID::null;

View File

@ -40,6 +40,7 @@
#include "llagent.h"
#include "llbutton.h"
#include "llcombobox.h"
#include "llfloaterreg.h"
#include "llfocusmgr.h"
#include "llmeshrepository.h"
#include "llnotificationsutil.h"
@ -391,10 +392,21 @@ void LLFloaterModelPreview::initModelPreview()
mModelPreview = new LLModelPreview(tex_width, tex_height, this);
mModelPreview->setPreviewTarget(PREVIEW_CAMERA_DISTANCE);
mModelPreview->setDetailsCallback(boost::bind(&LLFloaterModelPreview::setDetails, this, _1, _2, _3, _4, _5));
mModelPreview->setDetailsCallback(boost::bind(&LLFloaterModelPreview::setDetails, this, _1, _2, _3));
mModelPreview->setModelUpdatedCallback(boost::bind(&LLFloaterModelPreview::modelUpdated, this, _1));
}
//static
bool LLFloaterModelPreview::showModelPreview()
{
LLFloaterModelPreview* fmp = (LLFloaterModelPreview*)LLFloaterReg::getInstance("upload_model");
if (fmp && !fmp->isModelLoading())
{
fmp->loadHighLodModel();
}
return true;
}
void LLFloaterModelPreview::onUploadOptionChecked(LLUICtrl* ctrl)
{
if (mModelPreview)
@ -911,9 +923,6 @@ void LLFloaterModelPreview::draw()
}
}
childSetTextArg("prim_cost", "[PRIM_COST]", llformat("%d", mModelPreview->mResourceCost));
childSetTextArg("description_label", "[TEXTURES]", llformat("%d", mModelPreview->mTextureSet.size()));
if (!isMinimized() && mModelPreview->lodsReady())
{
draw3dPreview();
@ -1673,7 +1682,7 @@ void LLFloaterModelPreview::addStringToLogTab(const std::string& str, bool flash
}
}
void LLFloaterModelPreview::setDetails(F32 x, F32 y, F32 z, F32 streaming_cost, F32 physics_cost)
void LLFloaterModelPreview::setDetails(F32 x, F32 y, F32 z)
{
assert_main_thread();
childSetTextArg("import_dimensions", "[X]", llformat("%.3f", x));
@ -1846,9 +1855,20 @@ void LLFloaterModelPreview::toggleCalculateButton(bool visible)
void LLFloaterModelPreview::onLoDSourceCommit(S32 lod)
{
mModelPreview->updateLodControls(lod);
refresh();
LLComboBox* lod_source_combo = getChild<LLComboBox>("lod_source_" + lod_name[lod]);
if (lod_source_combo->getCurrentIndex() == LLModelPreview::LOD_FROM_FILE
&& mModelPreview->mLODFile[lod].empty())
{
// File wasn't selected, so nothing to do yet, refreshing
// hovewer will cause a small freeze with large meshes
// Might be good idea to open filepicker here
return;
}
refresh();
S32 index = lod_source_combo->getCurrentIndex();
if (index == LLModelPreview::MESH_OPTIMIZER_AUTO
|| index == LLModelPreview::MESH_OPTIMIZER_SLOPPY

View File

@ -73,6 +73,7 @@ public:
/*virtual*/ void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE);
void initModelPreview();
static bool showModelPreview();
BOOL handleMouseDown(S32 x, S32 y, MASK mask);
BOOL handleMouseUp(S32 x, S32 y, MASK mask);
@ -90,7 +91,7 @@ public:
void clearAvatarTab(); // clears table
void updateAvatarTab(bool highlight_overrides); // populates table and data as nessesary
void setDetails(F32 x, F32 y, F32 z, F32 streaming_cost, F32 physics_cost);
void setDetails(F32 x, F32 y, F32 z);
void setPreviewLOD(S32 lod);
void onBrowseLOD(S32 lod);

Some files were not shown because too many files have changed in this diff Show More