diff options
| author | Leyla Farazha <leyla@lindenlab.com> | 2011-03-28 13:15:49 -0700 | 
|---|---|---|
| committer | Leyla Farazha <leyla@lindenlab.com> | 2011-03-28 13:15:49 -0700 | 
| commit | ae086d95fa7545d3acc358e7d3e7485dc29aa066 (patch) | |
| tree | deadfc1164de517502070c2317401bea4d05a45e | |
| parent | 46297b954386158b183bc56a02904ca14d0c3d3a (diff) | |
| parent | 835671f27809ce8e5ab17e6c299be35260239d51 (diff) | |
Merge
26 files changed, 825 insertions, 146 deletions
| @@ -86,3 +86,4 @@ f1827b441e05bf37c68e2c15ebc6d09e9b03f527 2.6.0-start  c5bdef3aaa2744626aef3c217ce29e1900d357b3 2.6.1-start  9e4641f4a7870c0f565a25a2971368d5a29516a1 DRTVWR-41_2.6.0-beta2  9e4641f4a7870c0f565a25a2971368d5a29516a1 2.6.0-beta2 +56b2778c743c2a964d82e1caf11084d76a87de2c 2.6.2-start diff --git a/indra/integration_tests/CMakeLists.txt b/indra/integration_tests/CMakeLists.txt index 67e8fbf1f2..5935f23fe9 100644 --- a/indra/integration_tests/CMakeLists.txt +++ b/indra/integration_tests/CMakeLists.txt @@ -1,3 +1,4 @@  # -*- cmake -*-  add_subdirectory(llui_libtest) +add_subdirectory(llimage_libtest) diff --git a/indra/integration_tests/llimage_libtest/CMakeLists.txt b/indra/integration_tests/llimage_libtest/CMakeLists.txt new file mode 100644 index 0000000000..f59440be6b --- /dev/null +++ b/indra/integration_tests/llimage_libtest/CMakeLists.txt @@ -0,0 +1,131 @@ +# -*- cmake -*- + +# Integration tests of the llimage library (JPEG2000, PNG, jpeg, etc... images reading and writing) + +project (llimage_libtest) + +include(00-Common) +include(LLCommon) +include(Linking) +include(LLSharedLibs) +include(LLImage) +include(LLImageJ2COJ)  +include(LLKDU) +include(LLMath) +include(LLVFS) + +include_directories( +    ${LLCOMMON_INCLUDE_DIRS} +    ${LLVFS_INCLUDE_DIRS} +    ${LLIMAGE_INCLUDE_DIRS} +    ${LLMATH_INCLUDE_DIRS} +    ) + +set(llimage_libtest_SOURCE_FILES +    llimage_libtest.cpp +    ) + +set(llimage_libtest_HEADER_FILES +    CMakeLists.txt +    llimage_libtest.h +    ) + +set_source_files_properties(${llimage_libtest_HEADER_FILES} +                            PROPERTIES HEADER_FILE_ONLY TRUE) + +list(APPEND llimage_libtest_SOURCE_FILES ${llimage_libtest_HEADER_FILES}) + +add_executable(llimage_libtest +    WIN32 +    MACOSX_BUNDLE +    ${llimage_libtest_SOURCE_FILES} +) + +set_target_properties(llimage_libtest +    PROPERTIES +    WIN32_EXECUTABLE +    FALSE +) + +# OS-specific libraries +if (DARWIN) +  include(CMakeFindFrameworks) +  find_library(COREFOUNDATION_LIBRARY CoreFoundation) +  set(OS_LIBRARIES ${COREFOUNDATION_LIBRARY}) +elseif (WINDOWS) +#  set(OS_LIBRARIES) +elseif (LINUX) +#  set(OS_LIBRARIES) +else (DARWIN) +  message(FATAL_ERROR "Unknown platform") +endif (DARWIN) + +# Libraries on which this application depends on +# Sort by high-level to low-level +target_link_libraries(llimage_libtest +	${LLCOMMON_LIBRARIES} +	${LLVFS_LIBRARIES} +    ${LLIMAGE_LIBRARIES} +    ${LLKDU_LIBRARIES} +    ${KDU_LIBRARY} +    ${LLIMAGEJ2COJ_LIBRARIES} +    ${OS_LIBRARIES} +    ) +	 +if (DARWIN) +  # Path inside the app bundle where we'll need to copy libraries +  set(LLIMAGE_LIBTEST_DESTINATION_DIR +    ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/llimage_libtest.app/Contents/Resources +  ) +  # Create the Contents/Resources directory +  add_custom_command( +    TARGET llimage_libtest POST_BUILD +    COMMAND ${CMAKE_COMMAND} +    ARGS +      -E +      make_directory +      ${LLIMAGE_LIBTEST_DESTINATION_DIR} +    COMMENT "Creating Resources directory in app bundle." +  )  +else (DARWIN) +  set(LLIMAGE_LIBTEST_DESTINATION_DIR +    ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/ +  ) +endif (DARWIN) + +get_target_property(BUILT_LLCOMMON llcommon LOCATION) +add_custom_command(TARGET llimage_libtest POST_BUILD +  COMMAND ${CMAKE_COMMAND} -E copy ${BUILT_LLCOMMON}  ${LLIMAGE_LIBTEST_DESTINATION_DIR} +  DEPENDS ${BUILT_LLCOMMON} +) + +if (DARWIN) +  # Copy the required libraries to the package app +  add_custom_command(TARGET llimage_libtest POST_BUILD +    COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_SOURCE_DIR}/../libraries/universal-darwin/lib_release/libapr-1.0.3.7.dylib ${LLIMAGE_LIBTEST_DESTINATION_DIR} +    DEPENDS ${CMAKE_SOURCE_DIR}/../libraries/universal-darwin/lib_release/libapr-1.0.3.7.dylib +  ) + add_custom_command(TARGET llimage_libtest POST_BUILD +    COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_SOURCE_DIR}/../libraries/universal-darwin/lib_release/libaprutil-1.0.3.8.dylib ${LLIMAGE_LIBTEST_DESTINATION_DIR} +    DEPENDS ${CMAKE_SOURCE_DIR}/../libraries/universal-darwin/lib_release/libaprutil-1.0.3.8.dylib +  ) +  add_custom_command(TARGET llimage_libtest POST_BUILD +    COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_SOURCE_DIR}/../libraries/universal-darwin/lib_release/libexception_handler.dylib ${LLIMAGE_LIBTEST_DESTINATION_DIR} +    DEPENDS ${CMAKE_SOURCE_DIR}/../libraries/universal-darwin/lib_release/libexception_handler.dylib +  ) +  add_custom_command(TARGET llimage_libtest POST_BUILD +    COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_SOURCE_DIR}/../libraries/universal-darwin/lib_release/libexpat.0.5.0.dylib ${LLIMAGE_LIBTEST_DESTINATION_DIR} +    DEPENDS ${CMAKE_SOURCE_DIR}/../libraries/universal-darwin/lib_release/libexpat.0.5.0.dylib +  ) +endif (DARWIN) + +if (WINDOWS) +  # Check indra/test_apps/llplugintest/CMakeLists.txt for an example of what to copy over for Windows and how +endif (WINDOWS) + +# Ensure people working on the viewer don't break this library +# *NOTE: This could be removed, or only built by TeamCity, if the build +# and link times become too long. +add_dependencies(viewer llimage_libtest) + +ll_deploy_sharedlibs_command(llimage_libtest)  diff --git a/indra/integration_tests/llimage_libtest/llimage_libtest.cpp b/indra/integration_tests/llimage_libtest/llimage_libtest.cpp new file mode 100644 index 0000000000..365f5f758c --- /dev/null +++ b/indra/integration_tests/llimage_libtest/llimage_libtest.cpp @@ -0,0 +1,437 @@ +/**  + * @file llimage_libtest.cpp + * @author Merov Linden + * @brief Integration test for the llimage library + * + * $LicenseInfo:firstyear=2011&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2011, Linden Research, Inc. + *  + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + *  + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * Lesser General Public License for more details. + *  + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA + *  + * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA + * $/LicenseInfo$ + */ +#include "linden_common.h" +#include "llpointer.h" +#include "lltimer.h" + +#include "llimage_libtest.h" + +// Linden library includes +#include "llimage.h" +#include "llimagejpeg.h" +#include "llimagepng.h" +#include "llimagebmp.h" +#include "llimagetga.h" +#include "llimagej2c.h" +#include "lldir.h" + +// system libraries +#include <iostream> + +// doc string provided when invoking the program with --help  +static const char USAGE[] = "\n" +"usage:\tllimage_libtest [options]\n" +"\n" +" -h, --help\n" +"        Print this help\n" +" -i, --input <file1 .. file2>\n" +"        List of image files to load and convert. Patterns with wild cards can be used.\n" +" -o, --output <file1 .. file2> OR <type>\n" +"        List of image files to create (assumes same order as for input files)\n" +"        OR 3 letters file type extension to convert each input file into.\n" +" -log, --logmetrics <metric>\n" +"        Log performance data for <metric>. Results in <metric>.slp\n" +"        Note: so far, only ImageCompressionTester has been tested.\n" +" -r, --analyzeperformance\n" +"        Create a report comparing <metric>_baseline.slp with current <metric>.slp\n" +"        Results in <metric>_report.csv" +" -s, --image-stats\n" +"        Output stats for each input and output image.\n" +"\n"; + +// true when all image loading is done. Used by metric logging thread to know when to stop the thread. +static bool sAllDone = false; + +// Create an empty formatted image instance of the correct type from the filename +LLPointer<LLImageFormatted> create_image(const std::string &filename) +{ +	std::string exten = gDirUtilp->getExtension(filename); +	U32 codec = LLImageBase::getCodecFromExtension(exten); +	 +	LLPointer<LLImageFormatted> image; +	switch (codec) +	{ +		case IMG_CODEC_BMP: +			image = new LLImageBMP(); +			break; +		case IMG_CODEC_TGA: +			image = new LLImageTGA(); +			break; +		case IMG_CODEC_JPEG: +			image = new LLImageJPEG(); +			break; +		case IMG_CODEC_J2C: +			image = new LLImageJ2C(); +			break; +		case IMG_CODEC_PNG: +			image = new LLImagePNG(); +			break; +		default: +			return NULL; +	} +	 +	return image; +} + +void output_image_stats(LLPointer<LLImageFormatted> image, const std::string &filename) +{ +	// Print out some statistical data on the image +	std::cout << "Image stats for : " << filename << ", extension : " << image->getExtension() << std::endl; + +	std::cout << "    with : " << (int)(image->getWidth())       << ", height : " << (int)(image->getHeight())       << std::endl; +	std::cout << "    comp : " << (int)(image->getComponents())  << ", levels : " << (int)(image->getDiscardLevel()) << std::endl; +	std::cout << "    head : " << (int)(image->calcHeaderSize()) << ",   data : " << (int)(image->getDataSize())     << std::endl; + +	return; +} + +// Load an image from file and return a raw (decompressed) instance of its data +LLPointer<LLImageRaw> load_image(const std::string &src_filename, bool output_stats) +{ +	LLPointer<LLImageFormatted> image = create_image(src_filename); + +	if (!image->load(src_filename)) +	{ +		return NULL; +	} +	 +	if(	(image->getComponents() != 3) && (image->getComponents() != 4) ) +	{ +		std::cout << "Image files with less than 3 or more than 4 components are not supported\n"; +		return NULL; +	} +	 +	if (output_stats) +	{ +		output_image_stats(image, src_filename); +	} +	 +	LLPointer<LLImageRaw> raw_image = new LLImageRaw; +	if (!image->decode(raw_image, 0.0f)) +	{ +		return NULL; +	} +	 +	return raw_image; +} + +// Save a raw image instance into a file +bool save_image(const std::string &dest_filename, LLPointer<LLImageRaw> raw_image, bool output_stats) +{ +	LLPointer<LLImageFormatted> image = create_image(dest_filename); +	 +	if (!image->encode(raw_image, 0.0f)) +	{ +		return false; +	} +	 +	if (output_stats) +	{ +		output_image_stats(image, dest_filename); +	} + +	return image->save(dest_filename); +} + +void store_input_file(std::list<std::string> &input_filenames, const std::string &path) +{ +	// Break the incoming path in its components +	std::string dir = gDirUtilp->getDirName(path); +	std::string name = gDirUtilp->getBaseFileName(path); +	std::string exten = gDirUtilp->getExtension(path); + +	// std::cout << "store_input_file : " << path << ", dir : " << dir << ", name : " << name << ", exten : " << exten << std::endl; +	 +	// If extension is not an image type or "*", exit +	// Note: we don't support complex patterns for the extension like "j??" +	// Note: on most shells, the pattern expansion is done by the shell so that pattern matching limitation is actually not a problem +	if ((exten.compare("*") != 0) && (LLImageBase::getCodecFromExtension(exten) == IMG_CODEC_INVALID)) +	{ +		return; +	} + +	if ((name.find('*') != -1) || ((name.find('?') != -1))) +	{ +		// If file name is a pattern, iterate to get each file name and store +		std::string next_name; +		while (gDirUtilp->getNextFileInDir(dir,name,next_name)) +		{ +			std::string file_name = dir + gDirUtilp->getDirDelimiter() + next_name; +			input_filenames.push_back(file_name); +		} +	} +	else +	{ +		// Verify that the file does exist before storing  +		if (gDirUtilp->fileExists(path)) +		{ +			input_filenames.push_back(path); +		} +		else +		{ +			std::cout << "store_input_file : the file " << path << " could not be found" << std::endl; +		} +	}	 +} + +void store_output_file(std::list<std::string> &output_filenames, std::list<std::string> &input_filenames, const std::string &path) +{ +	// Break the incoming path in its components +	std::string dir = gDirUtilp->getDirName(path); +	std::string name = gDirUtilp->getBaseFileName(path); +	std::string exten = gDirUtilp->getExtension(path); +	 +	// std::cout << "store_output_file : " << path << ", dir : " << dir << ", name : " << name << ", exten : " << exten << std::endl; +	 +	if (dir.empty() && exten.empty()) +	{ +		// If dir and exten are empty, we interpret the name as a file extension type name and will iterate through input list to populate the output list +		exten = name; +		// Make sure the extension is an image type +		if (LLImageBase::getCodecFromExtension(exten) == IMG_CODEC_INVALID) +		{ +			return; +		} +		std::string delim = gDirUtilp->getDirDelimiter(); +		std::list<std::string>::iterator in_file  = input_filenames.begin(); +		std::list<std::string>::iterator end = input_filenames.end(); +		for (; in_file != end; ++in_file) +		{ +			dir = gDirUtilp->getDirName(*in_file); +			name = gDirUtilp->getBaseFileName(*in_file,true); +			std::string file_name; +			if (!dir.empty()) +			{ +				file_name = dir + delim + name + "." + exten; +			} +			else +			{ +				file_name = name + "." + exten; +			} +			output_filenames.push_back(file_name); +		} +	} +	else +	{ +		// Make sure the extension is an image type +		if (LLImageBase::getCodecFromExtension(exten) == IMG_CODEC_INVALID) +		{ +			return; +		} +		// Store the path +		output_filenames.push_back(path); +	} +} + +// Holds the metric gathering output in a thread safe way +class LogThread : public LLThread +{ +public: +	std::string mFile; + +	LogThread(std::string& test_name) : LLThread("llimage_libtest log") +	{ +		std::string file_name = test_name + std::string(".slp"); +		mFile = file_name; +	} +		 +	void run() +	{ +		std::ofstream os(mFile.c_str()); +			 +		while (!sAllDone) +		{ +			LLFastTimer::writeLog(os); +			os.flush(); +			ms_sleep(32); +		} +		LLFastTimer::writeLog(os); +		os.flush(); +		os.close(); +	}		 +}; + +int main(int argc, char** argv) +{ +	// List of input and output files +	std::list<std::string> input_filenames; +	std::list<std::string> output_filenames; +	bool analyze_performance = false; +	bool image_stats = false; + +	// Init whatever is necessary +	ll_init_apr(); +	LLImage::initClass(); +	LogThread* fast_timer_log_thread = NULL;	// For performance and metric gathering + +	// Analyze command line arguments +	for (int arg = 1; arg < argc; ++arg) +	{ +		if (!strcmp(argv[arg], "--help") || !strcmp(argv[arg], "-h")) +		{ +            // Send the usage to standard out +            std::cout << USAGE << std::endl; +			return 0; +		} +		else if ((!strcmp(argv[arg], "--input") || !strcmp(argv[arg], "-i")) && arg < argc-1) +		{ +			std::string file_name = argv[arg+1]; +			while (file_name[0] != '-')		// if arg starts with '-', we consider it's not a file name but some other argument +			{ +				// std::cout << "input file name : " << file_name << std::endl;				 +				store_input_file(input_filenames, file_name); +				arg += 1;					// Skip that arg now we know it's a file name +				if ((arg + 1) == argc)		// Break out of the loop if we reach the end of the arg list +					break; +				file_name = argv[arg+1];	// Next argument and loop over +			} +		} +		else if ((!strcmp(argv[arg], "--output") || !strcmp(argv[arg], "-o")) && arg < argc-1) +		{ +			std::string file_name = argv[arg+1]; +			while (file_name[0] != '-')		// if arg starts with '-', we consider it's not a file name but some other argument +			{ +				// std::cout << "output file name : " << file_name << std::endl;				 +				store_output_file(output_filenames, input_filenames, file_name); +				arg += 1;					// Skip that arg now we know it's a file name +				if ((arg + 1) == argc)		// Break out of the loop if we reach the end of the arg list +					break; +				file_name = argv[arg+1];	// Next argument and loop over +			} +		} +		else if (!strcmp(argv[arg], "--logmetrics") || !strcmp(argv[arg], "-log")) +		{ +			// '--logmetrics' needs to be specified with a named test metric argument +			// Note: for the moment, only ImageCompressionTester has been tested +			std::string test_name; +			if ((arg + 1) < argc) +			{ +				test_name = argv[arg+1]; +			} +			if (((arg + 1) >= argc) || (test_name[0] == '-')) +			{ +				// We don't have an argument left in the arg list or the next argument is another option +				std::cout << "No --logmetrics argument given, no perf data will be gathered" << std::endl; +			} +			else +			{ +				LLFastTimer::sMetricLog = TRUE; +				LLFastTimer::sLogName = test_name; +				arg += 1;					// Skip that arg now we know it's a valid test name +				if ((arg + 1) == argc)		// Break out of the loop if we reach the end of the arg list +					break; +			} +		} +		else if (!strcmp(argv[arg], "--analyzeperformance") || !strcmp(argv[arg], "-r")) +		{ +			analyze_performance = true; +		} +		else if (!strcmp(argv[arg], "--image-stats") || !strcmp(argv[arg], "-s")) +		{ +			image_stats = true; +		} +	} +		 +	// Check arguments consistency. Exit with proper message if inconsistent. +	if (input_filenames.size() == 0) +	{ +		std::cout << "No input file, nothing to do -> exit" << std::endl; +		return 0; +	} +	if (analyze_performance && !LLFastTimer::sMetricLog) +	{ +		std::cout << "Cannot create perf report if no perf gathered (i.e. use argument -log <perf> with -r) -> exit" << std::endl; +		return 0; +	} +	 + +	// Create the logging thread if required +	if (LLFastTimer::sMetricLog) +	{ +		LLFastTimer::sLogLock = new LLMutex(NULL); +		fast_timer_log_thread = new LogThread(LLFastTimer::sLogName); +		fast_timer_log_thread->start(); +	} +	 +	// Perform action on each input file +	std::list<std::string>::iterator in_file  = input_filenames.begin(); +	std::list<std::string>::iterator out_file = output_filenames.begin(); +	std::list<std::string>::iterator in_end = input_filenames.end(); +	std::list<std::string>::iterator out_end = output_filenames.end(); +	for (; in_file != in_end; ++in_file) +	{ +		// Load file +		LLPointer<LLImageRaw> raw_image = load_image(*in_file, image_stats); +		if (!raw_image) +		{ +			std::cout << "Error: Image " << *in_file << " could not be loaded" << std::endl; +			continue; +		} +	 +		// Save file +		if (out_file != out_end) +		{ +			if (!save_image(*out_file, raw_image, image_stats)) +			{ +				std::cout << "Error: Image " << *out_file << " could not be saved" << std::endl; +			} +			else +			{ +				std::cout << *in_file << " -> " << *out_file << std::endl; +			} +			++out_file; +		} +	} + +	// Stop the perf gathering system if needed +	if (LLFastTimer::sMetricLog) +	{ +		LLMetricPerformanceTesterBasic::deleteTester(LLFastTimer::sLogName); +		sAllDone = true; +	} +	 +	// Output perf data if requested by user +	if (analyze_performance) +	{ +		std::cout << "Analyzing performance" << std::endl; +		 +		std::string baseline_name = LLFastTimer::sLogName + "_baseline.slp"; +		std::string current_name  = LLFastTimer::sLogName + ".slp";  +		std::string report_name   = LLFastTimer::sLogName + "_report.csv"; +		 +		LLMetricPerformanceTesterBasic::doAnalysisMetrics(baseline_name, current_name, report_name); +	} +	 +	// Cleanup and exit +	LLImage::cleanupClass(); +	if (fast_timer_log_thread) +	{ +		fast_timer_log_thread->shutdown(); +	} +	 +	return 0; +} diff --git a/indra/integration_tests/llimage_libtest/llimage_libtest.h b/indra/integration_tests/llimage_libtest/llimage_libtest.h new file mode 100644 index 0000000000..63f3d46b50 --- /dev/null +++ b/indra/integration_tests/llimage_libtest/llimage_libtest.h @@ -0,0 +1,29 @@ +/**  + * @file llimage_libtest.h + * + * $LicenseInfo:firstyear=2011&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2011, Linden Research, Inc. + *  + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + *  + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * Lesser General Public License for more details. + *  + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA + *  + * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA + * $/LicenseInfo$ + */ +#ifndef LLIMAGE_LIBTEST_H +#define LLIMAGE_LIBTEST_H + + +#endif diff --git a/indra/llcommon/llmetricperformancetester.cpp b/indra/llcommon/llmetricperformancetester.cpp index 5fa3a5ea07..41d3eb0bf3 100644 --- a/indra/llcommon/llmetricperformancetester.cpp +++ b/indra/llcommon/llmetricperformancetester.cpp @@ -63,7 +63,18 @@ BOOL LLMetricPerformanceTesterBasic::addTester(LLMetricPerformanceTesterBasic* t  	sTesterMap.insert(std::make_pair(name, tester));  	return TRUE;  } -	 + +/*static*/  +void LLMetricPerformanceTesterBasic::deleteTester(std::string name) +{ +	name_tester_map_t::iterator tester = sTesterMap.find(name); +	if (tester != sTesterMap.end()) +	{ +		delete tester->second; +		sTesterMap.erase(tester); +	} +} +  /*static*/   LLMetricPerformanceTesterBasic* LLMetricPerformanceTesterBasic::getTester(std::string name)   { @@ -83,7 +94,78 @@ BOOL LLMetricPerformanceTesterBasic::isMetricLogRequested(std::string name)  	return (LLFastTimer::sMetricLog && ((LLFastTimer::sLogName == name) || (LLFastTimer::sLogName == DEFAULT_METRIC_NAME)));  } +/*static*/  +LLSD LLMetricPerformanceTesterBasic::analyzeMetricPerformanceLog(std::istream& is) +{ +	LLSD ret; +	LLSD cur; +	 +	while (!is.eof() && LLSDSerialize::fromXML(cur, is)) +	{ +		for (LLSD::map_iterator iter = cur.beginMap(); iter != cur.endMap(); ++iter) +		{ +			std::string label = iter->first; +			 +			LLMetricPerformanceTesterBasic* tester = LLMetricPerformanceTesterBasic::getTester(iter->second["Name"].asString()) ; +			if(tester) +			{ +				ret[label]["Name"] = iter->second["Name"] ; +				 +				S32 num_of_metrics = tester->getNumberOfMetrics() ; +				for(S32 index = 0 ; index < num_of_metrics ; index++) +				{ +					ret[label][ tester->getMetricName(index) ] = iter->second[ tester->getMetricName(index) ] ; +				} +			} +		} +	} +	 +	return ret; +} + +/*static*/  +void LLMetricPerformanceTesterBasic::doAnalysisMetrics(std::string baseline, std::string target, std::string output) +{ +	if(!LLMetricPerformanceTesterBasic::hasMetricPerformanceTesters()) +	{ +		return ; +	} +	 +	// Open baseline and current target, exit if one is inexistent +	std::ifstream base_is(baseline.c_str()); +	std::ifstream target_is(target.c_str()); +	if (!base_is.is_open() || !target_is.is_open()) +	{ +		llwarns << "'-analyzeperformance' error : baseline or current target file inexistent" << llendl; +		base_is.close(); +		target_is.close(); +		return; +	} +	//analyze baseline +	LLSD base = analyzeMetricPerformanceLog(base_is); +	base_is.close(); +	 +	//analyze current +	LLSD current = analyzeMetricPerformanceLog(target_is); +	target_is.close(); +	 +	//output comparision +	std::ofstream os(output.c_str()); +	 +	os << "Label, Metric, Base(B), Target(T), Diff(T-B), Percentage(100*T/B)\n";  +	for(LLMetricPerformanceTesterBasic::name_tester_map_t::iterator iter = LLMetricPerformanceTesterBasic::sTesterMap.begin() ;  +		iter != LLMetricPerformanceTesterBasic::sTesterMap.end() ; ++iter) +	{ +		LLMetricPerformanceTesterBasic* tester = ((LLMetricPerformanceTesterBasic*)iter->second) ;	 +		tester->analyzePerformance(&os, &base, ¤t) ; +	} +	 +	os.flush(); +	os.close(); +} + +  //----------------------------------------------------------------------------------------------  // LLMetricPerformanceTesterBasic : Tester instance methods  //---------------------------------------------------------------------------------------------- diff --git a/indra/llcommon/llmetricperformancetester.h b/indra/llcommon/llmetricperformancetester.h index 1372f48dcf..1a18cdf36f 100644 --- a/indra/llcommon/llmetricperformancetester.h +++ b/indra/llcommon/llmetricperformancetester.h @@ -62,6 +62,8 @@ public:  	 */  	virtual void analyzePerformance(std::ofstream* os, LLSD* base, LLSD* current) ; +	static void doAnalysisMetrics(std::string baseline, std::string target, std::string output) ; +  	/**  	 * @return Returns the number of the test metrics in this tester instance.  	 */ @@ -116,6 +118,7 @@ protected:  private:  	void preOutputTestResults(LLSD* sd) ;  	void postOutputTestResults(LLSD* sd) ; +	static LLSD analyzeMetricPerformanceLog(std::istream& is) ;  	std::string mName ;							// Name of this tester instance  	S32 mCount ;								// Current record count @@ -135,6 +138,12 @@ public:  	static LLMetricPerformanceTesterBasic* getTester(std::string name) ;  	/** +	 * @return Delete the named tester from the list  +	 * @param[in] name - Name of the tester instance to delete. +	 */ +	static void deleteTester(std::string name); + +	/**  	 * @return Returns TRUE if that metric *or* the default catch all metric has been requested to be logged  	 * @param[in] name - Name of the tester queried.  	 */ diff --git a/indra/llcommon/llversionviewer.h b/indra/llcommon/llversionviewer.h index d22c879243..488ec5b239 100644 --- a/indra/llcommon/llversionviewer.h +++ b/indra/llcommon/llversionviewer.h @@ -29,7 +29,7 @@  const S32 LL_VERSION_MAJOR = 2;  const S32 LL_VERSION_MINOR = 6; -const S32 LL_VERSION_PATCH = 2; +const S32 LL_VERSION_PATCH = 3;  const S32 LL_VERSION_BUILD = 0;  const char * const LL_CHANNEL = "Second Life Developer"; diff --git a/indra/llimage/llimage.h b/indra/llimage/llimage.h index 825b9aab1a..18444f3934 100644 --- a/indra/llimage/llimage.h +++ b/indra/llimage/llimage.h @@ -266,13 +266,13 @@ public:  	// subclasses must return a prefered file extension (lowercase without a leading dot)  	virtual std::string getExtension() = 0;  	// calcHeaderSize() returns the maximum size of header; -	//   0 indicates we don't know have a header and have to lead the entire file +	//   0 indicates we don't have a header and have to read the entire file  	virtual S32 calcHeaderSize() { return 0; };  	// calcDataSize() returns how many bytes to read to load discard_level (including header)  	virtual S32 calcDataSize(S32 discard_level);  	// calcDiscardLevelBytes() returns the smallest valid discard level based on the number of input bytes  	virtual S32 calcDiscardLevelBytes(S32 bytes); -	// getRawDiscardLevel()by default returns mDiscardLevel, but may be overridden (LLImageJ2C) +	// getRawDiscardLevel() by default returns mDiscardLevel, but may be overridden (LLImageJ2C)  	virtual S8  getRawDiscardLevel() { return mDiscardLevel; }  	BOOL load(const std::string& filename); diff --git a/indra/llimage/llimagej2c.cpp b/indra/llimage/llimagej2c.cpp index cb2a85fa91..80fec7f8a0 100644 --- a/indra/llimage/llimagej2c.cpp +++ b/indra/llimage/llimagej2c.cpp @@ -474,6 +474,7 @@ LLImageCompressionTester::LLImageCompressionTester() : LLMetricPerformanceTester  LLImageCompressionTester::~LLImageCompressionTester()  { +	outputTestResults();  	LLImageJ2C::sTesterp = NULL;  } diff --git a/indra/newview/llchathistory.cpp b/indra/newview/llchathistory.cpp index d4ec377e03..c0c9ea1451 100644 --- a/indra/newview/llchathistory.cpp +++ b/indra/newview/llchathistory.cpp @@ -793,21 +793,7 @@ void LLChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LL  			if ( chat.mSourceType == CHAT_SOURCE_OBJECT && chat.mFromID.notNull())  			{  				// for object IMs, create a secondlife:///app/objectim SLapp -				std::string url = LLSLURL("objectim", chat.mFromID, "").getSLURLString(); -				url += "?name=" + chat.mFromName; -				url += "&owner=" + chat.mOwnerID.asString(); - -				std::string slurl = args["slurl"].asString(); -				if (slurl.empty()) -				{ -				    LLViewerRegion *region = LLWorld::getInstance()->getRegionFromPosAgent(chat.mPosAgent); -				    if(region) -				      { -					LLSLURL region_slurl(region->getName(), chat.mPosAgent); -					slurl = region_slurl.getLocationString(); -				      } -				} -				url += "&slurl=" + LLURI::escape(slurl); +				std::string url = LLViewerChat::getSenderSLURL(chat, args);  				// set the link for the object name to be the objectim SLapp  				// (don't let object names with hyperlinks override our objectim Url) diff --git a/indra/newview/llchatitemscontainerctrl.cpp b/indra/newview/llchatitemscontainerctrl.cpp index 899e0431e7..8584885bc9 100644 --- a/indra/newview/llchatitemscontainerctrl.cpp +++ b/indra/newview/llchatitemscontainerctrl.cpp @@ -213,17 +213,6 @@ void LLNearbyChatToastPanel::init(LLSD& notification)  		{  			LLStyle::Params style_params_name; -			std::string href; - -			if (mSourceType == CHAT_SOURCE_AGENT) -			{ -				href = LLSLURL("agent", mFromID, "about").getSLURLString(); -			} -			else -			{ -				href = LLSLURL("object", mFromID, "inspect").getSLURLString(); -			} -  			LLColor4 user_name_color = LLUIColorTable::instance().getColor("HTMLLinkColor");  			style_params_name.color(user_name_color); @@ -232,7 +221,7 @@ void LLNearbyChatToastPanel::init(LLSD& notification)  			style_params_name.font.name(font_name);  			style_params_name.font.size(font_style_size); -			style_params_name.link_href = href; +			style_params_name.link_href = notification["sender_slurl"].asString();  			style_params_name.is_link = true;  			msg_text->appendText(str_sender, FALSE, style_params_name); diff --git a/indra/newview/llfasttimerview.cpp b/indra/newview/llfasttimerview.cpp index 2bafb9a4a7..6e78ea6bbe 100755 --- a/indra/newview/llfasttimerview.cpp +++ b/indra/newview/llfasttimerview.cpp @@ -1538,36 +1538,6 @@ void LLFastTimerView::doAnalysisDefault(std::string baseline, std::string target  	os.close();  } -//------------------------- -//static -LLSD LLFastTimerView::analyzeMetricPerformanceLog(std::istream& is) -{ -	LLSD ret; -	LLSD cur; - -	while (!is.eof() && LLSDSerialize::fromXML(cur, is)) -	{ -		for (LLSD::map_iterator iter = cur.beginMap(); iter != cur.endMap(); ++iter) -		{ -			std::string label = iter->first; - -			LLMetricPerformanceTesterBasic* tester = LLMetricPerformanceTesterBasic::getTester(iter->second["Name"].asString()) ; -			if(tester) -			{ -				ret[label]["Name"] = iter->second["Name"] ; - -				S32 num_of_metrics = tester->getNumberOfMetrics() ; -				for(S32 index = 0 ; index < num_of_metrics ; index++) -				{ -					ret[label][ tester->getMetricName(index) ] = iter->second[ tester->getMetricName(index) ] ; -				} -			} -		} -	} -		 -	return ret; -} -  //static  void LLFastTimerView::outputAllMetrics()  { @@ -1583,48 +1553,6 @@ void LLFastTimerView::outputAllMetrics()  }  //static -void LLFastTimerView::doAnalysisMetrics(std::string baseline, std::string target, std::string output) -{ -	if(!LLMetricPerformanceTesterBasic::hasMetricPerformanceTesters()) -	{ -		return ; -	} - -	// Open baseline and current target, exit if one is inexistent -	std::ifstream base_is(baseline.c_str()); -	std::ifstream target_is(target.c_str()); -	if (!base_is.is_open() || !target_is.is_open()) -	{ -		llwarns << "'-analyzeperformance' error : baseline or current target file inexistent" << llendl; -		base_is.close(); -		target_is.close(); -		return; -	} - -	//analyze baseline -	LLSD base = analyzeMetricPerformanceLog(base_is); -	base_is.close(); - -	//analyze current -	LLSD current = analyzeMetricPerformanceLog(target_is); -	target_is.close(); - -	//output comparision -	std::ofstream os(output.c_str()); -	 -	os << "Label, Metric, Base(B), Target(T), Diff(T-B), Percentage(100*T/B)\n";  -	for(LLMetricPerformanceTesterBasic::name_tester_map_t::iterator iter = LLMetricPerformanceTesterBasic::sTesterMap.begin() ;  -		iter != LLMetricPerformanceTesterBasic::sTesterMap.end() ; ++iter) -	{ -		LLMetricPerformanceTesterBasic* tester = ((LLMetricPerformanceTesterBasic*)iter->second) ;	 -		tester->analyzePerformance(&os, &base, ¤t) ; -	} -	 -	os.flush(); -	os.close(); -} - -//static  void LLFastTimerView::doAnalysis(std::string baseline, std::string target, std::string output)  {  	if(LLFastTimer::sLog) @@ -1635,7 +1563,7 @@ void LLFastTimerView::doAnalysis(std::string baseline, std::string target, std::  	if(LLFastTimer::sMetricLog)  	{ -		doAnalysisMetrics(baseline, target, output) ; +		LLMetricPerformanceTesterBasic::doAnalysisMetrics(baseline, target, output) ;  		return ;  	}  } diff --git a/indra/newview/llfasttimerview.h b/indra/newview/llfasttimerview.h index c409445d86..ea8251191b 100644 --- a/indra/newview/llfasttimerview.h +++ b/indra/newview/llfasttimerview.h @@ -42,8 +42,6 @@ public:  private:  	static void doAnalysisDefault(std::string baseline, std::string target, std::string output) ; -	static void doAnalysisMetrics(std::string baseline, std::string target, std::string output) ; -	static LLSD analyzeMetricPerformanceLog(std::istream& is) ;  	static LLSD analyzePerformanceLogDefault(std::istream& is) ;  	static void exportCharts(const std::string& base, const std::string& target); diff --git a/indra/newview/llfloatermodelpreview.cpp b/indra/newview/llfloatermodelpreview.cpp index e6ff25bcff..d7a285c666 100755 --- a/indra/newview/llfloatermodelpreview.cpp +++ b/indra/newview/llfloatermodelpreview.cpp @@ -322,8 +322,6 @@ BOOL LLFloaterModelPreview::postBuild()  	childDisable("upload_skin");  	childDisable("upload_joints"); -	childDisable("pelvis_offset"); -  	childDisable("ok_btn");  	mViewOptionMenuButton = getChild<LLMenuButton>("options_gear_btn"); @@ -2493,12 +2491,12 @@ U32 LLModelPreview::calcResourceCost()  	U32 num_hulls = 0;  	F32 debug_scale = mFMP ? mFMP->childGetValue("import_scale").asReal() : 1.f; -	mPelvisZOffset = mFMP ? mFMP->childGetValue("pelvis_offset").asReal() : 8.0f; +	mPelvisZOffset = mFMP ? mFMP->childGetValue("pelvis_offset").asReal() : 3.0f; -	//if ( mFMP && mFMP->childGetValue("upload_joints").asBoolean() )
 -	//{
 -	//	gAgentAvatarp->setPelvisOffset( mPelvisZOffset );
 -	//}
 +	if ( mFMP && mFMP->childGetValue("upload_joints").asBoolean() ) +	{ +		gAgentAvatarp->setPelvisOffset( mPelvisZOffset ); +	}  	F32 streaming_cost = 0.f;  	F32 physics_cost = 0.f; diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp index 60cbdcc98b..a2792bcdc6 100755 --- a/indra/newview/llmeshrepository.cpp +++ b/indra/newview/llmeshrepository.cpp @@ -28,7 +28,7 @@  #include "apr_pools.h"  #include "apr_dso.h" - +#include "llhttpstatuscodes.h"  #include "llmeshrepository.h"  #include "llagent.h" @@ -291,17 +291,21 @@ public:  		}  		else  		{ -			llwarns << status << ": " << reason << llendl; -			llwarns << "Retrying. (" << ++mData.mRetries << ")" << llendl; +			llwarns << status << ": " << reason << llendl;			 -			if (status == 499) +			if (status == HTTP_INTERNAL_ERROR)  			{ +				llwarns << "Retrying. (" << ++mData.mRetries << ")" << llendl;  				mThread->uploadModel(mData);  			} -			else if (status == 400) +			else if (status == HTTP_BAD_REQUEST)  			{  				llwarns << "Status 400 received from server, giving up." << llendl;  			} +			else if (status == HTTP_NOT_FOUND) +			{ +				llwarns <<"Status 404 received, server is disconnected, giving up." << llendl ; +			}  			else  			{  				llerrs << "Unhandled status " << status << llendl; @@ -1381,7 +1385,8 @@ bool LLMeshRepoThread::physicsShapeReceived(const LLUUID& mesh_id, U8* data, S32  LLMeshUploadThread::LLMeshUploadThread(LLMeshUploadThread::instance_list& data, LLVector3& scale, bool upload_textures,  										bool upload_skin, bool upload_joints) -: LLThread("mesh upload") +: LLThread("mesh upload"), +	mDiscarded(FALSE)  {  	mInstanceList = data;  	mUploadTextures = upload_textures; @@ -1475,8 +1480,26 @@ void LLMeshUploadThread::preStart()  	}  } +void LLMeshUploadThread::discard() +{ +	LLMutexLock lock(mMutex) ; +	mDiscarded = TRUE ; +} + +BOOL LLMeshUploadThread::isDiscarded() +{ +	LLMutexLock lock(mMutex) ; +	return mDiscarded ; +} +  void LLMeshUploadThread::run()  { +	if(isDiscarded()) +	{ +		mFinished = true; +		return ; +	} +	  	mCurlRequest = new LLCurlRequest();	  	std::set<LLViewerTexture* > textures; @@ -1605,7 +1628,7 @@ void LLMeshUploadThread::run()  		tcount = llmin(count+PUSH_PER_PROCESS, 100); -		while (!mInstanceQ.empty() && count < tcount) +		while (!mInstanceQ.empty() && count < tcount && !isDiscarded())  		{ //create any objects waiting for upload  			count++;  			object_asset["objects"].append(createObject(mInstanceQ.front())); @@ -1614,7 +1637,7 @@ void LLMeshUploadThread::run()  		mCurlRequest->process(); -		done = mInstanceQ.empty() && mConfirmedQ.empty() && mUploadQ.empty(); +		done = isDiscarded() || (mInstanceQ.empty() && mConfirmedQ.empty() && mUploadQ.empty());  	}  	while (!done || mCurlRequest->getQueued() > 0); @@ -1629,7 +1652,10 @@ void LLMeshUploadThread::run()  		object_asset["permissions"] = object_asset["objects"][0]["permissions"];  	} -	LLHTTPClient::post(url, object_asset, new LLHTTPClient::Responder()); +	if(!isDiscarded()) +	{ +		LLHTTPClient::post(url, object_asset, new LLHTTPClient::Responder()); +	}  	mFinished = true;  } @@ -2132,6 +2158,12 @@ void LLMeshRepository::shutdown()  {  	llinfos << "Shutting down mesh repository." << llendl; +	for (U32 i = 0; i < mUploads.size(); ++i) +	{ +		llinfos << "Discard the pending mesh uploads " << llendl; +		mUploads[i]->discard() ; //discard the uploading requests. +	} +  	mThread->mSignal->signal();  	while (!mThread->isStopped()) @@ -2750,6 +2782,11 @@ S32 LLMeshRepository::getMeshSize(const LLUUID& mesh_id, S32 lod)  void LLMeshUploadThread::sendCostRequest(LLMeshUploadData& data)  { +	if(isDiscarded()) +	{ +		return ; +	} +  	//write model file to memory buffer  	std::stringstream ostr; @@ -2808,6 +2845,11 @@ void LLMeshUploadThread::sendCostRequest(LLMeshUploadData& data)  void LLMeshUploadThread::sendCostRequest(LLTextureUploadData& data)  { +	if(isDiscarded()) +	{ +		return ; +	} +  	if (data.mTexture && data.mTexture->getDiscardLevel() >= 0)  	{  		LLSD asset_resources = LLSD::emptyMap(); @@ -2840,6 +2882,11 @@ void LLMeshUploadThread::sendCostRequest(LLTextureUploadData& data)  void LLMeshUploadThread::doUploadModel(LLMeshUploadData& data)  { +	if(isDiscarded()) +	{ +		return ; +	} +  	if (!data.mRSVP.empty())  	{  		std::stringstream ostr; @@ -2872,6 +2919,11 @@ void LLMeshUploadThread::doUploadModel(LLMeshUploadData& data)  void LLMeshUploadThread::doUploadTexture(LLTextureUploadData& data)  { +	if(isDiscarded()) +	{ +		return ; +	} +  	if (!data.mRSVP.empty())  	{  		std::stringstream ostr; diff --git a/indra/newview/llmeshrepository.h b/indra/newview/llmeshrepository.h index f0c0f308d5..4e349a1270 100644 --- a/indra/newview/llmeshrepository.h +++ b/indra/newview/llmeshrepository.h @@ -405,11 +405,12 @@ public:  	S32				mPendingConfirmations;  	S32				mPendingUploads;  	S32				mPendingCost; -	bool			mFinished;  	LLVector3		mOrigin; +	bool			mFinished;	  	bool			mUploadTextures;  	bool			mUploadSkin;  	bool			mUploadJoints; +	BOOL            mDiscarded ;  	LLHost			mHost;  	std::string		mUploadObjectAssetCapability; @@ -445,7 +446,8 @@ public:  	bool finished() { return mFinished; }  	virtual void run();  	void preStart(); -	 +	void discard() ; +	BOOL isDiscarded();  };  class LLMeshRepository diff --git a/indra/newview/llnearbychathandler.cpp b/indra/newview/llnearbychathandler.cpp index de5439e4e0..0d9daeb44e 100644 --- a/indra/newview/llnearbychathandler.cpp +++ b/indra/newview/llnearbychathandler.cpp @@ -558,6 +558,7 @@ void LLNearbyChatHandler::processChat(const LLChat& chat_msg, const LLSD &args)  	}  	*/ +	// Add a nearby chat toast.  	LLUUID id;  	id.generate(); @@ -583,6 +584,10 @@ void LLNearbyChatHandler::processChat(const LLChat& chat_msg, const LLSD &args)  		notification["text_color"] = r_color_name;  		notification["color_alpha"] = r_color_alpha;  		notification["font_size"] = (S32)LLViewerChat::getChatFontSize() ; + +		// Pass sender info so that it can be rendered properly (STORM-1021). +		notification["sender_slurl"] = LLViewerChat::getSenderSLURL(chat_msg, args); +  		channel->addNotification(notification);	  	} diff --git a/indra/newview/llviewerchat.cpp b/indra/newview/llviewerchat.cpp index 0af850a46b..286b16bab2 100644 --- a/indra/newview/llviewerchat.cpp +++ b/indra/newview/llviewerchat.cpp @@ -31,6 +31,8 @@  #include "llagent.h" 	// gAgent		  #include "lluicolortable.h"  #include "llviewercontrol.h" // gSavedSettings +#include "llviewerregion.h" +#include "llworld.h"  #include "llinstantmessage.h" //SYSTEM_FROM  // LLViewerChat @@ -214,3 +216,43 @@ void LLViewerChat::formatChatMsg(const LLChat& chat, std::string& formated_msg)  } +//static +std::string LLViewerChat::getSenderSLURL(const LLChat& chat, const LLSD& args) +{ +	switch (chat.mSourceType) +	{ +	case CHAT_SOURCE_AGENT: +		return LLSLURL("agent", chat.mFromID, "about").getSLURLString(); + +	case CHAT_SOURCE_OBJECT: +		return getObjectImSLURL(chat, args); + +	default: +		llwarns << "Getting SLURL for an unsupported sender type: " << chat.mSourceType << llendl; +	} + +	return LLStringUtil::null; +} + +//static +std::string LLViewerChat::getObjectImSLURL(const LLChat& chat, const LLSD& args) +{ +	std::string url = LLSLURL("objectim", chat.mFromID, "").getSLURLString(); +	url += "?name=" + chat.mFromName; +	url += "&owner=" + chat.mOwnerID.asString(); + +	std::string slurl = args["slurl"].asString(); +	if (slurl.empty()) +	{ +		LLViewerRegion *region = LLWorld::getInstance()->getRegionFromPosAgent(chat.mPosAgent); +		if(region) +		{ +			LLSLURL region_slurl(region->getName(), chat.mPosAgent); +			slurl = region_slurl.getLocationString(); +		} +	} + +	url += "&slurl=" + LLURI::escape(slurl); + +	return url; +} diff --git a/indra/newview/llviewerchat.h b/indra/newview/llviewerchat.h index a9f9a98960..0f15d29f04 100644 --- a/indra/newview/llviewerchat.h +++ b/indra/newview/llviewerchat.h @@ -40,6 +40,10 @@ public:  	static LLFontGL* getChatFont();  	static S32 getChatFontSize();  	static void formatChatMsg(const LLChat& chat, std::string& formated_msg); +	static std::string getSenderSLURL(const LLChat& chat, const LLSD& args); + +private: +	static std::string getObjectImSLURL(const LLChat& chat, const LLSD& args);  }; diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index 43d8b9d356..98e5e4c6de 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -3941,7 +3941,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)  						if ( bindCnt > 0 )
  						{					
  							const int jointCnt = pSkinData->mJointNames.size();
 -							const int pelvisZOffset = pSkinData->mPelvisOffset;
 +							const F32 pelvisZOffset = pSkinData->mPelvisOffset;
  							bool fullRig = (jointCnt>=20) ? true : false;
  							if ( fullRig )
  							{
 diff --git a/indra/newview/skins/default/xui/en/floater_model_preview.xml b/indra/newview/skins/default/xui/en/floater_model_preview.xml index 5a726d1821..0053be4f67 100644 --- a/indra/newview/skins/default/xui/en/floater_model_preview.xml +++ b/indra/newview/skins/default/xui/en/floater_model_preview.xml @@ -390,10 +390,10 @@        <check_box top_pad="5" left="20" name="upload_joints" height="15" follows="top|left" label="Joint positions"/>        <text left="10" top_pad="4" width="90" bottom="30" follows="top|left" height="15"> -        Pelvis Offset: +        Pelvis Z Offset:        </text> -      <spinner left="10" top_pad="4" height="20" follows="top|left" width="80" value="0.0" min_val="0.00" max_val="8.0" name="pelvis_offset"/> +      <spinner left="10" top_pad="4" height="20" follows="top|left" width="80" value="0.0" min_val="-3.00" max_val="3.0" name="pelvis_offset"/>      </panel>    </tab_container> diff --git a/indra/newview/skins/default/xui/en/menu_attachment_self.xml b/indra/newview/skins/default/xui/en/menu_attachment_self.xml index 84e81397be..b8128da358 100644 --- a/indra/newview/skins/default/xui/en/menu_attachment_self.xml +++ b/indra/newview/skins/default/xui/en/menu_attachment_self.xml @@ -68,7 +68,7 @@ name="Stand Up">       function="Self.EnableStandUp" />    </menu_item_call>    <menu_item_call -  label="Change Outfit" +  label="My Appearance"    name="Change Outfit">      <menu_item_call.on_click       function="CustomizeAvatar" /> diff --git a/indra/newview/skins/default/xui/en/menu_avatar_self.xml b/indra/newview/skins/default/xui/en/menu_avatar_self.xml index 2afa29ec10..d727294cc8 100644 --- a/indra/newview/skins/default/xui/en/menu_avatar_self.xml +++ b/indra/newview/skins/default/xui/en/menu_avatar_self.xml @@ -193,7 +193,7 @@          </menu_item_call>      </context_menu>       <menu_item_call -     label="Change Outfit" +     label="My Appearance"       layout="topleft"       name="Chenge Outfit">          <menu_item_call.on_click diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml index ea40a08c95..8c783ae218 100644 --- a/indra/newview/skins/default/xui/en/menu_viewer.xml +++ b/indra/newview/skins/default/xui/en/menu_viewer.xml @@ -41,7 +41,7 @@               parameter="agent" />          </menu_item_call>          <menu_item_call -         label="Change Outfit" +         label="My Appearance"           name="ChangeOutfit">              <menu_item_call.on_click               function="CustomizeAvatar" /> diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml index f703acaa66..d9d3fab6d4 100644 --- a/indra/newview/skins/default/xui/en/notifications.xml +++ b/indra/newview/skins/default/xui/en/notifications.xml @@ -821,22 +821,6 @@ You need to enter either the Username or both the First and Last name of your av    <notification     icon="alertmodal.tga" -   name="AddClassified" -   type="alertmodal"> -Classified ads appear in the 'Classified' section of the Search directory and on [http://secondlife.com/community/classifieds secondlife.com] for one week. -Fill out your ad, then click 'Publish...' to add it to the directory. -You'll be asked for a price to pay when clicking Publish. -Paying more makes your ad appear higher in the list, and also appear higher when people search for keywords. -    <tag>confirm</tag> -    <usetemplate -     ignoretext="How to create a new Classified ad" -     name="okcancelignore" -     notext="Cancel" -     yestext="OK"/> -  </notification> - -  <notification -   icon="alertmodal.tga"     name="DeleteClassified"     type="alertmodal">  Delete classified '[NAME]'? | 
