merge up from viewer-autobuild2010 through the start of 2.6.3

meow-7.2.2
Oz Linden 2011-03-28 09:06:51 -04:00
commit 77cd2e283a
12 changed files with 696 additions and 79 deletions

View File

@ -84,3 +84,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

View File

@ -1,3 +1,4 @@
# -*- cmake -*-
add_subdirectory(llui_libtest)
add_subdirectory(llimage_libtest)

View File

@ -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)

View File

@ -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;
}

View File

@ -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

View File

@ -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, &current) ;
}
os.flush();
os.close();
}
//----------------------------------------------------------------------------------------------
// LLMetricPerformanceTesterBasic : Tester instance methods
//----------------------------------------------------------------------------------------------

View File

@ -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
@ -134,6 +137,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.

View File

@ -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";

View File

@ -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);

View File

@ -474,6 +474,7 @@ LLImageCompressionTester::LLImageCompressionTester() : LLMetricPerformanceTester
LLImageCompressionTester::~LLImageCompressionTester()
{
outputTestResults();
LLImageJ2C::sTesterp = NULL;
}

View File

@ -1149,36 +1149,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()
{
@ -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
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::
if(LLFastTimer::sMetricLog)
{
doAnalysisMetrics(baseline, target, output) ;
LLMetricPerformanceTesterBasic::doAnalysisMetrics(baseline, target, output) ;
return ;
}
}

View File

@ -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) ;
public: