diff options
Diffstat (limited to 'indra')
57 files changed, 2265 insertions, 1853 deletions
| diff --git a/indra/cmake/Copy3rdPartyLibs.cmake b/indra/cmake/Copy3rdPartyLibs.cmake index 4698116022..1c43c4ce12 100644 --- a/indra/cmake/Copy3rdPartyLibs.cmake +++ b/indra/cmake/Copy3rdPartyLibs.cmake @@ -243,7 +243,7 @@ elseif(LINUX)          libaprutil-1.so.0          libatk-1.0.so          libbreakpad_client.so.0 -        libcrypto.so.0.9.8 +        libcrypto.so.1.0.0          libdb-5.1.so          libexpat.so          libexpat.so.1 @@ -259,7 +259,7 @@ elseif(LINUX)          libtcmalloc.so          libuuid.so.16          libuuid.so.16.0.22 -        libssl.so.0.9.8 +        libssl.so.1.0.0          libfontconfig.so.1.4.4         ) diff --git a/indra/cmake/Variables.cmake b/indra/cmake/Variables.cmake index 77dd34d122..03428691cf 100644 --- a/indra/cmake/Variables.cmake +++ b/indra/cmake/Variables.cmake @@ -102,7 +102,7 @@ if (${CMAKE_SYSTEM_NAME} MATCHES "Darwin")    set(CMAKE_OSX_DEPLOYMENT_TARGET 10.5)    set(CMAKE_OSX_SYSROOT /Developer/SDKs/MacOSX10.5.sdk)    set(CMAKE_XCODE_ATTRIBUTE_GCC_VERSION "4.2") -  set(CMAKE_XCODE_ATTRIBUTE_DEBUG_INFORMATION_FORMAT "DWARF with dSYM File") +  set(CMAKE_XCODE_ATTRIBUTE_DEBUG_INFORMATION_FORMAT dwarf-with-dsym)    # NOTE: To attempt an i386/PPC Universal build, add this on the configure line:    # -DCMAKE_OSX_ARCHITECTURES:STRING='i386;ppc' @@ -135,6 +135,7 @@ set(VIEWER_LOGIN_CHANNEL ${VIEWER_CHANNEL} CACHE STRING "Fake login channel for  set(VERSION_BUILD "0" CACHE STRING "Revision number passed in from the outside")  set(STANDALONE OFF CACHE BOOL "Do not use Linden-supplied prebuilt libraries.") +set(UNATTENDED OFF CACHE BOOL "Should be set to ON for building with VC Express editions.")  if (NOT STANDALONE AND EXISTS ${CMAKE_SOURCE_DIR}/llphysics)      set(SERVER ON CACHE BOOL "Build Second Life server software.") diff --git a/indra/integration_tests/llimage_libtest/llimage_libtest.cpp b/indra/integration_tests/llimage_libtest/llimage_libtest.cpp index 365f5f758c..60ddf63b21 100644 --- a/indra/integration_tests/llimage_libtest/llimage_libtest.cpp +++ b/indra/integration_tests/llimage_libtest/llimage_libtest.cpp @@ -53,12 +53,32 @@ static const char USAGE[] = "\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" +" -r, --region <x0, y0, x1, y1>\n" +"        Crop region applied to the input files in pixels.\n" +"        Only used for j2c images. Default is no region cropping.\n" +" -d, --discard_level <n>\n" +"        Discard level max used on input. 0 is highest resolution. Max discard level is 5.\n" +"        This allows the input image to be clamped in resolution when loading.\n" +"        Only valid for j2c images. Default is no discard.\n" +" -p, --precincts <n>\n" +"        Dimension of precincts in pixels. Precincts are assumed square and identical for\n" +"        all levels. Note that this option also add PLT and tile markers to the codestream, \n" +"        and uses RPCL order. Power of 2 must be used.\n" +"        Only valid for output j2c images. Default is no precincts used.\n" +" -b, --blocks <n>\n" +"        Dimension of coding blocks in pixels. Blocks are assumed square. Power of 2 must\n" +"        be used. Blocks must be smaller than precincts. Like precincts, this option adds\n" +"        PLT, tile markers and uses RPCL.\n" +"        Only valid for output j2c images. Default is 64.\n" +" -rev, --reversible\n" +"        Set the compression to be lossless (reversible in j2c parlance).\n" +"        Only valid for output j2c images.\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" +" -a, --analyzeperformance\n"  "        Create a report comparing <metric>_baseline.slp with current <metric>.slp\n" -"        Results in <metric>_report.csv" +"        Results in <metric>_report.csv\n"  " -s, --image-stats\n"  "        Output stats for each input and output image.\n"  "\n"; @@ -69,31 +89,8 @@ 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; -	} -	 +	std::string exten = gDirUtilp->getExtension(filename);	 +	LLPointer<LLImageFormatted> image = LLImageFormatted::createFromExtension(exten);  	return image;  } @@ -110,10 +107,11 @@ void output_image_stats(LLPointer<LLImageFormatted> image, const std::string &fi  }  // 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<LLImageRaw> load_image(const std::string &src_filename, int discard_level, int* region, bool output_stats)  {  	LLPointer<LLImageFormatted> image = create_image(src_filename); - +	 +	// This just loads the image file stream into a buffer. No decoding done.  	if (!image->load(src_filename))  	{  		return NULL; @@ -131,6 +129,15 @@ LLPointer<LLImageRaw> load_image(const std::string &src_filename, bool output_st  	}  	LLPointer<LLImageRaw> raw_image = new LLImageRaw; +	 +	// Set the image restriction on load in the case of a j2c image +	if ((image->getCodec() == IMG_CODEC_J2C) && ((discard_level != -1) || (region != NULL))) +	{ +		// That method doesn't exist (and likely, doesn't make sense) for any other image file format +		// hence the required cryptic cast. +		((LLImageJ2C*)(image.get()))->initDecode(*raw_image, discard_level, region); +	} +	  	if (!image->decode(raw_image, 0.0f))  	{  		return NULL; @@ -140,10 +147,22 @@ LLPointer<LLImageRaw> load_image(const std::string &src_filename, bool output_st  }  // Save a raw image instance into a file -bool save_image(const std::string &dest_filename, LLPointer<LLImageRaw> raw_image, bool output_stats) +bool save_image(const std::string &dest_filename, LLPointer<LLImageRaw> raw_image, int blocks_size, int precincts_size, bool reversible, bool output_stats)  {  	LLPointer<LLImageFormatted> image = create_image(dest_filename); +	// Set the image codestream parameters on output in the case of a j2c image +	if (image->getCodec() == IMG_CODEC_J2C) +	{ +		// That method doesn't exist (and likely, doesn't make sense) for any other image file format +		// hence the required cryptic cast. +		if ((blocks_size != -1) || (precincts_size != -1)) +		{ +			((LLImageJ2C*)(image.get()))->initEncode(*raw_image, blocks_size, precincts_size); +		} +		((LLImageJ2C*)(image.get()))->setReversible(reversible); +	} +	  	if (!image->encode(raw_image, 0.0f))  	{  		return false; @@ -280,8 +299,14 @@ int main(int argc, char** argv)  	// List of input and output files  	std::list<std::string> input_filenames;  	std::list<std::string> output_filenames; +	// Other optional parsed arguments  	bool analyze_performance = false;  	bool image_stats = false; +	int* region = NULL; +	int discard_level = -1; +	int precincts_size = -1; +	int blocks_size = -1; +	bool reversible = false;  	// Init whatever is necessary  	ll_init_apr(); @@ -323,6 +348,85 @@ int main(int argc, char** argv)  				file_name = argv[arg+1];	// Next argument and loop over  			}  		} +		else if ((!strcmp(argv[arg], "--region") || !strcmp(argv[arg], "-r")) && arg < argc-1) +		{ +			std::string value_str = argv[arg+1]; +			int index = 0; +			region = new int[4]; +			while (value_str[0] != '-')		// if arg starts with '-', it's the next option +			{ +				int value = atoi(value_str.c_str()); +				region[index++] = value; +				arg += 1;					// Definitely skip that arg now we know it's a number +				if ((arg + 1) == argc)		// Break out of the loop if we reach the end of the arg list +					break; +				if (index == 4)				// Break out of the loop if we captured 4 values already +					break; +				value_str = argv[arg+1];	// Next argument and loop over +			} +			if (index != 4) +			{ +				std::cout << "--region arguments invalid" << std::endl; +				delete [] region; +				region = NULL; +			} +		} +		else if (!strcmp(argv[arg], "--discard_level") || !strcmp(argv[arg], "-d")) +		{ +			std::string value_str; +			if ((arg + 1) < argc) +			{ +				value_str = argv[arg+1]; +			} +			if (((arg + 1) >= argc) || (value_str[0] == '-')) +			{ +				std::cout << "No valid --discard_level argument given, discard_level ignored" << std::endl; +			} +			else +			{ +				discard_level = atoi(value_str.c_str()); +				// Clamp to the values accepted by the viewer +				discard_level = llclamp(discard_level,0,5); +			} +		} +		else if (!strcmp(argv[arg], "--precincts") || !strcmp(argv[arg], "-p")) +		{ +			std::string value_str; +			if ((arg + 1) < argc) +			{ +				value_str = argv[arg+1]; +			} +			if (((arg + 1) >= argc) || (value_str[0] == '-')) +			{ +				std::cout << "No valid --precincts argument given, precincts ignored" << std::endl; +			} +			else +			{ +				precincts_size = atoi(value_str.c_str()); +				// *TODO: make sure precincts_size is a power of 2 +			} +		} +		else if (!strcmp(argv[arg], "--blocks") || !strcmp(argv[arg], "-b")) +		{ +			std::string value_str; +			if ((arg + 1) < argc) +			{ +				value_str = argv[arg+1]; +			} +			if (((arg + 1) >= argc) || (value_str[0] == '-')) +			{ +				std::cout << "No valid --blocks argument given, blocks ignored" << std::endl; +			} +			else +			{ +				blocks_size = atoi(value_str.c_str()); +				// *TODO: make sure blocks_size is a power of 2 +			} +		} +		else if (!strcmp(argv[arg], "--reversible") || !strcmp(argv[arg], "-rev")) +		{ +			reversible = true; +		}  		else if (!strcmp(argv[arg], "--logmetrics") || !strcmp(argv[arg], "-log"))  		{  			// '--logmetrics' needs to be specified with a named test metric argument @@ -346,7 +450,7 @@ int main(int argc, char** argv)  					break;  			}  		} -		else if (!strcmp(argv[arg], "--analyzeperformance") || !strcmp(argv[arg], "-r")) +		else if (!strcmp(argv[arg], "--analyzeperformance") || !strcmp(argv[arg], "-a"))  		{  			analyze_performance = true;  		} @@ -364,7 +468,7 @@ int main(int argc, char** argv)  	}  	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; +		std::cout << "Cannot create perf report if no perf gathered (i.e. use argument -log <perf> with -a) -> exit" << std::endl;  		return 0;  	} @@ -382,10 +486,10 @@ int main(int argc, char** argv)  	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) +	for (; in_file != in_end; ++in_file, ++out_file)  	{  		// Load file -		LLPointer<LLImageRaw> raw_image = load_image(*in_file, image_stats); +		LLPointer<LLImageRaw> raw_image = load_image(*in_file, discard_level, region, image_stats);  		if (!raw_image)  		{  			std::cout << "Error: Image " << *in_file << " could not be loaded" << std::endl; @@ -395,7 +499,7 @@ int main(int argc, char** argv)  		// Save file  		if (out_file != out_end)  		{ -			if (!save_image(*out_file, raw_image, image_stats)) +			if (!save_image(*out_file, raw_image, blocks_size, precincts_size, reversible, image_stats))  			{  				std::cout << "Error: Image " << *out_file << " could not be saved" << std::endl;  			} @@ -403,29 +507,28 @@ int main(int argc, char** argv)  			{  				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"; +		std::cout << "Analyzing performance, check report in : " << report_name << std::endl; +  		LLMetricPerformanceTesterBasic::doAnalysisMetrics(baseline_name, current_name, report_name);  	} +	// Stop the perf gathering system if needed +	if (LLFastTimer::sMetricLog) +	{ +		LLMetricPerformanceTesterBasic::deleteTester(LLFastTimer::sLogName); +		sAllDone = true; +	} +	  	// Cleanup and exit  	LLImage::cleanupClass();  	if (fast_timer_log_thread) diff --git a/indra/llcommon/llversionviewer.h b/indra/llcommon/llversionviewer.h index bd6df962a1..df5afcbf1c 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 = 5; +const S32 LL_VERSION_PATCH = 6;  const S32 LL_VERSION_BUILD = 0;  const char * const LL_CHANNEL = "Second Life Developer"; diff --git a/indra/llimage/llimage.cpp b/indra/llimage/llimage.cpp index 39211bf7fa..f0d15d9607 100644 --- a/indra/llimage/llimage.cpp +++ b/indra/llimage/llimage.cpp @@ -1254,28 +1254,7 @@ bool LLImageRaw::createFromFile(const std::string &filename, bool j2c_lowest_mip  		return false;  	} -	LLPointer<LLImageFormatted> image; -	switch(codec) -	{ -	  //case IMG_CODEC_RGB: -	  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_DXT: -		image = new LLImageDXT(); -		break; -	  default: -		return false; -	} +	LLPointer<LLImageFormatted> image = LLImageFormatted::createFromType(codec);  	llassert(image.notNull());  	U8 *buffer = image->allocateData(length); diff --git a/indra/llimage/llimagej2c.cpp b/indra/llimage/llimagej2c.cpp index 80fec7f8a0..a90df0f1c1 100644 --- a/indra/llimage/llimagej2c.cpp +++ b/indra/llimage/llimagej2c.cpp @@ -139,6 +139,15 @@ BOOL LLImageJ2C::updateData()  	return res;  } +BOOL LLImageJ2C::initDecode(LLImageRaw &raw_image, int discard_level, int* region) +{ +	return mImpl->initDecode(*this,raw_image,discard_level,region); +} + +BOOL LLImageJ2C::initEncode(LLImageRaw &raw_image, int blocks_size, int precincts_size) +{ +	return mImpl->initEncode(*this,raw_image,blocks_size,precincts_size); +}  BOOL LLImageJ2C::decode(LLImageRaw *raw_imagep, F32 decode_time)  { @@ -251,6 +260,9 @@ S32 LLImageJ2C::calcHeaderSizeJ2C()  //static  S32 LLImageJ2C::calcDataSizeJ2C(S32 w, S32 h, S32 comp, S32 discard_level, F32 rate)  { +	// Note: this only provides an *estimate* of the size in bytes of an image level +	// *TODO: find a way to read the true size (when available) and convey the fact +	// that the result is an estimate in the other cases  	if (rate <= 0.f) rate = .125f;  	while (discard_level > 0)  	{ diff --git a/indra/llimage/llimagej2c.h b/indra/llimage/llimagej2c.h index dd5bec8b2e..6bba81aab5 100644 --- a/indra/llimage/llimagej2c.h +++ b/indra/llimage/llimagej2c.h @@ -56,6 +56,8 @@ public:  	/*virtual*/ void resetLastError();  	/*virtual*/ void setLastError(const std::string& message, const std::string& filename = std::string()); +	BOOL initDecode(LLImageRaw &raw_image, int discard_level, int* region); +	BOOL initEncode(LLImageRaw &raw_image, int blocks_size, int precincts_size);  	// Encode with comment text   	BOOL encode(const LLImageRaw *raw_imagep, const char* comment_text, F32 encode_time=0.0); @@ -117,6 +119,8 @@ protected:  	virtual BOOL decodeImpl(LLImageJ2C &base, LLImageRaw &raw_image, F32 decode_time, S32 first_channel, S32 max_channel_count) = 0;  	virtual BOOL encodeImpl(LLImageJ2C &base, const LLImageRaw &raw_image, const char* comment_text, F32 encode_time=0.0,  							BOOL reversible=FALSE) = 0; +	virtual BOOL initDecode(LLImageJ2C &base, LLImageRaw &raw_image, int discard_level = -1, int* region = NULL) = 0; +	virtual BOOL initEncode(LLImageJ2C &base, LLImageRaw &raw_image, int blocks_size = -1, int precincts_size = -1) = 0;  	friend class LLImageJ2C;  }; diff --git a/indra/llimagej2coj/llimagej2coj.cpp b/indra/llimagej2coj/llimagej2coj.cpp index 13b12c0928..8288fa1f5c 100644 --- a/indra/llimagej2coj/llimagej2coj.cpp +++ b/indra/llimagej2coj/llimagej2coj.cpp @@ -107,6 +107,17 @@ LLImageJ2COJ::~LLImageJ2COJ()  {  } +BOOL LLImageJ2COJ::initDecode(LLImageJ2C &base, LLImageRaw &raw_image, int discard_level, int* region) +{ +	// No specific implementation for this method in the OpenJpeg case +	return FALSE; +} + +BOOL LLImageJ2COJ::initEncode(LLImageJ2C &base, LLImageRaw &raw_image, int blocks_size, int precincts_size) +{ +	// No specific implementation for this method in the OpenJpeg case +	return FALSE; +}  BOOL LLImageJ2COJ::decodeImpl(LLImageJ2C &base, LLImageRaw &raw_image, F32 decode_time, S32 first_channel, S32 max_channel_count)  { diff --git a/indra/llimagej2coj/llimagej2coj.h b/indra/llimagej2coj/llimagej2coj.h index 9476665ccb..9c7cc09fcb 100644 --- a/indra/llimagej2coj/llimagej2coj.h +++ b/indra/llimagej2coj/llimagej2coj.h @@ -39,6 +39,8 @@ protected:  	/*virtual*/ BOOL decodeImpl(LLImageJ2C &base, LLImageRaw &raw_image, F32 decode_time, S32 first_channel, S32 max_channel_count);  	/*virtual*/ BOOL encodeImpl(LLImageJ2C &base, const LLImageRaw &raw_image, const char* comment_text, F32 encode_time=0.0,  								BOOL reversible = FALSE); +	/*virtual*/ BOOL initDecode(LLImageJ2C &base, LLImageRaw &raw_image, int discard_level = -1, int* region = NULL); +	/*virtual*/ BOOL initEncode(LLImageJ2C &base, LLImageRaw &raw_image, int blocks_size = -1, int precincts_size = -1);  };  #endif diff --git a/indra/llkdu/llimagej2ckdu.cpp b/indra/llkdu/llimagej2ckdu.cpp index 10ea5685e8..ae456a48be 100644 --- a/indra/llkdu/llimagej2ckdu.cpp +++ b/indra/llkdu/llimagej2ckdu.cpp @@ -34,35 +34,35 @@  class kdc_flow_control { -public: // Member functions -    kdc_flow_control(kdu_image_in_base *img_in, kdu_codestream codestream); -    ~kdc_flow_control(); -    bool advance_components(); -    void process_components(); +public: +	kdc_flow_control(kdu_image_in_base *img_in, kdu_codestream codestream); +	~kdc_flow_control(); +	bool advance_components(); +	void process_components(); +	 +private: -private: // Data -     -    struct kdc_component_flow_control { -    public: // Data -        kdu_image_in_base *reader; -        int vert_subsampling; -        int ratio_counter;  /*  Initialized to 0, decremented by `count_delta'; +	struct kdc_component_flow_control { +	public: +		kdu_image_in_base *reader; +		int vert_subsampling; +		int ratio_counter;  /*  Initialized to 0, decremented by `count_delta';                                  when < 0, a new line must be processed, after                                  which it is incremented by `vert_subsampling'.  */ -        int initial_lines; -        int remaining_lines; -        kdu_line_buf *line; -    }; -     -    kdu_codestream codestream; -    kdu_dims valid_tile_indices; -    kdu_coords tile_idx; -    kdu_tile tile; -    int num_components; -    kdc_component_flow_control *components; -    int count_delta; // Holds the minimum of the `vert_subsampling' fields -    kdu_multi_analysis engine; -    kdu_long max_buffer_memory; +		int initial_lines; +		int remaining_lines; +		kdu_line_buf *line; +	}; +	 +	kdu_codestream codestream; +	kdu_dims valid_tile_indices; +	kdu_coords tile_idx; +	kdu_tile tile; +	int num_components; +	kdc_component_flow_control *components; +	int count_delta; // Holds the minimum of the `vert_subsampling' fields +	kdu_multi_analysis engine; +	kdu_long max_buffer_memory;  };  // @@ -72,7 +72,8 @@ void set_default_colour_weights(kdu_params *siz);  const char* engineInfoLLImageJ2CKDU()  { -	return "KDU v6.4.1"; +	std::string version = llformat("KDU %s", KDU_CORE_VERSION); +	return version.c_str();  }  LLImageJ2CKDU* createLLImageJ2CKDU() @@ -105,7 +106,11 @@ const char* fallbackEngineInfoLLImageJ2CImpl()  class LLKDUDecodeState  {  public: +	LLKDUDecodeState(kdu_tile tile, kdu_byte *buf, S32 row_gap); +	~LLKDUDecodeState(); +	BOOL processTileDecode(F32 decode_time, BOOL limit_time = TRUE); +private:  	S32 mNumComponents;  	BOOL mUseYCC;  	kdu_dims mDims; @@ -113,22 +118,12 @@ public:  	kdu_tile_comp mComps[4];  	kdu_line_buf mLines[4];  	kdu_pull_ifc mEngines[4]; -	bool mReversible[4]; // Some components may be reversible and others not. -	int mBitDepths[4]; // Original bit-depth may be quite different from 8. - +	bool mReversible[4]; // Some components may be reversible and others not +	int mBitDepths[4];   // Original bit-depth may be quite different from 8 +	  	kdu_tile mTile;  	kdu_byte *mBuf;  	S32 mRowGap; - -	LLKDUDecodeState(kdu_tile tile, kdu_byte *buf, S32 row_gap); -	~LLKDUDecodeState(); -	BOOL processTileDecode(F32 decode_time, BOOL limit_time = TRUE); - -public: -	int *AssignLayerBytes(siz_params *siz, int &num_specs); - -	void setupCodeStream(BOOL keep_codestream, LLImageJ2CKDU::ECodeStreamMode mode); -	BOOL initDecode(LLImageRaw &raw_image, F32 decode_time, LLImageJ2CKDU::ECodeStreamMode mode, S32 first_channel, S32 max_channel_count );  };  void ll_kdu_error( void ) @@ -153,7 +148,7 @@ class LLKDUMessageError : public kdu_message  public:  	/*virtual*/ void put_text(const char *s);  	/*virtual*/ void put_text(const kdu_uint16 *s); -	/*virtual*/ void flush(bool end_of_message=false); +	/*virtual*/ void flush(bool end_of_message = false);  	static LLKDUMessageError sDefaultMessage;  }; @@ -179,7 +174,7 @@ void LLKDUMessageError::put_text(const kdu_uint16 *s)  void LLKDUMessageError::flush(bool end_of_message)  { -	if( end_of_message )  +	if (end_of_message)   	{  		throw "KDU throwing an exception";  	} @@ -195,7 +190,9 @@ mCodeStreamp(NULL),  mTPosp(NULL),  mTileIndicesp(NULL),  mRawImagep(NULL), -mDecodeState(NULL) +mDecodeState(NULL), +mBlocksSize(-1), +mPrecinctsSize(-1)  {  } @@ -210,7 +207,7 @@ void transfer_bytes(kdu_byte *dest, kdu_line_buf &src, int gap, int precision);  void LLImageJ2CKDU::setupCodeStream(LLImageJ2C &base, BOOL keep_codestream, ECodeStreamMode mode)  {  	S32 data_size = base.getDataSize(); -	S32 max_bytes = base.getMaxBytes() ? base.getMaxBytes() : data_size; +	S32 max_bytes = (base.getMaxBytes() ? base.getMaxBytes() : data_size);  	//  	//  Initialization @@ -247,21 +244,21 @@ void LLImageJ2CKDU::setupCodeStream(LLImageJ2C &base, BOOL keep_codestream, ECod  	// Set the maximum number of bytes to use from the codestream  	mCodeStreamp->set_max_bytes(max_bytes); -	//    If you want to flip or rotate the image for some reason, change +	//	If you want to flip or rotate the image for some reason, change  	// the resolution, or identify a restricted region of interest, this is  	// the place to do it.  You may use "kdu_codestream::change_appearance"  	// and "kdu_codestream::apply_input_restrictions" for this purpose. -	//    If you wish to truncate the code-stream prior to decompression, you +	//	If you wish to truncate the code-stream prior to decompression, you  	// may use "kdu_codestream::set_max_bytes". -	//    If you wish to retain all compressed data so that the material +	//	If you wish to retain all compressed data so that the material  	// can be decompressed multiple times, possibly with different appearance  	// parameters, you should call "kdu_codestream::set_persistent" here. -	//    There are a variety of other features which must be enabled at +	//	There are a variety of other features which must be enabled at  	// this point if you want to take advantage of them.  See the  	// descriptions appearing with the "kdu_codestream" interface functions  	// in "kdu_compressed.h" for an itemized account of these capabilities. -	switch( mode ) +	switch (mode)  	{  	case MODE_FAST:  		mCodeStreamp->set_fast(); @@ -326,7 +323,19 @@ void LLImageJ2CKDU::cleanupCodeStream()  	mTileIndicesp = NULL;  } -BOOL LLImageJ2CKDU::initDecode(LLImageJ2C &base, LLImageRaw &raw_image, F32 decode_time, ECodeStreamMode mode, S32 first_channel, S32 max_channel_count ) +BOOL LLImageJ2CKDU::initDecode(LLImageJ2C &base, LLImageRaw &raw_image, int discard_level, int* region) +{ +	return initDecode(base,raw_image,0.0f,MODE_FAST,0,4,discard_level,region); +} + +BOOL LLImageJ2CKDU::initEncode(LLImageJ2C &base, LLImageRaw &raw_image, int blocks_size, int precincts_size) +{ +	mBlocksSize = blocks_size; +	mPrecinctsSize = precincts_size; +	return TRUE; +} + +BOOL LLImageJ2CKDU::initDecode(LLImageJ2C &base, LLImageRaw &raw_image, F32 decode_time, ECodeStreamMode mode, S32 first_channel, S32 max_channel_count, int discard_level, int* region)  {  	base.resetLastError(); @@ -339,17 +348,36 @@ BOOL LLImageJ2CKDU::initDecode(LLImageJ2C &base, LLImageRaw &raw_image, F32 deco  		mRawImagep = &raw_image;  		mCodeStreamp->change_appearance(false, true, false); -		mCodeStreamp->apply_input_restrictions(first_channel,max_channel_count,base.getRawDiscardLevel(),0,NULL); -		kdu_dims dims; mCodeStreamp->get_dims(0,dims); -		S32 channels = base.getComponents() - first_channel; -		if( channels > max_channel_count ) +		// Apply loading discard level and cropping if required +		kdu_dims* region_kdu = NULL; +		if (region != NULL)  		{ -			channels = max_channel_count; +			region_kdu = new kdu_dims; +			region_kdu->pos.x  = region[0]; +			region_kdu->pos.y  = region[1]; +			region_kdu->size.x = region[2] - region[0]; +			region_kdu->size.y = region[3] - region[1];  		} +		int discard = (discard_level != -1 ? discard_level : base.getRawDiscardLevel()); +		 +		// Apply loading restrictions +		mCodeStreamp->apply_input_restrictions( first_channel, max_channel_count, discard, 0, region_kdu); +		 +		// Clean-up +		if (region_kdu) +		{ +			delete region_kdu; +			region_kdu = NULL; +		} + +		// Resize raw_image according to the image to be decoded +		kdu_dims dims; mCodeStreamp->get_dims(0,dims); +		S32 channels = base.getComponents() - first_channel; +		channels = llmin(channels,max_channel_count);  		raw_image.resize(dims.size.x, dims.size.y, channels); +		//	llinfos << "Resizing raw_image to " << dims.size.x << ":" << dims.size.y << llendl; -		//	llinfos << "Resizing to " << dims.size.x << ":" << dims.size.y << llendl;  		if (!mTileIndicesp)  		{  			mTileIndicesp = new kdu_dims; @@ -426,7 +454,7 @@ BOOL LLImageJ2CKDU::decodeImpl(LLImageJ2C &base, LLImageRaw &raw_image, F32 deco  					// canvas coordinate system.  Comparing the two tells  					// us where the current tile is in the buffer.  					S32 channels = base.getComponents() - first_channel; -					if( channels > max_channel_count ) +					if (channels > max_channel_count)  					{  						channels = max_channel_count;  					} @@ -452,14 +480,14 @@ BOOL LLImageJ2CKDU::decodeImpl(LLImageJ2C &base, LLImageRaw &raw_image, F32 deco  					return FALSE;  				}  			} -			catch( const char* msg ) +			catch (const char* msg)  			{  				base.setLastError(ll_safe_string(msg));  				base.decodeFailed();  				cleanupCodeStream();  				return TRUE; // done  			} -			catch( ... ) +			catch (...)  			{  				base.setLastError( "Unknown J2C error" );  				base.decodeFailed(); @@ -482,28 +510,17 @@ BOOL LLImageJ2CKDU::decodeImpl(LLImageJ2C &base, LLImageRaw &raw_image, F32 deco  BOOL LLImageJ2CKDU::encodeImpl(LLImageJ2C &base, const LLImageRaw &raw_image, const char* comment_text, F32 encode_time, BOOL reversible)  { -	// Collect simple arguments. -	bool transpose, vflip, hflip; -	bool allow_rate_prediction, mem, quiet, no_weights; -	int cpu_iterations; -	std::ostream *record_stream; - -	transpose = false; -	record_stream = NULL; -	allow_rate_prediction = true; -	no_weights = false; -	cpu_iterations = -1; -	mem = false; -	quiet = false; -	vflip = true; -	hflip = false; +	// Declare and set simple arguments +	bool transpose = false; +	bool vflip = true; +	bool hflip = false;  	try  	{ -		// Set up input image files. +		// Set up input image files  		siz_params siz; -		// Should set rate someplace here. +		// Should set rate someplace here  		LLKDUMemIn mem_in(raw_image.getData(),  			raw_image.getDataSize(),  			raw_image.getWidth(), @@ -521,26 +538,17 @@ BOOL LLImageJ2CKDU::encodeImpl(LLImageJ2C &base, const LLImageRaw &raw_image, co  		siz.set(Sprecision,0,0,8);  // Image samples have original bit-depth of 8  		siz.set(Ssigned,0,0,false); // Image samples are originally unsigned -		kdu_params *siz_ref = &siz; siz_ref->finalize(); -		siz_params transformed_siz; // Use this one to construct code-strea +		kdu_params *siz_ref = &siz;  +		siz_ref->finalize(); +		siz_params transformed_siz; // Use this one to construct code-stream  		transformed_siz.copy_from(&siz,-1,-1,-1,0,transpose,false,false); -		// Construct the `kdu_codestream' object and parse all remaining arguments. - +		// Construct the `kdu_codestream' object and parse all remaining arguments  		U32 max_output_size = base.getWidth()*base.getHeight()*base.getComponents(); -		if (max_output_size < 1000) -		{ -			max_output_size = 1000; -		} +		max_output_size = (max_output_size < 1000 ? 1000 : max_output_size);  		U8 *output_buffer = new U8[max_output_size]; - -		U32 output_size = max_output_size; // gets modified -		LLKDUMemTarget output(output_buffer, output_size, base.getWidth()*base.getHeight()*base.getComponents()); -		if (output_size > max_output_size) -		{ -			llerrs << llformat("LLImageJ2C::encode output_size(%d) > max_output_size(%d)", -				output_size,max_output_size) << llendl; -		} +		U32 output_size = 0; // Address updated by LLKDUMemTarget to give the final compressed buffer size +		LLKDUMemTarget output(output_buffer, output_size, max_output_size);  		kdu_codestream codestream;  		codestream.create(&transformed_siz,&output); @@ -558,16 +566,22 @@ BOOL LLImageJ2CKDU::encodeImpl(LLImageJ2C &base, const LLImageRaw &raw_image, co  		kdu_long layer_bytes[64];  		U32 max_bytes = 0; -		if ((num_components >= 3) && !no_weights) +		if (num_components >= 3)  		{ +			// Note that we always use YCC and not YUV +			// *TODO: Verify this doesn't screws up reversible textures (like sculpties) as YCC is not reversible but YUV is...  			set_default_colour_weights(codestream.access_siz());  		}  		if (reversible)  		{ -			// If we're doing reversible, assume we're not using quality layers. -			// Yes, I know this is incorrect!  			codestream.access_siz()->parse_string("Creversible=yes"); +			// *TODO: we should use yuv in reversible mode and one level since those images are small.  +			// Don't turn this on now though as both create problems on decoding for the moment +			//codestream.access_siz()->parse_string("Clevels=1"); +			//codestream.access_siz()->parse_string("Cycc=no"); +			// If we're doing reversible (i.e. lossless compression), assumes we're not using quality layers. +			// *TODO: this is incorrect and unecessary. Try using the regular layer setting.  			codestream.access_siz()->parse_string("Clayers=1");  			num_layer_specs = 1;  			layer_bytes[0] = 0; @@ -577,6 +591,7 @@ BOOL LLImageJ2CKDU::encodeImpl(LLImageJ2C &base, const LLImageRaw &raw_image, co  			// Rate is the argument passed into the LLImageJ2C which  			// specifies the target compression rate.  The default is 8:1.  			// Possibly if max_bytes < 500, we should just use the default setting? +			// *TODO: mRate is actually always 8:1 in the viewer. Test different values. Also force to reversible for small (< 500 bytes) textures.  			if (base.mRate != 0.f)  			{  				max_bytes = (U32)(base.mRate*base.getWidth()*base.getHeight()*base.getComponents()); @@ -617,42 +632,56 @@ BOOL LLImageJ2CKDU::encodeImpl(LLImageJ2C &base, const LLImageRaw &raw_image, co  				codestream.access_siz()->parse_string(layer_string.c_str());  			}  		} -		codestream.access_siz()->finalize_all(); -		if (cpu_iterations >= 0) +		 +		// Set up data ordering, markers, etc... if precincts or blocks specified +		if ((mBlocksSize != -1) || (mPrecinctsSize != -1))  		{ -			codestream.collect_timing_stats(cpu_iterations); +			if (mPrecinctsSize != -1) +			{ +				std::string precincts_string = llformat("Cprecincts={%d,%d}",mPrecinctsSize,mPrecinctsSize); +				codestream.access_siz()->parse_string(precincts_string.c_str()); +			} +			if (mBlocksSize != -1) +			{ +				std::string blocks_string = llformat("Cblk={%d,%d}",mBlocksSize,mBlocksSize); +				codestream.access_siz()->parse_string(blocks_string.c_str()); +			} +			std::string ordering_string = llformat("Corder=RPCL"); +			codestream.access_siz()->parse_string(ordering_string.c_str()); +			std::string PLT_string = llformat("ORGgen_plt=yes"); +			codestream.access_siz()->parse_string(PLT_string.c_str()); +			std::string Parts_string = llformat("ORGtparts=R"); +			codestream.access_siz()->parse_string(Parts_string.c_str());  		} +		 +		codestream.access_siz()->finalize_all();  		codestream.change_appearance(transpose,vflip,hflip);  		// Now we are ready for sample data processing. -        kdc_flow_control *tile = new kdc_flow_control(&mem_in,codestream); -        bool done = false; -        while (!done) -        {  -            // Process line by line -            done = true; -            if (tile->advance_components()) -            { -                done = false; -                tile->process_components(); -            } -        } +		kdc_flow_control *tile = new kdc_flow_control(&mem_in,codestream); +		bool done = false; +		while (!done) +		{  +			// Process line by line +			if (tile->advance_components()) +			{ +				tile->process_components(); +			} +			else +			{ +				done = true; +			} +		}  		// Produce the compressed output -        codestream.flush(layer_bytes,num_layer_specs); +		codestream.flush(layer_bytes,num_layer_specs);  		// Cleanup -        delete tile; - +		delete tile;  		codestream.destroy(); -		if (record_stream != NULL) -		{ -			delete record_stream; -		}  		// Now that we're done encoding, create the new data buffer for the compressed  		// image and stick it there. -  		base.copyData(output_buffer, output_size);  		base.updateData(); // set width, height  		delete[] output_buffer; @@ -674,19 +703,19 @@ BOOL LLImageJ2CKDU::encodeImpl(LLImageJ2C &base, const LLImageRaw &raw_image, co  BOOL LLImageJ2CKDU::getMetadata(LLImageJ2C &base)  {  	// *FIX: kdu calls our callback function if there's an error, and -	// then bombs.  To regain control, we throw an exception, and +	// then bombs. To regain control, we throw an exception, and  	// catch it here.  	try  	{  		setupCodeStream(base, FALSE, MODE_FAST);  		return TRUE;  	} -	catch( const char* msg ) +	catch (const char* msg)  	{  		base.setLastError(ll_safe_string(msg));  		return FALSE;  	} -	catch( ... ) +	catch (...)  	{  		base.setLastError( "Unknown J2C error" );  		return FALSE; @@ -699,37 +728,49 @@ void set_default_colour_weights(kdu_params *siz)  	assert(cod != NULL);  	bool can_use_ycc = true; -	bool rev0=false; -	int depth0=0, sub_x0=1, sub_y0=1; -	for (int c=0; c < 3; c++) +	bool rev0 = false; +	int depth0 = 0, sub_x0 = 1, sub_y0 = 1; +	for (int c = 0; c < 3; c++)  	{ -		int depth=0; siz->get(Sprecision,c,0,depth); -		int sub_y=1; siz->get(Ssampling,c,0,sub_y); -		int sub_x=1; siz->get(Ssampling,c,1,sub_x); +		int depth = 0; siz->get(Sprecision,c,0,depth); +		int sub_y = 1; siz->get(Ssampling,c,0,sub_y); +		int sub_x = 1; siz->get(Ssampling,c,1,sub_x);  		kdu_params *coc = cod->access_relation(-1,c); -		bool rev=false; coc->get(Creversible,0,0,rev); +		bool rev = false; coc->get(Creversible,0,0,rev);  		if (c == 0) -		{ rev0=rev; depth0=depth; sub_x0=sub_x; sub_y0=sub_y; } -		else if ((rev != rev0) || (depth != depth0) || -			(sub_x != sub_x0) || (sub_y != sub_y0)) +		{ +			rev0 = rev; depth0 = depth; sub_x0 = sub_x; sub_y0 = sub_y; +		} +		else if ((rev != rev0) || (depth != depth0) ||  +				 (sub_x != sub_x0) || (sub_y != sub_y0)) +		{  			can_use_ycc = false; +		}  	}  	if (!can_use_ycc) +	{  		return; +	}  	bool use_ycc;  	if (!cod->get(Cycc,0,0,use_ycc)) +	{  		cod->set(Cycc,0,0,use_ycc=true); +	}  	if (!use_ycc) +	{  		return; +	}  	float weight; -	if (cod->get(Clev_weights,0,0,weight) || -		cod->get(Cband_weights,0,0,weight)) -		return; // Weights already specified explicitly. +	if (cod->get(Clev_weights,0,0,weight) || cod->get(Cband_weights,0,0,weight)) +	{ +		// Weights already specified explicitly -> nothing to do +		return;  +	} -	/* These example weights are adapted from numbers generated by Marcus Nadenau -	at EPFL, for a viewing distance of 15 cm and a display resolution of -	300 DPI. */ +	// These example weights are adapted from numbers generated by Marcus Nadenau +	// at EPFL, for a viewing distance of 15 cm and a display resolution of +	// 300 DPI.  	cod->parse_string("Cband_weights:C0="  		"{0.0901},{0.2758},{0.2758}," @@ -775,7 +816,7 @@ all necessary level shifting, type conversion, rounding and truncation. */  				val += 128;  				if (val & ((-1)<<8))  				{ -					val = (val<0)?0:255; +					val = (val < 0 ? 0 : 255);  				}  				*dest = (kdu_byte) val;  			} @@ -793,7 +834,7 @@ all necessary level shifting, type conversion, rounding and truncation. */  				val += 128;  				if (val & ((-1)<<8))  				{ -					val = (val<0)?0:255; +					val = (val < 0 ? 0 : 255);  				}  				*dest = (kdu_byte) val;  			} @@ -816,7 +857,7 @@ all necessary level shifting, type conversion, rounding and truncation. */  					val += 128;  					if (val & ((-1)<<8))  					{ -						val = (val<0)?0:255; +						val = (val < 0 ? 0 : 255);  					}  					*dest = (kdu_byte) val;  				} @@ -835,7 +876,7 @@ all necessary level shifting, type conversion, rounding and truncation. */  					val += 128;  					if (val & ((-1)<<8))  					{ -						val = (val<0)?0:(256-(1<<upshift)); +						val = (val < 0 ? 0 : 256 - (1<<upshift));  					}  					*dest = (kdu_byte) val;  				} @@ -857,7 +898,7 @@ all necessary level shifting, type conversion, rounding and truncation. */  					val += 128;  					if (val & ((-1)<<8))  					{ -						val = (val<0)?0:255; +						val = (val < 0 ? 0 : 255);  					}  					*dest = (kdu_byte) val;  				} @@ -873,7 +914,7 @@ all necessary level shifting, type conversion, rounding and truncation. */  					val += 128;  					if (val & ((-1)<<8))  					{ -						val = (val<0)?0:(256-(1<<upshift)); +						val = (val < 0 ? 0 : 256 - (1<<upshift));  					}  					*dest = (kdu_byte) val;  				} @@ -892,17 +933,17 @@ LLKDUDecodeState::LLKDUDecodeState(kdu_tile tile, kdu_byte *buf, S32 row_gap)  	mNumComponents = tile.get_num_components(); -	llassert(mNumComponents<=4); +	llassert(mNumComponents <= 4);  	mUseYCC = tile.get_ycc(); -	for (c=0; c<4; ++c) +	for (c = 0; c < 4; ++c)  	{  		mReversible[c] = false;  		mBitDepths[c] = 0;  	}  	// Open tile-components and create processing engines and resources -	for (c=0; c < mNumComponents; c++) +	for (c = 0; c < mNumComponents; c++)  	{  		mComps[c] = mTile.access_component(c);  		mReversible[c] = mComps[c].get_reversible(); @@ -929,7 +970,7 @@ LLKDUDecodeState::LLKDUDecodeState(kdu_tile tile, kdu_byte *buf, S32 row_gap)  		}  	}  	mAllocator.finalize(); // Actually creates buffering resources -	for (c=0; c < mNumComponents; c++) +	for (c = 0; c < mNumComponents; c++)  	{  		mLines[c].create(); // Grabs resources from the allocator.  	} @@ -937,13 +978,11 @@ LLKDUDecodeState::LLKDUDecodeState(kdu_tile tile, kdu_byte *buf, S32 row_gap)  LLKDUDecodeState::~LLKDUDecodeState()  { -	S32 c;  	// Cleanup -	for (c=0; c < mNumComponents; c++) +	for (S32 c = 0; c < mNumComponents; c++)  	{  		mEngines[c].destroy(); // engines are interfaces; no default destructors  	} -  	mTile.close();  } @@ -962,7 +1001,7 @@ separation between consecutive rows in the real buffer. */  	LLTimer decode_timer;  	while (mDims.size.y--)  	{ -		for (c=0; c < mNumComponents; c++) +		for (c = 0; c < mNumComponents; c++)  		{  			mEngines[c].pull(mLines[c],true);  		} @@ -970,7 +1009,7 @@ separation between consecutive rows in the real buffer. */  		{  			kdu_convert_ycc_to_rgb(mLines[0],mLines[1],mLines[2]);  		} -		for (c=0; c < mNumComponents; c++) +		for (c = 0; c < mNumComponents; c++)  		{  			transfer_bytes(mBuf+c,mLines[c],mNumComponents,mBitDepths[c]);  		} @@ -990,96 +1029,100 @@ separation between consecutive rows in the real buffer. */  kdc_flow_control::kdc_flow_control (kdu_image_in_base *img_in, kdu_codestream codestream)  { -    int n; -     -    this->codestream = codestream; -    codestream.get_valid_tiles(valid_tile_indices); -    tile_idx = valid_tile_indices.pos; -    tile = codestream.open_tile(tile_idx,NULL); -     -    // Set up the individual components -    num_components = codestream.get_num_components(true); -    components = new kdc_component_flow_control[num_components]; -    count_delta = 0; -    kdc_component_flow_control *comp = components; -    for (n = 0; n < num_components; n++, comp++) -    { -        comp->line = NULL; -        comp->reader = img_in; -        kdu_coords subsampling;   -        codestream.get_subsampling(n,subsampling,true); -        kdu_dims dims;   -        codestream.get_tile_dims(tile_idx,n,dims,true); -        comp->vert_subsampling = subsampling.y; -        if ((n == 0) || (comp->vert_subsampling < count_delta)) -        { -            count_delta = comp->vert_subsampling; -        } -        comp->ratio_counter = 0; -        comp->remaining_lines = comp->initial_lines = dims.size.y; -    } -    assert(num_components >= 0); -     -    tile.set_components_of_interest(num_components); -    max_buffer_memory = engine.create(codestream,tile,false,NULL,false,1,NULL,NULL,false); +	int n; +	 +	this->codestream = codestream; +	codestream.get_valid_tiles(valid_tile_indices); +	tile_idx = valid_tile_indices.pos; +	tile = codestream.open_tile(tile_idx,NULL); +	 +	// Set up the individual components +	num_components = codestream.get_num_components(true); +	components = new kdc_component_flow_control[num_components]; +	count_delta = 0; +	kdc_component_flow_control *comp = components; +	for (n = 0; n < num_components; n++, comp++) +	{ +		comp->line = NULL; +		comp->reader = img_in; +		kdu_coords subsampling;   +		codestream.get_subsampling(n,subsampling,true); +		kdu_dims dims;   +		codestream.get_tile_dims(tile_idx,n,dims,true); +		comp->vert_subsampling = subsampling.y; +		if ((n == 0) || (comp->vert_subsampling < count_delta)) +		{ +			count_delta = comp->vert_subsampling; +		} +		comp->ratio_counter = 0; +		comp->remaining_lines = comp->initial_lines = dims.size.y; +	} +	assert(num_components >= 0); +	 +	tile.set_components_of_interest(num_components); +	max_buffer_memory = engine.create(codestream,tile,false,NULL,false,1,NULL,NULL,false);  }  kdc_flow_control::~kdc_flow_control()  { -    if (components != NULL) -        delete[] components; -    if (engine.exists()) -        engine.destroy(); +	if (components != NULL) +	{ +		delete[] components; +	} +	if (engine.exists()) +	{ +		engine.destroy(); +	}  }  bool kdc_flow_control::advance_components()  { -    bool found_line = false; -    while (!found_line) -    { -        bool all_done = true; -        kdc_component_flow_control *comp = components; -        for (int n = 0; n < num_components; n++, comp++) -        { -            assert(comp->ratio_counter >= 0); -            if (comp->remaining_lines > 0) -            { -                all_done = false; -                comp->ratio_counter -= count_delta; -                if (comp->ratio_counter < 0) -                { -                    found_line = true; -                    comp->line = engine.exchange_line(n,NULL,NULL); -                    assert(comp->line != NULL); +	bool found_line = false; +	while (!found_line) +	{ +		bool all_done = true; +		kdc_component_flow_control *comp = components; +		for (int n = 0; n < num_components; n++, comp++) +		{ +			assert(comp->ratio_counter >= 0); +			if (comp->remaining_lines > 0) +			{ +				all_done = false; +				comp->ratio_counter -= count_delta; +				if (comp->ratio_counter < 0) +				{ +					found_line = true; +					comp->line = engine.exchange_line(n,NULL,NULL); +					assert(comp->line != NULL);  					if (comp->line->get_width())  					{  						comp->reader->get(n,*(comp->line),0);  					} -                } -            } -        } -        if (all_done) -        { -            return false; -        } -    } -    return true; +				} +			} +		} +		if (all_done) +		{ +			return false; +		} +	} +	return true;  }  void kdc_flow_control::process_components()  { -    kdc_component_flow_control *comp = components; -    for (int n = 0; n < num_components; n++, comp++) -    { -        if (comp->ratio_counter < 0) -        { -            comp->ratio_counter += comp->vert_subsampling; -            assert(comp->ratio_counter >= 0); -            assert(comp->remaining_lines > 0); -            comp->remaining_lines--; -            assert(comp->line != NULL); -            engine.exchange_line(n,comp->line,NULL); -            comp->line = NULL; -        } -    } +	kdc_component_flow_control *comp = components; +	for (int n = 0; n < num_components; n++, comp++) +	{ +		if (comp->ratio_counter < 0) +		{ +			comp->ratio_counter += comp->vert_subsampling; +			assert(comp->ratio_counter >= 0); +			assert(comp->remaining_lines > 0); +			comp->remaining_lines--; +			assert(comp->line != NULL); +			engine.exchange_line(n,comp->line,NULL); +			comp->line = NULL; +		} +	}  } diff --git a/indra/llkdu/llimagej2ckdu.h b/indra/llkdu/llimagej2ckdu.h index 5628f69eeb..9fce58b762 100644 --- a/indra/llkdu/llimagej2ckdu.h +++ b/indra/llkdu/llimagej2ckdu.h @@ -58,17 +58,21 @@ protected:  	/*virtual*/ BOOL decodeImpl(LLImageJ2C &base, LLImageRaw &raw_image, F32 decode_time, S32 first_channel, S32 max_channel_count);  	/*virtual*/ BOOL encodeImpl(LLImageJ2C &base, const LLImageRaw &raw_image, const char* comment_text, F32 encode_time=0.0,  								BOOL reversible=FALSE); +	/*virtual*/ BOOL initDecode(LLImageJ2C &base, LLImageRaw &raw_image, int discard_level = -1, int* region = NULL); +	/*virtual*/ BOOL initEncode(LLImageJ2C &base, LLImageRaw &raw_image, int blocks_size = -1, int precincts_size = -1);  private: +	BOOL initDecode(LLImageJ2C &base, LLImageRaw &raw_image, F32 decode_time, ECodeStreamMode mode, S32 first_channel, S32 max_channel_count, int discard_level = -1, int* region = NULL);  	void setupCodeStream(LLImageJ2C &base, BOOL keep_codestream, ECodeStreamMode mode);  	void cleanupCodeStream(); -	BOOL initDecode(LLImageJ2C &base, LLImageRaw &raw_image, F32 decode_time, ECodeStreamMode mode, S32 first_channel, S32 max_channel_count );  	// Encode variable  	LLKDUMemSource *mInputp;  	kdu_codestream *mCodeStreamp;  	kdu_coords *mTPosp; // tile position  	kdu_dims *mTileIndicesp; +	int mBlocksSize; +	int mPrecinctsSize;  	// Temporary variables for in-progress decodes...  	LLImageRaw *mRawImagep; diff --git a/indra/llkdu/llkdumem.cpp b/indra/llkdu/llkdumem.cpp index 1f549cbbe0..0347475559 100644 --- a/indra/llkdu/llkdumem.cpp +++ b/indra/llkdu/llkdumem.cpp @@ -47,12 +47,12 @@ LLKDUMemIn::LLKDUMemIn(const U8 *data,  	num_components = in_num_components;  	alignment_bytes = 0; -	for (n=0; n<3; ++n) +	for (n = 0; n < 3; ++n)  	{  		precision[n] = 0;  	} -	for (n=0; n < num_components; ++n) +	for (n = 0; n < num_components; ++n)  	{  		siz->set(Sdims,n,0,rows);  		siz->set(Sdims,n,1,cols); @@ -80,12 +80,12 @@ LLKDUMemIn::~LLKDUMemIn()  	}  	image_line_buf *tmp;  	while ((tmp=incomplete_lines) != NULL) -    { +	{  		incomplete_lines = tmp->next;  		delete tmp;   	}  	while ((tmp=free_lines) != NULL) -    { +	{  		free_lines = tmp->next;  		delete tmp;  	} @@ -98,16 +98,16 @@ bool LLKDUMemIn::get(int comp_idx, kdu_line_buf &line, int x_tnum)  	assert((idx >= 0) && (idx < num_components));  	x_tnum = x_tnum*num_components+idx;  	image_line_buf *scan, *prev=NULL; -	for (scan=incomplete_lines; scan != NULL; prev=scan, scan=scan->next) -    { +	for (scan = incomplete_lines; scan != NULL; prev = scan, scan = scan->next) +	{  		assert(scan->next_x_tnum >= x_tnum);  		if (scan->next_x_tnum == x_tnum)  		{  			break;  		} -    } +	}  	if (scan == NULL) -    { // Need to read a new image line. +	{ // Need to read a new image line.  		assert(x_tnum == 0); // Must consume in very specific order.  		if (num_unread_rows == 0)  		{ @@ -134,7 +134,7 @@ bool LLKDUMemIn::get(int comp_idx, kdu_line_buf &line, int x_tnum)  		num_unread_rows--;  		scan->accessed_samples = 0;  		scan->next_x_tnum = 0; -    } +	}  	assert((cols-scan->accessed_samples) >= line.get_width()); @@ -161,7 +161,7 @@ bool LLKDUMemIn::get(int comp_idx, kdu_line_buf &line, int x_tnum)  		}  	}  	else -    { +	{  		kdu_sample16 *dp = line.get_buf16();  		if (line.is_absolute())  		{ // 16-bit absolute integers @@ -177,7 +177,7 @@ bool LLKDUMemIn::get(int comp_idx, kdu_line_buf &line, int x_tnum)  				dp->ival = (((kdu_int16)(*sp)) - 128) << (KDU_FIX_POINT-8);  			}  		} -    } +	}  	scan->next_x_tnum++;  	if (idx == (num_components-1)) diff --git a/indra/llkdu/llkdumem.h b/indra/llkdu/llkdumem.h index 7064de4408..9d923fc367 100644 --- a/indra/llkdu/llkdumem.h +++ b/indra/llkdu/llkdumem.h @@ -39,7 +39,7 @@  class LLKDUMemSource: public kdu_compressed_source  { -public: // Member functions +public:  	LLKDUMemSource(U8 *input_buffer, U32 size)  	{  		mData = input_buffer; @@ -47,11 +47,11 @@ public: // Member functions  		mCurPos = 0;  	} -    ~LLKDUMemSource() +	~LLKDUMemSource()  	{  	} -    int read(kdu_byte *buf, int num_bytes) +	int read(kdu_byte *buf, int num_bytes)  	{  		U32 num_out;  		num_out = num_bytes; @@ -70,7 +70,7 @@ public: // Member functions  		mCurPos = 0;  	} -private: // Data +private:  	U8 *mData;  	U32 mSize;  	U32 mCurPos; @@ -78,7 +78,7 @@ private: // Data  class LLKDUMemTarget: public kdu_compressed_target  { -public: // Member functions +public:  	LLKDUMemTarget(U8 *output_buffer, U32 &output_size, const U32 buffer_size)  	{  		mData = output_buffer; @@ -87,11 +87,11 @@ public: // Member functions  		mOutputSize = &output_size;  	} -    ~LLKDUMemTarget() -    { +	~LLKDUMemTarget() +	{  	} -    bool write(const kdu_byte *buf, int num_bytes) +	bool write(const kdu_byte *buf, int num_bytes)  	{  		U32 num_out;  		num_out = num_bytes; @@ -108,7 +108,7 @@ public: // Member functions  		return true;  	} -private: // Data +private:  	U8 *mData;  	U32 mSize;  	U32 mCurPos; @@ -117,27 +117,27 @@ private: // Data  class LLKDUMemIn : public kdu_image_in_base  { -public: // Member functions -    LLKDUMemIn(const U8 *data, +public: +	LLKDUMemIn(const U8 *data,  				const U32 size,  				const U16 rows,  				const U16 cols,  				U8 in_num_components,  				siz_params *siz); -    ~LLKDUMemIn(); +	~LLKDUMemIn(); -    bool get(int comp_idx, kdu_line_buf &line, int x_tnum); +	bool get(int comp_idx, kdu_line_buf &line, int x_tnum); -private: // Data +private:  	const U8 *mData; -    int first_comp_idx; -    int num_components; -    int rows, cols; -    int alignment_bytes; // Number of 0's at end of each line. -    int precision[3]; -    image_line_buf *incomplete_lines; // Each "sample" represents a full pixel -    image_line_buf *free_lines; -    int num_unread_rows; +	int first_comp_idx; +	int num_components; +	int rows, cols; +	int alignment_bytes; // Number of 0's at end of each line. +	int precision[3]; +	image_line_buf *incomplete_lines; // Each "sample" represents a full pixel +	image_line_buf *free_lines; +	int num_unread_rows;  	U32 mCurPos;  	U32 mDataSize; diff --git a/indra/llui/llloadingindicator.cpp b/indra/llui/llloadingindicator.cpp index 7b29d92ea0..c4eec1835c 100644 --- a/indra/llui/llloadingindicator.cpp +++ b/indra/llui/llloadingindicator.cpp @@ -39,56 +39,24 @@  //static LLDefaultChildRegistry::Register<LLLoadingIndicator> r("loading_indicator");  /////////////////////////////////////////////////////////////////////////////// -// LLLoadingIndicator::Data class +// LLLoadingIndicator class  /////////////////////////////////////////////////////////////////////////////// -/** - * Pre-loaded images shared by all instances of the widget - */ -class LLLoadingIndicator::Data: public LLSingleton<LLLoadingIndicator::Data> +LLLoadingIndicator::LLLoadingIndicator(const Params& p) +:	LLUICtrl(p),  +	mImagesPerSec(p.images_per_sec > 0 ? p.images_per_sec : 1.0f),  +	mCurImageIdx(0)  { -public: -	/*virtual*/ void		initSingleton(); // from LLSingleton - -	LLPointer<LLUIImage>	getNextImage(S8& idx) const; -	U8						getImagesCount() const	{ return NIMAGES; } -private: - -	static const U8			NIMAGES = 12; -	LLPointer<LLUIImage>	mImages[NIMAGES]; -}; +} -// virtual -// Called right after the instance gets constructed. -void LLLoadingIndicator::Data::initSingleton() +void LLLoadingIndicator::initFromParams(const Params& p)  { -	// Load images. -	for (U8 i = 0; i < NIMAGES; ++i) +	for (LLInitParam::ParamIterator<LLUIImage*>::const_iterator it = p.images().image.begin(), end_it = p.images().image.end(); +		it != end_it; +		++it)  	{ -		std::string img_name = llformat("Progress_%d", i+1); -		mImages[i] = LLUI::getUIImage(img_name, 0); -		llassert(mImages[i]); +		mImages.push_back(it->getValue());  	} -} - -LLPointer<LLUIImage> LLLoadingIndicator::Data::getNextImage(S8& idx) const -{ -	// Calculate next index, performing array bounds checking. -	idx = (idx >= NIMAGES || idx < 0) ? 0 : (idx + 1) % NIMAGES;  -	return mImages[idx]; -} - -/////////////////////////////////////////////////////////////////////////////// -// LLLoadingIndicator class -/////////////////////////////////////////////////////////////////////////////// - -LLLoadingIndicator::LLLoadingIndicator(const Params& p) -:	LLUICtrl(p) -	, mRotationsPerSec(p.rotations_per_sec > 0 ? p.rotations_per_sec : 1.0f) -	, mCurImageIdx(-1) -{ -	// Select initial image. -	mCurImagep = Data::instance().getNextImage(mCurImageIdx);  	// Start timer for switching images.  	start(); @@ -100,16 +68,21 @@ void LLLoadingIndicator::draw()  	if (mImageSwitchTimer.getStarted() && mImageSwitchTimer.hasExpired())  	{  		// Switch to the next image. -		mCurImagep = Data::instance().getNextImage(mCurImageIdx); +		if (!mImages.empty()) +		{ +			mCurImageIdx = (mCurImageIdx + 1) % mImages.size(); +		}  		// Restart timer.  		start();  	} +	LLUIImagePtr cur_image = mImages.empty() ? LLUIImagePtr(NULL) : mImages[mCurImageIdx]; +  	// Draw current image. -	if( mCurImagep.notNull() ) +	if( cur_image.notNull() )  	{ -		mCurImagep->draw(getLocalRect(), LLColor4::white % getDrawContext().mAlpha); +		cur_image->draw(getLocalRect(), LLColor4::white % getDrawContext().mAlpha);  	}  	LLUICtrl::draw(); @@ -123,6 +96,6 @@ void LLLoadingIndicator::stop()  void LLLoadingIndicator::start()  {  	mImageSwitchTimer.start(); -	F32 period = 1.0f / (Data::instance().getImagesCount() * mRotationsPerSec); +	F32 period = 1.0f / (mImages.size() * mImagesPerSec);  	mImageSwitchTimer.setTimerExpirySec(period);  } diff --git a/indra/llui/llloadingindicator.h b/indra/llui/llloadingindicator.h index 4e4a224ef6..c0cb1cc74a 100644 --- a/indra/llui/llloadingindicator.h +++ b/indra/llui/llloadingindicator.h @@ -36,8 +36,8 @@  /**   * Perpetual loading indicator (a la MacOSX or YouTube)   *  - * Number of rotations per second can be overriden - * with the "roations_per_sec" parameter. + * Number of rotations per second can be overridden + * with the "images_per_sec" parameter.   *    * Can start/stop spinning.   *  @@ -49,11 +49,24 @@ class LLLoadingIndicator  {  	LOG_CLASS(LLLoadingIndicator);  public: + +	struct Images : public LLInitParam::Block<Images> +	{ +		Multiple<LLUIImage*>	image; + +		Images() +		:	image("image") +		{} +	}; +  	struct Params : public LLInitParam::Block<Params, LLUICtrl::Params>  	{ -		Optional<F32>	rotations_per_sec; +		Optional<F32>			images_per_sec; +		Batch<Images>			images; +  		Params() -		:	rotations_per_sec("rotations_per_sec", 1.0f) +		:	images_per_sec("images_per_sec", 1.0f), +			images("images")  		{}  	}; @@ -74,14 +87,15 @@ public:  private:  	LLLoadingIndicator(const Params&); -	friend class LLUICtrlFactory; +	void initFromParams(const Params&); -	class Data; +	friend class LLUICtrlFactory; -	F32						mRotationsPerSec; +	F32						mImagesPerSec;  	S8						mCurImageIdx; -	LLPointer<LLUIImage>	mCurImagep;  	LLFrameTimer			mImageSwitchTimer; + +	std::vector<LLUIImagePtr> mImages;  };  #endif // LL_LLLOADINGINDICATOR_H diff --git a/indra/llui/llui.cpp b/indra/llui/llui.cpp index 87669574c2..8020ca802b 100644 --- a/indra/llui/llui.cpp +++ b/indra/llui/llui.cpp @@ -1626,8 +1626,8 @@ void LLUI::cleanupClass()  {  	if(sImageProvider)  	{ -		sImageProvider->cleanUp(); -	} +	sImageProvider->cleanUp(); +}  }  void LLUI::setPopupFuncs(const add_popup_t& add_popup, const remove_popup_t& remove_popup,  const clear_popups_t& clear_popups) @@ -2074,32 +2074,32 @@ const LLView* LLUI::resolvePath(const LLView* context, const std::string& path)  namespace LLInitParam  { -	TypedParam<LLUIColor >::TypedParam(BlockDescriptor& descriptor, const char* name, const LLUIColor& value, ParamDescriptor::validation_func_t func, S32 min_count, S32 max_count) -	:	super_t(descriptor, name, value, func, min_count, max_count), +	ParamValue<LLUIColor, TypeValues<LLUIColor> >::ParamValue(const LLUIColor& color) +	:	super_t(color),  		red("red"),  		green("green"),  		blue("blue"),  		alpha("alpha"),  		control("")  	{ -		setBlockFromValue(); +		updateBlockFromValue();  	} -	void TypedParam<LLUIColor>::setValueFromBlock() const +	void ParamValue<LLUIColor, TypeValues<LLUIColor> >::updateValueFromBlock()  	{  		if (control.isProvided())  		{ -			mData.mValue = LLUIColorTable::instance().getColor(control); +			updateValue(LLUIColorTable::instance().getColor(control));  		}  		else  		{ -			mData.mValue = LLColor4(red, green, blue, alpha); +			updateValue(LLColor4(red, green, blue, alpha));  		}  	} -	void TypedParam<LLUIColor>::setBlockFromValue() +	void ParamValue<LLUIColor, TypeValues<LLUIColor> >::updateBlockFromValue()  	{ -		LLColor4 color = mData.mValue.get(); +		LLColor4 color = getValue();  		red.set(color.mV[VRED], false);  		green.set(color.mV[VGREEN], false);  		blue.set(color.mV[VBLUE], false); @@ -2107,38 +2107,32 @@ namespace LLInitParam  		control.set("", false);  	} -	void TypeValues<LLUIColor>::declareValues() -	{ -		declare("white", LLColor4::white); -		declare("black", LLColor4::black); -		declare("red", LLColor4::red); -		declare("green", LLColor4::green); -		declare("blue", LLColor4::blue); -	} -  	bool ParamCompare<const LLFontGL*, false>::equals(const LLFontGL* a, const LLFontGL* b)  	{  		return !(a->getFontDesc() < b->getFontDesc())  			&& !(b->getFontDesc() < a->getFontDesc());  	} -	TypedParam<const LLFontGL*>::TypedParam(BlockDescriptor& descriptor, const char* _name, const LLFontGL*const value, ParamDescriptor::validation_func_t func, S32 min_count, S32 max_count) -	:	super_t(descriptor, _name, value, func, min_count, max_count), +	ParamValue<const LLFontGL*, TypeValues<const LLFontGL*> >::ParamValue(const LLFontGL* fontp) +	:	super_t(fontp),  		name("name"),  		size("size"),  		style("style")  	{ -		setBlockFromValue(); +		if (!fontp) +		{ +			updateValue(LLFontGL::getFontDefault()); +		}  		addSynonym(name, ""); -		setBlockFromValue(); +		updateBlockFromValue();  	} -	void TypedParam<const LLFontGL*>::setValueFromBlock() const +	void ParamValue<const LLFontGL*, TypeValues<const LLFontGL*> >::updateValueFromBlock()  	{  		const LLFontGL* res_fontp = LLFontGL::getFontByName(name);  		if (res_fontp)  		{ -			mData.mValue = res_fontp; +			updateValue(res_fontp);  			return;  		} @@ -2148,22 +2142,26 @@ namespace LLInitParam  		const LLFontGL* fontp = LLFontGL::getFont(desc);  		if (fontp)  		{ -			mData.mValue = fontp; -		}		 +			updateValue(fontp); +		} +		else +		{ +			updateValue(LLFontGL::getFontDefault()); +		}  	} -	void TypedParam<const LLFontGL*>::setBlockFromValue() +	void ParamValue<const LLFontGL*, TypeValues<const LLFontGL*> >::updateBlockFromValue()  	{ -		if (mData.mValue) +		if (getValue())  		{ -			name.set(LLFontGL::nameFromFont(mData.mValue), false); -			size.set(LLFontGL::sizeFromFont(mData.mValue), false); -			style.set(LLFontGL::getStringFromStyle(mData.mValue->getFontDesc().getStyle()), false); +			name.set(LLFontGL::nameFromFont(getValue()), false); +			size.set(LLFontGL::sizeFromFont(getValue()), false); +			style.set(LLFontGL::getStringFromStyle(getValue()->getFontDesc().getStyle()), false);  		}  	} -	TypedParam<LLRect>::TypedParam(BlockDescriptor& descriptor, const char* name, const LLRect& value, ParamDescriptor::validation_func_t func, S32 min_count, S32 max_count) -	:	super_t(descriptor, name, value, func, min_count, max_count), +	ParamValue<LLRect, TypeValues<LLRect> >::ParamValue(const LLRect& rect) +	:	super_t(rect),  		left("left"),  		top("top"),  		right("right"), @@ -2171,10 +2169,10 @@ namespace LLInitParam  		width("width"),  		height("height")  	{ -		setBlockFromValue(); +		updateBlockFromValue();  	} -	void TypedParam<LLRect>::setValueFromBlock() const +	void ParamValue<LLRect, TypeValues<LLRect> >::updateValueFromBlock()  	{  		LLRect rect; @@ -2235,40 +2233,41 @@ namespace LLInitParam  			rect.mBottom = bottom;  			rect.mTop = top;  		} -		mData.mValue = rect; +		updateValue(rect);  	} -	void TypedParam<LLRect>::setBlockFromValue() +	void ParamValue<LLRect, TypeValues<LLRect> >::updateBlockFromValue()  	{  		// because of the ambiguity in specifying a rect by position and/or dimensions  		// we clear the "provided" flag so that values from xui/etc have priority  		// over those calculated from the rect object -		left.set(mData.mValue.mLeft, false); -		right.set(mData.mValue.mRight, false); -		bottom.set(mData.mValue.mBottom, false); -		top.set(mData.mValue.mTop, false); -		width.set(mData.mValue.getWidth(), false); -		height.set(mData.mValue.getHeight(), false); +		LLRect& value = getValue(); +		left.set(value.mLeft, false); +		right.set(value.mRight, false); +		bottom.set(value.mBottom, false); +		top.set(value.mTop, false); +		width.set(value.getWidth(), false); +		height.set(value.getHeight(), false);  	} -	TypedParam<LLCoordGL>::TypedParam(BlockDescriptor& descriptor, const char* name, LLCoordGL value, ParamDescriptor::validation_func_t func, S32 min_count, S32 max_count) -	:	super_t(descriptor, name, value, func, min_count, max_count), +	ParamValue<LLCoordGL, TypeValues<LLCoordGL> >::ParamValue(const LLCoordGL& coord) +	:	super_t(coord),  		x("x"),  		y("y")  	{ -		setBlockFromValue(); +		updateBlockFromValue();  	} -	void TypedParam<LLCoordGL>::setValueFromBlock() const +	void ParamValue<LLCoordGL, TypeValues<LLCoordGL> >::updateValueFromBlock()  	{ -		mData.mValue.set(x, y); +		updateValue(LLCoordGL(x, y));  	} -	void TypedParam<LLCoordGL>::setBlockFromValue() +	void ParamValue<LLCoordGL, TypeValues<LLCoordGL> >::updateBlockFromValue()  	{ -		x.set(mData.mValue.mX, false); -		y.set(mData.mValue.mY, false); +		x.set(getValue().mX, false); +		y.set(getValue().mY, false);  	} diff --git a/indra/llui/llui.h b/indra/llui/llui.h index 50cb9e6632..6a43477693 100644 --- a/indra/llui/llui.h +++ b/indra/llui/llui.h @@ -398,10 +398,10 @@ public:  namespace LLInitParam  {  	template<> -	class TypedParam<LLRect>  -	:	public BlockValue<LLRect> +	class ParamValue<LLRect, TypeValues<LLRect> >  +	:	public CustomParamValue<LLRect>  	{ -        typedef BlockValue<LLRect> super_t; +        typedef CustomParamValue<LLRect> super_t;  	public:  		Optional<S32>	left,  						top, @@ -410,62 +410,43 @@ namespace LLInitParam  						width,  						height; -		TypedParam(BlockDescriptor& descriptor, const char* name, const LLRect& value, ParamDescriptor::validation_func_t func, S32 min_count, S32 max_count); +		ParamValue(const LLRect& value); -		void setValueFromBlock() const; -		void setBlockFromValue(); +		void updateValueFromBlock(); +		void updateBlockFromValue();  	};  	template<> -	struct TypeValues<LLUIColor> : public TypeValuesHelper<LLUIColor> +	class ParamValue<LLUIColor, TypeValues<LLUIColor> >  +	:	public CustomParamValue<LLUIColor>  	{ -		static void declareValues(); -	}; +        typedef CustomParamValue<LLUIColor> super_t; -	template<> -	class TypedParam<LLUIColor>  -	:	public BlockValue<LLUIColor> -	{ -        typedef BlockValue<LLUIColor> super_t;  	public: -		Optional<F32>	red, -						green, -						blue, -						alpha; -		Optional<std::string> control; - -		TypedParam(BlockDescriptor& descriptor, const char* name, const LLUIColor& value, ParamDescriptor::validation_func_t func, S32 min_count, S32 max_count); -		void setValueFromBlock() const; -		void setBlockFromValue(); +		Optional<F32>			red, +								green, +								blue, +								alpha; +		Optional<std::string>	control; + +		ParamValue(const LLUIColor& color); +		void updateValueFromBlock(); +		void updateBlockFromValue();  	}; -	// provide a better default for Optional<const LLFontGL*> than NULL -	template <> -	struct DefaultInitializer<const LLFontGL*> -	{ -		// return reference to a single default instance of T -		// built-in types will be initialized to zero, default constructor otherwise -		static const LLFontGL* get()  -		{  -			static const LLFontGL* sDefaultFont = LLFontGL::getFontDefault();   -			return sDefaultFont; -		}  -	}; - -  	template<> -	class TypedParam<const LLFontGL*>  -	:	public BlockValue<const LLFontGL*> +	class ParamValue<const LLFontGL*, TypeValues<const LLFontGL*> >  +	:	public CustomParamValue<const LLFontGL* >  	{ -        typedef BlockValue<const LLFontGL*> super_t; +        typedef CustomParamValue<const LLFontGL*> super_t;  	public:  		Optional<std::string>	name,  								size,  								style; -		TypedParam(BlockDescriptor& descriptor, const char* name, const LLFontGL* const value, ParamDescriptor::validation_func_t func, S32 min_count, S32 max_count); -		void setValueFromBlock() const; -		void setBlockFromValue(); +		ParamValue(const LLFontGL* value); +		void updateValueFromBlock(); +		void updateBlockFromValue();  	};  	template<> @@ -494,17 +475,17 @@ namespace LLInitParam  	template<> -	class TypedParam<LLCoordGL> -	:	public BlockValue<LLCoordGL> +	class ParamValue<LLCoordGL, TypeValues<LLCoordGL> > +	:	public CustomParamValue<LLCoordGL>  	{ -		typedef BlockValue<LLCoordGL> super_t; +		typedef CustomParamValue<LLCoordGL> super_t;  	public:  		Optional<S32>	x,  						y; -		TypedParam(BlockDescriptor& descriptor, const char* name, LLCoordGL value, ParamDescriptor::validation_func_t func, S32 min_count, S32 max_count); -		void setValueFromBlock() const; -		void setBlockFromValue(); +		ParamValue(const LLCoordGL& val); +		void updateValueFromBlock(); +		void updateBlockFromValue();  	};  } diff --git a/indra/llui/lluiimage.cpp b/indra/llui/lluiimage.cpp index 1ffad4806e..f37947a50b 100644 --- a/indra/llui/lluiimage.cpp +++ b/indra/llui/lluiimage.cpp @@ -155,32 +155,32 @@ void LLUIImage::onImageLoaded()  namespace LLInitParam  { -	void TypedParam<LLUIImage*>::setValueFromBlock() const +	void ParamValue<LLUIImage*, TypeValues<LLUIImage*> >::updateValueFromBlock()  	{  		// The keyword "none" is specifically requesting a null image  		// do not default to current value. Used to overwrite template images.   		if (name() == "none")  		{ -			mData.mValue = NULL; +			updateValue(NULL);  			return;  		}  		LLUIImage* imagep =  LLUI::getUIImage(name());  		if (imagep)  		{ -			mData.mValue = imagep; +			updateValue(imagep);  		}  	} -	void TypedParam<LLUIImage*>::setBlockFromValue() +	void ParamValue<LLUIImage*, TypeValues<LLUIImage*> >::updateBlockFromValue()  	{ -		if (mData.mValue == NULL) +		if (getValue() == NULL)  		{  			name.set("none", false);  		}  		else  		{ -			name.set(mData.mValue->getName(), false); +			name.set(getValue()->getName(), false);  		}  	} diff --git a/indra/llui/lluiimage.h b/indra/llui/lluiimage.h index 38107c112d..139d88e0ac 100644 --- a/indra/llui/lluiimage.h +++ b/indra/llui/lluiimage.h @@ -92,22 +92,23 @@ protected:  namespace LLInitParam  {  	template<> -	class TypedParam<LLUIImage*, TypeValues<LLUIImage*>, false>  -	:	public BlockValue<LLUIImage*> +	class ParamValue<LLUIImage*, TypeValues<LLUIImage*> >  +	:	public CustomParamValue<LLUIImage*>  	{  		typedef boost::add_reference<boost::add_const<LLUIImage*>::type>::type	T_const_ref; -		typedef BlockValue<LLUIImage*> super_t; +		typedef CustomParamValue<LLUIImage*> super_t;  	public:  		Optional<std::string> name; -		TypedParam(BlockDescriptor& descriptor, const char* name, super_t::value_assignment_t value, ParamDescriptor::validation_func_t func, S32 min_count, S32 max_count) -		:	super_t(descriptor, name, value, func, min_count, max_count) +		ParamValue(LLUIImage* const& image) +		:	super_t(image)  		{ -			setBlockFromValue(); +			updateBlockFromValue(); +			addSynonym(name, "name");  		} -		void setValueFromBlock() const; -		void setBlockFromValue(); +		void updateValueFromBlock(); +		void updateBlockFromValue();  	};  	// Need custom comparison function for our test app, which only loads diff --git a/indra/llui/tests/llurlentry_stub.cpp b/indra/llui/tests/llurlentry_stub.cpp index ac2412c928..75946b2416 100644 --- a/indra/llui/tests/llurlentry_stub.cpp +++ b/indra/llui/tests/llurlentry_stub.cpp @@ -114,32 +114,30 @@ namespace LLInitParam  		const U8* block_addr = reinterpret_cast<const U8*>(enclosing_block);  		mEnclosingBlockOffset = (U16)(my_addr - block_addr);  	} -	void BaseBlock::setLastChangedParam(const Param& last_param, bool user_provided) {} +	void BaseBlock::paramChanged(const Param& last_param, bool user_provided) {} -	void BaseBlock::addParam(BlockDescriptor& block_data, const ParamDescriptor& in_param, const char* char_name){} +	void BaseBlock::addParam(BlockDescriptor& block_data, const ParamDescriptorPtr in_param, const char* char_name){} +	void BaseBlock::addSynonym(Param& param, const std::string& synonym) {}  	param_handle_t BaseBlock::getHandleFromParam(const Param* param) const {return 0;}  	void BaseBlock::init(BlockDescriptor& descriptor, BlockDescriptor& base_descriptor, size_t block_size)  	{  		descriptor.mCurrentBlockPtr = this;  	} -	bool BaseBlock::deserializeBlock(Parser& p, Parser::name_stack_range_t name_stack){ return true; } -	bool BaseBlock::serializeBlock(Parser& parser, Parser::name_stack_t name_stack, const LLInitParam::BaseBlock* diff_block) const { return true; } -	bool BaseBlock::inspectBlock(Parser& parser, Parser::name_stack_t name_stack) const { return true; } +	bool BaseBlock::deserializeBlock(Parser& p, Parser::name_stack_range_t name_stack, S32 generation){ return true; } +	void BaseBlock::serializeBlock(Parser& parser, Parser::name_stack_t name_stack, const LLInitParam::BaseBlock* diff_block) const {} +	bool BaseBlock::inspectBlock(Parser& parser, Parser::name_stack_t name_stack, S32 min_value, S32 max_value) const { return true; }  	bool BaseBlock::merge(BlockDescriptor& block_data, const BaseBlock& other, bool overwrite) { return true; }  	bool BaseBlock::validateBlock(bool emit_errors) const { return true; } -	TypedParam<LLUIColor >::TypedParam(BlockDescriptor& descriptor, const char* name, const LLUIColor& value, ParamDescriptor::validation_func_t func, S32 min_count, S32 max_count) -	:	super_t(descriptor, name, value, func, min_count, max_count) +	ParamValue<LLUIColor, TypeValues<LLUIColor> >::ParamValue(const LLUIColor& color) +	:	super_t(color)  	{} -	void TypedParam<LLUIColor>::setValueFromBlock() const +	void ParamValue<LLUIColor, TypeValues<LLUIColor> >::updateValueFromBlock()   	{} -	void TypedParam<LLUIColor>::setBlockFromValue() -	{} - -	void TypeValues<LLUIColor>::declareValues() +	void ParamValue<LLUIColor, TypeValues<LLUIColor> >::updateBlockFromValue()  	{}  	bool ParamCompare<const LLFontGL*, false>::equals(const LLFontGL* a, const LLFontGL* b) @@ -147,14 +145,14 @@ namespace LLInitParam  		return false;  	} -	TypedParam<const LLFontGL*>::TypedParam(BlockDescriptor& descriptor, const char* _name, const LLFontGL*const value, ParamDescriptor::validation_func_t func, S32 min_count, S32 max_count) -	:	super_t(descriptor, _name, value, func, min_count, max_count) +	ParamValue<const LLFontGL*, TypeValues<const LLFontGL*> >::ParamValue(const LLFontGL* fontp) +	:	super_t(fontp)  	{} -	void TypedParam<const LLFontGL*>::setValueFromBlock() const +	void ParamValue<const LLFontGL*, TypeValues<const LLFontGL*> >::updateValueFromBlock()  	{} -	void TypedParam<const LLFontGL*>::setBlockFromValue() +	void ParamValue<const LLFontGL*, TypeValues<const LLFontGL*> >::updateBlockFromValue()  	{}  	void TypeValues<LLFontGL::HAlign>::declareValues() @@ -166,10 +164,10 @@ namespace LLInitParam  	void TypeValues<LLFontGL::ShadowType>::declareValues()  	{} -	void TypedParam<LLUIImage*>::setValueFromBlock() const +	void ParamValue<LLUIImage*, TypeValues<LLUIImage*> >::updateValueFromBlock()  	{} -	void TypedParam<LLUIImage*>::setBlockFromValue() +	void ParamValue<LLUIImage*, TypeValues<LLUIImage*> >::updateBlockFromValue()  	{} diff --git a/indra/llui/tests/llurlentry_test.cpp b/indra/llui/tests/llurlentry_test.cpp index 8f0a48018f..2f814f4200 100644 --- a/indra/llui/tests/llurlentry_test.cpp +++ b/indra/llui/tests/llurlentry_test.cpp @@ -70,6 +70,22 @@ S32 LLUIImage::getHeight() const  	return 0;  } +namespace LLInitParam +{ +	S32 Parser::sNextParseGeneration = 0; +	BlockDescriptor::BlockDescriptor() {} +	ParamDescriptor::ParamDescriptor(param_handle_t p,  +						merge_func_t merge_func,  +						deserialize_func_t deserialize_func,  +						serialize_func_t serialize_func, +						validation_func_t validation_func, +						inspect_func_t inspect_func, +						S32 min_count, +						S32 max_count){} +	ParamDescriptor::~ParamDescriptor() {} + +} +  namespace tut  {  	struct LLUrlEntryData diff --git a/indra/llui/tests/llurlmatch_test.cpp b/indra/llui/tests/llurlmatch_test.cpp index fdaab00f18..aea605c9f2 100644 --- a/indra/llui/tests/llurlmatch_test.cpp +++ b/indra/llui/tests/llurlmatch_test.cpp @@ -66,11 +66,25 @@ namespace LLInitParam  	BaseBlock::BaseBlock() {}  	BaseBlock::~BaseBlock() {} -	void BaseBlock::setLastChangedParam(const Param& last_param, bool user_provided) {} - -	void BaseBlock::addParam(BlockDescriptor& block_data, const ParamDescriptor& in_param, const char* char_name){} +	S32 Parser::sNextParseGeneration = 0; + +	BlockDescriptor::BlockDescriptor() {} +	ParamDescriptor::ParamDescriptor(param_handle_t p,  +						merge_func_t merge_func,  +						deserialize_func_t deserialize_func,  +						serialize_func_t serialize_func, +						validation_func_t validation_func, +						inspect_func_t inspect_func, +						S32 min_count, +						S32 max_count){} +	ParamDescriptor::~ParamDescriptor() {} + +	void BaseBlock::paramChanged(const Param& last_param, bool user_provided) {} + +	void BaseBlock::addParam(BlockDescriptor& block_data, const ParamDescriptorPtr in_param, const char* char_name){}  	param_handle_t BaseBlock::getHandleFromParam(const Param* param) const {return 0;} -	 +	void BaseBlock::addSynonym(Param& param, const std::string& synonym) {} +  	void BaseBlock::init(BlockDescriptor& descriptor, BlockDescriptor& base_descriptor, size_t block_size)  	{  		descriptor.mCurrentBlockPtr = this; @@ -84,23 +98,20 @@ namespace LLInitParam  		mEnclosingBlockOffset = (U16)(my_addr - block_addr);  	} -	bool BaseBlock::deserializeBlock(Parser& p, Parser::name_stack_range_t name_stack){ return true; } -	bool BaseBlock::serializeBlock(Parser& parser, Parser::name_stack_t name_stack, const LLInitParam::BaseBlock* diff_block) const { return true; } -	bool BaseBlock::inspectBlock(Parser& parser, Parser::name_stack_t name_stack) const { return true; } +	bool BaseBlock::deserializeBlock(Parser& p, Parser::name_stack_range_t name_stack, S32 generation){ return true; } +	void BaseBlock::serializeBlock(Parser& parser, Parser::name_stack_t name_stack, const LLInitParam::BaseBlock* diff_block) const {} +	bool BaseBlock::inspectBlock(Parser& parser, Parser::name_stack_t name_stack, S32 min_count, S32 max_count) const { return true; }  	bool BaseBlock::merge(BlockDescriptor& block_data, const BaseBlock& other, bool overwrite) { return true; }  	bool BaseBlock::validateBlock(bool emit_errors) const { return true; } -	TypedParam<LLUIColor >::TypedParam(BlockDescriptor& descriptor, const char* name, const LLUIColor& value, ParamDescriptor::validation_func_t func, S32 min_count, S32 max_count) -	:	super_t(descriptor, name, value, func, min_count, max_count) +	ParamValue<LLUIColor, TypeValues<LLUIColor> >::ParamValue(const LLUIColor& color) +	:	super_t(color)  	{} -	void TypedParam<LLUIColor>::setValueFromBlock() const +	void ParamValue<LLUIColor, TypeValues<LLUIColor> >::updateValueFromBlock()  	{} -	void TypedParam<LLUIColor>::setBlockFromValue() -	{} - -	void TypeValues<LLUIColor>::declareValues() +	void ParamValue<LLUIColor, TypeValues<LLUIColor> >::updateBlockFromValue()  	{}  	bool ParamCompare<const LLFontGL*, false>::equals(const LLFontGL* a, const LLFontGL* b) @@ -108,14 +119,15 @@ namespace LLInitParam  		return false;  	} -	TypedParam<const LLFontGL*>::TypedParam(BlockDescriptor& descriptor, const char* _name, const LLFontGL*const value, ParamDescriptor::validation_func_t func, S32 min_count, S32 max_count) -	:	super_t(descriptor, _name, value, func, min_count, max_count) + +	ParamValue<const LLFontGL*, TypeValues<const LLFontGL*> >::ParamValue(const LLFontGL* fontp) +	:	super_t(fontp)  	{} -	void TypedParam<const LLFontGL*>::setValueFromBlock() const +	void ParamValue<const LLFontGL*, TypeValues<const LLFontGL*> >::updateValueFromBlock()  	{} -	void TypedParam<const LLFontGL*>::setBlockFromValue() +	void ParamValue<const LLFontGL*, TypeValues<const LLFontGL*> >::updateBlockFromValue()  	{}  	void TypeValues<LLFontGL::HAlign>::declareValues() @@ -127,10 +139,10 @@ namespace LLInitParam  	void TypeValues<LLFontGL::ShadowType>::declareValues()  	{} -	void TypedParam<LLUIImage*>::setValueFromBlock() const +	void ParamValue<LLUIImage*, TypeValues<LLUIImage*> >::updateValueFromBlock()  	{} -	void TypedParam<LLUIImage*>::setBlockFromValue() +	void ParamValue<LLUIImage*, TypeValues<LLUIImage*> >::updateBlockFromValue()  	{}  	bool ParamCompare<LLUIImage*, false>::equals( diff --git a/indra/llxuixml/llinitparam.cpp b/indra/llxuixml/llinitparam.cpp index fcdbaa4309..3c4eb70a5d 100644 --- a/indra/llxuixml/llinitparam.cpp +++ b/indra/llxuixml/llinitparam.cpp @@ -44,8 +44,51 @@ namespace LLInitParam  	}  	// +	// ParamDescriptor +	// +	ParamDescriptor::ParamDescriptor(param_handle_t p,  +									merge_func_t merge_func,  +									deserialize_func_t deserialize_func,  +									serialize_func_t serialize_func, +									validation_func_t validation_func, +									inspect_func_t inspect_func, +									S32 min_count, +									S32 max_count) +	:	mParamHandle(p), +		mMergeFunc(merge_func), +		mDeserializeFunc(deserialize_func), +		mSerializeFunc(serialize_func), +		mValidationFunc(validation_func), +		mInspectFunc(inspect_func), +		mMinCount(min_count), +		mMaxCount(max_count), +		mGeneration(0), +		mUserData(NULL) +	{} + +	ParamDescriptor::ParamDescriptor() +	:	mParamHandle(0), +		mMergeFunc(NULL), +		mDeserializeFunc(NULL), +		mSerializeFunc(NULL), +		mValidationFunc(NULL), +		mInspectFunc(NULL), +		mMinCount(0), +		mMaxCount(0), +		mGeneration(0), +		mUserData(NULL) +	{} + +	ParamDescriptor::~ParamDescriptor() +	{ +		delete mUserData; +	} + +	//  	// Parser  	// +	S32 Parser::sNextParseGeneration = 0; +  	Parser::~Parser()  	{} @@ -73,6 +116,12 @@ namespace LLInitParam  		std::copy(src_block_data.mAllParams.begin(), src_block_data.mAllParams.end(), std::back_inserter(mAllParams));  	} +	BlockDescriptor::BlockDescriptor() +	:	mMaxParamOffset(0), +		mInitializationState(UNINITIALIZED), +		mCurrentBlockPtr(NULL) +	{} +  	//  	// BaseBlock  	// @@ -115,7 +164,7 @@ namespace LLInitParam  	bool BaseBlock::submitValue(const Parser::name_stack_t& name_stack, Parser& p, bool silent)  	{ -		if (!deserializeBlock(p, std::make_pair(name_stack.begin(), name_stack.end()))) +		if (!deserializeBlock(p, std::make_pair(name_stack.begin(), name_stack.end()), -1))  		{  			if (!silent)  			{ @@ -145,7 +194,7 @@ namespace LLInitParam  		return true;  	} -	bool BaseBlock::serializeBlock(Parser& parser, Parser::name_stack_t name_stack, const LLInitParam::BaseBlock* diff_block) const +	void BaseBlock::serializeBlock(Parser& parser, Parser::name_stack_t name_stack, const LLInitParam::BaseBlock* diff_block) const  	{  		// named param is one like LLView::Params::follows  		// unnamed param is like LLView::Params::rect - implicit @@ -212,11 +261,9 @@ namespace LLInitParam  				name_stack.pop_back();  			}  		} - -		return true;  	} -	bool BaseBlock::inspectBlock(Parser& parser, Parser::name_stack_t name_stack) const +	bool BaseBlock::inspectBlock(Parser& parser, Parser::name_stack_t name_stack, S32 min_count, S32 max_count) const  	{  		// named param is one like LLView::Params::follows  		// unnamed param is like LLView::Params::rect - implicit @@ -273,11 +320,13 @@ namespace LLInitParam  		return true;  	} -	bool BaseBlock::deserializeBlock(Parser& p, Parser::name_stack_range_t name_stack) +	bool BaseBlock::deserializeBlock(Parser& p, Parser::name_stack_range_t name_stack, S32 parent_generation)  	{  		BlockDescriptor& block_data = mostDerivedBlockDescriptor();  		bool names_left = name_stack.first != name_stack.second; +		S32 parse_generation = name_stack.first == name_stack.second ? -1 : name_stack.first->second; +  		if (names_left)  		{  			const std::string& top_name = name_stack.first->first; @@ -294,7 +343,7 @@ namespace LLInitParam  				Parser::name_stack_range_t new_name_stack(name_stack.first, name_stack.second);  				++new_name_stack.first; -				return deserialize_func(*paramp, p, new_name_stack, name_stack.first == name_stack.second ? -1 : name_stack.first->second); +				return deserialize_func(*paramp, p, new_name_stack, parse_generation);  			}  		} @@ -306,7 +355,7 @@ namespace LLInitParam  			Param* paramp = getParamFromHandle((*it)->mParamHandle);  			ParamDescriptor::deserialize_func_t deserialize_func = (*it)->mDeserializeFunc; -			if (deserialize_func && deserialize_func(*paramp, p, name_stack, name_stack.first == name_stack.second ? -1 : name_stack.first->second)) +			if (deserialize_func && deserialize_func(*paramp, p, name_stack, parse_generation))  			{  				return true;  			} @@ -324,32 +373,32 @@ namespace LLInitParam  	}  	//static  -	void BaseBlock::addParam(BlockDescriptor& block_data, const ParamDescriptor& in_param, const char* char_name) +	void BaseBlock::addParam(BlockDescriptor& block_data, const ParamDescriptorPtr in_param, const char* char_name)  	{  		// create a copy of the paramdescriptor in allparams  		// so other data structures can store a pointer to it  		block_data.mAllParams.push_back(in_param); -		ParamDescriptor& param(block_data.mAllParams.back()); +		ParamDescriptorPtr param(block_data.mAllParams.back());  		std::string name(char_name); -		if ((size_t)param.mParamHandle > block_data.mMaxParamOffset) +		if ((size_t)param->mParamHandle > block_data.mMaxParamOffset)  		{  			llerrs << "Attempted to register param with block defined for parent class, make sure to derive from LLInitParam::Block<YOUR_CLASS, PARAM_BLOCK_BASE_CLASS>" << llendl;  		}  		if (name.empty())  		{ -			block_data.mUnnamedParams.push_back(¶m); +			block_data.mUnnamedParams.push_back(param);  		}  		else  		{  			// don't use insert, since we want to overwrite existing entries -			block_data.mNamedParams[name] = ¶m; +			block_data.mNamedParams[name] = param;  		} -		if (param.mValidationFunc) +		if (param->mValidationFunc)  		{ -			block_data.mValidationList.push_back(std::make_pair(param.mParamHandle, param.mValidationFunc)); +			block_data.mValidationList.push_back(std::make_pair(param->mParamHandle, param->mValidationFunc));  		}  	} @@ -367,7 +416,7 @@ namespace LLInitParam  				llerrs << "Attempted to register param with block defined for parent class, make sure to derive from LLInitParam::Block<YOUR_CLASS, PARAM_BLOCK_BASE_CLASS>" << llendl;  			} -			ParamDescriptor* param_descriptor = findParamDescriptor(handle); +			ParamDescriptorPtr param_descriptor = findParamDescriptor(param);  			if (param_descriptor)  			{  				if (synonym.empty()) @@ -382,7 +431,7 @@ namespace LLInitParam  		}  	} -	void BaseBlock::setLastChangedParam(const Param& last_param, bool user_provided) +	void BaseBlock::paramChanged(const Param& changed_param, bool user_provided)  	{   		if (user_provided)  		{ @@ -404,17 +453,18 @@ namespace LLInitParam  		return LLStringUtil::null;  	} -	ParamDescriptor* BaseBlock::findParamDescriptor(param_handle_t handle) +	ParamDescriptorPtr BaseBlock::findParamDescriptor(const Param& param)  	{ +		param_handle_t handle = getHandleFromParam(¶m);  		BlockDescriptor& descriptor = mostDerivedBlockDescriptor();  		BlockDescriptor::all_params_list_t::iterator end_it = descriptor.mAllParams.end();  		for (BlockDescriptor::all_params_list_t::iterator it = descriptor.mAllParams.begin();  			it != end_it;  			++it)  		{ -			if (it->mParamHandle == handle) return &(*it); +			if ((*it)->mParamHandle == handle) return *it;  		} -		return NULL; +		return ParamDescriptorPtr();  	}  	// take all provided params from other and apply to self @@ -427,19 +477,14 @@ namespace LLInitParam  			it != end_it;  			++it)  		{ -			const Param* other_paramp = other.getParamFromHandle(it->mParamHandle); -			ParamDescriptor::merge_func_t merge_func = it->mMergeFunc; +			const Param* other_paramp = other.getParamFromHandle((*it)->mParamHandle); +			ParamDescriptor::merge_func_t merge_func = (*it)->mMergeFunc;  			if (merge_func)  			{ -				Param* paramp = getParamFromHandle(it->mParamHandle); +				Param* paramp = getParamFromHandle((*it)->mParamHandle);  				some_param_changed |= merge_func(*paramp, *other_paramp, overwrite);  			}  		}  		return some_param_changed;  	} - -	bool ParamCompare<LLSD, false>::equals(const LLSD &a, const LLSD &b) -	{ -		return false; -	}  } diff --git a/indra/llxuixml/llinitparam.h b/indra/llxuixml/llinitparam.h index 1f9045754a..858f8405b4 100644 --- a/indra/llxuixml/llinitparam.h +++ b/indra/llxuixml/llinitparam.h @@ -1,5 +1,5 @@  /**  -f * @file llinitparam.h + * @file llinitparam.h   * @brief parameter block abstraction for creating complex objects and    * parsing construction parameters from xml and LLSD   * @@ -29,18 +29,14 @@ f * @file llinitparam.h  #define LL_LLPARAM_H  #include <vector> - -#include <stddef.h>  #include <boost/function.hpp> -#include <boost/bind.hpp>  #include <boost/type_traits/is_convertible.hpp>  #include <boost/unordered_map.hpp> -#include "llregistry.h" -#include "llmemory.h" - +#include <boost/shared_ptr.hpp>  namespace LLInitParam  { +	template<typename T> const T& defaultValue() { static T value; return value; }  	template <typename T, bool IS_BOOST_FUNCTION = boost::is_convertible<T, boost::function_base>::value >      struct ParamCompare  @@ -61,122 +57,119 @@ namespace LLInitParam  		}  	}; -	// default constructor adaptor for InitParam Values -	// constructs default instances of the given type, returned by const reference -	template <typename T> -	struct DefaultInitializer +	template<>  +	struct ParamCompare<LLSD, false>  	{ -		typedef const T&			T_const_ref; -		// return reference to a single default instance of T -		// built-in types will be initialized to zero, default constructor otherwise -		static T_const_ref get() { static T t = T(); return t; }  +		static bool equals(const LLSD &a, const LLSD &b) { return false; }  	};  	// helper functions and classes  	typedef ptrdiff_t param_handle_t; +	// empty default implementation of key cache +	// leverages empty base class optimization  	template <typename T>  	class TypeValues  	{  	public: -		// empty default implemenation of key cache -		class KeyCache +		typedef std::map<std::string, T> value_name_map_t; + +		void setValueName(const std::string& key) {} +		std::string getValueName() const { return ""; } +		void clearValueName() const {} + +		static bool getValueFromName(const std::string& name, T& value)  		{ -		public: -			void setKey(const std::string& key) {} -			std::string getKey() const { return ""; } -			void clearKey(){} -		}; +			return false; +		} -		static bool get(const std::string& name, T& value) +		static bool valueNamesExist()  		{  			return false;  		} -		static bool empty() +		static std::vector<std::string>* getPossibleValues()  		{ -			return true; +			return NULL;  		} -		static std::vector<std::string>* getPossibleValues() { return NULL; } +		static value_name_map_t* getValueNames() {return NULL;}  	};  	template <typename T, typename DERIVED_TYPE = TypeValues<T> >  	class TypeValuesHelper -	:	public LLRegistrySingleton<std::string, T, DERIVED_TYPE >  	{ -		typedef LLRegistrySingleton<std::string, T, DERIVED_TYPE>	super_t; -		typedef LLSingleton<DERIVED_TYPE>							singleton_t;  	public: +		typedef typename std::map<std::string, T> value_name_map_t;  		//TODO: cache key by index to save on param block size -		class KeyCache +		void setValueName(const std::string& value_name)   		{ -		public: -			void setKey(const std::string& key)  -			{ -				mKey = key;  -			} - -			void clearKey() -			{ -				mKey = ""; -			} +			mValueName = value_name;  +		} -			std::string getKey() const -			{  -				return mKey;  -			} +		std::string getValueName() const +		{  +			return mValueName;  +		} -		private: -			std::string mKey; -		}; +		void clearValueName() const +		{ +			mValueName.clear(); +		} -		static bool get(const std::string& name, T& value) +		static bool getValueFromName(const std::string& name, T& value)  		{ -			if (!singleton_t::instance().exists(name)) return false; +			value_name_map_t* map = getValueNames(); +			typename value_name_map_t::iterator found_it = map->find(name); +			if (found_it == map->end()) return false; -			value = *singleton_t::instance().getValue(name); +			value = found_it->second;  			return true;  		} -		static bool empty() +		static bool valueNamesExist()  		{ -			return singleton_t::instance().LLRegistry<std::string, T>::empty(); +			return !getValueNames()->empty();  		} -		//override this to add name value pairs -		static void declareValues() {} -	 -		void initSingleton() +		static value_name_map_t* getValueNames()  		{ -			DERIVED_TYPE::declareValues(); -		} +			static value_name_map_t sMap; +			static bool sInitialized = false; -		static const std::vector<std::string>* getPossibleValues()  -		{  -			// in order to return a pointer to a member, we lazily -			// evaluate the result and store it in mValues here -			if (singleton_t::instance().mValues.empty()) +			if (!sInitialized)  			{ -				typename super_t::Registrar::registry_map_t::const_iterator it; -				for (it = super_t::defaultRegistrar().beginItems(); it != super_t::defaultRegistrar().endItems(); ++it) -				{ -					singleton_t::instance().mValues.push_back(it->first); -				} +				sInitialized = true; +				DERIVED_TYPE::declareValues();  			} -			return &singleton_t::instance().mValues;  +			return &sMap;  		} +		static std::vector<std::string>* getPossibleValues() +		{ +			static std::vector<std::string> sValues; + +			value_name_map_t* map = getValueNames(); +			for (typename value_name_map_t::iterator it = map->begin(), end_it = map->end(); +				 it != end_it; +				 ++it) +			{ +				sValues.push_back(it->first); +			} +			return &sValues; +		} -	protected:  		static void declare(const std::string& name, const T& value)  		{ -			super_t::defaultRegistrar().add(name, value); +			(*getValueNames())[name] = value;  		} -	private: -		std::vector<std::string> mValues; +	protected: +		static void getName(const std::string& name, const T& value) +		{} + +		mutable std::string	mValueName;  	};  	class Parser @@ -193,9 +186,9 @@ namespace LLInitParam  			}  		}; -		typedef std::vector<std::pair<std::string, S32> >			name_stack_t; +		typedef std::vector<std::pair<std::string, S32> >								name_stack_t;  		typedef std::pair<name_stack_t::const_iterator, name_stack_t::const_iterator>	name_stack_range_t; -		typedef std::vector<std::string>							possible_values_t; +		typedef std::vector<std::string>												possible_values_t;  		typedef bool (*parser_read_func_t)(Parser& parser, void* output);  		typedef bool (*parser_write_func_t)(Parser& parser, const void*, const name_stack_t&); @@ -207,7 +200,7 @@ namespace LLInitParam  		Parser(parser_read_func_map_t& read_map, parser_write_func_map_t& write_map, parser_inspect_func_map_t& inspect_map)  		:	mParseSilently(false), -			mParseGeneration(0), +			mParseGeneration(sNextParseGeneration),  			mParserReadFuncs(&read_map),  			mParserWriteFuncs(&write_map),  			mParserInspectFuncs(&inspect_map) @@ -252,7 +245,7 @@ namespace LLInitParam  		void setParseSilently(bool silent) { mParseSilently = silent; }  		S32 getParseGeneration() { return mParseGeneration; } -		S32 newParseGeneration() { return ++mParseGeneration; } +		S32 newParseGeneration() { return mParseGeneration = ++sNextParseGeneration; }  	protected: @@ -276,6 +269,8 @@ namespace LLInitParam  		parser_write_func_map_t*	mParserWriteFuncs;  		parser_inspect_func_map_t*	mParserInspectFuncs;  		S32	mParseGeneration; + +		static S32					sNextParseGeneration;  	};  	// used to indicate no matching value to a given name when parsing @@ -295,12 +290,13 @@ namespace LLInitParam  		Param(class BaseBlock* enclosing_block);  		// store pointer to enclosing block as offset to reduce space and allow for quick copying -		BaseBlock& enclosingBlock() const +		class BaseBlock& enclosingBlock() const  		{   			const U8* my_addr = reinterpret_cast<const U8*>(this);  			// get address of enclosing BLOCK class using stored offset to enclosing BaseBlock class -			return *const_cast<BaseBlock*>( -							reinterpret_cast<const BaseBlock*>(my_addr - (ptrdiff_t)(S32)mEnclosingBlockOffset)); +			return *const_cast<class BaseBlock*> +				(reinterpret_cast<const class BaseBlock*> +					(my_addr - (ptrdiff_t)(S32)mEnclosingBlockOffset));  		}  	private: @@ -313,7 +309,11 @@ namespace LLInitParam  	// various callbacks and constraints associated with an individual param  	struct ParamDescriptor  	{ -	public: +		struct UserData +		{ +			virtual ~UserData() {} +		}; +  		typedef bool(*merge_func_t)(Param&, const Param&, bool);  		typedef bool(*deserialize_func_t)(Param&, Parser&, const Parser::name_stack_range_t&, S32);  		typedef void(*serialize_func_t)(const Param&, Parser&, Parser::name_stack_t&, const Param* diff_param); @@ -321,40 +321,18 @@ namespace LLInitParam  		typedef bool(*validation_func_t)(const Param*);  		ParamDescriptor(param_handle_t p,  -				merge_func_t merge_func,  -				deserialize_func_t deserialize_func,  -				serialize_func_t serialize_func, -				validation_func_t validation_func, -				inspect_func_t inspect_func, -				S32 min_count, -				S32 max_count) -		:	mParamHandle(p), -			mMergeFunc(merge_func), -			mDeserializeFunc(deserialize_func), -			mSerializeFunc(serialize_func), -			mValidationFunc(validation_func), -			mInspectFunc(inspect_func), -			mMinCount(min_count), -			mMaxCount(max_count), -			mGeneration(0), -			mNumRefs(0) -		{} +						merge_func_t merge_func,  +						deserialize_func_t deserialize_func,  +						serialize_func_t serialize_func, +						validation_func_t validation_func, +						inspect_func_t inspect_func, +						S32 min_count, +						S32 max_count); -		ParamDescriptor() -		:	mParamHandle(0), -			mMergeFunc(NULL), -			mDeserializeFunc(NULL), -			mSerializeFunc(NULL), -			mValidationFunc(NULL), -			mInspectFunc(NULL), -			mMinCount(0), -			mMaxCount(0), -			mGeneration(0), -			mNumRefs(0) -		{} +		ParamDescriptor(); +		~ParamDescriptor();  		param_handle_t		mParamHandle; -	  		merge_func_t		mMergeFunc;  		deserialize_func_t	mDeserializeFunc;  		serialize_func_t	mSerializeFunc; @@ -364,17 +342,16 @@ namespace LLInitParam  		S32					mMaxCount;  		S32					mGeneration;  		S32					mNumRefs; +		UserData*			mUserData;  	}; +	typedef boost::shared_ptr<ParamDescriptor> ParamDescriptorPtr; +  	// each derived Block class keeps a static data structure maintaining offsets to various params  	class BlockDescriptor  	{  	public: -		BlockDescriptor() -		:	mMaxParamOffset(0), -			mInitializationState(UNINITIALIZED), -			mCurrentBlockPtr(NULL) -		{} +		BlockDescriptor();  		typedef enum e_initialization_state  		{ @@ -385,12 +362,10 @@ namespace LLInitParam  		void aggregateBlockData(BlockDescriptor& src_block_data); -	public: -		typedef boost::unordered_map<const std::string, ParamDescriptor*> param_map_t; // references param descriptors stored in mAllParams -		typedef std::vector<ParamDescriptor*> param_list_t;  - -		typedef std::list<ParamDescriptor> all_params_list_t;// references param descriptors stored in mAllParams -		typedef std::vector<std::pair<param_handle_t, ParamDescriptor::validation_func_t> > param_validation_list_t; +		typedef boost::unordered_map<const std::string, ParamDescriptorPtr>						param_map_t;  +		typedef std::vector<ParamDescriptorPtr>													param_list_t;  +		typedef std::list<ParamDescriptorPtr>														all_params_list_t; +		typedef std::vector<std::pair<param_handle_t, ParamDescriptor::validation_func_t> >		param_validation_list_t;  		param_map_t						mNamedParams;			// parameters with associated names  		param_list_t					mUnnamedParams;			// parameters with_out_ associated names @@ -456,6 +431,7 @@ namespace LLInitParam  		Param* getParamFromHandle(const param_handle_t param_handle)  		{  			if (param_handle == 0) return NULL; +  			U8* baseblock_address = reinterpret_cast<U8*>(this);  			return reinterpret_cast<Param*>(baseblock_address + param_handle);  		} @@ -469,14 +445,13 @@ namespace LLInitParam  		void addSynonym(Param& param, const std::string& synonym);  		// Blocks can override this to do custom tracking of changes -		virtual void setLastChangedParam(const Param& last_param, bool user_provided); +		virtual void paramChanged(const Param& changed_param, bool user_provided);  		S32 getLastChangeVersion() const { return mChangeVersion; } -		bool isDefault() const { return mChangeVersion == 0; } -		bool deserializeBlock(Parser& p, Parser::name_stack_range_t name_stack); -		bool serializeBlock(Parser& p, Parser::name_stack_t name_stack = Parser::name_stack_t(), const BaseBlock* diff_block = NULL) const; -		bool inspectBlock(Parser& p, Parser::name_stack_t name_stack = Parser::name_stack_t()) const; +		bool deserializeBlock(Parser& p, Parser::name_stack_range_t name_stack, S32 generation); +		void serializeBlock(Parser& p, Parser::name_stack_t name_stack = Parser::name_stack_t(), const BaseBlock* diff_block = NULL) const; +		bool inspectBlock(Parser& p, Parser::name_stack_t name_stack = Parser::name_stack_t(), S32 min_count = 0, S32 max_count = S32_MAX) const;  		virtual const BlockDescriptor& mostDerivedBlockDescriptor() const { return selfBlockDescriptor(); }  		virtual BlockDescriptor& mostDerivedBlockDescriptor() { return selfBlockDescriptor(); } @@ -493,7 +468,10 @@ namespace LLInitParam  			return false;  		} -		static void addParam(BlockDescriptor& block_data, const ParamDescriptor& param, const char* name); +		static void addParam(BlockDescriptor& block_data, ParamDescriptorPtr param, const char* name); + +		ParamDescriptorPtr findParamDescriptor(const Param& param); +  	protected:  		void init(BlockDescriptor& descriptor, BlockDescriptor& base_descriptor, size_t block_size); @@ -512,63 +490,133 @@ namespace LLInitParam  	private:  		const std::string& getParamName(const BlockDescriptor& block_data, const Param* paramp) const; -		ParamDescriptor* findParamDescriptor(param_handle_t handle); -	}; - - -	template<typename T> -	struct ParamIterator -	{ -		typedef typename std::vector<T>::const_iterator		const_iterator; -		typedef typename std::vector<T>::iterator			iterator;  	};  	// these templates allow us to distinguish between template parameters  	// that derive from BaseBlock and those that don't -	// this is supposedly faster than boost::is_convertible and its ilk  	template<typename T, typename Void = void> -	struct IsBaseBlock +	struct IsBlock  	{  		static const bool value = false;  	};  	template<typename T> -	struct IsBaseBlock<T, typename T::baseblock_base_class_t> +	struct IsBlock<T, typename T::baseblock_base_class_t>  	{  		static const bool value = true;  	}; +	template<typename T, typename NAME_VALUE_LOOKUP, bool VALUE_IS_BLOCK = IsBlock<T>::value> +	class ParamValue : public NAME_VALUE_LOOKUP +	{ +	public: +		typedef const T&							value_assignment_t; + +		ParamValue(): mValue() {} +		ParamValue(const T& other) : mValue(other) {} + +		void setValue(value_assignment_t val) +		{ +			mValue = val; +		} + +		value_assignment_t getValue() const +		{ +			return mValue; +		} + +		T& getValue() +		{ +			return mValue; +		} + +	private: +		T mValue; +	}; + +	template<typename T, typename NAME_VALUE_LOOKUP> +	class ParamValue<T, NAME_VALUE_LOOKUP, true>  +	:	public T, +		public NAME_VALUE_LOOKUP +	{ +	public: +		typedef const T&							value_assignment_t; + +		S32 			mKeyVersion; +		mutable S32 	mValidatedVersion; +		mutable bool 	mValidated; // lazy validation flag + +		ParamValue()  +		:	T(), +			mKeyVersion(0), +			mValidatedVersion(-1), +			mValidated(false) +		{} + +		ParamValue(const T& other) +		:	T(other), +			mKeyVersion(0), +			mValidatedVersion(-1), +			mValidated(false) +		{ +		} + +		void setValue(value_assignment_t val) +		{ +			*this = val; +		} + +		value_assignment_t getValue() const +		{ +			return *this; +		} + +		T& getValue() +		{ +			return *this; +		} +	}; + +	template<typename T, typename NAME_VALUE_LOOKUP = TypeValues<T> > +	struct ParamIterator +	{ +		typedef typename std::vector<ParamValue<T, NAME_VALUE_LOOKUP> >::const_iterator		const_iterator; +		typedef typename std::vector<ParamValue<T, NAME_VALUE_LOOKUP> >::iterator			iterator; +	}; +  	// specialize for custom parsing/decomposition of specific classes  	// e.g. TypedParam<LLRect> has left, top, right, bottom, etc...  	template<typename	T,  			typename	NAME_VALUE_LOOKUP = TypeValues<T>,  			bool		HAS_MULTIPLE_VALUES = false, -			bool		VALUE_IS_BLOCK = IsBaseBlock<T>::value> +			bool		VALUE_IS_BLOCK = IsBlock<ParamValue<T, NAME_VALUE_LOOKUP> >::value>  	class TypedParam  -	:	public Param +	:	public Param,  +		public ParamValue<T, NAME_VALUE_LOOKUP>  	{  	public: -		typedef const T&																	value_const_ref_t; -		typedef value_const_ref_t															value_assignment_t; -		typedef typename NAME_VALUE_LOOKUP::KeyCache										key_cache_t; +		typedef const T&																	value_assignment_t;  		typedef	TypedParam<T, NAME_VALUE_LOOKUP, HAS_MULTIPLE_VALUES, VALUE_IS_BLOCK>		self_t; +		typedef NAME_VALUE_LOOKUP															name_value_lookup_t; +		typedef ParamValue<T, NAME_VALUE_LOOKUP>											param_value_t;  		TypedParam(BlockDescriptor& block_descriptor, const char* name, value_assignment_t value, ParamDescriptor::validation_func_t validate_func, S32 min_count, S32 max_count)   		:	Param(block_descriptor.mCurrentBlockPtr)  		{  			if (LL_UNLIKELY(block_descriptor.mInitializationState == BlockDescriptor::INITIALIZING))  			{ -				ParamDescriptor param_descriptor(block_descriptor.mCurrentBlockPtr->getHandleFromParam(this), + 				ParamDescriptorPtr param_descriptor = ParamDescriptorPtr(new ParamDescriptor( +												block_descriptor.mCurrentBlockPtr->getHandleFromParam(this),  												&mergeWith,  												&deserializeParam,  												&serializeParam,  												validate_func,  												&inspectParam, -												min_count, max_count); +												min_count, max_count));  				BaseBlock::addParam(block_descriptor, param_descriptor, name);  			} -			mData.mValue = value; +			setValue(value);  		}   		bool isProvided() const { return Param::anyProvided(); } @@ -579,27 +627,27 @@ namespace LLInitParam  			// no further names in stack, attempt to parse value now  			if (name_stack.first == name_stack.second)  			{ -				if (parser.readValue(typed_param.mData.mValue)) +				if (parser.readValue(typed_param.getValue()))  				{ -					typed_param.mData.clearKey(); +					typed_param.clearValueName();  					typed_param.setProvided(true); -					typed_param.enclosingBlock().setLastChangedParam(param, true); +					typed_param.enclosingBlock().paramChanged(param, true);  					return true;  				}  				// try to parse a known named value -				if(!NAME_VALUE_LOOKUP::empty()) +				if(name_value_lookup_t::valueNamesExist())  				{  					// try to parse a known named value  					std::string name;  					if (parser.readValue(name))  					{  						// try to parse a per type named value -						if (NAME_VALUE_LOOKUP::get(name, typed_param.mData.mValue)) +						if (name_value_lookup_t::getValueFromName(name, typed_param.getValue()))  						{ -							typed_param.mData.setKey(name); +							typed_param.setValueName(name);  							typed_param.setProvided(true); -							typed_param.enclosingBlock().setLastChangedParam(param, true); +							typed_param.enclosingBlock().paramChanged(param, true);  							return true;  						} @@ -619,13 +667,13 @@ namespace LLInitParam  				name_stack.back().second = parser.newParseGeneration();  			} -			std::string key = typed_param.mData.getKey(); +			std::string key = typed_param.getValueName();  			// first try to write out name of name/value pair  			if (!key.empty())  			{ -				if (!diff_param || !ParamCompare<std::string>::equals(static_cast<const self_t*>(diff_param)->mData.getKey(), key)) +				if (!diff_param || !ParamCompare<std::string>::equals(static_cast<const self_t*>(diff_param)->getValueName(), key))  				{  					if (!parser.writeValue(key, name_stack))  					{ @@ -634,8 +682,9 @@ namespace LLInitParam  				}  			}  			// then try to serialize value directly -			else if (!diff_param || !ParamCompare<T>::equals(typed_param.get(), static_cast<const self_t*>(diff_param)->get()))					{ -				if (!parser.writeValue(typed_param.mData.mValue, name_stack))  +			else if (!diff_param || !ParamCompare<T>::equals(typed_param.getValue(), static_cast<const self_t*>(diff_param)->getValue())) +			{ +				if (!parser.writeValue(typed_param.getValue(), name_stack))   				{  					return;  				} @@ -647,18 +696,18 @@ namespace LLInitParam  			// tell parser about our actual type  			parser.inspectValue<T>(name_stack, min_count, max_count, NULL);  			// then tell it about string-based alternatives ("red", "blue", etc. for LLColor4) -			if (NAME_VALUE_LOOKUP::getPossibleValues()) +			if (name_value_lookup_t::getPossibleValues())  			{ -				parser.inspectValue<std::string>(name_stack, min_count, max_count, NAME_VALUE_LOOKUP::getPossibleValues()); +				parser.inspectValue<std::string>(name_stack, min_count, max_count, name_value_lookup_t::getPossibleValues());  			}  		}  		void set(value_assignment_t val, bool flag_as_provided = true)  		{ -			mData.mValue = val; -			mData.clearKey(); +			setValue(val); +			param_value_t::clearValueName();  			setProvided(flag_as_provided); -			Param::enclosingBlock().setLastChangedParam(*this, flag_as_provided); +			Param::enclosingBlock().paramChanged(*this, flag_as_provided);  		}  		void setIfNotProvided(value_assignment_t val, bool flag_as_provided = true) @@ -670,65 +719,56 @@ namespace LLInitParam  		}  		// implicit conversion -		operator value_assignment_t() const { return get(); }  +		operator value_assignment_t() const { return param_value_t::getValue(); }   		// explicit conversion -		value_assignment_t operator()() const { return get(); }  +		value_assignment_t operator()() const { return param_value_t::getValue(); }   	protected: -		value_assignment_t get() const -		{ -			return mData.mValue; -		}  		static bool mergeWith(Param& dst, const Param& src, bool overwrite)  		{  			const self_t& src_typed_param = static_cast<const self_t&>(src);  			self_t& dst_typed_param = static_cast<self_t&>(dst); +  			if (src_typed_param.isProvided()  				&& (overwrite || !dst_typed_param.isProvided()))  			{ -				dst_typed_param.mData.clearKey(); -				dst_typed_param.set(src_typed_param.get()); +				dst_typed_param.clearValueName(); +				dst_typed_param.set(src_typed_param.getValue());  				return true;  			}  			return false;  		} - -		struct Data : public key_cache_t -		{ -			T mValue; -		}; - -		Data		mData;  	};  	// parameter that is a block  	template <typename T, typename NAME_VALUE_LOOKUP>  	class TypedParam<T, NAME_VALUE_LOOKUP, false, true>  -	:	public T, -		public Param +	:	public Param, +		public ParamValue<T, NAME_VALUE_LOOKUP>  	{  	public:  		typedef const T											value_const_t;  		typedef T												value_t; -		typedef value_const_t&									value_const_ref_t; -		typedef value_const_ref_t								value_assignment_t; -		typedef typename NAME_VALUE_LOOKUP::KeyCache			key_cache_t; +		typedef value_const_t&									value_assignment_t;  		typedef TypedParam<T, NAME_VALUE_LOOKUP, false, true>	self_t; +		typedef NAME_VALUE_LOOKUP								name_value_lookup_t; +		typedef ParamValue<T, NAME_VALUE_LOOKUP>				param_value_t;  		TypedParam(BlockDescriptor& block_descriptor, const char* name, value_assignment_t value, ParamDescriptor::validation_func_t validate_func, S32 min_count, S32 max_count)  		:	Param(block_descriptor.mCurrentBlockPtr), -			T(value) +			param_value_t(value)  		{  			if (LL_UNLIKELY(block_descriptor.mInitializationState == BlockDescriptor::INITIALIZING))  			{ -				ParamDescriptor param_descriptor(block_descriptor.mCurrentBlockPtr->getHandleFromParam(this), +				ParamDescriptorPtr param_descriptor = ParamDescriptorPtr(new ParamDescriptor( +												block_descriptor.mCurrentBlockPtr->getHandleFromParam(this),  												&mergeWith,  												&deserializeParam,  												&serializeParam,  												validate_func,   												&inspectParam, -												min_count, max_count); +												min_count, max_count));  				BaseBlock::addParam(block_descriptor, param_descriptor, name);  			}  		} @@ -737,25 +777,27 @@ namespace LLInitParam  		{   			self_t& typed_param = static_cast<self_t&>(param);  			// attempt to parse block... -			if(typed_param.deserializeBlock(parser, name_stack)) +			if(typed_param.deserializeBlock(parser, name_stack, generation))  			{ -				typed_param.mData.clearKey(); -				typed_param.enclosingBlock().setLastChangedParam(param, true); +				typed_param.clearValueName(); +				typed_param.enclosingBlock().paramChanged(param, true); +				typed_param.setProvided(true);  				return true;  			} -			if(!NAME_VALUE_LOOKUP::empty()) +			if(name_value_lookup_t::valueNamesExist())  			{  				// try to parse a known named value  				std::string name;  				if (parser.readValue(name))  				{  					// try to parse a per type named value -					if (NAME_VALUE_LOOKUP::get(name, typed_param)) +					if (name_value_lookup_t::getValueFromName(name, typed_param.getValue()))  					{ -						typed_param.enclosingBlock().setLastChangedParam(param, true); -						typed_param.mData.setKey(name); -						typed_param.mData.mKeyVersion = typed_param.getLastChangeVersion(); +						typed_param.enclosingBlock().paramChanged(param, true); +						typed_param.setValueName(name); +						typed_param.setProvided(true); +						typed_param.mKeyVersion = typed_param.getLastChangeVersion();  						return true;  					} @@ -767,13 +809,15 @@ namespace LLInitParam  		static void serializeParam(const Param& param, Parser& parser, Parser::name_stack_t& name_stack, const Param* diff_param)  		{  			const self_t& typed_param = static_cast<const self_t&>(param); +			if (!typed_param.isProvided()) return; +  			if (!name_stack.empty())  			{  				name_stack.back().second = parser.newParseGeneration();  			} -			std::string key = typed_param.mData.getKey(); -			if (!key.empty() && typed_param.mData.mKeyVersion == typed_param.getLastChangeVersion()) +			std::string key = typed_param.getValueName(); +			if (!key.empty() && typed_param.mKeyVersion == typed_param.getLastChangeVersion())  			{  				if (!parser.writeValue(key, name_stack))  				{ @@ -790,33 +834,33 @@ namespace LLInitParam  		{  			// I am a param that is also a block, so just recurse into my contents  			const self_t& typed_param = static_cast<const self_t&>(param); -			typed_param.inspectBlock(parser, name_stack); +			typed_param.inspectBlock(parser, name_stack, min_count, max_count);  		}  		// a param-that-is-a-block is provided when the user has set one of its child params  		// *and* the block as a whole validates  		bool isProvided() const   		{  -			// only validate block when it hasn't already passed validation and user has supplied *some* value -			if (Param::anyProvided() && mData.mValidatedVersion < T::getLastChangeVersion()) +			// only validate block when it hasn't already passed validation with current data +			if (Param::anyProvided() && param_value_t::mValidatedVersion < param_value_t::getLastChangeVersion())  			{  				// a sub-block is "provided" when it has been filled in enough to be valid -				mData.mValidated = T::validateBlock(false); -				mData.mValidatedVersion = T::getLastChangeVersion(); +				param_value_t::mValidated = param_value_t::validateBlock(false); +				param_value_t::mValidatedVersion = param_value_t::getLastChangeVersion();  			} -			return Param::anyProvided() && mData.mValidated; +			return Param::anyProvided() && param_value_t::mValidated;  		}  		// assign block contents to this param-that-is-a-block  		void set(value_assignment_t val, bool flag_as_provided = true)  		{ -			value_t::operator=(val); -			mData.clearKey(); +			setValue(val); +			param_value_t::clearValueName();  			// force revalidation of block by clearing known provided version  			// next call to isProvided() will update provision status based on validity -			mData.mValidatedVersion = 0; +			param_value_t::mValidatedVersion = -1;  			setProvided(flag_as_provided); -			Param::enclosingBlock().setLastChangedParam(*this, flag_as_provided); +			Param::enclosingBlock().paramChanged(*this, flag_as_provided);  		}  		void setIfNotProvided(value_assignment_t val, bool flag_as_provided = true) @@ -828,10 +872,10 @@ namespace LLInitParam  		}  		// propagate changed status up to enclosing block -		/*virtual*/ void setLastChangedParam(const Param& last_param, bool user_provided) +		/*virtual*/ void paramChanged(const Param& changed_param, bool user_provided)  		{  -			T::setLastChangedParam(last_param, user_provided); -			Param::enclosingBlock().setLastChangedParam(*this, user_provided); +			ParamValue<T, NAME_VALUE_LOOKUP>::paramChanged(changed_param, user_provided); +			Param::enclosingBlock().paramChanged(*this, user_provided);  			if (user_provided)  			{  				// a child param has been explicitly changed @@ -841,41 +885,28 @@ namespace LLInitParam  		}  		// implicit conversion -		operator value_assignment_t() const { return get(); }  +		operator value_assignment_t() const { return param_value_t::getValue(); }   		// explicit conversion -		value_assignment_t operator()() const { return get(); }  +		value_assignment_t operator()() const { return param_value_t::getValue(); }   	protected: -		value_assignment_t get() const -		{ -			return *this; -		}  		static bool mergeWith(Param& dst, const Param& src, bool overwrite)  		{  			const self_t& src_typed_param = static_cast<const self_t&>(src);  			self_t& dst_typed_param = static_cast<self_t&>(dst); -			if (dst_typed_param.T::merge(T::selfBlockDescriptor(), src_typed_param, overwrite)) + +			if (src_typed_param.isProvided() +				&& (overwrite || !dst_typed_param.isProvided()))  			{ -				dst_typed_param.mData.clearKey(); -				return true; +				if (dst_typed_param.merge(param_value_t::selfBlockDescriptor(), src_typed_param, overwrite)) +				{ +					dst_typed_param.clearValueName(); +					return true; +				}  			}  			return false;  		} - -		struct Data : public key_cache_t -		{ -			S32 			mKeyVersion; -			mutable S32 	mValidatedVersion; -			mutable bool 	mValidated; // lazy validation flag - -			Data()  -			:	mKeyVersion(0), -				mValidatedVersion(0), -				mValidated(false) -			{} -		}; -		Data	mData;  	};  	// container of non-block parameters @@ -885,29 +916,28 @@ namespace LLInitParam  	{  	public:  		typedef TypedParam<VALUE_TYPE, NAME_VALUE_LOOKUP, true, false>		self_t; -		typedef typename std::vector<VALUE_TYPE>							container_t; +		typedef ParamValue<VALUE_TYPE, NAME_VALUE_LOOKUP>			param_value_t; +		typedef typename std::vector<param_value_t>							container_t;  		typedef const container_t&											value_assignment_t;  		typedef VALUE_TYPE													value_t; -		typedef value_t&													value_ref_t; -		typedef const value_t&												value_const_ref_t; +		typedef NAME_VALUE_LOOKUP											name_value_lookup_t; -		typedef typename NAME_VALUE_LOOKUP::KeyCache						key_cache_t; -  		TypedParam(BlockDescriptor& block_descriptor, const char* name, value_assignment_t value, ParamDescriptor::validation_func_t validate_func, S32 min_count, S32 max_count)  -		:	Param(block_descriptor.mCurrentBlockPtr), -			mValues(value) +		:	Param(block_descriptor.mCurrentBlockPtr)  		{ -			mCachedKeys.resize(mValues.size()); +			std::copy(value.begin(), value.end(), std::back_inserter(mValues)); +  			if (LL_UNLIKELY(block_descriptor.mInitializationState == BlockDescriptor::INITIALIZING))  			{ -				ParamDescriptor param_descriptor(block_descriptor.mCurrentBlockPtr->getHandleFromParam(this), +				ParamDescriptorPtr param_descriptor = ParamDescriptorPtr(new ParamDescriptor( +												block_descriptor.mCurrentBlockPtr->getHandleFromParam(this),  												&mergeWith,  												&deserializeParam,  												&serializeParam,  												validate_func,  												&inspectParam, -												min_count, max_count); +												min_count, max_count));  				BaseBlock::addParam(block_descriptor, param_descriptor, name);  			}  		}  @@ -924,29 +954,22 @@ namespace LLInitParam  				// attempt to read value directly  				if (parser.readValue(value))  				{ -					typed_param.mValues.push_back(value); -					// save an empty name/value key as a placeholder -					typed_param.mCachedKeys.push_back(key_cache_t()); -					typed_param.enclosingBlock().setLastChangedParam(param, true); -					typed_param.setProvided(true); +					typed_param.add(value);  					return true;  				}  				// try to parse a known named value -				if(!NAME_VALUE_LOOKUP::empty()) +				if(name_value_lookup_t::valueNamesExist())  				{  					// try to parse a known named value  					std::string name;  					if (parser.readValue(name))  					{  						// try to parse a per type named value -						if (NAME_VALUE_LOOKUP::get(name, typed_param.mValues)) +						if (name_value_lookup_t::getValueFromName(name, typed_param.mValues))  						{ -							typed_param.mValues.push_back(value); -							typed_param.mCachedKeys.push_back(key_cache_t()); -							typed_param.mCachedKeys.back().setKey(name); -							typed_param.enclosingBlock().setLastChangedParam(param, true); -							typed_param.setProvided(true); +							typed_param.add(value); +							typed_param.mValues.back().setValueName(name);  							return true;  						} @@ -961,25 +984,27 @@ namespace LLInitParam  			const self_t& typed_param = static_cast<const self_t&>(param);  			if (!typed_param.isProvided() || name_stack.empty()) return; -			const_iterator it = typed_param.mValues.begin(); -			for (typename std::vector<key_cache_t>::const_iterator key_it = typed_param.mCachedKeys.begin(); -				it != typed_param.mValues.end(); -				++key_it, ++it) +			for (const_iterator it = typed_param.mValues.begin(), end_it = typed_param.mValues.end(); +				it != end_it; +				++it)  			{ -				std::string key = key_it->get(); +				std::string key = it->getValue();  				name_stack.back().second = parser.newParseGeneration(); -				if(!key.empty()) +				if(key.empty()) +				// not parsed via name values, write out value directly  				{ -					if(!parser.writeValue(key, name_stack)) +					if (!parser.writeValue(*it, name_stack))  					{ -						return; +						break;  					}  				} -				// not parse via name values, write out value directly -				else if (!parser.writeValue(*it, name_stack)) +				else   				{ -					return; +					if(!parser.writeValue(key, name_stack)) +					{ +						break; +					}  				}  			}  		} @@ -987,19 +1012,17 @@ namespace LLInitParam  		static void inspectParam(const Param& param, Parser& parser, Parser::name_stack_t& name_stack, S32 min_count, S32 max_count)  		{  			parser.inspectValue<VALUE_TYPE>(name_stack, min_count, max_count, NULL); -			if (NAME_VALUE_LOOKUP::getPossibleValues()) +			if (name_value_lookup_t::getPossibleValues())  			{ -				parser.inspectValue<std::string>(name_stack, min_count, max_count, NAME_VALUE_LOOKUP::getPossibleValues()); +				parser.inspectValue<std::string>(name_stack, min_count, max_count, name_value_lookup_t::getPossibleValues());  			}  		}  		void set(value_assignment_t val, bool flag_as_provided = true)  		{  			mValues = val; -			mCachedKeys.clear(); -			mCachedKeys.resize(mValues.size());  			setProvided(flag_as_provided); -			Param::enclosingBlock().setLastChangedParam(*this, flag_as_provided); +			Param::enclosingBlock().paramChanged(*this, flag_as_provided);  		} @@ -1011,23 +1034,23 @@ namespace LLInitParam  			}  		} -		value_ref_t add() +		value_t& add()  		{ -			mValues.push_back(value_t()); -			mCachedKeys.push_back(key_cache_t()); +			mValues.push_back(param_value_t(value_t()));  			setProvided(true); +			Param::enclosingBlock().paramChanged(*this, true);  			return mValues.back();  		} -		void add(value_const_ref_t item) +		void add(const value_t& item)  		{ -			mValues.push_back(item); -			mCachedKeys.push_back(key_cache_t()); +			mValues.push_back(param_value_t(item));  			setProvided(true); +			Param::enclosingBlock().paramChanged(*this, true);  		}  		// implicit conversion -		operator value_assignment_t() const { return self_t::get(); }  +		operator value_assignment_t() const { return mValues; }   		typedef typename container_t::iterator iterator;  		typedef typename container_t::const_iterator const_iterator; @@ -1044,27 +1067,25 @@ namespace LLInitParam  		}  	protected: -		value_assignment_t get() const -		{ -			return mValues; -		} -  		static bool mergeWith(Param& dst, const Param& src, bool overwrite)  		{  			const self_t& src_typed_param = static_cast<const self_t&>(src);  			self_t& dst_typed_param = static_cast<self_t&>(dst); -			if (src_typed_param.isProvided() -				&& (overwrite || !dst_typed_param.isProvided())) +			if (overwrite)  			{ -				dst_typed_param.set(src_typed_param.get()); -				return true; +				std::copy(src_typed_param.begin(), src_typed_param.end(), std::back_inserter(dst_typed_param.mValues));  			} -			return false; +			else +			{ +				container_t new_values(src_typed_param.mValues); +				std::copy(dst_typed_param.begin(), dst_typed_param.end(), std::back_inserter(new_values)); +				std::swap(dst_typed_param.mValues, new_values); +			} +			return true;  		}  		container_t		mValues; -		std::vector<key_cache_t>	mCachedKeys;  	};  	// container of block parameters @@ -1074,80 +1095,76 @@ namespace LLInitParam  	{  	public:  		typedef TypedParam<VALUE_TYPE, NAME_VALUE_LOOKUP, true, true>	self_t; -		typedef typename std::vector<VALUE_TYPE>						container_t; +		typedef ParamValue<VALUE_TYPE, NAME_VALUE_LOOKUP>				param_value_t; +		typedef typename std::vector<param_value_t>						container_t;  		typedef const container_t&										value_assignment_t; -  		typedef VALUE_TYPE												value_t; -		typedef value_t&												value_ref_t; -		typedef const value_t&											value_const_ref_t; - -		typedef typename NAME_VALUE_LOOKUP::KeyCache					key_cache_t; +		typedef NAME_VALUE_LOOKUP										name_value_lookup_t;  		TypedParam(BlockDescriptor& block_descriptor, const char* name, value_assignment_t value, ParamDescriptor::validation_func_t validate_func, S32 min_count, S32 max_count)   		:	Param(block_descriptor.mCurrentBlockPtr), -			mValues(value), -			mLastParamGeneration(0) +			mLastParseGeneration(0)  		{ -			mCachedKeys.resize(mValues.size()); +			std::copy(value.begin(), value.end(), back_inserter(mValues)); +  			if (LL_UNLIKELY(block_descriptor.mInitializationState == BlockDescriptor::INITIALIZING))  			{ -				ParamDescriptor param_descriptor(block_descriptor.mCurrentBlockPtr->getHandleFromParam(this), +				ParamDescriptorPtr param_descriptor = ParamDescriptorPtr(new ParamDescriptor( +												block_descriptor.mCurrentBlockPtr->getHandleFromParam(this),  												&mergeWith,  												&deserializeParam,  												&serializeParam,  												validate_func,  												&inspectParam, -												min_count, max_count); +												min_count, max_count));  				BaseBlock::addParam(block_descriptor, param_descriptor, name);  			}  		}   		bool isProvided() const { return Param::anyProvided(); } -		value_ref_t operator[](S32 index) { return mValues[index]; } -		value_const_ref_t operator[](S32 index) const { return mValues[index]; } -  		static bool deserializeParam(Param& param, Parser& parser, const Parser::name_stack_range_t& name_stack, S32 generation)   		{   			self_t& typed_param = static_cast<self_t&>(param);  			bool new_value = false; -			if (generation != typed_param.mLastParamGeneration || typed_param.mValues.empty()) + +			if (generation != typed_param.mLastParseGeneration  +				|| typed_param.mValues.empty())  			{  				new_value = true;  				typed_param.mValues.push_back(value_t()); -				typed_param.mCachedKeys.push_back(Data());  			} -			value_ref_t value = typed_param.mValues.back(); +			param_value_t& value = typed_param.mValues.back();  			// attempt to parse block... -			if(value.deserializeBlock(parser, name_stack)) +			if(value.deserializeBlock(parser, name_stack, generation))  			{  				if (new_value)  				{	// successfully parsed new value, let's keep it -					typed_param.mLastParamGeneration = generation; +					typed_param.mLastParseGeneration = generation;  				} -				typed_param.enclosingBlock().setLastChangedParam(param, true); +				typed_param.enclosingBlock().paramChanged(param, true);  				typed_param.setProvided(true);  				return true;  			} -			else if(!NAME_VALUE_LOOKUP::empty()) +			else if(name_value_lookup_t::valueNamesExist())  			{  				// try to parse a known named value  				std::string name;  				if (parser.readValue(name))  				{  					// try to parse a per type named value -					if (NAME_VALUE_LOOKUP::get(name, value)) +					if (name_value_lookup_t::getValueFromName(name, value.getValue()))  					{  						if (new_value)  						{	// successfully parsed new value, let's keep it -							typed_param.mLastParamGeneration = generation; +							typed_param.mLastParseGeneration = generation;  						} -						typed_param.mCachedKeys.back().setKey(name); -						typed_param.mCachedKeys.back().mKeyVersion = value.getLastChangeVersion(); -						typed_param.enclosingBlock().setLastChangedParam(param, true); +						typed_param.mValues.back().setValueName(name); +						typed_param.mValues.back().mKeyVersion = value.getLastChangeVersion(); +						typed_param.enclosingBlock().paramChanged(param, true);  						typed_param.setProvided(true);  						return true;  					} @@ -1158,7 +1175,6 @@ namespace LLInitParam  			if (new_value)  			{	// failed to parse new value, pop it off  				typed_param.mValues.pop_back(); -				typed_param.mCachedKeys.pop_back();  			}  			return false; @@ -1169,26 +1185,22 @@ namespace LLInitParam  			const self_t& typed_param = static_cast<const self_t&>(param);  			if (!typed_param.isProvided() || name_stack.empty()) return; -			const_iterator it = typed_param.mValues.begin(); -			for (typename std::vector<Data>::const_iterator key_it = typed_param.mCachedKeys.begin(); -				it != typed_param.mValues.end(); -				++key_it, ++it) +			for (const_iterator it = typed_param.mValues.begin(), end_it = typed_param.mValues.end(); +				it != end_it; +				++it)  			{  				name_stack.back().second = parser.newParseGeneration(); -				std::string key = key_it->getKey(); -				if (!key.empty() && key_it->mKeyVersion == it->getLastChangeVersion()) +				std::string key = it->getValueName(); +				if (!key.empty() && it->mKeyVersion == it->getLastChangeVersion())  				{ -					if(!parser.writeValue(key, name_stack)) -					{ -						return; -					} +					parser.writeValue(key, name_stack);  				}  				// Not parsed via named values, write out value directly  				// NOTE: currently we don't worry about removing default values in Multiple -				else if (!it->serializeBlock(parser, name_stack, NULL)) +				else   				{ -					return; +					it->serializeBlock(parser, name_stack, NULL);  				}  			}  		} @@ -1196,16 +1208,14 @@ namespace LLInitParam  		static void inspectParam(const Param& param, Parser& parser, Parser::name_stack_t& name_stack, S32 min_count, S32 max_count)  		{  			// I am a vector of blocks, so describe my contents recursively -			value_t().inspectBlock(parser, name_stack); +			param_value_t(value_t()).inspectBlock(parser, name_stack, min_count, max_count);  		}  		void set(value_assignment_t val, bool flag_as_provided = true)  		{  			mValues = val; -			mCachedKeys.clear(); -			mCachedKeys.resize(mValues.size());  			setProvided(flag_as_provided); -			Param::enclosingBlock().setLastChangedParam(*this, flag_as_provided); +			Param::enclosingBlock().paramChanged(*this, flag_as_provided);  		}  		void setIfNotProvided(value_assignment_t val, bool flag_as_provided = true) @@ -1216,23 +1226,23 @@ namespace LLInitParam  			}  		} -		value_ref_t add() +		value_t& add()  		{  			mValues.push_back(value_t()); -			mCachedKeys.push_back(Data());  			setProvided(true); +			Param::enclosingBlock().paramChanged(*this, true);  			return mValues.back();  		} -		void add(value_const_ref_t item) +		void add(const value_t& item)  		{  			mValues.push_back(item); -			mCachedKeys.push_back(Data());  			setProvided(true); +			Param::enclosingBlock().paramChanged(*this, true);  		}  		// implicit conversion -		operator value_assignment_t() const { return self_t::get(); }  +		operator value_assignment_t() const { return mValues; }   		typedef typename container_t::iterator iterator;  		typedef typename container_t::const_iterator const_iterator; @@ -1246,8 +1256,8 @@ namespace LLInitParam  		U32 numValidElements() const  		{  			U32 count = 0; -			for (const_iterator it = mValues.begin(); -				it != mValues.end(); +			for (const_iterator it = mValues.begin(), end_it = mValues.end(); +				it != end_it;  				++it)  			{  				if(it->validateBlock(false)) count++; @@ -1256,43 +1266,35 @@ namespace LLInitParam  		}  	protected: -		value_assignment_t get() const -		{ -			return mValues; -		}  		static bool mergeWith(Param& dst, const Param& src, bool overwrite)  		{  			const self_t& src_typed_param = static_cast<const self_t&>(src);  			self_t& dst_typed_param = static_cast<self_t&>(dst); -			if (src_typed_param.isProvided() -				&& (overwrite || !dst_typed_param.isProvided())) +			if (overwrite)  			{ -				dst_typed_param.set(src_typed_param.get()); -				return true; +				std::copy(src_typed_param.begin(), src_typed_param.end(), std::back_inserter(dst_typed_param.mValues));  			} -			return false; +			else +			{ +				container_t new_values(src_typed_param.mValues); +				std::copy(dst_typed_param.begin(), dst_typed_param.end(), std::back_inserter(new_values)); +				std::swap(dst_typed_param.mValues, new_values); +			} +			return true;  		} -		struct Data : public key_cache_t -		{ -			S32 mKeyVersion;	// version of block for which key was last valid - -			Data() : mKeyVersion(0) {} -		}; -  		container_t			mValues; -		std::vector<Data>	mCachedKeys; -		S32			mLastParamGeneration; +		S32			mLastParseGeneration;  	};  	template <typename DERIVED_BLOCK>  	class Choice : public BaseBlock  	{ -		typedef Choice<DERIVED_BLOCK> self_t; -		typedef Choice<DERIVED_BLOCK> enclosing_block_t; +		typedef Choice<DERIVED_BLOCK>	self_t; +		typedef Choice<DERIVED_BLOCK>	enclosing_block_t;  		LOG_CLASS(self_t);  	public: @@ -1321,9 +1323,9 @@ namespace LLInitParam  		}  		// clear out old choice when param has changed -		/*virtual*/ void setLastChangedParam(const Param& last_param, bool user_provided) +		/*virtual*/ void paramChanged(const Param& changed_param, bool user_provided)  		{  -			param_handle_t changed_param_handle = BaseBlock::getHandleFromParam(&last_param); +			param_handle_t changed_param_handle = BaseBlock::getHandleFromParam(&changed_param);  			// if we have a new choice...  			if (changed_param_handle != mCurChoice)  			{ @@ -1335,7 +1337,7 @@ namespace LLInitParam  				}  				mCurChoice = changed_param_handle;  			} -			BaseBlock::setLastChangedParam(last_param, user_provided); +			BaseBlock::paramChanged(changed_param, user_provided);  		}  		virtual const BlockDescriptor& mostDerivedBlockDescriptor() const { return selfBlockDescriptor(); } @@ -1358,20 +1360,21 @@ namespace LLInitParam  			friend class Choice<DERIVED_BLOCK>;  			typedef Alternative<T, NAME_VALUE_LOOKUP>									self_t; -			typedef TypedParam<T, NAME_VALUE_LOOKUP, false, IsBaseBlock<T>::value>		super_t; +			typedef TypedParam<T, NAME_VALUE_LOOKUP, false, IsBlock<ParamValue<T, NAME_VALUE_LOOKUP> >::value>		super_t;  			typedef typename super_t::value_assignment_t								value_assignment_t; -			explicit Alternative(const char* name, value_assignment_t val = DefaultInitializer<T>::get()) +			explicit Alternative(const char* name, value_assignment_t val = defaultValue<T>())  			:	super_t(DERIVED_BLOCK::selfBlockDescriptor(), name, val, NULL, 0, 1),  				mOriginalValue(val)  			{  				// assign initial choice to first declared option  				DERIVED_BLOCK* blockp = ((DERIVED_BLOCK*)DERIVED_BLOCK::selfBlockDescriptor().mCurrentBlockPtr); -				if (LL_UNLIKELY( -						DERIVED_BLOCK::selfBlockDescriptor().mInitializationState == BlockDescriptor::INITIALIZING -							&& blockp->mCurChoice == 0)) +				if (LL_UNLIKELY(DERIVED_BLOCK::selfBlockDescriptor().mInitializationState == BlockDescriptor::INITIALIZING))  				{ -					blockp->mCurChoice = Param::enclosingBlock().getHandleFromParam(this); +					if(blockp->mCurChoice == 0) +					{ +						blockp->mCurChoice = Param::enclosingBlock().getHandleFromParam(this); +					}  				}  			} @@ -1390,7 +1393,7 @@ namespace LLInitParam  			{   				if (static_cast<enclosing_block_t&>(Param::enclosingBlock()).getCurrentChoice() == this)  				{ -					return super_t::get();  +					return super_t::getValue();   				}  				return mOriginalValue;  			}  @@ -1399,7 +1402,7 @@ namespace LLInitParam  			{   				if (static_cast<enclosing_block_t&>(Param::enclosingBlock()).getCurrentChoice() == this)  				{ -					return super_t::get();  +					return super_t::getValue();   				}  				return mOriginalValue;  			}  @@ -1433,8 +1436,8 @@ namespace LLInitParam  	class Block   	:	public BASE_BLOCK  	{ -		typedef Block<DERIVED_BLOCK, BASE_BLOCK> self_t; -		typedef Block<DERIVED_BLOCK, BASE_BLOCK> block_t; +		typedef Block<DERIVED_BLOCK, BASE_BLOCK>	self_t; +		typedef Block<DERIVED_BLOCK, BASE_BLOCK>	block_t;  	public:  		typedef BASE_BLOCK base_block_t; @@ -1442,13 +1445,13 @@ namespace LLInitParam  		// take all provided params from other and apply to self  		bool overwriteFrom(const self_t& other)  		{ -			return BaseBlock::merge(selfBlockDescriptor(), other, true); +			return static_cast<DERIVED_BLOCK*>(this)->merge(selfBlockDescriptor(), other, true);  		}  		// take all provided params that are not already provided, and apply to self  		bool fillFrom(const self_t& other)  		{ -			return BaseBlock::merge(selfBlockDescriptor(), other, false); +			return static_cast<DERIVED_BLOCK*>(this)->merge(selfBlockDescriptor(), other, false);  		}  		virtual const BlockDescriptor& mostDerivedBlockDescriptor() const { return selfBlockDescriptor(); } @@ -1468,10 +1471,10 @@ namespace LLInitParam  		class Optional : public TypedParam<T, NAME_VALUE_LOOKUP, false>  		{  		public: -			typedef TypedParam<T, NAME_VALUE_LOOKUP, false, IsBaseBlock<T>::value>		super_t; +			typedef TypedParam<T, NAME_VALUE_LOOKUP, false, IsBlock<ParamValue<T, NAME_VALUE_LOOKUP> >::value>		super_t;  			typedef typename super_t::value_assignment_t								value_assignment_t; -			explicit Optional(const char* name = "", value_assignment_t val = DefaultInitializer<T>::get()) +			explicit Optional(const char* name = "", value_assignment_t val = defaultValue<T>())  			:	super_t(DERIVED_BLOCK::selfBlockDescriptor(), name, val, NULL, 0, 1)  			{  				//#pragma message("Parsing LLInitParam::Block::Optional") @@ -1483,7 +1486,7 @@ namespace LLInitParam  				return *this;  			} -			DERIVED_BLOCK& operator()(typename super_t::value_assignment_t val) +			DERIVED_BLOCK& operator()(value_assignment_t val)  			{  				super_t::set(val);  				return static_cast<DERIVED_BLOCK&>(Param::enclosingBlock()); @@ -1495,12 +1498,12 @@ namespace LLInitParam  		class Mandatory : public TypedParam<T, NAME_VALUE_LOOKUP, false>  		{  		public: -			typedef TypedParam<T, NAME_VALUE_LOOKUP, false, IsBaseBlock<T>::value>		super_t; +			typedef TypedParam<T, NAME_VALUE_LOOKUP, false, IsBlock<ParamValue<T, NAME_VALUE_LOOKUP> >::value>		super_t;  			typedef Mandatory<T, NAME_VALUE_LOOKUP>										self_t;  			typedef typename super_t::value_assignment_t								value_assignment_t;  			// mandatory parameters require a name to be parseable -			explicit Mandatory(const char* name = "", value_assignment_t val = DefaultInitializer<T>::get()) +			explicit Mandatory(const char* name = "", value_assignment_t val = defaultValue<T>())  			:	super_t(DERIVED_BLOCK::selfBlockDescriptor(), name, val, &validate, 1, 1)  			{} @@ -1529,15 +1532,15 @@ namespace LLInitParam  		class Multiple : public TypedParam<T, NAME_VALUE_LOOKUP, true>  		{  		public: -			typedef TypedParam<T, NAME_VALUE_LOOKUP, true, IsBaseBlock<T>::value>	super_t; +			typedef TypedParam<T, NAME_VALUE_LOOKUP, true, IsBlock<ParamValue<T, NAME_VALUE_LOOKUP> >::value>	super_t;  			typedef Multiple<T, RANGE, NAME_VALUE_LOOKUP>							self_t;  			typedef typename super_t::container_t									container_t;  			typedef typename super_t::value_assignment_t							value_assignment_t;  			typedef typename super_t::iterator										iterator;  			typedef typename super_t::const_iterator								const_iterator; -			explicit Multiple(const char* name = "", value_assignment_t val = DefaultInitializer<container_t>::get()) -			:	super_t(DERIVED_BLOCK::selfBlockDescriptor(), name, val, &validate, RANGE::minCount(), RANGE::maxCount()) +			explicit Multiple(const char* name = "") +			:	super_t(DERIVED_BLOCK::selfBlockDescriptor(), name, container_t(), &validate, RANGE::minCount(), RANGE::maxCount())  			{}  			Multiple& operator=(value_assignment_t val) @@ -1545,7 +1548,7 @@ namespace LLInitParam  				set(val);  				return *this;  			} -			 +  			DERIVED_BLOCK& operator()(typename super_t::value_assignment_t val)  			{  				super_t::set(val); @@ -1559,6 +1562,96 @@ namespace LLInitParam  			}  		}; +		template <typename T, typename RANGE = BaseBlock::AnyAmount, typename NAME_VALUE_LOOKUP = TypeValues<T> > +		class Batch : private TypedParam<T, NAME_VALUE_LOOKUP, false> +		{ +		public: +			typedef ParamValue<T, NAME_VALUE_LOOKUP>										param_value_t; +			typedef TypedParam<T, NAME_VALUE_LOOKUP, false, IsBlock<param_value_t>::value>	super_t; +			typedef Batch<T, RANGE, NAME_VALUE_LOOKUP>										self_t; +			typedef typename super_t::value_assignment_t									value_assignment_t; +			typedef typename super_t::value_t												value_t; + +			struct BatchDefaultValue : public ParamDescriptor::UserData +			{ +				BatchDefaultValue(const T& value) +				:	mValue(value) +				{} + +				T mValue; +			}; + +			explicit Batch(const char* name, value_assignment_t val) +			:	super_t(DERIVED_BLOCK::selfBlockDescriptor(), name, val, NULL, 0, 1), +				mLastParseGeneration(-1) +			{ +				BlockDescriptor& block_descriptor = DERIVED_BLOCK::selfBlockDescriptor(); +				if (LL_UNLIKELY(block_descriptor.mInitializationState == BlockDescriptor::INITIALIZING)) +				{ +					ParamDescriptorPtr param_descriptorp = block_descriptor.mCurrentBlockPtr->findParamDescriptor(*this); + +					if (param_descriptorp) +					{ +						param_descriptorp->mDeserializeFunc = &deserializeParam; +						param_descriptorp->mUserData = new BatchDefaultValue(new param_value_t(val)); +					} +				} +			} + +			explicit Batch(const char* name = "") +			:	super_t(DERIVED_BLOCK::selfBlockDescriptor(), name, defaultValue<T>(), NULL, 0, 1), +				mLastParseGeneration(-1) +			{ +				BlockDescriptor& block_descriptor = DERIVED_BLOCK::selfBlockDescriptor(); +				if (LL_UNLIKELY(block_descriptor.mInitializationState == BlockDescriptor::INITIALIZING)) +				{ +					ParamDescriptorPtr param_descriptorp = block_descriptor.mCurrentBlockPtr->findParamDescriptor(*this); + +					if (param_descriptorp) +					{ +						param_descriptorp->mDeserializeFunc = &deserializeParam; +					} +				} +			} + +			Batch& operator=(value_assignment_t val) +			{ +				set(val); +				return *this; +			} + +			DERIVED_BLOCK& operator()(value_assignment_t val) +			{ +				super_t::set(val); +				return static_cast<DERIVED_BLOCK&>(Param::enclosingBlock()); +			} + +			using super_t::operator(); + +		private: +			static bool deserializeParam(Param& param, Parser& parser, const Parser::name_stack_range_t& name_stack, S32 generation)  +			{ +				self_t& typed_param = static_cast<self_t&>(param); + +				if (generation != typed_param.mLastParseGeneration) +				{ +					ParamDescriptorPtr descriptor = typed_param.enclosingBlock().findParamDescriptor(param); +					if (descriptor && static_cast<BatchDefaultValue*>(descriptor->mUserData)) +					{ +						static_cast<param_value_t&>(typed_param) = (static_cast<BatchDefaultValue*>(descriptor->mUserData))->mValue; +					} +					else +					{ +						static_cast<param_value_t&>(typed_param) = param_value_t(value_t()); +					} +					typed_param.mLastParseGeneration = generation; +				} +				return super_t::deserializeParam(param, parser, name_stack, generation); +			} + +			S32 mLastParseGeneration; +		}; +  		class Deprecated : public Param  		{  		public: @@ -1568,13 +1661,14 @@ namespace LLInitParam  				BlockDescriptor& block_descriptor = DERIVED_BLOCK::selfBlockDescriptor();  				if (LL_UNLIKELY(block_descriptor.mInitializationState == BlockDescriptor::INITIALIZING))  				{ -					ParamDescriptor param_descriptor(block_descriptor.mCurrentBlockPtr->getHandleFromParam(this), +					ParamDescriptorPtr param_descriptor = ParamDescriptorPtr(new ParamDescriptor( +													block_descriptor.mCurrentBlockPtr->getHandleFromParam(this),  													NULL,  													&deserializeParam,  													NULL,  													NULL,  													NULL,  -													0, S32_MAX); +													0, S32_MAX));  					BaseBlock::addParam(block_descriptor, param_descriptor, name);  				}  			} @@ -1602,137 +1696,91 @@ namespace LLInitParam  		}  	}; -	template<typename T, typename DERIVED = TypedParam<T> > -	class BlockValue -	:	public Block<TypedParam<T, TypeValues<T>, false> >, -		public Param +	template<typename T> +	class CustomParamValue +	:	public Block<ParamValue<T, TypeValues<T> > >, +		public TypeValues<T>  	{  	public:  		typedef enum e_value_age  		{	 -			OLDER_THAN_BLOCK,	// mData.mValue needs to be refreshed from the block parameters -			NEWER_THAN_BLOCK,	// mData.mValue holds the authoritative value (which has been replicated to the block parameters via setBlockFromValue) -			SAME_AS_BLOCK		// mData.mValue is derived from the block parameters, which are authoritative +			VALUE_NEEDS_UPDATE,		// mValue needs to be refreshed from the block parameters +			VALUE_AUTHORITATIVE,	// mValue holds the authoritative value (which has been replicated to the block parameters via updateBlockFromValue) +			BLOCK_AUTHORITATIVE		// mValue is derived from the block parameters, which are authoritative  		} EValueAge; -		typedef BlockValue<T>										self_t; -		typedef Block<TypedParam<T, TypeValues<T>, false> >			block_t; -		typedef const T&											value_const_ref_t; -		typedef value_const_ref_t									value_assignment_t; -		typedef typename TypeValues<T>::KeyCache					key_cache_t; - -		BlockValue(BlockDescriptor& block_descriptor, const char* name, value_assignment_t value, ParamDescriptor::validation_func_t validate_func, S32 min_count, S32 max_count) -		:	Param(block_descriptor.mCurrentBlockPtr), -			mData(value, NEWER_THAN_BLOCK) -		{ -			if (LL_UNLIKELY(block_descriptor.mInitializationState == BlockDescriptor::INITIALIZING)) -			{ -				ParamDescriptor param_descriptor(block_descriptor.mCurrentBlockPtr->getHandleFromParam(this), -												&mergeWith, -												&deserializeParam, -												&serializeParam, -												validate_func, -												&inspectParam, -												min_count, max_count); -				BaseBlock::addParam(block_descriptor, param_descriptor, name); -			} -		} +		typedef ParamValue<T, TypeValues<T> >	derived_t; +		typedef CustomParamValue<T>				self_t; +		typedef Block<derived_t>		block_t; +		typedef const T&						value_assignment_t; -		// implicit conversion -		operator value_assignment_t() const { return get(); }  -		// explicit conversion -		value_assignment_t operator()() const { return get(); }  +		CustomParamValue(const T& value = T()) +		:	mValue(value), +			mValueAge(VALUE_AUTHORITATIVE), +			mKeyVersion(0), +			mValidatedVersion(-1) +		{} -		static bool deserializeParam(Param& param, Parser& parser, const Parser::name_stack_range_t& name_stack, S32 generation) +		bool deserializeBlock(Parser& parser, Parser::name_stack_range_t name_stack, S32 generation)  		{ -			DERIVED& typed_param = static_cast<DERIVED&>(param); +			derived_t& typed_param = static_cast<derived_t&>(*this);  			// type to apply parse direct value T  			if (name_stack.first == name_stack.second)  			{ -				if(parser.readValue(typed_param.mData.mValue)) +				if(parser.readValue(typed_param.mValue))  				{ -					typed_param.enclosingBlock().setLastChangedParam(param, true); -					typed_param.setProvided(true); -					typed_param.mData.clearKey(); -					typed_param.mData.mValueAge = NEWER_THAN_BLOCK; -					typed_param.setBlockFromValue(); +					typed_param.clearValueName(); +					typed_param.mValueAge = VALUE_AUTHORITATIVE; +					typed_param.updateBlockFromValue();  					return true;  				} - -				if(!TypeValues<T>::empty()) -				{ -					// try to parse a known named value -					std::string name; -					if (parser.readValue(name)) -					{ -						// try to parse a per type named value -						if (TypeValues<T>::get(name, typed_param.mData.mValue)) -						{ -							typed_param.mData.setKey(name); -							typed_param.enclosingBlock().setLastChangedParam(param, true); -							typed_param.setProvided(true); -							typed_param.mData.mValueAge = NEWER_THAN_BLOCK; -							typed_param.setBlockFromValue(); - -							return true; -						} -					} -				}  			}  			// fall back on parsing block components for T  			// if we deserialized at least one component... -			if (typed_param.BaseBlock::deserializeBlock(parser, name_stack)) +			if (typed_param.BaseBlock::deserializeBlock(parser, name_stack, generation))  			{ -				// ...our block is provided, and considered changed -				typed_param.enclosingBlock().setLastChangedParam(param, true); -				typed_param.setProvided(true);  				return true;  			} +  			return false;  		} -		static void serializeParam(const Param& param, Parser& parser, Parser::name_stack_t& name_stack, const Param* diff_param) +		void serializeBlock(Parser& parser, Parser::name_stack_t name_stack = Parser::name_stack_t(), const BaseBlock* diff_block = NULL) const  		{ -			const self_t& typed_param = static_cast<const self_t&>(param); +			const self_t& typed_param = static_cast<const self_t&>(*this); +			const self_t* diff_param = static_cast<const self_t*>(diff_block); -			if (!typed_param.isProvided()) return; -			 -			std::string key = typed_param.mData.getKey(); +			std::string key = typed_param.getValueName();  			// first try to write out name of name/value pair  			if (!key.empty())  			{ -				if (!diff_param || !ParamCompare<std::string>::equals(static_cast<const self_t*>(diff_param)->mData.getKey(), key)) +				if (!diff_param || !ParamCompare<std::string>::equals(diff_param->getValueName(), key))  				{ -					if (!parser.writeValue(key, name_stack)) -					{ -						return; -					} +					parser.writeValue(key, name_stack);  				}  			}  			// then try to serialize value directly -			else if (!diff_param || !ParamCompare<T>::equals(typed_param.get(), (static_cast<const self_t*>(diff_param))->get()))	 +			else if (!diff_param || !ParamCompare<T>::equals(typed_param.getValue(), diff_param->getValue()))              { -				if (parser.writeValue(typed_param.mData.mValue, name_stack))  +				if (!parser.writeValue(typed_param.getValue(), name_stack))   				{ -					return; +					//RN: *always* serialize provided components of BlockValue (don't pass diff_param on), +					// since these tend to be viewed as the constructor arguments for the value T.  It seems +					// cleaner to treat the uniqueness of a BlockValue according to the generated value, and +					// not the individual components.  This way <color red="0" green="1" blue="0"/> will not +					// be exported as <color green="1"/>, since it was probably the intent of the user to  +					// be specific about the RGB color values.  This also fixes an issue where we distinguish +					// between rect.left not being provided and rect.left being explicitly set to 0 (same as default) +					block_t::serializeBlock(parser, name_stack, NULL);  				} - -				//RN: *always* serialize provided components of BlockValue (don't pass diff_param on), -				// since these tend to be viewed as the constructor arguments for the value T.  It seems -				// cleaner to treat the uniqueness of a BlockValue according to the generated value, and -				// not the individual components.  This way <color red="0" green="1" blue="0"/> will not -				// be exported as <color green="1"/>, since it was probably the intent of the user to  -				// be specific about the RGB color values.  This also fixes an issue where we distinguish -				// between rect.left not being provided and rect.left being explicitly set to 0 (same as default) -				typed_param.BaseBlock::serializeBlock(parser, name_stack, NULL);  			}  		} -		static void inspectParam(const Param& param, Parser& parser, Parser::name_stack_t& name_stack, S32 min_count, S32 max_count) +		bool inspectBlock(Parser& parser, Parser::name_stack_t name_stack = Parser::name_stack_t(), S32 min_count = 0, S32 max_count = S32_MAX) const  		{  			// first, inspect with actual type...  			parser.inspectValue<T>(name_stack, min_count, max_count, NULL); @@ -1742,25 +1790,19 @@ namespace LLInitParam  				parser.inspectValue<std::string>(name_stack, min_count, max_count, TypeValues<T>::getPossibleValues());  			}  			// then recursively inspect contents... -			const self_t& typed_param = static_cast<const self_t&>(param); -			typed_param.inspectBlock(parser, name_stack); +			return block_t::inspectBlock(parser, name_stack, min_count, max_count);  		} - -		bool isProvided() const  +		bool validateBlock(bool emit_errors = true) const  		{ -			if (!Param::anyProvided()) return false; - -			// block has an updated parameter -			// if cached value is stale, regenerate from params -			if (mData.mValueAge == OLDER_THAN_BLOCK) +			if (mValueAge == VALUE_NEEDS_UPDATE)  			{ -				if (block_t::validateBlock(false)) +				if (block_t::validateBlock(emit_errors))  				{ -					static_cast<const DERIVED*>(this)->setValueFromBlock();  					// clear stale keyword associated with old value -					mData.clearKey(); -					mData.mValueAge = SAME_AS_BLOCK; +					TypeValues<T>::clearValueName(); +					mValueAge = BLOCK_AUTHORITATIVE; +					static_cast<derived_t*>(const_cast<self_t*>(this))->updateValueFromBlock();  					return true;  				}  				else @@ -1777,104 +1819,75 @@ namespace LLInitParam  			}  		} -		void set(value_assignment_t val, bool flag_as_provided = true) -		{ -			Param::enclosingBlock().setLastChangedParam(*this, flag_as_provided); -			 -			// set param version number to be up to date, so we ignore block contents -			mData.mValueAge = NEWER_THAN_BLOCK; - -			mData.mValue = val; -			mData.clearKey(); -			setProvided(flag_as_provided); -			static_cast<DERIVED*>(this)->setBlockFromValue(); -		} - -		void setIfNotProvided(value_assignment_t val, bool flag_as_provided = true) -		{ -			// don't override any user provided value -			if (!isProvided()) -			{ -				set(val, flag_as_provided); -			} -		} -   		// propagate change status up to enclosing block -		/*virtual*/ void setLastChangedParam(const Param& last_param, bool user_provided) +		/*virtual*/ void paramChanged(const Param& changed_param, bool user_provided)  		{  -			BaseBlock::setLastChangedParam(last_param, user_provided); -			Param::enclosingBlock().setLastChangedParam(*this, user_provided); +			BaseBlock::paramChanged(changed_param, user_provided);  			if (user_provided) -			{ -				setProvided(true);  // some component provided +		{  				// a parameter changed, so our value is out of date -				mData.mValueAge = OLDER_THAN_BLOCK; +				mValueAge = VALUE_NEEDS_UPDATE;  			}  		} - -	protected: -		value_assignment_t get() const +			 +		void setValue(value_assignment_t val)  		{ -			// if some parameters were provided, issue warnings on invalid blocks -			if (Param::anyProvided() && (mData.mValueAge == OLDER_THAN_BLOCK)) -			{ -				// go ahead and issue warnings at this point if any param is invalid -				if(block_t::validateBlock(true)) -				{ -					static_cast<const DERIVED*>(this)->setValueFromBlock(); -					mData.clearKey(); -					mData.mValueAge = SAME_AS_BLOCK; -				} -			} - -			return mData.mValue; +			derived_t& typed_param = static_cast<derived_t&>(*this); +			// set param version number to be up to date, so we ignore block contents +			mValueAge = VALUE_AUTHORITATIVE; +			mValue = val; +			typed_param.clearValueName(); +			static_cast<derived_t*>(const_cast<self_t*>(this))->updateBlockFromValue();  		} +		value_assignment_t getValue() const +		{ +			validateBlock(true); +			return mValue; +		} -		struct Data : public key_cache_t +		T& getValue()   		{ -			Data(const T& value, EValueAge age)  -			:	mValue(value), -				mValueAge(age) -			{} +			validateBlock(true); +			return mValue; +		} -			T			mValue; -			EValueAge	mValueAge; -		}; +		S32 				mKeyVersion; -		// mutable to allow lazy updates on get -		mutable Data		mData; +	protected: -	private: -		static bool mergeWith(Param& dst, const Param& src, bool overwrite) +		// use this from within updateValueFromBlock() to set the value without making it authoritative +		void updateValue(value_assignment_t value)  		{ -			const DERIVED& src_typed_param = static_cast<const DERIVED&>(src); -			DERIVED& dst_typed_param = static_cast<DERIVED&>(dst); +			mValue = value; +		} -			if (src_typed_param.isProvided() -				&& (overwrite || !dst_typed_param.isProvided())) +		bool merge(BlockDescriptor& block_data, const BaseBlock& other, bool overwrite) +		{ +			const derived_t& src_typed_param = static_cast<const derived_t&>(other); + +			if (src_typed_param.mValueAge == VALUE_AUTHORITATIVE)  			{ -				if (src_typed_param.mData.mValueAge == NEWER_THAN_BLOCK) -				{ -					// copy value over -					dst_typed_param.set(src_typed_param.get()); -				} -				else -				{ -					// merge individual parameters into destination -					dst_typed_param.merge(block_t::selfBlockDescriptor(), src_typed_param, overwrite); -				} +				// copy value over +				setValue(src_typed_param.getValue());  				return true;  			} -			return false; +			else +			{ +				// merge individual parameters into destination +				return block_t::merge(block_t::selfBlockDescriptor(), src_typed_param, overwrite); +			}  		} -	}; -	template<>  -	struct ParamCompare<LLSD, false> -	{ -		static bool equals(const LLSD &a, const LLSD &b); +		mutable S32			mValidatedVersion; +		mutable bool 		mValidated; // lazy validation flag + +	private: + +		mutable T			mValue; +		mutable EValueAge	mValueAge;  	};  } +  #endif // LL_LLPARAM_H diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index cac7df56e4..4e666952ce 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -12602,6 +12602,39 @@      <key>Value</key>      <integer>1</integer>    </map> +  <key>EnableInventory</key> +  <map> +    <key>Comment</key> +    <string>Enable opening inventory from web link</string> +    <key>Persist</key> +    <integer>1</integer> +    <key>Type</key> +    <string>Boolean</string> +    <key>Value</key> +    <integer>1</integer> +  </map> +  <key>EnableSearch</key> +  <map> +    <key>Comment</key> +    <string>Enable opening search from web link</string> +    <key>Persist</key> +    <integer>1</integer> +    <key>Type</key> +    <string>Boolean</string> +    <key>Value</key> +    <integer>1</integer> +  </map> +  <key>EnableAppearance</key> +  <map> +    <key>Comment</key> +    <string>Enable opening appearance from web link</string> +    <key>Persist</key> +    <integer>1</integer> +    <key>Type</key> +    <string>Boolean</string> +    <key>Value</key> +    <integer>1</integer> +  </map>      <key>SearchFromAddressBar</key>      <map>        <key>Comment</key> diff --git a/indra/newview/app_settings/settings_minimal.xml b/indra/newview/app_settings/settings_minimal.xml index 490da2c9d4..bc97ec00e9 100644 --- a/indra/newview/app_settings/settings_minimal.xml +++ b/indra/newview/app_settings/settings_minimal.xml @@ -303,6 +303,39 @@        <key>Value</key>        <integer>0</integer>      </map> +    <key>EnableInventory</key> +    <map> +      <key>Comment</key> +      <string>Enable opening inventory from web link</string> +      <key>Persist</key> +      <integer>1</integer> +      <key>Type</key> +      <string>Boolean</string> +      <key>Value</key> +      <integer>0</integer> +    </map> +    <key>EnableSearch</key> +    <map> +      <key>Comment</key> +      <string>Enable opening search from web link</string> +      <key>Persist</key> +      <integer>1</integer> +      <key>Type</key> +      <string>Boolean</string> +      <key>Value</key> +      <integer>0</integer> +    </map> +    <key>EnableAppearance</key> +    <map> +      <key>Comment</key> +      <string>Enable opening appearance from web link</string> +      <key>Persist</key> +      <integer>1</integer> +      <key>Type</key> +      <string>Boolean</string> +      <key>Value</key> +      <integer>0</integer> +    </map>      <key>DoubleClickShowWorldMap</key>      <map>        <key>Comment</key> diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp index 1cf552e42c..f9e850899a 100644 --- a/indra/newview/llappearancemgr.cpp +++ b/indra/newview/llappearancemgr.cpp @@ -110,6 +110,12 @@ public:  	{  		// support secondlife:///app/appearance/show, but for now we just  		// make all secondlife:///app/appearance SLapps behave this way +		if (!LLUI::sSettingGroups["config"]->getBOOL("EnableAppearance")) +		{ +			LLNotificationsUtil::add("NoAppearance", LLSD(), LLSD(), std::string("SwitchToStandardSkinAndQuit")); +			return true; +		} +  		LLSideTray::getInstance()->showPanel("sidepanel_appearance", LLSD());  		return true;  	} diff --git a/indra/newview/lldateutil.cpp b/indra/newview/lldateutil.cpp index fcc73a07bc..18ae6107e7 100644 --- a/indra/newview/lldateutil.cpp +++ b/indra/newview/lldateutil.cpp @@ -32,9 +32,9 @@  #include "llui.h"  static S32 DAYS_PER_MONTH_NOLEAP[] = -	{ 31, 28, 21, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; +	{ 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };  static S32 DAYS_PER_MONTH_LEAP[] = -	{ 31, 29, 21, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; +	{ 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };  static S32 days_from_month(S32 year, S32 month)  { diff --git a/indra/newview/llfloaterimagepreview.cpp b/indra/newview/llfloaterimagepreview.cpp index c7fbdd5745..d76e7885bc 100644 --- a/indra/newview/llfloaterimagepreview.cpp +++ b/indra/newview/llfloaterimagepreview.cpp @@ -325,122 +325,51 @@ void LLFloaterImagePreview::draw()  bool LLFloaterImagePreview::loadImage(const std::string& src_filename)  {  	std::string exten = gDirUtilp->getExtension(src_filename); -	 -	U32 codec = IMG_CODEC_INVALID; -	std::string temp_str; -	if( exten == "bmp") -	{ -		codec = IMG_CODEC_BMP; -	} -	else if( exten == "tga") -	{ -		codec = IMG_CODEC_TGA; -	} -	else if( exten == "jpg" || exten == "jpeg") -	{ -		codec = IMG_CODEC_JPEG; -	} -	else if( exten == "png" ) -	{ -		codec = IMG_CODEC_PNG; -	} +	U32 codec = LLImageBase::getCodecFromExtension(exten);  	LLImageDimensionsInfo image_info; -	if(!image_info.load(src_filename,codec)) +	if (!image_info.load(src_filename,codec))  	{  		mImageLoadError = image_info.getLastError();  		return false;  	}  	S32 max_width = gSavedSettings.getS32("max_texture_dimension_X"); -	S32 max_heigh = gSavedSettings.getS32("max_texture_dimension_Y"); +	S32 max_height = gSavedSettings.getS32("max_texture_dimension_Y"); -	if(image_info.getWidth() > max_width|| image_info.getHeight() > max_heigh) +	if ((image_info.getWidth() > max_width) || (image_info.getHeight() > max_height))  	{  		LLStringUtil::format_map_t args;  		args["WIDTH"] = llformat("%d", max_width); -		args["HEIGHT"] = llformat("%d", max_heigh); +		args["HEIGHT"] = llformat("%d", max_height);  		mImageLoadError = LLTrans::getString("texture_load_dimensions_error", args);  		return false;  	} - +	// Load the image +	LLPointer<LLImageFormatted> image = LLImageFormatted::createFromType(codec); +	if (image.isNull()) +	{ +		return false; +	} +	if (!image->load(src_filename)) +	{ +		return false; +	} +	// Decompress or expand it in a raw image structure  	LLPointer<LLImageRaw> raw_image = new LLImageRaw; - -	switch (codec) +	if (!image->decode(raw_image, 0.0f))  	{ -	case IMG_CODEC_BMP: -		{ -			LLPointer<LLImageBMP> bmp_image = new LLImageBMP; - -			if (!bmp_image->load(src_filename)) -			{ -				return false; -			} -			 -			if (!bmp_image->decode(raw_image, 0.0f)) -			{ -				return false; -			} -		} -		break; -	case IMG_CODEC_TGA: -		{ -			LLPointer<LLImageTGA> tga_image = new LLImageTGA; - -			if (!tga_image->load(src_filename)) -			{ -				return false; -			} -			 -			if (!tga_image->decode(raw_image)) -			{ -				return false; -			} - -			if(	(tga_image->getComponents() != 3) && -				(tga_image->getComponents() != 4) ) -			{ -				tga_image->setLastError( "Image files with less than 3 or more than 4 components are not supported." ); -				return false; -			} -		} -		break; -	case IMG_CODEC_JPEG: -		{ -			LLPointer<LLImageJPEG> jpeg_image = new LLImageJPEG; - -			if (!jpeg_image->load(src_filename)) -			{ -				return false; -			} -			 -			if (!jpeg_image->decode(raw_image, 0.0f)) -			{ -				return false; -			} -		} -		break; -	case IMG_CODEC_PNG: -		{ -			LLPointer<LLImagePNG> png_image = new LLImagePNG; - -			if (!png_image->load(src_filename)) -			{ -				return false; -			} -			 -			if (!png_image->decode(raw_image, 0.0f)) -			{ -				return false; -			} -		} -		break; -	default:  		return false;  	} - +	// Check the image constraints +	if ((image->getComponents() != 3) && (image->getComponents() != 4)) +	{ +		image->setLastError("Image files with less than 3 or more than 4 components are not supported."); +		return false; +	} +	  	raw_image->biasedScaleToPowerOfTwo(1024);  	mRawImagep = raw_image; diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp index 1a9d0af9af..b4b12024aa 100644 --- a/indra/newview/llfloaterpreference.cpp +++ b/indra/newview/llfloaterpreference.cpp @@ -286,8 +286,7 @@ LLFloaterPreference::LLFloaterPreference(const LLSD& key)  	mOriginalIMViaEmail(false),  	mLanguageChanged(false),  	mAvatarDataInitialized(false), -	mDoubleClickActionDirty(false), -	mFavoritesRecordMayExist(false) +	mDoubleClickActionDirty(false)  {  	//Build Floater is now Called from 	LLFloaterReg::add("preferences", "floater_preferences.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterPreference>); @@ -412,6 +411,8 @@ BOOL LLFloaterPreference::postBuild()  	gSavedSettings.getControl("ChatFontSize")->getSignal()->connect(boost::bind(&LLNearbyChat::processChatHistoryStyleUpdate, _2)); +	gSavedSettings.getControl("ChatFontSize")->getSignal()->connect(boost::bind(&LLViewerChat::signalChatFontChanged)); +  	gSavedSettings.getControl("ChatBubbleOpacity")->getSignal()->connect(boost::bind(&LLFloaterPreference::onNameTagOpacityChange, this, _2));  	LLTabContainer* tabcontainer = getChild<LLTabContainer>("pref core"); @@ -565,34 +566,6 @@ void LLFloaterPreference::apply()  		updateDoubleClickSettings();  		mDoubleClickActionDirty = false;  	} - -	if (mFavoritesRecordMayExist && !gSavedPerAccountSettings.getBOOL("ShowFavoritesOnLogin")) -	{ -		removeFavoritesRecordOfUser();		 -	} -} - -void LLFloaterPreference::removeFavoritesRecordOfUser() -{ -	mFavoritesRecordMayExist = false; -	std::string filename = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, "stored_favorites.xml"); -	LLSD fav_llsd; -	llifstream file; -	file.open(filename); -	if (!file.is_open()) return; -	LLSDSerialize::fromXML(fav_llsd, file); -	 -	LLAvatarName av_name; -	LLAvatarNameCache::get( gAgentID, &av_name ); -	if (fav_llsd.has(av_name.getLegacyName())) -	{ -		fav_llsd.erase(av_name.getLegacyName()); -	} -	 -	llofstream out_file; -	out_file.open(filename); -	LLSDSerialize::toPrettyXML(fav_llsd, out_file); -  }  void LLFloaterPreference::cancel() @@ -678,11 +651,6 @@ void LLFloaterPreference::onOpen(const LLSD& key)  		getChildView("maturity_desired_combobox")->setVisible( false);  	} -	if (LLStartUp::getStartupState() == STATE_STARTED) -	{ -		mFavoritesRecordMayExist = gSavedPerAccountSettings.getBOOL("ShowFavoritesOnLogin"); -	} -  	// Forget previous language changes.  	mLanguageChanged = false; diff --git a/indra/newview/llfloaterpreference.h b/indra/newview/llfloaterpreference.h index 5d5e066ec5..4d8a2489be 100644 --- a/indra/newview/llfloaterpreference.h +++ b/indra/newview/llfloaterpreference.h @@ -159,8 +159,6 @@ public:  	void buildPopupLists();  	static void refreshSkin(void* data); -	// Remove record of current user's favorites from file on disk. -	void removeFavoritesRecordOfUser();  private:  	static std::string sSkin;  	// set true if state of double-click action checkbox or radio-group was changed by user @@ -172,8 +170,6 @@ private:  	bool mAvatarDataInitialized;  	bool mOriginalHideOnlineStatus; -	// Record of current user's favorites may be stored in file on disk. -	bool mFavoritesRecordMayExist;  	std::string mDirectoryVisibility;  	LLAvatarData mAvatarProperties; diff --git a/indra/newview/llfloatersearch.cpp b/indra/newview/llfloatersearch.cpp index 2041fac8d8..d5806e375c 100644 --- a/indra/newview/llfloatersearch.cpp +++ b/indra/newview/llfloatersearch.cpp @@ -31,6 +31,7 @@  #include "llfloaterreg.h"  #include "llfloatersearch.h"  #include "llmediactrl.h" +#include "llnotificationsutil.h"  #include "lllogininstance.h"  #include "lluri.h"  #include "llagent.h" @@ -46,6 +47,12 @@ public:  	LLSearchHandler() : LLCommandHandler("search", UNTRUSTED_THROTTLE) { }  	bool handle(const LLSD& tokens, const LLSD& query_map, LLMediaCtrl* web)  	{ +		if (!LLUI::sSettingGroups["config"]->getBOOL("EnableSearch")) +		{ +			LLNotificationsUtil::add("NoSearch", LLSD(), LLSD(), std::string("SwitchToStandardSkinAndQuit")); +			return true; +		} +  		const size_t parts = tokens.size();  		// get the (optional) category for the search diff --git a/indra/newview/lllogininstance.cpp b/indra/newview/lllogininstance.cpp index abcd8588dc..36c5d12897 100644 --- a/indra/newview/lllogininstance.cpp +++ b/indra/newview/lllogininstance.cpp @@ -558,6 +558,18 @@ void LLLoginInstance::constructAuthParams(LLPointer<LLCredential> user_credentia  	requested_options.append("buddy-list");  	requested_options.append("newuser-config");  	requested_options.append("ui-config"); + +	//send this info to login.cgi for stats gathering  +	//since viewerstats isn't reliable enough +	if (gSavedSettings.getString("SessionSettingsFile").empty()) +	{ +		requested_options.append("advanced-mode"); +	} +	else +	{ +		requested_options.append("basic-mode"); +	} +  #endif  	requested_options.append("max-agent-groups");	  	requested_options.append("map-server-url");	 diff --git a/indra/newview/llnearbychatbar.cpp b/indra/newview/llnearbychatbar.cpp index 162e465fef..d3fd959152 100644 --- a/indra/newview/llnearbychatbar.cpp +++ b/indra/newview/llnearbychatbar.cpp @@ -47,6 +47,7 @@  #include "llwindow.h"  #include "llviewerwindow.h"  #include "llrootview.h" +#include "llviewerchat.h"  S32 LLNearbyChatBar::sLastSpecialChatChannel = 0; @@ -433,13 +434,26 @@ BOOL LLNearbyChatBar::postBuild()  	mChatBox->setPassDelete(TRUE);  	mChatBox->setReplaceNewlinesWithSpaces(FALSE);  	mChatBox->setEnableLineHistory(TRUE); +	mChatBox->setFont(LLViewerChat::getChatFont());  	mOutputMonitor = getChild<LLOutputMonitorCtrl>("chat_zone_indicator");  	mOutputMonitor->setVisible(FALSE); +	// Register for font change notifications +	LLViewerChat::setFontChangedCallback(boost::bind(&LLNearbyChatBar::onChatFontChange, this, _1)); +  	return TRUE;  } +void LLNearbyChatBar::onChatFontChange(LLFontGL* fontp) +{ +	// Update things with the new font whohoo +	if (mChatBox) +	{ +		mChatBox->setFont(fontp); +	} +} +  //static  LLNearbyChatBar* LLNearbyChatBar::getInstance()  { diff --git a/indra/newview/llnearbychatbar.h b/indra/newview/llnearbychatbar.h index 96ab45071b..efddec942f 100644 --- a/indra/newview/llnearbychatbar.h +++ b/indra/newview/llnearbychatbar.h @@ -127,6 +127,7 @@ protected:  	void sendChat( EChatType type );  	void onChatBoxCommit(); +	void onChatFontChange(LLFontGL* fontp);  	static LLWString stripChannelNumber(const LLWString &mesg, S32* channel);  	EChatType processChatTypeTriggers(EChatType type, std::string &str); diff --git a/indra/newview/llpanellogin.cpp b/indra/newview/llpanellogin.cpp index 7820ac3ecd..979d96ca0d 100644 --- a/indra/newview/llpanellogin.cpp +++ b/indra/newview/llpanellogin.cpp @@ -81,6 +81,9 @@ const S32 MAX_PASSWORD = 16;  LLPanelLogin *LLPanelLogin::sInstance = NULL;  BOOL LLPanelLogin::sCapslockDidNotification = FALSE; +// Helper for converting a user name into the canonical "Firstname Lastname" form. +// For new accounts without a last name "Resident" is added as a last name. +static std::string canonicalize_username(const std::string& name);  class LLLoginRefreshHandler : public LLCommandHandler  { @@ -302,7 +305,14 @@ void LLPanelLogin::addFavoritesToStartLocation()  	for (LLSD::map_const_iterator iter = fav_llsd.beginMap();  		iter != fav_llsd.endMap(); ++iter)  	{ -		if(iter->first != getChild<LLComboBox>("username_combo")->getSimple()) continue; +		std::string user_defined_name = getChild<LLComboBox>("username_combo")->getSimple(); + +		// The account name in stored_favorites.xml has Resident last name even if user has +		// a single word account name, so it can be compared case-insensitive with the +		// user defined "firstname lastname". +		S32 res = LLStringUtil::compareInsensitive(canonicalize_username(user_defined_name), iter->first); +		if (res != 0) continue; +  		combo->addSeparator();  		LLSD user_llsd = iter->second;  		for (LLSD::array_const_iterator iter1 = user_llsd.beginArray(); @@ -1186,3 +1196,28 @@ void LLPanelLogin::onModeChangeConfirm(const LLSD& original_value, const LLSD& n  		break;  	}  } + +std::string canonicalize_username(const std::string& name) +{ +	std::string cname = name; +	LLStringUtil::trim(cname); + +	// determine if the username is a first/last form or not. +	size_t separator_index = cname.find_first_of(" ._"); +	std::string first = cname.substr(0, separator_index); +	std::string last; +	if (separator_index != cname.npos) +	{ +		last = cname.substr(separator_index+1, cname.npos); +		LLStringUtil::trim(last); +	} +	else +	{ +		// ...on Linden grids, single username users as considered to have +		// last name "Resident" +		last = "Resident"; +	} + +	// Username in traditional "firstname lastname" form. +	return first + ' ' + last; +} diff --git a/indra/newview/llpreviewtexture.cpp b/indra/newview/llpreviewtexture.cpp index 6cfb708112..18d6731fcb 100644 --- a/indra/newview/llpreviewtexture.cpp +++ b/indra/newview/llpreviewtexture.cpp @@ -143,10 +143,7 @@ void LLPreviewTexture::onSaveAsBtn(void* data)  void LLPreviewTexture::draw()  { -	if (mUpdateDimensions) -	{ -		updateDimensions(); -	} +	updateDimensions();  	LLPreview::draw(); @@ -396,27 +393,32 @@ void LLPreviewTexture::onFileLoadedForSave(BOOL success,  void LLPreviewTexture::updateDimensions()  {  	if (!mImage) +	{  		return; - -	if(mImage->getFullWidth() == 0 || mImage->getFullHeight() == 0) +	} +	if ((mImage->getFullWidth() * mImage->getFullHeight()) == 0)  	{  		return;  	} -	mUpdateDimensions = FALSE; - -	getChild<LLUICtrl>("dimensions")->setTextArg("[WIDTH]", llformat("%d", mImage->getFullWidth())); +	// Update the width/height display every time +	getChild<LLUICtrl>("dimensions")->setTextArg("[WIDTH]",  llformat("%d", mImage->getFullWidth()));  	getChild<LLUICtrl>("dimensions")->setTextArg("[HEIGHT]", llformat("%d", mImage->getFullHeight())); -	 -	//reshape floater -	reshape(getRect().getWidth(), getRect().getHeight()); +	// Reshape the floater only when required +	if (mUpdateDimensions) +	{ +		mUpdateDimensions = FALSE; +		 +		//reshape floater +		reshape(getRect().getWidth(), getRect().getHeight()); -	gFloaterView->adjustToFitScreen(this, FALSE); +		gFloaterView->adjustToFitScreen(this, FALSE); -	LLRect dim_rect(getChildView("dimensions")->getRect()); -	LLRect aspect_label_rect(getChildView("aspect_ratio")->getRect()); -	getChildView("aspect_ratio")->setVisible( dim_rect.mRight < aspect_label_rect.mLeft); +		LLRect dim_rect(getChildView("dimensions")->getRect()); +		LLRect aspect_label_rect(getChildView("aspect_ratio")->getRect()); +		getChildView("aspect_ratio")->setVisible( dim_rect.mRight < aspect_label_rect.mLeft); +	}  } diff --git a/indra/newview/llsidetray.cpp b/indra/newview/llsidetray.cpp index 4f18ee1da2..e4c2293938 100644 --- a/indra/newview/llsidetray.cpp +++ b/indra/newview/llsidetray.cpp @@ -1192,6 +1192,38 @@ void LLSideTray::reshape(S32 width, S32 height, BOOL called_from_parent)  	arrange();  } +// This is just LLView::findChildView specialized to restrict the search to LLPanels. +// Optimization for EXT-4068 to avoid searching down to the individual item level +// when inventories are large. +LLPanel *findChildPanel(LLPanel *panel, const std::string& name, bool recurse) +{ +	for (LLView::child_list_const_iter_t child_it = panel->beginChild(); +		 child_it != panel->endChild(); ++child_it) +	{ +		LLPanel *child_panel = dynamic_cast<LLPanel*>(*child_it); +		if (!child_panel) +			continue; +		if (child_panel->getName() == name) +			return child_panel; +	} +	if (recurse) +	{ +		for (LLView::child_list_const_iter_t child_it = panel->beginChild(); +			 child_it != panel->endChild(); ++child_it) +		{ +			LLPanel *child_panel = dynamic_cast<LLPanel*>(*child_it); +			if (!child_panel) +				continue; +			LLPanel *found_panel = findChildPanel(child_panel,name,recurse); +			if (found_panel) +			{ +				return found_panel; +			} +		} +	} +	return NULL; +} +  /**   * Activate tab with "panel_name" panel   * if no such tab - return false, otherwise true. @@ -1221,23 +1253,50 @@ LLPanel*	LLSideTray::showPanel		(const std::string& panel_name, const LLSD& para  	return new_panel;  } -void LLSideTray::hidePanel(const std::string& panel_name) +bool LLSideTray::hidePanel(const std::string& panel_name)  { +	bool panelHidden = false; +	  	LLPanel* panelp = getPanel(panel_name); +  	if (panelp)  	{ -		if(isTabAttached(panel_name)) +		LLView* parentp = panelp->getParent(); +		 +		// Collapse the side bar if the panel or the panel's parent is an attached tab +		if (isTabAttached(panel_name) || (parentp && isTabAttached(parentp->getName())))  		{  			collapseSideBar(); +			panelHidden = true;  		}  		else  		{ -			LLFloaterReg::hideInstance("side_bar_tab", panel_name); +			panelHidden = LLFloaterReg::hideInstance("side_bar_tab", panel_name); +			 +			if (!panelHidden) +			{ +				// Look up the panel in the list of detached tabs. +				for (child_vector_const_iter_t child_it = mDetachedTabs.begin(); child_it != mDetachedTabs.end(); ++child_it) +				{ +					LLPanel *detached_panel = dynamic_cast<LLPanel*>(*child_it); +					 +					if (detached_panel) +					{ +						// Hide this detached panel if it is a parent of our panel +						if (findChildPanel(detached_panel, panel_name, true) != NULL) +						{ +							panelHidden = LLFloaterReg::hideInstance("side_bar_tab", detached_panel->getName()); +							break; +						} +					} +				} +			}  		}  	} +	 +	return panelHidden;  } -  void LLSideTray::togglePanel(LLPanel* &sub_panel, const std::string& panel_name, const LLSD& params)  {  	if(!sub_panel) @@ -1255,38 +1314,6 @@ void LLSideTray::togglePanel(LLPanel* &sub_panel, const std::string& panel_name,  	}  } -// This is just LLView::findChildView specialized to restrict the search to LLPanels. -// Optimization for EXT-4068 to avoid searching down to the individual item level -// when inventories are large. -LLPanel *findChildPanel(LLPanel *panel, const std::string& name, bool recurse) -{ -	for (LLView::child_list_const_iter_t child_it = panel->beginChild(); -		 child_it != panel->endChild(); ++child_it) -	{ -		LLPanel *child_panel = dynamic_cast<LLPanel*>(*child_it); -		if (!child_panel) -			continue; -		if (child_panel->getName() == name) -			return child_panel; -	} -	if (recurse) -	{ -		for (LLView::child_list_const_iter_t child_it = panel->beginChild(); -			 child_it != panel->endChild(); ++child_it) -		{ -			LLPanel *child_panel = dynamic_cast<LLPanel*>(*child_it); -			if (!child_panel) -				continue; -			LLPanel *found_panel = findChildPanel(child_panel,name,recurse); -			if (found_panel) -			{ -				return found_panel; -			} -		} -	} -	return NULL; -} -  LLPanel* LLSideTray::getPanel(const std::string& panel_name)  {  	// Look up the panel in the list of detached tabs. diff --git a/indra/newview/llsidetray.h b/indra/newview/llsidetray.h index 1dddd9e9bc..46765bfbcc 100644 --- a/indra/newview/llsidetray.h +++ b/indra/newview/llsidetray.h @@ -104,7 +104,7 @@ public:  	 */  	LLPanel*	showPanel		(const std::string& panel_name, const LLSD& params = LLSD()); -	void		hidePanel		(const std::string& panel_name); +	bool		hidePanel		(const std::string& panel_name);  	/**  	 * Toggling Side Tray tab which contains "sub_panel" child of "panel_name" panel. diff --git a/indra/newview/llsidetraylistener.cpp b/indra/newview/llsidetraylistener.cpp index 6db13e517d..cd6fa28948 100644 --- a/indra/newview/llsidetraylistener.cpp +++ b/indra/newview/llsidetraylistener.cpp @@ -4,8 +4,25 @@   * @date   2011-02-15   * @brief  Implementation for llsidetraylistener.   *  - * $LicenseInfo:firstyear=2011&license=lgpl$ - * Copyright (c) 2011, Linden Research, Inc. + * $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$   */ diff --git a/indra/newview/llsidetraylistener.h b/indra/newview/llsidetraylistener.h index 0dd2067433..51e2137762 100644 --- a/indra/newview/llsidetraylistener.h +++ b/indra/newview/llsidetraylistener.h @@ -4,8 +4,25 @@   * @date   2011-02-15   * @brief     *  - * $LicenseInfo:firstyear=2011&license=lgpl$ - * Copyright (c) 2011, Linden Research, Inc. + * $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$   */ diff --git a/indra/newview/lltoolpie.cpp b/indra/newview/lltoolpie.cpp index 95bd210ae3..06e0d17b8c 100644 --- a/indra/newview/lltoolpie.cpp +++ b/indra/newview/lltoolpie.cpp @@ -639,6 +639,7 @@ BOOL LLToolPie::handleMouseUp(S32 x, S32 y, MASK mask)  	if (click_action == CLICK_ACTION_NONE				// not doing 1-click action  		&& gSavedSettings.getBOOL("ClickToWalk")		// click to walk enabled  		&& !gAgent.getFlying()							// don't auto-navigate while flying until that works +		&& !gAgentAvatarp->isSitting()  		&& !mBlockClickToWalk							// another behavior hasn't cancelled click to walk  		&& !mPick.mPosGlobal.isExactlyZero()			// valid coordinates for pick  		&& (mPick.mPickType == LLPickInfo::PICK_LAND	// we clicked on land diff --git a/indra/newview/llviewerchat.cpp b/indra/newview/llviewerchat.cpp index 286b16bab2..f5484ff010 100644 --- a/indra/newview/llviewerchat.cpp +++ b/indra/newview/llviewerchat.cpp @@ -36,6 +36,7 @@  #include "llinstantmessage.h" //SYSTEM_FROM  // LLViewerChat +LLViewerChat::font_change_signal_t LLViewerChat::sChatFontChangedSignal;  //static   void LLViewerChat::getChatColor(const LLChat& chat, LLColor4& r_color) @@ -256,3 +257,16 @@ std::string LLViewerChat::getObjectImSLURL(const LLChat& chat, const LLSD& args)  	return url;  } + +//static  +boost::signals2::connection LLViewerChat::setFontChangedCallback(const font_change_signal_t::slot_type& cb) +{ +	return sChatFontChangedSignal.connect(cb); +} + +//static +void LLViewerChat::signalChatFontChanged() +{ +	// Notify all observers that our font has changed +	sChatFontChangedSignal(getChatFont()); +} diff --git a/indra/newview/llviewerchat.h b/indra/newview/llviewerchat.h index 0f15d29f04..c05caf0a95 100644 --- a/indra/newview/llviewerchat.h +++ b/indra/newview/llviewerchat.h @@ -35,6 +35,8 @@  class LLViewerChat   {  public: +	typedef boost::signals2::signal<void (LLFontGL*)> font_change_signal_t; +  	static void getChatColor(const LLChat& chat, LLColor4& r_color);  	static void getChatColor(const LLChat& chat, std::string& r_color_name, F32& r_color_alpha);  	static LLFontGL* getChatFont(); @@ -42,8 +44,12 @@ public:  	static void formatChatMsg(const LLChat& chat, std::string& formated_msg);  	static std::string getSenderSLURL(const LLChat& chat, const LLSD& args); +	static boost::signals2::connection setFontChangedCallback(const font_change_signal_t::slot_type& cb); +	static void signalChatFontChanged(); +  private:  	static std::string getObjectImSLURL(const LLChat& chat, const LLSD& args); +	static font_change_signal_t sChatFontChangedSignal;  }; diff --git a/indra/newview/llviewerinventory.cpp b/indra/newview/llviewerinventory.cpp index 519514d99c..9e58acdcd3 100644 --- a/indra/newview/llviewerinventory.cpp +++ b/indra/newview/llviewerinventory.cpp @@ -183,6 +183,12 @@ public:  			return false;  		} +		if (!LLUI::sSettingGroups["config"]->getBOOL("EnableInventory")) +		{ +				LLNotificationsUtil::add("NoInventory", LLSD(), LLSD(), std::string("SwitchToStandardSkinAndQuit")); +				return true; +		} +  		// support secondlife:///app/inventory/show  		if (params[0].asString() == "show")  		{ @@ -1450,6 +1456,9 @@ private:  	void saveFavoritesSLURLs(); +	// Remove record of current user's favorites from file on disk. +	void removeFavoritesRecordOfUser(); +  	void onLandmarkLoaded(const LLUUID& asset_id, LLLandmark* landmark);  	void storeFavoriteSLURL(const LLUUID& asset_id, std::string& slurl); @@ -1534,6 +1543,10 @@ void LLFavoritesOrderStorage::destroyClass()  	{  		LLFavoritesOrderStorage::instance().saveFavoritesSLURLs();  	} +	else +	{ +		LLFavoritesOrderStorage::instance().removeFavoritesRecordOfUser(); +	}  }  void LLFavoritesOrderStorage::load() @@ -1602,6 +1615,28 @@ void LLFavoritesOrderStorage::saveFavoritesSLURLs()  	LLSDSerialize::toPrettyXML(fav_llsd, file);  } +void LLFavoritesOrderStorage::removeFavoritesRecordOfUser() +{ +	std::string filename = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, "stored_favorites.xml"); +	LLSD fav_llsd; +	llifstream file; +	file.open(filename); +	if (!file.is_open()) return; +	LLSDSerialize::fromXML(fav_llsd, file); + +	LLAvatarName av_name; +	LLAvatarNameCache::get( gAgentID, &av_name ); +	if (fav_llsd.has(av_name.getLegacyName())) +	{ +		fav_llsd.erase(av_name.getLegacyName()); +	} + +	llofstream out_file; +	out_file.open(filename); +	LLSDSerialize::toPrettyXML(fav_llsd, out_file); + +} +  void LLFavoritesOrderStorage::onLandmarkLoaded(const LLUUID& asset_id, LLLandmark* landmark)  {  	if (!landmark) return; diff --git a/indra/newview/llviewermenufile.cpp b/indra/newview/llviewermenufile.cpp index fda291f3c1..2cf8dbec89 100644 --- a/indra/newview/llviewermenufile.cpp +++ b/indra/newview/llviewermenufile.cpp @@ -493,6 +493,7 @@ void upload_new_resource(const std::string& src_filename, std::string name,  	LLSD args;  	std::string exten = gDirUtilp->getExtension(src_filename); +	U32 codec = LLImageBase::getCodecFromExtension(exten);  	LLAssetType::EType asset_type = LLAssetType::AT_NONE;  	std::string error_message; @@ -510,66 +511,20 @@ void upload_new_resource(const std::string& src_filename, std::string name,   		upload_error(error_message, "NoFileExtension", filename, args);  		return;  	} -	else if( exten == "bmp") +	else if (codec != IMG_CODEC_INVALID)  	{ +		// It's an image file, the upload procedure is the same for all  		asset_type = LLAssetType::AT_TEXTURE; -		if (!LLViewerTextureList::createUploadFile(src_filename, -												 filename, -												 IMG_CODEC_BMP )) +		if (!LLViewerTextureList::createUploadFile(src_filename, filename, codec ))  		{  			error_message = llformat( "Problem with file %s:\n\n%s\n", -					src_filename.c_str(), LLImage::getLastError().c_str()); +									 src_filename.c_str(), LLImage::getLastError().c_str());  			args["FILE"] = src_filename;  			args["ERROR"] = LLImage::getLastError();  			upload_error(error_message, "ProblemWithFile", filename, args);  			return;  		}  	} -	else if( exten == "tga") -	{ -		asset_type = LLAssetType::AT_TEXTURE; -		if (!LLViewerTextureList::createUploadFile(src_filename, -												 filename, -												 IMG_CODEC_TGA )) -		{ -			error_message = llformat("Problem with file %s:\n\n%s\n", -					src_filename.c_str(), LLImage::getLastError().c_str()); -			args["FILE"] = src_filename; -			args["ERROR"] = LLImage::getLastError(); -			upload_error(error_message, "ProblemWithFile", filename, args); -			return; -		} -	} -	else if( exten == "jpg" || exten == "jpeg") -	{ -		asset_type = LLAssetType::AT_TEXTURE; -		if (!LLViewerTextureList::createUploadFile(src_filename, -												 filename, -												 IMG_CODEC_JPEG )) -		{ -			error_message = llformat("Problem with file %s:\n\n%s\n", -					src_filename.c_str(), LLImage::getLastError().c_str()); -			args["FILE"] = src_filename; -			args["ERROR"] = LLImage::getLastError(); -			upload_error(error_message, "ProblemWithFile", filename, args); -			return; -		} -	} - 	else if( exten == "png") - 	{ - 		asset_type = LLAssetType::AT_TEXTURE; - 		if (!LLViewerTextureList::createUploadFile(src_filename, - 												 filename, - 												 IMG_CODEC_PNG )) - 		{ - 			error_message = llformat("Problem with file %s:\n\n%s\n", - 					src_filename.c_str(), LLImage::getLastError().c_str()); - 			args["FILE"] = src_filename; - 			args["ERROR"] = LLImage::getLastError(); - 			upload_error(error_message, "ProblemWithFile", filename, args); - 			return; - 		} - 	}  	else if(exten == "wav")  	{  		asset_type = LLAssetType::AT_SOUND;  // tag it as audio diff --git a/indra/newview/llviewertexturelist.cpp b/indra/newview/llviewertexturelist.cpp index 06f6ff23c2..5afed721ac 100644 --- a/indra/newview/llviewertexturelist.cpp +++ b/indra/newview/llviewertexturelist.cpp @@ -927,99 +927,43 @@ void LLViewerTextureList::decodeAllImages(F32 max_time)  BOOL LLViewerTextureList::createUploadFile(const std::string& filename,  										 const std::string& out_filename,  										 const U8 codec) -{ -	// First, load the image. +{	 +	// Load the image +	LLPointer<LLImageFormatted> image = LLImageFormatted::createFromType(codec); +	if (image.isNull()) +	{ +		return FALSE; +	}	 +	if (!image->load(filename)) +	{ +		return FALSE; +	} +	// Decompress or expand it in a raw image structure  	LLPointer<LLImageRaw> raw_image = new LLImageRaw; -	 -	switch (codec) +	if (!image->decode(raw_image, 0.0f))  	{ -		case IMG_CODEC_BMP: -		{ -			LLPointer<LLImageBMP> bmp_image = new LLImageBMP; -			 -			if (!bmp_image->load(filename)) -			{ -				return FALSE; -			} -			 -			if (!bmp_image->decode(raw_image, 0.0f)) -			{ -				return FALSE; -			} -		} -			break; -		case IMG_CODEC_TGA: -		{ -			LLPointer<LLImageTGA> tga_image = new LLImageTGA; -			 -			if (!tga_image->load(filename)) -			{ -				return FALSE; -			} -			 -			if (!tga_image->decode(raw_image)) -			{ -				return FALSE; -			} -			 -			if(	(tga_image->getComponents() != 3) && -			   (tga_image->getComponents() != 4) ) -			{ -				tga_image->setLastError( "Image files with less than 3 or more than 4 components are not supported." ); -				return FALSE; -			} -		} -			break; -		case IMG_CODEC_JPEG: -		{ -			LLPointer<LLImageJPEG> jpeg_image = new LLImageJPEG; -			 -			if (!jpeg_image->load(filename)) -			{ -				return FALSE; -			} -			 -			if (!jpeg_image->decode(raw_image, 0.0f)) -			{ -				return FALSE; -			} -		} -			break; -		case IMG_CODEC_PNG: -		{ -			LLPointer<LLImagePNG> png_image = new LLImagePNG; -			 -			if (!png_image->load(filename)) -			{ -				return FALSE; -			} -			 -			if (!png_image->decode(raw_image, 0.0f)) -			{ -				return FALSE; -			} -		} -			break; -		default: -			return FALSE; +		return FALSE;  	} -	 -	LLPointer<LLImageJ2C> compressedImage = convertToUploadFile(raw_image); -	 -	if( !compressedImage->save(out_filename) ) +	// Check the image constraints +	if ((image->getComponents() != 3) && (image->getComponents() != 4))  	{ -		llinfos << "Couldn't create output file " << out_filename << llendl; +		image->setLastError("Image files with less than 3 or more than 4 components are not supported.");  		return FALSE;  	} -	 -	// test to see if the encode and save worked. +	// Convert to j2c (JPEG2000) and save the file locally +	LLPointer<LLImageJ2C> compressedImage = convertToUploadFile(raw_image);	 +	if (!compressedImage->save(out_filename)) +	{ +		llinfos << "Couldn't create output file : " << out_filename << llendl; +		return FALSE; +	} +	// Test to see if the encode and save worked  	LLPointer<LLImageJ2C> integrity_test = new LLImageJ2C; -	if( !integrity_test->loadAndValidate( out_filename ) ) +	if (!integrity_test->loadAndValidate( out_filename ))  	{ -		llinfos << "Image: " << out_filename << " is corrupt." << llendl; +		llinfos << "Image file : " << out_filename << " is corrupt" << llendl;  		return FALSE;  	} -	  	return TRUE;  } diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index 4305349ea2..e020296842 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -3968,7 +3968,9 @@ BOOL LLViewerWindow::thumbnailSnapshot(LLImageRaw *raw, S32 preview_width, S32 p  	return rawSnapshot(raw, preview_width, preview_height, FALSE, FALSE, show_ui, do_rebuild, type);  } -// Saves the image from the screen to the specified filename and path. +// Saves the image from the screen to a raw image +// Since the required size might be bigger than the available screen, this method rerenders the scene in parts (called subimages) and copy +// the results over to the final raw image.  BOOL LLViewerWindow::rawSnapshot(LLImageRaw *raw, S32 image_width, S32 image_height,   								 BOOL keep_window_aspect, BOOL is_texture, BOOL show_ui, BOOL do_rebuild, ESnapshotType type, S32 max_size)  { @@ -3986,8 +3988,6 @@ BOOL LLViewerWindow::rawSnapshot(LLImageRaw *raw, S32 image_width, S32 image_hei  	// Hide all the UI widgets first and draw a frame  	BOOL prev_draw_ui = gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI) ? TRUE : FALSE; -	show_ui = show_ui ? TRUE : FALSE; -  	if ( prev_draw_ui != show_ui)  	{  		LLPipeline::toggleRenderDebugFeature((void*)LLPipeline::RENDER_DEBUG_FEATURE_UI); @@ -4007,55 +4007,49 @@ BOOL LLViewerWindow::rawSnapshot(LLImageRaw *raw, S32 image_width, S32 image_hei  	// from window  	LLRect window_rect = show_ui ? getWindowRectRaw() : getWorldViewRectRaw();  -	S32 snapshot_width = window_rect.getWidth(); +	S32 snapshot_width  = window_rect.getWidth();  	S32 snapshot_height = window_rect.getHeight();  	// SNAPSHOT -	S32 window_width = snapshot_width; +	S32 window_width  = snapshot_width;  	S32 window_height = snapshot_height; +	// Note: Scaling of the UI is currently *not* supported so we limit the output size if UI is requested  	if (show_ui)  	{ -		image_width = llmin(image_width, window_width); +		// If the user wants the UI, limit the output size to the available screen size +		image_width  = llmin(image_width, window_width);  		image_height = llmin(image_height, window_height);  	}  	F32 scale_factor = 1.0f ; -	if(!keep_window_aspect) //image cropping -	{		 +	if (!keep_window_aspect || (image_width > window_width) || (image_height > window_height)) +	{	 +		// if image cropping or need to enlarge the scene, compute a scale_factor  		F32 ratio = llmin( (F32)window_width / image_width , (F32)window_height / image_height) ; -		snapshot_width = (S32)(ratio * image_width) ; +		snapshot_width  = (S32)(ratio * image_width) ;  		snapshot_height = (S32)(ratio * image_height) ;  		scale_factor = llmax(1.0f, 1.0f / ratio) ;  	} -	else //the scene(window) proportion needs to be maintained. -	{ -		if(image_width > window_width || image_height > window_height) //need to enlarge the scene -		{ -			F32 ratio = llmin( (F32)window_width / image_width , (F32)window_height / image_height) ; -			snapshot_width = (S32)(ratio * image_width) ; -			snapshot_height = (S32)(ratio * image_height) ; -			scale_factor = llmax(1.0f, 1.0f / ratio) ;	 -		} -	}  	if (show_ui && scale_factor > 1.f)  	{ +		// Note: we should never get there...  		llwarns << "over scaling UI not supported." << llendl;  	} -	S32 buffer_x_offset = llfloor(((window_width - snapshot_width) * scale_factor) / 2.f); +	S32 buffer_x_offset = llfloor(((window_width  - snapshot_width)  * scale_factor) / 2.f);  	S32 buffer_y_offset = llfloor(((window_height - snapshot_height) * scale_factor) / 2.f); -	S32 image_buffer_x = llfloor(snapshot_width*scale_factor) ; -	S32 image_buffer_y = llfloor(snapshot_height *scale_factor) ; +	S32 image_buffer_x = llfloor(snapshot_width  * scale_factor) ; +	S32 image_buffer_y = llfloor(snapshot_height * scale_factor) ; -	if(image_buffer_x > max_size || image_buffer_y > max_size) //boundary check to avoid memory overflow +	if ((image_buffer_x > max_size) || (image_buffer_y > max_size)) // boundary check to avoid memory overflow  	{  		scale_factor *= llmin((F32)max_size / image_buffer_x, (F32)max_size / image_buffer_y) ; -		image_buffer_x = llfloor(snapshot_width*scale_factor) ; -		image_buffer_y = llfloor(snapshot_height *scale_factor) ; +		image_buffer_x = llfloor(snapshot_width  * scale_factor) ; +		image_buffer_y = llfloor(snapshot_height * scale_factor) ;  	} -	if(image_buffer_x > 0 && image_buffer_y > 0) +	if ((image_buffer_x > 0) && (image_buffer_y > 0))  	{  		raw->resize(image_buffer_x, image_buffer_y, 3);  	} @@ -4063,7 +4057,7 @@ BOOL LLViewerWindow::rawSnapshot(LLImageRaw *raw, S32 image_width, S32 image_hei  	{  		return FALSE ;  	} -	if(raw->isBufferInvalid()) +	if (raw->isBufferInvalid())  	{  		return FALSE ;  	} @@ -4071,6 +4065,7 @@ BOOL LLViewerWindow::rawSnapshot(LLImageRaw *raw, S32 image_width, S32 image_hei  	BOOL high_res = scale_factor >= 2.f; // Font scaling is slow, only do so if rez is much higher  	if (high_res && show_ui)  	{ +		// Note: we should never get there...  		llwarns << "High res UI snapshot not supported. " << llendl;  		/*send_agent_pause();  		//rescale fonts @@ -4085,6 +4080,8 @@ BOOL LLViewerWindow::rawSnapshot(LLImageRaw *raw, S32 image_width, S32 image_hei  	gObjectList.generatePickList(*LLViewerCamera::getInstance()); +	// Subimages are in fact partial rendering of the final view. This happens when the final view is bigger than the screen. +	// In most common cases, scale_factor is 1 and there's no more than 1 iteration on x and y  	for (int subimage_y = 0; subimage_y < scale_factor; ++subimage_y)  	{  		S32 subimage_y_offset = llclamp(buffer_y_offset - (subimage_y * window_height), 0, window_height);; @@ -4098,69 +4095,70 @@ BOOL LLViewerWindow::rawSnapshot(LLImageRaw *raw, S32 image_width, S32 image_hei  			gDisplaySwapBuffers = FALSE;  			gDepthDirty = TRUE; -			const U32 subfield = subimage_x+(subimage_y*llceil(scale_factor)); - -			if (LLPipeline::sRenderDeferred) -			{ -					display(do_rebuild, scale_factor, subfield, TRUE); -			} -			else -			{ -				display(do_rebuild, scale_factor, subfield, TRUE); -					// Required for showing the GUI in snapshots and performing bloom composite overlay -					// Call even if show_ui is FALSE -				render_ui(scale_factor, subfield); -			} -  			S32 subimage_x_offset = llclamp(buffer_x_offset - (subimage_x * window_width), 0, window_width);  			// handle fractional rows  			U32 read_width = llmax(0, (window_width - subimage_x_offset) -  									llmax(0, (window_width * (subimage_x + 1)) - (buffer_x_offset + raw->getWidth()))); -			for(U32 out_y = 0; out_y < read_height ; out_y++) +			 +			// Skip rendering and sampling altogether if either width or height is degenerated to 0 (common in cropping cases) +			if (read_width && read_height)  			{ -				S32 output_buffer_offset = (  -							(out_y * (raw->getWidth())) // ...plus iterated y... -							+ (window_width * subimage_x) // ...plus subimage start in x... -							+ (raw->getWidth() * window_height * subimage_y) // ...plus subimage start in y... -							- output_buffer_offset_x // ...minus buffer padding x... -							- (output_buffer_offset_y * (raw->getWidth()))  // ...minus buffer padding y... -						) * raw->getComponents(); +				const U32 subfield = subimage_x+(subimage_y*llceil(scale_factor)); +				display(do_rebuild, scale_factor, subfield, TRUE); -				// Ping the wathdog thread every 100 lines to keep us alive (arbitrary number, feel free to change) -				if (out_y % 100 == 0) +				if (!LLPipeline::sRenderDeferred)  				{ -					LLAppViewer::instance()->pingMainloopTimeout("LLViewerWindow::rawSnapshot"); +					// Required for showing the GUI in snapshots and performing bloom composite overlay +					// Call even if show_ui is FALSE +					render_ui(scale_factor, subfield);  				} -				if (type == SNAPSHOT_TYPE_COLOR) +				for (U32 out_y = 0; out_y < read_height ; out_y++)  				{ -					glReadPixels( -						subimage_x_offset, out_y + subimage_y_offset, -						read_width, 1, -						GL_RGB, GL_UNSIGNED_BYTE, -						raw->getData() + output_buffer_offset -					); -				} -				else // SNAPSHOT_TYPE_DEPTH -				{ -					LLPointer<LLImageRaw> depth_line_buffer = new LLImageRaw(read_width, 1, sizeof(GL_FLOAT)); // need to store floating point values -					glReadPixels( -						subimage_x_offset, out_y + subimage_y_offset, -						read_width, 1, -						GL_DEPTH_COMPONENT, GL_FLOAT, -						depth_line_buffer->getData()// current output pixel is beginning of buffer... -					); - -					for (S32 i = 0; i < (S32)read_width; i++) +					S32 output_buffer_offset = (  +												(out_y * (raw->getWidth())) // ...plus iterated y... +												+ (window_width * subimage_x) // ...plus subimage start in x... +												+ (raw->getWidth() * window_height * subimage_y) // ...plus subimage start in y... +												- output_buffer_offset_x // ...minus buffer padding x... +												- (output_buffer_offset_y * (raw->getWidth()))  // ...minus buffer padding y... +												) * raw->getComponents(); +				 +					// Ping the watchdog thread every 100 lines to keep us alive (arbitrary number, feel free to change) +					if (out_y % 100 == 0)  					{ -						F32 depth_float = *(F32*)(depth_line_buffer->getData() + (i * sizeof(F32))); -					 -						F32 linear_depth_float = 1.f / (depth_conversion_factor_1 - (depth_float * depth_conversion_factor_2)); -						U8 depth_byte = F32_to_U8(linear_depth_float, LLViewerCamera::getInstance()->getNear(), LLViewerCamera::getInstance()->getFar()); -						//write converted scanline out to result image -						for(S32 j = 0; j < raw->getComponents(); j++) +						LLAppViewer::instance()->pingMainloopTimeout("LLViewerWindow::rawSnapshot"); +					} +				 +					if (type == SNAPSHOT_TYPE_COLOR) +					{ +						glReadPixels( +									 subimage_x_offset, out_y + subimage_y_offset, +									 read_width, 1, +									 GL_RGB, GL_UNSIGNED_BYTE, +									 raw->getData() + output_buffer_offset +									 ); +					} +					else // SNAPSHOT_TYPE_DEPTH +					{ +						LLPointer<LLImageRaw> depth_line_buffer = new LLImageRaw(read_width, 1, sizeof(GL_FLOAT)); // need to store floating point values +						glReadPixels( +									 subimage_x_offset, out_y + subimage_y_offset, +									 read_width, 1, +									 GL_DEPTH_COMPONENT, GL_FLOAT, +									 depth_line_buffer->getData()// current output pixel is beginning of buffer... +									 ); + +						for (S32 i = 0; i < (S32)read_width; i++)  						{ -							*(raw->getData() + output_buffer_offset + (i * raw->getComponents()) + j) = depth_byte; +							F32 depth_float = *(F32*)(depth_line_buffer->getData() + (i * sizeof(F32))); +					 +							F32 linear_depth_float = 1.f / (depth_conversion_factor_1 - (depth_float * depth_conversion_factor_2)); +							U8 depth_byte = F32_to_U8(linear_depth_float, LLViewerCamera::getInstance()->getNear(), LLViewerCamera::getInstance()->getFar()); +							// write converted scanline out to result image +							for (S32 j = 0; j < raw->getComponents(); j++) +							{ +								*(raw->getData() + output_buffer_offset + (i * raw->getComponents()) + j) = depth_byte; +							}  						}  					}  				} diff --git a/indra/newview/skins/default/colors.xml b/indra/newview/skins/default/colors.xml index 72a4dd7f63..a19eccf748 100644 --- a/indra/newview/skins/default/colors.xml +++ b/indra/newview/skins/default/colors.xml @@ -760,4 +760,21 @@      <color       name="MenuBarProjectBgColor"       reference="MdBlue" /> +   +    <!-- Generic color names (legacy) --> +  <color +    name="white" +    value="1 1 1 1"/> +  <color +    name="black" +    value="0 0 0 1"/> +  <color +    name="red" +    value="1 0 0 1"/> +  <color +    name="green" +    value="0 1 0 1"/> +  <color +    name="blue" +    value="0 0 1 1"/>  </colors> diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml index 51610c0ae0..a5115b0faa 100644 --- a/indra/newview/skins/default/xui/en/menu_viewer.xml +++ b/indra/newview/skins/default/xui/en/menu_viewer.xml @@ -3113,6 +3113,16 @@               function="ToggleControl"               parameter="ImagePipelineUseHTTP" />          </menu_item_check> +        <menu_item_check +         label="HTTP Inventory" +         name="HTTP Inventory"> +            <menu_item_check.on_check +             function="CheckControl" +             parameter="UseHTTPInventory" /> +            <menu_item_check.on_click +             function="ToggleControl" +             parameter="UseHTTPInventory" /> +        </menu_item_check>          <menu_item_call           label="Compress Images"           name="Compress Images"> diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml index 318bc9251f..3fb3717e68 100644 --- a/indra/newview/skins/default/xui/en/notifications.xml +++ b/indra/newview/skins/default/xui/en/notifications.xml @@ -7214,7 +7214,49 @@ The site at '<nolink>[HOST_NAME]</nolink>' in realm '     yestext="Quit"     notext="Don't Quit"/>    </notification> -   + +  <notification + name="NoInventory" + label="" + type="alertmodal" + unique="true"> +    <tag>fail</tag> +    <tag>confirm</tag> +    Viewing inventory is only available in Advanced mode. Would you like to logout and change modes? +    <usetemplate +   name="okcancelbuttons" +   yestext="Quit" +   notext="Don't Quit"/> +  </notification> + +  <notification + name="NoAppearance" + label="" + type="alertmodal" + unique="true"> +    <tag>fail</tag> +    <tag>confirm</tag> +    The appearance editor is only available in Advanced mode. Would you like to logout and change modes? +    <usetemplate +   name="okcancelbuttons" +   yestext="Quit" +   notext="Don't Quit"/> +  </notification> + +  <notification + name="NoSearch" + label="" + type="alertmodal" + unique="true"> +    <tag>fail</tag> +    <tag>confirm</tag> +    Search is only available in Advanced mode. Would you like to logout and change modes? +    <usetemplate +   name="okcancelbuttons" +   yestext="Quit" +   notext="Don't Quit"/> +  </notification> +    <global name="UnsupportedCPU">  - Your CPU speed does not meet the minimum requirements.    </global> diff --git a/indra/newview/skins/default/xui/en/panel_bottomtray.xml b/indra/newview/skins/default/xui/en/panel_bottomtray.xml index a92cc886e7..c8882fd02c 100644 --- a/indra/newview/skins/default/xui/en/panel_bottomtray.xml +++ b/indra/newview/skins/default/xui/en/panel_bottomtray.xml @@ -5,121 +5,121 @@   bg_opaque_color="DkGray"   chrome="true"   follows="left|bottom|right" - focus_root="true"  + focus_root="true"   height="33"   layout="topleft"   left="0"   name="bottom_tray"   top="28"   width="1310"> -    <string +  <string       name="DragIndicationImageName"       value="Accordion_ArrowOpened_Off" /> -    <string +  <string       name="SpeakBtnToolTip"       value="Turns microphone on/off" /> -    <string +  <string       name="VoiceControlBtnToolTip"       value="Shows/hides voice control panel" /> -    <layout_stack +  <layout_stack       border_size="0"       clip="false"       follows="all"       height="28" -     layout="topleft" -     left="0" +   layout="topleft" +   left="0"       mouse_opaque="false"       name="toolbar_stack"       orientation="horizontal"       top="0"       width="1310"> -        <layout_panel +    <layout_panel           auto_resize="false" -         user_resize="false"  +         user_resize="false"           min_width="2"           width="2" /> -        <layout_panel +    <layout_panel           auto_resize="false"           layout="topleft"           max_width="320"           min_width="214" -         height="28"  +         height="28"           mouse_opaque="false" -         name="chat_bar_layout_panel" +		 name="chat_bar_layout_panel"           user_resize="true" -         width="310" > -          <panel -            name="chat_bar" -            filename="panel_nearby_chat_bar.xml" -            left="0" -            height="28" -            width="308" -            top="0" -            mouse_opaque="false" -            follows="left|right" +     width="310" > +      <panel +		   name="chat_bar" +			  filename="panel_nearby_chat_bar.xml" +			  left="0" +			  height="28" +        width="308" +			  top="0" +			  mouse_opaque="false" +			  follows="left|right"            /> -        </layout_panel> -        <!-- +    </layout_panel> +    <!--           This 5px Panel is an indicator of where the resize handle is.           The panel provides a gap between the resize handle icon and a button to the right.            --> -        <layout_panel -         auto_resize="false" -         layout="topleft" -         max_width="5"  -         min_width="5" -         name="chat_bar_resize_handle_panel" -         user_resize="false" -         width="5"> -            <icon -             follows="top|right" -             height="25" -             image_name="ChatBarHandle" -             layout="topleft" -             left="-7" -             name="resize_handle" -             top="4" -             width="5" /> -        </layout_panel> -        <layout_panel -         auto_resize="false" -         follows="left|right" -         height="28" -         layout="topleft" -         min_height="28" -         min_width="59" -         mouse_opaque="false" -         name="speak_panel" -         top_delta="0" -         user_resize="false" -         width="108"> -            <talk_button -             follows="left|right" -             height="23" -             layout="topleft" -             left="0" -             name="talk" -             top="5" -             width="105"> -                <show_button -                 tab_stop="true"> -                    <init_callback -                     function="Button.SetDockableFloaterToggle" -                     parameter="voice_controls" /> -                </show_button> -                <!-- do not remove halign attribute with default value. otherwise it can't be overridden in other locales. +    <layout_panel +     auto_resize="false" +     layout="topleft" +     max_width="5" +     min_width="5" +     name="chat_bar_resize_handle_panel" +     user_resize="false" +     width="5"> +      <icon +       follows="top|right" +       height="25" +       image_name="ChatBarHandle" +       layout="topleft" +       left="-7" +       name="resize_handle" +       top="4" +       width="5" /> +    </layout_panel> +    <layout_panel +        auto_resize="false" +        follows="left|right" +        height="28" +        layout="topleft" +        min_height="28" +        min_width="59" +        mouse_opaque="false" +        name="speak_panel" +        top_delta="0" +        user_resize="false" +        width="108"> +      <talk_button +       follows="left|right" +       height="23" +       layout="topleft" +       left="0" +       name="talk" +       top="5" +       width="105"> +        <show_button +         tab_stop="true"> +          <init_callback +           function="Button.SetDockableFloaterToggle" +           parameter="voice_controls" /> +        </show_button> +        <!-- do not remove halign attribute with default value. otherwise it can't be overridden in other locales.                   & pad_right is default value for long label which can be right aligned. See EXT-6318 --> -                <speak_button -                 halign="center" -                 label="Speak" -                 label_selected="Speak" -                 name="speak_btn" -                 pad_right="20" -                 tab_stop="true" -                 use_ellipses="true" /> -            </talk_button> -        </layout_panel> -        <layout_panel +        <speak_button +         halign="center" +         label="Speak" +         label_selected="Speak" +         name="speak_btn" +         pad_right="20" +         tab_stop="true" +         use_ellipses="true" /> +      </talk_button> +    </layout_panel> +    <layout_panel           auto_resize="false"           follows="right"           height="28" @@ -131,7 +131,7 @@           top_delta="0"           user_resize="false"           width="85"> -            <gesture_combo_list +      <gesture_combo_list               follows="left|right"               height="23"               label="Gesture" @@ -141,46 +141,46 @@               tool_tip="Shows/hides gestures"               top="5"               width="82"> -                <combo_button +        <combo_button                   pad_right="10"                   use_ellipses="true" /> -                <combo_list +        <combo_list                   page_lines="17" /> -            </gesture_combo_list> -        </layout_panel> -        <layout_panel +      </gesture_combo_list> +    </layout_panel> +    <layout_panel           auto_resize="false" -         follows="right" -         height="28" -         layout="topleft" -         min_height="28" -         min_width="52" -         mouse_opaque="false" -         name="movement_panel" -         user_resize="false" -         width="83"> -            <bottomtray_button -             follows="left|right" -             height="23" -             image_pressed="PushButton_Press" -             image_pressed_selected="PushButton_Selected_Press" -             image_selected="PushButton_Selected_Press" -             is_toggle="true" -             label="Move" -             layout="topleft" -             name="movement_btn" -             tool_tip="Shows/hides movement controls" -             top="5" -             use_ellipses="true" -             width="80"> -                <init_callback -                 function="Button.SetDockableFloaterToggle" -                 parameter="moveview" /> -            </bottomtray_button> +     follows="right" +     height="28" +     layout="topleft" +     min_height="28" +     min_width="52" +     mouse_opaque="false" +     name="movement_panel" +     user_resize="false" +     width="83"> +      <bottomtray_button +       follows="left|right" +       height="23" +       image_pressed="PushButton_Press" +       image_pressed_selected="PushButton_Selected_Press" +       image_selected="PushButton_Selected_Press" +       is_toggle="true" +       label="Move" +       layout="topleft" +       name="movement_btn" +       tool_tip="Shows/hides movement controls" +       top="5" +       use_ellipses="true" +       width="80"> +        <init_callback +         function="Button.SetDockableFloaterToggle" +         parameter="moveview" /> +      </bottomtray_button> -        </layout_panel> -        <layout_panel -         auto_resize="false" +    </layout_panel> +    <layout_panel +     auto_resize="false"           follows="left|right"           height="28"           layout="topleft" @@ -190,7 +190,7 @@           name="cam_panel"           user_resize="false"           width="83"> -            <bottomtray_button +      <bottomtray_button               follows="left|right"               height="23"               image_pressed="PushButton_Press" @@ -205,180 +205,180 @@               top="5"               use_ellipses="true"               width="80"> -                <init_callback +        <init_callback                   function="Button.SetDockableFloaterToggle"                   parameter="camera" /> -            </bottomtray_button> -        </layout_panel> -        <layout_panel -         auto_resize="false" -         follows="left|right" -         height="28" -         layout="topleft" -         min_width="40" -         mouse_opaque="false" -         name="snapshot_panel" -         user_resize="false" -         width="39"> -            <bottomtray_button -             follows="left|right" -             height="23" -             image_overlay="Snapshot_Off" -             image_pressed="PushButton_Press" -             image_pressed_selected="PushButton_Selected_Press" -             image_selected="PushButton_Selected_Press" -             is_toggle="true" -             layout="topleft" -             left="0" -             name="snapshots" -             tool_tip="Take snapshot" -             top="5" -             width="36"> -                <init_callback -                 function="Button.SetFloaterToggle" -                 parameter="snapshot" /> -            </bottomtray_button> -        </layout_panel> -        <layout_panel +      </bottomtray_button> +    </layout_panel> +    <layout_panel           auto_resize="false"           follows="left|right"           height="28"           layout="topleft" -         min_height="28" -         min_width="52" -         mouse_opaque="false" -         name="build_btn_panel" -         user_resize="false" -         width="83"> -<!--*FIX: Build Floater is not opened with default registration. Will be fixed soon. +     min_width="40" +		  mouse_opaque="false" +     name="snapshot_panel" +		  user_resize="false" +     width="39"> +      <bottomtray_button +			follows="left|right" +			height="23" +       image_overlay="Snapshot_Off" +			image_pressed="PushButton_Press" +			image_pressed_selected="PushButton_Selected_Press" +			image_selected="PushButton_Selected_Press" +       is_toggle="true" +			layout="topleft" +			left="0" +       name="snapshots" +       tool_tip="Take snapshot" +			top="5" +       width="36"> +        <init_callback +         function="Button.SetFloaterToggle" +         parameter="snapshot" /> +      </bottomtray_button> +    </layout_panel> +    <layout_panel +		  auto_resize="false" +		  follows="left|right" +		  height="28" +		  layout="topleft" +		  min_height="28" +     min_width="52" +		  mouse_opaque="false" +     name="build_btn_panel" +		  user_resize="false" +     width="83"> +      <!--*FIX: Build Floater is not opened with default registration. Will be fixed soon.  Disabled for now.  --> -            <bottomtray_button -             follows="left|right" -             height="23" -             image_pressed="PushButton_Press" -             image_pressed_selected="PushButton_Selected_Press" -             image_selected="PushButton_Selected_Press" -             is_toggle="true" -             label="Build" -             layout="topleft" -             left="0" -             name="build_btn" -             tool_tip="Shows/hides Build Tools" -             top="5" -             use_ellipses="true" -             width="80"> -                <commit_callback -                 function="Build.Toggle" -                 parameter="build" /> -            </bottomtray_button> -        </layout_panel> -        <layout_panel -         auto_resize="false" -         follows="left|right" -         height="28" -         layout="topleft" -         min_height="28" -         min_width="52" -         mouse_opaque="false" -         name="search_btn_panel" -         user_resize="false" -         width="83"> -            <bottomtray_button -             follows="left|right" -             height="23" -             image_pressed="PushButton_Press" -             image_pressed_selected="PushButton_Selected_Press" -             image_selected="PushButton_Selected_Press" -             is_toggle="true" -             label="Search" -             layout="topleft" -             left="0" -             name="search_btn" -             tool_tip="Shows/hides Search" -             top="5" -             use_ellipses="true" -             width="80"> -                <init_callback -                 function="Button.SetFloaterToggle" -                 parameter="search" /> -            </bottomtray_button> -        </layout_panel> -        <layout_panel -         auto_resize="false" -         follows="left|right" -         height="28" -         layout="topleft" +      <bottomtray_button +			follows="left|right" +			height="23" +			image_pressed="PushButton_Press" +			image_pressed_selected="PushButton_Selected_Press" +			image_selected="PushButton_Selected_Press" +       is_toggle="true" +       label="Build" +			layout="topleft" +			left="0" +       name="build_btn" +       tool_tip="Shows/hides Build Tools" +			top="5" +			use_ellipses="true" +       width="80"> +        <commit_callback +         function="Build.Toggle" +         parameter="build" /> +      </bottomtray_button> +    </layout_panel> +    <layout_panel +		  auto_resize="false" +		  follows="left|right" +		  height="28" +		  layout="topleft"           min_height="28" -         min_width="52" +     min_width="52"           mouse_opaque="false" -         name="world_map_btn_panel" +     name="search_btn_panel"           user_resize="false" -         width="83"> -            <bottomtray_button -             follows="left|right" -             height="23" -             image_pressed="PushButton_Press" -             image_pressed_selected="PushButton_Selected_Press" -             image_selected="PushButton_Selected_Press" -             is_toggle="true" -             label="Map" -             layout="topleft" -             left="0" -             name="world_map_btn" -             tool_tip="Shows/hides World Map" -             top="5" -             use_ellipses="true" -             width="80"> -                <init_callback -                 function="Button.SetFloaterToggle" -                 parameter="world_map" /> -            </bottomtray_button> -        </layout_panel> -        <layout_panel -         auto_resize="false" -         follows="left|right" -         height="28" -         layout="topleft" -         min_height="28" -         min_width="52" -         mouse_opaque="false" -         name="mini_map_btn_panel" -         user_resize="false" -         width="83"> -            <bottomtray_button -             follows="left|right" -             height="23" -             image_pressed="PushButton_Press" -             image_pressed_selected="PushButton_Selected_Press" -             image_selected="PushButton_Selected_Press" -             is_toggle="true" -             label="Mini-Map" -             layout="topleft" -             left="0" -             name="mini_map_btn" -             tool_tip="Shows/hides Mini-Map" -             top="5" -             use_ellipses="true" -             width="80"> -                <init_callback -                 function="Button.SetFloaterToggle" -                 parameter="mini_map" /> -            </bottomtray_button> -        </layout_panel> -        <layout_panel -         follows="left|right" -         height="30" -         layout="topleft" -         min_width="95" -         mouse_opaque="false" -         name="chiclet_list_panel" -         top="0" -         user_resize="false" -         width="189"> -<!--*NOTE: min_width of the chiclet_panel (chiclet_list) must be the same +     width="83"> +      <bottomtray_button +			  follows="left|right" +			  height="23" +			  image_pressed="PushButton_Press" +			  image_pressed_selected="PushButton_Selected_Press" +			  image_selected="PushButton_Selected_Press" +       is_toggle="true" +       label="Search" +			  layout="topleft" +			  left="0" +       name="search_btn" +       tool_tip="Shows/hides Search" +			  top="5" +			  use_ellipses="true" +       width="80"> +        <init_callback +         function="Button.SetFloaterToggle" +         parameter="search" /> +      </bottomtray_button> +    </layout_panel> +    <layout_panel +		   auto_resize="false" +     follows="left|right" +		   height="28" +		   layout="topleft" +		   min_height="28" +     min_width="52" +		   mouse_opaque="false" +     name="world_map_btn_panel" +		   user_resize="false" +     width="83"> +      <bottomtray_button +			  follows="left|right" +			  height="23" +			  image_pressed="PushButton_Press" +			  image_pressed_selected="PushButton_Selected_Press" +			  image_selected="PushButton_Selected_Press" +       is_toggle="true" +       label="Map" +			  layout="topleft" +			  left="0" +       name="world_map_btn" +       tool_tip="Shows/hides World Map" +			  top="5" +			  use_ellipses="true" +       width="80"> +        <init_callback +         function="Button.SetFloaterToggle" +         parameter="world_map" /> +      </bottomtray_button> +    </layout_panel> +    <layout_panel +		   auto_resize="false" +     follows="left|right" +		   height="28" +		   layout="topleft" +		   min_height="28" +     min_width="52" +		   mouse_opaque="false" +     name="mini_map_btn_panel" +		   user_resize="false" +     width="83"> +      <bottomtray_button +			  follows="left|right" +			  height="23" +			  image_pressed="PushButton_Press" +			  image_pressed_selected="PushButton_Selected_Press" +			  image_selected="PushButton_Selected_Press" +       is_toggle="true" +       label="Mini-Map" +			  layout="topleft" +			  left="0" +       name="mini_map_btn" +       tool_tip="Shows/hides Mini-Map" +			  top="5" +			  use_ellipses="true" +       width="80"> +        <init_callback +         function="Button.SetFloaterToggle" +         parameter="mini_map" /> +      </bottomtray_button> +    </layout_panel> +    <layout_panel +		   follows="left|right" +		   height="30" +		   layout="topleft" +		   min_width="95" +		   mouse_opaque="false" +		   name="chiclet_list_panel" +		   top="0" +		   user_resize="false" +		   width="189"> +      <!--*NOTE: min_width of the chiclet_panel (chiclet_list) must be the same  as for parent layout_panel (chiclet_list_panel) to resize bottom tray properly. EXT-991--> -            <chiclet_panel +      <chiclet_panel               chiclet_padding="4"               follows="left|right"               height="24" @@ -389,7 +389,7 @@ as for parent layout_panel (chiclet_list_panel) to resize bottom tray properly.               name="chiclet_list"               top="7"               width="189"> -                <button +        <button                   auto_resize="true"                   follows="right"                   height="29" @@ -406,7 +406,7 @@ as for parent layout_panel (chiclet_list_panel) to resize bottom tray properly.                   top="-28"                   visible="false"                   width="7" /> -                <button +        <button                   auto_resize="true"                   follows="right"                   height="29" @@ -423,13 +423,13 @@ as for parent layout_panel (chiclet_list_panel) to resize bottom tray properly.                   top="-28"                   visible="false"                   width="7" /> -            </chiclet_panel> -        </layout_panel> -        <layout_panel auto_resize="false" -                      user_resize="false"  +      </chiclet_panel> +    </layout_panel> +    <layout_panel auto_resize="false" +                      user_resize="false"                        width="4"                        min_width="4"/> -        <layout_panel +    <layout_panel           auto_resize="false"           follows="right"           height="28" @@ -440,7 +440,7 @@ as for parent layout_panel (chiclet_list_panel) to resize bottom tray properly.           top="0"           user_resize="false"           width="37"> -            <chiclet_im_well +      <chiclet_im_well               follows="right"               height="28"               layout="topleft" @@ -449,7 +449,7 @@ as for parent layout_panel (chiclet_list_panel) to resize bottom tray properly.               name="im_well"               top="0"               width="35"> -             <!-- +        <!--  Emulate 4 states of button by background images, see details in EXT-3147. The same should be for notification_well button  xml attribute           Description  image_unselected        "Unlit" - there are no new messages @@ -457,7 +457,7 @@ image_selected          "Unlit" + "Selected" - there are no new messages and the  image_pressed           "Lit" - there are new messages  image_pressed_selected  "Lit" + "Selected" - there are new messages and the Well is open               --> -                <button +        <button                   auto_resize="true"                   follows="right"                   halign="center" @@ -472,13 +472,13 @@ image_pressed_selected  "Lit" + "Selected" - there are new messages and the Well                   name="Unread IM messages"                   tool_tip="Conversations"                   width="34"> -                    <init_callback +          <init_callback                       function="Button.SetDockableFloaterToggle"                       parameter="im_well_window" /> -                </button> -            </chiclet_im_well> -        </layout_panel> -        <layout_panel +        </button> +      </chiclet_im_well> +    </layout_panel> +    <layout_panel           auto_resize="false"           follows="right"           height="28" @@ -489,7 +489,7 @@ image_pressed_selected  "Lit" + "Selected" - there are new messages and the Well           top="0"           user_resize="false"           width="37"> -            <chiclet_notification +      <chiclet_notification               follows="right"               height="23"               layout="topleft" @@ -498,7 +498,7 @@ image_pressed_selected  "Lit" + "Selected" - there are new messages and the Well               name="notification_well"               top="5"               width="35"> -                <button +        <button                   auto_resize="true"                   bottom_pad="3"                   follows="right" @@ -514,17 +514,17 @@ image_pressed_selected  "Lit" + "Selected" - there are new messages and the Well                   name="Unread"                   tool_tip="Notifications"                   width="34"> -                    <init_callback +          <init_callback                       function="Button.SetDockableFloaterToggle"                       parameter="notification_well_window" /> -                </button> -            </chiclet_notification> -        </layout_panel> -      <layout_panel -         auto_resize="false" -         user_resize="false"  -         min_width="4" -         name="DUMMY2" -         width="8" /> -    </layout_stack> +        </button> +      </chiclet_notification> +    </layout_panel> +    <layout_panel +		   auto_resize="false" +		   user_resize="false" +		   min_width="4" +		   name="DUMMY2" +		   width="8" /> +  </layout_stack>  </panel> diff --git a/indra/newview/skins/default/xui/en/widgets/loading_indicator.xml b/indra/newview/skins/default/xui/en/widgets/loading_indicator.xml index 6040d24128..ea1d89c975 100644 --- a/indra/newview/skins/default/xui/en/widgets/loading_indicator.xml +++ b/indra/newview/skins/default/xui/en/widgets/loading_indicator.xml @@ -3,6 +3,20 @@      follows="left|top"      mouse_opaque="false"      name="loading_indicator" -    rotations_per_sec="1.0" -    tab_stop="false" -/> +    images_per_sec="1.0" +    tab_stop="false"> +  <images> +    <image name="Progress_1"/> +    <image name="Progress_2"/> +    <image name="Progress_3"/> +    <image name="Progress_4"/> +    <image name="Progress_5"/> +    <image name="Progress_6"/> +    <image name="Progress_7"/> +    <image name="Progress_8"/> +    <image name="Progress_9"/> +    <image name="Progress_10"/> +    <image name="Progress_11"/> +    <image name="Progress_12"/> +  </images> +</loading_indicator>
\ No newline at end of file diff --git a/indra/newview/skins/minimal/xui/en/panel_bottomtray.xml b/indra/newview/skins/minimal/xui/en/panel_bottomtray.xml index d0a77e8c2a..e0c0bd13d9 100644 --- a/indra/newview/skins/minimal/xui/en/panel_bottomtray.xml +++ b/indra/newview/skins/minimal/xui/en/panel_bottomtray.xml @@ -59,8 +59,8 @@  			  follows="left|right"            />  		</layout_panel> -		<layout_panel -         auto_resize="false" +    <layout_panel +        auto_resize="false"           follows="right"           height="28"           layout="topleft" @@ -163,7 +163,7 @@  			layout="topleft"  			left="0"  			name="destination_btn" -			tool_tip="Shows destinations" +			tool_tip="Shows destinations window"  			top="5"  			is_toggle="true"  			use_ellipses="true" diff --git a/indra/newview/skins/minimal/xui/en/panel_im_control_panel.xml b/indra/newview/skins/minimal/xui/en/panel_im_control_panel.xml index 53def54aca..c3f46f11e0 100644 --- a/indra/newview/skins/minimal/xui/en/panel_im_control_panel.xml +++ b/indra/newview/skins/minimal/xui/en/panel_im_control_panel.xml @@ -23,5 +23,69 @@       orientation="vertical"       top_pad="5"       width="145"> +      <layout_panel +       auto_resize="false" +       follows="top|left|right" +       height="20" +       layout="topleft" +       left="2" +       min_height="20" +       width="140" +       name="view_profile_btn_panel" +       top="0" +       user_resize="false"> +        <button +         follows="left|top|right" +         height="23" +         label="Profile" +         name="view_profile_btn" +         top="0" +         width="140" /> +      </layout_panel> +      <layout_panel +       auto_resize="false" +       follows="top|left|right" +       height="25" +       layout="topleft" +       min_height="25" +       width="140" +       name="add_friend_btn_panel" +       user_resize="false"> +        <button +         follows="left|top|right" +         height="23" +         label="Add Friend" +         name="add_friend_btn" +         top="5" +         width="140" /> +      </layout_panel> +      <layout_panel +       auto_resize="false" +       follows="top|left|right" +       height="25" +       layout="topleft" +       min_height="25" +       width="140" +       name="teleport_btn_panel" +       user_resize="false"> +        <button +             auto_resize="false" +             follows="left|top|right" +             height="23" +             label="Teleport" +             name="teleport_btn" +             tool_tip = "Offer to teleport this person" +             width="140" /> +      </layout_panel> +      <layout_panel +       mouse_opaque="false" +       auto_resize="true" +       follows="top|left" +       height="0" +       layout="topleft" +       min_height="0" +       width="140" +       name="spacer" +       user_resize="false" />      </layout_stack>  </panel> diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py index f0b1973fdf..f671c770ea 100644 --- a/indra/newview/viewer_manifest.py +++ b/indra/newview/viewer_manifest.py @@ -939,9 +939,9 @@ class Linux_i686Manifest(LinuxManifest):              self.path("libdb-5.1.so")              self.path("libdb-5.so")              self.path("libdb.so") -            self.path("libcrypto.so.0.9.8") +            self.path("libcrypto.so.1.0.0")              self.path("libexpat.so.1.5.2") -            self.path("libssl.so.0.9.8") +            self.path("libssl.so.1.0.0")              self.path("libuuid.so")              self.path("libuuid.so.16")              self.path("libuuid.so.16.0.22") diff --git a/indra/test_apps/llplugintest/llmediaplugintest.cpp b/indra/test_apps/llplugintest/llmediaplugintest.cpp index 7164934b26..884b00f0cc 100644 --- a/indra/test_apps/llplugintest/llmediaplugintest.cpp +++ b/indra/test_apps/llplugintest/llmediaplugintest.cpp @@ -2154,6 +2154,10 @@ void LLMediaPluginTest::handleMediaEvent(LLPluginClassMedia* self, EMediaEvent e  		}  		break; +		case MEDIA_EVENT_NAVIGATE_ERROR_PAGE: +			std::cerr <<  "Media event:  MEDIA_EVENT_NAVIGATE_ERROR_PAGE, uri is: " << self->getClickURL() << std::endl; +		break; +			  		case MEDIA_EVENT_CLICK_LINK_HREF:  		{  			std::cerr <<  "Media event:  MEDIA_EVENT_CLICK_LINK_HREF, uri is " << self->getClickURL() << ", target is " << self->getClickTarget() << std::endl; | 
