Skip to content
Snippets Groups Projects
Commit 94aa24a8 authored by Oz Linden's avatar Oz Linden
Browse files

merge changes for social-859

parents 1a2cc89c e952f77a
Branches
Tags
No related merge requests found
Showing
with 769 additions and 126 deletions
...@@ -86,3 +86,8 @@ f1827b441e05bf37c68e2c15ebc6d09e9b03f527 2.6.0-start ...@@ -86,3 +86,8 @@ f1827b441e05bf37c68e2c15ebc6d09e9b03f527 2.6.0-start
c5bdef3aaa2744626aef3c217ce29e1900d357b3 2.6.1-start c5bdef3aaa2744626aef3c217ce29e1900d357b3 2.6.1-start
c5bdef3aaa2744626aef3c217ce29e1900d357b3 DRTVWR-43_2.6.1-beta1 c5bdef3aaa2744626aef3c217ce29e1900d357b3 DRTVWR-43_2.6.1-beta1
c5bdef3aaa2744626aef3c217ce29e1900d357b3 2.6.1-beta1 c5bdef3aaa2744626aef3c217ce29e1900d357b3 2.6.1-beta1
9e4641f4a7870c0f565a25a2971368d5a29516a1 DRTVWR-41_2.6.0-beta2
9e4641f4a7870c0f565a25a2971368d5a29516a1 2.6.0-beta2
56b2778c743c2a964d82e1caf11084d76a87de2c 2.6.2-start
d1203046bb653b763f835b04d184646949d8dd5c DRTVWR-45_2.6.2-beta1
d1203046bb653b763f835b04d184646949d8dd5c 2.6.2-beta1
...@@ -155,7 +155,8 @@ media.build_viewer_update_version_manager = false ...@@ -155,7 +155,8 @@ media.build_viewer_update_version_manager = false
# oz # oz
# ================ # ================
oz_viewer-devreview.build_debug_release_separately = true oz-viewer-devreview.build_debug_release_separately = true
oz_viewer-poreview.build_debug_release_separately = true
oz-project-1.build_debug_release_separately = true oz-project-1.build_debug_release_separately = true
oz-project-2.build_debug_release_separately = true oz-project-2.build_debug_release_separately = true
oz-project-3.build_debug_release_separately = true oz-project-3.build_debug_release_separately = true
......
# -*- cmake -*- # -*- cmake -*-
add_subdirectory(llui_libtest) add_subdirectory(llui_libtest)
add_subdirectory(llimage_libtest)
# -*- 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)
/**
* @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;
}
/**
* @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
...@@ -64,6 +64,17 @@ BOOL LLMetricPerformanceTesterBasic::addTester(LLMetricPerformanceTesterBasic* t ...@@ -64,6 +64,17 @@ BOOL LLMetricPerformanceTesterBasic::addTester(LLMetricPerformanceTesterBasic* t
return TRUE; 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*/ /*static*/
LLMetricPerformanceTesterBasic* LLMetricPerformanceTesterBasic::getTester(std::string name) LLMetricPerformanceTesterBasic* LLMetricPerformanceTesterBasic::getTester(std::string name)
{ {
...@@ -83,6 +94,77 @@ BOOL LLMetricPerformanceTesterBasic::isMetricLogRequested(std::string name) ...@@ -83,6 +94,77 @@ BOOL LLMetricPerformanceTesterBasic::isMetricLogRequested(std::string name)
return (LLFastTimer::sMetricLog && ((LLFastTimer::sLogName == name) || (LLFastTimer::sLogName == DEFAULT_METRIC_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, &current) ;
}
os.flush();
os.close();
}
//---------------------------------------------------------------------------------------------- //----------------------------------------------------------------------------------------------
// LLMetricPerformanceTesterBasic : Tester instance methods // LLMetricPerformanceTesterBasic : Tester instance methods
......
...@@ -62,6 +62,8 @@ class LL_COMMON_API LLMetricPerformanceTesterBasic ...@@ -62,6 +62,8 @@ class LL_COMMON_API LLMetricPerformanceTesterBasic
*/ */
virtual void analyzePerformance(std::ofstream* os, LLSD* base, LLSD* current) ; 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. * @return Returns the number of the test metrics in this tester instance.
*/ */
...@@ -116,6 +118,7 @@ class LL_COMMON_API LLMetricPerformanceTesterBasic ...@@ -116,6 +118,7 @@ class LL_COMMON_API LLMetricPerformanceTesterBasic
private: private:
void preOutputTestResults(LLSD* sd) ; void preOutputTestResults(LLSD* sd) ;
void postOutputTestResults(LLSD* sd) ; void postOutputTestResults(LLSD* sd) ;
static LLSD analyzeMetricPerformanceLog(std::istream& is) ;
std::string mName ; // Name of this tester instance std::string mName ; // Name of this tester instance
S32 mCount ; // Current record count S32 mCount ; // Current record count
...@@ -134,6 +137,12 @@ class LL_COMMON_API LLMetricPerformanceTesterBasic ...@@ -134,6 +137,12 @@ class LL_COMMON_API LLMetricPerformanceTesterBasic
*/ */
static LLMetricPerformanceTesterBasic* getTester(std::string name) ; 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 * @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. * @param[in] name - Name of the tester queried.
......
...@@ -29,7 +29,7 @@ ...@@ -29,7 +29,7 @@
const S32 LL_VERSION_MAJOR = 2; const S32 LL_VERSION_MAJOR = 2;
const S32 LL_VERSION_MINOR = 6; const S32 LL_VERSION_MINOR = 6;
const S32 LL_VERSION_PATCH = 1; const S32 LL_VERSION_PATCH = 2;
const S32 LL_VERSION_BUILD = 0; const S32 LL_VERSION_BUILD = 0;
const char * const LL_CHANNEL = "Second Life Developer"; const char * const LL_CHANNEL = "Second Life Developer";
......
...@@ -266,7 +266,7 @@ class LLImageFormatted : public LLImageBase ...@@ -266,7 +266,7 @@ class LLImageFormatted : public LLImageBase
// subclasses must return a prefered file extension (lowercase without a leading dot) // subclasses must return a prefered file extension (lowercase without a leading dot)
virtual std::string getExtension() = 0; virtual std::string getExtension() = 0;
// calcHeaderSize() returns the maximum size of header; // 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; }; virtual S32 calcHeaderSize() { return 0; };
// calcDataSize() returns how many bytes to read to load discard_level (including header) // calcDataSize() returns how many bytes to read to load discard_level (including header)
virtual S32 calcDataSize(S32 discard_level); virtual S32 calcDataSize(S32 discard_level);
......
...@@ -474,6 +474,7 @@ LLImageCompressionTester::LLImageCompressionTester() : LLMetricPerformanceTester ...@@ -474,6 +474,7 @@ LLImageCompressionTester::LLImageCompressionTester() : LLMetricPerformanceTester
LLImageCompressionTester::~LLImageCompressionTester() LLImageCompressionTester::~LLImageCompressionTester()
{ {
outputTestResults();
LLImageJ2C::sTesterp = NULL; LLImageJ2C::sTesterp = NULL;
} }
......
...@@ -793,21 +793,7 @@ void LLChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LL ...@@ -793,21 +793,7 @@ void LLChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LL
if ( chat.mSourceType == CHAT_SOURCE_OBJECT && chat.mFromID.notNull()) if ( chat.mSourceType == CHAT_SOURCE_OBJECT && chat.mFromID.notNull())
{ {
// for object IMs, create a secondlife:///app/objectim SLapp // for object IMs, create a secondlife:///app/objectim SLapp
std::string url = LLSLURL("objectim", chat.mFromID, "").getSLURLString(); std::string url = LLViewerChat::getSenderSLURL(chat, args);
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);
// set the link for the object name to be the objectim SLapp // set the link for the object name to be the objectim SLapp
// (don't let object names with hyperlinks override our objectim Url) // (don't let object names with hyperlinks override our objectim Url)
......
...@@ -213,17 +213,6 @@ void LLNearbyChatToastPanel::init(LLSD& notification) ...@@ -213,17 +213,6 @@ void LLNearbyChatToastPanel::init(LLSD& notification)
{ {
LLStyle::Params style_params_name; 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"); LLColor4 user_name_color = LLUIColorTable::instance().getColor("HTMLLinkColor");
style_params_name.color(user_name_color); style_params_name.color(user_name_color);
...@@ -232,7 +221,7 @@ void LLNearbyChatToastPanel::init(LLSD& notification) ...@@ -232,7 +221,7 @@ void LLNearbyChatToastPanel::init(LLSD& notification)
style_params_name.font.name(font_name); style_params_name.font.name(font_name);
style_params_name.font.size(font_style_size); 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; style_params_name.is_link = true;
msg_text->appendText(str_sender, FALSE, style_params_name); msg_text->appendText(str_sender, FALSE, style_params_name);
......
...@@ -27,6 +27,7 @@ ...@@ -27,6 +27,7 @@
#include "llviewerprecompiledheaders.h" #include "llviewerprecompiledheaders.h"
#include "llexternaleditor.h" #include "llexternaleditor.h"
#include "lltrans.h"
#include "llui.h" #include "llui.h"
// static // static
...@@ -35,13 +36,13 @@ const std::string LLExternalEditor::sFilenameMarker = "%s"; ...@@ -35,13 +36,13 @@ const std::string LLExternalEditor::sFilenameMarker = "%s";
// static // static
const std::string LLExternalEditor::sSetting = "ExternalEditor"; const std::string LLExternalEditor::sSetting = "ExternalEditor";
bool LLExternalEditor::setCommand(const std::string& env_var, const std::string& override) LLExternalEditor::EErrorCode LLExternalEditor::setCommand(const std::string& env_var, const std::string& override)
{ {
std::string cmd = findCommand(env_var, override); std::string cmd = findCommand(env_var, override);
if (cmd.empty()) if (cmd.empty())
{ {
llwarns << "Empty editor command" << llendl; llwarns << "Editor command is empty or not set" << llendl;
return false; return EC_NOT_SPECIFIED;
} }
// Add the filename marker if missing. // Add the filename marker if missing.
...@@ -55,7 +56,7 @@ bool LLExternalEditor::setCommand(const std::string& env_var, const std::string& ...@@ -55,7 +56,7 @@ bool LLExternalEditor::setCommand(const std::string& env_var, const std::string&
if (tokenize(tokens, cmd) < 2) // 2 = bin + at least one arg (%s) if (tokenize(tokens, cmd) < 2) // 2 = bin + at least one arg (%s)
{ {
llwarns << "Error parsing editor command" << llendl; llwarns << "Error parsing editor command" << llendl;
return false; return EC_PARSE_ERROR;
} }
// Check executable for existence. // Check executable for existence.
...@@ -63,7 +64,7 @@ bool LLExternalEditor::setCommand(const std::string& env_var, const std::string& ...@@ -63,7 +64,7 @@ bool LLExternalEditor::setCommand(const std::string& env_var, const std::string&
if (!LLFile::isfile(bin_path)) if (!LLFile::isfile(bin_path))
{ {
llwarns << "Editor binary [" << bin_path << "] not found" << llendl; llwarns << "Editor binary [" << bin_path << "] not found" << llendl;
return false; return EC_BINARY_NOT_FOUND;
} }
// Save command. // Save command.
...@@ -76,16 +77,16 @@ bool LLExternalEditor::setCommand(const std::string& env_var, const std::string& ...@@ -76,16 +77,16 @@ bool LLExternalEditor::setCommand(const std::string& env_var, const std::string&
} }
llinfos << "Setting command [" << bin_path << " " << mArgs << "]" << llendl; llinfos << "Setting command [" << bin_path << " " << mArgs << "]" << llendl;
return true; return EC_SUCCESS;
} }
bool LLExternalEditor::run(const std::string& file_path) LLExternalEditor::EErrorCode LLExternalEditor::run(const std::string& file_path)
{ {
std::string args = mArgs; std::string args = mArgs;
if (mProcess.getExecutable().empty() || args.empty()) if (mProcess.getExecutable().empty() || args.empty())
{ {
llwarns << "Editor command not set" << llendl; llwarns << "Editor command not set" << llendl;
return false; return EC_NOT_SPECIFIED;
} }
// Substitute the filename marker in the command with the actual passed file name. // Substitute the filename marker in the command with the actual passed file name.
...@@ -111,7 +112,22 @@ bool LLExternalEditor::run(const std::string& file_path) ...@@ -111,7 +112,22 @@ bool LLExternalEditor::run(const std::string& file_path)
mProcess.orphan(); mProcess.orphan();
} }
return result == 0; return result == 0 ? EC_SUCCESS : EC_FAILED_TO_RUN;
}
// static
std::string LLExternalEditor::getErrorMessage(EErrorCode code)
{
switch (code)
{
case EC_SUCCESS: return LLTrans::getString("ok");
case EC_NOT_SPECIFIED: return LLTrans::getString("ExternalEditorNotSet");
case EC_PARSE_ERROR: return LLTrans::getString("ExternalEditorCommandParseError");
case EC_BINARY_NOT_FOUND: return LLTrans::getString("ExternalEditorNotFound");
case EC_FAILED_TO_RUN: return LLTrans::getString("ExternalEditorFailedToRun");
}
return LLTrans::getString("Unknown");
} }
// static // static
......
...@@ -42,6 +42,14 @@ class LLExternalEditor ...@@ -42,6 +42,14 @@ class LLExternalEditor
public: public:
typedef enum e_error_code {
EC_SUCCESS, /// No error.
EC_NOT_SPECIFIED, /// Editor path not specified.
EC_PARSE_ERROR, /// Editor command parsing error.
EC_BINARY_NOT_FOUND, /// Could find the editor binary (missing or not quoted).
EC_FAILED_TO_RUN, /// Could not execute the editor binary.
} EErrorCode;
/** /**
* Set editor command. * Set editor command.
* *
...@@ -51,19 +59,25 @@ class LLExternalEditor ...@@ -51,19 +59,25 @@ class LLExternalEditor
* First tries the override, then a predefined setting (sSetting), * First tries the override, then a predefined setting (sSetting),
* then the environment variable. * then the environment variable.
* *
* @return Command if found, empty string otherwise. * @return EC_SUCCESS if command is valid and refers to an existing executable,
* EC_NOT_SPECIFIED or EC_FAILED_TO_RUNan on error.
* *
* @see sSetting * @see sSetting
*/ */
bool setCommand(const std::string& env_var, const std::string& override = LLStringUtil::null); EErrorCode setCommand(const std::string& env_var, const std::string& override = LLStringUtil::null);
/** /**
* Run the editor with the given file. * Run the editor with the given file.
* *
* @param file_path File to edit. * @param file_path File to edit.
* @return true on success, false on error. * @return EC_SUCCESS on success, error code on error.
*/
EErrorCode run(const std::string& file_path);
/**
* Get a meaningful error message for the given status code.
*/ */
bool run(const std::string& file_path); static std::string getErrorMessage(EErrorCode code);
private: private:
......
...@@ -1149,36 +1149,6 @@ void LLFastTimerView::doAnalysisDefault(std::string baseline, std::string target ...@@ -1149,36 +1149,6 @@ void LLFastTimerView::doAnalysisDefault(std::string baseline, std::string target
os.close(); 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 //static
void LLFastTimerView::outputAllMetrics() void LLFastTimerView::outputAllMetrics()
{ {
...@@ -1193,48 +1163,6 @@ void LLFastTimerView::outputAllMetrics() ...@@ -1193,48 +1163,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, &current) ;
}
os.flush();
os.close();
}
//static //static
void LLFastTimerView::doAnalysis(std::string baseline, std::string target, std::string output) void LLFastTimerView::doAnalysis(std::string baseline, std::string target, std::string output)
{ {
...@@ -1246,7 +1174,7 @@ void LLFastTimerView::doAnalysis(std::string baseline, std::string target, std:: ...@@ -1246,7 +1174,7 @@ void LLFastTimerView::doAnalysis(std::string baseline, std::string target, std::
if(LLFastTimer::sMetricLog) if(LLFastTimer::sMetricLog)
{ {
doAnalysisMetrics(baseline, target, output) ; LLMetricPerformanceTesterBasic::doAnalysisMetrics(baseline, target, output) ;
return ; return ;
} }
} }
......
...@@ -42,8 +42,6 @@ class LLFastTimerView : public LLFloater ...@@ -42,8 +42,6 @@ class LLFastTimerView : public LLFloater
private: private:
static void doAnalysisDefault(std::string baseline, std::string target, std::string output) ; 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 LLSD analyzePerformanceLogDefault(std::istream& is) ;
public: public:
......
...@@ -185,7 +185,7 @@ void LLFloaterTopObjects::handleReply(LLMessageSystem *msg, void** data) ...@@ -185,7 +185,7 @@ void LLFloaterTopObjects::handleReply(LLMessageSystem *msg, void** data)
have_extended_data = true; have_extended_data = true;
msg->getU32("DataExtended", "TimeStamp", time_stamp, block); msg->getU32("DataExtended", "TimeStamp", time_stamp, block);
msg->getF32("DataExtended", "MonoScore", mono_score, block); msg->getF32("DataExtended", "MonoScore", mono_score, block);
msg->getS32(_PREHASH_ReportData,"PublicURLs",public_urls,block); msg->getS32("DataExtended", "PublicURLs", public_urls, block);
} }
LLSD element; LLSD element;
......
...@@ -1037,18 +1037,29 @@ void LLFloaterUIPreview::onClickEditFloater() ...@@ -1037,18 +1037,29 @@ void LLFloaterUIPreview::onClickEditFloater()
cmd_override = bin + " " + args; cmd_override = bin + " " + args;
} }
} }
if (!mExternalEditor.setCommand("LL_XUI_EDITOR", cmd_override))
LLExternalEditor::EErrorCode status = mExternalEditor.setCommand("LL_XUI_EDITOR", cmd_override);
if (status != LLExternalEditor::EC_SUCCESS)
{
std::string warning;
if (status == LLExternalEditor::EC_NOT_SPECIFIED) // Use custom message for this error.
{
warning = getString("ExternalEditorNotSet");
}
else
{ {
std::string warning = "Select an editor by setting the environment variable LL_XUI_EDITOR " warning = LLExternalEditor::getErrorMessage(status);
"or the ExternalEditor setting or specifying its path in the \"Editor Path\" field."; }
popupAndPrintWarning(warning); popupAndPrintWarning(warning);
return; return;
} }
// Run the editor. // Run the editor.
if (!mExternalEditor.run(file_path)) if (mExternalEditor.run(file_path) != LLExternalEditor::EC_SUCCESS)
{ {
popupAndPrintWarning("Failed to run editor"); popupAndPrintWarning(LLExternalEditor::getErrorMessage(status));
return; return;
} }
} }
......
...@@ -558,6 +558,7 @@ void LLNearbyChatHandler::processChat(const LLChat& chat_msg, const LLSD &args) ...@@ -558,6 +558,7 @@ void LLNearbyChatHandler::processChat(const LLChat& chat_msg, const LLSD &args)
} }
*/ */
// Add a nearby chat toast.
LLUUID id; LLUUID id;
id.generate(); id.generate();
...@@ -583,6 +584,10 @@ void LLNearbyChatHandler::processChat(const LLChat& chat_msg, const LLSD &args) ...@@ -583,6 +584,10 @@ void LLNearbyChatHandler::processChat(const LLChat& chat_msg, const LLSD &args)
notification["text_color"] = r_color_name; notification["text_color"] = r_color_name;
notification["color_alpha"] = r_color_alpha; notification["color_alpha"] = r_color_alpha;
notification["font_size"] = (S32)LLViewerChat::getChatFontSize() ; 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); channel->addNotification(notification);
} }
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment