diff options
Diffstat (limited to 'indra')
72 files changed, 515 insertions, 2445 deletions
| diff --git a/indra/llcommon/llmemory.cpp b/indra/llcommon/llmemory.cpp index 049e962638..b3debf3550 100644 --- a/indra/llcommon/llmemory.cpp +++ b/indra/llcommon/llmemory.cpp @@ -57,10 +57,6 @@ U32Kilobytes LLMemory::sAllocatedPageSizeInKB(0);  U32Kilobytes LLMemory::sMaxHeapSizeInKB(U32_MAX);  BOOL LLMemory::sEnableMemoryFailurePrevention = FALSE; -#if __DEBUG_PRIVATE_MEM__ -LLPrivateMemoryPoolManager::mem_allocation_info_t LLPrivateMemoryPoolManager::sMemAllocationTracker; -#endif -  void ll_assert_aligned_func(uintptr_t ptr,U32 alignment)  {  #if defined(LL_WINDOWS) && defined(LL_DEBUG_BUFFER_OVERRUN) @@ -154,17 +150,12 @@ void LLMemory::logMemoryInfo(BOOL update)  	if(update)  	{  		updateMemoryInfo() ; -		LLPrivateMemoryPoolManager::getInstance()->updateStatistics() ;  	}  	LL_INFOS() << "Current allocated physical memory(KB): " << sAllocatedMemInKB << LL_ENDL ;  	LL_INFOS() << "Current allocated page size (KB): " << sAllocatedPageSizeInKB << LL_ENDL ;  	LL_INFOS() << "Current available physical memory(KB): " << sAvailPhysicalMemInKB << LL_ENDL ;  	LL_INFOS() << "Current max usable memory(KB): " << sMaxPhysicalMemInKB << LL_ENDL ; - -	LL_INFOS() << "--- private pool information -- " << LL_ENDL ; -	LL_INFOS() << "Total reserved (KB): " << LLPrivateMemoryPoolManager::getInstance()->mTotalReservedSize / 1024 << LL_ENDL ; -	LL_INFOS() << "Total allocated (KB): " << LLPrivateMemoryPoolManager::getInstance()->mTotalAllocatedSize / 1024 << LL_ENDL ;  }  //return 0: everything is normal; @@ -356,1729 +347,6 @@ U64 LLMemory::getCurrentRSS()  #endif -//-------------------------------------------------------------------------------------------------- -//-------------------------------------------------------------------------------------------------- -//minimum slot size and minimal slot size interval -const U32 ATOMIC_MEM_SLOT = 16 ; //bytes - -//minimum block sizes (page size) for small allocation, medium allocation, large allocation  -const U32 MIN_BLOCK_SIZES[LLPrivateMemoryPool::SUPER_ALLOCATION] = {2 << 10, 4 << 10, 16 << 10} ; // - -//maximum block sizes for small allocation, medium allocation, large allocation  -const U32 MAX_BLOCK_SIZES[LLPrivateMemoryPool::SUPER_ALLOCATION] = {64 << 10, 1 << 20, 4 << 20} ; - -//minimum slot sizes for small allocation, medium allocation, large allocation  -const U32 MIN_SLOT_SIZES[LLPrivateMemoryPool::SUPER_ALLOCATION]  = {ATOMIC_MEM_SLOT, 2 << 10, 512 << 10}; - -//maximum slot sizes for small allocation, medium allocation, large allocation  -const U32 MAX_SLOT_SIZES[LLPrivateMemoryPool::SUPER_ALLOCATION]  = {(2 << 10) - ATOMIC_MEM_SLOT, (512 - 2) << 10, 4 << 20}; - -//size of a block with multiple slots can not exceed CUT_OFF_SIZE -const U32 CUT_OFF_SIZE = (64 << 10) ; //64 KB - -//max number of slots in a block -const U32 MAX_NUM_SLOTS_IN_A_BLOCK = llmin(MIN_BLOCK_SIZES[0] / ATOMIC_MEM_SLOT, ATOMIC_MEM_SLOT * 8) ; - -//------------------------------------------------------------- -//align val to be integer times of ATOMIC_MEM_SLOT -U32 align(U32 val) -{ -	U32 aligned = (val / ATOMIC_MEM_SLOT) * ATOMIC_MEM_SLOT ; -	if(aligned < val) -	{ -		aligned += ATOMIC_MEM_SLOT ; -	} - -	return aligned ; -} - -//------------------------------------------------------------- -//class LLPrivateMemoryPool::LLMemoryBlock -//------------------------------------------------------------- -// -//each memory block could fit for two page sizes: 0.75 * mSlotSize, which starts from the beginning of the memory chunk and grow towards the end of the -//the block; another is mSlotSize, which starts from the end of the block and grows towards the beginning of the block. -// -LLPrivateMemoryPool::LLMemoryBlock::LLMemoryBlock() -{ -	//empty -} -		 -LLPrivateMemoryPool::LLMemoryBlock::~LLMemoryBlock()  -{ -	//empty -} - -//create and initialize a memory block -void LLPrivateMemoryPool::LLMemoryBlock::init(char* buffer, U32 buffer_size, U32 slot_size) -{ -	mBuffer = buffer ; -	mBufferSize = buffer_size ; -	mSlotSize = slot_size ; -	mTotalSlots = buffer_size / mSlotSize ;	 -	 -	llassert_always(buffer_size / mSlotSize <= MAX_NUM_SLOTS_IN_A_BLOCK) ; //max number is 128 -	 -	mAllocatedSlots = 0 ; -	mDummySize = 0 ; - -	//init the bit map. -	//mark free bits	 -	if(mTotalSlots > 32) //reserve extra space from mBuffer to store bitmap if needed. -	{ -		mDummySize = ATOMIC_MEM_SLOT ;		 -		mTotalSlots -= (mDummySize + mSlotSize - 1) / mSlotSize ; -		mUsageBits = 0 ; - -		S32 usage_bit_len = (mTotalSlots + 31) / 32 ; -		 -		for(S32 i = 0 ; i < usage_bit_len - 1 ; i++) -		{ -			*((U32*)mBuffer + i) = 0 ; -		} -		for(S32 i = usage_bit_len - 1 ; i < mDummySize / sizeof(U32) ; i++) -		{ -			*((U32*)mBuffer + i) = 0xffffffff ; -		} - -		if(mTotalSlots & 31) -		{ -			*((U32*)mBuffer + usage_bit_len - 2) = (0xffffffff << (mTotalSlots & 31)) ; -		}		 -	}	 -	else//no extra bitmap space reserved -	{ -		mUsageBits = 0 ; -		if(mTotalSlots & 31) -		{ -			mUsageBits = (0xffffffff << (mTotalSlots & 31)) ; -		} -	} - -	mSelf = this ; -	mNext = NULL ; -	mPrev = NULL ; - -	llassert_always(mTotalSlots > 0) ; -} - -//mark this block to be free with the memory [mBuffer, mBuffer + mBufferSize). -void LLPrivateMemoryPool::LLMemoryBlock::setBuffer(char* buffer, U32 buffer_size) -{ -	mBuffer = buffer ; -	mBufferSize = buffer_size ; -	mSelf = NULL ; -	mTotalSlots = 0 ; //set the block is free. -} - -//reserve a slot -char* LLPrivateMemoryPool::LLMemoryBlock::allocate()  -{ -	llassert_always(mAllocatedSlots < mTotalSlots) ; -	 -	//find a free slot -	U32* bits = NULL ; -	U32  k = 0 ; -	if(mUsageBits != 0xffffffff) -	{ -		bits = &mUsageBits ; -	} -	else if(mDummySize > 0)//go to extra space -	{		 -		for(S32 i = 0 ; i < mDummySize / sizeof(U32); i++) -		{ -			if(*((U32*)mBuffer + i) != 0xffffffff) -			{ -				bits = (U32*)mBuffer + i ; -				k = i + 1 ; -				break ; -			} -		} -	}	 -	S32 idx = 0 ; -	U32 tmp = *bits ; -	for(; tmp & 1 ; tmp >>= 1, idx++) ; - -	//set the slot reserved -	if(!idx) -	{ -		*bits |= 1 ; -	} -	else -	{ -		*bits |= (1 << idx) ; -	} - -	mAllocatedSlots++ ; -	 -	return mBuffer + mDummySize + (k * 32 + idx) * mSlotSize ; -} - -//free a slot -void  LLPrivateMemoryPool::LLMemoryBlock::freeMem(void* addr)  -{ -	//bit index -	uintptr_t idx = ((uintptr_t)addr - (uintptr_t)mBuffer - mDummySize) / mSlotSize ; - -	U32* bits = &mUsageBits ; -	if(idx >= 32) -	{ -		bits = (U32*)mBuffer + (idx - 32) / 32 ; -	} - -	//reset the bit -	if(idx & 31) -	{ -		*bits &= ~(1 << (idx & 31)) ; -	} -	else -	{ -		*bits &= ~1 ; -	} - -	mAllocatedSlots-- ; -} - -//for debug use: reset the entire bitmap. -void  LLPrivateMemoryPool::LLMemoryBlock::resetBitMap() -{ -	for(S32 i = 0 ; i < mDummySize / sizeof(U32) ; i++) -	{ -		*((U32*)mBuffer + i) = 0 ; -	} -	mUsageBits = 0 ; -} -//------------------------------------------------------------------- -//class LLMemoryChunk -//-------------------------------------------------------------------- -LLPrivateMemoryPool::LLMemoryChunk::LLMemoryChunk() -{ -	//empty -} - -LLPrivateMemoryPool::LLMemoryChunk::~LLMemoryChunk() -{ -	//empty -} - -//create and init a memory chunk -void LLPrivateMemoryPool::LLMemoryChunk::init(char* buffer, U32 buffer_size, U32 min_slot_size, U32 max_slot_size, U32 min_block_size, U32 max_block_size)  -{ -	mBuffer = buffer ; -	mBufferSize = buffer_size ; -	mAlloatedSize = 0 ; - -	mMetaBuffer = mBuffer + sizeof(LLMemoryChunk) ; - -	mMinBlockSize = min_block_size; //page size -	mMinSlotSize = min_slot_size; -	mMaxSlotSize = max_slot_size ; -	mBlockLevels = mMaxSlotSize / mMinSlotSize ; -	mPartitionLevels = max_block_size / mMinBlockSize + 1 ; - -	S32 max_num_blocks = (buffer_size - sizeof(LLMemoryChunk) - mBlockLevels * sizeof(LLMemoryBlock*) - mPartitionLevels * sizeof(LLMemoryBlock*)) /  -		                 (mMinBlockSize + sizeof(LLMemoryBlock)) ; -	//meta data space -	mBlocks = (LLMemoryBlock*)mMetaBuffer ; //space reserved for all memory blocks. -	mAvailBlockList = (LLMemoryBlock**)((char*)mBlocks + sizeof(LLMemoryBlock) * max_num_blocks) ;  -	mFreeSpaceList = (LLMemoryBlock**)((char*)mAvailBlockList + sizeof(LLMemoryBlock*) * mBlockLevels) ;  -	 -	//data buffer, which can be used for allocation -	mDataBuffer = (char*)mFreeSpaceList + sizeof(LLMemoryBlock*) * mPartitionLevels ; -	 -	//alignmnet -	mDataBuffer = mBuffer + align(mDataBuffer - mBuffer) ; -	 -	//init -	for(U32 i = 0 ; i < mBlockLevels; i++) -	{ -		mAvailBlockList[i] = NULL ; -	} -	for(U32 i = 0 ; i < mPartitionLevels ; i++) -	{ -		mFreeSpaceList[i] = NULL ; -	} - -	//assign the entire chunk to the first block -	mBlocks[0].mPrev = NULL ; -	mBlocks[0].mNext = NULL ; -	mBlocks[0].setBuffer(mDataBuffer, buffer_size - (mDataBuffer - mBuffer)) ; -	addToFreeSpace(&mBlocks[0]) ; - -	mNext = NULL ; -	mPrev = NULL ; -} - -//static  -U32 LLPrivateMemoryPool::LLMemoryChunk::getMaxOverhead(U32 data_buffer_size, U32 min_slot_size,  -													   U32 max_slot_size, U32 min_block_size, U32 max_block_size) -{ -	//for large allocations, reserve some extra memory for meta data to avoid wasting much  -	if(data_buffer_size / min_slot_size < 64) //large allocations -	{ -		U32 overhead = sizeof(LLMemoryChunk) + (data_buffer_size / min_block_size) * sizeof(LLMemoryBlock) + -			sizeof(LLMemoryBlock*) * (max_slot_size / min_slot_size) + sizeof(LLMemoryBlock*) * (max_block_size / min_block_size + 1) ; - -		//round to integer times of min_block_size -		overhead = ((overhead + min_block_size - 1) / min_block_size) * min_block_size ; -		return overhead ; -	} -	else -	{ -		return 0 ; //do not reserve extra overhead if for small allocations -	} -} - -char* LLPrivateMemoryPool::LLMemoryChunk::allocate(U32 size) -{ -	if(mMinSlotSize > size) -	{ -		size = mMinSlotSize ; -	} -	if(mAlloatedSize + size  > mBufferSize - (mDataBuffer - mBuffer)) -	{ -		return NULL ; //no enough space in this chunk. -	} - -	char* p = NULL ; -	U32 blk_idx = getBlockLevel(size); - -	LLMemoryBlock* blk = NULL ; - -	//check if there is free block available -	if(mAvailBlockList[blk_idx]) -	{ -		blk = mAvailBlockList[blk_idx] ; -		p = blk->allocate() ; -		 -		if(blk->isFull()) -		{ -			popAvailBlockList(blk_idx) ; -		} -	} - -	//ask for a new block -	if(!p) -	{ -		blk = addBlock(blk_idx) ; -		if(blk) -		{ -			p = blk->allocate() ; - -			if(blk->isFull()) -			{ -				popAvailBlockList(blk_idx) ; -			} -		} -	} - -	//ask for space from larger blocks -	if(!p) -	{ -		for(S32 i = blk_idx + 1 ; i < mBlockLevels; i++) -		{ -			if(mAvailBlockList[i]) -			{ -				blk = mAvailBlockList[i] ; -				p = blk->allocate() ; - -				if(blk->isFull()) -				{ -					popAvailBlockList(i) ; -				} -				break ; -			} -		} -	} - -	if(p && blk) -	{		 -		mAlloatedSize += blk->getSlotSize() ; -	} -	return p ; -} - -void LLPrivateMemoryPool::LLMemoryChunk::freeMem(void* addr) -{	 -	U32 blk_idx = getPageIndex((uintptr_t)addr) ; -	LLMemoryBlock* blk = (LLMemoryBlock*)(mMetaBuffer + blk_idx * sizeof(LLMemoryBlock)) ; -	blk = blk->mSelf ; - -	bool was_full = blk->isFull() ; -	blk->freeMem(addr) ; -	mAlloatedSize -= blk->getSlotSize() ; - -	if(blk->empty()) -	{ -		removeBlock(blk) ; -	} -	else if(was_full) -	{ -		addToAvailBlockList(blk) ; -	}	 -} - -bool LLPrivateMemoryPool::LLMemoryChunk::empty() -{ -	return !mAlloatedSize ; -} - -bool LLPrivateMemoryPool::LLMemoryChunk::containsAddress(const char* addr) const -{ -	return (uintptr_t)mBuffer <= (uintptr_t)addr && (uintptr_t)mBuffer + mBufferSize > (uintptr_t)addr ; -} - -//debug use -void LLPrivateMemoryPool::LLMemoryChunk::dump() -{ -#if 0 -	//sanity check -	//for(S32 i = 0 ; i < mBlockLevels ; i++) -	//{ -	//	LLMemoryBlock* blk = mAvailBlockList[i] ; -	//	while(blk) -	//	{ -	//		blk_list.push_back(blk) ; -	//		blk = blk->mNext ; -	//	} -	//} -	for(S32 i = 0 ; i < mPartitionLevels ; i++) -	{ -		LLMemoryBlock* blk = mFreeSpaceList[i] ; -		while(blk) -		{ -			blk_list.push_back(blk) ; -			blk = blk->mNext ; -		} -	} - -	std::sort(blk_list.begin(), blk_list.end(), LLMemoryBlock::CompareAddress()); - -	U32 total_size = blk_list[0]->getBufferSize() ; -	for(U32 i = 1 ; i < blk_list.size(); i++) -	{ -		total_size += blk_list[i]->getBufferSize() ; -		if((uintptr_t)blk_list[i]->getBuffer() < (uintptr_t)blk_list[i-1]->getBuffer() + blk_list[i-1]->getBufferSize()) -		{ -			LL_ERRS() << "buffer corrupted." << LL_ENDL ; -		} -	} - -	llassert_always(total_size + mMinBlockSize >= mBufferSize - ((uintptr_t)mDataBuffer - (uintptr_t)mBuffer)) ; - -	U32 blk_num = (mBufferSize - (mDataBuffer - mBuffer)) / mMinBlockSize ; -	for(U32 i = 0 ; i < blk_num ; ) -	{ -		LLMemoryBlock* blk = &mBlocks[i] ; -		if(blk->mSelf) -		{ -			U32 end = blk->getBufferSize() / mMinBlockSize ; -			for(U32 j = 0 ; j < end ; j++) -			{ -				llassert_always(blk->mSelf == blk || !blk->mSelf) ; -			} -			i += end ; -		} -		else -		{ -			LL_ERRS() << "gap happens" << LL_ENDL ; -		} -	} -#endif -#if 0 -	LL_INFOS() << "---------------------------" << LL_ENDL ; -	LL_INFOS() << "Chunk buffer: " << (uintptr_t)getBuffer() << " size: " << getBufferSize() << LL_ENDL ; - -	LL_INFOS() << "available blocks ... " << LL_ENDL ; -	for(S32 i = 0 ; i < mBlockLevels ; i++) -	{ -		LLMemoryBlock* blk = mAvailBlockList[i] ; -		while(blk) -		{ -			LL_INFOS() << "blk buffer " << (uintptr_t)blk->getBuffer() << " size: " << blk->getBufferSize() << LL_ENDL ; -			blk = blk->mNext ; -		} -	} - -	LL_INFOS() << "free blocks ... " << LL_ENDL ; -	for(S32 i = 0 ; i < mPartitionLevels ; i++) -	{ -		LLMemoryBlock* blk = mFreeSpaceList[i] ; -		while(blk) -		{ -			LL_INFOS() << "blk buffer " << (uintptr_t)blk->getBuffer() << " size: " << blk->getBufferSize() << LL_ENDL ; -			blk = blk->mNext ; -		} -	} -#endif -} - -//compute the size for a block, the size is round to integer times of mMinBlockSize. -U32 LLPrivateMemoryPool::LLMemoryChunk::calcBlockSize(U32 slot_size) -{ -	// -	//Note: we try to make a block to have 32 slots if the size is not over 32 pages -	//32 is the number of bits of an integer in a 32-bit system -	// - -	U32 block_size; -	U32 cut_off_size = llmin(CUT_OFF_SIZE, (U32)(mMinBlockSize << 5)) ; - -	if((slot_size << 5) <= mMinBlockSize)//for small allocations, return one page  -	{ -		block_size = mMinBlockSize ; -	} -	else if(slot_size >= cut_off_size)//for large allocations, return one-slot block -	{ -		block_size = (slot_size / mMinBlockSize) * mMinBlockSize ; -		if(block_size < slot_size) -		{ -			block_size += mMinBlockSize ; -		} -	} -	else //medium allocations -	{ -		if((slot_size << 5) >= cut_off_size) -		{ -			block_size = cut_off_size ; -		} -		else -		{ -			block_size = ((slot_size << 5) / mMinBlockSize) * mMinBlockSize ; -		} -	} - -	llassert_always(block_size >= slot_size) ; - -	return block_size ; -} - -//create a new block in the chunk -LLPrivateMemoryPool::LLMemoryBlock* LLPrivateMemoryPool::LLMemoryChunk::addBlock(U32 blk_idx) -{	 -	U32 slot_size = mMinSlotSize * (blk_idx + 1) ; -	U32 preferred_block_size = calcBlockSize(slot_size) ;	 -	U16 idx = getPageLevel(preferred_block_size);  -	LLMemoryBlock* blk = NULL ; -	 -	if(mFreeSpaceList[idx])//if there is free slot for blk_idx -	{ -		blk = createNewBlock(mFreeSpaceList[idx], preferred_block_size, slot_size, blk_idx) ; -	} -	else if(mFreeSpaceList[mPartitionLevels - 1]) //search free pool -	{		 -		blk = createNewBlock(mFreeSpaceList[mPartitionLevels - 1], preferred_block_size, slot_size, blk_idx) ; -	} -	else //search for other non-preferred but enough space slot. -	{ -		S32 min_idx = 0 ; -		if(slot_size > mMinBlockSize) -		{ -			min_idx = getPageLevel(slot_size) ; -		} -		for(S32 i = (S32)idx - 1 ; i >= min_idx ; i--) //search the small slots first -		{ -			if(mFreeSpaceList[i]) -			{ -				U32 new_preferred_block_size = mFreeSpaceList[i]->getBufferSize(); -				new_preferred_block_size = (new_preferred_block_size / mMinBlockSize) * mMinBlockSize ; //round to integer times of mMinBlockSize. - -				//create a NEW BLOCK THERE. -				if(new_preferred_block_size >= slot_size) //at least there is space for one slot. -				{ -					 -					blk = createNewBlock(mFreeSpaceList[i], new_preferred_block_size, slot_size, blk_idx) ; -				} -				break ; -			}  -		} - -		if(!blk) -		{ -			for(U16 i = idx + 1 ; i < mPartitionLevels - 1; i++) //search the large slots  -			{ -				if(mFreeSpaceList[i]) -				{ -					//create a NEW BLOCK THERE. -					blk = createNewBlock(mFreeSpaceList[i], preferred_block_size, slot_size, blk_idx) ; -					break ; -				}  -			} -		} -	} - -	return blk ; -} - -//create a new block at the designed location -LLPrivateMemoryPool::LLMemoryBlock* LLPrivateMemoryPool::LLMemoryChunk::createNewBlock(LLMemoryBlock* blk, U32 buffer_size, U32 slot_size, U32 blk_idx) -{ -	//unlink from the free space -	removeFromFreeSpace(blk) ; - -	//check the rest space -	U32 new_free_blk_size = blk->getBufferSize() - buffer_size ;	 -	if(new_free_blk_size < mMinBlockSize) //can not partition the memory into size smaller than mMinBlockSize -	{ -		new_free_blk_size = 0 ; //discard the last small extra space. -	}			 - -	//add the rest space back to the free list -	if(new_free_blk_size > 0) //blk still has free space -	{ -		LLMemoryBlock* next_blk = blk + (buffer_size / mMinBlockSize) ; -		next_blk->mPrev = NULL ; -		next_blk->mNext = NULL ; -		next_blk->setBuffer(blk->getBuffer() + buffer_size, new_free_blk_size) ; -		addToFreeSpace(next_blk) ; -	} - -	blk->init(blk->getBuffer(), buffer_size, slot_size) ; -	//insert to the available block list... -	mAvailBlockList[blk_idx] = blk ; - -	//mark the address map: all blocks covered by this block space pointing back to this block. -	U32 end = (buffer_size / mMinBlockSize) ; -	for(U32 i = 1 ; i < end ; i++) -	{ -		(blk + i)->mSelf = blk ; -	} - -	return blk ; -} - -//delete a block, release the block to the free pool. -void LLPrivateMemoryPool::LLMemoryChunk::removeBlock(LLMemoryBlock* blk) -{ -	//remove from the available block list -	if(blk->mPrev) -	{ -		blk->mPrev->mNext = blk->mNext ; -	} -	if(blk->mNext) -	{ -		blk->mNext->mPrev = blk->mPrev ; -	} -	U32 blk_idx = getBlockLevel(blk->getSlotSize()); -	if(mAvailBlockList[blk_idx] == blk) -	{ -		mAvailBlockList[blk_idx] = blk->mNext ; -	} - -	blk->mNext = NULL ; -	blk->mPrev = NULL ; -	 -	//mark it free -	blk->setBuffer(blk->getBuffer(), blk->getBufferSize()) ; - -#if 1 -	//merge blk with neighbors if possible -	if(blk->getBuffer() > mDataBuffer) //has the left neighbor -	{ -		if((blk - 1)->mSelf->isFree()) -		{ -			LLMemoryBlock* left_blk = (blk - 1)->mSelf ; -			removeFromFreeSpace((blk - 1)->mSelf); -			left_blk->setBuffer(left_blk->getBuffer(), left_blk->getBufferSize() + blk->getBufferSize()) ; -			blk = left_blk ; -		} -	} -	if(blk->getBuffer() + blk->getBufferSize() <= mBuffer + mBufferSize - mMinBlockSize) //has the right neighbor -	{ -		U32 d = blk->getBufferSize() / mMinBlockSize ; -		if((blk + d)->isFree()) -		{ -			LLMemoryBlock* right_blk = blk + d ; -			removeFromFreeSpace(blk + d) ; -			blk->setBuffer(blk->getBuffer(), blk->getBufferSize() + right_blk->getBufferSize()) ; -		} -	} -#endif -	 -	addToFreeSpace(blk) ; - -	return ; -} - -//the top block in the list is full, pop it out of the list -void LLPrivateMemoryPool::LLMemoryChunk::popAvailBlockList(U32 blk_idx)  -{ -	if(mAvailBlockList[blk_idx]) -	{ -		LLMemoryBlock* next = mAvailBlockList[blk_idx]->mNext ; -		if(next) -		{ -			next->mPrev = NULL ; -		} -		mAvailBlockList[blk_idx]->mPrev = NULL ; -		mAvailBlockList[blk_idx]->mNext = NULL ; -		mAvailBlockList[blk_idx] = next ; -	} -} - -//add the block back to the free pool -void LLPrivateMemoryPool::LLMemoryChunk::addToFreeSpace(LLMemoryBlock* blk)  -{ -	llassert_always(!blk->mPrev) ; -	llassert_always(!blk->mNext) ; - -	U16 free_idx = blk->getBufferSize() / mMinBlockSize - 1; - -	(blk + free_idx)->mSelf = blk ; //mark the end pointing back to the head. -	free_idx = llmin(free_idx, (U16)(mPartitionLevels - 1)) ; - -	blk->mNext = mFreeSpaceList[free_idx] ; -	if(mFreeSpaceList[free_idx]) -	{ -		mFreeSpaceList[free_idx]->mPrev = blk ; -	} -	mFreeSpaceList[free_idx] = blk ; -	blk->mPrev = NULL ; -	blk->mSelf = blk ; -	 -	return ; -} - -//remove the space from the free pool -void LLPrivateMemoryPool::LLMemoryChunk::removeFromFreeSpace(LLMemoryBlock* blk)  -{ -	U16 free_idx = blk->getBufferSize() / mMinBlockSize - 1; -	free_idx = llmin(free_idx, (U16)(mPartitionLevels - 1)) ; - -	if(mFreeSpaceList[free_idx] == blk) -	{ -		mFreeSpaceList[free_idx] = blk->mNext ; -	} -	if(blk->mPrev) -	{ -		blk->mPrev->mNext = blk->mNext ; -	} -	if(blk->mNext) -	{ -		blk->mNext->mPrev = blk->mPrev ; -	} -	blk->mNext = NULL ; -	blk->mPrev = NULL ; -	blk->mSelf = NULL ; - -	return ; -} - -void LLPrivateMemoryPool::LLMemoryChunk::addToAvailBlockList(LLMemoryBlock* blk)  -{ -	llassert_always(!blk->mPrev) ; -	llassert_always(!blk->mNext) ; - -	U32 blk_idx = getBlockLevel(blk->getSlotSize()); - -	blk->mNext = mAvailBlockList[blk_idx] ; -	if(blk->mNext) -	{ -		blk->mNext->mPrev = blk ; -	} -	blk->mPrev = NULL ; -	mAvailBlockList[blk_idx] = blk ; - -	return ; -} - -U32 LLPrivateMemoryPool::LLMemoryChunk::getPageIndex(uintptr_t addr) -{ -	return (addr - (uintptr_t)mDataBuffer) / mMinBlockSize ; -} - -//for mAvailBlockList -U32 LLPrivateMemoryPool::LLMemoryChunk::getBlockLevel(U32 size) -{ -	llassert(size >= mMinSlotSize && size <= mMaxSlotSize) ; - -	//start from 0 -	return (size + mMinSlotSize - 1) / mMinSlotSize - 1 ; -} - -//for mFreeSpaceList -U16 LLPrivateMemoryPool::LLMemoryChunk::getPageLevel(U32 size) -{ -	//start from 0 -	U16 level = size / mMinBlockSize - 1 ; -	if(level >= mPartitionLevels) -	{ -		level = mPartitionLevels - 1 ; -	} -	return level ; -} - -//------------------------------------------------------------------- -//class LLPrivateMemoryPool -//-------------------------------------------------------------------- -const U32 CHUNK_SIZE = 4 << 20 ; //4 MB -const U32 LARGE_CHUNK_SIZE = 4 * CHUNK_SIZE ; //16 MB -LLPrivateMemoryPool::LLPrivateMemoryPool(S32 type, U32 max_pool_size) : -	mMutexp(NULL),	 -	mReservedPoolSize(0), -	mHashFactor(1), -	mType(type), -	mMaxPoolSize(max_pool_size) -{ -	if(type == STATIC_THREADED || type == VOLATILE_THREADED) -	{ -		mMutexp = new LLMutex(NULL) ; -	} - -	for(S32 i = 0 ; i < SUPER_ALLOCATION ; i++) -	{ -		mChunkList[i] = NULL ; -	}	 -	 -	mNumOfChunks = 0 ; -} - -LLPrivateMemoryPool::~LLPrivateMemoryPool() -{ -	destroyPool(); -	delete mMutexp ; -} - -char* LLPrivateMemoryPool::allocate(U32 size) -{	 -	if(!size) -	{ -		return NULL ; -	} - -	//if the asked size larger than MAX_BLOCK_SIZE, fetch from heap directly, the pool does not manage it -	if(size >= CHUNK_SIZE) -	{ -		return (char*)ll_aligned_malloc_16(size) ; -	} - -	char* p = NULL ; - -	//find the appropriate chunk -	S32 chunk_idx = getChunkIndex(size) ; -	 -	lock() ; - -	LLMemoryChunk* chunk = mChunkList[chunk_idx]; -	while(chunk) -	{ -		if((p = chunk->allocate(size))) -		{ -			break ; -		} -		chunk = chunk->mNext ; -	} -	 -	//fetch new memory chunk -	if(!p) -	{ -		if(mReservedPoolSize + CHUNK_SIZE > mMaxPoolSize) -		{ -			chunk = mChunkList[chunk_idx]; -			while(chunk) -			{ -				if((p = chunk->allocate(size))) -				{ -					break ; -				} -				chunk = chunk->mNext ; -			} -		} -		else -		{ -			chunk = addChunk(chunk_idx) ; -			if(chunk) -			{ -				p = chunk->allocate(size) ; -			} -		} -	} - -	unlock() ; - -	if(!p) //to get memory from the private pool failed, try the heap directly -	{ -		static bool to_log = true ; -		 -		if(to_log) -		{ -			LL_WARNS() << "The memory pool overflows, now using heap directly!" << LL_ENDL ; -			to_log = false ; -		} - -		return (char*)ll_aligned_malloc_16(size) ; -	} - -	return p ; -} - -void LLPrivateMemoryPool::freeMem(void* addr) -{ -	if(!addr) -	{ -		return ; -	} -	 -	lock() ; -	 -	LLMemoryChunk* chunk = findChunk((char*)addr) ; -	 -	if(!chunk) -	{ -		ll_aligned_free_16(addr) ; //release from heap -	} -	else -	{ -		chunk->freeMem(addr) ; - -		if(chunk->empty()) -		{ -			removeChunk(chunk) ; -		} -	} -	 -	unlock() ; -} - -void LLPrivateMemoryPool::dump() -{ -} - -U32 LLPrivateMemoryPool::getTotalAllocatedSize() -{ -	U32 total_allocated = 0 ; - -	LLMemoryChunk* chunk ; -	for(S32 i = 0 ; i < SUPER_ALLOCATION ; i++) -	{ -		chunk = mChunkList[i]; -		while(chunk) -		{ -			total_allocated += chunk->getAllocatedSize() ; -			chunk = chunk->mNext ; -		} -	} - -	return total_allocated ; -} - -void LLPrivateMemoryPool::lock() -{ -	if(mMutexp) -	{ -		mMutexp->lock() ; -	} -} - -void LLPrivateMemoryPool::unlock() -{ -	if(mMutexp) -	{ -		mMutexp->unlock() ; -	} -} - -S32  LLPrivateMemoryPool::getChunkIndex(U32 size)  -{ -	S32 i ; -	for(i = 0 ; size > MAX_SLOT_SIZES[i]; i++); -	 -	llassert_always(i < SUPER_ALLOCATION); - -	return i ; -} - -//destroy the entire pool -void  LLPrivateMemoryPool::destroyPool() -{ -	lock() ; - -	if(mNumOfChunks > 0) -	{ -		LL_WARNS() << "There is some memory not freed when destroy the memory pool!" << LL_ENDL ; -	} - -	mNumOfChunks = 0 ; -	mChunkHashList.clear() ; -	mHashFactor = 1 ; -	for(S32 i = 0 ; i < SUPER_ALLOCATION ; i++) -	{ -		mChunkList[i] = NULL ; -	} - -	unlock() ; -} - -bool LLPrivateMemoryPool::checkSize(U32 asked_size) -{ -	if(mReservedPoolSize + asked_size > mMaxPoolSize) -	{ -		LL_INFOS() << "Max pool size: " << mMaxPoolSize << LL_ENDL ; -		LL_INFOS() << "Total reserved size: " << mReservedPoolSize + asked_size << LL_ENDL ; -		LL_INFOS() << "Total_allocated Size: " << getTotalAllocatedSize() << LL_ENDL ; - -		//LL_ERRS() << "The pool is overflowing..." << LL_ENDL ; - -		return false ; -	} - -	return true ; -} - -LLPrivateMemoryPool::LLMemoryChunk* LLPrivateMemoryPool::addChunk(S32 chunk_index) -{ -	U32 preferred_size ; -	U32 overhead ; -	if(chunk_index < LARGE_ALLOCATION) -	{ -		preferred_size = CHUNK_SIZE ; //4MB -		overhead = LLMemoryChunk::getMaxOverhead(preferred_size, MIN_SLOT_SIZES[chunk_index], -			MAX_SLOT_SIZES[chunk_index], MIN_BLOCK_SIZES[chunk_index], MAX_BLOCK_SIZES[chunk_index]) ; -	} -	else -	{ -		preferred_size = LARGE_CHUNK_SIZE ; //16MB -		overhead = LLMemoryChunk::getMaxOverhead(preferred_size, MIN_SLOT_SIZES[chunk_index],  -			MAX_SLOT_SIZES[chunk_index], MIN_BLOCK_SIZES[chunk_index], MAX_BLOCK_SIZES[chunk_index]) ; -	} - -	if(!checkSize(preferred_size + overhead)) -	{ -		return NULL ; -	} - -	mReservedPoolSize += preferred_size + overhead ; - -	char* buffer = (char*)ll_aligned_malloc_16(preferred_size + overhead) ; -	if(!buffer) -	{ -		return NULL ; -	} -	 -	LLMemoryChunk* chunk = new (buffer) LLMemoryChunk() ; -	chunk->init(buffer, preferred_size + overhead, MIN_SLOT_SIZES[chunk_index], -		MAX_SLOT_SIZES[chunk_index], MIN_BLOCK_SIZES[chunk_index], MAX_BLOCK_SIZES[chunk_index]) ; - -	//add to the tail of the linked list -	{ -		if(!mChunkList[chunk_index]) -		{ -			mChunkList[chunk_index] = chunk ; -		} -		else -		{ -			LLMemoryChunk* cur = mChunkList[chunk_index] ; -			while(cur->mNext) -			{ -				cur = cur->mNext ; -			} -			cur->mNext = chunk ; -			chunk->mPrev = cur ; -		} -	} - -	//insert into the hash table -	addToHashTable(chunk) ; -	 -	mNumOfChunks++; - -	return chunk ; -} - -void LLPrivateMemoryPool::removeChunk(LLMemoryChunk* chunk)  -{ -	if(!chunk) -	{ -		return ; -	} - -	//remove from the linked list -	for(S32 i = 0 ; i < SUPER_ALLOCATION ; i++) -	{ -		if(mChunkList[i] == chunk) -		{ -			mChunkList[i] = chunk->mNext ; -		} -	} - -	if(chunk->mPrev) -	{ -		chunk->mPrev->mNext = chunk->mNext ; -	} -	if(chunk->mNext) -	{ -		chunk->mNext->mPrev = chunk->mPrev ; -	} - -	//remove from the hash table -	removeFromHashTable(chunk) ; -	 -	mNumOfChunks--; -	mReservedPoolSize -= chunk->getBufferSize() ; -	 -	//release memory -	ll_aligned_free_16(chunk->getBuffer()) ; -} - -U16 LLPrivateMemoryPool::findHashKey(const char* addr) -{ -	return (((uintptr_t)addr) / CHUNK_SIZE) % mHashFactor ; -} - -LLPrivateMemoryPool::LLMemoryChunk* LLPrivateMemoryPool::findChunk(const char* addr) -{ -	U16 key = findHashKey(addr) ;	 -	if(mChunkHashList.size() <= key) -	{ -		return NULL ; -	} - -	return mChunkHashList[key].findChunk(addr) ;	 -} - -void LLPrivateMemoryPool::addToHashTable(LLMemoryChunk* chunk)  -{ -	static const U16 HASH_FACTORS[] = {41, 83, 193, 317, 419, 523, 719, 997, 1523, 0xFFFF};  -	 -	U16 i ; -	if(mChunkHashList.empty()) -	{ -		mHashFactor = HASH_FACTORS[0] ; -		rehash() ;		 -	} - -	U16 start_key = findHashKey(chunk->getBuffer()) ; -	U16 end_key = findHashKey(chunk->getBuffer() + chunk->getBufferSize() - 1) ; -	bool need_rehash = false ; -	 -	if(mChunkHashList[start_key].hasElement(chunk)) -	{ -		return; //already inserted. -	} -	need_rehash = mChunkHashList[start_key].add(chunk) ; -	 -	if(start_key == end_key && !need_rehash) -	{ -		return ; //done -	} - -	if(!need_rehash) -	{ -		need_rehash = mChunkHashList[end_key].add(chunk) ; -	} - -	if(!need_rehash) -	{ -		if(end_key < start_key) -		{ -			need_rehash = fillHashTable(start_key + 1, mHashFactor, chunk) ; -			if(!need_rehash) -			{ -				need_rehash = fillHashTable(0, end_key, chunk) ; -			} -		} -		else -		{ -			need_rehash = fillHashTable(start_key + 1, end_key, chunk) ; -		} -	} -	 -	if(need_rehash) -	{ -		i = 0 ; -		while(HASH_FACTORS[i] <= mHashFactor) i++; - -		mHashFactor = HASH_FACTORS[i] ; -		llassert_always(mHashFactor != 0xFFFF) ;//stop point to prevent endlessly recursive calls - -		rehash() ; -	} -} - -void LLPrivateMemoryPool::removeFromHashTable(LLMemoryChunk* chunk)  -{ -	U16 start_key = findHashKey(chunk->getBuffer()) ; -	U16 end_key = findHashKey(chunk->getBuffer() + chunk->getBufferSize() - 1) ; -	 -	mChunkHashList[start_key].remove(chunk) ; -	if(start_key == end_key) -	{ -		return ; //done -	} - -	mChunkHashList[end_key].remove(chunk) ; -	 -	if(end_key < start_key) -	{ -		for(U16 i = start_key + 1 ; i < mHashFactor; i++) -		{ -			mChunkHashList[i].remove(chunk) ; -		} -		for(U16 i = 0 ; i < end_key; i++) -		{ -			mChunkHashList[i].remove(chunk) ; -		} -	} -	else -	{ -		for(U16 i = start_key + 1 ; i < end_key; i++) -		{ -			mChunkHashList[i].remove(chunk) ; -		} -	} -} - -void LLPrivateMemoryPool::rehash() -{ -	LL_INFOS() << "new hash factor: " << mHashFactor << LL_ENDL ; - -	mChunkHashList.clear() ; -	mChunkHashList.resize(mHashFactor) ; - -	LLMemoryChunk* chunk ; -	for(U16 i = 0 ; i < SUPER_ALLOCATION ; i++) -	{ -		chunk = mChunkList[i] ;  -		while(chunk) -		{ -			addToHashTable(chunk) ; -			chunk = chunk->mNext ; -		} -	} -} - -bool LLPrivateMemoryPool::fillHashTable(U16 start, U16 end, LLMemoryChunk* chunk) -{ -	for(U16 i = start; i < end; i++) -	{ -		if(mChunkHashList[i].add(chunk)) -		{			 -			return true ; -		}		 -	} - -	return false ; -} - -//-------------------------------------------------------------------- -// class LLChunkHashElement -//-------------------------------------------------------------------- -LLPrivateMemoryPool::LLMemoryChunk* LLPrivateMemoryPool::LLChunkHashElement::findChunk(const char* addr) -{ -	if(mFirst && mFirst->containsAddress(addr)) -	{ -		return mFirst ; -	} -	else if(mSecond && mSecond->containsAddress(addr)) -	{ -		return mSecond ; -	} - -	return NULL ; -} - -//return false if successfully inserted to the hash slot. -bool LLPrivateMemoryPool::LLChunkHashElement::add(LLPrivateMemoryPool::LLMemoryChunk* chunk) -{ -	llassert_always(!hasElement(chunk)) ; - -	if(!mFirst) -	{ -		mFirst = chunk ; -	} -	else if(!mSecond) -	{ -		mSecond = chunk ; -	} -	else -	{ -		return true ; //failed -	} - -	return false ; -} - -void LLPrivateMemoryPool::LLChunkHashElement::remove(LLPrivateMemoryPool::LLMemoryChunk* chunk) -{ -	if(mFirst == chunk) -	{ -		mFirst = NULL ; -	} -	else if(mSecond ==chunk) -	{ -		mSecond = NULL ; -	} -	else -	{ -		LL_ERRS() << "This slot does not contain this chunk!" << LL_ENDL ; -	} -} - -//-------------------------------------------------------------------- -//class LLPrivateMemoryPoolManager -//-------------------------------------------------------------------- -LLPrivateMemoryPoolManager* LLPrivateMemoryPoolManager::sInstance = NULL ; -BOOL LLPrivateMemoryPoolManager::sPrivatePoolEnabled = FALSE ; -std::vector<LLPrivateMemoryPool*> LLPrivateMemoryPoolManager::sDanglingPoolList ; - -LLPrivateMemoryPoolManager::LLPrivateMemoryPoolManager(BOOL enabled, U32 max_pool_size)  -{ -	mPoolList.resize(LLPrivateMemoryPool::MAX_TYPES) ; - -	for(S32 i = 0 ; i < LLPrivateMemoryPool::MAX_TYPES; i++) -	{ -		mPoolList[i] = NULL ; -	} - -	sPrivatePoolEnabled = enabled ; - -	const U32 MAX_POOL_SIZE = 256 * 1024 * 1024 ; //256 MB -	mMaxPrivatePoolSize = llmax(max_pool_size, MAX_POOL_SIZE) ; -} - -LLPrivateMemoryPoolManager::~LLPrivateMemoryPoolManager()  -{ - -#if __DEBUG_PRIVATE_MEM__ -	if(!sMemAllocationTracker.empty()) -	{ -		LL_WARNS() << "there is potential memory leaking here. The list of not freed memory blocks are from: " <<LL_ENDL ; - -		S32 k = 0 ; -		for(mem_allocation_info_t::iterator iter = sMemAllocationTracker.begin() ; iter != sMemAllocationTracker.end() ; ++iter) -		{ -			LL_INFOS() << k++ << ", " << (uintptr_t)iter->first << " : " << iter->second << LL_ENDL ; -		} -		sMemAllocationTracker.clear() ; -	} -#endif - -#if 0 -	//all private pools should be released by their owners before reaching here. -	for(S32 i = 0 ; i < LLPrivateMemoryPool::MAX_TYPES; i++) -	{ -		llassert_always(!mPoolList[i]) ; -	} -	mPoolList.clear() ; - -#else -	//forcefully release all memory -	for(S32 i = 0 ; i < LLPrivateMemoryPool::MAX_TYPES; i++) -	{ -		if(mPoolList[i]) -		{ -			if(mPoolList[i]->isEmpty()) -			{ -				delete mPoolList[i] ; -			} -			else -			{ -				//can not delete this pool because it has alloacted memory to be freed. -				//move it to the dangling list. -				sDanglingPoolList.push_back(mPoolList[i]) ;				 -			} - -			mPoolList[i] = NULL ; -		} -	} -	mPoolList.clear() ; -#endif -} - -//static  -void LLPrivateMemoryPoolManager::initClass(BOOL enabled, U32 max_pool_size)  -{ -	llassert_always(!sInstance) ; - -	sInstance = new LLPrivateMemoryPoolManager(enabled, max_pool_size) ; -} - -//static  -LLPrivateMemoryPoolManager* LLPrivateMemoryPoolManager::getInstance()  -{ -	//if(!sInstance) -	//{ -	//	sInstance = new LLPrivateMemoryPoolManager(FALSE) ; -	//} -	return sInstance ; -} -	 -//static  -void LLPrivateMemoryPoolManager::destroyClass()  -{ -	if(sInstance) -	{ -		delete sInstance ; -		sInstance = NULL ; -	} -} - -LLPrivateMemoryPool* LLPrivateMemoryPoolManager::newPool(S32 type)  -{ -	if(!sPrivatePoolEnabled) -	{ -		return NULL ; -	} - -	if(!mPoolList[type]) -	{ -		mPoolList[type] = new LLPrivateMemoryPool(type, mMaxPrivatePoolSize) ; -	} - -	return mPoolList[type] ; -} - -void LLPrivateMemoryPoolManager::deletePool(LLPrivateMemoryPool* pool)  -{ -	if(pool && pool->isEmpty()) -	{ -		mPoolList[pool->getType()] = NULL ; -		delete pool; -	} -} - -//debug -void LLPrivateMemoryPoolManager::updateStatistics() -{ -	mTotalReservedSize = 0 ; -	mTotalAllocatedSize = 0 ; - -	for(U32 i = 0; i < mPoolList.size(); i++) -	{ -		if(mPoolList[i]) -		{ -			mTotalReservedSize += mPoolList[i]->getTotalReservedSize() ; -			mTotalAllocatedSize += mPoolList[i]->getTotalAllocatedSize() ; -		} -	} -} - -#if __DEBUG_PRIVATE_MEM__ -//static  -char* LLPrivateMemoryPoolManager::allocate(LLPrivateMemoryPool* poolp, U32 size, const char* function, const int line)  -{ -	char* p ; - -	if(!poolp) -	{ -		p = (char*)ll_aligned_malloc_16(size) ; -	} -	else -	{ -		p = poolp->allocate(size) ; -	} -	 -	if(p) -	{ -		char num[16] ; -		sprintf(num, " line: %d ", line) ; -		std::string str(function) ; -		str += num;  - -		sMemAllocationTracker[p] = str ; -	} - -	return p ; -}	 -#else -//static  -char* LLPrivateMemoryPoolManager::allocate(LLPrivateMemoryPool* poolp, U32 size)  -{ -	if(poolp) -	{ -		return poolp->allocate(size) ;		 -	} -	else -	{ -		return (char*)ll_aligned_malloc_16(size) ; -	} -} -#endif - -//static  -void  LLPrivateMemoryPoolManager::freeMem(LLPrivateMemoryPool* poolp, void* addr)  -{ -	if(!addr) -	{ -		return ; -	} - -#if __DEBUG_PRIVATE_MEM__ -	sMemAllocationTracker.erase((char*)addr) ; -#endif - -	if(poolp) -	{ -		poolp->freeMem(addr) ; -	} -	else -	{ -		if(!sPrivatePoolEnabled) -		{ -			ll_aligned_free_16(addr) ; //private pool is disabled. -		} -		else if(!sInstance) //the private memory manager is destroyed, try the dangling list -		{ -			for(S32 i = 0 ; i < sDanglingPoolList.size(); i++) -			{ -				if(sDanglingPoolList[i]->findChunk((char*)addr)) -				{ -					sDanglingPoolList[i]->freeMem(addr) ; -					if(sDanglingPoolList[i]->isEmpty()) -					{ -						delete sDanglingPoolList[i] ; -						 -						if(i < sDanglingPoolList.size() - 1) -						{ -							sDanglingPoolList[i] = sDanglingPoolList[sDanglingPoolList.size() - 1] ; -						} -						sDanglingPoolList.pop_back() ; -					} - -					addr = NULL ; -					break ; -				} -			}		 -			llassert_always(!addr) ; //addr should be release before hitting here! -		} -		else -		{ -			LL_ERRS() << "private pool is used before initialized.!" << LL_ENDL ; -		} -	}	 -} - -//-------------------------------------------------------------------- -//class LLPrivateMemoryPoolTester -//-------------------------------------------------------------------- -#if 0 -LLPrivateMemoryPoolTester* LLPrivateMemoryPoolTester::sInstance = NULL ; -LLPrivateMemoryPool* LLPrivateMemoryPoolTester::sPool = NULL ; -LLPrivateMemoryPoolTester::LLPrivateMemoryPoolTester() -{	 -} -	 -LLPrivateMemoryPoolTester::~LLPrivateMemoryPoolTester()  -{	 -} - -//static  -LLPrivateMemoryPoolTester* LLPrivateMemoryPoolTester::getInstance()  -{ -	if(!sInstance) -	{ -		sInstance = ::new LLPrivateMemoryPoolTester() ; -	} -	return sInstance ; -} - -//static  -void LLPrivateMemoryPoolTester::destroy() -{ -	if(sInstance) -	{ -		::delete sInstance ; -		sInstance = NULL ; -	} - -	if(sPool) -	{ -		LLPrivateMemoryPoolManager::getInstance()->deletePool(sPool) ; -		sPool = NULL ; -	} -} - -void LLPrivateMemoryPoolTester::run(S32 type)  -{ -	if(sPool) -	{ -		LLPrivateMemoryPoolManager::getInstance()->deletePool(sPool) ; -	} -	sPool = LLPrivateMemoryPoolManager::getInstance()->newPool(type) ; - -	//run the test -	correctnessTest() ; -	performanceTest() ; -	//fragmentationtest() ; - -	//release pool. -	LLPrivateMemoryPoolManager::getInstance()->deletePool(sPool) ; -	sPool = NULL ; -} - -void LLPrivateMemoryPoolTester::test(U32 min_size, U32 max_size, U32 stride, U32 times,  -									 bool random_deletion, bool output_statistics) -{ -	U32 levels = (max_size - min_size) / stride + 1 ; -	char*** p ; -	U32 i, j ; -	U32 total_allocated_size = 0 ; - -	//allocate space for p ; -	if(!(p = ::new char**[times]) || !(*p = ::new char*[times * levels])) -	{ -		LL_ERRS() << "memory initialization for p failed" << LL_ENDL ; -	} - -	//init -	for(i = 0 ; i < times; i++) -	{ -		p[i] = *p + i * levels ; -		for(j = 0 ; j < levels; j++) -		{ -			p[i][j] = NULL ; -		} -	} - -	//allocation -	U32 size ; -	for(i = 0 ; i < times ; i++) -	{ -		for(j = 0 ; j < levels; j++)  -		{ -			size = min_size + j * stride ; -			p[i][j] = ALLOCATE_MEM(sPool, size) ; - -			total_allocated_size+= size ; - -			*(U32*)p[i][j] = i ; -			*((U32*)p[i][j] + 1) = j ; -			//p[i][j][size - 1] = '\0' ; //access the last element to verify the success of the allocation. - -			//randomly release memory -			if(random_deletion) -			{ -				S32 k = rand() % levels ; - -				if(p[i][k]) -				{ -					llassert_always(*(U32*)p[i][k] == i && *((U32*)p[i][k] + 1) == k) ; -					FREE_MEM(sPool, p[i][k]) ; -					total_allocated_size -= min_size + k * stride ; -					p[i][k] = NULL ; -				} -			} -		} -	} - -	//output pool allocation statistics -	if(output_statistics) -	{ -	} - -	//release all memory allocations -	for(i = 0 ; i < times; i++) -	{ -		for(j = 0 ; j < levels; j++) -		{ -			if(p[i][j]) -			{ -				llassert_always(*(U32*)p[i][j] == i && *((U32*)p[i][j] + 1) == j) ; -				FREE_MEM(sPool, p[i][j]) ; -				total_allocated_size -= min_size + j * stride ; -				p[i][j] = NULL ; -			} -		} -	} - -	::delete[] *p ; -	::delete[] p ; -} - -void LLPrivateMemoryPoolTester::testAndTime(U32 size, U32 times) -{ -	LLTimer timer ; - -	LL_INFOS() << " -**********************- " << LL_ENDL ; -	LL_INFOS() << "test size: " << size << " test times: " << times << LL_ENDL ; - -	timer.reset() ; -	char** p = new char*[times] ; -		 -	//using the customized memory pool -	//allocation -	for(U32 i = 0 ; i < times; i++) -	{ -		p[i] = ALLOCATE_MEM(sPool, size) ; -		if(!p[i]) -		{ -			LL_ERRS() << "allocation failed" << LL_ENDL ; -		} -	} -	//de-allocation -	for(U32 i = 0 ; i < times; i++) -	{ -		FREE_MEM(sPool, p[i]) ; -		p[i] = NULL ; -	} -	LL_INFOS() << "time spent using customized memory pool: " << timer.getElapsedTimeF32() << LL_ENDL ; - -	timer.reset() ; - -	//using the standard allocator/de-allocator: -	//allocation -	for(U32 i = 0 ; i < times; i++) -	{ -		p[i] = ::new char[size] ; -		if(!p[i]) -		{ -			LL_ERRS() << "allocation failed" << LL_ENDL ; -		} -	} -	//de-allocation -	for(U32 i = 0 ; i < times; i++) -	{ -		::delete[] p[i] ; -		p[i] = NULL ; -	} -	LL_INFOS() << "time spent using standard allocator/de-allocator: " << timer.getElapsedTimeF32() << LL_ENDL ; - -	delete[] p; -} - -void LLPrivateMemoryPoolTester::correctnessTest()  -{ -	//try many different sized allocation, and all kinds of edge cases, access the allocated memory  -	//to see if allocation is right. -	 -	//edge case -	char* p = ALLOCATE_MEM(sPool, 0) ; -	FREE_MEM(sPool, p) ; - -	//small sized -	// [8 bytes, 2KB), each asks for 256 allocations and deallocations -	test(8, 2040, 8, 256, true, true) ; -	 -	//medium sized -	//[2KB, 512KB), each asks for 16 allocations and deallocations -	test(2048, 512 * 1024 - 2048, 2048, 16, true, true) ; - -	//large sized -	//[512KB, 4MB], each asks for 8 allocations and deallocations -	test(512 * 1024, 4 * 1024 * 1024, 64 * 1024, 6, true, true) ; -} - -void LLPrivateMemoryPoolTester::performanceTest()  -{ -	U32 test_size[3] = {768, 3* 1024, 3* 1024 * 1024}; -	 -	//small sized -	testAndTime(test_size[0], 8) ; -	 -	//medium sized -	testAndTime(test_size[1], 8) ; - -	//large sized -	testAndTime(test_size[2], 8) ; -} - -void LLPrivateMemoryPoolTester::fragmentationtest()  -{ -	//for internal fragmentation statistics: -	//every time when asking for a new chunk during correctness test, and performance test, -	//print out the chunk usage statistices. -} -#endif  //--------------------------------------------------------------------  #if defined(LL_WINDOWS) && defined(LL_DEBUG_BUFFER_OVERRUN) diff --git a/indra/llcommon/llmemory.h b/indra/llcommon/llmemory.h index c37967e10e..5b17d9e3a4 100644 --- a/indra/llcommon/llmemory.h +++ b/indra/llcommon/llmemory.h @@ -356,327 +356,6 @@ private:  	static BOOL sEnableMemoryFailurePrevention;  }; -// -//class LLPrivateMemoryPool defines a private memory pool for an application to use, so the application does not -//need to access the heap directly fro each memory allocation. Throught this, the allocation speed is faster,  -//and reduces virtaul address space gragmentation problem. -//Note: this class is thread-safe by passing true to the constructor function. However, you do not need to do this unless -//you are sure the memory allocation and de-allocation will happen in different threads. To make the pool thread safe -//increases allocation and deallocation cost. -// -class LL_COMMON_API LLPrivateMemoryPool -{ -	friend class LLPrivateMemoryPoolManager ; - -public: -	class LL_COMMON_API LLMemoryBlock //each block is devided into slots uniformly -	{ -	public:  -		LLMemoryBlock() ; -		~LLMemoryBlock() ; - -		void init(char* buffer, U32 buffer_size, U32 slot_size) ; -		void setBuffer(char* buffer, U32 buffer_size) ; - -		char* allocate() ; -		void  freeMem(void* addr) ; - -		bool empty() {return !mAllocatedSlots;} -		bool isFull() {return mAllocatedSlots == mTotalSlots;} -		bool isFree() {return !mTotalSlots;} - -		U32  getSlotSize()const {return mSlotSize;} -		U32  getTotalSlots()const {return mTotalSlots;} -		U32  getBufferSize()const {return mBufferSize;} -		char* getBuffer() const {return mBuffer;} - -		//debug use -		void resetBitMap() ; -	private: -		char* mBuffer; -		U32   mSlotSize ; //when the block is not initialized, it is the buffer size. -		U32   mBufferSize ; -		U32   mUsageBits ; -		U8    mTotalSlots ; -		U8    mAllocatedSlots ; -		U8    mDummySize ; //size of extra bytes reserved for mUsageBits. - -	public: -		LLMemoryBlock* mPrev ; -		LLMemoryBlock* mNext ; -		LLMemoryBlock* mSelf ; - -		struct CompareAddress -		{ -			bool operator()(const LLMemoryBlock* const& lhs, const LLMemoryBlock* const& rhs) -			{ -				return (uintptr_t)lhs->getBuffer() < (uintptr_t)rhs->getBuffer(); -			} -		}; -	}; - -	class LL_COMMON_API LLMemoryChunk //is divided into memory blocks. -	{ -	public: -		LLMemoryChunk() ; -		~LLMemoryChunk() ; - -		void init(char* buffer, U32 buffer_size, U32 min_slot_size, U32 max_slot_size, U32 min_block_size, U32 max_block_size) ; -		void setBuffer(char* buffer, U32 buffer_size) ; - -		bool empty() ; -		 -		char* allocate(U32 size) ; -		void  freeMem(void* addr) ; - -		char* getBuffer() const {return mBuffer;} -		U32 getBufferSize() const {return mBufferSize;} -		U32 getAllocatedSize() const {return mAlloatedSize;} - -		bool containsAddress(const char* addr) const; - -		static U32 getMaxOverhead(U32 data_buffer_size, U32 min_slot_size,  -													   U32 max_slot_size, U32 min_block_size, U32 max_block_size) ; -	 -		void dump() ; - -	private: -		U32 getPageIndex(uintptr_t addr) ; -		U32 getBlockLevel(U32 size) ; -		U16 getPageLevel(U32 size) ; -		LLMemoryBlock* addBlock(U32 blk_idx) ; -		void popAvailBlockList(U32 blk_idx) ; -		void addToFreeSpace(LLMemoryBlock* blk) ; -		void removeFromFreeSpace(LLMemoryBlock* blk) ; -		void removeBlock(LLMemoryBlock* blk) ; -		void addToAvailBlockList(LLMemoryBlock* blk) ; -		U32  calcBlockSize(U32 slot_size); -		LLMemoryBlock* createNewBlock(LLMemoryBlock* blk, U32 buffer_size, U32 slot_size, U32 blk_idx) ; - -	private: -		LLMemoryBlock** mAvailBlockList ;//256 by mMinSlotSize -		LLMemoryBlock** mFreeSpaceList; -		LLMemoryBlock*  mBlocks ; //index of blocks by address. -		 -		char* mBuffer ; -		U32   mBufferSize ; -		char* mDataBuffer ; -		char* mMetaBuffer ; -		U32   mMinBlockSize ; -		U32   mMinSlotSize ; -		U32   mMaxSlotSize ; -		U32   mAlloatedSize ; -		U16   mBlockLevels; -		U16   mPartitionLevels; - -	public: -		//form a linked list -		LLMemoryChunk* mNext ; -		LLMemoryChunk* mPrev ; -	} ; - -private: -	LLPrivateMemoryPool(S32 type, U32 max_pool_size) ; -	~LLPrivateMemoryPool() ; - -	char *allocate(U32 size) ; -	void  freeMem(void* addr) ; -	 -	void  dump() ; -	U32   getTotalAllocatedSize() ; -	U32   getTotalReservedSize() {return mReservedPoolSize;} -	S32   getType() const {return mType; } -	bool  isEmpty() const {return !mNumOfChunks; } - -private: -	void lock() ; -	void unlock() ;	 -	S32 getChunkIndex(U32 size) ; -	LLMemoryChunk*  addChunk(S32 chunk_index) ; -	bool checkSize(U32 asked_size) ; -	void removeChunk(LLMemoryChunk* chunk) ; -	U16  findHashKey(const char* addr); -	void addToHashTable(LLMemoryChunk* chunk) ; -	void removeFromHashTable(LLMemoryChunk* chunk) ; -	void rehash() ; -	bool fillHashTable(U16 start, U16 end, LLMemoryChunk* chunk) ; -	LLMemoryChunk* findChunk(const char* addr) ; - -	void destroyPool() ; - -public: -	enum -	{ -		SMALL_ALLOCATION = 0, //from 8 bytes to 2KB(exclusive), page size 2KB, max chunk size is 4MB. -		MEDIUM_ALLOCATION,    //from 2KB to 512KB(exclusive), page size 32KB, max chunk size 4MB -		LARGE_ALLOCATION,     //from 512KB to 4MB(inclusive), page size 64KB, max chunk size 16MB -		SUPER_ALLOCATION      //allocation larger than 4MB. -	}; - -	enum -	{ -		STATIC = 0 ,       //static pool(each alllocation stays for a long time) without threading support -		VOLATILE,          //Volatile pool(each allocation stays for a very short time) without threading support -		STATIC_THREADED,   //static pool with threading support -		VOLATILE_THREADED, //volatile pool with threading support -		MAX_TYPES -	}; //pool types - -private: -	LLMutex* mMutexp ; -	U32  mMaxPoolSize; -	U32  mReservedPoolSize ;	 - -	LLMemoryChunk* mChunkList[SUPER_ALLOCATION] ; //all memory chunks reserved by this pool, sorted by address	 -	U16 mNumOfChunks ; -	U16 mHashFactor ; - -	S32 mType ; - -	class LLChunkHashElement -	{ -	public: -		LLChunkHashElement() {mFirst = NULL ; mSecond = NULL ;} - -		bool add(LLMemoryChunk* chunk) ; -		void remove(LLMemoryChunk* chunk) ; -		LLMemoryChunk* findChunk(const char* addr) ; - -		bool empty() {return !mFirst && !mSecond; } -		bool full()  {return mFirst && mSecond; } -		bool hasElement(LLMemoryChunk* chunk) {return mFirst == chunk || mSecond == chunk;} - -	private: -		LLMemoryChunk* mFirst ; -		LLMemoryChunk* mSecond ; -	}; -	std::vector<LLChunkHashElement> mChunkHashList ; -}; - -class LL_COMMON_API LLPrivateMemoryPoolManager -{ -private: -	LLPrivateMemoryPoolManager(BOOL enabled, U32 max_pool_size) ; -	~LLPrivateMemoryPoolManager() ; - -public:	 -	static LLPrivateMemoryPoolManager* getInstance() ; -	static void initClass(BOOL enabled, U32 pool_size) ; -	static void destroyClass() ; - -	LLPrivateMemoryPool* newPool(S32 type) ; -	void deletePool(LLPrivateMemoryPool* pool) ; - -private:	 -	std::vector<LLPrivateMemoryPool*> mPoolList ;	 -	U32  mMaxPrivatePoolSize; - -	static LLPrivateMemoryPoolManager* sInstance ; -	static BOOL sPrivatePoolEnabled; -	static std::vector<LLPrivateMemoryPool*> sDanglingPoolList ; -public: -	//debug and statistics info. -	void updateStatistics() ; - -	U32 mTotalReservedSize ; -	U32 mTotalAllocatedSize ; - -public: -#if __DEBUG_PRIVATE_MEM__ -	static char* allocate(LLPrivateMemoryPool* poolp, U32 size, const char* function, const int line) ;	 -	 -	typedef std::map<char*, std::string> mem_allocation_info_t ; -	static mem_allocation_info_t sMemAllocationTracker; -#else -	static char* allocate(LLPrivateMemoryPool* poolp, U32 size) ;	 -#endif -	static void  freeMem(LLPrivateMemoryPool* poolp, void* addr) ; -}; - -//------------------------------------------------------------------------------------- -#if __DEBUG_PRIVATE_MEM__ -#define ALLOCATE_MEM(poolp, size) LLPrivateMemoryPoolManager::allocate((poolp), (size), __FUNCTION__, __LINE__) -#else -#define ALLOCATE_MEM(poolp, size) LLPrivateMemoryPoolManager::allocate((poolp), (size)) -#endif -#define FREE_MEM(poolp, addr) LLPrivateMemoryPoolManager::freeMem((poolp), (addr)) -//------------------------------------------------------------------------------------- - -// -//the below singleton is used to test the private memory pool. -// -#if 0 -class LL_COMMON_API LLPrivateMemoryPoolTester -{ -private: -	LLPrivateMemoryPoolTester() ; -	~LLPrivateMemoryPoolTester() ; - -public: -	static LLPrivateMemoryPoolTester* getInstance() ; -	static void destroy() ; - -	void run(S32 type) ;	 - -private: -	void correctnessTest() ; -	void performanceTest() ; -	void fragmentationtest() ; - -	void test(U32 min_size, U32 max_size, U32 stride, U32 times, bool random_deletion, bool output_statistics) ; -	void testAndTime(U32 size, U32 times) ; - -#if 0 -public: -	void* operator new(size_t size) -	{ -		return (void*)sPool->allocate(size) ; -	} -    void  operator delete(void* addr) -	{ -		sPool->freeMem(addr) ; -	} -	void* operator new[](size_t size) -	{ -		return (void*)sPool->allocate(size) ; -	} -    void  operator delete[](void* addr) -	{ -		sPool->freeMem(addr) ; -	} -#endif - -private: -	static LLPrivateMemoryPoolTester* sInstance; -	static LLPrivateMemoryPool* sPool ; -	static LLPrivateMemoryPool* sThreadedPool ; -}; -#if 0 -//static -void* LLPrivateMemoryPoolTester::operator new(size_t size) -{ -	return (void*)sPool->allocate(size) ; -} - -//static -void  LLPrivateMemoryPoolTester::operator delete(void* addr) -{ -	sPool->free(addr) ; -} - -//static -void* LLPrivateMemoryPoolTester::operator new[](size_t size) -{ -	return (void*)sPool->allocate(size) ; -} - -//static -void  LLPrivateMemoryPoolTester::operator delete[](void* addr) -{ -	sPool->free(addr) ; -} -#endif -#endif  // LLRefCount moved to llrefcount.h  // LLPointer moved to llpointer.h diff --git a/indra/llcommon/llsdserialize.cpp b/indra/llcommon/llsdserialize.cpp index be54ed053b..580e87954b 100644 --- a/indra/llcommon/llsdserialize.cpp +++ b/indra/llcommon/llsdserialize.cpp @@ -51,6 +51,7 @@  // File constants  static const int MAX_HDR_LEN = 20; +static const S32 UNZIP_LLSD_MAX_DEPTH = 96;  static const char LEGACY_NON_HEADER[] = "<llsd>";  const std::string LLSD_BINARY_HEADER("LLSD/Binary");  const std::string LLSD_XML_HEADER("LLSD/XML"); @@ -317,11 +318,11 @@ LLSDParser::LLSDParser()  LLSDParser::~LLSDParser()  { } -S32 LLSDParser::parse(std::istream& istr, LLSD& data, S32 max_bytes) +S32 LLSDParser::parse(std::istream& istr, LLSD& data, S32 max_bytes, S32 max_depth)  {  	mCheckLimits = (LLSDSerialize::SIZE_UNLIMITED == max_bytes) ? false : true;  	mMaxBytesLeft = max_bytes; -	return doParse(istr, data); +	return doParse(istr, data, max_depth);  } @@ -403,7 +404,7 @@ LLSDNotationParser::~LLSDNotationParser()  { }  // virtual -S32 LLSDNotationParser::doParse(std::istream& istr, LLSD& data) const +S32 LLSDNotationParser::doParse(std::istream& istr, LLSD& data, S32 max_depth) const  {  	// map: { string:object, string:object }  	// array: [ object, object, object ] @@ -418,6 +419,10 @@ S32 LLSDNotationParser::doParse(std::istream& istr, LLSD& data) const  	// binary: b##"ff3120ab1" | b(size)"raw data"  	char c;  	c = istr.peek(); +	if (max_depth == 0) +	{ +		return PARSE_FAILURE; +	}  	while(isspace(c))  	{  		// pop the whitespace. @@ -434,7 +439,7 @@ S32 LLSDNotationParser::doParse(std::istream& istr, LLSD& data) const  	{  	case '{':  	{ -		S32 child_count = parseMap(istr, data); +		S32 child_count = parseMap(istr, data, max_depth - 1);  		if((child_count == PARSE_FAILURE) || data.isUndefined())  		{  			parse_count = PARSE_FAILURE; @@ -453,7 +458,7 @@ S32 LLSDNotationParser::doParse(std::istream& istr, LLSD& data) const  	case '[':  	{ -		S32 child_count = parseArray(istr, data); +		S32 child_count = parseArray(istr, data, max_depth - 1);  		if((child_count == PARSE_FAILURE) || data.isUndefined())  		{  			parse_count = PARSE_FAILURE; @@ -658,7 +663,7 @@ S32 LLSDNotationParser::doParse(std::istream& istr, LLSD& data) const  	return parse_count;  } -S32 LLSDNotationParser::parseMap(std::istream& istr, LLSD& map) const +S32 LLSDNotationParser::parseMap(std::istream& istr, LLSD& map, S32 max_depth) const  {  	// map: { string:object, string:object }  	map = LLSD::emptyMap(); @@ -693,7 +698,7 @@ S32 LLSDNotationParser::parseMap(std::istream& istr, LLSD& map) const  				}  				putback(istr, c);  				LLSD child; -				S32 count = doParse(istr, child); +				S32 count = doParse(istr, child, max_depth);  				if(count > 0)  				{  					// There must be a value for every key, thus @@ -718,7 +723,7 @@ S32 LLSDNotationParser::parseMap(std::istream& istr, LLSD& map) const  	return parse_count;  } -S32 LLSDNotationParser::parseArray(std::istream& istr, LLSD& array) const +S32 LLSDNotationParser::parseArray(std::istream& istr, LLSD& array, S32 max_depth) const  {  	// array: [ object, object, object ]  	array = LLSD::emptyArray(); @@ -737,7 +742,7 @@ S32 LLSDNotationParser::parseArray(std::istream& istr, LLSD& array) const  				continue;  			}  			putback(istr, c); -			S32 count = doParse(istr, child); +			S32 count = doParse(istr, child, max_depth);  			if(PARSE_FAILURE == count)  			{  				return PARSE_FAILURE; @@ -869,7 +874,7 @@ LLSDBinaryParser::~LLSDBinaryParser()  }  // virtual -S32 LLSDBinaryParser::doParse(std::istream& istr, LLSD& data) const +S32 LLSDBinaryParser::doParse(std::istream& istr, LLSD& data, S32 max_depth) const  {  /**   * Undefined: '!'<br> @@ -893,12 +898,16 @@ S32 LLSDBinaryParser::doParse(std::istream& istr, LLSD& data) const  	{  		return 0;  	} +	if (max_depth == 0) +	{ +		return PARSE_FAILURE; +	}  	S32 parse_count = 1;  	switch(c)  	{  	case '{':  	{ -		S32 child_count = parseMap(istr, data); +		S32 child_count = parseMap(istr, data, max_depth - 1);  		if((child_count == PARSE_FAILURE) || data.isUndefined())  		{  			parse_count = PARSE_FAILURE; @@ -917,7 +926,7 @@ S32 LLSDBinaryParser::doParse(std::istream& istr, LLSD& data) const  	case '[':  	{ -		S32 child_count = parseArray(istr, data); +		S32 child_count = parseArray(istr, data, max_depth - 1);  		if((child_count == PARSE_FAILURE) || data.isUndefined())  		{  			parse_count = PARSE_FAILURE; @@ -1098,7 +1107,7 @@ S32 LLSDBinaryParser::doParse(std::istream& istr, LLSD& data) const  	return parse_count;  } -S32 LLSDBinaryParser::parseMap(std::istream& istr, LLSD& map) const +S32 LLSDBinaryParser::parseMap(std::istream& istr, LLSD& map, S32 max_depth) const  {  	map = LLSD::emptyMap();  	U32 value_nbo = 0; @@ -1128,7 +1137,7 @@ S32 LLSDBinaryParser::parseMap(std::istream& istr, LLSD& map) const  		}  		}  		LLSD child; -		S32 child_count = doParse(istr, child); +		S32 child_count = doParse(istr, child, max_depth);  		if(child_count > 0)  		{  			// There must be a value for every key, thus child_count @@ -1152,7 +1161,7 @@ S32 LLSDBinaryParser::parseMap(std::istream& istr, LLSD& map) const  	return parse_count;  } -S32 LLSDBinaryParser::parseArray(std::istream& istr, LLSD& array) const +S32 LLSDBinaryParser::parseArray(std::istream& istr, LLSD& array, S32 max_depth) const  {  	array = LLSD::emptyArray();  	U32 value_nbo = 0; @@ -1168,7 +1177,7 @@ S32 LLSDBinaryParser::parseArray(std::istream& istr, LLSD& array) const  	while((c != ']') && (count < size) && istr.good())  	{  		LLSD child; -		S32 child_count = doParse(istr, child); +		S32 child_count = doParse(istr, child, max_depth);  		if(PARSE_FAILURE == child_count)  		{  			return PARSE_FAILURE; @@ -2238,7 +2247,7 @@ LLUZipHelper::EZipRresult LLUZipHelper::unzip_llsd(LLSD& data, std::istream& is,  			return ZR_MEM_ERROR;  		} -		if (!LLSDSerialize::fromBinary(data, istr, cur_size)) +		if (!LLSDSerialize::fromBinary(data, istr, cur_size, UNZIP_LLSD_MAX_DEPTH))  		{  			free(result);  			return ZR_PARSE_ERROR; diff --git a/indra/llcommon/llsdserialize.h b/indra/llcommon/llsdserialize.h index 9f58d44fe7..8165410e80 100644 --- a/indra/llcommon/llsdserialize.h +++ b/indra/llcommon/llsdserialize.h @@ -77,7 +77,7 @@ public:  	 * @return Returns the number of LLSD objects parsed into  	 * data. Returns PARSE_FAILURE (-1) on parse failure.  	 */ -	S32 parse(std::istream& istr, LLSD& data, S32 max_bytes); +	S32 parse(std::istream& istr, LLSD& data, S32 max_bytes, S32 max_depth = -1);  	/** Like parse(), but uses a different call (istream.getline()) to read by lines  	 *  This API is better suited for XML, where the parse cannot tell @@ -103,10 +103,12 @@ protected:  	 * caller.  	 * @param istr The input stream.  	 * @param data[out] The newly parse structured data. +	 * @param max_depth Max depth parser will check before exiting +	 *  with parse error, -1 - unlimited.  	 * @return Returns the number of LLSD objects parsed into  	 * data. Returns PARSE_FAILURE (-1) on parse failure.  	 */ -	virtual S32 doParse(std::istream& istr, LLSD& data) const = 0; +	virtual S32 doParse(std::istream& istr, LLSD& data, S32 max_depth = -1) const = 0;  	/**   	 * @brief Virtual default function for resetting the parser @@ -241,10 +243,12 @@ protected:  	 * caller.  	 * @param istr The input stream.  	 * @param data[out] The newly parse structured data. Undefined on failure. +	 * @param max_depth Max depth parser will check before exiting +	 *  with parse error, -1 - unlimited.  	 * @return Returns the number of LLSD objects parsed into  	 * data. Returns PARSE_FAILURE (-1) on parse failure.  	 */ -	virtual S32 doParse(std::istream& istr, LLSD& data) const; +	virtual S32 doParse(std::istream& istr, LLSD& data, S32 max_depth = -1) const;  private:  	/**  @@ -252,18 +256,20 @@ private:  	 *  	 * @param istr The input stream.  	 * @param map The map to add the parsed data. +	 * @param max_depth Allowed parsing depth.  	 * @return Returns The number of LLSD objects parsed into data.  	 */ -	S32 parseMap(std::istream& istr, LLSD& map) const; +	S32 parseMap(std::istream& istr, LLSD& map, S32 max_depth) const;  	/**   	 * @brief Parse an array from the istream.  	 *  	 * @param istr The input stream.  	 * @param array The array to append the parsed data. +	 * @param max_depth Allowed parsing depth.  	 * @return Returns The number of LLSD objects parsed into data.  	 */ -	S32 parseArray(std::istream& istr, LLSD& array) const; +	S32 parseArray(std::istream& istr, LLSD& array, S32 max_depth) const;  	/**   	 * @brief Parse a string from the istream and assign it to data. @@ -314,10 +320,12 @@ protected:  	 * caller.  	 * @param istr The input stream.  	 * @param data[out] The newly parse structured data. +	 * @param max_depth Max depth parser will check before exiting +	 *  with parse error, -1 - unlimited.  	 * @return Returns the number of LLSD objects parsed into  	 * data. Returns PARSE_FAILURE (-1) on parse failure.  	 */ -	virtual S32 doParse(std::istream& istr, LLSD& data) const; +	virtual S32 doParse(std::istream& istr, LLSD& data, S32 max_depth = -1) const;  	/**   	 * @brief Virtual default function for resetting the parser @@ -362,10 +370,12 @@ protected:  	 * caller.  	 * @param istr The input stream.  	 * @param data[out] The newly parse structured data. +	 * @param max_depth Max depth parser will check before exiting +	 *  with parse error, -1 - unlimited.  	 * @return Returns the number of LLSD objects parsed into  	 * data. Returns -1 on parse failure.  	 */ -	virtual S32 doParse(std::istream& istr, LLSD& data) const; +	virtual S32 doParse(std::istream& istr, LLSD& data, S32 max_depth = -1) const;  private:  	/**  @@ -373,18 +383,20 @@ private:  	 *  	 * @param istr The input stream.  	 * @param map The map to add the parsed data. +	 * @param max_depth Allowed parsing depth.  	 * @return Returns The number of LLSD objects parsed into data.  	 */ -	S32 parseMap(std::istream& istr, LLSD& map) const; +	S32 parseMap(std::istream& istr, LLSD& map, S32 max_depth) const;  	/**   	 * @brief Parse an array from the istream.  	 *  	 * @param istr The input stream.  	 * @param array The array to append the parsed data. +	 * @param max_depth Allowed parsing depth.  	 * @return Returns The number of LLSD objects parsed into data.  	 */ -	S32 parseArray(std::istream& istr, LLSD& array) const; +	S32 parseArray(std::istream& istr, LLSD& array, S32 max_depth) const;  	/**   	 * @brief Parse a string from the istream and assign it to data. @@ -800,16 +812,16 @@ public:  		LLPointer<LLSDBinaryFormatter> f = new LLSDBinaryFormatter;  		return f->format(sd, str, LLSDFormatter::OPTIONS_NONE);  	} -	static S32 fromBinary(LLSD& sd, std::istream& str, S32 max_bytes) +	static S32 fromBinary(LLSD& sd, std::istream& str, S32 max_bytes, S32 max_depth = -1)  	{  		LLPointer<LLSDBinaryParser> p = new LLSDBinaryParser; -		return p->parse(str, sd, max_bytes); +		return p->parse(str, sd, max_bytes, max_depth);  	} -	static LLSD fromBinary(std::istream& str, S32 max_bytes) +	static LLSD fromBinary(std::istream& str, S32 max_bytes, S32 max_depth = -1)  	{  		LLPointer<LLSDBinaryParser> p = new LLSDBinaryParser;  		LLSD sd; -		(void)p->parse(str, sd, max_bytes); +		(void)p->parse(str, sd, max_bytes, max_depth);  		return sd;  	}  }; diff --git a/indra/llcommon/llsdserialize_xml.cpp b/indra/llcommon/llsdserialize_xml.cpp index 8d72a1c329..6d0fe862b9 100644 --- a/indra/llcommon/llsdserialize_xml.cpp +++ b/indra/llcommon/llsdserialize_xml.cpp @@ -917,7 +917,7 @@ void LLSDXMLParser::parsePart(const char *buf, int len)  }  // virtual -S32 LLSDXMLParser::doParse(std::istream& input, LLSD& data) const +S32 LLSDXMLParser::doParse(std::istream& input, LLSD& data, S32 max_depth) const  {  	#ifdef XML_PARSER_PERFORMANCE_TESTS  	XML_Timer timer( &parseTime ); diff --git a/indra/llimage/llimage.cpp b/indra/llimage/llimage.cpp index 4a76d15096..dca03cfe04 100644 --- a/indra/llimage/llimage.cpp +++ b/indra/llimage/llimage.cpp @@ -588,7 +588,6 @@ std::string LLImage::sLastErrorMessage;  LLMutex* LLImage::sMutex = NULL;  bool LLImage::sUseNewByteRange = false;  S32  LLImage::sMinimalReverseByteRangePercent = 75; -LLPrivateMemoryPool* LLImageBase::sPrivatePoolp = NULL ;  //static  void LLImage::initClass(bool use_new_byte_range, S32 minimal_reverse_byte_range_percent) @@ -596,8 +595,6 @@ void LLImage::initClass(bool use_new_byte_range, S32 minimal_reverse_byte_range_  	sUseNewByteRange = use_new_byte_range;      sMinimalReverseByteRangePercent = minimal_reverse_byte_range_percent;  	sMutex = new LLMutex(NULL); - -	LLImageBase::createPrivatePool() ;  }  //static @@ -605,8 +602,6 @@ void LLImage::cleanupClass()  {  	delete sMutex;  	sMutex = NULL; - -	LLImageBase::destroyPrivatePool() ;  }  //static @@ -644,25 +639,6 @@ LLImageBase::~LLImageBase()  	deleteData(); // virtual  } -//static  -void LLImageBase::createPrivatePool()  -{ -	if(!sPrivatePoolp) -	{ -		sPrivatePoolp = LLPrivateMemoryPoolManager::getInstance()->newPool(LLPrivateMemoryPool::STATIC_THREADED) ; -	} -} -	 -//static  -void LLImageBase::destroyPrivatePool()  -{ -	if(sPrivatePoolp) -	{ -		LLPrivateMemoryPoolManager::getInstance()->deletePool(sPrivatePoolp) ; -		sPrivatePoolp = NULL ; -	} -} -  // virtual  void LLImageBase::dump()  { @@ -696,7 +672,7 @@ void LLImageBase::sanityCheck()  // virtual  void LLImageBase::deleteData()  { -	FREE_MEM(sPrivatePoolp, mData) ; +	ll_aligned_free_16(mData);  	disclaimMem(mDataSize);  	mDataSize = 0;  	mData = NULL; @@ -736,7 +712,7 @@ U8* LLImageBase::allocateData(S32 size)  	if (!mBadBufferAllocation && (!mData || size != mDataSize))  	{  		deleteData(); // virtual -		mData = (U8*)ALLOCATE_MEM(sPrivatePoolp, size); +		mData = (U8*)ll_aligned_malloc_16(size);  		if (!mData)  		{  			LL_WARNS() << "Failed to allocate image data size [" << size << "]" << LL_ENDL; @@ -763,7 +739,7 @@ U8* LLImageBase::allocateData(S32 size)  // virtual  U8* LLImageBase::reallocateData(S32 size)  { -	U8 *new_datap = (U8*)ALLOCATE_MEM(sPrivatePoolp, size); +	U8 *new_datap = (U8*)ll_aligned_malloc_16(size);  	if (!new_datap)  	{  		LL_WARNS() << "Out of memory in LLImageBase::reallocateData" << LL_ENDL; @@ -773,7 +749,7 @@ U8* LLImageBase::reallocateData(S32 size)  	{  		S32 bytes = llmin(mDataSize, size);  		memcpy(new_datap, mData, bytes);	/* Flawfinder: ignore */ -		FREE_MEM(sPrivatePoolp, mData) ; +		ll_aligned_free_16(mData) ;  	}  	mData = new_datap;  	disclaimMem(mDataSize); @@ -1470,7 +1446,7 @@ bool LLImageRaw::scale( S32 new_width, S32 new_height, bool scale_image_data )  		if (new_data_size > 0)          { -            U8 *new_data = (U8*)ALLOCATE_MEM(LLImageBase::getPrivatePool(), new_data_size);  +            U8 *new_data = (U8*)ll_aligned_malloc_16(new_data_size);               if(NULL == new_data)               {                  return false;  @@ -2169,7 +2145,7 @@ void LLImageFormatted::appendData(U8 *data, S32 size)  			S32 newsize = cursize + size;  			reallocateData(newsize);  			memcpy(getData() + cursize, data, size); -			FREE_MEM(LLImageBase::getPrivatePool(), data); +			ll_aligned_free_16(data);  		}  	}  } diff --git a/indra/llimage/llimage.h b/indra/llimage/llimage.h index 958c9fad3d..8ec49d3f0f 100644 --- a/indra/llimage/llimage.h +++ b/indra/llimage/llimage.h @@ -71,7 +71,6 @@ const S32 HTTP_PACKET_SIZE = 1496;  class LLImageFormatted;  class LLImageRaw;  class LLColor4U; -class LLPrivateMemoryPool;  typedef enum e_image_codec  { @@ -160,10 +159,6 @@ public:  	static F32 calc_download_priority(F32 virtual_size, F32 visible_area, S32 bytes_sent);  	static EImageCodec getCodecFromExtension(const std::string& exten); -	 -	static void createPrivatePool() ; -	static void destroyPrivatePool() ; -	static LLPrivateMemoryPool* getPrivatePool() {return sPrivatePoolp;}  	//static LLTrace::MemStatHandle sMemStat; @@ -178,8 +173,6 @@ private:  	bool mBadBufferAllocation ;  	bool mAllowOverSize ; - -	static LLPrivateMemoryPool* sPrivatePoolp ;  };  // Raw representation of an image (used for textures, and other uncompressed formats diff --git a/indra/llimage/llimagedxt.cpp b/indra/llimage/llimagedxt.cpp index 0ec83415a0..3a7319d765 100644 --- a/indra/llimage/llimagedxt.cpp +++ b/indra/llimage/llimagedxt.cpp @@ -430,7 +430,7 @@ bool LLImageDXT::convertToDXR()  	S32 nmips = calcNumMips(width,height);  	S32 total_bytes = getDataSize();  	U8* olddata = getData(); -	U8* newdata = (U8*)ALLOCATE_MEM(LLImageBase::getPrivatePool(), total_bytes); +	U8* newdata = (U8*)ll_aligned_malloc_16(total_bytes);  	if (!newdata)  	{  		LL_ERRS() << "Out of memory in LLImageDXT::convertToDXR()" << LL_ENDL; diff --git a/indra/llimage/llimagej2c.cpp b/indra/llimage/llimagej2c.cpp index c40df009d8..4bff21610f 100644 --- a/indra/llimage/llimagej2c.cpp +++ b/indra/llimage/llimagej2c.cpp @@ -368,7 +368,7 @@ bool LLImageJ2C::loadAndValidate(const std::string &filename)  	}  	else  	{ -		U8 *data = (U8*)ALLOCATE_MEM(LLImageBase::getPrivatePool(), file_size); +		U8 *data = (U8*)ll_aligned_malloc_16(file_size);  		if (!data)  		{  			infile.close(); @@ -383,7 +383,7 @@ bool LLImageJ2C::loadAndValidate(const std::string &filename)  			if (s != APR_SUCCESS || (S32)bytes_read != file_size)  			{ -				FREE_MEM(LLImageBase::getPrivatePool(), data); +				ll_aligned_free_16(data);  				setLastError("Unable to read entire file");  				res = false;  			} diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index 24f46d720b..648f9a8d93 100644 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -2921,28 +2921,54 @@ F32 LLVolume::sculptGetSurfaceArea()  	return area;  } -// create placeholder shape -void LLVolume::sculptGeneratePlaceholder() +// create empty placeholder shape +void LLVolume::sculptGenerateEmptyPlaceholder()  {  	S32 sizeS = mPathp->mPath.size();  	S32 sizeT = mProfilep->mProfile.size(); -	 +  	S32 line = 0; -	// for now, this is a sphere.  	for (S32 s = 0; s < sizeS; s++)  	{  		for (S32 t = 0; t < sizeT; t++)  		{  			S32 i = t + line;  			LLVector4a& pt = mMesh[i]; +					 +			F32* p = pt.getF32ptr(); -			 -			F32 u = (F32)s/(sizeS-1); -			F32 v = (F32)t/(sizeT-1); +			p[0] = 0; +			p[1] = 0; +			p[2] = 0; + +			llassert(pt.isFinite3()); +		} +		line += sizeT; +	} +} + +// create sphere placeholder shape +void LLVolume::sculptGenerateSpherePlaceholder() +{ +	S32 sizeS = mPathp->mPath.size(); +	S32 sizeT = mProfilep->mProfile.size(); + +	S32 line = 0; + +	for (S32 s = 0; s < sizeS; s++) +	{ +		for (S32 t = 0; t < sizeT; t++) +		{ +			S32 i = t + line; +			LLVector4a& pt = mMesh[i]; + + +			F32 u = (F32)s / (sizeS - 1); +			F32 v = (F32)t / (sizeT - 1);  			const F32 RADIUS = (F32) 0.3; -					 +  			F32* p = pt.getF32ptr();  			p[0] = (F32)(sin(F_PI * v) * cos(2.0 * F_PI * u) * RADIUS); @@ -2950,7 +2976,6 @@ void LLVolume::sculptGeneratePlaceholder()  			p[2] = (F32)(cos(F_PI * v) * RADIUS);  			llassert(pt.isFinite3()); -  		}  		line += sizeT;  	} @@ -3113,9 +3138,9 @@ void sculpt_calc_mesh_resolution(U16 width, U16 height, U8 type, F32 detail, S32  }  // sculpt replaces generate() for sculpted surfaces -void LLVolume::sculpt(U16 sculpt_width, U16 sculpt_height, S8 sculpt_components, const U8* sculpt_data, S32 sculpt_level) +void LLVolume::sculpt(U16 sculpt_width, U16 sculpt_height, S8 sculpt_components, const U8* sculpt_data, S32 sculpt_level, bool visible_placeholder)  { -    U8 sculpt_type = mParams.getSculptType(); +	U8 sculpt_type = mParams.getSculptType();  	BOOL data_is_empty = FALSE; @@ -3163,13 +3188,22 @@ void LLVolume::sculpt(U16 sculpt_width, U16 sculpt_height, S8 sculpt_components,  			if (area < SCULPT_MIN_AREA || area > SCULPT_MAX_AREA)  			{  				data_is_empty = TRUE; +				visible_placeholder = true;  			}  		}  	}  	if (data_is_empty)  	{ -		sculptGeneratePlaceholder(); +		if (visible_placeholder) +		{ +			// Object should be visible since there will be nothing else to display +			sculptGenerateSpherePlaceholder(); +		} +		else +		{ +			sculptGenerateEmptyPlaceholder(); +		}  	} diff --git a/indra/llmath/llvolume.h b/indra/llmath/llvolume.h index a8089f3709..4357b69b90 100644 --- a/indra/llmath/llvolume.h +++ b/indra/llmath/llvolume.h @@ -1059,7 +1059,7 @@ public:  	U32					mFaceMask;			// bit array of which faces exist in this volume  	LLVector3			mLODScaleBias;		// vector for biasing LOD based on scale -	void sculpt(U16 sculpt_width, U16 sculpt_height, S8 sculpt_components, const U8* sculpt_data, S32 sculpt_level); +	void sculpt(U16 sculpt_width, U16 sculpt_height, S8 sculpt_components, const U8* sculpt_data, S32 sculpt_level, bool visible_placeholder);  	void copyVolumeFaces(const LLVolume* volume);  	void copyFacesTo(std::vector<LLVolumeFace> &faces) const;  	void copyFacesFrom(const std::vector<LLVolumeFace> &faces); @@ -1068,7 +1068,8 @@ public:  private:  	void sculptGenerateMapVertices(U16 sculpt_width, U16 sculpt_height, S8 sculpt_components, const U8* sculpt_data, U8 sculpt_type);  	F32 sculptGetSurfaceArea(); -	void sculptGeneratePlaceholder(); +	void sculptGenerateEmptyPlaceholder(); +	void sculptGenerateSpherePlaceholder();  	void sculptCalcMeshResolution(U16 width, U16 height, U8 type, S32& s, S32& t); diff --git a/indra/llrender/llfontfreetype.cpp b/indra/llrender/llfontfreetype.cpp index de26d19efc..5c1f4ff8b3 100644 --- a/indra/llrender/llfontfreetype.cpp +++ b/indra/llrender/llfontfreetype.cpp @@ -106,6 +106,8 @@ LLFontFreetype::LLFontFreetype()  	mAscender(0.f),  	mDescender(0.f),  	mLineHeight(0.f), +	pFontBuffer(NULL), +	mBufferSize(0),  	mIsFallback(FALSE),  	mFTFace(NULL),  	mRenderGlyphCount(0), @@ -128,6 +130,8 @@ LLFontFreetype::~LLFontFreetype()  	mCharGlyphInfoMap.clear();  	delete mFontBitmapCachep; +	delete pFontBuffer; +	disclaimMem(mBufferSize);  	// mFallbackFonts cleaned up by LLPointer destructor  } @@ -143,13 +147,64 @@ BOOL LLFontFreetype::loadFace(const std::string& filename, F32 point_size, F32 v  	int error; +#ifdef LL_WINDOWS + +	if (mBufferSize > 0) +	{ +		delete pFontBuffer; +		disclaimMem(mBufferSize); +		pFontBuffer = NULL; +		mBufferSize = 0; +	} + +	S32 file_size = 0; +	LLFILE* file = LLFile::fopen(filename, "rb"); +	if (!file) +	{ +		return FALSE; +	} + +	if (!fseek(file, 0, SEEK_END)) +	{ +		file_size = ftell(file); +		fseek(file, 0, SEEK_SET); +	} + +	// Don't delete before FT_Done_Face +	pFontBuffer = new(std::nothrow) U8[file_size]; +	if (!pFontBuffer) +	{ +		fclose(file); +		return FALSE; +	} + +	mBufferSize = fread(pFontBuffer, 1, file_size, file); +	fclose(file); + +	if (mBufferSize != file_size) +	{ +		delete pFontBuffer; +		mBufferSize = 0; +		return FALSE; +	} + +	error = FT_New_Memory_Face( gFTLibrary, +								(FT_Byte*) pFontBuffer, +								mBufferSize, +								0, +								&mFTFace); +#else  	error = FT_New_Face( gFTLibrary,  						 filename.c_str(),  						 0, -						 &mFTFace ); +						 &mFTFace); +#endif -    if (error) +	if (error)  	{ +		delete pFontBuffer; +		pFontBuffer = NULL; +		mBufferSize = 0;  		return FALSE;  	} @@ -166,10 +221,15 @@ BOOL LLFontFreetype::loadFace(const std::string& filename, F32 point_size, F32 v  	{  		// Clean up freetype libs.  		FT_Done_Face(mFTFace); +		delete pFontBuffer; +		pFontBuffer = NULL; +		mBufferSize = 0;  		mFTFace = NULL;  		return FALSE;  	} +	claimMem(mBufferSize); +  	F32 y_max, y_min, x_max, x_min;  	F32 ems_per_unit = 1.f/ mFTFace->units_per_EM;  	F32 pixels_per_unit = pixels_per_em * ems_per_unit; diff --git a/indra/llrender/llfontfreetype.h b/indra/llrender/llfontfreetype.h index a5ece42b88..26ba695418 100644 --- a/indra/llrender/llfontfreetype.h +++ b/indra/llrender/llfontfreetype.h @@ -158,6 +158,8 @@ private:  	F32 mLineHeight;  	LLFT_Face mFTFace; +	U8* pFontBuffer; +	S32 mBufferSize;  	BOOL mIsFallback;  	font_vector_t mFallbackFonts; // A list of fallback fonts to look for glyphs in (for Unicode chars) diff --git a/indra/llrender/llfontregistry.cpp b/indra/llrender/llfontregistry.cpp index d003687415..3c829596ce 100644 --- a/indra/llrender/llfontregistry.cpp +++ b/indra/llrender/llfontregistry.cpp @@ -447,7 +447,7 @@ LLFontGL *LLFontRegistry::createFont(const LLFontDescriptor& desc)  			if (!fontp->loadFace(font_path, extra_scale * point_size,  								 LLFontGL::sVertDPI, LLFontGL::sHorizDPI, 2, is_fallback))  			{ -				LL_INFOS_ONCE("LLFontRegistry") << "Couldn't load font " << *file_name_it << LL_ENDL; +				LL_INFOS_ONCE("LLFontRegistry") << "Couldn't load font " << *file_name_it << " from path " << local_path << LL_ENDL;  				delete fontp;  				fontp = NULL;  			} diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp index f10301b42d..a55ca5ed9c 100644 --- a/indra/llrender/llvertexbuffer.cpp +++ b/indra/llrender/llvertexbuffer.cpp @@ -98,7 +98,6 @@ U32 LLVertexBuffer::sCurVAOName = 1;  U32 LLVertexBuffer::sAllocatedIndexBytes = 0;  U32 LLVertexBuffer::sIndexCount = 0; -LLPrivateMemoryPool* LLVertexBuffer::sPrivatePoolp = NULL;  U32 LLVertexBuffer::sBindCount = 0;  U32 LLVertexBuffer::sSetCount = 0;  S32 LLVertexBuffer::sCount = 0; @@ -191,6 +190,10 @@ volatile U8* LLVBOPool::allocate(U32& name, U32 size, bool for_seed)  			if (mUsage != GL_DYNAMIC_COPY_ARB)  			{ //data will be provided by application  				ret = (U8*) ll_aligned_malloc<64>(size); +				if (!ret) +				{ +					LL_ERRS() << "Failed to allocate for LLVBOPool buffer" << LL_ENDL; +				}  			}  		}  		else @@ -859,11 +862,6 @@ void LLVertexBuffer::initClass(bool use_vbo, bool no_vbo_mapping)  {  	sEnableVBOs = use_vbo && gGLManager.mHasVertexBufferObject;  	sDisableVBOMapping = sEnableVBOs && no_vbo_mapping; - -	if (!sPrivatePoolp) -	{  -		sPrivatePoolp = LLPrivateMemoryPoolManager::getInstance()->newPool(LLPrivateMemoryPool::STATIC); -	}  }  //static  @@ -906,12 +904,6 @@ void LLVertexBuffer::cleanupClass()  	sStreamVBOPool.cleanup();  	sDynamicVBOPool.cleanup();  	sDynamicCopyVBOPool.cleanup(); - -	if(sPrivatePoolp) -	{ -		LLPrivateMemoryPoolManager::getInstance()->deletePool(sPrivatePoolp); -		sPrivatePoolp = NULL; -	}  }  //---------------------------------------------------------------------------- @@ -1202,7 +1194,7 @@ bool LLVertexBuffer::createGLBuffer(U32 size)  	{  		static int gl_buffer_idx = 0;  		mGLBuffer = ++gl_buffer_idx; -		mMappedData = (U8*)ALLOCATE_MEM(sPrivatePoolp, size); +		mMappedData = (U8*)ll_aligned_malloc_16(size);  		disclaimMem(mSize);  		mSize = size;  		claimMem(mSize); @@ -1244,7 +1236,7 @@ bool LLVertexBuffer::createGLIndices(U32 size)  	}  	else  	{ -		mMappedIndexData = (U8*)ALLOCATE_MEM(sPrivatePoolp, size); +		mMappedIndexData = (U8*)ll_aligned_malloc_16(size);  		static int gl_buffer_idx = 0;  		mGLIndices = ++gl_buffer_idx;  		mIndicesSize = size; @@ -1267,7 +1259,7 @@ void LLVertexBuffer::destroyGLBuffer()  		}  		else  		{ -			FREE_MEM(sPrivatePoolp, (void*) mMappedData); +			ll_aligned_free_16((void*)mMappedData);  			mMappedData = NULL;  			mEmpty = true;  		} @@ -1287,7 +1279,7 @@ void LLVertexBuffer::destroyGLIndices()  		}  		else  		{ -			FREE_MEM(sPrivatePoolp, (void*) mMappedIndexData); +			ll_aligned_free_16((void*)mMappedIndexData);  			mMappedIndexData = NULL;  			mEmpty = true;  		} diff --git a/indra/llui/llbadge.cpp b/indra/llui/llbadge.cpp index 15b6899d74..589b75ab5b 100644 --- a/indra/llui/llbadge.cpp +++ b/indra/llui/llbadge.cpp @@ -102,6 +102,7 @@ LLBadge::LLBadge(const LLBadge::Params& p)  	, mPaddingHoriz(p.padding_horiz)  	, mPaddingVert(p.padding_vert)  	, mParentScroller(NULL) +	, mDrawAtParentTop(false)  {  	if (mImage.isNull())  	{ @@ -307,7 +308,14 @@ void LLBadge::draw()  			// Compute y position  			if (mLocationOffsetVCenter == BADGE_OFFSET_NOT_SPECIFIED)  			{ -				badge_center_y = owner_rect.mBottom + owner_rect.getHeight() * mLocationPercentVCenter; +				if(mDrawAtParentTop) +				{ +					badge_center_y = owner_rect.mTop - badge_height * 0.5f - 1; +				} +				else +				{ +					badge_center_y = owner_rect.mBottom + owner_rect.getHeight() * mLocationPercentVCenter; +				}  			}  			else  			{ diff --git a/indra/llui/llbadge.h b/indra/llui/llbadge.h index 4b21a71aaa..55f92e6e34 100644 --- a/indra/llui/llbadge.h +++ b/indra/llui/llbadge.h @@ -137,6 +137,8 @@ public:  	const std::string	getLabel() const { return wstring_to_utf8str(mLabel); }  	void				setLabel( const LLStringExplicit& label); +	void				setDrawAtParentTop(bool draw_at_top) { mDrawAtParentTop = draw_at_top;} +  private:  	LLPointer< LLUIImage >	mBorderImage;  	LLUIColor				mBorderColor; @@ -164,6 +166,7 @@ private:  	F32						mPaddingVert;  	LLScrollContainer*		mParentScroller; +	bool					mDrawAtParentTop;  };  // Build time optimization, generate once in .cpp file diff --git a/indra/llui/llbadgeowner.cpp b/indra/llui/llbadgeowner.cpp index 55e64bb940..0557cd4375 100644 --- a/indra/llui/llbadgeowner.cpp +++ b/indra/llui/llbadgeowner.cpp @@ -64,6 +64,14 @@ void LLBadgeOwner::setBadgeVisibility(bool visible)  	}  } +void LLBadgeOwner::setDrawBadgeAtTop(bool draw_at_top) +{ +	if (mBadge) +	{ +		mBadge->setDrawAtParentTop(draw_at_top); +	} +} +  void LLBadgeOwner::addBadgeToParentHolder()  {  	LLView * owner_view = mBadgeOwnerView.get(); diff --git a/indra/llui/llbadgeowner.h b/indra/llui/llbadgeowner.h index 53c2de95c8..01ed95f3a3 100644 --- a/indra/llui/llbadgeowner.h +++ b/indra/llui/llbadgeowner.h @@ -45,6 +45,7 @@ public:  	bool hasBadgeHolderParent() const { return mHasBadgeHolderParent; };  	void setBadgeVisibility(bool visible); +	void setDrawBadgeAtTop(bool draw_at_top);  private: diff --git a/indra/llui/lltrans.cpp b/indra/llui/lltrans.cpp index 4d4ff4236d..a1a8feedaa 100644 --- a/indra/llui/lltrans.cpp +++ b/indra/llui/lltrans.cpp @@ -36,6 +36,7 @@  #include <map>  LLTrans::template_map_t LLTrans::sStringTemplates; +LLTrans::template_map_t LLTrans::sDefaultStringTemplates;  LLStringUtil::format_map_t LLTrans::sDefaultArgs;  struct StringDef : public LLInitParam::Block<StringDef> @@ -76,7 +77,7 @@ bool LLTrans::parseStrings(LLXMLNodePtr &root, const std::set<std::string>& defa  		LL_ERRS() << "Problem reading strings: " << xml_filename << LL_ENDL;  		return false;  	} -	 +	static bool default_strings_init = false;  	sStringTemplates.clear();  	sDefaultArgs.clear(); @@ -86,7 +87,10 @@ bool LLTrans::parseStrings(LLXMLNodePtr &root, const std::set<std::string>& defa  	{  		LLTransTemplate xml_template(it->name, it->value);  		sStringTemplates[xml_template.mName] = xml_template; -		 +		if (!default_strings_init) +		{ +			sDefaultStringTemplates[xml_template.mName] = xml_template; +		}  		std::set<std::string>::const_iterator iter = default_args.find(xml_template.mName);  		if (iter != default_args.end())  		{ @@ -96,6 +100,7 @@ bool LLTrans::parseStrings(LLXMLNodePtr &root, const std::set<std::string>& defa  			sDefaultArgs[name] = xml_template.mText;  		}  	} +	default_strings_init = true;  	return true;  } @@ -138,12 +143,17 @@ bool LLTrans::parseLanguageStrings(LLXMLNodePtr &root)  static LLTrace::BlockTimerStatHandle FTM_GET_TRANS("Translate string");  //static  -std::string LLTrans::getString(const std::string &xml_desc, const LLStringUtil::format_map_t& msg_args) +std::string LLTrans::getString(const std::string &xml_desc, const LLStringUtil::format_map_t& msg_args, bool def_string)  {  	// Don't care about time as much as call count.  Make sure we're not  	// calling LLTrans::getString() in an inner loop. JC  	LL_RECORD_BLOCK_TIME(FTM_GET_TRANS); +	if (def_string) +	{ +		return getDefString(xml_desc, msg_args); +	} +  	template_map_t::iterator iter = sStringTemplates.find(xml_desc);  	if (iter != sStringTemplates.end())  	{ @@ -161,13 +171,38 @@ std::string LLTrans::getString(const std::string &xml_desc, const LLStringUtil::  	}  } +//static  +std::string LLTrans::getDefString(const std::string &xml_desc, const LLStringUtil::format_map_t& msg_args) +{ +	template_map_t::iterator iter = sDefaultStringTemplates.find(xml_desc); +	if (iter != sDefaultStringTemplates.end()) +	{ +		std::string text = iter->second.mText; +		LLStringUtil::format_map_t args = sDefaultArgs; +		args.insert(msg_args.begin(), msg_args.end()); +		LLStringUtil::format(text, args); + +		return text; +	} +	else +	{ +		LL_WARNS_ONCE("configuration") << "Missing String in strings.xml: [" << xml_desc << "]" << LL_ENDL; +		return "MissingString(" + xml_desc + ")"; +	} +} +  //static -std::string LLTrans::getString(const std::string &xml_desc, const LLSD& msg_args) +std::string LLTrans::getString(const std::string &xml_desc, const LLSD& msg_args, bool def_string)  {  	// Don't care about time as much as call count.  Make sure we're not  	// calling LLTrans::getString() in an inner loop. JC  	LL_RECORD_BLOCK_TIME(FTM_GET_TRANS); +	if (def_string) +	{ +		return getDefString(xml_desc, msg_args); +	} +  	template_map_t::iterator iter = sStringTemplates.find(xml_desc);  	if (iter != sStringTemplates.end())  	{ @@ -182,6 +217,23 @@ std::string LLTrans::getString(const std::string &xml_desc, const LLSD& msg_args  	}  } +//static +std::string LLTrans::getDefString(const std::string &xml_desc, const LLSD& msg_args) +{ +	template_map_t::iterator iter = sDefaultStringTemplates.find(xml_desc); +	if (iter != sDefaultStringTemplates.end()) +	{ +		std::string text = iter->second.mText; +		LLStringUtil::format(text, msg_args); +		return text; +	} +	else +	{ +		LL_WARNS_ONCE("configuration") << "Missing String in strings.xml: [" << xml_desc << "]" << LL_ENDL; +		return "MissingString(" + xml_desc + ")"; +	} +} +  //static   bool LLTrans::findString(std::string &result, const std::string &xml_desc, const LLStringUtil::format_map_t& msg_args)  { diff --git a/indra/llui/lltrans.h b/indra/llui/lltrans.h index a47ce94f08..9bd751fc78 100644 --- a/indra/llui/lltrans.h +++ b/indra/llui/lltrans.h @@ -76,8 +76,10 @@ public:  	 * @param args A list of substrings to replace in the string  	 * @returns Translated string  	 */ -	static std::string getString(const std::string &xml_desc, const LLStringUtil::format_map_t& args); -	static std::string getString(const std::string &xml_desc, const LLSD& args); +	static std::string getString(const std::string &xml_desc, const LLStringUtil::format_map_t& args, bool def_string = false); +	static std::string getDefString(const std::string &xml_desc, const LLStringUtil::format_map_t& args); +	static std::string getString(const std::string &xml_desc, const LLSD& args, bool def_string = false); +	static std::string getDefString(const std::string &xml_desc, const LLSD& args);  	static bool findString(std::string &result, const std::string &xml_desc, const LLStringUtil::format_map_t& args);  	static bool findString(std::string &result, const std::string &xml_desc, const LLSD& args); @@ -92,7 +94,7 @@ public:  	 * @param xml_desc String's description  	 * @returns Translated string  	 */ -	static std::string getString(const std::string &xml_desc) +	static std::string getString(const std::string &xml_desc, bool def_string = false)  	{  		LLStringUtil::format_map_t empty;  		return getString(xml_desc, empty); @@ -128,6 +130,7 @@ public:  private:  	typedef std::map<std::string, LLTransTemplate > template_map_t;  	static template_map_t sStringTemplates; +	static template_map_t sDefaultStringTemplates;  	static LLStringUtil::format_map_t sDefaultArgs;  }; diff --git a/indra/llvfs/llvfs.cpp b/indra/llvfs/llvfs.cpp index db0eac7031..d5bd1834c2 100644 --- a/indra/llvfs/llvfs.cpp +++ b/indra/llvfs/llvfs.cpp @@ -2120,7 +2120,11 @@ time_t LLVFS::creationTime()      int errors = LLFile::stat(mDataFilename, &data_file_stat);      if (0 == errors)      { -        return data_file_stat.st_ctime; +        time_t creation_time = data_file_stat.st_ctime; +#if LL_DARWIN +        creation_time = data_file_stat.st_birthtime; +#endif +        return creation_time;      }      return 0;  } diff --git a/indra/llwindow/llwindowwin32.cpp b/indra/llwindow/llwindowwin32.cpp index 9fa07d1d34..38f8989797 100644 --- a/indra/llwindow/llwindowwin32.cpp +++ b/indra/llwindow/llwindowwin32.cpp @@ -69,6 +69,10 @@ const F32	ICON_FLASH_TIME = 0.5f;  #define WM_DPICHANGED 0x02E0  #endif +#ifndef USER_DEFAULT_SCREEN_DPI +#define USER_DEFAULT_SCREEN_DPI 96 // Win7 +#endif +  extern BOOL gDebugWindowProc;  LPWSTR gIconResource = IDI_APPLICATION; diff --git a/indra/newview/Info-SecondLife.plist b/indra/newview/Info-SecondLife.plist index 8aabd6818b..af4cf26ac6 100644 --- a/indra/newview/Info-SecondLife.plist +++ b/indra/newview/Info-SecondLife.plist @@ -21,7 +21,7 @@  	<key>CFBundlePackageType</key>  	<string>APPL</string>  	<key>CFBundleShortVersionString</key> -	<string>${MACOSX_BUNDLE_SHORT_VERSION_STRING}</string> +	<string>${MACOSX_BUNDLE_LONG_VERSION_STRING}</string>  	<key>CFBundleSignature</key>  	<string>????</string>  	<key>CFBundleVersion</key> diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index dd07972249..3b518515cb 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -2369,7 +2369,7 @@        <key>Value</key>        <integer>0</integer>      </map> -    <key>DebugShowPrivateMem</key> +    <key>DEPRECATED: DebugShowPrivateMem</key>  <!-- deprecated (see MAINT-8091) -->      <map>        <key>Comment</key>        <string>Show Private Mem Info</string> @@ -6408,10 +6408,10 @@          <key>Value</key>              <real>600.0</real>          </map> -    <key>MemoryPrivatePoolEnabled</key> +    <key>MemoryPrivatePoolEnabled</key>  <!-- deprecated (see MAINT-8091) -->      <map>        <key>Comment</key> -      <string>Enable the private memory pool management</string> +      <string>DEPRECATED: Enable the private memory pool management</string>        <key>Persist</key>        <integer>1</integer>        <key>Type</key> @@ -6419,10 +6419,10 @@        <key>Value</key>        <integer>0</integer>      </map> -    <key>MemoryPrivatePoolSize</key> +    <key>MemoryPrivatePoolSize</key>  <!-- deprecated (see MAINT-8091) -->      <map>        <key>Comment</key> -      <string>Size of the private memory pool in MB (min. value is 256)</string> +      <string>DEPRECATED: Size of the private memory pool in MB (min. value is 256)</string>        <key>Persist</key>        <integer>1</integer>        <key>Type</key> diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp index 0fb811a386..c0f88ef704 100644 --- a/indra/newview/llappearancemgr.cpp +++ b/indra/newview/llappearancemgr.cpp @@ -1919,7 +1919,7 @@ bool LLAppearanceMgr::getCanReplaceCOF(const LLUUID& outfit_cat_id)  	}  	// Check whether it's the base outfit. -	if (outfit_cat_id.isNull() || outfit_cat_id == getBaseOutfitUUID()) +	if (outfit_cat_id.isNull())  	{  		return false;  	} diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 464e216cf0..d9273dfcb5 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -353,6 +353,8 @@ BOOL gCrashOnStartup = FALSE;  BOOL gLLErrorActivated = FALSE;  BOOL gLogoutInProgress = FALSE; +BOOL gSimulateMemLeak = FALSE; +  ////////////////////////////////////////////////////////////  // Internal globals... that should be removed.  static std::string gArgs; @@ -797,7 +799,6 @@ bool LLAppViewer::init()  	initMaxHeapSize() ;  	LLCoros::instance().setStackSize(gSavedSettings.getS32("CoroutineStackSize")); -	LLPrivateMemoryPoolManager::initClass((BOOL)gSavedSettings.getBOOL("MemoryPrivatePoolEnabled"), (U32)gSavedSettings.getU32("MemoryPrivatePoolSize")*1024*1024) ;  	// write Google Breakpad minidump files to a per-run dump directory to avoid multiple viewer issues.  	std::string logdir = gDirUtilp->getExpandedFilename(LL_PATH_DUMP, "");  	mDumpPath = logdir; @@ -1318,13 +1319,49 @@ LLTrace::BlockTimerStatHandle FTM_FRAME("Frame");  bool LLAppViewer::frame()  { +	bool ret = false; + +	if (gSimulateMemLeak) +	{ +		try +		{ +			ret = doFrame(); +		} +		catch (const LLContinueError&) +		{ +			LOG_UNHANDLED_EXCEPTION(""); +		} +		catch (std::bad_alloc) +		{ +			LLMemory::logMemoryInfo(TRUE); +			LLFloaterMemLeak* mem_leak_instance = LLFloaterReg::findTypedInstance<LLFloaterMemLeak>("mem_leaking"); +			if (mem_leak_instance) +			{ +				mem_leak_instance->stop(); +			} +			LL_WARNS() << "Bad memory allocation in LLAppViewer::frame()!" << LL_ENDL; +		} +	} +	else +	{  +		try +		{ +			ret = doFrame(); +		} +		catch (const LLContinueError&) +		{ +			LOG_UNHANDLED_EXCEPTION(""); +		} +	} + +	return ret; +} + +bool LLAppViewer::doFrame() +{  	LLEventPump& mainloop(LLEventPumps::instance().obtain("mainloop"));  	LLSD newFrame; -	//LLPrivateMemoryPoolTester::getInstance()->run(false) ; -	//LLPrivateMemoryPoolTester::getInstance()->run(true) ; -	//LLPrivateMemoryPoolTester::destroy() ; -  	LL_RECORD_BLOCK_TIME(FTM_FRAME);  	LLTrace::BlockTimer::processTimes();  	LLTrace::get_frame_recording().nextPeriod(); @@ -1338,7 +1375,6 @@ bool LLAppViewer::frame()  	//check memory availability information  	checkMemory() ; -	try  	{  		pingMainloopTimeout("Main:MiscNativeWindowEvents"); @@ -1362,12 +1398,15 @@ bool LLAppViewer::frame()  		}  		//memory leaking simulation -		LLFloaterMemLeak* mem_leak_instance = -			LLFloaterReg::findTypedInstance<LLFloaterMemLeak>("mem_leaking"); -		if(mem_leak_instance) +		if (gSimulateMemLeak)  		{ -			mem_leak_instance->idle() ;				 -		}							 +			LLFloaterMemLeak* mem_leak_instance = +				LLFloaterReg::findTypedInstance<LLFloaterMemLeak>("mem_leaking"); +			if (mem_leak_instance) +			{ +				mem_leak_instance->idle(); +			} +		}  		// canonical per-frame event  		mainloop.post(newFrame); @@ -1542,60 +1581,13 @@ bool LLAppViewer::frame()  			pingMainloopTimeout("Main:End");  		}  	} -	catch (const LLContinueError&) -	{ -		LOG_UNHANDLED_EXCEPTION(""); -	} -	catch(std::bad_alloc) -	{ -		LLMemory::logMemoryInfo(TRUE) ; - -		//stop memory leaking simulation -		LLFloaterMemLeak* mem_leak_instance = -			LLFloaterReg::findTypedInstance<LLFloaterMemLeak>("mem_leaking"); -		if(mem_leak_instance) -		{ -			mem_leak_instance->stop() ; -			LL_WARNS() << "Bad memory allocation in LLAppViewer::frame()!" << LL_ENDL ; -		} -		else -		{ -			//output possible call stacks to log file. -			LLError::LLCallStacks::print() ; - -			LL_ERRS() << "Bad memory allocation in LLAppViewer::frame()!" << LL_ENDL ; -		} -	} -	catch (...) -	{ -		CRASH_ON_UNHANDLED_EXCEPTION(""); -	}  	if (LLApp::isExiting())  	{  		// Save snapshot for next time, if we made it through initialization  		if (STATE_STARTED == LLStartUp::getStartupState())  		{ -			try -			{ -				saveFinalSnapshot(); -			} -			catch(std::bad_alloc) -			{ -				LL_WARNS() << "Bad memory allocation when saveFinalSnapshot() is called!" << LL_ENDL ; - -				//stop memory leaking simulation -				LLFloaterMemLeak* mem_leak_instance = -				LLFloaterReg::findTypedInstance<LLFloaterMemLeak>("mem_leaking"); -				if(mem_leak_instance) -				{ -					mem_leak_instance->stop() ; -				} -			} -			catch (...) -			{ -				CRASH_ON_UNHANDLED_EXCEPTION("saveFinalSnapshot()"); -			} +			saveFinalSnapshot();  		}  		delete gServicePump; @@ -2078,9 +2070,6 @@ bool LLAppViewer::cleanup()  	LLMainLoopRepeater::instance().stop(); -	//release all private memory pools. -	LLPrivateMemoryPoolManager::destroyClass() ; -  	ll_close_fail_log();  	LLError::LLCallStacks::cleanup(); @@ -3230,7 +3219,7 @@ LLSD LLAppViewer::getViewerInfo() const  	return info;  } -std::string LLAppViewer::getViewerInfoString() const +std::string LLAppViewer::getViewerInfoString(bool default_string) const  {  	std::ostringstream support; @@ -3240,7 +3229,7 @@ std::string LLAppViewer::getViewerInfoString() const  	LLStringUtil::format_map_t args;  	// allow the "Release Notes" URL label to be localized -	args["ReleaseNotes"] = LLTrans::getString("ReleaseNotes"); +	args["ReleaseNotes"] = LLTrans::getString("ReleaseNotes", default_string);  	for (LLSD::map_const_iterator ii(info.beginMap()), iend(info.endMap());  		ii != iend; ++ii) @@ -3250,7 +3239,7 @@ std::string LLAppViewer::getViewerInfoString() const  			// Scalar value  			if (ii->second.isUndefined())  			{ -				args[ii->first] = LLTrans::getString("none_text"); +				args[ii->first] = LLTrans::getString("none_text", default_string);  			}  			else  			{ @@ -3269,101 +3258,37 @@ std::string LLAppViewer::getViewerInfoString() const  	}  	// Now build the various pieces -	support << LLTrans::getString("AboutHeader", args); +	support << LLTrans::getString("AboutHeader", args, default_string);  	if (info.has("BUILD_CONFIG"))  	{ -		support << "\n" << LLTrans::getString("BuildConfig", args); +		support << "\n" << LLTrans::getString("BuildConfig", args, default_string);  	}  	if (info.has("REGION"))  	{ -		support << "\n\n" << LLTrans::getString("AboutPosition", args); +		support << "\n\n" << LLTrans::getString("AboutPosition", args, default_string);  	} -	support << "\n\n" << LLTrans::getString("AboutSystem", args); +	support << "\n\n" << LLTrans::getString("AboutSystem", args, default_string);  	support << "\n";  	if (info.has("GRAPHICS_DRIVER_VERSION"))  	{ -		support << "\n" << LLTrans::getString("AboutDriver", args); +		support << "\n" << LLTrans::getString("AboutDriver", args, default_string);  	} -	support << "\n" << LLTrans::getString("AboutOGL", args); -	support << "\n\n" << LLTrans::getString("AboutSettings", args); -	support << "\n\n" << LLTrans::getString("AboutLibs", args); +	support << "\n" << LLTrans::getString("AboutOGL", args, default_string); +	support << "\n\n" << LLTrans::getString("AboutSettings", args, default_string); +	support << "\n\n" << LLTrans::getString("AboutLibs", args, default_string);  	if (info.has("COMPILER"))  	{ -		support << "\n" << LLTrans::getString("AboutCompiler", args); +		support << "\n" << LLTrans::getString("AboutCompiler", args, default_string);  	}  	if (info.has("PACKETS_IN"))  	{ -		support << '\n' << LLTrans::getString("AboutTraffic", args); +		support << '\n' << LLTrans::getString("AboutTraffic", args, default_string);  	}  	// SLT timestamp  	LLSD substitution;  	substitution["datetime"] = (S32)time(NULL);//(S32)time_corrected(); -	support << "\n" << LLTrans::getString("AboutTime", substitution); - -	return support.str(); -} - -std::string LLAppViewer::getShortViewerInfoString() const -{ -	std::ostringstream support; -	LLSD info(getViewerInfo()); - -	support << LLTrans::getString("APP_NAME") << " " << info["VIEWER_VERSION_STR"].asString(); -	support << " (" << info["CHANNEL"].asString() << ")"; -	if (info.has("BUILD_CONFIG")) -	{ -		support << "\n" << "Build Configuration " << info["BUILD_CONFIG"].asString(); -	} -	if (info.has("REGION")) -	{ -		support << "\n\n" << "You are at " << ll_vector3_from_sd(info["POSITION_LOCAL"]) << " in " << info["REGION"].asString(); -		support << " located at " << info["HOSTNAME"].asString() << " (" << info["HOSTIP"].asString() << ")"; -		support << "\n" << "SLURL: " << info["SLURL"].asString(); -		support << "\n" << "(Global coordinates " << ll_vector3_from_sd(info["POSITION"]) << ")"; -		support << "\n" << info["SERVER_VERSION"].asString(); -	} - -	support << "\n\n" << "CPU: " << info["CPU"].asString(); -	support << "\n" << "Memory: " << info["MEMORY_MB"].asString() << " MB"; -	support << "\n" << "OS: " << info["OS_VERSION"].asString(); -	support << "\n" << "Graphics Card: " << info["GRAPHICS_CARD"].asString() << " (" <<  info["GRAPHICS_CARD_VENDOR"].asString() << ")"; - -	if (info.has("GRAPHICS_DRIVER_VERSION")) -	{ -		support << "\n" << "Windows Graphics Driver Version: " << info["GRAPHICS_DRIVER_VERSION"].asString(); -	} - -	support << "\n" << "OpenGL Version: " << info["OPENGL_VERSION"].asString(); - -	support << "\n\n" << "Window size:" << info["WINDOW_WIDTH"].asString() << "x" << info["WINDOW_HEIGHT"].asString(); -	support << "\n" << "Language: " << LLUI::getLanguage(); -	support << "\n" << "Font Size Adjustment: " << info["FONT_SIZE_ADJUSTMENT"].asString() << "pt"; -	support << "\n" << "UI Scaling: " << info["UI_SCALE"].asString(); -	support << "\n" << "Draw distance: " << info["DRAW_DISTANCE"].asString(); -	support << "\n" << "Bandwidth: " << info["NET_BANDWITH"].asString() << "kbit/s"; -	support << "\n" << "LOD factor: " << info["LOD_FACTOR"].asString(); -	support << "\n" << "Render quality: " << info["RENDER_QUALITY"].asString() << " / 7"; -	support << "\n" << "ALM: " << info["GPU_SHADERS"].asString(); -	support << "\n" << "Texture memory: " << info["TEXTURE_MEMORY"].asString() << "MB"; -	support << "\n" << "VFS (cache) creation time: " << info["VFS_TIME"].asString(); - -	support << "\n\n" << "J2C Decoder: " << info["J2C_VERSION"].asString(); -	support << "\n" << "Audio Driver: " << info["AUDIO_DRIVER_VERSION"].asString(); -	support << "\n" << "LLCEFLib/CEF: " << info["LLCEFLIB_VERSION"].asString(); -	support << "\n" << "LibVLC: " << info["LIBVLC_VERSION"].asString(); -	support << "\n" << "Voice Server: " << info["VOICE_VERSION"].asString(); - -	if (info.has("PACKETS_IN")) -	{ -		support << "\n" << "Packets Lost: " << info["PACKETS_LOST"].asInteger() << "/" << info["PACKETS_IN"].asInteger(); -		F32 packets_pct = info["PACKETS_PCT"].asReal(); -		support << " (" << ll_round(packets_pct, 0.001f) << "%)"; -	} - -	LLSD substitution; -	substitution["datetime"] = (S32)time(NULL); -	support << "\n" << LLTrans::getString("AboutTime", substitution); +	support << "\n" << LLTrans::getString("AboutTime", substitution, default_string);  	return support.str();  } diff --git a/indra/newview/llappviewer.h b/indra/newview/llappviewer.h index 6eb45d2495..e607b4a994 100644 --- a/indra/newview/llappviewer.h +++ b/indra/newview/llappviewer.h @@ -99,8 +99,7 @@ public:  	void setServerReleaseNotesURL(const std::string& url) { mServerReleaseNotesURL = url; }  	LLSD getViewerInfo() const; -	std::string getViewerInfoString() const; -	std::string getShortViewerInfoString() const; +	std::string getViewerInfoString(bool default_string = false) const;  	// Report true if under the control of a debugger. A null-op default.  	virtual bool beingDebugged() { return false; }  @@ -222,6 +221,8 @@ protected:  private: +	bool doFrame(); +  	void initMaxHeapSize();  	bool initThreads(); // Initialize viewer threads, return false on failure.  	bool initConfiguration(); // Initialize settings from the command line/config file. @@ -396,4 +397,6 @@ extern LLUUID gBlackSquareID;  extern BOOL gRandomizeFramerate;  extern BOOL gPeriodicSlowFrame; +extern BOOL gSimulateMemLeak; +  #endif // LL_LLAPPVIEWER_H diff --git a/indra/newview/llfacebookconnect.cpp b/indra/newview/llfacebookconnect.cpp index 1de4102dba..43b01fa2f1 100644 --- a/indra/newview/llfacebookconnect.cpp +++ b/indra/newview/llfacebookconnect.cpp @@ -503,13 +503,10 @@ LLFacebookConnect::LLFacebookConnect()  void LLFacebookConnect::openFacebookWeb(std::string url)  { -	// Open the URL in an internal browser window without navigation UI  	LLFloaterWebContent::Params p;      p.url(url);      p.show_chrome(true); -    p.allow_address_entry(false);      p.allow_back_forward_navigation(false); -    p.trusted_content(true);      p.clean_browser(true);  	LLFloater *floater = LLFloaterReg::showInstance("fbc_web", p);  	//the internal web browser has a bug that prevents it from gaining focus unless a mouse event occurs first (it seems). diff --git a/indra/newview/llfilteredwearablelist.cpp b/indra/newview/llfilteredwearablelist.cpp index e67a6a2b77..2bfaa1e5bc 100644 --- a/indra/newview/llfilteredwearablelist.cpp +++ b/indra/newview/llfilteredwearablelist.cpp @@ -32,6 +32,7 @@  #include "llinventoryitemslist.h"  #include "llinventorymodel.h"  #include "llviewerinventory.h" +#include "lltrans.h"  LLFilteredWearableListManager::LLFilteredWearableListManager(LLInventoryItemsList* list, LLInventoryCollectFunctor* collector) @@ -118,6 +119,11 @@ void LLFilteredWearableListManager::populateList()  	// Probably will also need to get items from Library (waiting for reply in EXT-6724). +	if (item_array.empty() && gInventory.isCategoryComplete(gInventory.getRootFolderID())) +	{ +		mWearableList->setNoItemsCommentText(LLTrans::getString("NoneFound")); +	} +  	mWearableList->refreshList(item_array);  } diff --git a/indra/newview/llflickrconnect.cpp b/indra/newview/llflickrconnect.cpp index c0ca5b8cf8..d7d161f239 100644 --- a/indra/newview/llflickrconnect.cpp +++ b/indra/newview/llflickrconnect.cpp @@ -397,13 +397,10 @@ LLFlickrConnect::LLFlickrConnect()  void LLFlickrConnect::openFlickrWeb(std::string url)  { -	// Open the URL in an internal browser window without navigation UI  	LLFloaterWebContent::Params p;      p.url(url);      p.show_chrome(true); -    p.allow_address_entry(false);      p.allow_back_forward_navigation(false); -    p.trusted_content(true);      p.clean_browser(true);  	LLFloater *floater = LLFloaterReg::showInstance("flickr_web", p);  	//the internal web browser has a bug that prevents it from gaining focus unless a mouse event occurs first (it seems). diff --git a/indra/newview/llfloaterimagepreview.cpp b/indra/newview/llfloaterimagepreview.cpp index a9e4d752ac..0c2bb25e07 100644 --- a/indra/newview/llfloaterimagepreview.cpp +++ b/indra/newview/llfloaterimagepreview.cpp @@ -793,7 +793,7 @@ void LLImagePreviewSculpted::setPreviewTarget(LLImageRaw* imagep, F32 distance)  	if (imagep)  	{ -		mVolume->sculpt(imagep->getWidth(), imagep->getHeight(), imagep->getComponents(), imagep->getData(), 0); +		mVolume->sculpt(imagep->getWidth(), imagep->getHeight(), imagep->getComponents(), imagep->getData(), 0, false);  	}  	const LLVolumeFace &vf = mVolume->getVolumeFace(0); diff --git a/indra/newview/llfloatermemleak.cpp b/indra/newview/llfloatermemleak.cpp index 9edfe1e354..c43526acaf 100644 --- a/indra/newview/llfloatermemleak.cpp +++ b/indra/newview/llfloatermemleak.cpp @@ -42,6 +42,8 @@ U32 LLFloaterMemLeak::sTotalLeaked = 0 ;  S32 LLFloaterMemLeak::sStatus = LLFloaterMemLeak::STOP ;  BOOL LLFloaterMemLeak::sbAllocationFailed = FALSE ; +extern BOOL gSimulateMemLeak; +  LLFloaterMemLeak::LLFloaterMemLeak(const LLSD& key)  	: LLFloater(key)  { @@ -104,6 +106,7 @@ void LLFloaterMemLeak::release()  	sStatus = STOP ;  	sTotalLeaked = 0 ;  	sbAllocationFailed = FALSE ; +	gSimulateMemLeak = FALSE;  }  void LLFloaterMemLeak::stop() @@ -140,8 +143,7 @@ void LLFloaterMemLeak::idle()  	}  	if(!p)  	{ -		sStatus = STOP ; -		sbAllocationFailed = TRUE ; +		stop();  	}  } @@ -181,6 +183,7 @@ void LLFloaterMemLeak::onChangeMaxMemLeaking()  void LLFloaterMemLeak::onClickStart()  {  	sStatus = START ; +	gSimulateMemLeak = TRUE;  }  void LLFloaterMemLeak::onClickStop() diff --git a/indra/newview/llfloaterreporter.cpp b/indra/newview/llfloaterreporter.cpp index c0f5e63623..3a3660bb31 100644 --- a/indra/newview/llfloaterreporter.cpp +++ b/indra/newview/llfloaterreporter.cpp @@ -162,7 +162,8 @@ LLFloaterReporter::LLFloaterReporter(const LLSD& key)  	mPosition(),  	mCopyrightWarningSeen( FALSE ),  	mResourceDatap(new LLResourceData()), -	mAvatarNameCacheConnection() +	mAvatarNameCacheConnection(), +	mSnapshotTimer()  {  } @@ -245,6 +246,12 @@ LLFloaterReporter::~LLFloaterReporter()  void LLFloaterReporter::draw()  {  	LLFloater::draw(); +	static LLCachedControl<F32> screenshot_delay(gSavedSettings, "AbuseReportScreenshotDelay"); +	if (mSnapshotTimer.getStarted() && mSnapshotTimer.getElapsedTimeF32() > screenshot_delay) +	{ +		mSnapshotTimer.stop(); +		takeNewSnapshot(); +	}  }  void LLFloaterReporter::enableControls(BOOL enable) @@ -877,8 +884,7 @@ void LLFloaterReporter::onOpen(const LLSD& key)  {  	childSetEnabled("send_btn", false);  	//Time delay to avoid UI artifacts. MAINT-7067 -	doAfterInterval(boost::bind(&LLFloaterReporter::takeNewSnapshot,this), gSavedSettings.getF32("AbuseReportScreenshotDelay")); - +	mSnapshotTimer.start();  }  void LLFloaterReporter::onLoadScreenshotDialog(const LLSD& notification, const LLSD& response) @@ -950,6 +956,7 @@ void LLFloaterReporter::setPosBox(const LLVector3d &pos)  void LLFloaterReporter::onClose(bool app_quitting)  { +	mSnapshotTimer.stop();  	gSavedPerAccountSettings.setBOOL("PreviousScreenshotForReport", app_quitting);  } diff --git a/indra/newview/llfloaterreporter.h b/indra/newview/llfloaterreporter.h index decc01be98..f5ba63ce7f 100644 --- a/indra/newview/llfloaterreporter.h +++ b/indra/newview/llfloaterreporter.h @@ -149,6 +149,7 @@ private:  	LLPointer<LLImageRaw> mImageRaw;  	LLPointer<LLImageRaw> mPrevImageRaw; +	LLFrameTimer	mSnapshotTimer;  };  #endif diff --git a/indra/newview/llfloaterwebprofile.cpp b/indra/newview/llfloaterwebprofile.cpp index a46f1d8af2..891bb90c0e 100644 --- a/indra/newview/llfloaterwebprofile.cpp +++ b/indra/newview/llfloaterwebprofile.cpp @@ -38,8 +38,10 @@ LLFloaterWebProfile::LLFloaterWebProfile(const Params& key) :  void LLFloaterWebProfile::onOpen(const LLSD& key)  {  	Params p(key); -	p.show_chrome(false). -		window_class("profile"); +	p.show_chrome(true); +	p.window_class("profile"); +	p.allow_address_entry(false); +	p.trusted_content(true);  	LLFloaterWebContent::onOpen(p);  	applyPreferredRect();  } diff --git a/indra/newview/llfloaterworldmap.cpp b/indra/newview/llfloaterworldmap.cpp index 83f268818e..3c3b004d2c 100644 --- a/indra/newview/llfloaterworldmap.cpp +++ b/indra/newview/llfloaterworldmap.cpp @@ -549,10 +549,10 @@ void LLFloaterWorldMap::trackAvatar( const LLUUID& avatar_id, const std::string&  			getChild<LLUICtrl>("teleport_coordinate_z")->setValue(LLSD(200.f));  		}  		// Don't re-request info if we already have it or we won't have it in time to teleport -		if (mTrackedStatus != LLTracker::TRACKING_AVATAR || name != mTrackedAvatarName) +		if (mTrackedStatus != LLTracker::TRACKING_AVATAR || avatar_id != mTrackedAvatarID)  		{  			mTrackedStatus = LLTracker::TRACKING_AVATAR; -			mTrackedAvatarName = name; +			mTrackedAvatarID = avatar_id;  			LLTracker::trackAvatar(avatar_id, name);  		}  	} diff --git a/indra/newview/llfloaterworldmap.h b/indra/newview/llfloaterworldmap.h index c5801c8819..fce945df6c 100644 --- a/indra/newview/llfloaterworldmap.h +++ b/indra/newview/llfloaterworldmap.h @@ -190,7 +190,7 @@ private:  	LLVector3d				mTrackedLocation;  	LLTracker::ETrackingStatus mTrackedStatus;  	std::string				mTrackedSimName; -	std::string				mTrackedAvatarName; +	LLUUID					mTrackedAvatarID;  	LLSLURL  				mSLURL;  	LLCtrlListInterface *	mListFriendCombo; diff --git a/indra/newview/llglsandbox.cpp b/indra/newview/llglsandbox.cpp index 63270e13fe..fc93181ef4 100644 --- a/indra/newview/llglsandbox.cpp +++ b/indra/newview/llglsandbox.cpp @@ -920,7 +920,7 @@ public:  		// unbind  		if (texUnit)  		{ -			texUnit->unbind(LLTexUnit::TT_TEXTURE); +				texUnit->unbind(LLTexUnit::TT_TEXTURE);  		}  		// ensure that we delete these textures regardless of how we exit  		LLImageGL::deleteTextures(source.size(), &source[0]); diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp index 3acfaeb049..67b51f11b3 100644 --- a/indra/newview/llinventorybridge.cpp +++ b/indra/newview/llinventorybridge.cpp @@ -6588,11 +6588,9 @@ void LLWearableBridge::buildContextMenu(LLMenuGL& menu, U32 flags)  		getClipboardEntries(true, items, disabled_items, flags);  		items.push_back(std::string("Wearable And Object Separator")); -  		items.push_back(std::string("Wearable Edit")); -		bool modifiable = !gAgentWearables.isWearableModifiable(item->getUUID()); -		if (((flags & FIRST_SELECTED_ITEM) == 0) || modifiable) +		if (((flags & FIRST_SELECTED_ITEM) == 0) || (item && !gAgentWearables.isWearableModifiable(item->getUUID())))  		{  			disabled_items.push_back(std::string("Wearable Edit"));  		} diff --git a/indra/newview/llmoveview.cpp b/indra/newview/llmoveview.cpp index 4999318973..c03080beb8 100644 --- a/indra/newview/llmoveview.cpp +++ b/indra/newview/llmoveview.cpp @@ -400,12 +400,12 @@ void LLFloaterMove::initMovementMode()  	{  		initMovementMode = MM_FLY;  	} -	setMovementMode(initMovementMode); +	 +	mCurrentMode = initMovementMode; +	bool hide_mode_buttons = (MM_FLY == mCurrentMode) || (isAgentAvatarValid() && gAgentAvatarp->isSitting()); -	if (isAgentAvatarValid()) -	{ -		showModeButtons(!gAgentAvatarp->isSitting()); -	} +	updateButtonsWithMovementMode(mCurrentMode); +	showModeButtons(!hide_mode_buttons);  }  void LLFloaterMove::setModeTooltip(const EMovementMode mode) diff --git a/indra/newview/lloutfitgallery.cpp b/indra/newview/lloutfitgallery.cpp index c38d3ab140..dc3b153da2 100644 --- a/indra/newview/lloutfitgallery.cpp +++ b/indra/newview/lloutfitgallery.cpp @@ -1267,6 +1267,13 @@ LLUUID LLOutfitGallery::getDefaultPhoto()  void LLOutfitGallery::onTexturePickerCommit(LLTextureCtrl::ETexturePickOp op, LLUUID id)  { +    LLUUID selected_outfit_id = getSelectedOutfitUUID(); + +    if (selected_outfit_id.isNull()) +    { +        return; +    } +      LLFloaterTexturePicker* floaterp = (LLFloaterTexturePicker*)mFloaterHandle.get();      if (floaterp && op == LLTextureCtrl::TEXTURE_SELECT) @@ -1316,8 +1323,8 @@ void LLOutfitGallery::onTexturePickerCommit(LLTextureCtrl::ETexturePickOp op, LL              return;          } -        checkRemovePhoto(getSelectedOutfitUUID()); -        linkPhotoToOutfit(image_item_id, getSelectedOutfitUUID()); +        checkRemovePhoto(selected_outfit_id); +        linkPhotoToOutfit(image_item_id, selected_outfit_id);      }  } diff --git a/indra/newview/lloutfitslist.cpp b/indra/newview/lloutfitslist.cpp index e2157f985e..892fa385d7 100644 --- a/indra/newview/lloutfitslist.cpp +++ b/indra/newview/lloutfitslist.cpp @@ -1050,15 +1050,15 @@ bool LLOutfitContextMenu::onEnable(LLSD::String param)  bool LLOutfitContextMenu::onVisible(LLSD::String param)  {      LLUUID outfit_cat_id = mUUIDs.back(); -    bool is_worn = LLAppearanceMgr::instance().getBaseOutfitUUID() == outfit_cat_id;      if ("edit" == param)      { +        bool is_worn = LLAppearanceMgr::instance().getBaseOutfitUUID() == outfit_cat_id;          return is_worn;      }      else if ("wear_replace" == param)      { -        return !is_worn; +        return true;      }      else if ("delete" == param)      { diff --git a/indra/newview/llpanelmarketplaceinboxinventory.cpp b/indra/newview/llpanelmarketplaceinboxinventory.cpp index 2d2ba30e9b..f089faea09 100644 --- a/indra/newview/llpanelmarketplaceinboxinventory.cpp +++ b/indra/newview/llpanelmarketplaceinboxinventory.cpp @@ -139,6 +139,7 @@ void LLInboxFolderViewFolder::draw()  	if (!hasBadgeHolderParent())  	{  		addBadgeToParentHolder(); +		setDrawBadgeAtTop(true);  	}  	setBadgeVisibility(mFresh); diff --git a/indra/newview/llpanelobject.cpp b/indra/newview/llpanelobject.cpp index 0bf4d48421..73d08ec335 100644 --- a/indra/newview/llpanelobject.cpp +++ b/indra/newview/llpanelobject.cpp @@ -342,9 +342,9 @@ void LLPanelObject::getState( )  	}  	// can move or rotate only linked group with move permissions, or sub-object with move and modify perms -	BOOL enable_move	= objectp->permMove() && !objectp->isPermanentEnforced() && ((root_objectp == NULL) || !root_objectp->isPermanentEnforced()) && !objectp->isAttachment() && (objectp->permModify() || !gSavedSettings.getBOOL("EditLinkedParts")); +	BOOL enable_move	= objectp->permMove() && !objectp->isPermanentEnforced() && ((root_objectp == NULL) || !root_objectp->isPermanentEnforced()) && (objectp->permModify() || !gSavedSettings.getBOOL("EditLinkedParts"));  	BOOL enable_scale	= objectp->permMove() && !objectp->isPermanentEnforced() && ((root_objectp == NULL) || !root_objectp->isPermanentEnforced()) && objectp->permModify(); -	BOOL enable_rotate	= objectp->permMove() && !objectp->isPermanentEnforced() && ((root_objectp == NULL) || !root_objectp->isPermanentEnforced()) && ( (objectp->permModify() && !objectp->isAttachment()) || !gSavedSettings.getBOOL("EditLinkedParts")); +	BOOL enable_rotate	= objectp->permMove() && !objectp->isPermanentEnforced() && ((root_objectp == NULL) || !root_objectp->isPermanentEnforced()) && (objectp->permModify() || !gSavedSettings.getBOOL("EditLinkedParts"));  	S32 selected_count = LLSelectMgr::getInstance()->getSelection()->getObjectCount();  	BOOL single_volume = (LLSelectMgr::getInstance()->selectionAllPCode( LL_PCODE_VOLUME )) diff --git a/indra/newview/llpanelobjectinventory.cpp b/indra/newview/llpanelobjectinventory.cpp index b5ee68ba25..c50f3477ad 100644 --- a/indra/newview/llpanelobjectinventory.cpp +++ b/indra/newview/llpanelobjectinventory.cpp @@ -696,6 +696,10 @@ void LLTaskInvFVBridge::buildContextMenu(LLMenuGL& menu, U32 flags)  		items.push_back(std::string("Task Open"));  	}  	items.push_back(std::string("Task Properties")); +	if ((flags & FIRST_SELECTED_ITEM) == 0) +	{ +		disabled_items.push_back(std::string("Task Properties")); +	}  	if(isItemRenameable())  	{  		items.push_back(std::string("Task Rename")); @@ -1017,6 +1021,10 @@ void LLTaskSoundBridge::buildContextMenu(LLMenuGL& menu, U32 flags)  		}  	}  	items.push_back(std::string("Task Properties")); +	if ((flags & FIRST_SELECTED_ITEM) == 0) +	{ +		disabled_items.push_back(std::string("Task Properties")); +	}  	if(isItemRenameable())  	{  		items.push_back(std::string("Task Rename")); @@ -1388,6 +1396,10 @@ void LLTaskMeshBridge::buildContextMenu(LLMenuGL& menu, U32 flags)  		}  	}  	items.push_back(std::string("Task Properties")); +	if ((flags & FIRST_SELECTED_ITEM) == 0) +	{ +		disabled_items.push_back(std::string("Task Properties")); +	}  	if(isItemRenameable())  	{  		items.push_back(std::string("Task Rename")); diff --git a/indra/newview/llpanelwearing.cpp b/indra/newview/llpanelwearing.cpp index 3099a6e039..75c8765c5b 100644 --- a/indra/newview/llpanelwearing.cpp +++ b/indra/newview/llpanelwearing.cpp @@ -65,7 +65,7 @@ public:  		LLUICtrl::EnableCallbackRegistry::ScopedRegistrar enable_registrar;  		registrar.add("Gear.Edit", boost::bind(&edit_outfit)); -		registrar.add("Gear.TakeOff", boost::bind(&LLWearingGearMenu::onTakeOff, this)); +		registrar.add("Gear.TakeOff", boost::bind(&LLPanelWearing::onRemoveItem, mPanelWearing));  		registrar.add("Gear.Copy", boost::bind(&LLPanelWearing::copyToClipboard, mPanelWearing));  		enable_registrar.add("Gear.OnEnable", boost::bind(&LLPanelWearing::isActionEnabled, mPanelWearing, _2)); @@ -79,13 +79,6 @@ public:  private: -	void onTakeOff() -	{ -		uuid_vec_t selected_uuids; -		mPanelWearing->getSelectedItemsUUIDs(selected_uuids); -		LLAppearanceMgr::instance().removeItemsFromAvatar(selected_uuids); -	} -  	LLToggleableMenu*		mMenu;  	LLPanelWearing* 		mPanelWearing;  }; @@ -343,7 +336,14 @@ bool LLPanelWearing::isActionEnabled(const LLSD& userdata)  	if (command_name == "take_off")  	{ -		return hasItemSelected() && canTakeOffSelected(); +		if (mWearablesTab->isExpanded()) +		{ +			return hasItemSelected() && canTakeOffSelected(); +		} +		else +		{ +			return mTempItemsList->hasSelectedItem(); +		}  	}  	return false; @@ -532,6 +532,21 @@ void LLPanelWearing::onRemoveAttachment()  	}  } +void LLPanelWearing::onRemoveItem() +{ +	if (mWearablesTab->isExpanded()) +	{ +		uuid_vec_t selected_uuids; +		getSelectedItemsUUIDs(selected_uuids); +		LLAppearanceMgr::instance().removeItemsFromAvatar(selected_uuids); +	} +	else +	{ +		onRemoveAttachment(); +	} +} + +  void LLPanelWearing::copyToClipboard()  {  	std::string text; diff --git a/indra/newview/llpanelwearing.h b/indra/newview/llpanelwearing.h index c5cb79092a..715404a457 100644 --- a/indra/newview/llpanelwearing.h +++ b/indra/newview/llpanelwearing.h @@ -80,6 +80,7 @@ public:  	void onAccordionTabStateChanged();  	void setAttachmentDetails(LLSD content);  	void requestAttachmentDetails(); +	void onRemoveItem();  	void onEditAttachment();  	void onRemoveAttachment(); diff --git a/indra/newview/llphysicsmotion.cpp b/indra/newview/llphysicsmotion.cpp index 08d734ddac..f48ce680fd 100644 --- a/indra/newview/llphysicsmotion.cpp +++ b/indra/newview/llphysicsmotion.cpp @@ -44,7 +44,9 @@ typedef std::map<std::string, std::string> controller_map_t;  typedef std::map<std::string, F32> default_controller_map_t;  #define MIN_REQUIRED_PIXEL_AREA_AVATAR_PHYSICS_MOTION 0.f -#define TIME_ITERATION_STEP 0.05f +// we use TIME_ITERATION_STEP_MAX in division operation, make sure this is a simple +// value and devision result won't end with repeated/recurring tail like 1.333(3) +#define TIME_ITERATION_STEP_MAX 0.05f // minimal step size will end up as 0.025  inline F64 llsgn(const F64 a)  { @@ -480,7 +482,7 @@ BOOL LLPhysicsMotion::onUpdate(F32 time)          if (!mParamDriver)                  return FALSE; -        if (!mLastTime) +        if (!mLastTime || mLastTime >= time)          {                  mLastTime = time;                  return FALSE; @@ -561,14 +563,10 @@ BOOL LLPhysicsMotion::onUpdate(F32 time)  	// bounce at right (relatively) position.  	// Note: this doesn't look to be optimal, since it provides only "roughly same" behavior, but  	// irregularity at higher fps looks to be insignificant so it works good enough for low fps. -	for (F32 time_iteration = 0; time_iteration <= time_delta; time_iteration += TIME_ITERATION_STEP) +	U32 steps = (U32)(time_delta / TIME_ITERATION_STEP_MAX) + 1; +	F32 time_iteration_step = time_delta / (F32)steps; //minimal step size ends up as 0.025 +	for (U32 i = 0; i < steps; i++)  	{ -		F32 time_iteration_step = TIME_ITERATION_STEP; -		if (time_iteration + TIME_ITERATION_STEP > time_delta) -		{ -			time_iteration_step = time_delta-time_iteration; -		} -		  		// mPositon_local should be in normalized 0,1 range already.  Just making sure...  		const F32 position_current_local = llclamp(mPosition_local,  							   0.0f, diff --git a/indra/newview/llpreviewscript.cpp b/indra/newview/llpreviewscript.cpp index 6ecc4c7fb9..945f3c370c 100644 --- a/indra/newview/llpreviewscript.cpp +++ b/indra/newview/llpreviewscript.cpp @@ -2041,7 +2041,15 @@ void LLLiveLSLEditor::loadScriptText(LLVFS *vfs, const LLUUID &uuid, LLAssetType  	mScriptEd->setScriptText(LLStringExplicit(&buffer[0]), TRUE);  	mScriptEd->makeEditorPristine(); -	mScriptEd->setScriptName(getItem()->getName()); + +	std::string script_name = DEFAULT_SCRIPT_NAME; +	const LLInventoryItem* inv_item = getItem(); + +	if(inv_item) +	{ +		script_name = inv_item->getName(); +	} +	mScriptEd->setScriptName(script_name);  } diff --git a/indra/newview/lltexturecache.cpp b/indra/newview/lltexturecache.cpp index dadf2f9701..2a0d961952 100644 --- a/indra/newview/lltexturecache.cpp +++ b/indra/newview/lltexturecache.cpp @@ -117,7 +117,7 @@ public:  	~LLTextureCacheWorker()  	{  		llassert_always(!haveWork()); -		FREE_MEM(LLImageBase::getPrivatePool(), mReadData); +		ll_aligned_free_16(mReadData);  	}  	// override this interface @@ -237,7 +237,7 @@ bool LLTextureCacheLocalFileWorker::doRead()  // 						<< " Bytes: " << mDataSize << " Offset: " << mOffset  // 						<< " / " << mDataSize << LL_ENDL;  				mDataSize = 0; // failed -				FREE_MEM(LLImageBase::getPrivatePool(), mReadData); +				ll_aligned_free_16(mReadData);  				mReadData = NULL;  			}  			return true; @@ -252,7 +252,7 @@ bool LLTextureCacheLocalFileWorker::doRead()  	{  		mDataSize = local_size;  	} -	mReadData = (U8*)ALLOCATE_MEM(LLImageBase::getPrivatePool(), mDataSize); +	mReadData = (U8*)ll_aligned_malloc_16(mDataSize);  	S32 bytes_read = LLAPRFile::readEx(mFileName, mReadData, mOffset, mDataSize, mCache->getLocalAPRFilePool());	 @@ -262,7 +262,7 @@ bool LLTextureCacheLocalFileWorker::doRead()  // 				<< " Bytes: " << mDataSize << " Offset: " << mOffset  // 				<< " / " << mDataSize << LL_ENDL;  		mDataSize = 0; -		FREE_MEM(LLImageBase::getPrivatePool(), mReadData); +		ll_aligned_free_16(mReadData);  		mReadData = NULL;  	}  	else @@ -386,7 +386,7 @@ bool LLTextureCacheRemoteWorker::doRead()  			mDataSize = local_size;  		}  		// Allocate read buffer -		mReadData = (U8*)ALLOCATE_MEM(LLImageBase::getPrivatePool(), mDataSize); +		mReadData = (U8*)ll_aligned_malloc_16(mDataSize);  		if (mReadData)  		{ @@ -402,7 +402,7 @@ bool LLTextureCacheRemoteWorker::doRead()   						<< " Bytes: " << mDataSize << " Offset: " << mOffset   					<< " / " << mDataSize << LL_ENDL;  				mDataSize = 0; -				FREE_MEM(LLImageBase::getPrivatePool(), mReadData); +				ll_aligned_free_16(mReadData);  				mReadData = NULL;  			}  			else @@ -451,7 +451,7 @@ bool LLTextureCacheRemoteWorker::doRead()  		S32 size = TEXTURE_CACHE_ENTRY_SIZE - mOffset;  		size = llmin(size, mDataSize);  		// Allocate the read buffer -		mReadData = (U8*)ALLOCATE_MEM(LLImageBase::getPrivatePool(), size); +		mReadData = (U8*)ll_aligned_malloc_16(size);  		if (mReadData)  		{  			S32 bytes_read = LLAPRFile::readEx(mCache->mHeaderDataFileName,  @@ -461,7 +461,7 @@ bool LLTextureCacheRemoteWorker::doRead()  				LL_WARNS() << "LLTextureCacheWorker: "  << mID  						<< " incorrect number of bytes read from header: " << bytes_read  						<< " / " << size << LL_ENDL; -				FREE_MEM(LLImageBase::getPrivatePool(), mReadData); +				ll_aligned_free_16(mReadData);  				mReadData = NULL;  				mDataSize = -1; // failed  				done = true; @@ -500,7 +500,7 @@ bool LLTextureCacheRemoteWorker::doRead()  			S32 data_offset, file_size, file_offset;  			// Reserve the whole data buffer first -			U8* data = (U8*)ALLOCATE_MEM(LLImageBase::getPrivatePool(), mDataSize); +			U8* data = (U8*)ll_aligned_malloc_16(mDataSize);  			if (data)  			{  				// Set the data file pointers taking the read offset into account. 2 cases: @@ -514,7 +514,7 @@ bool LLTextureCacheRemoteWorker::doRead()  					// Copy the raw data we've been holding from the header cache into the new sized buffer  					llassert_always(mReadData);  					memcpy(data, mReadData, data_offset); -					FREE_MEM(LLImageBase::getPrivatePool(), mReadData); +					ll_aligned_free_16(mReadData);  					mReadData = NULL;  				}  				else @@ -540,7 +540,7 @@ bool LLTextureCacheRemoteWorker::doRead()  					LL_WARNS() << "LLTextureCacheWorker: "  << mID  							<< " incorrect number of bytes read from body: " << bytes_read  							<< " / " << file_size << LL_ENDL; -					FREE_MEM(LLImageBase::getPrivatePool(), mReadData); +					ll_aligned_free_16(mReadData);  					mReadData = NULL;  					mDataSize = -1; // failed  					done = true; @@ -550,7 +550,7 @@ bool LLTextureCacheRemoteWorker::doRead()  			{  				LL_WARNS() << "LLTextureCacheWorker: "  << mID  					<< " failed to allocate memory for reading: " << mDataSize << LL_ENDL; -				FREE_MEM(LLImageBase::getPrivatePool(), mReadData); +				ll_aligned_free_16(mReadData);  				mReadData = NULL;  				mDataSize = -1; // failed  				done = true; @@ -673,11 +673,11 @@ bool LLTextureCacheRemoteWorker::doWrite()  			{  				// We need to write a full record in the header cache so, if the amount of data is smaller  				// than a record, we need to transfer the data to a buffer padded with 0 and write that -				U8* padBuffer = (U8*)ALLOCATE_MEM(LLImageBase::getPrivatePool(), TEXTURE_CACHE_ENTRY_SIZE); +				U8* padBuffer = (U8*)ll_aligned_malloc_16(TEXTURE_CACHE_ENTRY_SIZE);  				memset(padBuffer, 0, TEXTURE_CACHE_ENTRY_SIZE);		// Init with zeros  				memcpy(padBuffer, mWriteData, mDataSize);			// Copy the write buffer  				bytes_written = LLAPRFile::writeEx(mCache->mHeaderDataFileName, padBuffer, offset, size, mCache->getLocalAPRFilePool()); -				FREE_MEM(LLImageBase::getPrivatePool(), padBuffer); +				ll_aligned_free_16(padBuffer);  			}  			else  			{ @@ -783,7 +783,7 @@ void LLTextureCacheWorker::finishWork(S32 param, bool completed)  			}  			else  			{ -				FREE_MEM(LLImageBase::getPrivatePool(), mReadData); +				ll_aligned_free_16(mReadData);  				mReadData = NULL;  			}  		} @@ -845,7 +845,7 @@ LLTextureCache::~LLTextureCache()  	writeUpdatedEntries() ;  	delete mFastCachep;  	delete mFastCachePoolp; -	FREE_MEM(LLImageBase::getPrivatePool(), mFastCachePadBuffer); +	ll_aligned_free_16(mFastCachePadBuffer);  }  ////////////////////////////////////////////////////////////////////////////// @@ -1983,10 +1983,10 @@ LLPointer<LLImageRaw> LLTextureCache::readFromFastCache(const LLUUID& id, S32& d  		}  		discardlevel = head[3]; -		data =  (U8*)ALLOCATE_MEM(LLImageBase::getPrivatePool(), image_size); +		data = (U8*)ll_aligned_malloc_16(image_size);  		if(mFastCachep->read(data, image_size) != image_size)  		{ -			FREE_MEM(LLImageBase::getPrivatePool(), data); +			ll_aligned_free_16(data);  			closeFastCache();  			return NULL;  		} @@ -2078,7 +2078,7 @@ void LLTextureCache::openFastCache(bool first_time)  		{  			if(!mFastCachePadBuffer)  			{ -				mFastCachePadBuffer = (U8*)ALLOCATE_MEM(LLImageBase::getPrivatePool(), TEXTURE_FAST_CACHE_ENTRY_SIZE); +				mFastCachePadBuffer = (U8*)ll_aligned_malloc_16(TEXTURE_FAST_CACHE_ENTRY_SIZE);  			}  			mFastCachePoolp = new LLVolatileAPRPool();  			if (LLAPRFile::isExist(mFastCacheFileName, mFastCachePoolp)) diff --git a/indra/newview/lltexturefetch.cpp b/indra/newview/lltexturefetch.cpp index 1f7796e6d0..6fd90e4935 100644 --- a/indra/newview/lltexturefetch.cpp +++ b/indra/newview/lltexturefetch.cpp @@ -1761,7 +1761,7 @@ bool LLTextureFetchWorker::doWork(S32 param)  				mRequestedOffset += src_offset;  			} -			U8 * buffer = (U8 *)ALLOCATE_MEM(LLImageBase::getPrivatePool(), total_size); +			U8 * buffer = (U8 *)ll_aligned_malloc_16(total_size);  			if (!buffer)  			{  				// abort. If we have no space for packet, we have not enough space to decode image @@ -2266,7 +2266,7 @@ bool LLTextureFetchWorker::processSimulatorPackets()  			if (buffer_size > cur_size)  			{  				/// We have new data -				U8* buffer = (U8*)ALLOCATE_MEM(LLImageBase::getPrivatePool(), buffer_size); +				U8* buffer = (U8*)ll_aligned_malloc_16(buffer_size);  				S32 offset = 0;  				if (cur_size > 0 && mFirstPacket > 0)  				{ @@ -5059,7 +5059,7 @@ void LLTextureFetchDebugger::callbackHTTP(FetchEntry & fetch, LLCore::HttpRespon  		//LL_INFOS(LOG_TXT) << "Fetch Debugger : got results for " << fetch.mID << ", data_size = " << data_size << ", received = " << fetch.mCurlReceivedSize << ", requested = " << fetch.mRequestedSize << ", partial = " << partial << LL_ENDL;  		if ((fetch.mCurlReceivedSize >= fetch.mRequestedSize) || !partial || (fetch.mRequestedSize == 600))  		{ -			U8* d_buffer = (U8*)ALLOCATE_MEM(LLImageBase::getPrivatePool(), data_size); +			U8* d_buffer = (U8*)ll_aligned_malloc_16(data_size);  			if (ba)  			{  				ba->read(0, d_buffer, data_size); diff --git a/indra/newview/lltwitterconnect.cpp b/indra/newview/lltwitterconnect.cpp index 9b7c13b57d..5d598aaebe 100644 --- a/indra/newview/lltwitterconnect.cpp +++ b/indra/newview/lltwitterconnect.cpp @@ -380,13 +380,10 @@ LLTwitterConnect::LLTwitterConnect()  void LLTwitterConnect::openTwitterWeb(std::string url)  { -	// Open the URL in an internal browser window without navigation UI  	LLFloaterWebContent::Params p;      p.url(url);      p.show_chrome(true); -    p.allow_address_entry(false);      p.allow_back_forward_navigation(false); -    p.trusted_content(true);      p.clean_browser(true);  	LLFloater *floater = LLFloaterReg::showInstance("twitter_web", p);  	//the internal web browser has a bug that prevents it from gaining focus unless a mouse event occurs first (it seems). diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index 5bbf5650ad..e973363e0f 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -8001,7 +8001,7 @@ void handle_report_bug(const LLSD& param)  	LLUIString url(param.asString());  	LLStringUtil::format_map_t replace; -	replace["[ENVIRONMENT]"] = LLURI::escape(LLAppViewer::instance()->getShortViewerInfoString()); +	replace["[ENVIRONMENT]"] = LLURI::escape(LLAppViewer::instance()->getViewerInfoString(true));  	LLSLURL location_url;  	LLAgentUI::buildSLURL(location_url);  	replace["[LOCATION]"] = LLURI::escape(location_url.getSLURLString()); diff --git a/indra/newview/llviewertextureanim.cpp b/indra/newview/llviewertextureanim.cpp index 9af92d7377..9603811066 100644 --- a/indra/newview/llviewertextureanim.cpp +++ b/indra/newview/llviewertextureanim.cpp @@ -146,6 +146,8 @@ S32 LLViewerTextureAnim::animateTextures(F32 &off_s, F32 &off_t,  	if (!(mMode & SMOOTH))  	{  		frame_counter = (F32)llfloor(frame_counter + 0.01f); +		// account for 0.01, we shouldn't step over full length +		frame_counter = llmin(full_length - 1.f, frame_counter);  	}  	if (mMode & PING_PONG) diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index 74deaffe16..c057954606 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -740,16 +740,6 @@ public:  			ypos += y_inc;  		} -		if (gSavedSettings.getBOOL("DebugShowPrivateMem")) -		{ -			LLPrivateMemoryPoolManager::getInstance()->updateStatistics() ; -			addText(xpos, ypos, llformat("Total Reserved(KB): %d", LLPrivateMemoryPoolManager::getInstance()->mTotalReservedSize / 1024)); -			ypos += y_inc; - -			addText(xpos, ypos, llformat("Total Allocated(KB): %d", LLPrivateMemoryPoolManager::getInstance()->mTotalAllocatedSize / 1024)); -			ypos += y_inc; -		} -  		// only display these messages if we are actually rendering beacons at this moment  		if (LLPipeline::getRenderBeacons() && LLFloaterReg::instanceVisible("beacons"))  		{ diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index eae8f2cc56..652a447545 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -5304,6 +5304,10 @@ LLUUID LLVOAvatar::remapMotionID(const LLUUID& id)  			if (use_new_walk_run)  				result = ANIM_AGENT_FEMALE_RUN_NEW;  		} +		else if (id == ANIM_AGENT_SIT) +		{ +			result = ANIM_AGENT_SIT_FEMALE; +		}  	}  	else  	{ diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index 7b4d8ef329..d93cae992b 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -1200,7 +1200,7 @@ void LLVOVolume::sculpt()  				mSculptTexture->updateBindStatsForTester() ;  			}  		} -		getVolume()->sculpt(sculpt_width, sculpt_height, sculpt_components, sculpt_data, discard_level); +		getVolume()->sculpt(sculpt_width, sculpt_height, sculpt_components, sculpt_data, discard_level, mSculptTexture->isMissingAsset());  		//notify rebuild any other VOVolumes that reference this sculpty volume  		for (S32 i = 0; i < mSculptTexture->getNumVolumes(); ++i) @@ -2525,7 +2525,9 @@ void LLVOVolume::mediaNavigateBounceBack(U8 texture_index)  			LL_WARNS("MediaOnAPrim") << "FAILED to bounce back URL \"" << url << "\" -- unloading impl" << LL_ENDL;  			impl->setMediaFailed(true);  		} -		else { +		// Make sure we are not bouncing to url we came from +		else if (impl->getCurrentMediaURL() != url)  +		{  			// Okay, navigate now              LL_INFOS("MediaOnAPrim") << "bouncing back to URL: " << url << LL_ENDL;              impl->navigateTo(url, "", false, true); diff --git a/indra/newview/llwearableitemslist.cpp b/indra/newview/llwearableitemslist.cpp index 5fb3d62445..ee2270c323 100644 --- a/indra/newview/llwearableitemslist.cpp +++ b/indra/newview/llwearableitemslist.cpp @@ -645,7 +645,7 @@ LLWearableItemsList::LLWearableItemsList(const LLWearableItemsList::Params& p)  		setRightMouseDownCallback(boost::bind(&LLWearableItemsList::onRightClick, this, _2, _3));  	}  	mWornIndicationEnabled = p.worn_indication_enabled; -	setNoItemsCommentText(LLTrans::getString("NoneFound")); +	setNoItemsCommentText(LLTrans::getString("LoadingData"));  }  // virtual diff --git a/indra/newview/skins/default/xui/da/floater_tos.xml b/indra/newview/skins/default/xui/da/floater_tos.xml index af9ee0bd06..bd8ecb92e9 100644 --- a/indra/newview/skins/default/xui/da/floater_tos.xml +++ b/indra/newview/skins/default/xui/da/floater_tos.xml @@ -8,7 +8,9 @@  	</floater.string>  	<button label="Fortsæt" label_selected="Fortsæt" name="Continue"/>  	<button label="Annullér" label_selected="Annullér" name="Cancel"/> -	<check_box label="Jeg er enig med "Terms of Service and Privacy Policy"" name="agree_chk"/> +  <text name="agree_list"> +	  Jeg er enig med "Terms of Service and Privacy Policy" +  </text>  	<text name="tos_heading">  		Læs venligst følgende "Terms of Service and Privacy Policy" grundigt. For at fortsætte med at logge på [SECOND_LIFE], skal du acceptere aftale.  	</text> diff --git a/indra/newview/skins/default/xui/de/floater_tos.xml b/indra/newview/skins/default/xui/de/floater_tos.xml index 636c2629da..47551d2a82 100644 --- a/indra/newview/skins/default/xui/de/floater_tos.xml +++ b/indra/newview/skins/default/xui/de/floater_tos.xml @@ -12,10 +12,9 @@  	<text name="external_tos_required">  		Sie müssen sich unter https://my.secondlife.com anmelden und die Servicebedingungen akzeptieren, bevor Sie fortfahren können. Vielen Dank!  	</text> -	<check_box label="Ich habe die" name="agree_chk"/>  	<text name="agree_list"> -		Allgemeinen Geschäftsbedingungen, die Datenschutzrichtlinie sowie die Servicebedingungen inklusive der Anforderungen zur Streitschlichtung gelesen und akzeptiere diese. -	</text> -	<button label="Weiter" label_selected="Weiter" name="Continue"/> +    Ich habe die Allgemeinen Geschäftsbedingungen, die Datenschutzrichtlinie sowie die Servicebedingungen inklusive der Anforderungen zur Streitschlichtung gelesen und akzeptiere diese. +  </text> +	<button label="Weiter" label_selected="Weiter" name="Continue" top_delta="45"/>  	<button label="Abbrechen" label_selected="Abbrechen" name="Cancel"/>  </floater> diff --git a/indra/newview/skins/default/xui/en/floater_snapshot.xml b/indra/newview/skins/default/xui/en/floater_snapshot.xml index 76adaad57c..e50747cb5f 100644 --- a/indra/newview/skins/default/xui/en/floater_snapshot.xml +++ b/indra/newview/skins/default/xui/en/floater_snapshot.xml @@ -127,7 +127,7 @@  	   top_delta="0"         width="31" />  	<panel -     height="154" +     height="159"       layout="topleft"  	 follows="top|left"       left="0" @@ -250,7 +250,7 @@       left="0"       name="panel_container"       default_panel_name="panel_snapshot_options" -     top_pad="10" +     top_pad="5"       width="215">        <panel         class="llpanelsnapshotoptions" diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml index 92511167c0..fa15fb0657 100644 --- a/indra/newview/skins/default/xui/en/menu_viewer.xml +++ b/indra/newview/skins/default/xui/en/menu_viewer.xml @@ -2373,16 +2373,6 @@                 function="ToggleControl"                 parameter="DebugShowMemory" />              </menu_item_check> -	     <menu_item_check -               label="Show Private Mem Info" -               name="Show Private Mem Info"> -              <menu_item_check.on_check -               function="CheckControl" -               parameter="DebugShowPrivateMem" /> -              <menu_item_check.on_click -               function="ToggleControl" -               parameter="DebugShowPrivateMem" /> -            </menu_item_check>              <menu_item_separator/> diff --git a/indra/newview/skins/default/xui/es/floater_tos.xml b/indra/newview/skins/default/xui/es/floater_tos.xml index 412e0501a0..8d83eb5b24 100644 --- a/indra/newview/skins/default/xui/es/floater_tos.xml +++ b/indra/newview/skins/default/xui/es/floater_tos.xml @@ -12,10 +12,9 @@  	<text name="external_tos_required">  		Para poder proseguir, debes iniciar sesión en https://my.secondlife.com y aceptar las Condiciones del servicio. Gracias.  	</text> -	<check_box label="He leído y acepto" name="agree_chk"/>  	<text name="agree_list"> -		los Términos y Condiciones, la Política de privacidad y las Condiciones del servicio de Second Life, incluyendo los requerimientos para resolver disputas. -	</text> +    He leído y acepto los Términos y Condiciones, la Política de privacidad y las Condiciones del servicio de Second Life, incluyendo los requerimientos para resolver disputas. +  </text>  	<button label="Continuar" label_selected="Continuar" name="Continue"/>  	<button label="Cancelar" label_selected="Cancelar" name="Cancel"/>  </floater> diff --git a/indra/newview/skins/default/xui/fr/floater_tos.xml b/indra/newview/skins/default/xui/fr/floater_tos.xml index 124a8ffee2..4e359e6482 100644 --- a/indra/newview/skins/default/xui/fr/floater_tos.xml +++ b/indra/newview/skins/default/xui/fr/floater_tos.xml @@ -12,9 +12,8 @@  	<text name="external_tos_required">  		Vous devez vous rendre sur https://my.secondlife.com et vous connecter pour accepter les Conditions d’utilisation avant de pouvoir continuer. Merci !  	</text> -	<check_box label="J'ai lu et j'accepte" name="agree_chk"/>  	<text name="agree_list"> -		les termes et conditions; la Politique de confidentialité et les Conditions d'utilisation de Second Life, y compris ls exigences de résolution des différends. +    J'ai lu et j'accepte les termes et conditions; la Politique de confidentialité et les Conditions d'utilisation de Second Life, y compris ls exigences de résolution des différends.  	</text>  	<button label="Continuer" label_selected="Continuer" name="Continue"/>  	<button label="Annuler" label_selected="Annuler" name="Cancel"/> diff --git a/indra/newview/skins/default/xui/it/floater_tos.xml b/indra/newview/skins/default/xui/it/floater_tos.xml index 8fa74e0fca..0016df1882 100644 --- a/indra/newview/skins/default/xui/it/floater_tos.xml +++ b/indra/newview/skins/default/xui/it/floater_tos.xml @@ -12,10 +12,9 @@  	<text name="external_tos_required">  		Per continuare, visita https://my.secondlife.com e accedi per accettare i Termini del servizio. Grazie.  	</text> -	<check_box label="Ho letto e sono d’accordo con" name="agree_chk"/>  	<text name="agree_list"> -		i Termini e le Condizioni di Second Life, le clausole di riservatezza, i Termini del Servizio, compresi i requisiti per la risoluzione delle dispute. -	</text> +    Ho letto e sono d’accordo con i Termini e le Condizioni di Second Life, le clausole di riservatezza, i Termini del Servizio, compresi i requisiti per la risoluzione delle dispute. +  </text>  	<button label="Continua" label_selected="Continua" name="Continue"/>  	<button label="Annulla" label_selected="Annulla" name="Cancel"/>  </floater> diff --git a/indra/newview/skins/default/xui/ja/floater_tos.xml b/indra/newview/skins/default/xui/ja/floater_tos.xml index 28e51e6d63..8045a1f1f7 100644 --- a/indra/newview/skins/default/xui/ja/floater_tos.xml +++ b/indra/newview/skins/default/xui/ja/floater_tos.xml @@ -12,10 +12,9 @@  	<text name="external_tos_required">  		操作を続けるに、https://my.secondlife.com に移動し、利用規約に同意する必要があります。  	</text> -	<check_box label="私は以下の内容を読み、同意します。" name="agree_chk"/>  	<text name="agree_list"> -		Second Life の利用規約、プライバシーポリシー、およびサービス規約(紛争解決のための必要条件を含む)。 -	</text> +    私は以下の内容を読み、同意します。Second Life の利用規約、プライバシーポリシー、およびサービス規約(紛争解決のための必要条件を含む)。 +  </text>  	<button label="続行" label_selected="続行" name="Continue"/>  	<button label="取り消し" label_selected="取り消し" name="Cancel"/>  </floater> diff --git a/indra/newview/skins/default/xui/pl/floater_tos.xml b/indra/newview/skins/default/xui/pl/floater_tos.xml index c3bc528d17..789c65a16e 100644 --- a/indra/newview/skins/default/xui/pl/floater_tos.xml +++ b/indra/newview/skins/default/xui/pl/floater_tos.xml @@ -5,7 +5,9 @@  	</floater.string>  	<button label="Kontynuuj" label_selected="Kontynuuj" name="Continue" />  	<button label="Anuluj" label_selected="Anuluj" name="Cancel" /> -	<check_box label="Zgadzam się na Warunki korzystania z Usług (Terms of Service) i Politykę Prywatności (Privacy Policy)" name="agree_chk" /> +  <text name="agree_list"> +    Zgadzam się na Warunki korzystania z Usług (Terms of Service) i Politykę Prywatności (Privacy Policy) +  </text>    	<text name="tos_heading">  		Proszę dokładnie przeczytać Warunki korzystania z Usług (Terms of Service) i Politykę Prywatności (Privacy Policy). Musisz je zaakceptować, aby kontynuować logowanie.  	</text> diff --git a/indra/newview/skins/default/xui/pt/floater_tos.xml b/indra/newview/skins/default/xui/pt/floater_tos.xml index f8b2bc4aa7..09a90bc76c 100644 --- a/indra/newview/skins/default/xui/pt/floater_tos.xml +++ b/indra/newview/skins/default/xui/pt/floater_tos.xml @@ -12,10 +12,9 @@  	<text name="external_tos_required">  		Antes de continuar, você precisará visitar https://my.secondlife.com e fazer login para aceitar os Termos de Serviço. Obrigado!  	</text> -	<check_box label="Li e concordo" name="agree_chk"/>  	<text name="agree_list"> -		os Termos e condições, Política de privacidade e Termos de serviço do Second Life, incluindo as exigências para resolver disputas. -	</text> +    Li e concordo os Termos e condições, Política de privacidade e Termos de serviço do Second Life, incluindo as exigências para resolver disputas. +  </text>  	<button label="Continuar" label_selected="Continuar" name="Continue"/>  	<button label="Cancelar" label_selected="Cancelar" name="Cancel"/>  </floater> diff --git a/indra/newview/skins/default/xui/ru/floater_tos.xml b/indra/newview/skins/default/xui/ru/floater_tos.xml index 4c53fc9038..4cfdf5af70 100644 --- a/indra/newview/skins/default/xui/ru/floater_tos.xml +++ b/indra/newview/skins/default/xui/ru/floater_tos.xml @@ -12,10 +12,9 @@  	<text name="external_tos_required">  		Для продолжения перейдите на сайт https://my.secondlife.com, войдите и примите Условия обслуживания. Спасибо!  	</text> -	<check_box label="Я прочитал и согласен с" name="agree_chk"/>  	<text name="agree_list"> -		условия и положения по конфиденциальности Пользовательского соглашения, включая требования по разрешению разногласий. -	</text> +    Я прочитал и согласен с условиями и положениями по конфиденциальности Пользовательского соглашения, включая требования по разрешению разногласий. +  </text>  	<button label="Продолжить" label_selected="Продолжить" name="Continue"/>  	<button label="Отмена" label_selected="Отмена" name="Cancel"/>  </floater> diff --git a/indra/newview/skins/default/xui/tr/floater_tos.xml b/indra/newview/skins/default/xui/tr/floater_tos.xml index 249a0f691e..9c0249526a 100644 --- a/indra/newview/skins/default/xui/tr/floater_tos.xml +++ b/indra/newview/skins/default/xui/tr/floater_tos.xml @@ -12,9 +12,8 @@  	<text name="external_tos_required">  		Devam edebilmeniz için https://my.secondlife.com adresine gidip oturum açarak Hizmet Sözleşmesi'ni kabul etmeniz gerekir. Teşekkürler!  	</text> -	<check_box label="Uyuşmazlıkların çözümü gerekliliklerini içeren Second Life Şartlar ve Koşulları, Gizlilik Politikası'nı ve Hizmet Koşulları'nı" name="agree_chk"/>  	<text name="agree_list"> -		okudum ve kabul ediyorum. +		Uyuşmazlıkların çözümü gerekliliklerini içeren Second Life Şartlar ve Koşulları, Gizlilik Politikası'nı ve Hizmet Koşulları'nı okudum ve kabul ediyorum.  	</text>  	<button label="Devam Et" label_selected="Devam Et" name="Continue"/>  	<button label="İptal" label_selected="İptal" name="Cancel"/> diff --git a/indra/newview/skins/default/xui/zh/floater_tos.xml b/indra/newview/skins/default/xui/zh/floater_tos.xml index 4e028c849f..cde6445e34 100644 --- a/indra/newview/skins/default/xui/zh/floater_tos.xml +++ b/indra/newview/skins/default/xui/zh/floater_tos.xml @@ -12,10 +12,9 @@  	<text name="external_tos_required">  		你需先登入 https://my.secondlife.com 同意服務條款,才可繼續。 謝謝你!  	</text> -	<check_box label="我已閱畢並同意" name="agree_chk"/>  	<text name="agree_list"> -		Second Life使用條款、隱私政策、服務條款,包括解決爭端的規定途徑。 -	</text> +    我已閱畢並同意 Second Life使用條款、隱私政策、服務條款,包括解決爭端的規定途徑。 +  </text>  	<button label="繼續" label_selected="繼續" name="Continue"/>  	<button label="取消" label_selected="取消" name="Cancel"/>  </floater> | 
