merge changes for DRTVWR-149
commit
7637acf76e
|
|
@ -1,5 +1,6 @@
|
|||
syntax: glob
|
||||
|
||||
|
||||
# WinMerge temp files
|
||||
*.bak
|
||||
# Compiled python bytecode
|
||||
|
|
|
|||
31
BuildParams
31
BuildParams
|
|
@ -181,4 +181,35 @@ simon_viewer-dev-private.email_status_this_is_os = false
|
|||
vir-project-1.viewer_channel = "Second Life Release"
|
||||
vir-project-1.login_channel = "Second Life Release"
|
||||
|
||||
# ========================================
|
||||
# THX-1138 / Runway projects
|
||||
# ========================================
|
||||
viewer-thx1138-runway-shared.viewer_channel = "Project Viewer - THX-1138 Runway"
|
||||
viewer-thx1138-runway-shared.login_channel = "Project Viewer - THX-1138 Runway"
|
||||
viewer-thx1138-runway-shared.viewer_grid = uma
|
||||
viewer-thx1138-runway-shared.build_debug_release_separately = true
|
||||
viewer-thx1138-runway-shared.build_CYGWIN_Debug = false
|
||||
viewer-thx1138-runway-shared.build_viewer_update_version_manager = false
|
||||
|
||||
viewer-thx1138.viewer_channel = "Project Viewer - THX-1138"
|
||||
viewer-thx1138.login_channel = "Project Viewer - THX-1138"
|
||||
viewer-thx1138.viewer_grid = uma
|
||||
viewer-thx1138.build_debug_release_separately = true
|
||||
viewer-thx1138.build_CYGWIN_Debug = false
|
||||
viewer-thx1138.build_viewer_update_version_manager = false
|
||||
|
||||
runway-merge.viewer_channel = "Project Viewer - Runway Merge"
|
||||
runway-merge.login_channel = "Project Viewer - Runway Merge"
|
||||
runway-merge.viewer_grid = agni
|
||||
runway-merge.build_debug_release_separately = true
|
||||
runway-merge.build_CYGWIN_Debug = false
|
||||
runway-merge.build_viewer_update_version_manager = false
|
||||
|
||||
runway.viewer_channel = "Project Viewer - Runway"
|
||||
runway.login_channel = "Project Viewer - Runway"
|
||||
runway.viewer_grid = agni
|
||||
runway.build_debug_release_separately = true
|
||||
runway.build_CYGWIN_Debug = false
|
||||
runway.build_viewer_update_version_manager = false
|
||||
|
||||
# eof
|
||||
|
|
|
|||
|
|
@ -54,6 +54,11 @@ static const char USAGE[] = "\n"
|
|||
" -o, --output <file1 .. file2> OR <type>\n"
|
||||
" List of image files to create (assumes same order as for input files)\n"
|
||||
" OR 3 letters file type extension to convert each input file into.\n"
|
||||
" -load, --load_size <n>\n"
|
||||
" Portion of the input file to load, in bytes."
|
||||
" If (load == 0), it will load the whole file."
|
||||
" If (load == -1), it will load the size relevant to reach the requested discard level (see -d)."
|
||||
" Only valid for j2c images. Default is 0 (load whole file).\n"
|
||||
" -r, --region <x0, y0, x1, y1>\n"
|
||||
" Crop region applied to the input files in pixels.\n"
|
||||
" Only used for j2c images. Default is no region cropping.\n"
|
||||
|
|
@ -104,22 +109,52 @@ void output_image_stats(LLPointer<LLImageFormatted> image, const std::string &fi
|
|||
// Print out some statistical data on the image
|
||||
std::cout << "Image stats for : " << filename << ", extension : " << image->getExtension() << std::endl;
|
||||
|
||||
std::cout << " with : " << (int)(image->getWidth()) << ", height : " << (int)(image->getHeight()) << std::endl;
|
||||
std::cout << " comp : " << (int)(image->getComponents()) << ", levels : " << (int)(image->getDiscardLevel()) << std::endl;
|
||||
std::cout << " head : " << (int)(image->calcHeaderSize()) << ", data : " << (int)(image->getDataSize()) << std::endl;
|
||||
std::cout << " with : " << (int)(image->getWidth()) << ", height : " << (int)(image->getHeight()) << std::endl;
|
||||
std::cout << " comp : " << (int)(image->getComponents()) << ", levels : " << (int)(image->getLevels()) << std::endl;
|
||||
std::cout << " head : " << (int)(image->calcHeaderSize()) << ", data : " << (int)(image->getDataSize()) << std::endl;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Load an image from file and return a raw (decompressed) instance of its data
|
||||
LLPointer<LLImageRaw> load_image(const std::string &src_filename, int discard_level, int* region, bool output_stats)
|
||||
LLPointer<LLImageRaw> load_image(const std::string &src_filename, int discard_level, int* region, int load_size, bool output_stats)
|
||||
{
|
||||
LLPointer<LLImageFormatted> image = create_image(src_filename);
|
||||
|
||||
// This just loads the image file stream into a buffer. No decoding done.
|
||||
if (!image->load(src_filename))
|
||||
// We support partial loading only for j2c images
|
||||
if (image->getCodec() == IMG_CODEC_J2C)
|
||||
{
|
||||
return NULL;
|
||||
// Load the header
|
||||
if (!image->load(src_filename, 600))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
S32 h = ((LLImageJ2C*)(image.get()))->calcHeaderSize();
|
||||
S32 d = (load_size > 0 ? ((LLImageJ2C*)(image.get()))->calcDiscardLevelBytes(load_size) : 0);
|
||||
S8 r = ((LLImageJ2C*)(image.get()))->getRawDiscardLevel();
|
||||
std::cout << "Merov debug : header = " << h << ", load_size = " << load_size << ", discard level = " << d << ", raw discard level = " << r << std::endl;
|
||||
for (d = 0; d < MAX_DISCARD_LEVEL; d++)
|
||||
{
|
||||
S32 data_size = ((LLImageJ2C*)(image.get()))->calcDataSize(d);
|
||||
std::cout << "Merov debug : discard_level = " << d << ", data_size = " << data_size << std::endl;
|
||||
}
|
||||
if (load_size < 0)
|
||||
{
|
||||
load_size = (discard_level != -1 ? ((LLImageJ2C*)(image.get()))->calcDataSize(discard_level) : 0);
|
||||
}
|
||||
// Load the requested byte range
|
||||
if (!image->load(src_filename, load_size))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// This just loads the image file stream into a buffer. No decoding done.
|
||||
if (!image->load(src_filename))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if( (image->getComponents() != 3) && (image->getComponents() != 4) )
|
||||
|
|
@ -310,6 +345,7 @@ int main(int argc, char** argv)
|
|||
bool image_stats = false;
|
||||
int* region = NULL;
|
||||
int discard_level = -1;
|
||||
int load_size = 0;
|
||||
int precincts_size = -1;
|
||||
int blocks_size = -1;
|
||||
int levels = 0;
|
||||
|
|
@ -396,6 +432,22 @@ int main(int argc, char** argv)
|
|||
discard_level = llclamp(discard_level,0,5);
|
||||
}
|
||||
}
|
||||
else if (!strcmp(argv[arg], "--load_size") || !strcmp(argv[arg], "-load"))
|
||||
{
|
||||
std::string value_str;
|
||||
if ((arg + 1) < argc)
|
||||
{
|
||||
value_str = argv[arg+1];
|
||||
}
|
||||
if (((arg + 1) >= argc) || (value_str[0] == '-'))
|
||||
{
|
||||
std::cout << "No valid --load_size argument given, load_size ignored" << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
load_size = atoi(value_str.c_str());
|
||||
}
|
||||
}
|
||||
else if (!strcmp(argv[arg], "--precincts") || !strcmp(argv[arg], "-p"))
|
||||
{
|
||||
std::string value_str;
|
||||
|
|
@ -510,7 +562,7 @@ int main(int argc, char** argv)
|
|||
for (; in_file != in_end; ++in_file, ++out_file)
|
||||
{
|
||||
// Load file
|
||||
LLPointer<LLImageRaw> raw_image = load_image(*in_file, discard_level, region, image_stats);
|
||||
LLPointer<LLImageRaw> raw_image = load_image(*in_file, discard_level, region, load_size, image_stats);
|
||||
if (!raw_image)
|
||||
{
|
||||
std::cout << "Error: Image " << *in_file << " could not be loaded" << std::endl;
|
||||
|
|
|
|||
|
|
@ -48,11 +48,15 @@
|
|||
//static
|
||||
std::string LLImage::sLastErrorMessage;
|
||||
LLMutex* LLImage::sMutex = NULL;
|
||||
bool LLImage::sUseNewByteRange = false;
|
||||
S32 LLImage::sMinimalReverseByteRangePercent = 75;
|
||||
LLPrivateMemoryPool* LLImageBase::sPrivatePoolp = NULL ;
|
||||
|
||||
//static
|
||||
void LLImage::initClass()
|
||||
void LLImage::initClass(bool use_new_byte_range, S32 minimal_reverse_byte_range_percent)
|
||||
{
|
||||
sUseNewByteRange = use_new_byte_range;
|
||||
sMinimalReverseByteRangePercent = minimal_reverse_byte_range_percent;
|
||||
sMutex = new LLMutex(NULL);
|
||||
|
||||
LLImageBase::createPrivatePool() ;
|
||||
|
|
@ -1334,7 +1338,8 @@ LLImageFormatted::LLImageFormatted(S8 codec)
|
|||
mCodec(codec),
|
||||
mDecoding(0),
|
||||
mDecoded(0),
|
||||
mDiscardLevel(-1)
|
||||
mDiscardLevel(-1),
|
||||
mLevels(0)
|
||||
{
|
||||
mMemType = LLMemType::MTYPE_IMAGEFORMATTED;
|
||||
}
|
||||
|
|
@ -1561,7 +1566,7 @@ void LLImageFormatted::appendData(U8 *data, S32 size)
|
|||
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
BOOL LLImageFormatted::load(const std::string &filename)
|
||||
BOOL LLImageFormatted::load(const std::string &filename, int load_size)
|
||||
{
|
||||
resetLastError();
|
||||
|
||||
|
|
@ -1580,14 +1585,19 @@ BOOL LLImageFormatted::load(const std::string &filename)
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
// Constrain the load size to acceptable values
|
||||
if ((load_size == 0) || (load_size > file_size))
|
||||
{
|
||||
load_size = file_size;
|
||||
}
|
||||
BOOL res;
|
||||
U8 *data = allocateData(file_size);
|
||||
apr_size_t bytes_read = file_size;
|
||||
U8 *data = allocateData(load_size);
|
||||
apr_size_t bytes_read = load_size;
|
||||
apr_status_t s = apr_file_read(apr_file, data, &bytes_read); // modifies bytes_read
|
||||
if (s != APR_SUCCESS || (S32) bytes_read != file_size)
|
||||
if (s != APR_SUCCESS || (S32) bytes_read != load_size)
|
||||
{
|
||||
deleteData();
|
||||
setLastError("Unable to read entire file",filename);
|
||||
setLastError("Unable to read file",filename);
|
||||
res = FALSE;
|
||||
}
|
||||
else
|
||||
|
|
|
|||
|
|
@ -48,6 +48,8 @@ const S32 MAX_PRECINCT_SIZE = 2048; // No reason to be bigger than MAX_IMAGE_S
|
|||
const S32 MIN_PRECINCT_SIZE = 4; // Can't be smaller than MIN_BLOCK_SIZE
|
||||
const S32 MAX_BLOCK_SIZE = 64; // Max total block size is 4096, hence 64x64 when using square blocks
|
||||
const S32 MIN_BLOCK_SIZE = 4; // Min block dim is 4 according to jpeg2000 spec
|
||||
const S32 MIN_LAYER_SIZE = 2000; // Size of the first quality layer (after header). Must be > to FIRST_PACKET_SIZE!!
|
||||
const S32 MAX_NB_LAYERS = 64; // Max number of layers we'll entertain in SL (practical limit)
|
||||
|
||||
const S32 MIN_IMAGE_SIZE = (1<<MIN_IMAGE_MIP); // 4, only used for expand/contract power of 2
|
||||
const S32 MAX_IMAGE_SIZE = (1<<MAX_IMAGE_MIP); // 2048
|
||||
|
|
@ -60,6 +62,7 @@ const S32 MAX_IMAGE_DATA_SIZE = MAX_IMAGE_AREA * MAX_IMAGE_COMPONENTS; //2048 *
|
|||
// *TODO: change both to 1024 when SIM texture fetching is deprecated
|
||||
const S32 FIRST_PACKET_SIZE = 600;
|
||||
const S32 MAX_IMG_PACKET_SIZE = 1000;
|
||||
const S32 HTTP_PACKET_SIZE = 1496;
|
||||
|
||||
// Base classes for images.
|
||||
// There are two major parts for the image:
|
||||
|
|
@ -89,15 +92,20 @@ typedef enum e_image_codec
|
|||
class LLImage
|
||||
{
|
||||
public:
|
||||
static void initClass();
|
||||
static void initClass(bool use_new_byte_range = false, S32 minimal_reverse_byte_range_percent = 75);
|
||||
static void cleanupClass();
|
||||
|
||||
static const std::string& getLastError();
|
||||
static void setLastError(const std::string& message);
|
||||
|
||||
static bool useNewByteRange() { return sUseNewByteRange; }
|
||||
static S32 getReverseByteRangePercent() { return sMinimalReverseByteRangePercent; }
|
||||
|
||||
protected:
|
||||
static LLMutex* sMutex;
|
||||
static std::string sLastErrorMessage;
|
||||
static bool sUseNewByteRange;
|
||||
static S32 sMinimalReverseByteRangePercent;
|
||||
};
|
||||
|
||||
//============================================================================
|
||||
|
|
@ -294,7 +302,7 @@ public:
|
|||
// getRawDiscardLevel() by default returns mDiscardLevel, but may be overridden (LLImageJ2C)
|
||||
virtual S8 getRawDiscardLevel() { return mDiscardLevel; }
|
||||
|
||||
BOOL load(const std::string& filename);
|
||||
BOOL load(const std::string& filename, int load_size = 0);
|
||||
BOOL save(const std::string& filename);
|
||||
|
||||
virtual BOOL updateData() = 0; // pure virtual
|
||||
|
|
@ -313,6 +321,8 @@ public:
|
|||
BOOL isDecoded() const { return mDecoded ? TRUE : FALSE; }
|
||||
void setDiscardLevel(S8 discard_level) { mDiscardLevel = discard_level; }
|
||||
S8 getDiscardLevel() const { return mDiscardLevel; }
|
||||
S8 getLevels() const { return mLevels; }
|
||||
void setLevels(S8 nlevels) { mLevels = nlevels; }
|
||||
|
||||
// setLastError needs to be deferred for J2C images since it may be called from a DLL
|
||||
virtual void resetLastError();
|
||||
|
|
@ -325,7 +335,8 @@ protected:
|
|||
S8 mCodec;
|
||||
S8 mDecoding;
|
||||
S8 mDecoded; // unused, but changing LLImage layout requires recompiling static Mac/Linux libs. 2009-01-30 JC
|
||||
S8 mDiscardLevel;
|
||||
S8 mDiscardLevel; // Current resolution level worked on. 0 = full res, 1 = half res, 2 = quarter res, etc...
|
||||
S8 mLevels; // Number of resolution levels in that image. Min is 1. 0 means unknown.
|
||||
|
||||
public:
|
||||
static S32 sGlobalFormattedMemory;
|
||||
|
|
|
|||
|
|
@ -56,7 +56,7 @@ std::string LLImageJ2C::getEngineInfo()
|
|||
LLImageJ2C::LLImageJ2C() : LLImageFormatted(IMG_CODEC_J2C),
|
||||
mMaxBytes(0),
|
||||
mRawDiscardLevel(-1),
|
||||
mRate(0.0f),
|
||||
mRate(DEFAULT_COMPRESSION_RATE),
|
||||
mReversible(FALSE),
|
||||
mAreaUsedForDataSizeCalcs(0)
|
||||
{
|
||||
|
|
@ -142,6 +142,7 @@ BOOL LLImageJ2C::updateData()
|
|||
|
||||
BOOL LLImageJ2C::initDecode(LLImageRaw &raw_image, int discard_level, int* region)
|
||||
{
|
||||
setDiscardLevel(discard_level != -1 ? discard_level : 0);
|
||||
return mImpl->initDecode(*this,raw_image,discard_level,region);
|
||||
}
|
||||
|
||||
|
|
@ -261,19 +262,34 @@ S32 LLImageJ2C::calcHeaderSizeJ2C()
|
|||
//static
|
||||
S32 LLImageJ2C::calcDataSizeJ2C(S32 w, S32 h, S32 comp, S32 discard_level, F32 rate)
|
||||
{
|
||||
// Note: this only provides an *estimate* of the size in bytes of an image level
|
||||
// *TODO: find a way to read the true size (when available) and convey the fact
|
||||
// that the result is an estimate in the other cases
|
||||
if (rate <= 0.f) rate = .125f;
|
||||
while (discard_level > 0)
|
||||
// Note: This provides an estimation for the first to last quality layer of a given discard level
|
||||
// This is however an efficient approximation, as the true discard level boundary would be
|
||||
// in general too big for fast fetching.
|
||||
// For details about the equation used here, see https://wiki.lindenlab.com/wiki/THX1138_KDU_Improvements#Byte_Range_Study
|
||||
|
||||
// Estimate the number of layers. This is consistent with what's done for j2c encoding in LLImageJ2CKDU::encodeImpl().
|
||||
S32 nb_layers = 1;
|
||||
S32 surface = w*h;
|
||||
S32 s = 64*64;
|
||||
while (surface > s)
|
||||
{
|
||||
if (w < 1 || h < 1)
|
||||
break;
|
||||
w >>= 1;
|
||||
h >>= 1;
|
||||
discard_level--;
|
||||
nb_layers++;
|
||||
s *= 4;
|
||||
}
|
||||
S32 bytes = (S32)((F32)(w*h*comp)*rate);
|
||||
F32 layer_factor = 3.0f * (7 - llclamp(nb_layers,1,6));
|
||||
|
||||
// Compute w/pow(2,discard_level) and h/pow(2,discard_level)
|
||||
w >>= discard_level;
|
||||
h >>= discard_level;
|
||||
w = llmax(w, 1);
|
||||
h = llmax(h, 1);
|
||||
|
||||
// Temporary: compute both new and old range and pick one according to the settings TextureNewByteRange
|
||||
// *TODO: Take the old code out once we have enough tests done
|
||||
S32 bytes;
|
||||
S32 new_bytes = (S32) (sqrt((F32)(w*h))*(F32)(comp)*rate*1000.f/layer_factor);
|
||||
S32 old_bytes = (S32)((F32)(w*h*comp)*rate);
|
||||
bytes = (LLImage::useNewByteRange() && (new_bytes < old_bytes) ? new_bytes : old_bytes);
|
||||
bytes = llmax(bytes, calcHeaderSizeJ2C());
|
||||
return bytes;
|
||||
}
|
||||
|
|
@ -283,15 +299,12 @@ S32 LLImageJ2C::calcHeaderSize()
|
|||
return calcHeaderSizeJ2C();
|
||||
}
|
||||
|
||||
|
||||
// calcDataSize() returns how many bytes to read
|
||||
// to load discard_level (including header and higher discard levels)
|
||||
// calcDataSize() returns how many bytes to read to load discard_level (including header)
|
||||
S32 LLImageJ2C::calcDataSize(S32 discard_level)
|
||||
{
|
||||
discard_level = llclamp(discard_level, 0, MAX_DISCARD_LEVEL);
|
||||
|
||||
if ( mAreaUsedForDataSizeCalcs != (getHeight() * getWidth())
|
||||
|| mDataSizes[0] == 0)
|
||||
|| (mDataSizes[0] == 0))
|
||||
{
|
||||
mAreaUsedForDataSizeCalcs = getHeight() * getWidth();
|
||||
|
||||
|
|
@ -301,25 +314,6 @@ S32 LLImageJ2C::calcDataSize(S32 discard_level)
|
|||
mDataSizes[level] = calcDataSizeJ2C(getWidth(), getHeight(), getComponents(), level, mRate);
|
||||
level--;
|
||||
}
|
||||
|
||||
/* This is technically a more correct way to calculate the size required
|
||||
for each discard level, since they should include the size needed for
|
||||
lower levels. Unfortunately, this doesn't work well and will lead to
|
||||
download stalls. The true correct way is to parse the header. This will
|
||||
all go away with http textures at some point.
|
||||
|
||||
// Calculate the size for each discard level. Lower levels (higher quality)
|
||||
// contain the cumulative size of higher levels
|
||||
S32 total_size = calcHeaderSizeJ2C();
|
||||
|
||||
S32 level = MAX_DISCARD_LEVEL; // Start at the highest discard
|
||||
while ( level >= 0 )
|
||||
{ // Add in this discard level and all before it
|
||||
total_size += calcDataSizeJ2C(getWidth(), getHeight(), getComponents(), level, mRate);
|
||||
mDataSizes[level] = total_size;
|
||||
level--;
|
||||
}
|
||||
*/
|
||||
}
|
||||
return mDataSizes[discard_level];
|
||||
}
|
||||
|
|
@ -334,8 +328,9 @@ S32 LLImageJ2C::calcDiscardLevelBytes(S32 bytes)
|
|||
}
|
||||
while (1)
|
||||
{
|
||||
S32 bytes_needed = calcDataSize(discard_level); // virtual
|
||||
if (bytes >= bytes_needed - (bytes_needed>>2)) // For J2c, up the res at 75% of the optimal number of bytes
|
||||
S32 bytes_needed = calcDataSize(discard_level);
|
||||
// Use TextureReverseByteRange percent (see settings.xml) of the optimal size to qualify as correct rendering for the given discard level
|
||||
if (bytes >= (bytes_needed*LLImage::getReverseByteRangePercent()/100))
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
|
@ -348,11 +343,6 @@ S32 LLImageJ2C::calcDiscardLevelBytes(S32 bytes)
|
|||
return discard_level;
|
||||
}
|
||||
|
||||
void LLImageJ2C::setRate(F32 rate)
|
||||
{
|
||||
mRate = rate;
|
||||
}
|
||||
|
||||
void LLImageJ2C::setMaxBytes(S32 max_bytes)
|
||||
{
|
||||
mMaxBytes = max_bytes;
|
||||
|
|
@ -474,6 +464,7 @@ LLImageCompressionTester::LLImageCompressionTester() : LLMetricPerformanceTester
|
|||
addMetric("Perf Compression (kB/s)");
|
||||
|
||||
mRunBytesInDecompression = 0;
|
||||
mRunBytesOutDecompression = 0;
|
||||
mRunBytesInCompression = 0;
|
||||
|
||||
mTotalBytesInDecompression = 0;
|
||||
|
|
@ -483,6 +474,7 @@ LLImageCompressionTester::LLImageCompressionTester() : LLMetricPerformanceTester
|
|||
|
||||
mTotalTimeDecompression = 0.0f;
|
||||
mTotalTimeCompression = 0.0f;
|
||||
mRunTimeDecompression = 0.0f;
|
||||
}
|
||||
|
||||
LLImageCompressionTester::~LLImageCompressionTester()
|
||||
|
|
@ -565,12 +557,17 @@ void LLImageCompressionTester::updateDecompressionStats(const S32 bytesIn, const
|
|||
mTotalBytesInDecompression += bytesIn;
|
||||
mRunBytesInDecompression += bytesIn;
|
||||
mTotalBytesOutDecompression += bytesOut;
|
||||
if (mRunBytesInDecompression > (1000000))
|
||||
mRunBytesOutDecompression += bytesOut;
|
||||
//if (mRunBytesInDecompression > (1000000))
|
||||
if (mRunBytesOutDecompression > (10000000))
|
||||
//if ((mTotalTimeDecompression - mRunTimeDecompression) >= (5.0f))
|
||||
{
|
||||
// Output everything
|
||||
outputTestResults();
|
||||
// Reset the decompression data of the run
|
||||
mRunBytesInDecompression = 0;
|
||||
mRunBytesOutDecompression = 0;
|
||||
mRunTimeDecompression = mTotalTimeDecompression;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -31,6 +31,9 @@
|
|||
#include "llassettype.h"
|
||||
#include "llmetricperformancetester.h"
|
||||
|
||||
// JPEG2000 : compression rate used in j2c conversion.
|
||||
const F32 DEFAULT_COMPRESSION_RATE = 1.f/8.f;
|
||||
|
||||
class LLImageJ2CImpl;
|
||||
class LLImageCompressionTester ;
|
||||
|
||||
|
|
@ -67,12 +70,11 @@ public:
|
|||
|
||||
// Encode accessors
|
||||
void setReversible(const BOOL reversible); // Use non-lossy?
|
||||
void setRate(F32 rate);
|
||||
void setMaxBytes(S32 max_bytes);
|
||||
S32 getMaxBytes() const { return mMaxBytes; }
|
||||
|
||||
static S32 calcHeaderSizeJ2C();
|
||||
static S32 calcDataSizeJ2C(S32 w, S32 h, S32 comp, S32 discard_level, F32 rate = 0.f);
|
||||
static S32 calcDataSizeJ2C(S32 w, S32 h, S32 comp, S32 discard_level, F32 rate = DEFAULT_COMPRESSION_RATE);
|
||||
|
||||
static std::string getEngineInfo();
|
||||
|
||||
|
|
@ -154,13 +156,15 @@ class LLImageCompressionTester : public LLMetricPerformanceTesterBasic
|
|||
U32 mTotalBytesOutDecompression; // Total bytes produced by decompressor
|
||||
U32 mTotalBytesInCompression; // Total bytes fed to compressor
|
||||
U32 mTotalBytesOutCompression; // Total bytes produced by compressor
|
||||
U32 mRunBytesInDecompression; // Bytes fed to decompressor in this run
|
||||
U32 mRunBytesInDecompression; // Bytes fed to decompressor in this run
|
||||
U32 mRunBytesOutDecompression; // Bytes produced by the decompressor in this run
|
||||
U32 mRunBytesInCompression; // Bytes fed to compressor in this run
|
||||
//
|
||||
// Time
|
||||
//
|
||||
F32 mTotalTimeDecompression; // Total time spent in computing decompression
|
||||
F32 mTotalTimeCompression; // Total time spent in computing compression
|
||||
F32 mRunTimeDecompression; // Time in this run (we output every 5 sec in decompress)
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@
|
|||
#include "llmath.h"
|
||||
#include "llkdumem.h"
|
||||
|
||||
#include "kdu_block_coding.h"
|
||||
|
||||
class kdc_flow_control {
|
||||
|
||||
|
|
@ -244,7 +245,9 @@ void LLImageJ2CKDU::setupCodeStream(LLImageJ2C &base, BOOL keep_codestream, ECod
|
|||
mCodeStreamp->create(mInputp);
|
||||
|
||||
// Set the maximum number of bytes to use from the codestream
|
||||
mCodeStreamp->set_max_bytes(max_bytes);
|
||||
// *TODO: This seems to be wrong. The base class should have no idea of how j2c compression works so no
|
||||
// good way of computing what's the byte range to be used.
|
||||
mCodeStreamp->set_max_bytes(max_bytes,true);
|
||||
|
||||
// If you want to flip or rotate the image for some reason, change
|
||||
// the resolution, or identify a restricted region of interest, this is
|
||||
|
|
@ -291,8 +294,13 @@ void LLImageJ2CKDU::setupCodeStream(LLImageJ2C &base, BOOL keep_codestream, ECod
|
|||
}
|
||||
}
|
||||
|
||||
// Get the number of resolution levels in that image
|
||||
mLevels = mCodeStreamp->get_min_dwt_levels();
|
||||
|
||||
// Set the base dimensions
|
||||
base.setSize(dims.size.x, dims.size.y, components);
|
||||
|
||||
base.setLevels(mLevels);
|
||||
|
||||
if (!keep_codestream)
|
||||
{
|
||||
mCodeStreamp->destroy();
|
||||
|
|
@ -351,7 +359,8 @@ BOOL LLImageJ2CKDU::initEncode(LLImageJ2C &base, LLImageRaw &raw_image, int bloc
|
|||
mLevels = levels;
|
||||
if (mLevels != 0)
|
||||
{
|
||||
mLevels = llclamp(mLevels,MIN_DECOMPOSITION_LEVELS,MIN_DECOMPOSITION_LEVELS);
|
||||
mLevels = llclamp(mLevels,MIN_DECOMPOSITION_LEVELS,MAX_DECOMPOSITION_LEVELS);
|
||||
base.setLevels(mLevels);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
|
@ -364,6 +373,9 @@ BOOL LLImageJ2CKDU::initDecode(LLImageJ2C &base, LLImageRaw &raw_image, F32 deco
|
|||
// To regain control, we throw an exception, and catch it here.
|
||||
try
|
||||
{
|
||||
// Merov : Test!! DO NOT COMMIT!!
|
||||
//findDiscardLevelsBoundaries(base);
|
||||
|
||||
base.updateRawDiscardLevel();
|
||||
setupCodeStream(base, TRUE, mode);
|
||||
|
||||
|
|
@ -381,7 +393,7 @@ BOOL LLImageJ2CKDU::initDecode(LLImageJ2C &base, LLImageRaw &raw_image, F32 deco
|
|||
region_kdu->size.y = region[3] - region[1];
|
||||
}
|
||||
int discard = (discard_level != -1 ? discard_level : base.getRawDiscardLevel());
|
||||
|
||||
//llinfos << "Merov debug : initDecode, discard used = " << discard << ", asked = " << discard_level << llendl;
|
||||
// Apply loading restrictions
|
||||
mCodeStreamp->apply_input_restrictions( first_channel, max_channel_count, discard, 0, region_kdu);
|
||||
|
||||
|
|
@ -394,12 +406,9 @@ BOOL LLImageJ2CKDU::initDecode(LLImageJ2C &base, LLImageRaw &raw_image, F32 deco
|
|||
|
||||
// Resize raw_image according to the image to be decoded
|
||||
kdu_dims dims; mCodeStreamp->get_dims(0,dims);
|
||||
// *TODO: Use the real number of levels read from the file throughout the code instead of relying on an infered value from dimensions
|
||||
//S32 levels = mCodeStreamp->get_min_dwt_levels();
|
||||
S32 channels = base.getComponents() - first_channel;
|
||||
channels = llmin(channels,max_channel_count);
|
||||
raw_image.resize(dims.size.x, dims.size.y, channels);
|
||||
//llinfos << "j2c image dimension: width = " << dims.size.x << ", height = " << dims.size.y << ", channels = " << channels << ", levels = " << levels << llendl;
|
||||
|
||||
if (!mTileIndicesp)
|
||||
{
|
||||
|
|
@ -583,12 +592,6 @@ BOOL LLImageJ2CKDU::encodeImpl(LLImageJ2C &base, const LLImageRaw &raw_image, co
|
|||
comment.put_text(comment_text);
|
||||
}
|
||||
|
||||
// Set codestream options
|
||||
int num_layer_specs = 0;
|
||||
|
||||
kdu_long layer_bytes[64];
|
||||
U32 max_bytes = 0;
|
||||
|
||||
if (num_components >= 3)
|
||||
{
|
||||
// Note that we always use YCC and not YUV
|
||||
|
|
@ -596,66 +599,51 @@ BOOL LLImageJ2CKDU::encodeImpl(LLImageJ2C &base, const LLImageRaw &raw_image, co
|
|||
set_default_colour_weights(codestream.access_siz());
|
||||
}
|
||||
|
||||
// Set codestream options
|
||||
int nb_layers = 0;
|
||||
kdu_long layer_bytes[MAX_NB_LAYERS];
|
||||
U32 max_bytes = (U32)(base.getWidth() * base.getHeight() * base.getComponents());
|
||||
|
||||
// Rate is the argument passed into the LLImageJ2C which specifies the target compression rate. The default is 8:1.
|
||||
// *TODO: mRate is actually always 8:1 in the viewer. Test different values.
|
||||
llassert (base.mRate > 0.f);
|
||||
max_bytes = (U32)((F32)(max_bytes) * base.mRate);
|
||||
|
||||
// This code is where we specify the target number of bytes for each quality layer.
|
||||
// We're using a logarithmic spacing rule that fits with our way of fetching texture data.
|
||||
// Note: For more info on this layers business, read kdu_codestream::flush() doc in kdu_compressed.h
|
||||
layer_bytes[nb_layers++] = FIRST_PACKET_SIZE;
|
||||
U32 i = MIN_LAYER_SIZE;
|
||||
while ((i < max_bytes) && (nb_layers < (MAX_NB_LAYERS-1)))
|
||||
{
|
||||
layer_bytes[nb_layers++] = i;
|
||||
i *= 4;
|
||||
}
|
||||
// Note: for small images, we can have (max_bytes < FIRST_PACKET_SIZE), hence the test
|
||||
if (layer_bytes[nb_layers-1] < max_bytes)
|
||||
{
|
||||
// Set the last quality layer so to fit the preset compression ratio
|
||||
layer_bytes[nb_layers++] = max_bytes;
|
||||
}
|
||||
|
||||
if (reversible)
|
||||
{
|
||||
// Use 0 for a last quality layer for reversible images so all remaining code blocks will be flushed
|
||||
// Hack: KDU encoding for reversible images has a bug for small images that leads to j2c images that
|
||||
// cannot be open or are very blurry. Avoiding that last layer prevents the problem to happen.
|
||||
if ((base.getWidth() >= 32) || (base.getHeight() >= 32))
|
||||
{
|
||||
layer_bytes[nb_layers++] = 0;
|
||||
}
|
||||
codestream.access_siz()->parse_string("Creversible=yes");
|
||||
// *TODO: we should use yuv in reversible mode and one level since those images are small.
|
||||
// Don't turn this on now though as both create problems on decoding for the moment
|
||||
//codestream.access_siz()->parse_string("Clevels=1");
|
||||
// *TODO: we should use yuv in reversible mode
|
||||
// Don't turn this on now though as it creates problems on decoding for the moment
|
||||
//codestream.access_siz()->parse_string("Cycc=no");
|
||||
// If we're doing reversible (i.e. lossless compression), assumes we're not using quality layers.
|
||||
// *TODO: this is incorrect and unecessary. Try using the regular layer setting.
|
||||
codestream.access_siz()->parse_string("Clayers=1");
|
||||
num_layer_specs = 1;
|
||||
layer_bytes[0] = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Rate is the argument passed into the LLImageJ2C which
|
||||
// specifies the target compression rate. The default is 8:1.
|
||||
// Possibly if max_bytes < 500, we should just use the default setting?
|
||||
// *TODO: mRate is actually always 8:1 in the viewer. Test different values. Also force to reversible for small (< 500 bytes) textures.
|
||||
if (base.mRate != 0.f)
|
||||
{
|
||||
max_bytes = (U32)(base.mRate*base.getWidth()*base.getHeight()*base.getComponents());
|
||||
}
|
||||
else
|
||||
{
|
||||
max_bytes = (U32)(base.getWidth()*base.getHeight()*base.getComponents()*0.125);
|
||||
}
|
||||
|
||||
const U32 min_bytes = FIRST_PACKET_SIZE;
|
||||
if (max_bytes > min_bytes)
|
||||
{
|
||||
U32 i;
|
||||
// This code is where we specify the target number of bytes for
|
||||
// each layer. Not sure if we should do this for small images
|
||||
// or not. The goal is to have this roughly align with
|
||||
// different quality levels that we decode at.
|
||||
for (i = min_bytes; i < max_bytes; i*=4)
|
||||
{
|
||||
if (i == min_bytes * 4)
|
||||
{
|
||||
i = 2000;
|
||||
}
|
||||
layer_bytes[num_layer_specs] = i;
|
||||
num_layer_specs++;
|
||||
}
|
||||
layer_bytes[num_layer_specs] = max_bytes;
|
||||
num_layer_specs++;
|
||||
|
||||
std::string layer_string = llformat("Clayers=%d",num_layer_specs);
|
||||
codestream.access_siz()->parse_string(layer_string.c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
layer_bytes[0] = min_bytes;
|
||||
num_layer_specs = 1;
|
||||
std::string layer_string = llformat("Clayers=%d",num_layer_specs);
|
||||
codestream.access_siz()->parse_string(layer_string.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
std::string layer_string = llformat("Clayers=%d",nb_layers);
|
||||
codestream.access_siz()->parse_string(layer_string.c_str());
|
||||
|
||||
// Set up data ordering, markers, etc... if precincts or blocks specified
|
||||
if ((mBlocksSize != -1) || (mPrecinctsSize != -1))
|
||||
{
|
||||
|
|
@ -669,23 +657,26 @@ BOOL LLImageJ2CKDU::encodeImpl(LLImageJ2C &base, const LLImageRaw &raw_image, co
|
|||
std::string blocks_string = llformat("Cblk={%d,%d}",mBlocksSize,mBlocksSize);
|
||||
codestream.access_siz()->parse_string(blocks_string.c_str());
|
||||
}
|
||||
std::string ordering_string = llformat("Corder=RPCL");
|
||||
std::string ordering_string = llformat("Corder=LRCP");
|
||||
codestream.access_siz()->parse_string(ordering_string.c_str());
|
||||
std::string PLT_string = llformat("ORGgen_plt=yes");
|
||||
codestream.access_siz()->parse_string(PLT_string.c_str());
|
||||
std::string Parts_string = llformat("ORGtparts=R");
|
||||
codestream.access_siz()->parse_string(Parts_string.c_str());
|
||||
}
|
||||
|
||||
// Set the number of wavelets subresolutions (aka levels)
|
||||
if (mLevels != 0)
|
||||
{
|
||||
std::string levels_string = llformat("Clevels=%d",mLevels);
|
||||
codestream.access_siz()->parse_string(levels_string.c_str());
|
||||
}
|
||||
|
||||
// Complete the encode settings
|
||||
codestream.access_siz()->finalize_all();
|
||||
codestream.change_appearance(transpose,vflip,hflip);
|
||||
|
||||
// Now we are ready for sample data processing.
|
||||
// Now we are ready for sample data processing
|
||||
kdc_flow_control *tile = new kdc_flow_control(&mem_in,codestream);
|
||||
bool done = false;
|
||||
while (!done)
|
||||
|
|
@ -702,7 +693,7 @@ BOOL LLImageJ2CKDU::encodeImpl(LLImageJ2C &base, const LLImageRaw &raw_image, co
|
|||
}
|
||||
|
||||
// Produce the compressed output
|
||||
codestream.flush(layer_bytes,num_layer_specs);
|
||||
codestream.flush(layer_bytes,nb_layers);
|
||||
|
||||
// Cleanup
|
||||
delete tile;
|
||||
|
|
@ -750,6 +741,207 @@ BOOL LLImageJ2CKDU::getMetadata(LLImageJ2C &base)
|
|||
}
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/* STATIC copy_block */
|
||||
/*****************************************************************************/
|
||||
|
||||
static void copy_block(kdu_block *in, kdu_block *out)
|
||||
{
|
||||
if (in->K_max_prime != out->K_max_prime)
|
||||
{
|
||||
std::cout << "Cannot copy blocks belonging to subbands with different quantization parameters." << std::endl;
|
||||
return;
|
||||
}
|
||||
if ((in->size.x != out->size.x) || (in->size.y != out->size.y))
|
||||
{
|
||||
std::cout << "Cannot copy code-blocks with different dimensions." << std::endl;
|
||||
return;
|
||||
}
|
||||
out->missing_msbs = in->missing_msbs;
|
||||
if (out->max_passes < (in->num_passes+2)) // Gives us enough to round up
|
||||
out->set_max_passes(in->num_passes+2,false); // to the next whole bit-plane
|
||||
out->num_passes = in->num_passes;
|
||||
int num_bytes = 0;
|
||||
for (int z=0; z < in->num_passes; z++)
|
||||
{
|
||||
num_bytes += (out->pass_lengths[z] = in->pass_lengths[z]);
|
||||
out->pass_slopes[z] = in->pass_slopes[z];
|
||||
}
|
||||
|
||||
// Just copy compressed code-bytes. Block transcoding not supported.
|
||||
if (out->max_bytes < num_bytes)
|
||||
out->set_max_bytes(num_bytes,false);
|
||||
memcpy(out->byte_buffer,in->byte_buffer,(size_t) num_bytes);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/* STATIC copy_tile */
|
||||
/*****************************************************************************/
|
||||
|
||||
static void
|
||||
copy_tile(kdu_tile tile_in, kdu_tile tile_out, int tnum_in, int tnum_out,
|
||||
kdu_params *siz_in, kdu_params *siz_out, int skip_components,
|
||||
int &num_blocks)
|
||||
{
|
||||
int num_components = tile_out.get_num_components();
|
||||
int new_tpart=0, next_tpart = 1;
|
||||
|
||||
for (int c=0; c < num_components; c++)
|
||||
{
|
||||
kdu_tile_comp comp_in, comp_out;
|
||||
comp_in = tile_in.access_component(c);
|
||||
comp_out = tile_out.access_component(c);
|
||||
int num_resolutions = comp_out.get_num_resolutions();
|
||||
//std::cout << " Copying tile : num_resolutions = " << num_resolutions << std::endl;
|
||||
for (int r=0; r < num_resolutions; r++)
|
||||
{
|
||||
kdu_resolution res_in; res_in = comp_in.access_resolution(r);
|
||||
kdu_resolution res_out; res_out = comp_out.access_resolution(r);
|
||||
int b, min_band;
|
||||
int num_bands = res_in.get_valid_band_indices(min_band);
|
||||
std::cout << " Copying tile : num_bands = " << num_bands << std::endl;
|
||||
for (b=min_band; num_bands > 0; num_bands--, b++)
|
||||
{
|
||||
kdu_subband band_in; band_in = res_in.access_subband(b);
|
||||
kdu_subband band_out; band_out = res_out.access_subband(b);
|
||||
kdu_dims blocks_in; band_in.get_valid_blocks(blocks_in);
|
||||
kdu_dims blocks_out; band_out.get_valid_blocks(blocks_out);
|
||||
if ((blocks_in.size.x != blocks_out.size.x) ||
|
||||
(blocks_in.size.y != blocks_out.size.y))
|
||||
{
|
||||
std::cout << "Transcoding operation cannot proceed: Code-block partitions for the input and output code-streams do not agree." << std::endl;
|
||||
return;
|
||||
}
|
||||
kdu_coords idx;
|
||||
//std::cout << " Copying tile : block indices, x = " << blocks_out.size.x << " and y = " << blocks_out.size.y << std::endl;
|
||||
for (idx.y=0; idx.y < blocks_out.size.y; idx.y++)
|
||||
{
|
||||
for (idx.x=0; idx.x < blocks_out.size.x; idx.x++)
|
||||
{
|
||||
kdu_block *in =
|
||||
band_in.open_block(idx+blocks_in.pos,&new_tpart);
|
||||
for (; next_tpart <= new_tpart; next_tpart++)
|
||||
siz_out->copy_from(siz_in,tnum_in,tnum_out,next_tpart,
|
||||
skip_components);
|
||||
kdu_block *out = band_out.open_block(idx+blocks_out.pos);
|
||||
copy_block(in,out);
|
||||
band_in.close_block(in);
|
||||
band_out.close_block(out);
|
||||
num_blocks++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Find the block boundary for each discard level in the input image.
|
||||
// We parse the input blocks and copy them in a temporary output stream.
|
||||
// For the moment, we do nothing more that parsing the raw list of blocks and outputing result.
|
||||
void LLImageJ2CKDU::findDiscardLevelsBoundaries(LLImageJ2C &base)
|
||||
{
|
||||
// We need the number of levels in that image before starting.
|
||||
getMetadata(base);
|
||||
|
||||
for (int discard_level = 0; discard_level < mLevels; discard_level++)
|
||||
{
|
||||
//std::cout << "Parsing discard level = " << discard_level << std::endl;
|
||||
// Create the input codestream object.
|
||||
setupCodeStream(base, TRUE, MODE_FAST);
|
||||
mCodeStreamp->apply_input_restrictions(0, 4, discard_level, 0, NULL);
|
||||
mCodeStreamp->set_max_bytes(KDU_LONG_MAX,true);
|
||||
siz_params *siz_in = mCodeStreamp->access_siz();
|
||||
|
||||
// Create the output codestream object.
|
||||
siz_params siz;
|
||||
siz.copy_from(siz_in,-1,-1,-1,0,discard_level,false,false,false);
|
||||
siz.set(Scomponents,0,0,mCodeStreamp->get_num_components());
|
||||
|
||||
U32 max_output_size = base.getWidth()*base.getHeight()*base.getComponents();
|
||||
max_output_size = (max_output_size < 1000 ? 1000 : max_output_size);
|
||||
U8 *output_buffer = new U8[max_output_size];
|
||||
U32 output_size = 0; // Address updated by LLKDUMemTarget to give the final compressed buffer size
|
||||
LLKDUMemTarget output(output_buffer, output_size, max_output_size);
|
||||
kdu_codestream codestream_out;
|
||||
codestream_out.create(&siz,&output);
|
||||
//codestream_out.share_buffering(*mCodeStreamp);
|
||||
siz_params *siz_out = codestream_out.access_siz();
|
||||
siz_out->copy_from(siz_in,-1,-1,-1,0,discard_level,false,false,false);
|
||||
codestream_out.access_siz()->finalize_all(-1);
|
||||
|
||||
// Set up rate control variables
|
||||
kdu_long max_bytes = KDU_LONG_MAX;
|
||||
kdu_params *cod = siz_out->access_cluster(COD_params);
|
||||
int total_layers; cod->get(Clayers,0,0,total_layers);
|
||||
kdu_long *layer_bytes = new kdu_long[total_layers];
|
||||
int nel, non_empty_layers = 0;
|
||||
|
||||
// Now ready to perform the transfer of compressed data between streams
|
||||
int flush_counter = INT_MAX;
|
||||
kdu_dims tile_indices_in;
|
||||
mCodeStreamp->get_valid_tiles(tile_indices_in);
|
||||
kdu_dims tile_indices_out;
|
||||
codestream_out.get_valid_tiles(tile_indices_out);
|
||||
assert((tile_indices_in.size.x == tile_indices_out.size.x) &&
|
||||
(tile_indices_in.size.y == tile_indices_out.size.y));
|
||||
int num_blocks=0;
|
||||
|
||||
kdu_coords idx;
|
||||
//std::cout << "Parsing tiles : x = " << tile_indices_out.size.x << " to y = " << tile_indices_out.size.y << std::endl;
|
||||
for (idx.y=0; idx.y < tile_indices_out.size.y; idx.y++)
|
||||
{
|
||||
for (idx.x=0; idx.x < tile_indices_out.size.x; idx.x++)
|
||||
{
|
||||
kdu_tile tile_in = mCodeStreamp->open_tile(idx+tile_indices_in.pos);
|
||||
int tnum_in = tile_in.get_tnum();
|
||||
int tnum_out = idx.x + idx.y*tile_indices_out.size.x;
|
||||
siz_out->copy_from(siz_in,tnum_in,tnum_out,0,0,discard_level,false,false,false);
|
||||
siz_out->finalize_all(tnum_out);
|
||||
// Note: do not open the output tile without first copying any tile-specific code-stream parameters
|
||||
kdu_tile tile_out = codestream_out.open_tile(idx+tile_indices_out.pos);
|
||||
assert(tnum_out == tile_out.get_tnum());
|
||||
copy_tile(tile_in,tile_out,tnum_in,tnum_out,siz_in,siz_out,0,num_blocks);
|
||||
tile_in.close();
|
||||
tile_out.close();
|
||||
flush_counter--;
|
||||
if ((flush_counter <= 0) && codestream_out.ready_for_flush())
|
||||
{
|
||||
flush_counter = INT_MAX;
|
||||
nel = codestream_out.trans_out(max_bytes,layer_bytes,total_layers);
|
||||
non_empty_layers = (nel > non_empty_layers)?nel:non_empty_layers;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Generate the output code-stream
|
||||
if (codestream_out.ready_for_flush())
|
||||
{
|
||||
nel = codestream_out.trans_out(max_bytes,layer_bytes,total_layers);
|
||||
non_empty_layers = (nel > non_empty_layers)?nel:non_empty_layers;
|
||||
}
|
||||
if (non_empty_layers > total_layers)
|
||||
non_empty_layers = total_layers; // Can happen if a tile has more layers
|
||||
|
||||
// Print out stats
|
||||
std::cout << "Code stream parsing for discard level = " << discard_level << std::endl;
|
||||
std::cout << " Total compressed memory in = " << mCodeStreamp->get_compressed_data_memory() << " bytes" << std::endl;
|
||||
std::cout << " Total compressed memory out = " << codestream_out.get_compressed_data_memory() << " bytes" << std::endl;
|
||||
//std::cout << " Output contains " << total_layers << " quality layers" << std::endl;
|
||||
std::cout << " Transferred " << num_blocks << " code-blocks from in to out" << std::endl;
|
||||
//std::cout << " Read " << mCodeStreamp->get_num_tparts() << " tile-part(s) from a total of " << (int) tile_indices_in.area() << " tile(s)" << std::endl;
|
||||
std::cout << " Total bytes read = " << mCodeStreamp->get_total_bytes() << std::endl;
|
||||
//std::cout << " Wrote " << codestream_out.get_num_tparts() << " tile-part(s) in a total of " << (int) tile_indices_out.area() << " tile(s)" << std::endl;
|
||||
std::cout << " Total bytes written = " << codestream_out.get_total_bytes() << std::endl;
|
||||
std::cout << "-------------" << std::endl;
|
||||
|
||||
// Clean-up
|
||||
cleanupCodeStream();
|
||||
codestream_out.destroy();
|
||||
delete[] output_buffer;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void set_default_colour_weights(kdu_params *siz)
|
||||
{
|
||||
kdu_params *cod = siz->access_cluster(COD_params);
|
||||
|
|
|
|||
|
|
@ -60,6 +60,7 @@ protected:
|
|||
BOOL reversible=FALSE);
|
||||
/*virtual*/ BOOL initDecode(LLImageJ2C &base, LLImageRaw &raw_image, int discard_level = -1, int* region = NULL);
|
||||
/*virtual*/ BOOL initEncode(LLImageJ2C &base, LLImageRaw &raw_image, int blocks_size = -1, int precincts_size = -1, int levels = 0);
|
||||
void findDiscardLevelsBoundaries(LLImageJ2C &base);
|
||||
|
||||
private:
|
||||
BOOL initDecode(LLImageJ2C &base, LLImageRaw &raw_image, F32 decode_time, ECodeStreamMode mode, S32 first_channel, S32 max_channel_count, int discard_level = -1, int* region = NULL);
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@
|
|||
// Class to test
|
||||
#include "llimagej2ckdu.h"
|
||||
#include "llkdumem.h"
|
||||
#include "kdu_block_coding.h"
|
||||
// Tut header
|
||||
#include "lltut.h"
|
||||
|
||||
|
|
@ -86,7 +87,7 @@ void LLImageFormatted::resetLastError() { }
|
|||
void LLImageFormatted::sanityCheck() { }
|
||||
void LLImageFormatted::setLastError(const std::string& , const std::string& ) { }
|
||||
|
||||
LLImageJ2C::LLImageJ2C() : LLImageFormatted(IMG_CODEC_J2C) { }
|
||||
LLImageJ2C::LLImageJ2C() : LLImageFormatted(IMG_CODEC_J2C), mRate(DEFAULT_COMPRESSION_RATE) { }
|
||||
LLImageJ2C::~LLImageJ2C() { }
|
||||
S32 LLImageJ2C::calcDataSize(S32 ) { return 0; }
|
||||
S32 LLImageJ2C::calcDiscardLevelBytes(S32 ) { return 0; }
|
||||
|
|
@ -107,16 +108,25 @@ bool LLKDUMemIn::get(int, kdu_line_buf&, int) { return false; }
|
|||
|
||||
// Stub Kakadu Library calls
|
||||
kdu_tile_comp kdu_tile::access_component(int ) { kdu_tile_comp a; return a; }
|
||||
kdu_block_encoder::kdu_block_encoder() { }
|
||||
kdu_block_decoder::kdu_block_decoder() { }
|
||||
void kdu_block::set_max_passes(int , bool ) { }
|
||||
void kdu_block::set_max_bytes(int , bool ) { }
|
||||
void kdu_block::set_max_samples(int ) { }
|
||||
void kdu_tile::close(kdu_thread_env* ) { }
|
||||
int kdu_tile::get_num_components() { return 0; }
|
||||
bool kdu_tile::get_ycc() { return false; }
|
||||
void kdu_tile::set_components_of_interest(int , const int* ) { }
|
||||
int kdu_tile::get_tnum() { return 0; }
|
||||
kdu_resolution kdu_tile_comp::access_resolution() { kdu_resolution a; return a; }
|
||||
kdu_resolution kdu_tile_comp::access_resolution(int ) { kdu_resolution a; return a; }
|
||||
int kdu_tile_comp::get_bit_depth(bool ) { return 8; }
|
||||
bool kdu_tile_comp::get_reversible() { return false; }
|
||||
int kdu_tile_comp::get_num_resolutions() { return 1; }
|
||||
kdu_subband kdu_resolution::access_subband(int ) { kdu_subband a; return a; }
|
||||
void kdu_resolution::get_dims(kdu_dims& ) { }
|
||||
int kdu_resolution::which() { return 0; }
|
||||
int kdu_resolution::get_valid_band_indices(int &) { return 1; }
|
||||
kdu_decoder::kdu_decoder(kdu_subband , kdu_sample_allocator*, bool , float, int, kdu_thread_env*, kdu_thread_queue*) { }
|
||||
kdu_synthesis::kdu_synthesis(kdu_resolution, kdu_sample_allocator*, bool, float, kdu_thread_env*, kdu_thread_queue*) { }
|
||||
kdu_params::kdu_params(const char*, bool, bool, bool, bool, bool) { }
|
||||
|
|
@ -124,6 +134,7 @@ kdu_params::~kdu_params() { }
|
|||
void kdu_params::set(const char* , int , int , bool ) { }
|
||||
void kdu_params::set(const char* , int , int , int ) { }
|
||||
void kdu_params::finalize_all(bool ) { }
|
||||
void kdu_params::finalize_all(int, bool ) { }
|
||||
void kdu_params::copy_from(kdu_params*, int, int, int, int, int, bool, bool, bool) { }
|
||||
bool kdu_params::parse_string(const char*) { return false; }
|
||||
bool kdu_params::get(const char*, int, int, bool&, bool, bool, bool) { return false; }
|
||||
|
|
@ -135,6 +146,7 @@ void kdu_codestream::set_fast() { }
|
|||
void kdu_codestream::set_fussy() { }
|
||||
void kdu_codestream::get_dims(int, kdu_dims&, bool ) { }
|
||||
int kdu_codestream::get_min_dwt_levels() { return 5; }
|
||||
int kdu_codestream::get_max_tile_layers() { return 1; }
|
||||
void kdu_codestream::change_appearance(bool, bool, bool) { }
|
||||
void kdu_codestream::get_tile_dims(kdu_coords, int, kdu_dims&, bool ) { }
|
||||
void kdu_codestream::destroy() { }
|
||||
|
|
@ -148,9 +160,18 @@ void kdu_codestream::get_subsampling(int , kdu_coords&, bool ) { }
|
|||
void kdu_codestream::flush(kdu_long *, int , kdu_uint16 *, bool, bool, double, kdu_thread_env*) { }
|
||||
void kdu_codestream::set_resilient(bool ) { }
|
||||
int kdu_codestream::get_num_components(bool ) { return 0; }
|
||||
kdu_long kdu_codestream::get_total_bytes(bool ) { return 0; }
|
||||
kdu_long kdu_codestream::get_compressed_data_memory(bool ) {return 0; }
|
||||
void kdu_codestream::share_buffering(kdu_codestream ) { }
|
||||
int kdu_codestream::get_num_tparts() { return 0; }
|
||||
int kdu_codestream::trans_out(kdu_long, kdu_long*, int, bool, kdu_thread_env* ) { return 0; }
|
||||
bool kdu_codestream::ready_for_flush(kdu_thread_env*) { return false; }
|
||||
siz_params* kdu_codestream::access_siz() { return NULL; }
|
||||
kdu_tile kdu_codestream::open_tile(kdu_coords , kdu_thread_env* ) { kdu_tile a; return a; }
|
||||
kdu_codestream_comment kdu_codestream::add_comment() { kdu_codestream_comment a; return a; }
|
||||
void kdu_subband::close_block(kdu_block*, kdu_thread_env*) { }
|
||||
void kdu_subband::get_valid_blocks(kdu_dims &indices) { }
|
||||
kdu_block* kdu_subband::open_block(kdu_coords, int*, kdu_thread_env*) { return NULL; }
|
||||
bool kdu_codestream_comment::put_text(const char*) { return false; }
|
||||
void kdu_customize_warnings(kdu_message*) { }
|
||||
void kdu_customize_errors(kdu_message*) { }
|
||||
|
|
|
|||
|
|
@ -1506,7 +1506,8 @@ void LLCurl::cleanupClass()
|
|||
delete sHandleMutexp ;
|
||||
sHandleMutexp = NULL ;
|
||||
|
||||
llassert(Easy::sActiveHandles.empty());
|
||||
// removed as per https://jira.secondlife.com/browse/SH-3115
|
||||
//llassert(Easy::sActiveHandles.empty());
|
||||
}
|
||||
|
||||
//static
|
||||
|
|
|
|||
|
|
@ -43,7 +43,6 @@
|
|||
const F32 MIN_TEXTURE_LIFETIME = 10.f;
|
||||
|
||||
//statics
|
||||
LLGLuint LLImageGL::sCurrentBoundTextures[MAX_GL_TEXTURE_UNITS] = { 0 };
|
||||
|
||||
U32 LLImageGL::sUniqueCount = 0;
|
||||
U32 LLImageGL::sBindCount = 0;
|
||||
|
|
@ -65,19 +64,10 @@ std::set<LLImageGL*> LLImageGL::sImageList;
|
|||
//****************************************************************************************************
|
||||
//-----------------------
|
||||
//debug use
|
||||
BOOL gAuditTexture = FALSE ;
|
||||
#define MAX_TEXTURE_LOG_SIZE 22 //2048 * 2048
|
||||
std::vector<S32> LLImageGL::sTextureLoadedCounter(MAX_TEXTURE_LOG_SIZE + 1) ;
|
||||
std::vector<S32> LLImageGL::sTextureBoundCounter(MAX_TEXTURE_LOG_SIZE + 1) ;
|
||||
std::vector<S32> LLImageGL::sTextureCurBoundCounter(MAX_TEXTURE_LOG_SIZE + 1) ;
|
||||
S32 LLImageGL::sCurTexSizeBar = -1 ;
|
||||
S32 LLImageGL::sCurTexPickSize = -1 ;
|
||||
LLPointer<LLImageGL> LLImageGL::sHighlightTexturep = NULL;
|
||||
S32 LLImageGL::sMaxCatagories = 1 ;
|
||||
S32 LLImageGL::sMaxCategories = 1 ;
|
||||
|
||||
std::vector<S32> LLImageGL::sTextureMemByCategory;
|
||||
std::vector<S32> LLImageGL::sTextureMemByCategoryBound ;
|
||||
std::vector<S32> LLImageGL::sTextureCurMemByCategoryBound ;
|
||||
//------------------------
|
||||
//****************************************************************************************************
|
||||
//End for texture auditing use only
|
||||
|
|
@ -175,49 +165,11 @@ BOOL is_little_endian()
|
|||
//static
|
||||
void LLImageGL::initClass(S32 num_catagories)
|
||||
{
|
||||
sMaxCatagories = num_catagories ;
|
||||
|
||||
sTextureMemByCategory.resize(sMaxCatagories);
|
||||
sTextureMemByCategoryBound.resize(sMaxCatagories) ;
|
||||
sTextureCurMemByCategoryBound.resize(sMaxCatagories) ;
|
||||
}
|
||||
|
||||
//static
|
||||
void LLImageGL::cleanupClass()
|
||||
{
|
||||
sTextureMemByCategory.clear() ;
|
||||
sTextureMemByCategoryBound.clear() ;
|
||||
sTextureCurMemByCategoryBound.clear() ;
|
||||
}
|
||||
|
||||
//static
|
||||
void LLImageGL::setHighlightTexture(S32 category)
|
||||
{
|
||||
const S32 dim = 128;
|
||||
sHighlightTexturep = new LLImageGL() ;
|
||||
LLPointer<LLImageRaw> image_raw = new LLImageRaw(dim,dim,3);
|
||||
U8* data = image_raw->getData();
|
||||
for (S32 i = 0; i<dim; i++)
|
||||
{
|
||||
for (S32 j = 0; j<dim; j++)
|
||||
{
|
||||
const S32 border = 2;
|
||||
if (i<border || j<border || i>=(dim-border) || j>=(dim-border))
|
||||
{
|
||||
*data++ = 0xff;
|
||||
*data++ = 0xff;
|
||||
*data++ = 0xff;
|
||||
}
|
||||
else
|
||||
{
|
||||
*data++ = 0xff;
|
||||
*data++ = 0xff;
|
||||
*data++ = 0x00;
|
||||
}
|
||||
}
|
||||
}
|
||||
sHighlightTexturep->createGLTexture(0, image_raw, 0, TRUE, category);
|
||||
image_raw = NULL;
|
||||
}
|
||||
|
||||
//static
|
||||
|
|
@ -285,31 +237,11 @@ void LLImageGL::updateStats(F32 current_time)
|
|||
sLastFrameTime = current_time;
|
||||
sBoundTextureMemoryInBytes = sCurBoundTextureMemory;
|
||||
sCurBoundTextureMemory = 0;
|
||||
|
||||
if(gAuditTexture)
|
||||
{
|
||||
for(U32 i = 0 ; i < sTextureCurBoundCounter.size() ; i++)
|
||||
{
|
||||
sTextureBoundCounter[i] = sTextureCurBoundCounter[i] ;
|
||||
sTextureCurBoundCounter[i] = 0 ;
|
||||
}
|
||||
for(U32 i = 0 ; i < sTextureCurMemByCategoryBound.size() ; i++)
|
||||
{
|
||||
sTextureMemByCategoryBound[i] = sTextureCurMemByCategoryBound[i] ;
|
||||
sTextureCurMemByCategoryBound[i] = 0 ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//static
|
||||
S32 LLImageGL::updateBoundTexMem(const S32 mem, const S32 ncomponents, S32 category)
|
||||
{
|
||||
if(gAuditTexture && ncomponents > 0 && category > -1)
|
||||
{
|
||||
sTextureCurBoundCounter[getTextureCounterIndex(mem / ncomponents)]++ ;
|
||||
sTextureCurMemByCategoryBound[category] += mem ;
|
||||
}
|
||||
|
||||
LLImageGL::sCurBoundTextureMemory += mem ;
|
||||
return LLImageGL::sCurBoundTextureMemory;
|
||||
}
|
||||
|
|
@ -1284,7 +1216,7 @@ BOOL LLImageGL::createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S
|
|||
return TRUE ;
|
||||
}
|
||||
|
||||
setCategory(category) ;
|
||||
setCategory(category);
|
||||
const U8* rawdata = imageraw->getData();
|
||||
return createGLTexture(discard_level, rawdata, FALSE, usename);
|
||||
}
|
||||
|
|
@ -1362,11 +1294,6 @@ BOOL LLImageGL::createGLTexture(S32 discard_level, const U8* data_in, BOOL data_
|
|||
{
|
||||
sGlobalTextureMemoryInBytes -= mTextureMemory;
|
||||
|
||||
if(gAuditTexture)
|
||||
{
|
||||
decTextureCounter(mTextureMemory, mComponents, mCategory) ;
|
||||
}
|
||||
|
||||
LLImageGL::deleteTextures(1, &old_name);
|
||||
|
||||
stop_glerror();
|
||||
|
|
@ -1376,10 +1303,6 @@ BOOL LLImageGL::createGLTexture(S32 discard_level, const U8* data_in, BOOL data_
|
|||
sGlobalTextureMemoryInBytes += mTextureMemory;
|
||||
mTexelsInGLTexture = getWidth() * getHeight() ;
|
||||
|
||||
if(gAuditTexture)
|
||||
{
|
||||
incTextureCounter(mTextureMemory, mComponents, mCategory) ;
|
||||
}
|
||||
// mark this as bound at this point, so we don't throw it out immediately
|
||||
mLastBindTime = sLastFrameTime;
|
||||
return TRUE;
|
||||
|
|
@ -1536,22 +1459,29 @@ void LLImageGL::destroyGLTexture()
|
|||
{
|
||||
if(mTextureMemory)
|
||||
{
|
||||
if(gAuditTexture)
|
||||
{
|
||||
decTextureCounter(mTextureMemory, mComponents, mCategory) ;
|
||||
}
|
||||
sGlobalTextureMemoryInBytes -= mTextureMemory;
|
||||
mTextureMemory = 0;
|
||||
}
|
||||
|
||||
LLImageGL::deleteTextures(1, &mTexName);
|
||||
mTexName = 0;
|
||||
mCurrentDiscardLevel = -1 ; //invalidate mCurrentDiscardLevel.
|
||||
mTexName = 0;
|
||||
mGLTextureCreated = FALSE ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//force to invalidate the gl texture, most likely a sculpty texture
|
||||
void LLImageGL::forceToInvalidateGLTexture()
|
||||
{
|
||||
if (mTexName != 0)
|
||||
{
|
||||
destroyGLTexture();
|
||||
}
|
||||
else
|
||||
{
|
||||
mCurrentDiscardLevel = -1 ; //invalidate mCurrentDiscardLevel.
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
|
|
@ -1969,70 +1899,6 @@ BOOL LLImageGL::getMask(const LLVector2 &tc)
|
|||
return res;
|
||||
}
|
||||
|
||||
void LLImageGL::setCategory(S32 category)
|
||||
{
|
||||
#if 0 //turn this off temporarily because it is not in use now.
|
||||
if(!gAuditTexture)
|
||||
{
|
||||
return ;
|
||||
}
|
||||
if(mCategory != category)
|
||||
{
|
||||
if(mCategory > -1)
|
||||
{
|
||||
sTextureMemByCategory[mCategory] -= mTextureMemory ;
|
||||
}
|
||||
if(category > -1 && category < sMaxCatagories)
|
||||
{
|
||||
sTextureMemByCategory[category] += mTextureMemory ;
|
||||
mCategory = category;
|
||||
}
|
||||
else
|
||||
{
|
||||
mCategory = -1 ;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
//for debug use
|
||||
//val is a "power of two" number
|
||||
S32 LLImageGL::getTextureCounterIndex(U32 val)
|
||||
{
|
||||
//index range is [0, MAX_TEXTURE_LOG_SIZE].
|
||||
if(val < 2)
|
||||
{
|
||||
return 0 ;
|
||||
}
|
||||
else if(val >= (1 << MAX_TEXTURE_LOG_SIZE))
|
||||
{
|
||||
return MAX_TEXTURE_LOG_SIZE ;
|
||||
}
|
||||
else
|
||||
{
|
||||
S32 ret = 0 ;
|
||||
while(val >>= 1)
|
||||
{
|
||||
++ret;
|
||||
}
|
||||
return ret ;
|
||||
}
|
||||
}
|
||||
|
||||
//static
|
||||
void LLImageGL::incTextureCounter(U32 val, S32 ncomponents, S32 category)
|
||||
{
|
||||
sTextureLoadedCounter[getTextureCounterIndex(val)]++ ;
|
||||
sTextureMemByCategory[category] += (S32)val * ncomponents ;
|
||||
}
|
||||
|
||||
//static
|
||||
void LLImageGL::decTextureCounter(U32 val, S32 ncomponents, S32 category)
|
||||
{
|
||||
sTextureLoadedCounter[getTextureCounterIndex(val)]-- ;
|
||||
sTextureMemByCategory[category] += (S32)val * ncomponents ;
|
||||
}
|
||||
|
||||
void LLImageGL::setCurTexSizebar(S32 index, BOOL set_pick_size)
|
||||
{
|
||||
sCurTexSizeBar = index ;
|
||||
|
|
|
|||
|
|
@ -102,8 +102,8 @@ public:
|
|||
static void setManualImage(U32 target, S32 miplevel, S32 intformat, S32 width, S32 height, U32 pixformat, U32 pixtype, const void *pixels);
|
||||
|
||||
BOOL createGLTexture() ;
|
||||
BOOL createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S32 usename = 0, BOOL to_create = TRUE,
|
||||
S32 category = sMaxCatagories - 1);
|
||||
BOOL createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S32 usename = 0, BOOL to_create = TRUE,
|
||||
S32 category = sMaxCategories-1);
|
||||
BOOL createGLTexture(S32 discard_level, const U8* data, BOOL data_hasmips = FALSE, S32 usename = 0);
|
||||
void setImage(const LLImageRaw* imageraw);
|
||||
void setImage(const U8* data_in, BOOL data_hasmips = FALSE);
|
||||
|
|
@ -114,6 +114,7 @@ public:
|
|||
// Read back a raw image for this discard level, if it exists
|
||||
BOOL readBackRaw(S32 discard_level, LLImageRaw* imageraw, bool compressed_ok) const;
|
||||
void destroyGLTexture();
|
||||
void forceToInvalidateGLTexture();
|
||||
|
||||
void setExplicitFormat(LLGLint internal_format, LLGLenum primary_format, LLGLenum type_format = 0, BOOL swap_bytes = FALSE);
|
||||
void setComponents(S8 ncomponents) { mComponents = ncomponents; }
|
||||
|
|
@ -234,8 +235,6 @@ public:
|
|||
static S32 sCount;
|
||||
|
||||
static F32 sLastFrameTime;
|
||||
|
||||
static LLGLuint sCurrentBoundTextures[MAX_GL_TEXTURE_UNITS]; // Currently bound texture ID
|
||||
|
||||
// Global memory statistics
|
||||
static S32 sGlobalTextureMemoryInBytes; // Tracks main memory texmem
|
||||
|
|
@ -257,9 +256,10 @@ public:
|
|||
public:
|
||||
static void initClass(S32 num_catagories) ;
|
||||
static void cleanupClass() ;
|
||||
private:
|
||||
static S32 sMaxCatagories ;
|
||||
|
||||
private:
|
||||
static S32 sMaxCategories;
|
||||
|
||||
//the flag to allow to call readBackRaw(...).
|
||||
//can be removed if we do not use that function at all.
|
||||
static BOOL sAllowReadBackRaw ;
|
||||
|
|
@ -269,39 +269,22 @@ private:
|
|||
//****************************************************************************************************
|
||||
private:
|
||||
S32 mCategory ;
|
||||
public:
|
||||
void setCategory(S32 category) ;
|
||||
S32 getCategory()const {return mCategory ;}
|
||||
|
||||
public:
|
||||
void setCategory(S32 category) {mCategory = category;}
|
||||
S32 getCategory()const {return mCategory;}
|
||||
|
||||
//for debug use: show texture size distribution
|
||||
//----------------------------------------
|
||||
static LLPointer<LLImageGL> sHighlightTexturep; //default texture to replace normal textures
|
||||
static std::vector<S32> sTextureLoadedCounter ;
|
||||
static std::vector<S32> sTextureBoundCounter ;
|
||||
static std::vector<S32> sTextureCurBoundCounter ;
|
||||
static S32 sCurTexSizeBar ;
|
||||
static S32 sCurTexPickSize ;
|
||||
|
||||
static void setHighlightTexture(S32 category) ;
|
||||
static S32 getTextureCounterIndex(U32 val) ;
|
||||
static void incTextureCounter(U32 val, S32 ncomponents, S32 category) ;
|
||||
static void decTextureCounter(U32 val, S32 ncomponents, S32 category) ;
|
||||
static void setCurTexSizebar(S32 index, BOOL set_pick_size = TRUE) ;
|
||||
static void resetCurTexSizebar();
|
||||
//----------------------------------------
|
||||
|
||||
//for debug use: show texture category distribution
|
||||
//----------------------------------------
|
||||
|
||||
static std::vector<S32> sTextureMemByCategory;
|
||||
static std::vector<S32> sTextureMemByCategoryBound ;
|
||||
static std::vector<S32> sTextureCurMemByCategoryBound ;
|
||||
//----------------------------------------
|
||||
//****************************************************************************************************
|
||||
//End of definitions for texture auditing use only
|
||||
//****************************************************************************************************
|
||||
|
||||
};
|
||||
|
||||
extern BOOL gAuditTexture;
|
||||
#endif // LL_LLIMAGEGL_H
|
||||
|
|
|
|||
|
|
@ -246,14 +246,6 @@ bool LLTexUnit::bind(LLTexture* texture, bool for_rendering, bool forceBind)
|
|||
}
|
||||
|
||||
//in audit, replace the selected texture by the default one.
|
||||
if(gAuditTexture && for_rendering && LLImageGL::sCurTexPickSize > 0)
|
||||
{
|
||||
if(texture->getWidth() * texture->getHeight() == LLImageGL::sCurTexPickSize)
|
||||
{
|
||||
gl_tex->updateBindStats(gl_tex->mTextureMemory);
|
||||
return bind(LLImageGL::sHighlightTexturep.get());
|
||||
}
|
||||
}
|
||||
if ((mCurrTexture != gl_tex->getTexName()) || forceBind)
|
||||
{
|
||||
activate();
|
||||
|
|
|
|||
|
|
@ -196,24 +196,24 @@ void LLContainerView::arrange(S32 width, S32 height, BOOL called_from_parent)
|
|||
if (total_height < height)
|
||||
total_height = height;
|
||||
|
||||
LLRect my_rect = getRect();
|
||||
if (followsTop())
|
||||
{
|
||||
// HACK: casting away const. Should use setRect or some helper function instead.
|
||||
const_cast<LLRect&>(getRect()).mBottom = getRect().mTop - total_height;
|
||||
my_rect.mBottom = my_rect.mTop - total_height;
|
||||
}
|
||||
else
|
||||
{
|
||||
// HACK: casting away const. Should use setRect or some helper function instead.
|
||||
const_cast<LLRect&>(getRect()).mTop = getRect().mBottom + total_height;
|
||||
my_rect.mTop = my_rect.mBottom + total_height;
|
||||
}
|
||||
// HACK: casting away const. Should use setRect or some helper function instead.
|
||||
const_cast<LLRect&>(getRect()).mRight = getRect().mLeft + width;
|
||||
|
||||
my_rect.mRight = my_rect.mLeft + width;
|
||||
setRect(my_rect);
|
||||
|
||||
top = total_height;
|
||||
if (mShowLabel)
|
||||
{
|
||||
top -= 20;
|
||||
}
|
||||
{
|
||||
top -= 20;
|
||||
}
|
||||
|
||||
bottom = top;
|
||||
|
||||
|
|
|
|||
|
|
@ -272,7 +272,7 @@ LLRect LLStatBar::getRequiredRect()
|
|||
{
|
||||
if (mDisplayHistory)
|
||||
{
|
||||
rect.mTop = 67;
|
||||
rect.mTop = 35 + mStatp->getNumBins();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
|||
|
|
@ -237,6 +237,7 @@ set(viewer_SOURCE_FILES
|
|||
llfloatertelehub.cpp
|
||||
llfloatertestinspectors.cpp
|
||||
llfloatertestlistview.cpp
|
||||
llfloatertexturefetchdebugger.cpp
|
||||
llfloatertools.cpp
|
||||
llfloatertopobjects.cpp
|
||||
llfloatertos.cpp
|
||||
|
|
@ -793,6 +794,7 @@ set(viewer_HEADER_FILES
|
|||
llfloatertelehub.h
|
||||
llfloatertestinspectors.h
|
||||
llfloatertestlistview.h
|
||||
llfloatertexturefetchdebugger.h
|
||||
llfloatertools.h
|
||||
llfloatertopobjects.h
|
||||
llfloatertos.h
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@
|
|||
<key>tags</key>
|
||||
<array>
|
||||
<string>AppInit</string>
|
||||
<string>Capabilities</string>
|
||||
<string>Capabilities</string>
|
||||
<string>SystemInfo</string>
|
||||
<string>TextureCache</string>
|
||||
<string>AppCache</string>
|
||||
|
|
@ -42,8 +42,10 @@
|
|||
</array>
|
||||
<key>tags</key>
|
||||
<array>
|
||||
<!-- sample entry for debugging a specific item -->
|
||||
<!-- <string>Voice</string> -->
|
||||
<!-- sample entry for debugging specific items
|
||||
<string>Avatar</string>
|
||||
<string>Voice</string>
|
||||
-->
|
||||
</array>
|
||||
</map>
|
||||
</array>
|
||||
|
|
|
|||
|
|
@ -335,17 +335,6 @@
|
|||
<key>Value</key>
|
||||
<integer>1</integer>
|
||||
</map>
|
||||
<key>AuditTexture</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Enable texture auditting.</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
<key>AutoAcceptNewInventory</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
|
|
@ -1936,7 +1925,7 @@
|
|||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
<integer>1</integer>
|
||||
</map>
|
||||
<key>DebugBeaconLineWidth</key>
|
||||
<map>
|
||||
|
|
@ -7183,6 +7172,17 @@
|
|||
<key>Value</key>
|
||||
<integer>-1</integer>
|
||||
</map>
|
||||
<key>QAModeMetrics</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>"Enables QA features (logging, faster cycling) for metrics collector"</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
<key>QuietSnapshotsToDisk</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
|
|
@ -10664,6 +10664,39 @@
|
|||
<key>Value</key>
|
||||
<real>20.0</real>
|
||||
</map>
|
||||
<key>TexelPixelRatio</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>texel pixel ratio = texel / pixel</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>F32</string>
|
||||
<key>Value</key>
|
||||
<real>1.0</real>
|
||||
</map>
|
||||
<key>TextureCameraMotionThreshold</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>If the overall motion is lower than this value, textures will be loaded faster</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>F32</string>
|
||||
<key>Value</key>
|
||||
<real>0.2</real>
|
||||
</map>
|
||||
<key>TextureCameraMotionBoost</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Progressive discard level decrement when the camera is still</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>S32</string>
|
||||
<key>Value</key>
|
||||
<integer>3</integer>
|
||||
</map>
|
||||
<key>TextureDecodeDisabled</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
|
|
@ -10697,6 +10730,17 @@
|
|||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
<key>TextureFetchDebuggerEnabled</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Enable the texture fetching debugger if set</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
<key>TextureLoadFullRes</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
|
|
@ -10719,6 +10763,17 @@
|
|||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
<key>TextureNewByteRange</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Use the new more accurate byte range computation for j2c discard levels</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>1</integer>
|
||||
</map>
|
||||
<key>TexturePickerShowFolders</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
|
|
@ -10741,6 +10796,17 @@
|
|||
<key>Value</key>
|
||||
<integer>2</integer>
|
||||
</map>
|
||||
<key>TextureReverseByteRange</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Minimal percent of the optimal byte range allowed to render a given discard level</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>S32</string>
|
||||
<key>Value</key>
|
||||
<integer>50</integer>
|
||||
</map>
|
||||
<key>ThrottleBandwidthKBPS</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
|
|
|
|||
|
|
@ -3253,6 +3253,10 @@ void LLAgent::processControlRelease(LLMessageSystem *msg, void **)
|
|||
void LLAgent::processAgentCachedTextureResponse(LLMessageSystem *mesgsys, void **user_data)
|
||||
{
|
||||
gAgentQueryManager.mNumPendingQueries--;
|
||||
if (gAgentQueryManager.mNumPendingQueries == 0)
|
||||
{
|
||||
selfStopPhase("fetch_texture_cache_entries");
|
||||
}
|
||||
|
||||
if (!isAgentAvatarValid() || gAgentAvatarp->isDead())
|
||||
{
|
||||
|
|
@ -3302,13 +3306,12 @@ void LLAgent::processAgentCachedTextureResponse(LLMessageSystem *mesgsys, void *
|
|||
else
|
||||
{
|
||||
// no cache of this bake. request upload.
|
||||
gAgentAvatarp->requestLayerSetUpload(baked_index);
|
||||
gAgentAvatarp->invalidateComposite(gAgentAvatarp->getLayerSet(baked_index),TRUE);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
llinfos << "Received cached texture response for " << num_results << " textures." << llendl;
|
||||
gAgentAvatarp->outputRezTiming("Fetched agent wearables textures from cache. Will now load them");
|
||||
|
||||
|
|
@ -3775,7 +3778,15 @@ void LLAgent::sendAgentSetAppearance()
|
|||
return;
|
||||
}
|
||||
|
||||
llinfos << "TAT: Sent AgentSetAppearance: " << gAgentAvatarp->getBakedStatusForPrintout() << llendl;
|
||||
if (!gAgentWearables.changeInProgress())
|
||||
{
|
||||
// Change is fully resolved, can close some open phases.
|
||||
gAgentAvatarp->getPhases().stopPhase("process_initial_wearables_update");
|
||||
gAgentAvatarp->getPhases().stopPhase("wear_inventory_category");
|
||||
}
|
||||
|
||||
gAgentAvatarp->sendAppearanceChangeMetrics();
|
||||
LL_INFOS("Avatar") << gAgentAvatarp->avString() << "TAT: Sent AgentSetAppearance: " << gAgentAvatarp->getBakedStatusForPrintout() << LL_ENDL;
|
||||
//dumpAvatarTEs( "sendAgentSetAppearance()" );
|
||||
|
||||
LLMessageSystem* msg = gMessageSystem;
|
||||
|
|
@ -3822,14 +3833,14 @@ void LLAgent::sendAgentSetAppearance()
|
|||
// only update cache entries if we have all our baked textures
|
||||
if (textures_current)
|
||||
{
|
||||
llinfos << "TAT: Sending cached texture data" << llendl;
|
||||
LL_INFOS("Avatar") << gAgentAvatarp->avString() << "TAT: Sending cached texture data" << LL_ENDL;
|
||||
for (U8 baked_index = 0; baked_index < BAKED_NUM_INDICES; baked_index++)
|
||||
{
|
||||
BOOL generate_valid_hash = TRUE;
|
||||
if (isAgentAvatarValid() && !gAgentAvatarp->isBakedTextureFinal((LLVOAvatarDefines::EBakedTextureIndex)baked_index))
|
||||
{
|
||||
generate_valid_hash = FALSE;
|
||||
llinfos << "Not caching baked texture upload for " << (U32)baked_index << " due to being uploaded at low resolution." << llendl;
|
||||
LL_DEBUGS("Avatar") << gAgentAvatarp->avString() << "Not caching baked texture upload for " << (U32)baked_index << " due to being uploaded at low resolution." << LL_ENDL;
|
||||
}
|
||||
|
||||
const LLUUID hash = gAgentWearables.computeBakedTextureHash((EBakedTextureIndex) baked_index, generate_valid_hash);
|
||||
|
|
|
|||
|
|
@ -126,6 +126,17 @@ LLAgentListener::LLAgentListener(LLAgent &agent)
|
|||
"[\"obj_uuid\"]: id of object to look at, use this or [\"position\"] to indicate the target\n"
|
||||
"[\"position\"]: region position {x, y, z} where to find closest object or avatar to look at",
|
||||
&LLAgentListener::lookAt);
|
||||
add("getGroups",
|
||||
"Send information about the agent's groups on [\"reply\"]:\n"
|
||||
"[\"groups\"]: array of group information\n"
|
||||
"[\"id\"]: group id\n"
|
||||
"[\"name\"]: group name\n"
|
||||
"[\"insignia\"]: group insignia texture id\n"
|
||||
"[\"notices\"]: boolean indicating if this user accepts notices from this group\n"
|
||||
"[\"display\"]: boolean indicating if this group is listed in the user's profile\n"
|
||||
"[\"contrib\"]: user's land contribution to this group\n",
|
||||
&LLAgentListener::getGroups,
|
||||
LLSDMap("reply", LLSD()));
|
||||
}
|
||||
|
||||
void LLAgentListener::requestTeleport(LLSD const & event_data) const
|
||||
|
|
|
|||
|
|
@ -955,6 +955,8 @@ void LLAgentWearables::processAgentInitialWearablesUpdate(LLMessageSystem* mesgs
|
|||
|
||||
if (isAgentAvatarValid())
|
||||
{
|
||||
//gAgentAvatarp->clearPhases(); // reset phase timers for outfit loading.
|
||||
gAgentAvatarp->getPhases().startPhase("process_initial_wearables_update");
|
||||
gAgentAvatarp->outputRezTiming("Received initial wearables update");
|
||||
}
|
||||
|
||||
|
|
@ -1448,7 +1450,16 @@ void LLAgentWearables::setWearableOutfit(const LLInventoryItem::item_array_t& it
|
|||
{
|
||||
gAgentAvatarp->setCompositeUpdatesEnabled(TRUE);
|
||||
gAgentAvatarp->updateVisualParams();
|
||||
gAgentAvatarp->invalidateAll();
|
||||
|
||||
// If we have not yet declouded, we may want to use
|
||||
// baked texture UUIDs sent from the first objectUpdate message
|
||||
// don't overwrite these. If we have already declouded, we've saved
|
||||
// these ids as the last known good textures and can invalidate without
|
||||
// re-clouding.
|
||||
if (!gAgentAvatarp->getIsCloud())
|
||||
{
|
||||
gAgentAvatarp->invalidateAll();
|
||||
}
|
||||
}
|
||||
|
||||
// Start rendering & update the server
|
||||
|
|
@ -1630,10 +1641,11 @@ void LLAgentWearables::queryWearableCache()
|
|||
{
|
||||
if (isAgentAvatarValid())
|
||||
{
|
||||
selfStartPhase("fetch_texture_cache_entries");
|
||||
gAgentAvatarp->outputRezTiming("Fetching textures from cache");
|
||||
}
|
||||
|
||||
llinfos << "Requesting texture cache entry for " << num_queries << " baked textures" << llendl;
|
||||
LL_INFOS("Avatar") << gAgentAvatarp->avString() << "Requesting texture cache entry for " << num_queries << " baked textures" << LL_ENDL;
|
||||
gMessageSystem->sendReliable(gAgent.getRegion()->getHost());
|
||||
gAgentQueryManager.mNumPendingQueries++;
|
||||
gAgentQueryManager.mWearablesCacheQueryID++;
|
||||
|
|
@ -2081,6 +2093,11 @@ boost::signals2::connection LLAgentWearables::addLoadedCallback(loaded_callback_
|
|||
return mLoadedSignal.connect(cb);
|
||||
}
|
||||
|
||||
bool LLAgentWearables::changeInProgress() const
|
||||
{
|
||||
return mCOFChangeInProgress;
|
||||
}
|
||||
|
||||
void LLAgentWearables::notifyLoadingStarted()
|
||||
{
|
||||
mCOFChangeInProgress = true;
|
||||
|
|
|
|||
|
|
@ -233,6 +233,7 @@ public:
|
|||
typedef boost::signals2::signal<void()> loaded_signal_t;
|
||||
boost::signals2::connection addLoadedCallback(loaded_callback_t cb);
|
||||
|
||||
bool changeInProgress() const;
|
||||
void notifyLoadingStarted();
|
||||
void notifyLoadingFinished();
|
||||
|
||||
|
|
|
|||
|
|
@ -89,6 +89,7 @@ LLInitialWearablesFetch::LLInitialWearablesFetch(const LLUUID& cof_id) :
|
|||
{
|
||||
if (isAgentAvatarValid())
|
||||
{
|
||||
gAgentAvatarp->getPhases().startPhase("initial_wearables_fetch");
|
||||
gAgentAvatarp->outputRezTiming("Initial wearables fetch started");
|
||||
}
|
||||
}
|
||||
|
|
@ -107,6 +108,7 @@ void LLInitialWearablesFetch::done()
|
|||
doOnIdleOneTime(boost::bind(&LLInitialWearablesFetch::processContents,this));
|
||||
if (isAgentAvatarValid())
|
||||
{
|
||||
gAgentAvatarp->getPhases().stopPhase("initial_wearables_fetch");
|
||||
gAgentAvatarp->outputRezTiming("Initial wearables fetch done");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -50,6 +50,11 @@
|
|||
#include "llviewerregion.h"
|
||||
#include "llwearablelist.h"
|
||||
|
||||
std::string self_av_string()
|
||||
{
|
||||
return gAgentAvatarp->avString();
|
||||
}
|
||||
|
||||
// RAII thingy to guarantee that a variable gets reset when the Setter
|
||||
// goes out of scope. More general utility would be handy - TODO:
|
||||
// check boost.
|
||||
|
|
@ -156,6 +161,10 @@ public:
|
|||
{
|
||||
mCatID = cat_id;
|
||||
mAppend = append;
|
||||
|
||||
LL_INFOS("Avatar") << self_av_string() << "starting" << LL_ENDL;
|
||||
|
||||
selfStartPhase("wear_inventory_category_callback");
|
||||
}
|
||||
void fire(const LLUUID& item_id)
|
||||
{
|
||||
|
|
@ -167,13 +176,16 @@ public:
|
|||
* after the last item has fired the event and dereferenced it -- if all
|
||||
* the events actually fire!
|
||||
*/
|
||||
LL_DEBUGS("Avatar") << self_av_string() << " fired on copied item, id " << item_id << LL_ENDL;
|
||||
}
|
||||
|
||||
protected:
|
||||
~LLWearInventoryCategoryCallback()
|
||||
{
|
||||
llinfos << "done all inventory callbacks" << llendl;
|
||||
LL_INFOS("Avatar") << self_av_string() << "done all inventory callbacks" << LL_ENDL;
|
||||
|
||||
selfStopPhase("wear_inventory_category_callback");
|
||||
|
||||
// Is the destructor called by ordinary dereference, or because the app's shutting down?
|
||||
// If the inventory callback manager goes away, we're shutting down, no longer want the callback.
|
||||
if( LLInventoryCallbackManager::is_instantiated() )
|
||||
|
|
@ -182,7 +194,7 @@ protected:
|
|||
}
|
||||
else
|
||||
{
|
||||
llwarns << "Dropping unhandled LLWearInventoryCategoryCallback" << llendl;
|
||||
llwarns << self_av_string() << "Dropping unhandled LLWearInventoryCategoryCallback" << llendl;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -212,11 +224,14 @@ LLUpdateAppearanceOnDestroy::LLUpdateAppearanceOnDestroy(bool update_base_outfit
|
|||
mFireCount(0),
|
||||
mUpdateBaseOrder(update_base_outfit_ordering)
|
||||
{
|
||||
selfStartPhase("update_appearance_on_destroy");
|
||||
}
|
||||
|
||||
LLUpdateAppearanceOnDestroy::~LLUpdateAppearanceOnDestroy()
|
||||
{
|
||||
llinfos << "done update appearance on destroy" << llendl;
|
||||
LL_INFOS("Avatar") << self_av_string() << "done update appearance on destroy" << LL_ENDL;
|
||||
|
||||
selfStopPhase("update_appearance_on_destroy");
|
||||
|
||||
if (!LLApp::isExiting())
|
||||
{
|
||||
|
|
@ -229,7 +244,7 @@ void LLUpdateAppearanceOnDestroy::fire(const LLUUID& inv_item)
|
|||
LLViewerInventoryItem* item = (LLViewerInventoryItem*)gInventory.getItem(inv_item);
|
||||
const std::string item_name = item ? item->getName() : "ITEM NOT FOUND";
|
||||
#ifndef LL_RELEASE_FOR_DOWNLOAD
|
||||
llinfos << "callback fired [ name:" << item_name << " UUID:" << inv_item << " count:" << mFireCount << " ] " << llendl;
|
||||
LL_DEBUGS("Avatar") << self_av_string() << "callback fired [ name:" << item_name << " UUID:" << inv_item << " count:" << mFireCount << " ] " << LL_ENDL;
|
||||
#endif
|
||||
mFireCount++;
|
||||
}
|
||||
|
|
@ -339,11 +354,16 @@ LLWearableHoldingPattern::LLWearableHoldingPattern():
|
|||
|
||||
}
|
||||
sActiveHoldingPatterns.insert(this);
|
||||
selfStartPhase("holding_pattern");
|
||||
}
|
||||
|
||||
LLWearableHoldingPattern::~LLWearableHoldingPattern()
|
||||
{
|
||||
sActiveHoldingPatterns.erase(this);
|
||||
if (isMostRecent())
|
||||
{
|
||||
selfStopPhase("holding_pattern");
|
||||
}
|
||||
}
|
||||
|
||||
bool LLWearableHoldingPattern::isMostRecent()
|
||||
|
|
@ -390,9 +410,10 @@ void LLWearableHoldingPattern::checkMissingWearables()
|
|||
{
|
||||
if (!isMostRecent())
|
||||
{
|
||||
llwarns << "skipping because LLWearableHolding pattern is invalid (superceded by later outfit request)" << llendl;
|
||||
// runway why don't we actually skip here?
|
||||
llwarns << self_av_string() << "skipping because LLWearableHolding pattern is invalid (superceded by later outfit request)" << llendl;
|
||||
}
|
||||
|
||||
|
||||
std::vector<S32> found_by_type(LLWearableType::WT_COUNT,0);
|
||||
std::vector<S32> requested_by_type(LLWearableType::WT_COUNT,0);
|
||||
for (found_list_t::iterator it = getFoundList().begin(); it != getFoundList().end(); ++it)
|
||||
|
|
@ -408,7 +429,7 @@ void LLWearableHoldingPattern::checkMissingWearables()
|
|||
{
|
||||
if (requested_by_type[type] > found_by_type[type])
|
||||
{
|
||||
llwarns << "got fewer wearables than requested, type " << type << ": requested " << requested_by_type[type] << ", found " << found_by_type[type] << llendl;
|
||||
llwarns << self_av_string() << "got fewer wearables than requested, type " << type << ": requested " << requested_by_type[type] << ", found " << found_by_type[type] << llendl;
|
||||
}
|
||||
if (found_by_type[type] > 0)
|
||||
continue;
|
||||
|
|
@ -425,11 +446,13 @@ void LLWearableHoldingPattern::checkMissingWearables()
|
|||
mTypesToRecover.insert(type);
|
||||
mTypesToLink.insert(type);
|
||||
recoverMissingWearable((LLWearableType::EType)type);
|
||||
llwarns << "need to replace " << type << llendl;
|
||||
llwarns << self_av_string() << "need to replace " << type << llendl;
|
||||
}
|
||||
}
|
||||
|
||||
resetTime(60.0F);
|
||||
|
||||
selfStartPhase("get_missing_wearables");
|
||||
if (!pollMissingWearables())
|
||||
{
|
||||
doOnIdleRepeating(boost::bind(&LLWearableHoldingPattern::pollMissingWearables,this));
|
||||
|
|
@ -445,13 +468,14 @@ void LLWearableHoldingPattern::onAllComplete()
|
|||
|
||||
if (!isMostRecent())
|
||||
{
|
||||
llwarns << "skipping because LLWearableHolding pattern is invalid (superceded by later outfit request)" << llendl;
|
||||
// runway need to skip here?
|
||||
llwarns << self_av_string() << "skipping because LLWearableHolding pattern is invalid (superceded by later outfit request)" << llendl;
|
||||
}
|
||||
|
||||
// Activate all gestures in this folder
|
||||
if (mGestItems.count() > 0)
|
||||
{
|
||||
llinfos << "Activating " << mGestItems.count() << " gestures" << llendl;
|
||||
LL_DEBUGS("Avatar") << self_av_string() << "Activating " << mGestItems.count() << " gestures" << LL_ENDL;
|
||||
|
||||
LLGestureMgr::instance().activateGestures(mGestItems);
|
||||
|
||||
|
|
@ -468,13 +492,13 @@ void LLWearableHoldingPattern::onAllComplete()
|
|||
}
|
||||
|
||||
// Update wearables.
|
||||
llinfos << "Updating agent wearables with " << mResolved << " wearable items " << llendl;
|
||||
LL_INFOS("Avatar") << self_av_string() << "Updating agent wearables with " << mResolved << " wearable items " << LL_ENDL;
|
||||
LLAppearanceMgr::instance().updateAgentWearables(this, false);
|
||||
|
||||
// Update attachments to match those requested.
|
||||
if (isAgentAvatarValid())
|
||||
{
|
||||
llinfos << "Updating " << mObjItems.count() << " attachments" << llendl;
|
||||
LL_DEBUGS("Avatar") << self_av_string() << "Updating " << mObjItems.count() << " attachments" << LL_ENDL;
|
||||
LLAgentWearables::userUpdateAttachments(mObjItems);
|
||||
}
|
||||
|
||||
|
|
@ -492,9 +516,12 @@ void LLWearableHoldingPattern::onAllComplete()
|
|||
|
||||
void LLWearableHoldingPattern::onFetchCompletion()
|
||||
{
|
||||
selfStopPhase("get_wearables");
|
||||
|
||||
if (!isMostRecent())
|
||||
{
|
||||
llwarns << "skipping because LLWearableHolding pattern is invalid (superceded by later outfit request)" << llendl;
|
||||
// runway skip here?
|
||||
llwarns << self_av_string() << "skipping because LLWearableHolding pattern is invalid (superceded by later outfit request)" << llendl;
|
||||
}
|
||||
|
||||
checkMissingWearables();
|
||||
|
|
@ -505,7 +532,8 @@ bool LLWearableHoldingPattern::pollFetchCompletion()
|
|||
{
|
||||
if (!isMostRecent())
|
||||
{
|
||||
llwarns << "skipping because LLWearableHolding pattern is invalid (superceded by later outfit request)" << llendl;
|
||||
// runway skip here?
|
||||
llwarns << self_av_string() << "skipping because LLWearableHolding pattern is invalid (superceded by later outfit request)" << llendl;
|
||||
}
|
||||
|
||||
bool completed = isFetchCompleted();
|
||||
|
|
@ -514,14 +542,14 @@ bool LLWearableHoldingPattern::pollFetchCompletion()
|
|||
|
||||
if (done)
|
||||
{
|
||||
llinfos << "polling, done status: " << completed << " timed out " << timed_out
|
||||
<< " elapsed " << mWaitTime.getElapsedTimeF32() << llendl;
|
||||
LL_INFOS("Avatar") << self_av_string() << "polling, done status: " << completed << " timed out " << timed_out
|
||||
<< " elapsed " << mWaitTime.getElapsedTimeF32() << LL_ENDL;
|
||||
|
||||
mFired = true;
|
||||
|
||||
if (timed_out)
|
||||
{
|
||||
llwarns << "Exceeded max wait time for wearables, updating appearance based on what has arrived" << llendl;
|
||||
llwarns << self_av_string() << "Exceeded max wait time for wearables, updating appearance based on what has arrived" << llendl;
|
||||
}
|
||||
|
||||
onFetchCompletion();
|
||||
|
|
@ -543,6 +571,7 @@ public:
|
|||
if (!mHolder->isMostRecent())
|
||||
{
|
||||
llwarns << "skipping because LLWearableHolding pattern is invalid (superceded by later outfit request)" << llendl;
|
||||
// runway skip here?
|
||||
}
|
||||
|
||||
llinfos << "Recovered item link for type " << mType << llendl;
|
||||
|
|
@ -569,12 +598,12 @@ public:
|
|||
}
|
||||
else
|
||||
{
|
||||
llwarns << "inventory item not found for recovered wearable" << llendl;
|
||||
llwarns << self_av_string() << "inventory item not found for recovered wearable" << llendl;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
llwarns << "inventory link not found for recovered wearable" << llendl;
|
||||
llwarns << self_av_string() << "inventory link not found for recovered wearable" << llendl;
|
||||
}
|
||||
}
|
||||
private:
|
||||
|
|
@ -596,10 +625,11 @@ public:
|
|||
{
|
||||
if (!mHolder->isMostRecent())
|
||||
{
|
||||
llwarns << "skipping because LLWearableHolding pattern is invalid (superceded by later outfit request)" << llendl;
|
||||
// runway skip here?
|
||||
llwarns << self_av_string() << "skipping because LLWearableHolding pattern is invalid (superceded by later outfit request)" << llendl;
|
||||
}
|
||||
|
||||
llinfos << "Recovered item for type " << mType << llendl;
|
||||
LL_DEBUGS("Avatar") << self_av_string() << "Recovered item for type " << mType << LL_ENDL;
|
||||
LLViewerInventoryItem *itemp = gInventory.getItem(item_id);
|
||||
mWearable->setItemID(item_id);
|
||||
LLPointer<LLInventoryCallback> cb = new RecoveredItemLinkCB(mType,mWearable,mHolder);
|
||||
|
|
@ -626,7 +656,8 @@ void LLWearableHoldingPattern::recoverMissingWearable(LLWearableType::EType type
|
|||
{
|
||||
if (!isMostRecent())
|
||||
{
|
||||
llwarns << "skipping because LLWearableHolding pattern is invalid (superceded by later outfit request)" << llendl;
|
||||
// runway skip here?
|
||||
llwarns << self_av_string() << "skipping because LLWearableHolding pattern is invalid (superceded by later outfit request)" << llendl;
|
||||
}
|
||||
|
||||
// Try to recover by replacing missing wearable with a new one.
|
||||
|
|
@ -665,7 +696,7 @@ void LLWearableHoldingPattern::clearCOFLinksForMissingWearables()
|
|||
if ((data.mWearableType < LLWearableType::WT_COUNT) && (!data.mWearable))
|
||||
{
|
||||
// Wearable link that was never resolved; remove links to it from COF
|
||||
llinfos << "removing link for unresolved item " << data.mItemID.asString() << llendl;
|
||||
LL_INFOS("Avatar") << self_av_string() << "removing link for unresolved item " << data.mItemID.asString() << LL_ENDL;
|
||||
LLAppearanceMgr::instance().removeCOFItemLinks(data.mItemID,false);
|
||||
}
|
||||
}
|
||||
|
|
@ -675,7 +706,8 @@ bool LLWearableHoldingPattern::pollMissingWearables()
|
|||
{
|
||||
if (!isMostRecent())
|
||||
{
|
||||
llwarns << "skipping because LLWearableHolding pattern is invalid (superceded by later outfit request)" << llendl;
|
||||
// runway skip here?
|
||||
llwarns << self_av_string() << "skipping because LLWearableHolding pattern is invalid (superceded by later outfit request)" << llendl;
|
||||
}
|
||||
|
||||
bool timed_out = isTimedOut();
|
||||
|
|
@ -684,15 +716,17 @@ bool LLWearableHoldingPattern::pollMissingWearables()
|
|||
|
||||
if (!done)
|
||||
{
|
||||
llinfos << "polling missing wearables, waiting for items " << mTypesToRecover.size()
|
||||
LL_INFOS("Avatar") << self_av_string() << "polling missing wearables, waiting for items " << mTypesToRecover.size()
|
||||
<< " links " << mTypesToLink.size()
|
||||
<< " wearables, timed out " << timed_out
|
||||
<< " elapsed " << mWaitTime.getElapsedTimeF32()
|
||||
<< " done " << done << llendl;
|
||||
<< " done " << done << LL_ENDL;
|
||||
}
|
||||
|
||||
if (done)
|
||||
{
|
||||
selfStopPhase("get_missing_wearables");
|
||||
|
||||
gAgentAvatarp->debugWearablesLoaded();
|
||||
|
||||
// BAP - if we don't call clearCOFLinksForMissingWearables()
|
||||
|
|
@ -722,14 +756,14 @@ void LLWearableHoldingPattern::handleLateArrivals()
|
|||
}
|
||||
if (!isMostRecent())
|
||||
{
|
||||
llwarns << "Late arrivals not handled - outfit change no longer valid" << llendl;
|
||||
llwarns << self_av_string() << "Late arrivals not handled - outfit change no longer valid" << llendl;
|
||||
}
|
||||
if (!mIsAllComplete)
|
||||
{
|
||||
llwarns << "Late arrivals not handled - in middle of missing wearables processing" << llendl;
|
||||
llwarns << self_av_string() << "Late arrivals not handled - in middle of missing wearables processing" << llendl;
|
||||
}
|
||||
|
||||
llinfos << "Need to handle " << mLateArrivals.size() << " late arriving wearables" << llendl;
|
||||
LL_INFOS("Avatar") << self_av_string() << "Need to handle " << mLateArrivals.size() << " late arriving wearables" << LL_ENDL;
|
||||
|
||||
// Update mFoundList using late-arriving wearables.
|
||||
std::set<LLWearableType::EType> replaced_types;
|
||||
|
|
@ -805,19 +839,19 @@ void LLWearableHoldingPattern::onWearableAssetFetch(LLWearable *wearable)
|
|||
{
|
||||
if (!isMostRecent())
|
||||
{
|
||||
llwarns << "skipping because LLWearableHolding pattern is invalid (superceded by later outfit request)" << llendl;
|
||||
llwarns << self_av_string() << "skipping because LLWearableHolding pattern is invalid (superceded by later outfit request)" << llendl;
|
||||
}
|
||||
|
||||
mResolved += 1; // just counting callbacks, not successes.
|
||||
llinfos << "resolved " << mResolved << "/" << getFoundList().size() << llendl;
|
||||
LL_DEBUGS("Avatar") << self_av_string() << "resolved " << mResolved << "/" << getFoundList().size() << LL_ENDL;
|
||||
if (!wearable)
|
||||
{
|
||||
llwarns << "no wearable found" << llendl;
|
||||
llwarns << self_av_string() << "no wearable found" << llendl;
|
||||
}
|
||||
|
||||
if (mFired)
|
||||
{
|
||||
llwarns << "called after holder fired" << llendl;
|
||||
llwarns << self_av_string() << "called after holder fired" << llendl;
|
||||
if (wearable)
|
||||
{
|
||||
mLateArrivals.insert(wearable);
|
||||
|
|
@ -843,7 +877,7 @@ void LLWearableHoldingPattern::onWearableAssetFetch(LLWearable *wearable)
|
|||
// Failing this means inventory or asset server are corrupted in a way we don't handle.
|
||||
if ((data.mWearableType >= LLWearableType::WT_COUNT) || (wearable->getType() != data.mWearableType))
|
||||
{
|
||||
llwarns << "recovered wearable but type invalid. inventory wearable type: " << data.mWearableType << " asset wearable type: " << wearable->getType() << llendl;
|
||||
llwarns << self_av_string() << "recovered wearable but type invalid. inventory wearable type: " << data.mWearableType << " asset wearable type: " << wearable->getType() << llendl;
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -1391,8 +1425,8 @@ void LLAppearanceMgr::filterWearableItems(
|
|||
|
||||
// Create links to all listed items.
|
||||
void LLAppearanceMgr::linkAll(const LLUUID& cat_uuid,
|
||||
LLInventoryModel::item_array_t& items,
|
||||
LLPointer<LLInventoryCallback> cb)
|
||||
LLInventoryModel::item_array_t& items,
|
||||
LLPointer<LLInventoryCallback> cb)
|
||||
{
|
||||
for (S32 i=0; i<items.count(); i++)
|
||||
{
|
||||
|
|
@ -1408,7 +1442,7 @@ void LLAppearanceMgr::linkAll(const LLUUID& cat_uuid,
|
|||
const LLViewerInventoryCategory *cat = gInventory.getCategory(cat_uuid);
|
||||
const std::string cat_name = cat ? cat->getName() : "CAT NOT FOUND";
|
||||
#ifndef LL_RELEASE_FOR_DOWNLOAD
|
||||
llinfos << "Linking Item [ name:" << item->getName() << " UUID:" << item->getUUID() << " ] to Category [ name:" << cat_name << " UUID:" << cat_uuid << " ] " << llendl;
|
||||
LL_DEBUGS("Avatar") << self_av_string() << "Linking Item [ name:" << item->getName() << " UUID:" << item->getUUID() << " ] to Category [ name:" << cat_name << " UUID:" << cat_uuid << " ] " << LL_ENDL;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
|
@ -1416,7 +1450,7 @@ void LLAppearanceMgr::linkAll(const LLUUID& cat_uuid,
|
|||
void LLAppearanceMgr::updateCOF(const LLUUID& category, bool append)
|
||||
{
|
||||
LLViewerInventoryCategory *pcat = gInventory.getCategory(category);
|
||||
llinfos << "starting, cat " << (pcat ? pcat->getName() : "[UNKNOWN]") << llendl;
|
||||
LL_INFOS("Avatar") << self_av_string() << "starting, cat '" << (pcat ? pcat->getName() : "[UNKNOWN]") << "'" << LL_ENDL;
|
||||
|
||||
const LLUUID cof = getCOF();
|
||||
|
||||
|
|
@ -1478,26 +1512,26 @@ void LLAppearanceMgr::updateCOF(const LLUUID& category, bool append)
|
|||
gInventory.notifyObservers();
|
||||
|
||||
// Create links to new COF contents.
|
||||
llinfos << "creating LLUpdateAppearanceOnDestroy" << llendl;
|
||||
LL_DEBUGS("Avatar") << self_av_string() << "creating LLUpdateAppearanceOnDestroy" << LL_ENDL;
|
||||
LLPointer<LLInventoryCallback> link_waiter = new LLUpdateAppearanceOnDestroy(!append);
|
||||
|
||||
#ifndef LL_RELEASE_FOR_DOWNLOAD
|
||||
llinfos << "Linking body items" << llendl;
|
||||
LL_DEBUGS("Avatar") << self_av_string() << "Linking body items" << LL_ENDL;
|
||||
#endif
|
||||
linkAll(cof, body_items, link_waiter);
|
||||
|
||||
#ifndef LL_RELEASE_FOR_DOWNLOAD
|
||||
llinfos << "Linking wear items" << llendl;
|
||||
LL_DEBUGS("Avatar") << self_av_string() << "Linking wear items" << LL_ENDL;
|
||||
#endif
|
||||
linkAll(cof, wear_items, link_waiter);
|
||||
|
||||
#ifndef LL_RELEASE_FOR_DOWNLOAD
|
||||
llinfos << "Linking obj items" << llendl;
|
||||
LL_DEBUGS("Avatar") << self_av_string() << "Linking obj items" << LL_ENDL;
|
||||
#endif
|
||||
linkAll(cof, obj_items, link_waiter);
|
||||
|
||||
#ifndef LL_RELEASE_FOR_DOWNLOAD
|
||||
llinfos << "Linking gesture items" << llendl;
|
||||
LL_DEBUGS("Avatar") << self_av_string() << "Linking gesture items" << LL_ENDL;
|
||||
#endif
|
||||
linkAll(cof, gest_items, link_waiter);
|
||||
|
||||
|
|
@ -1506,7 +1540,7 @@ void LLAppearanceMgr::updateCOF(const LLUUID& category, bool append)
|
|||
{
|
||||
createBaseOutfitLink(category, link_waiter);
|
||||
}
|
||||
llinfos << "waiting for LLUpdateAppearanceOnDestroy" << llendl;
|
||||
LL_DEBUGS("Avatar") << self_av_string() << "waiting for LLUpdateAppearanceOnDestroy" << LL_ENDL;
|
||||
}
|
||||
|
||||
void LLAppearanceMgr::updatePanelOutfitName(const std::string& name)
|
||||
|
|
@ -1663,7 +1697,7 @@ void LLAppearanceMgr::enforceItemRestrictions()
|
|||
++it)
|
||||
{
|
||||
LLViewerInventoryItem *item = *it;
|
||||
llinfos << "purging duplicate or excess item " << item->getName() << llendl;
|
||||
LL_DEBUGS("Avatar") << self_av_string() << "purging duplicate or excess item " << item->getName() << LL_ENDL;
|
||||
gInventory.purgeObject(item->getUUID());
|
||||
}
|
||||
gInventory.notifyObservers();
|
||||
|
|
@ -1678,9 +1712,11 @@ void LLAppearanceMgr::updateAppearanceFromCOF(bool update_base_outfit_ordering)
|
|||
return;
|
||||
}
|
||||
|
||||
LLVOAvatar::ScopedPhaseSetter(gAgentAvatarp,"update_appearance_from_cof");
|
||||
|
||||
BoolSetter setIsInUpdateAppearanceFromCOF(mIsInUpdateAppearanceFromCOF);
|
||||
|
||||
llinfos << "starting" << llendl;
|
||||
LL_INFOS("Avatar") << self_av_string() << "starting" << LL_ENDL;
|
||||
|
||||
//checking integrity of the COF in terms of ordering of wearables,
|
||||
//checking and updating links' descriptions of wearables in the COF (before analyzed for "dirty" state)
|
||||
|
|
@ -1772,12 +1808,14 @@ void LLAppearanceMgr::updateAppearanceFromCOF(bool update_base_outfit_ordering)
|
|||
}
|
||||
}
|
||||
|
||||
selfStartPhase("get_wearables");
|
||||
|
||||
for (LLWearableHoldingPattern::found_list_t::iterator it = holder->getFoundList().begin();
|
||||
it != holder->getFoundList().end(); ++it)
|
||||
{
|
||||
LLFoundData& found = *it;
|
||||
|
||||
lldebugs << "waiting for onWearableAssetFetch callback, asset " << found.mAssetID.asString() << llendl;
|
||||
lldebugs << self_av_string() << "waiting for onWearableAssetFetch callback, asset " << found.mAssetID.asString() << llendl;
|
||||
|
||||
// Fetch the wearables about to be worn.
|
||||
LLWearableList::instance().getAsset(found.mAssetID,
|
||||
|
|
@ -1849,11 +1887,15 @@ void LLAppearanceMgr::wearInventoryCategory(LLInventoryCategory* category, bool
|
|||
{
|
||||
if(!category) return;
|
||||
|
||||
selfClearPhases();
|
||||
selfStartPhase("wear_inventory_category");
|
||||
|
||||
gAgentWearables.notifyLoadingStarted();
|
||||
|
||||
llinfos << "wearInventoryCategory( " << category->getName()
|
||||
<< " )" << llendl;
|
||||
LL_INFOS("Avatar") << self_av_string() << "wearInventoryCategory( " << category->getName()
|
||||
<< " )" << LL_ENDL;
|
||||
|
||||
selfStartPhase("wear_inventory_category_fetch");
|
||||
callAfterCategoryFetch(category->getUUID(),boost::bind(&LLAppearanceMgr::wearCategoryFinal,
|
||||
&LLAppearanceMgr::instance(),
|
||||
category->getUUID(), copy, append));
|
||||
|
|
@ -1861,7 +1903,9 @@ void LLAppearanceMgr::wearInventoryCategory(LLInventoryCategory* category, bool
|
|||
|
||||
void LLAppearanceMgr::wearCategoryFinal(LLUUID& cat_id, bool copy_items, bool append)
|
||||
{
|
||||
llinfos << "starting" << llendl;
|
||||
LL_INFOS("Avatar") << self_av_string() << "starting" << LL_ENDL;
|
||||
|
||||
selfStopPhase("wear_inventory_category_fetch");
|
||||
|
||||
// We now have an outfit ready to be copied to agent inventory. Do
|
||||
// it, and wear that outfit normally.
|
||||
|
|
@ -1944,8 +1988,8 @@ void LLAppearanceMgr::wearInventoryCategoryOnAvatar( LLInventoryCategory* catego
|
|||
// wearables being dirty.
|
||||
if(!category) return;
|
||||
|
||||
llinfos << "wearInventoryCategoryOnAvatar( " << category->getName()
|
||||
<< " )" << llendl;
|
||||
LL_INFOS("Avatar") << self_av_string() << "wearInventoryCategoryOnAvatar '" << category->getName()
|
||||
<< "'" << LL_ENDL;
|
||||
|
||||
if (gAgentCamera.cameraCustomizeAvatar())
|
||||
{
|
||||
|
|
@ -1958,7 +2002,7 @@ void LLAppearanceMgr::wearInventoryCategoryOnAvatar( LLInventoryCategory* catego
|
|||
|
||||
void LLAppearanceMgr::wearOutfitByName(const std::string& name)
|
||||
{
|
||||
llinfos << "Wearing category " << name << llendl;
|
||||
LL_INFOS("Avatar") << self_av_string() << "Wearing category " << name << LL_ENDL;
|
||||
//inc_busy_count();
|
||||
|
||||
LLInventoryModel::cat_array_t cat_array;
|
||||
|
|
@ -2281,7 +2325,7 @@ const std::string OTHER_GESTURES_FOLDER = "Other Gestures";
|
|||
|
||||
void LLAppearanceMgr::copyLibraryGestures()
|
||||
{
|
||||
llinfos << "Copying library gestures" << llendl;
|
||||
LL_INFOS("Avatar") << self_av_string() << "Copying library gestures" << LL_ENDL;
|
||||
|
||||
// Copy gestures
|
||||
LLUUID lib_gesture_cat_id =
|
||||
|
|
@ -2337,11 +2381,11 @@ void LLAppearanceMgr::copyLibraryGestures()
|
|||
LLUUID cat_id = findDescendentCategoryIDByName(lib_gesture_cat_id,folder_name);
|
||||
if (cat_id.isNull())
|
||||
{
|
||||
llwarns << "failed to find gesture folder for " << folder_name << llendl;
|
||||
llwarns << self_av_string() << "failed to find gesture folder for " << folder_name << llendl;
|
||||
}
|
||||
else
|
||||
{
|
||||
llinfos << "initiating fetch and copy for " << folder_name << " cat_id " << cat_id << llendl;
|
||||
LL_DEBUGS("Avatar") << self_av_string() << "initiating fetch and copy for " << folder_name << " cat_id " << cat_id << LL_ENDL;
|
||||
callAfterCategoryFetch(cat_id,
|
||||
boost::bind(&LLAppearanceMgr::shallowCopyCategory,
|
||||
&LLAppearanceMgr::instance(),
|
||||
|
|
@ -2355,7 +2399,7 @@ void LLAppearanceMgr::autopopulateOutfits()
|
|||
// If this is the very first time the user has logged into viewer2+ (from a legacy viewer, or new account)
|
||||
// then auto-populate outfits from the library into the My Outfits folder.
|
||||
|
||||
llinfos << "avatar fully visible" << llendl;
|
||||
LL_INFOS("Avatar") << self_av_string() << "avatar fully visible" << LL_ENDL;
|
||||
|
||||
static bool check_populate_my_outfits = true;
|
||||
if (check_populate_my_outfits &&
|
||||
|
|
@ -2731,7 +2775,7 @@ void LLAppearanceMgr::dumpCat(const LLUUID& cat_id, const std::string& msg)
|
|||
}
|
||||
|
||||
void LLAppearanceMgr::dumpItemArray(const LLInventoryModel::item_array_t& items,
|
||||
const std::string& msg)
|
||||
const std::string& msg)
|
||||
{
|
||||
for (S32 i=0; i<items.count(); i++)
|
||||
{
|
||||
|
|
@ -2742,9 +2786,8 @@ void LLAppearanceMgr::dumpItemArray(const LLInventoryModel::item_array_t& items,
|
|||
{
|
||||
asset_id = linked_item->getAssetUUID();
|
||||
}
|
||||
llinfos << msg << " " << i <<" " << (item ? item->getName() : "(nullitem)") << " " << asset_id.asString() << llendl;
|
||||
LL_DEBUGS("Avatar") << self_av_string() << msg << " " << i <<" " << (item ? item->getName() : "(nullitem)") << " " << asset_id.asString() << LL_ENDL;
|
||||
}
|
||||
llinfos << llendl;
|
||||
}
|
||||
|
||||
LLAppearanceMgr::LLAppearanceMgr():
|
||||
|
|
|
|||
|
|
@ -93,6 +93,7 @@
|
|||
#include "llsecondlifeurls.h"
|
||||
#include "llupdaterservice.h"
|
||||
#include "llcallfloater.h"
|
||||
#include "llfloatertexturefetchdebugger.h"
|
||||
|
||||
// Linden library includes
|
||||
#include "llavatarnamecache.h"
|
||||
|
|
@ -560,7 +561,6 @@ static void settings_modify()
|
|||
LLVOSurfacePatch::sLODFactor *= LLVOSurfacePatch::sLODFactor; //square lod factor to get exponential range of [1,4]
|
||||
gDebugGL = gSavedSettings.getBOOL("RenderDebugGL") || gDebugSession;
|
||||
gDebugPipeline = gSavedSettings.getBOOL("RenderDebugPipeline");
|
||||
gAuditTexture = gSavedSettings.getBOOL("AuditTexture");
|
||||
}
|
||||
|
||||
class LLFastTimerLogThread : public LLThread
|
||||
|
|
@ -731,12 +731,12 @@ bool LLAppViewer::init()
|
|||
|
||||
{
|
||||
// Viewer metrics initialization
|
||||
static LLCachedControl<bool> metrics_submode(gSavedSettings,
|
||||
"QAModeMetrics",
|
||||
false,
|
||||
"Enables QA features (logging, faster cycling) for metrics collector");
|
||||
//static LLCachedControl<bool> metrics_submode(gSavedSettings,
|
||||
// "QAModeMetrics",
|
||||
// false,
|
||||
// "Enables QA features (logging, faster cycling) for metrics collector");
|
||||
|
||||
if (metrics_submode)
|
||||
if (gSavedSettings.getBOOL("QAModeMetrics"))
|
||||
{
|
||||
app_metrics_qa_mode = true;
|
||||
app_metrics_interval = METRICS_INTERVAL_QA;
|
||||
|
|
@ -1219,7 +1219,7 @@ bool LLAppViewer::mainLoop()
|
|||
if(mem_leak_instance)
|
||||
{
|
||||
mem_leak_instance->idle() ;
|
||||
}
|
||||
}
|
||||
|
||||
// canonical per-frame event
|
||||
mainloop.post(newFrame);
|
||||
|
|
@ -1340,13 +1340,11 @@ bool LLAppViewer::mainLoop()
|
|||
ms_sleep(500);
|
||||
}
|
||||
|
||||
static const F64 FRAME_SLOW_THRESHOLD = 0.5; //2 frames per seconds
|
||||
const F64 max_idle_time = llmin(.005*10.0*gFrameTimeSeconds, 0.005); // 5 ms a second
|
||||
idleTimer.reset();
|
||||
bool is_slow = (frameTimer.getElapsedTimeF64() > FRAME_SLOW_THRESHOLD) ;
|
||||
S32 total_work_pending = 0;
|
||||
S32 total_io_pending = 0;
|
||||
while(!is_slow)//do not unpause threads if the frame rates are very low.
|
||||
while(1)
|
||||
{
|
||||
S32 work_pending = 0;
|
||||
S32 io_pending = 0;
|
||||
|
|
@ -1406,6 +1404,17 @@ bool LLAppViewer::mainLoop()
|
|||
LLLFSThread::sLocal->pause();
|
||||
}
|
||||
|
||||
//texture fetching debugger
|
||||
if(LLTextureFetchDebugger::isEnabled())
|
||||
{
|
||||
LLFloaterTextureFetchDebugger* tex_fetch_debugger_instance =
|
||||
LLFloaterReg::findTypedInstance<LLFloaterTextureFetchDebugger>("tex_fetch_debugger");
|
||||
if(tex_fetch_debugger_instance)
|
||||
{
|
||||
tex_fetch_debugger_instance->idle() ;
|
||||
}
|
||||
}
|
||||
|
||||
if ((LLStartUp::getStartupState() >= STATE_CLEANUP) &&
|
||||
(frameTimer.getElapsedTimeF64() > FRAME_STALL_THRESHOLD))
|
||||
{
|
||||
|
|
@ -1951,7 +1960,7 @@ bool LLAppViewer::initThreads()
|
|||
static const bool enable_threads = true;
|
||||
#endif
|
||||
|
||||
LLImage::initClass();
|
||||
LLImage::initClass(gSavedSettings.getBOOL("TextureNewByteRange"),gSavedSettings.getS32("TextureReverseByteRange"));
|
||||
|
||||
LLVFSThread::initClass(enable_threads && false);
|
||||
LLLFSThread::initClass(enable_threads && false);
|
||||
|
|
@ -4201,6 +4210,7 @@ void LLAppViewer::idle()
|
|||
// The 5-second interval is nice for this purpose. If the object debug
|
||||
// bit moves or is disabled, please give this a suitable home.
|
||||
LLViewerAssetStatsFF::record_fps_main(gFPSClamped);
|
||||
LLViewerAssetStatsFF::record_avatar_stats();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -4248,7 +4258,8 @@ void LLAppViewer::idle()
|
|||
static LLTimer report_interval;
|
||||
|
||||
// *TODO: Add configuration controls for this
|
||||
if (report_interval.getElapsedTimeF32() >= app_metrics_interval)
|
||||
F32 seconds = report_interval.getElapsedTimeF32();
|
||||
if (seconds >= app_metrics_interval)
|
||||
{
|
||||
metricsSend(! gDisconnected);
|
||||
report_interval.reset();
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@
|
|||
#include "llagentpicksinfo.h"
|
||||
#include "lldateutil.h"
|
||||
#include "llviewergenericmessage.h"
|
||||
#include "llstartup.h"
|
||||
|
||||
// Linden library includes
|
||||
#include "llavatarconstants.h" // AVATAR_TRANSACTED, etc.
|
||||
|
|
@ -113,6 +114,14 @@ void LLAvatarPropertiesProcessor::sendGenericRequest(const LLUUID& avatar_id, EA
|
|||
|
||||
void LLAvatarPropertiesProcessor::sendAvatarPropertiesRequest(const LLUUID& avatar_id)
|
||||
{
|
||||
// this is the startup state when send_complete_agent_movement() message is sent.
|
||||
// Before this, the AvatarPropertiesRequest message
|
||||
// won't work so don't bother trying
|
||||
if (LLStartUp::getStartupState() <= STATE_AGENT_SEND)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (isPendingRequest(avatar_id, APT_PROPERTIES))
|
||||
{
|
||||
// waiting for a response, don't re-request
|
||||
|
|
|
|||
|
|
@ -68,8 +68,6 @@ LLDebugView::~LLDebugView()
|
|||
gDebugView = NULL;
|
||||
gTextureView = NULL;
|
||||
gSceneView = NULL;
|
||||
gTextureSizeView = NULL;
|
||||
gTextureCategoryView = NULL;
|
||||
}
|
||||
|
||||
void LLDebugView::init()
|
||||
|
|
@ -117,35 +115,11 @@ void LLDebugView::init()
|
|||
LLTextureView::Params tvp;
|
||||
tvp.name("gTextureView");
|
||||
tvp.rect(r);
|
||||
tvp.follows.flags(FOLLOWS_BOTTOM|FOLLOWS_LEFT);
|
||||
tvp.follows.flags(FOLLOWS_TOP|FOLLOWS_LEFT);
|
||||
tvp.visible(false);
|
||||
gTextureView = LLUICtrlFactory::create<LLTextureView>(tvp);
|
||||
addChild(gTextureView);
|
||||
//gTextureView->reshape(r.getWidth(), r.getHeight(), TRUE);
|
||||
|
||||
|
||||
if(gAuditTexture)
|
||||
{
|
||||
r.set(150, rect.getHeight() - 50, 900 + LLImageGL::sTextureLoadedCounter.size() * 30, 100);
|
||||
LLTextureSizeView::Params tsv ;
|
||||
tsv.name("gTextureSizeView");
|
||||
tsv.rect(r);
|
||||
tsv.follows.flags(FOLLOWS_BOTTOM|FOLLOWS_LEFT);
|
||||
tsv.visible(false);
|
||||
gTextureSizeView = LLUICtrlFactory::create<LLTextureSizeView>(tsv);
|
||||
addChild(gTextureSizeView);
|
||||
gTextureSizeView->setType(LLTextureSizeView::TEXTURE_MEM_OVER_SIZE) ;
|
||||
|
||||
r.set(150, rect.getHeight() - 50, 900 + LLViewerTexture::getTotalNumOfCategories() * 30, 100);
|
||||
LLTextureSizeView::Params tcv ;
|
||||
tcv.name("gTextureCategoryView");
|
||||
tcv.rect(r);
|
||||
tcv.follows.flags(FOLLOWS_BOTTOM|FOLLOWS_LEFT);
|
||||
tcv.visible(false);
|
||||
gTextureCategoryView = LLUICtrlFactory::create<LLTextureSizeView>(tcv);
|
||||
gTextureCategoryView->setType(LLTextureSizeView::TEXTURE_MEM_OVER_CATEGORY);
|
||||
addChild(gTextureCategoryView);
|
||||
}
|
||||
}
|
||||
|
||||
void LLDebugView::draw()
|
||||
|
|
|
|||
|
|
@ -0,0 +1,390 @@
|
|||
/**
|
||||
* @file llfloatertexturefetchdebugger.cpp
|
||||
* @brief LLFloaterTextureFetchDebugger class definition
|
||||
*
|
||||
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2010, Linden Research, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#include "llviewerprecompiledheaders.h"
|
||||
|
||||
#include "llfloatertexturefetchdebugger.h"
|
||||
|
||||
#include "lluictrlfactory.h"
|
||||
#include "llbutton.h"
|
||||
#include "llspinctrl.h"
|
||||
#include "llresmgr.h"
|
||||
|
||||
#include "llmath.h"
|
||||
#include "llviewerwindow.h"
|
||||
#include "llappviewer.h"
|
||||
#include "lltexturefetch.h"
|
||||
#include "llviewercontrol.h"
|
||||
|
||||
LLFloaterTextureFetchDebugger::LLFloaterTextureFetchDebugger(const LLSD& key)
|
||||
: LLFloater(key),
|
||||
mDebugger(NULL)
|
||||
{
|
||||
setTitle("Texture Fetching Debugger Floater");
|
||||
|
||||
mCommitCallbackRegistrar.add("TexFetchDebugger.ChangeTexelPixelRatio", boost::bind(&LLFloaterTextureFetchDebugger::onChangeTexelPixelRatio, this));
|
||||
|
||||
mCommitCallbackRegistrar.add("TexFetchDebugger.Start", boost::bind(&LLFloaterTextureFetchDebugger::onClickStart, this));
|
||||
mCommitCallbackRegistrar.add("TexFetchDebugger.Clear", boost::bind(&LLFloaterTextureFetchDebugger::onClickClear, this));
|
||||
mCommitCallbackRegistrar.add("TexFetchDebugger.Close", boost::bind(&LLFloaterTextureFetchDebugger::onClickClose, this));
|
||||
|
||||
mCommitCallbackRegistrar.add("TexFetchDebugger.CacheRead", boost::bind(&LLFloaterTextureFetchDebugger::onClickCacheRead, this));
|
||||
mCommitCallbackRegistrar.add("TexFetchDebugger.CacheWrite", boost::bind(&LLFloaterTextureFetchDebugger::onClickCacheWrite, this));
|
||||
mCommitCallbackRegistrar.add("TexFetchDebugger.HTTPLoad", boost::bind(&LLFloaterTextureFetchDebugger::onClickHTTPLoad, this));
|
||||
mCommitCallbackRegistrar.add("TexFetchDebugger.Decode", boost::bind(&LLFloaterTextureFetchDebugger::onClickDecode, this));
|
||||
mCommitCallbackRegistrar.add("TexFetchDebugger.GLTexture", boost::bind(&LLFloaterTextureFetchDebugger::onClickGLTexture, this));
|
||||
|
||||
mCommitCallbackRegistrar.add("TexFetchDebugger.RefetchVisCache", boost::bind(&LLFloaterTextureFetchDebugger::onClickRefetchVisCache, this));
|
||||
mCommitCallbackRegistrar.add("TexFetchDebugger.RefetchVisHTTP", boost::bind(&LLFloaterTextureFetchDebugger::onClickRefetchVisHTTP, this));
|
||||
}
|
||||
//----------------------------------------------
|
||||
|
||||
BOOL LLFloaterTextureFetchDebugger::postBuild(void)
|
||||
{
|
||||
mDebugger = LLAppViewer::getTextureFetch()->getFetchDebugger();
|
||||
|
||||
//set states for buttons
|
||||
mButtonStateMap["start_btn"] = true;
|
||||
mButtonStateMap["close_btn"] = true;
|
||||
mButtonStateMap["clear_btn"] = true;
|
||||
mButtonStateMap["cacheread_btn"] = false;
|
||||
mButtonStateMap["cachewrite_btn"] = false;
|
||||
mButtonStateMap["http_btn"] = false;
|
||||
mButtonStateMap["decode_btn"] = false;
|
||||
mButtonStateMap["gl_btn"] = false;
|
||||
|
||||
mButtonStateMap["refetchviscache_btn"] = true;
|
||||
mButtonStateMap["refetchvishttp_btn"] = true;
|
||||
|
||||
updateButtons();
|
||||
|
||||
getChild<LLUICtrl>("texel_pixel_ratio")->setValue(gSavedSettings.getF32("TexelPixelRatio"));
|
||||
|
||||
return TRUE ;
|
||||
}
|
||||
|
||||
LLFloaterTextureFetchDebugger::~LLFloaterTextureFetchDebugger()
|
||||
{
|
||||
//stop everything
|
||||
mDebugger->stopDebug();
|
||||
}
|
||||
|
||||
void LLFloaterTextureFetchDebugger::updateButtons()
|
||||
{
|
||||
for(std::map<std::string, bool>::iterator iter = mButtonStateMap.begin(); iter != mButtonStateMap.end(); ++iter)
|
||||
{
|
||||
if(iter->second)
|
||||
{
|
||||
childEnable(iter->first.c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
childDisable(iter->first.c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LLFloaterTextureFetchDebugger::disableButtons()
|
||||
{
|
||||
childDisable("start_btn");
|
||||
childDisable("clear_btn");
|
||||
childDisable("cacheread_btn");
|
||||
childDisable("cachewrite_btn");
|
||||
childDisable("http_btn");
|
||||
childDisable("decode_btn");
|
||||
childDisable("gl_btn");
|
||||
childDisable("refetchviscache_btn");
|
||||
childDisable("refetchvishttp_btn");
|
||||
}
|
||||
|
||||
void LLFloaterTextureFetchDebugger::idle()
|
||||
{
|
||||
LLTextureFetchDebugger::e_debug_state state = mDebugger->getState();
|
||||
|
||||
if(mDebugger->update())
|
||||
{
|
||||
switch(state)
|
||||
{
|
||||
case LLTextureFetchDebugger::IDLE:
|
||||
break;
|
||||
case LLTextureFetchDebugger::READ_CACHE:
|
||||
mButtonStateMap["cachewrite_btn"] = true;
|
||||
mButtonStateMap["decode_btn"] = true;
|
||||
updateButtons();
|
||||
break;
|
||||
case LLTextureFetchDebugger::WRITE_CACHE:
|
||||
updateButtons();
|
||||
break;
|
||||
case LLTextureFetchDebugger::DECODING:
|
||||
mButtonStateMap["gl_btn"] = true;
|
||||
updateButtons();
|
||||
break;
|
||||
case LLTextureFetchDebugger::HTTP_FETCHING:
|
||||
mButtonStateMap["cacheread_btn"] = true;
|
||||
mButtonStateMap["cachewrite_btn"] = true;
|
||||
mButtonStateMap["decode_btn"] = true;
|
||||
updateButtons();
|
||||
break;
|
||||
case LLTextureFetchDebugger::GL_TEX:
|
||||
updateButtons();
|
||||
break;
|
||||
case LLTextureFetchDebugger::REFETCH_VIS_CACHE:
|
||||
updateButtons();
|
||||
case LLTextureFetchDebugger::REFETCH_VIS_HTTP:
|
||||
updateButtons();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------
|
||||
void LLFloaterTextureFetchDebugger::onChangeTexelPixelRatio()
|
||||
{
|
||||
gSavedSettings.setF32("TexelPixelRatio", getChild<LLUICtrl>("texel_pixel_ratio")->getValue().asReal());
|
||||
}
|
||||
|
||||
void LLFloaterTextureFetchDebugger::onClickStart()
|
||||
{
|
||||
disableButtons();
|
||||
|
||||
mDebugger->startDebug();
|
||||
|
||||
mButtonStateMap["start_btn"] = false;
|
||||
mButtonStateMap["cacheread_btn"] = true;
|
||||
mButtonStateMap["http_btn"] = true;
|
||||
updateButtons();
|
||||
}
|
||||
|
||||
void LLFloaterTextureFetchDebugger::onClickClose()
|
||||
{
|
||||
setVisible(FALSE);
|
||||
|
||||
//stop everything
|
||||
mDebugger->stopDebug();
|
||||
}
|
||||
|
||||
void LLFloaterTextureFetchDebugger::onClickClear()
|
||||
{
|
||||
mButtonStateMap["start_btn"] = true;
|
||||
mButtonStateMap["close_btn"] = true;
|
||||
mButtonStateMap["clear_btn"] = true;
|
||||
mButtonStateMap["cacheread_btn"] = false;
|
||||
mButtonStateMap["cachewrite_btn"] = false;
|
||||
mButtonStateMap["http_btn"] = false;
|
||||
mButtonStateMap["decode_btn"] = false;
|
||||
mButtonStateMap["gl_btn"] = false;
|
||||
mButtonStateMap["refetchviscache_btn"] = true;
|
||||
mButtonStateMap["refetchvishttp_btn"] = true;
|
||||
updateButtons();
|
||||
|
||||
//stop everything
|
||||
mDebugger->stopDebug();
|
||||
mDebugger->clearHistory();
|
||||
}
|
||||
|
||||
void LLFloaterTextureFetchDebugger::onClickCacheRead()
|
||||
{
|
||||
disableButtons();
|
||||
|
||||
mDebugger->debugCacheRead();
|
||||
}
|
||||
|
||||
void LLFloaterTextureFetchDebugger::onClickCacheWrite()
|
||||
{
|
||||
disableButtons();
|
||||
|
||||
mDebugger->debugCacheWrite();
|
||||
}
|
||||
|
||||
void LLFloaterTextureFetchDebugger::onClickHTTPLoad()
|
||||
{
|
||||
disableButtons();
|
||||
|
||||
mDebugger->debugHTTP();
|
||||
}
|
||||
|
||||
void LLFloaterTextureFetchDebugger::onClickDecode()
|
||||
{
|
||||
disableButtons();
|
||||
|
||||
mDebugger->debugDecoder();
|
||||
}
|
||||
|
||||
void LLFloaterTextureFetchDebugger::onClickGLTexture()
|
||||
{
|
||||
disableButtons();
|
||||
|
||||
mDebugger->debugGLTextureCreation();
|
||||
}
|
||||
|
||||
void LLFloaterTextureFetchDebugger::onClickRefetchVisCache()
|
||||
{
|
||||
disableButtons();
|
||||
|
||||
mDebugger->debugRefetchVisibleFromCache();
|
||||
}
|
||||
|
||||
void LLFloaterTextureFetchDebugger::onClickRefetchVisHTTP()
|
||||
{
|
||||
disableButtons();
|
||||
|
||||
mDebugger->debugRefetchVisibleFromHTTP();
|
||||
}
|
||||
|
||||
void LLFloaterTextureFetchDebugger::draw()
|
||||
{
|
||||
//total number of fetched textures
|
||||
{
|
||||
getChild<LLUICtrl>("total_num_fetched_label")->setTextArg("[NUM]", llformat("%d", mDebugger->getNumFetchedTextures()));
|
||||
}
|
||||
|
||||
//total number of fetching requests
|
||||
{
|
||||
getChild<LLUICtrl>("total_num_fetching_requests_label")->setTextArg("[NUM]", llformat("%d", mDebugger->getNumFetchingRequests()));
|
||||
}
|
||||
|
||||
//total number of cache hits
|
||||
{
|
||||
getChild<LLUICtrl>("total_num_cache_hits_label")->setTextArg("[NUM]", llformat("%d", mDebugger->getNumCacheHits()));
|
||||
}
|
||||
|
||||
//total number of visible textures
|
||||
{
|
||||
getChild<LLUICtrl>("total_num_visible_tex_label")->setTextArg("[NUM]", llformat("%d", mDebugger->getNumVisibleFetchedTextures()));
|
||||
}
|
||||
|
||||
//total number of visible texture fetching requests
|
||||
{
|
||||
getChild<LLUICtrl>("total_num_visible_tex_fetch_req_label")->setTextArg("[NUM]", llformat("%d", mDebugger->getNumVisibleFetchingRequests()));
|
||||
}
|
||||
|
||||
//total number of fetched data
|
||||
{
|
||||
getChild<LLUICtrl>("total_fetched_data_label")->setTextArg("[SIZE1]", llformat("%d", mDebugger->getFetchedData() >> 10));
|
||||
getChild<LLUICtrl>("total_fetched_data_label")->setTextArg("[SIZE2]", llformat("%d", mDebugger->getDecodedData() >> 10));
|
||||
getChild<LLUICtrl>("total_fetched_data_label")->setTextArg("[PIXEL]", llformat("%.3f", mDebugger->getFetchedPixels() / 1000000.f));
|
||||
}
|
||||
|
||||
//total number of visible fetched data
|
||||
{
|
||||
getChild<LLUICtrl>("total_fetched_vis_data_label")->setTextArg("[SIZE1]", llformat("%d", mDebugger->getVisibleFetchedData() >> 10));
|
||||
getChild<LLUICtrl>("total_fetched_vis_data_label")->setTextArg("[SIZE2]", llformat("%d", mDebugger->getVisibleDecodedData() >> 10));
|
||||
}
|
||||
|
||||
//total number of rendered fetched data
|
||||
{
|
||||
getChild<LLUICtrl>("total_fetched_rendered_data_label")->setTextArg("[SIZE1]", llformat("%d", mDebugger->getRenderedData() >> 10));
|
||||
getChild<LLUICtrl>("total_fetched_rendered_data_label")->setTextArg("[SIZE2]", llformat("%d", mDebugger->getRenderedDecodedData() >> 10));
|
||||
getChild<LLUICtrl>("total_fetched_rendered_data_label")->setTextArg("[PIXEL]", llformat("%.3f", mDebugger->getRenderedPixels() / 1000000.f));
|
||||
}
|
||||
|
||||
//total time on cache readings
|
||||
if(mDebugger->getCacheReadTime() < 0.f)
|
||||
{
|
||||
getChild<LLUICtrl>("total_time_cache_read_label")->setTextArg("[TIME]", std::string("----"));
|
||||
}
|
||||
else
|
||||
{
|
||||
getChild<LLUICtrl>("total_time_cache_read_label")->setTextArg("[TIME]", llformat("%.3f", mDebugger->getCacheReadTime()));
|
||||
}
|
||||
|
||||
//total time on cache writings
|
||||
if(mDebugger->getCacheWriteTime() < 0.f)
|
||||
{
|
||||
getChild<LLUICtrl>("total_time_cache_write_label")->setTextArg("[TIME]", std::string("----"));
|
||||
}
|
||||
else
|
||||
{
|
||||
getChild<LLUICtrl>("total_time_cache_write_label")->setTextArg("[TIME]", llformat("%.3f", mDebugger->getCacheWriteTime()));
|
||||
}
|
||||
|
||||
//total time on decoding
|
||||
if(mDebugger->getDecodeTime() < 0.f)
|
||||
{
|
||||
getChild<LLUICtrl>("total_time_decode_label")->setTextArg("[TIME]", std::string("----"));
|
||||
}
|
||||
else
|
||||
{
|
||||
getChild<LLUICtrl>("total_time_decode_label")->setTextArg("[TIME]", llformat("%.3f", mDebugger->getDecodeTime()));
|
||||
}
|
||||
|
||||
//total time on gl texture creation
|
||||
if(mDebugger->getGLCreationTime() < 0.f)
|
||||
{
|
||||
getChild<LLUICtrl>("total_time_gl_label")->setTextArg("[TIME]", std::string("----"));
|
||||
}
|
||||
else
|
||||
{
|
||||
getChild<LLUICtrl>("total_time_gl_label")->setTextArg("[TIME]", llformat("%.3f", mDebugger->getGLCreationTime()));
|
||||
}
|
||||
|
||||
//total time on HTTP fetching
|
||||
if(mDebugger->getHTTPTime() < 0.f)
|
||||
{
|
||||
getChild<LLUICtrl>("total_time_http_label")->setTextArg("[TIME]", std::string("----"));
|
||||
}
|
||||
else
|
||||
{
|
||||
getChild<LLUICtrl>("total_time_http_label")->setTextArg("[TIME]", llformat("%.3f", mDebugger->getHTTPTime()));
|
||||
}
|
||||
|
||||
//total time on entire fetching
|
||||
{
|
||||
getChild<LLUICtrl>("total_time_fetch_label")->setTextArg("[TIME]", llformat("%.3f", mDebugger->getTotalFetchingTime()));
|
||||
}
|
||||
|
||||
//total time on refetching visible textures from cache
|
||||
if(mDebugger->getRefetchVisCacheTime() < 0.f)
|
||||
{
|
||||
getChild<LLUICtrl>("total_time_refetch_vis_cache_label")->setTextArg("[TIME]", std::string("----"));
|
||||
getChild<LLUICtrl>("total_time_refetch_vis_cache_label")->setTextArg("[SIZE]", std::string("----"));
|
||||
getChild<LLUICtrl>("total_time_refetch_vis_cache_label")->setTextArg("[PIXEL]", std::string("----"));
|
||||
}
|
||||
else
|
||||
{
|
||||
getChild<LLUICtrl>("total_time_refetch_vis_cache_label")->setTextArg("[TIME]", llformat("%.3f", mDebugger->getRefetchVisCacheTime()));
|
||||
getChild<LLUICtrl>("total_time_refetch_vis_cache_label")->setTextArg("[SIZE]", llformat("%d", mDebugger->getRefetchedData() >> 10));
|
||||
getChild<LLUICtrl>("total_time_refetch_vis_cache_label")->setTextArg("[PIXEL]", llformat("%.3f", mDebugger->getRefetchedPixels() / 1000000.f));
|
||||
}
|
||||
|
||||
//total time on refetching visible textures from http
|
||||
if(mDebugger->getRefetchVisHTTPTime() < 0.f)
|
||||
{
|
||||
getChild<LLUICtrl>("total_time_refetch_vis_http_label")->setTextArg("[TIME]", std::string("----"));
|
||||
getChild<LLUICtrl>("total_time_refetch_vis_http_label")->setTextArg("[SIZE]", std::string("----"));
|
||||
getChild<LLUICtrl>("total_time_refetch_vis_http_label")->setTextArg("[PIXEL]", std::string("----"));
|
||||
}
|
||||
else
|
||||
{
|
||||
getChild<LLUICtrl>("total_time_refetch_vis_http_label")->setTextArg("[TIME]", llformat("%.3f", mDebugger->getRefetchVisHTTPTime()));
|
||||
getChild<LLUICtrl>("total_time_refetch_vis_http_label")->setTextArg("[SIZE]", llformat("%d", mDebugger->getRefetchedData() >> 10));
|
||||
getChild<LLUICtrl>("total_time_refetch_vis_http_label")->setTextArg("[PIXEL]", llformat("%.3f", mDebugger->getRefetchedPixels() / 1000000.f));
|
||||
}
|
||||
|
||||
LLFloater::draw();
|
||||
}
|
||||
|
|
@ -0,0 +1,71 @@
|
|||
/**
|
||||
* @file llfloatertexturefetchdebugger.h
|
||||
* @brief texture fetching debugger window, debug use only
|
||||
*
|
||||
* $LicenseInfo:firstyear=2004&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2010, Linden Research, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#ifndef LL_FLOATER_TEXTURE_FETCH_DEBUGGER__H
|
||||
#define LL_FLOATER_TEXTURE_FETCH_DEBUGGER__H
|
||||
|
||||
#include "llfloater.h"
|
||||
class LLTextureFetchDebugger;
|
||||
|
||||
class LLFloaterTextureFetchDebugger : public LLFloater
|
||||
{
|
||||
friend class LLFloaterReg;
|
||||
public:
|
||||
/// initialize all the callbacks for the menu
|
||||
|
||||
virtual BOOL postBuild() ;
|
||||
virtual void draw() ;
|
||||
|
||||
void onChangeTexelPixelRatio();
|
||||
|
||||
void onClickStart();
|
||||
void onClickClear();
|
||||
void onClickClose();
|
||||
|
||||
void onClickCacheRead();
|
||||
void onClickCacheWrite();
|
||||
void onClickHTTPLoad();
|
||||
void onClickDecode();
|
||||
void onClickGLTexture();
|
||||
|
||||
void onClickRefetchVisCache();
|
||||
void onClickRefetchVisHTTP();
|
||||
public:
|
||||
void idle() ;
|
||||
|
||||
private:
|
||||
LLFloaterTextureFetchDebugger(const LLSD& key);
|
||||
virtual ~LLFloaterTextureFetchDebugger();
|
||||
|
||||
void updateButtons();
|
||||
void disableButtons();
|
||||
|
||||
private:
|
||||
LLTextureFetchDebugger* mDebugger;
|
||||
std::map<std::string, bool> mButtonStateMap;
|
||||
};
|
||||
|
||||
#endif // LL_FLOATER_TEXTURE_FETCH_DEBUGGER__H
|
||||
|
|
@ -1759,6 +1759,7 @@ bool LLInventoryModel::loadSkeleton(
|
|||
update_map_t child_counts;
|
||||
cat_array_t categories;
|
||||
item_array_t items;
|
||||
item_array_t possible_broken_links;
|
||||
cat_set_t invalid_categories; // Used to mark categories that weren't successfully loaded.
|
||||
std::string owner_id_str;
|
||||
owner_id.toString(owner_id_str);
|
||||
|
|
@ -1807,7 +1808,7 @@ bool LLInventoryModel::loadSkeleton(
|
|||
LLViewerInventoryCategory* tcat = *cit;
|
||||
|
||||
// we can safely ignore anything loaded from file, but
|
||||
// not sent down in the skeleton.
|
||||
// not sent down in the skeleton. Must have been removed from inventory.
|
||||
if(cit == not_cached)
|
||||
{
|
||||
continue;
|
||||
|
|
@ -1845,6 +1846,8 @@ bool LLInventoryModel::loadSkeleton(
|
|||
// Add all the items loaded which are parented to a
|
||||
// category with a correctly cached parent
|
||||
S32 bad_link_count = 0;
|
||||
S32 good_link_count = 0;
|
||||
S32 recovered_link_count = 0;
|
||||
cat_map_t::iterator unparented = mCategoryMap.end();
|
||||
for(item_array_t::const_iterator item_iter = items.begin();
|
||||
item_iter != items.end();
|
||||
|
|
@ -1861,26 +1864,56 @@ bool LLInventoryModel::loadSkeleton(
|
|||
// This can happen if the linked object's baseobj is removed from the cache but the linked object is still in the cache.
|
||||
if (item->getIsBrokenLink())
|
||||
{
|
||||
bad_link_count++;
|
||||
//bad_link_count++;
|
||||
lldebugs << "Attempted to add cached link item without baseobj present ( name: "
|
||||
<< item->getName() << " itemID: " << item->getUUID()
|
||||
<< " assetID: " << item->getAssetUUID()
|
||||
<< " ). Ignoring and invalidating " << cat->getName() << " . " << llendl;
|
||||
invalid_categories.insert(cit->second);
|
||||
possible_broken_links.push_back(item);
|
||||
continue;
|
||||
}
|
||||
else if (item->getIsLinkType())
|
||||
{
|
||||
good_link_count++;
|
||||
}
|
||||
addItem(item);
|
||||
cached_item_count += 1;
|
||||
++child_counts[cat->getUUID()];
|
||||
}
|
||||
}
|
||||
}
|
||||
if (bad_link_count > 0)
|
||||
if (possible_broken_links.size() > 0)
|
||||
{
|
||||
llinfos << "Attempted to add " << bad_link_count
|
||||
<< " cached link items without baseobj present. "
|
||||
<< "The corresponding categories were invalidated." << llendl;
|
||||
for(item_array_t::const_iterator item_iter = possible_broken_links.begin();
|
||||
item_iter != possible_broken_links.end();
|
||||
++item_iter)
|
||||
{
|
||||
LLViewerInventoryItem *item = (*item_iter).get();
|
||||
const cat_map_t::iterator cit = mCategoryMap.find(item->getParentUUID());
|
||||
const LLViewerInventoryCategory* cat = cit->second.get();
|
||||
if (item->getIsBrokenLink())
|
||||
{
|
||||
bad_link_count++;
|
||||
invalid_categories.insert(cit->second);
|
||||
//llinfos << "link still broken: " << item->getName() << " in folder " << cat->getName() << llendl;
|
||||
}
|
||||
else
|
||||
{
|
||||
// was marked as broken because of loading order, its actually fine to load
|
||||
addItem(item);
|
||||
cached_item_count += 1;
|
||||
++child_counts[cat->getUUID()];
|
||||
recovered_link_count++;
|
||||
}
|
||||
}
|
||||
|
||||
llinfos << "Attempted to add " << bad_link_count
|
||||
<< " cached link items without baseobj present. "
|
||||
<< good_link_count << " link items were successfully added. "
|
||||
<< recovered_link_count << " links added in recovery. "
|
||||
<< "The corresponding categories were invalidated." << llendl;
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -2778,7 +2811,7 @@ void LLInventoryModel::processBulkUpdateInventory(LLMessageSystem* msg, void**)
|
|||
{
|
||||
LLPointer<LLViewerInventoryItem> titem = new LLViewerInventoryItem;
|
||||
titem->unpackMessage(msg, _PREHASH_ItemData, i);
|
||||
llinfos << "unpaked item '" << titem->getName() << "' in "
|
||||
llinfos << "unpacked item '" << titem->getName() << "' in "
|
||||
<< titem->getParentUUID() << llendl;
|
||||
U32 callback_id;
|
||||
msg->getU32Fast(_PREHASH_ItemData, _PREHASH_CallbackID, callback_id);
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@
|
|||
|
||||
#include "llfirstuse.h"
|
||||
#include "llnearbychatbar.h"
|
||||
#include "llnearbychatbarlistener.h"
|
||||
#include "llagent.h"
|
||||
#include "llgesturemgr.h"
|
||||
#include "llmultigesture.h"
|
||||
|
|
@ -80,6 +81,7 @@ LLNearbyChatBar::LLNearbyChatBar(const LLSD& key)
|
|||
mExpandedHeight(COLLAPSED_HEIGHT + EXPANDED_HEIGHT)
|
||||
{
|
||||
mSpeakerMgr = LLLocalSpeakerMgr::getInstance();
|
||||
mListener.reset(new LLNearbyChatBarListener(*this));
|
||||
}
|
||||
|
||||
//virtual
|
||||
|
|
|
|||
|
|
@ -35,6 +35,8 @@
|
|||
#include "lloutputmonitorctrl.h"
|
||||
#include "llspeakers.h"
|
||||
|
||||
class LLNearbyChatBarListener;
|
||||
|
||||
class LLNearbyChatBar : public LLFloater
|
||||
{
|
||||
public:
|
||||
|
|
@ -92,6 +94,8 @@ protected:
|
|||
LLLocalSpeakerMgr* mSpeakerMgr;
|
||||
|
||||
S32 mExpandedHeight;
|
||||
|
||||
boost::shared_ptr<LLNearbyChatBarListener> mListener;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -3647,6 +3647,110 @@ void renderShadowFrusta(LLDrawInfo* params)
|
|||
gGL.setSceneBlendType(LLRender::BT_ALPHA);
|
||||
}
|
||||
|
||||
void renderTexelDensity(LLDrawable* drawable)
|
||||
{
|
||||
if (LLViewerTexture::sDebugTexelsMode == LLViewerTexture::DEBUG_TEXELS_OFF
|
||||
|| LLViewerTexture::sCheckerBoardImagep.isNull())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
LLGLEnable _(GL_BLEND);
|
||||
//gObjectFullbrightProgram.bind();
|
||||
|
||||
LLMatrix4 checkerboard_matrix;
|
||||
S32 discard_level = -1;
|
||||
|
||||
for (S32 f = 0; f < drawable->getNumFaces(); f++)
|
||||
{
|
||||
LLFace* facep = drawable->getFace(f);
|
||||
LLVertexBuffer* buffer = facep->getVertexBuffer();
|
||||
LLViewerTexture* texturep = facep->getTexture();
|
||||
|
||||
if (texturep == NULL) continue;
|
||||
|
||||
switch(LLViewerTexture::sDebugTexelsMode)
|
||||
{
|
||||
case LLViewerTexture::DEBUG_TEXELS_CURRENT:
|
||||
discard_level = -1;
|
||||
break;
|
||||
case LLViewerTexture::DEBUG_TEXELS_DESIRED:
|
||||
{
|
||||
LLViewerFetchedTexture* fetched_texturep = dynamic_cast<LLViewerFetchedTexture*>(texturep);
|
||||
discard_level = fetched_texturep ? fetched_texturep->getDesiredDiscardLevel() : -1;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
case LLViewerTexture::DEBUG_TEXELS_FULL:
|
||||
discard_level = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
checkerboard_matrix.initScale(LLVector3(texturep->getWidth(discard_level) / 8, texturep->getHeight(discard_level) / 8, 1.f));
|
||||
|
||||
gGL.getTexUnit(0)->bind(LLViewerTexture::sCheckerBoardImagep, TRUE);
|
||||
gGL.matrixMode(LLRender::MM_TEXTURE);
|
||||
gGL.loadMatrix((GLfloat*)&checkerboard_matrix.mMatrix);
|
||||
|
||||
if (buffer && (facep->getGeomCount() >= 3))
|
||||
{
|
||||
buffer->setBuffer(LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0);
|
||||
U16 start = facep->getGeomStart();
|
||||
U16 end = start + facep->getGeomCount()-1;
|
||||
U32 count = facep->getIndicesCount();
|
||||
U16 offset = facep->getIndicesStart();
|
||||
buffer->drawRange(LLRender::TRIANGLES, start, end, count, offset);
|
||||
}
|
||||
|
||||
gGL.loadIdentity();
|
||||
gGL.matrixMode(LLRender::MM_MODELVIEW);
|
||||
}
|
||||
|
||||
//S32 num_textures = llmax(1, (S32)params->mTextureList.size());
|
||||
|
||||
//for (S32 i = 0; i < num_textures; i++)
|
||||
//{
|
||||
// LLViewerTexture* texturep = params->mTextureList.empty() ? params->mTexture.get() : params->mTextureList[i].get();
|
||||
// if (texturep == NULL) continue;
|
||||
|
||||
// LLMatrix4 checkboard_matrix;
|
||||
// S32 discard_level = -1;
|
||||
// switch(LLViewerTexture::sDebugTexelsMode)
|
||||
// {
|
||||
// case LLViewerTexture::DEBUG_TEXELS_CURRENT:
|
||||
// discard_level = -1;
|
||||
// break;
|
||||
// case LLViewerTexture::DEBUG_TEXELS_DESIRED:
|
||||
// {
|
||||
// LLViewerFetchedTexture* fetched_texturep = dynamic_cast<LLViewerFetchedTexture*>(texturep);
|
||||
// discard_level = fetched_texturep ? fetched_texturep->getDesiredDiscardLevel() : -1;
|
||||
// break;
|
||||
// }
|
||||
// default:
|
||||
// case LLViewerTexture::DEBUG_TEXELS_FULL:
|
||||
// discard_level = 0;
|
||||
// break;
|
||||
// }
|
||||
|
||||
// checkboard_matrix.initScale(LLVector3(texturep->getWidth(discard_level) / 8, texturep->getHeight(discard_level) / 8, 1.f));
|
||||
// gGL.getTexUnit(i)->activate();
|
||||
|
||||
// glMatrixMode(GL_TEXTURE);
|
||||
// glPushMatrix();
|
||||
// glLoadIdentity();
|
||||
// //gGL.matrixMode(LLRender::MM_TEXTURE);
|
||||
// glLoadMatrixf((GLfloat*) checkboard_matrix.mMatrix);
|
||||
|
||||
// gGL.getTexUnit(i)->bind(LLViewerTexture::sCheckerBoardImagep, TRUE);
|
||||
|
||||
// pushVerts(params, LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_COLOR | LLVertexBuffer::MAP_NORMAL );
|
||||
|
||||
// glPopMatrix();
|
||||
// glMatrixMode(GL_MODELVIEW);
|
||||
// //gGL.matrixMode(LLRender::MM_MODELVIEW);
|
||||
//}
|
||||
}
|
||||
|
||||
|
||||
void renderLights(LLDrawable* drawablep)
|
||||
{
|
||||
|
|
@ -4042,6 +4146,10 @@ public:
|
|||
{
|
||||
renderComplexityDisplay(drawable);
|
||||
}
|
||||
if(gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_TEXEL_DENSITY))
|
||||
{
|
||||
renderTexelDensity(drawable);
|
||||
}
|
||||
|
||||
LLVOAvatar* avatar = dynamic_cast<LLVOAvatar*>(drawable->getVObj().get());
|
||||
|
||||
|
|
@ -4291,7 +4399,8 @@ void LLSpatialPartition::renderDebug()
|
|||
LLPipeline::RENDER_DEBUG_AGENT_TARGET |
|
||||
//LLPipeline::RENDER_DEBUG_BUILD_QUEUE |
|
||||
LLPipeline::RENDER_DEBUG_SHADOW_FRUSTA |
|
||||
LLPipeline::RENDER_DEBUG_RENDER_COMPLEXITY))
|
||||
LLPipeline::RENDER_DEBUG_RENDER_COMPLEXITY |
|
||||
LLPipeline::RENDER_DEBUG_TEXEL_DENSITY))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -240,6 +240,7 @@ static bool mLoginStatePastUI = false;
|
|||
|
||||
boost::scoped_ptr<LLEventPump> LLStartUp::sStateWatcher(new LLEventStream("StartupState"));
|
||||
boost::scoped_ptr<LLStartupListener> LLStartUp::sListener(new LLStartupListener());
|
||||
boost::scoped_ptr<LLViewerStats::PhaseMap> LLStartUp::sPhases(new LLViewerStats::PhaseMap);
|
||||
|
||||
//
|
||||
// local function declaration
|
||||
|
|
@ -2705,7 +2706,10 @@ void LLStartUp::setStartupState( EStartupState state )
|
|||
LL_INFOS("AppInit") << "Startup state changing from " <<
|
||||
getStartupStateString() << " to " <<
|
||||
startupStateToString(state) << LL_ENDL;
|
||||
|
||||
sPhases->stopPhase(getStartupStateString());
|
||||
gStartupState = state;
|
||||
sPhases->startPhase(getStartupStateString());
|
||||
postStartupState();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -34,6 +34,8 @@ class LLEventPump;
|
|||
class LLStartupListener;
|
||||
class LLSLURL;
|
||||
|
||||
#include "llviewerstats.h"
|
||||
|
||||
// functions
|
||||
bool idle_startup();
|
||||
void release_start_screen();
|
||||
|
|
@ -113,6 +115,7 @@ public:
|
|||
|
||||
static bool startLLProxy(); // Initialize the SOCKS 5 proxy
|
||||
|
||||
static LLViewerStats::PhaseMap& getPhases() { return *sPhases; }
|
||||
private:
|
||||
static LLSLURL sStartSLURL;
|
||||
|
||||
|
|
@ -120,6 +123,7 @@ private:
|
|||
static EStartupState gStartupState; // Do not set directly, use LLStartup::setStartupState
|
||||
static boost::scoped_ptr<LLEventPump> sStateWatcher;
|
||||
static boost::scoped_ptr<LLStartupListener> sListener;
|
||||
static boost::scoped_ptr<LLViewerStats::PhaseMap> sPhases;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -55,6 +55,9 @@ using namespace LLVOAvatarDefines;
|
|||
static const S32 BAKE_UPLOAD_ATTEMPTS = 7;
|
||||
static const F32 BAKE_UPLOAD_RETRY_DELAY = 2.f; // actual delay grows by power of 2 each attempt
|
||||
|
||||
// runway consolidate
|
||||
extern std::string self_av_string();
|
||||
|
||||
class LLTexLayerInfo
|
||||
{
|
||||
friend class LLTexLayer;
|
||||
|
|
@ -494,7 +497,6 @@ void LLTexLayerSetBuffer::doUpload()
|
|||
}
|
||||
|
||||
LLPointer<LLImageJ2C> compressedImage = new LLImageJ2C;
|
||||
compressedImage->setRate(0.f);
|
||||
const char* comment_text = LINDEN_J2C_COMMENT_PREFIX "RGBHM"; // writes into baked_color_data. 5 channels (rgb, heightfield/alpha, mask)
|
||||
if (compressedImage->encode(baked_image, comment_text))
|
||||
{
|
||||
|
|
@ -577,7 +579,7 @@ void LLTexLayerSetBuffer::doUpload()
|
|||
args["BODYREGION"] = mTexLayerSet->getBodyRegionName();
|
||||
args["RESOLUTION"] = lod_str;
|
||||
LLNotificationsUtil::add("AvatarRezSelfBakedTextureUploadNotification",args);
|
||||
llinfos << "Uploading [ name: " << mTexLayerSet->getBodyRegionName() << " res:" << lod_str << " time:" << (U32)mNeedsUploadTimer.getElapsedTimeF32() << " ]" << llendl;
|
||||
LL_DEBUGS("Avatar") << self_av_string() << "Uploading [ name: " << mTexLayerSet->getBodyRegionName() << " res:" << lod_str << " time:" << (U32)mNeedsUploadTimer.getElapsedTimeF32() << " ]" << LL_ENDL;
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
@ -631,7 +633,7 @@ void LLTexLayerSetBuffer::doUpdate()
|
|||
args["BODYREGION"] = mTexLayerSet->getBodyRegionName();
|
||||
args["RESOLUTION"] = lod_str;
|
||||
LLNotificationsUtil::add("AvatarRezSelfBakedTextureUpdateNotification",args);
|
||||
llinfos << "Locally updating [ name: " << mTexLayerSet->getBodyRegionName() << " res:" << lod_str << " time:" << (U32)mNeedsUpdateTimer.getElapsedTimeF32() << " ]" << llendl;
|
||||
LL_DEBUGS("Avatar") << self_av_string() << "Locally updating [ name: " << mTexLayerSet->getBodyRegionName() << " res:" << lod_str << " time:" << (U32)mNeedsUpdateTimer.getElapsedTimeF32() << " ]" << LL_ENDL;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -52,12 +52,20 @@
|
|||
#include "llviewerstats.h"
|
||||
#include "llviewerassetstats.h"
|
||||
#include "llworld.h"
|
||||
#include "llsdutil.h"
|
||||
#include "llstartup.h"
|
||||
#include "llviewerstats.h"
|
||||
|
||||
bool LLTextureFetchDebugger::sDebuggerEnabled = false ;
|
||||
LLStat LLTextureFetch::sCacheHitRate("texture_cache_hits", 128);
|
||||
LLStat LLTextureFetch::sCacheReadLatency("texture_cache_read_latency", 128);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
class LLTextureFetchWorker : public LLWorkerClass
|
||||
{
|
||||
friend class LLTextureFetch;
|
||||
friend class HTTPGetResponder;
|
||||
friend class LLTextureFetchDebugger;
|
||||
|
||||
private:
|
||||
class CacheReadResponder : public LLTextureCache::ReadResponder
|
||||
|
|
@ -242,6 +250,8 @@ private:
|
|||
S32 mDecodedDiscard;
|
||||
LLFrameTimer mRequestedTimer;
|
||||
LLFrameTimer mFetchTimer;
|
||||
LLTimer mCacheReadTimer;
|
||||
F32 mCacheReadTime;
|
||||
LLTextureCache::handle_t mCacheReadHandle;
|
||||
LLTextureCache::handle_t mCacheWriteHandle;
|
||||
U8* mBuffer;
|
||||
|
|
@ -258,6 +268,7 @@ private:
|
|||
BOOL mNeedsAux;
|
||||
BOOL mHaveAllData;
|
||||
BOOL mInLocalCache;
|
||||
BOOL mInCache;
|
||||
bool mCanUseHTTP ;
|
||||
bool mCanUseNET ; //can get from asset server.
|
||||
S32 mHTTPFailCount;
|
||||
|
|
@ -653,6 +664,7 @@ LLTextureFetchWorker::LLTextureFetchWorker(LLTextureFetch* fetcher,
|
|||
mRequestedDiscard(-1),
|
||||
mLoadedDiscard(-1),
|
||||
mDecodedDiscard(-1),
|
||||
mCacheReadTime(0.f),
|
||||
mCacheReadHandle(LLTextureCache::nullHandle()),
|
||||
mCacheWriteHandle(LLTextureCache::nullHandle()),
|
||||
mBuffer(NULL),
|
||||
|
|
@ -669,6 +681,7 @@ LLTextureFetchWorker::LLTextureFetchWorker(LLTextureFetch* fetcher,
|
|||
mNeedsAux(FALSE),
|
||||
mHaveAllData(FALSE),
|
||||
mInLocalCache(FALSE),
|
||||
mInCache(FALSE),
|
||||
mCanUseHTTP(true),
|
||||
mHTTPFailCount(0),
|
||||
mRetryAttempt(0),
|
||||
|
|
@ -838,6 +851,8 @@ void LLTextureFetchWorker::startWork(S32 param)
|
|||
// Called from LLWorkerThread::processRequest()
|
||||
bool LLTextureFetchWorker::doWork(S32 param)
|
||||
{
|
||||
static const F32 FETCHING_TIMEOUT = 120.f;//seconds
|
||||
|
||||
LLMutexLock lock(&mWorkMutex);
|
||||
|
||||
if ((mFetcher->isQuitting() || getFlags(LLWorkerClass::WCF_DELETE_REQUESTED)))
|
||||
|
|
@ -896,6 +911,7 @@ bool LLTextureFetchWorker::doWork(S32 param)
|
|||
mCacheReadHandle = LLTextureCache::nullHandle();
|
||||
mCacheWriteHandle = LLTextureCache::nullHandle();
|
||||
mState = LOAD_FROM_TEXTURE_CACHE;
|
||||
mInCache = FALSE;
|
||||
mDesiredSize = llmax(mDesiredSize, TEXTURE_CACHE_ENTRY_SIZE); // min desired size is TEXTURE_CACHE_ENTRY_SIZE
|
||||
LL_DEBUGS("Texture") << mID << ": Priority: " << llformat("%8.0f",mImagePriority)
|
||||
<< " Desired Discard: " << mDesiredDiscard << " Desired Size: " << mDesiredSize << LL_ENDL;
|
||||
|
|
@ -926,6 +942,7 @@ bool LLTextureFetchWorker::doWork(S32 param)
|
|||
CacheReadResponder* responder = new CacheReadResponder(mFetcher, mID, mFormattedImage);
|
||||
mCacheReadHandle = mFetcher->mTextureCache->readFromCache(filename, mID, cache_priority,
|
||||
offset, size, responder);
|
||||
mCacheReadTimer.reset();
|
||||
}
|
||||
else if (mUrl.empty())
|
||||
{
|
||||
|
|
@ -934,6 +951,7 @@ bool LLTextureFetchWorker::doWork(S32 param)
|
|||
CacheReadResponder* responder = new CacheReadResponder(mFetcher, mID, mFormattedImage);
|
||||
mCacheReadHandle = mFetcher->mTextureCache->readFromCache(mID, cache_priority,
|
||||
offset, size, responder);
|
||||
mCacheReadTimer.reset();
|
||||
}
|
||||
else if(mCanUseHTTP)
|
||||
{
|
||||
|
|
@ -982,11 +1000,12 @@ bool LLTextureFetchWorker::doWork(S32 param)
|
|||
llassert_always(mFormattedImage->getDataSize() > 0);
|
||||
mLoadedDiscard = mDesiredDiscard;
|
||||
mState = DECODE_IMAGE;
|
||||
mInCache = TRUE;
|
||||
mWriteToCacheState = NOT_WRITE ;
|
||||
LL_DEBUGS("Texture") << mID << ": Cached. Bytes: " << mFormattedImage->getDataSize()
|
||||
<< " Size: " << llformat("%dx%d",mFormattedImage->getWidth(),mFormattedImage->getHeight())
|
||||
<< " Desired Discard: " << mDesiredDiscard << " Desired Size: " << mDesiredSize << LL_ENDL;
|
||||
// fall through
|
||||
LLTextureFetch::sCacheHitRate.addValue(100.f);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -1002,6 +1021,7 @@ bool LLTextureFetchWorker::doWork(S32 param)
|
|||
mState = LOAD_FROM_NETWORK;
|
||||
}
|
||||
// fall through
|
||||
LLTextureFetch::sCacheHitRate.addValue(0.f);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1177,6 +1197,8 @@ bool LLTextureFetchWorker::doWork(S32 param)
|
|||
bool res = false;
|
||||
if (!mUrl.empty())
|
||||
{
|
||||
mRequestedTimer.reset();
|
||||
|
||||
mLoaded = FALSE;
|
||||
mGetStatus = 0;
|
||||
mGetReason.clear();
|
||||
|
|
@ -1335,6 +1357,13 @@ bool LLTextureFetchWorker::doWork(S32 param)
|
|||
}
|
||||
else
|
||||
{
|
||||
if(FETCHING_TIMEOUT < mRequestedTimer.getElapsedTimeF32())
|
||||
{
|
||||
//timeout, abort.
|
||||
mState = DONE;
|
||||
return true;
|
||||
}
|
||||
|
||||
setPriority(LLWorkerThread::PRIORITY_LOW | mWorkPriority);
|
||||
return false;
|
||||
}
|
||||
|
|
@ -1396,6 +1425,11 @@ bool LLTextureFetchWorker::doWork(S32 param)
|
|||
{
|
||||
if (mDecoded)
|
||||
{
|
||||
if(mFetcher->getFetchDebugger() && !mInLocalCache)
|
||||
{
|
||||
mFetcher->getFetchDebugger()->addHistoryEntry(this);
|
||||
}
|
||||
|
||||
if (mDecodedDiscard < 0)
|
||||
{
|
||||
LL_DEBUGS("Texture") << mID << ": Failed to Decode." << LL_ENDL;
|
||||
|
|
@ -1780,6 +1814,7 @@ void LLTextureFetchWorker::callbackDecoded(bool success, LLImageRaw* raw, LLImag
|
|||
mDecoded = TRUE;
|
||||
// llinfos << mID << " : DECODE COMPLETE " << llendl;
|
||||
setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority);
|
||||
mCacheReadTime = mCacheReadTimer.getElapsedTimeF32();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -1824,11 +1859,18 @@ LLTextureFetch::LLTextureFetch(LLTextureCache* cache, LLImageDecodeThread* image
|
|||
mHTTPTextureBits(0),
|
||||
mTotalHTTPRequests(0),
|
||||
mCurlGetRequest(NULL),
|
||||
mQAMode(qa_mode)
|
||||
mQAMode(qa_mode),
|
||||
mFetchDebugger(NULL)
|
||||
{
|
||||
mCurlPOSTRequestCount = 0;
|
||||
mMaxBandwidth = gSavedSettings.getF32("ThrottleBandwidthKBPS");
|
||||
mTextureInfo.setUpLogging(gSavedSettings.getBOOL("LogTextureDownloadsToViewerLog"), gSavedSettings.getBOOL("LogTextureDownloadsToSimulator"), gSavedSettings.getU32("TextureLoggingThreshold"));
|
||||
|
||||
LLTextureFetchDebugger::sDebuggerEnabled = gSavedSettings.getBOOL("TextureFetchDebuggerEnabled");
|
||||
if(LLTextureFetchDebugger::isEnabled())
|
||||
{
|
||||
mFetchDebugger = new LLTextureFetchDebugger(this, cache, imagedecodethread) ;
|
||||
}
|
||||
}
|
||||
|
||||
LLTextureFetch::~LLTextureFetch()
|
||||
|
|
@ -1843,11 +1885,17 @@ LLTextureFetch::~LLTextureFetch()
|
|||
}
|
||||
|
||||
// ~LLQueuedThread() called here
|
||||
|
||||
delete mFetchDebugger;
|
||||
}
|
||||
|
||||
bool LLTextureFetch::createRequest(const std::string& url, const LLUUID& id, const LLHost& host, F32 priority,
|
||||
S32 w, S32 h, S32 c, S32 desired_discard, bool needs_aux, bool can_use_http)
|
||||
{
|
||||
if(mFetcherLocked)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (mDebugPause)
|
||||
{
|
||||
return false;
|
||||
|
|
@ -2092,6 +2140,11 @@ bool LLTextureFetch::getRequestFinished(const LLUUID& id, S32& discard_level,
|
|||
discard_level = worker->mDecodedDiscard;
|
||||
raw = worker->mRawImage;
|
||||
aux = worker->mAuxImage;
|
||||
F32 cache_read_time = worker->mCacheReadTime;
|
||||
if (cache_read_time != 0.f)
|
||||
{
|
||||
sCacheReadLatency.addValue(cache_read_time * 1000.f);
|
||||
}
|
||||
res = true;
|
||||
LL_DEBUGS("Texture") << id << ": Request Finished. State: " << worker->mState << " Discard: " << discard_level << LL_ENDL;
|
||||
worker->unlockWorkMutex();
|
||||
|
|
@ -2222,7 +2275,13 @@ S32 LLTextureFetch::update(F32 max_time_ms)
|
|||
|
||||
if (!mDebugPause)
|
||||
{
|
||||
sendRequestListToSimulators();
|
||||
// this is the startup state when send_complete_agent_movement() message is sent.
|
||||
// Before this, the RequestImages message sent by sendRequestListToSimulators
|
||||
// won't work so don't bother trying
|
||||
if (LLStartUp::getStartupState() > STATE_AGENT_SEND)
|
||||
{
|
||||
sendRequestListToSimulators();
|
||||
}
|
||||
}
|
||||
|
||||
if (!mThreaded)
|
||||
|
|
@ -2258,6 +2317,11 @@ void LLTextureFetch::startThread()
|
|||
{
|
||||
// Construct mCurlGetRequest from Worker Thread
|
||||
mCurlGetRequest = new LLCurlRequest();
|
||||
|
||||
if(mFetchDebugger)
|
||||
{
|
||||
mFetchDebugger->setCurlGetRequest(mCurlGetRequest);
|
||||
}
|
||||
}
|
||||
|
||||
// WORKER THREAD
|
||||
|
|
@ -2266,6 +2330,10 @@ void LLTextureFetch::endThread()
|
|||
// Destroy mCurlGetRequest from Worker Thread
|
||||
delete mCurlGetRequest;
|
||||
mCurlGetRequest = NULL;
|
||||
if(mFetchDebugger)
|
||||
{
|
||||
mFetchDebugger->setCurlGetRequest(NULL);
|
||||
}
|
||||
}
|
||||
|
||||
// WORKER THREAD
|
||||
|
|
@ -2803,7 +2871,6 @@ void LLTextureFetch::cmdDoWork()
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Private (anonymous) class methods implementing the command scheme.
|
||||
|
|
@ -2959,7 +3026,7 @@ TFReqSendMetrics::doWork(LLTextureFetch * fetcher)
|
|||
// In QA mode, Metrics submode, log the result for ease of testing
|
||||
if (fetcher->isQAMode())
|
||||
{
|
||||
LL_INFOS("Textures") << merged_llsd << LL_ENDL;
|
||||
LL_INFOS("Textures") << ll_pretty_print_sd(merged_llsd) << LL_ENDL;
|
||||
}
|
||||
|
||||
gViewerAssetStatsThread1->reset();
|
||||
|
|
@ -3007,5 +3074,659 @@ truncate_viewer_metrics(int max_regions, LLSD & metrics)
|
|||
|
||||
} // end of anonymous namespace
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
//Start LLTextureFetchDebugger
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
//---------------------
|
||||
class LLDebuggerCacheReadResponder : public LLTextureCache::ReadResponder
|
||||
{
|
||||
public:
|
||||
LLDebuggerCacheReadResponder(LLTextureFetchDebugger* debugger, S32 id, LLImageFormatted* image)
|
||||
: mDebugger(debugger), mID(id)
|
||||
{
|
||||
setImage(image);
|
||||
}
|
||||
virtual void completed(bool success)
|
||||
{
|
||||
mDebugger->callbackCacheRead(mID, success, mFormattedImage, mImageSize, mImageLocal);
|
||||
}
|
||||
private:
|
||||
LLTextureFetchDebugger* mDebugger;
|
||||
S32 mID;
|
||||
};
|
||||
|
||||
class LLDebuggerCacheWriteResponder : public LLTextureCache::WriteResponder
|
||||
{
|
||||
public:
|
||||
LLDebuggerCacheWriteResponder(LLTextureFetchDebugger* debugger, S32 id)
|
||||
: mDebugger(debugger), mID(id)
|
||||
{
|
||||
}
|
||||
virtual void completed(bool success)
|
||||
{
|
||||
mDebugger->callbackCacheWrite(mID, success);
|
||||
}
|
||||
private:
|
||||
LLTextureFetchDebugger* mDebugger;
|
||||
S32 mID;
|
||||
};
|
||||
|
||||
class LLDebuggerDecodeResponder : public LLImageDecodeThread::Responder
|
||||
{
|
||||
public:
|
||||
LLDebuggerDecodeResponder(LLTextureFetchDebugger* debugger, S32 id)
|
||||
: mDebugger(debugger), mID(id)
|
||||
{
|
||||
}
|
||||
virtual void completed(bool success, LLImageRaw* raw, LLImageRaw* aux)
|
||||
{
|
||||
mDebugger->callbackDecoded(mID, success, raw, aux);
|
||||
}
|
||||
private:
|
||||
LLTextureFetchDebugger* mDebugger;
|
||||
S32 mID;
|
||||
};
|
||||
|
||||
class LLDebuggerHTTPResponder : public LLCurl::Responder
|
||||
{
|
||||
public:
|
||||
LLDebuggerHTTPResponder(LLTextureFetchDebugger* debugger, S32 index)
|
||||
: mDebugger(debugger), mIndex(index)
|
||||
{
|
||||
}
|
||||
virtual void completedRaw(U32 status, const std::string& reason,
|
||||
const LLChannelDescriptors& channels,
|
||||
const LLIOPipe::buffer_ptr_t& buffer)
|
||||
{
|
||||
bool success = false;
|
||||
bool partial = false;
|
||||
if (HTTP_OK <= status && status < HTTP_MULTIPLE_CHOICES)
|
||||
{
|
||||
success = true;
|
||||
if (HTTP_PARTIAL_CONTENT == status) // partial information
|
||||
{
|
||||
partial = true;
|
||||
}
|
||||
}
|
||||
if (!success)
|
||||
{
|
||||
llinfos << "Fetch Debugger : CURL GET FAILED, index = " << mIndex << ", status:" << status << " reason:" << reason << llendl;
|
||||
}
|
||||
mDebugger->callbackHTTP(mIndex, channels, buffer, partial, success);
|
||||
}
|
||||
virtual bool followRedir()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
private:
|
||||
LLTextureFetchDebugger* mDebugger;
|
||||
S32 mIndex;
|
||||
};
|
||||
|
||||
LLTextureFetchDebugger::LLTextureFetchDebugger(LLTextureFetch* fetcher, LLTextureCache* cache, LLImageDecodeThread* imagedecodethread) :
|
||||
mFetcher(fetcher),
|
||||
mTextureCache(cache),
|
||||
mImageDecodeThread(imagedecodethread),
|
||||
mCurlGetRequest(NULL)
|
||||
{
|
||||
init();
|
||||
}
|
||||
|
||||
LLTextureFetchDebugger::~LLTextureFetchDebugger()
|
||||
{
|
||||
mFetchingHistory.clear();
|
||||
stopDebug();
|
||||
}
|
||||
|
||||
void LLTextureFetchDebugger::init()
|
||||
{
|
||||
mState = IDLE;
|
||||
|
||||
mCacheReadTime = -1.f;
|
||||
mCacheWriteTime = -1.f;
|
||||
mDecodingTime = -1.f;
|
||||
mHTTPTime = -1.f;
|
||||
mGLCreationTime = -1.f;
|
||||
mTotalFetchingTime = 0.f;
|
||||
mRefetchVisCacheTime = -1.f;
|
||||
mRefetchVisHTTPTime = -1.f;
|
||||
|
||||
mNumFetchedTextures = 0;
|
||||
mNumCacheHits = 0;
|
||||
mNumVisibleFetchedTextures = 0;
|
||||
mNumVisibleFetchingRequests = 0;
|
||||
mFetchedData = 0;
|
||||
mDecodedData = 0;
|
||||
mVisibleFetchedData = 0;
|
||||
mVisibleDecodedData = 0;
|
||||
mRenderedData = 0;
|
||||
mRenderedDecodedData = 0;
|
||||
mFetchedPixels = 0;
|
||||
mRenderedPixels = 0;
|
||||
mRefetchedData = 0;
|
||||
mRefetchedPixels = 0;
|
||||
|
||||
mFreezeHistory = FALSE;
|
||||
}
|
||||
|
||||
void LLTextureFetchDebugger::startDebug()
|
||||
{
|
||||
//lock the fetcher
|
||||
mFetcher->lockFetcher(true);
|
||||
mFreezeHistory = TRUE;
|
||||
|
||||
//clear the current fetching queue
|
||||
gTextureList.clearFetchingRequests();
|
||||
|
||||
//wait for all works to be done
|
||||
while(1)
|
||||
{
|
||||
S32 pending = 0;
|
||||
pending += LLAppViewer::getTextureCache()->update(1);
|
||||
pending += LLAppViewer::getImageDecodeThread()->update(1);
|
||||
pending += LLAppViewer::getTextureFetch()->update(1);
|
||||
if(!pending)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//collect statistics
|
||||
mTotalFetchingTime = gDebugTimers[0].getElapsedTimeF32() - mTotalFetchingTime;
|
||||
|
||||
std::set<LLUUID> fetched_textures;
|
||||
S32 size = mFetchingHistory.size();
|
||||
for(S32 i = 0 ; i < size; i++)
|
||||
{
|
||||
bool in_list = true;
|
||||
if(fetched_textures.find(mFetchingHistory[i].mID) == fetched_textures.end())
|
||||
{
|
||||
fetched_textures.insert(mFetchingHistory[i].mID);
|
||||
in_list = false;
|
||||
}
|
||||
|
||||
LLViewerFetchedTexture* tex = LLViewerTextureManager::findFetchedTexture(mFetchingHistory[i].mID);
|
||||
if(tex && tex->isJustBound()) //visible
|
||||
{
|
||||
if(!in_list)
|
||||
{
|
||||
mNumVisibleFetchedTextures++;
|
||||
}
|
||||
mNumVisibleFetchingRequests++;
|
||||
|
||||
mVisibleFetchedData += mFetchingHistory[i].mFetchedSize;
|
||||
mVisibleDecodedData += mFetchingHistory[i].mDecodedSize;
|
||||
|
||||
if(tex->getDiscardLevel() >= mFetchingHistory[i].mDecodedLevel)
|
||||
{
|
||||
mRenderedData += mFetchingHistory[i].mFetchedSize;
|
||||
mRenderedDecodedData += mFetchingHistory[i].mDecodedSize;
|
||||
mRenderedPixels += tex->getWidth() * tex->getHeight();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mNumFetchedTextures = fetched_textures.size();
|
||||
}
|
||||
|
||||
void LLTextureFetchDebugger::stopDebug()
|
||||
{
|
||||
//clear the current debug work
|
||||
S32 size = mFetchingHistory.size();
|
||||
switch(mState)
|
||||
{
|
||||
case READ_CACHE:
|
||||
for(S32 i = 0 ; i < size; i++)
|
||||
{
|
||||
if (mFetchingHistory[i]. mCacheHandle != LLTextureCache::nullHandle())
|
||||
{
|
||||
mTextureCache->readComplete(mFetchingHistory[i].mCacheHandle, true);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case WRITE_CACHE:
|
||||
for(S32 i = 0 ; i < size; i++)
|
||||
{
|
||||
if (mFetchingHistory[i].mCacheHandle != LLTextureCache::nullHandle())
|
||||
{
|
||||
mTextureCache->writeComplete(mFetchingHistory[i].mCacheHandle, true);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case DECODING:
|
||||
break;
|
||||
case HTTP_FETCHING:
|
||||
break;
|
||||
case GL_TEX:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
while(1)
|
||||
{
|
||||
if(update())
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//unlock the fetcher
|
||||
mFetcher->lockFetcher(false);
|
||||
mFreezeHistory = FALSE;
|
||||
mTotalFetchingTime = gDebugTimers[0].getElapsedTimeF32(); //reset
|
||||
}
|
||||
|
||||
//called in the main thread and when the fetching queue is empty
|
||||
void LLTextureFetchDebugger::clearHistory()
|
||||
{
|
||||
mFetchingHistory.clear();
|
||||
init();
|
||||
}
|
||||
|
||||
void LLTextureFetchDebugger::addHistoryEntry(LLTextureFetchWorker* worker)
|
||||
{
|
||||
if(mFreezeHistory)
|
||||
{
|
||||
mRefetchedPixels += worker->mRawImage->getWidth() * worker->mRawImage->getHeight();
|
||||
mRefetchedData += worker->mFormattedImage->getDataSize();
|
||||
return;
|
||||
}
|
||||
|
||||
if(worker->mInCache)
|
||||
{
|
||||
mNumCacheHits++;
|
||||
}
|
||||
mFetchedData += worker->mFormattedImage->getDataSize();
|
||||
mDecodedData += worker->mRawImage->getDataSize();
|
||||
mFetchedPixels += worker->mRawImage->getWidth() * worker->mRawImage->getHeight();
|
||||
|
||||
mFetchingHistory.push_back(FetchEntry(worker->mID, worker->mDesiredSize, worker->mDecodedDiscard, worker->mFormattedImage->getDataSize(), worker->mRawImage->getDataSize()));
|
||||
//mFetchingHistory.push_back(FetchEntry(worker->mID, worker->mDesiredSize, worker->mHaveAllData ? 0 : worker->mLoadedDiscard, worker->mFormattedImage->getComponents(),
|
||||
//worker->mDecodedDiscard, worker->mFormattedImage->getDataSize(), worker->mRawImage->getDataSize()));
|
||||
}
|
||||
|
||||
void LLTextureFetchDebugger::lockCache()
|
||||
{
|
||||
}
|
||||
|
||||
void LLTextureFetchDebugger::unlockCache()
|
||||
{
|
||||
}
|
||||
|
||||
void LLTextureFetchDebugger::debugCacheRead()
|
||||
{
|
||||
lockCache();
|
||||
llassert_always(mState == IDLE);
|
||||
mTimer.reset();
|
||||
mState = READ_CACHE;
|
||||
|
||||
S32 size = mFetchingHistory.size();
|
||||
for(S32 i = 0 ; i < size ; i++)
|
||||
{
|
||||
mFetchingHistory[i].mFormattedImage = NULL;
|
||||
mFetchingHistory[i].mCacheHandle = mTextureCache->readFromCache(mFetchingHistory[i].mID, LLWorkerThread::PRIORITY_NORMAL, 0, mFetchingHistory[i].mFetchedSize,
|
||||
new LLDebuggerCacheReadResponder(this, i, mFetchingHistory[i].mFormattedImage));
|
||||
}
|
||||
}
|
||||
|
||||
void LLTextureFetchDebugger::clearCache()
|
||||
{
|
||||
S32 size = mFetchingHistory.size();
|
||||
{
|
||||
std::set<LLUUID> deleted_list;
|
||||
for(S32 i = 0 ; i < size ; i++)
|
||||
{
|
||||
if(deleted_list.find(mFetchingHistory[i].mID) == deleted_list.end())
|
||||
{
|
||||
deleted_list.insert(mFetchingHistory[i].mID);
|
||||
mTextureCache->removeFromCache(mFetchingHistory[i].mID);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LLTextureFetchDebugger::debugCacheWrite()
|
||||
{
|
||||
//remove from cache
|
||||
clearCache();
|
||||
|
||||
lockCache();
|
||||
llassert_always(mState == IDLE);
|
||||
mTimer.reset();
|
||||
mState = WRITE_CACHE;
|
||||
|
||||
S32 size = mFetchingHistory.size();
|
||||
for(S32 i = 0 ; i < size ; i++)
|
||||
{
|
||||
if(mFetchingHistory[i].mFormattedImage.notNull())
|
||||
{
|
||||
mFetchingHistory[i].mCacheHandle = mTextureCache->writeToCache(mFetchingHistory[i].mID, LLWorkerThread::PRIORITY_NORMAL,
|
||||
mFetchingHistory[i].mFormattedImage->getData(), mFetchingHistory[i].mFetchedSize,
|
||||
mFetchingHistory[i].mDecodedLevel == 0 ? mFetchingHistory[i].mFetchedSize : mFetchingHistory[i].mFetchedSize + 1,
|
||||
new LLDebuggerCacheWriteResponder(this, i));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LLTextureFetchDebugger::lockDecoder()
|
||||
{
|
||||
}
|
||||
|
||||
void LLTextureFetchDebugger::unlockDecoder()
|
||||
{
|
||||
}
|
||||
|
||||
void LLTextureFetchDebugger::debugDecoder()
|
||||
{
|
||||
lockDecoder();
|
||||
llassert_always(mState == IDLE);
|
||||
mTimer.reset();
|
||||
mState = DECODING;
|
||||
|
||||
S32 size = mFetchingHistory.size();
|
||||
for(S32 i = 0 ; i < size ; i++)
|
||||
{
|
||||
if(mFetchingHistory[i].mFormattedImage.isNull())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
mImageDecodeThread->decodeImage(mFetchingHistory[i].mFormattedImage, LLWorkerThread::PRIORITY_NORMAL,
|
||||
mFetchingHistory[i].mDecodedLevel, mFetchingHistory[i].mNeedsAux,
|
||||
new LLDebuggerDecodeResponder(this, i));
|
||||
}
|
||||
}
|
||||
|
||||
void LLTextureFetchDebugger::debugHTTP()
|
||||
{
|
||||
llassert_always(mState == IDLE);
|
||||
|
||||
LLViewerRegion* region = gAgent.getRegion();
|
||||
if (!region)
|
||||
{
|
||||
llinfos << "Fetch Debugger : Current region undefined. Cannot fetch textures through HTTP." << llendl;
|
||||
return;
|
||||
}
|
||||
|
||||
mHTTPUrl = region->getHttpUrl();
|
||||
if (mHTTPUrl.empty())
|
||||
{
|
||||
llinfos << "Fetch Debugger : Current region URL undefined. Cannot fetch textures through HTTP." << llendl;
|
||||
return;
|
||||
}
|
||||
|
||||
mTimer.reset();
|
||||
mState = HTTP_FETCHING;
|
||||
|
||||
S32 size = mFetchingHistory.size();
|
||||
for (S32 i = 0 ; i < size ; i++)
|
||||
{
|
||||
mFetchingHistory[i].mCurlState = FetchEntry::CURL_NOT_DONE;
|
||||
mFetchingHistory[i].mCurlReceivedSize = 0;
|
||||
mFetchingHistory[i].mHTTPFailCount = 0;
|
||||
}
|
||||
mNbCurlRequests = 0;
|
||||
mNbCurlCompleted = 0;
|
||||
|
||||
fillCurlQueue();
|
||||
}
|
||||
|
||||
S32 LLTextureFetchDebugger::fillCurlQueue()
|
||||
{
|
||||
if (mNbCurlRequests == 24)
|
||||
return mNbCurlRequests;
|
||||
|
||||
S32 size = mFetchingHistory.size();
|
||||
for (S32 i = 0 ; i < size ; i++)
|
||||
{
|
||||
if (mFetchingHistory[i].mCurlState != FetchEntry::CURL_NOT_DONE)
|
||||
continue;
|
||||
std::string texture_url = mHTTPUrl + "/?texture_id=" + mFetchingHistory[i].mID.asString().c_str();
|
||||
S32 requestedSize = mFetchingHistory[i].mRequestedSize;
|
||||
// We request the whole file if the size was not set.
|
||||
requestedSize = llmax(0,requestedSize);
|
||||
// We request the whole file if the size was set to an absurdly high value (meaning all file)
|
||||
requestedSize = (requestedSize == 33554432 ? 0 : requestedSize);
|
||||
std::vector<std::string> headers;
|
||||
headers.push_back("Accept: image/x-j2c");
|
||||
bool res = mCurlGetRequest->getByteRange(texture_url, headers, 0, requestedSize, new LLDebuggerHTTPResponder(this, i));
|
||||
if (res)
|
||||
{
|
||||
mFetchingHistory[i].mCurlState = FetchEntry::CURL_IN_PROGRESS;
|
||||
mNbCurlRequests++;
|
||||
// Hack
|
||||
if (mNbCurlRequests == 24)
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
//llinfos << "Fetch Debugger : Having " << mNbCurlRequests << " requests through the curl thread." << llendl;
|
||||
return mNbCurlRequests;
|
||||
}
|
||||
|
||||
void LLTextureFetchDebugger::debugGLTextureCreation()
|
||||
{
|
||||
llassert_always(mState == IDLE);
|
||||
mState = GL_TEX;
|
||||
std::vector<LLViewerFetchedTexture*> tex_list;
|
||||
|
||||
S32 size = mFetchingHistory.size();
|
||||
for(S32 i = 0 ; i < size ; i++)
|
||||
{
|
||||
if(mFetchingHistory[i].mRawImage.notNull())
|
||||
{
|
||||
LLViewerFetchedTexture* tex = gTextureList.findImage(mFetchingHistory[i].mID) ;
|
||||
if(tex && !tex->isForSculptOnly())
|
||||
{
|
||||
tex->destroyGLTexture() ;
|
||||
tex_list.push_back(tex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mTimer.reset();
|
||||
S32 j = 0 ;
|
||||
S32 size1 = tex_list.size();
|
||||
for(S32 i = 0 ; i < size && j < size1; i++)
|
||||
{
|
||||
if(mFetchingHistory[i].mRawImage.notNull())
|
||||
{
|
||||
if(mFetchingHistory[i].mID == tex_list[j]->getID())
|
||||
{
|
||||
tex_list[j]->createGLTexture(mFetchingHistory[i].mDecodedLevel, mFetchingHistory[i].mRawImage, 0, TRUE, tex_list[j]->getBoostLevel());
|
||||
j++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mGLCreationTime = mTimer.getElapsedTimeF32() ;
|
||||
return;
|
||||
}
|
||||
|
||||
//clear fetching results of all textures.
|
||||
void LLTextureFetchDebugger::clearTextures()
|
||||
{
|
||||
S32 size = mFetchingHistory.size();
|
||||
for(S32 i = 0 ; i < size ; i++)
|
||||
{
|
||||
LLViewerFetchedTexture* tex = gTextureList.findImage(mFetchingHistory[i].mID) ;
|
||||
if(tex)
|
||||
{
|
||||
tex->clearFetchedResults() ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LLTextureFetchDebugger::debugRefetchVisibleFromCache()
|
||||
{
|
||||
llassert_always(mState == IDLE);
|
||||
mState = REFETCH_VIS_CACHE;
|
||||
|
||||
clearTextures();
|
||||
|
||||
mTimer.reset();
|
||||
mFetcher->lockFetcher(false);
|
||||
}
|
||||
|
||||
void LLTextureFetchDebugger::debugRefetchVisibleFromHTTP()
|
||||
{
|
||||
llassert_always(mState == IDLE);
|
||||
mState = REFETCH_VIS_HTTP;
|
||||
|
||||
clearCache();
|
||||
clearTextures();
|
||||
|
||||
mTimer.reset();
|
||||
mFetcher->lockFetcher(false);
|
||||
}
|
||||
|
||||
bool LLTextureFetchDebugger::update()
|
||||
{
|
||||
switch(mState)
|
||||
{
|
||||
case READ_CACHE:
|
||||
if(!mTextureCache->update(1))
|
||||
{
|
||||
mCacheReadTime = mTimer.getElapsedTimeF32() ;
|
||||
mState = IDLE;
|
||||
unlockCache();
|
||||
}
|
||||
break;
|
||||
case WRITE_CACHE:
|
||||
if(!mTextureCache->update(1))
|
||||
{
|
||||
mCacheWriteTime = mTimer.getElapsedTimeF32() ;
|
||||
mState = IDLE;
|
||||
unlockCache();
|
||||
}
|
||||
break;
|
||||
case DECODING:
|
||||
if(!mImageDecodeThread->update(1))
|
||||
{
|
||||
mDecodingTime = mTimer.getElapsedTimeF32() ;
|
||||
mState = IDLE;
|
||||
unlockDecoder();
|
||||
}
|
||||
break;
|
||||
case HTTP_FETCHING:
|
||||
mCurlGetRequest->process();
|
||||
LLCurl::getCurlThread()->update(1);
|
||||
if (!fillCurlQueue() && mNbCurlCompleted == mFetchingHistory.size())
|
||||
{
|
||||
mHTTPTime = mTimer.getElapsedTimeF32() ;
|
||||
mState = IDLE;
|
||||
}
|
||||
break;
|
||||
case GL_TEX:
|
||||
mState = IDLE;
|
||||
break;
|
||||
case REFETCH_VIS_CACHE:
|
||||
if (LLAppViewer::getTextureFetch()->getNumRequests() == 0)
|
||||
{
|
||||
mRefetchVisCacheTime = gDebugTimers[0].getElapsedTimeF32() - mTotalFetchingTime;
|
||||
mState = IDLE;
|
||||
mFetcher->lockFetcher(true);
|
||||
}
|
||||
break;
|
||||
case REFETCH_VIS_HTTP:
|
||||
if (LLAppViewer::getTextureFetch()->getNumRequests() == 0)
|
||||
{
|
||||
mRefetchVisHTTPTime = gDebugTimers[0].getElapsedTimeF32() - mTotalFetchingTime;
|
||||
mState = IDLE;
|
||||
mFetcher->lockFetcher(true);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
mState = IDLE;
|
||||
break;
|
||||
}
|
||||
|
||||
return mState == IDLE;
|
||||
}
|
||||
|
||||
void LLTextureFetchDebugger::callbackCacheRead(S32 id, bool success, LLImageFormatted* image,
|
||||
S32 imagesize, BOOL islocal)
|
||||
{
|
||||
if (success)
|
||||
{
|
||||
mFetchingHistory[id].mFormattedImage = image;
|
||||
}
|
||||
mTextureCache->readComplete(mFetchingHistory[id].mCacheHandle, false);
|
||||
mFetchingHistory[id].mCacheHandle = LLTextureCache::nullHandle();
|
||||
}
|
||||
|
||||
void LLTextureFetchDebugger::callbackCacheWrite(S32 id, bool success)
|
||||
{
|
||||
mTextureCache->writeComplete(mFetchingHistory[id].mCacheHandle);
|
||||
mFetchingHistory[id].mCacheHandle = LLTextureCache::nullHandle();
|
||||
}
|
||||
|
||||
void LLTextureFetchDebugger::callbackDecoded(S32 id, bool success, LLImageRaw* raw, LLImageRaw* aux)
|
||||
{
|
||||
if (success)
|
||||
{
|
||||
llassert_always(raw);
|
||||
mFetchingHistory[id].mRawImage = raw;
|
||||
}
|
||||
}
|
||||
|
||||
void LLTextureFetchDebugger::callbackHTTP(S32 id, const LLChannelDescriptors& channels,
|
||||
const LLIOPipe::buffer_ptr_t& buffer,
|
||||
bool partial, bool success)
|
||||
{
|
||||
mNbCurlRequests--;
|
||||
if (success)
|
||||
{
|
||||
mFetchingHistory[id].mCurlState = FetchEntry::CURL_DONE;
|
||||
mNbCurlCompleted++;
|
||||
|
||||
S32 data_size = buffer->countAfter(channels.in(), NULL);
|
||||
mFetchingHistory[id].mCurlReceivedSize += data_size;
|
||||
//llinfos << "Fetch Debugger : got results for " << id << ", data_size = " << data_size << ", received = " << mFetchingHistory[id].mCurlReceivedSize << ", requested = " << mFetchingHistory[id].mRequestedSize << ", partial = " << partial << llendl;
|
||||
if ((mFetchingHistory[id].mCurlReceivedSize >= mFetchingHistory[id].mRequestedSize) || !partial || (mFetchingHistory[id].mRequestedSize == 600))
|
||||
{
|
||||
U8* d_buffer = (U8*)ALLOCATE_MEM(LLImageBase::getPrivatePool(), data_size);
|
||||
buffer->readAfter(channels.in(), NULL, d_buffer, data_size);
|
||||
|
||||
llassert_always(mFetchingHistory[id].mFormattedImage.isNull());
|
||||
{
|
||||
// For now, create formatted image based on extension
|
||||
std::string texture_url = mHTTPUrl + "/?texture_id=" + mFetchingHistory[id].mID.asString().c_str();
|
||||
std::string extension = gDirUtilp->getExtension(texture_url);
|
||||
mFetchingHistory[id].mFormattedImage = LLImageFormatted::createFromType(LLImageBase::getCodecFromExtension(extension));
|
||||
if (mFetchingHistory[id].mFormattedImage.isNull())
|
||||
{
|
||||
mFetchingHistory[id].mFormattedImage = new LLImageJ2C; // default
|
||||
}
|
||||
}
|
||||
|
||||
mFetchingHistory[id].mFormattedImage->setData(d_buffer, data_size);
|
||||
}
|
||||
}
|
||||
else //failed
|
||||
{
|
||||
mFetchingHistory[id].mHTTPFailCount++;
|
||||
if(mFetchingHistory[id].mHTTPFailCount < 5)
|
||||
{
|
||||
// Fetch will have to be redone
|
||||
mFetchingHistory[id].mCurlState = FetchEntry::CURL_NOT_DONE;
|
||||
}
|
||||
else //skip
|
||||
{
|
||||
mFetchingHistory[id].mCurlState = FetchEntry::CURL_DONE;
|
||||
mNbCurlCompleted++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//---------------------
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
//End LLTextureFetchDebugger
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -34,14 +34,17 @@
|
|||
#include "llcurl.h"
|
||||
#include "lltextureinfo.h"
|
||||
#include "llapr.h"
|
||||
#include "llimageworker.h"
|
||||
//#include "lltexturecache.h"
|
||||
|
||||
class LLViewerTexture;
|
||||
class LLTextureFetchWorker;
|
||||
class HTTPGetResponder;
|
||||
class LLTextureCache;
|
||||
class LLImageDecodeThread;
|
||||
class LLHost;
|
||||
class LLViewerAssetStats;
|
||||
class LLTextureFetchDebugger;
|
||||
class LLTextureCache;
|
||||
|
||||
// Interface class
|
||||
class LLTextureFetch : public LLWorkerThread
|
||||
|
|
@ -164,6 +167,9 @@ private:
|
|||
LLMutex mQueueMutex; //to protect mRequestMap and mCommands only
|
||||
LLMutex mNetworkQueueMutex; //to protect mNetworkQueue, mHTTPTextureQueue and mCancelQueue.
|
||||
|
||||
static LLStat sCacheHitRate;
|
||||
static LLStat sCacheReadLatency;
|
||||
|
||||
LLTextureCache* mTextureCache;
|
||||
LLImageDecodeThread* mImageDecodeThread;
|
||||
LLCurlRequest* mCurlGetRequest;
|
||||
|
|
@ -209,7 +215,195 @@ public:
|
|||
// attempt to log metrics follows a break in the metrics stream
|
||||
// reporting due to either startup or a problem POSTing data.
|
||||
static volatile bool svMetricsDataBreak;
|
||||
|
||||
private:
|
||||
//debug use
|
||||
LLTextureFetchDebugger* mFetchDebugger;
|
||||
bool mFetcherLocked;
|
||||
|
||||
public:
|
||||
//debug use
|
||||
LLTextureFetchDebugger* getFetchDebugger() { return mFetchDebugger;}
|
||||
void lockFetcher(bool lock) { mFetcherLocked = lock;}
|
||||
};
|
||||
|
||||
//debug use
|
||||
class LLTextureFetchDebugger
|
||||
{
|
||||
friend class LLTextureFetch;
|
||||
public:
|
||||
LLTextureFetchDebugger(LLTextureFetch* fetcher, LLTextureCache* cache, LLImageDecodeThread* imagedecodethread) ;
|
||||
~LLTextureFetchDebugger();
|
||||
|
||||
public:
|
||||
enum e_debug_state
|
||||
{
|
||||
IDLE = 0,
|
||||
READ_CACHE,
|
||||
WRITE_CACHE,
|
||||
DECODING,
|
||||
HTTP_FETCHING,
|
||||
GL_TEX,
|
||||
REFETCH_VIS_CACHE,
|
||||
REFETCH_VIS_HTTP,
|
||||
REFETCH_ALL_CACHE,
|
||||
REFETCH_ALL_HTTP,
|
||||
INVALID
|
||||
};
|
||||
|
||||
private:
|
||||
struct FetchEntry
|
||||
{
|
||||
enum e_curl_state
|
||||
{
|
||||
CURL_NOT_DONE = 0,
|
||||
CURL_IN_PROGRESS,
|
||||
CURL_DONE
|
||||
};
|
||||
LLUUID mID;
|
||||
S32 mRequestedSize;
|
||||
S32 mDecodedLevel;
|
||||
S32 mFetchedSize;
|
||||
S32 mDecodedSize;
|
||||
BOOL mNeedsAux;
|
||||
U32 mCacheHandle;
|
||||
LLPointer<LLImageFormatted> mFormattedImage;
|
||||
LLPointer<LLImageRaw> mRawImage;
|
||||
e_curl_state mCurlState;
|
||||
S32 mCurlReceivedSize;
|
||||
S32 mHTTPFailCount;
|
||||
|
||||
FetchEntry() :
|
||||
mDecodedLevel(-1),
|
||||
mFetchedSize(0),
|
||||
mDecodedSize(0)
|
||||
{}
|
||||
FetchEntry(LLUUID& id, S32 r_size, /*S32 f_discard, S32 c,*/ S32 level, S32 f_size, S32 d_size) :
|
||||
mID(id),
|
||||
mRequestedSize(r_size),
|
||||
mDecodedLevel(level),
|
||||
mFetchedSize(f_size),
|
||||
mDecodedSize(d_size),
|
||||
mNeedsAux(false),
|
||||
mHTTPFailCount(0)
|
||||
{}
|
||||
};
|
||||
std::vector<FetchEntry> mFetchingHistory;
|
||||
|
||||
e_debug_state mState;
|
||||
|
||||
F32 mCacheReadTime;
|
||||
F32 mCacheWriteTime;
|
||||
F32 mDecodingTime;
|
||||
F32 mHTTPTime;
|
||||
F32 mGLCreationTime;
|
||||
|
||||
F32 mTotalFetchingTime;
|
||||
F32 mRefetchVisCacheTime;
|
||||
F32 mRefetchVisHTTPTime;
|
||||
|
||||
LLTimer mTimer;
|
||||
|
||||
LLTextureFetch* mFetcher;
|
||||
LLTextureCache* mTextureCache;
|
||||
LLImageDecodeThread* mImageDecodeThread;
|
||||
LLCurlRequest* mCurlGetRequest;
|
||||
|
||||
S32 mNumFetchedTextures;
|
||||
S32 mNumCacheHits;
|
||||
S32 mNumVisibleFetchedTextures;
|
||||
S32 mNumVisibleFetchingRequests;
|
||||
U32 mFetchedData;
|
||||
U32 mDecodedData;
|
||||
U32 mVisibleFetchedData;
|
||||
U32 mVisibleDecodedData;
|
||||
U32 mRenderedData;
|
||||
U32 mRenderedDecodedData;
|
||||
U32 mFetchedPixels;
|
||||
U32 mRenderedPixels;
|
||||
U32 mRefetchedData;
|
||||
U32 mRefetchedPixels;
|
||||
|
||||
BOOL mFreezeHistory;
|
||||
|
||||
std::string mHTTPUrl;
|
||||
S32 mNbCurlRequests;
|
||||
S32 mNbCurlCompleted;
|
||||
|
||||
public:
|
||||
bool update(); //called in the main thread once per frame
|
||||
|
||||
//fetching history
|
||||
void clearHistory();
|
||||
void addHistoryEntry(LLTextureFetchWorker* worker);
|
||||
|
||||
void setCurlGetRequest(LLCurlRequest* request) { mCurlGetRequest = request;}
|
||||
|
||||
void startDebug();
|
||||
void stopDebug(); //stop everything
|
||||
void debugCacheRead();
|
||||
void debugCacheWrite();
|
||||
void debugHTTP();
|
||||
void debugDecoder();
|
||||
void debugGLTextureCreation();
|
||||
void debugRefetchVisibleFromCache();
|
||||
void debugRefetchVisibleFromHTTP();
|
||||
|
||||
void callbackCacheRead(S32 id, bool success, LLImageFormatted* image,
|
||||
S32 imagesize, BOOL islocal);
|
||||
void callbackCacheWrite(S32 id, bool success);
|
||||
void callbackDecoded(S32 id, bool success, LLImageRaw* raw, LLImageRaw* aux);
|
||||
void callbackHTTP(S32 id, const LLChannelDescriptors& channels,
|
||||
const LLIOPipe::buffer_ptr_t& buffer,
|
||||
bool partial, bool success);
|
||||
|
||||
|
||||
e_debug_state getState() {return mState;}
|
||||
S32 getNumFetchedTextures() {return mNumFetchedTextures;}
|
||||
S32 getNumFetchingRequests() {return mFetchingHistory.size();}
|
||||
S32 getNumCacheHits() {return mNumCacheHits;}
|
||||
S32 getNumVisibleFetchedTextures() {return mNumVisibleFetchedTextures;}
|
||||
S32 getNumVisibleFetchingRequests() {return mNumVisibleFetchingRequests;}
|
||||
U32 getFetchedData() {return mFetchedData;}
|
||||
U32 getDecodedData() {return mDecodedData;}
|
||||
U32 getVisibleFetchedData() {return mVisibleFetchedData;}
|
||||
U32 getVisibleDecodedData() {return mVisibleDecodedData;}
|
||||
U32 getRenderedData() {return mRenderedData;}
|
||||
U32 getRenderedDecodedData() {return mRenderedDecodedData;}
|
||||
U32 getFetchedPixels() {return mFetchedPixels;}
|
||||
U32 getRenderedPixels() {return mRenderedPixels;}
|
||||
U32 getRefetchedData() {return mRefetchedData;}
|
||||
U32 getRefetchedPixels() {return mRefetchedPixels;}
|
||||
|
||||
F32 getCacheReadTime() {return mCacheReadTime;}
|
||||
F32 getCacheWriteTime() {return mCacheWriteTime;}
|
||||
F32 getDecodeTime() {return mDecodingTime;}
|
||||
F32 getGLCreationTime() {return mGLCreationTime;}
|
||||
F32 getHTTPTime() {return mHTTPTime;}
|
||||
F32 getTotalFetchingTime() {return mTotalFetchingTime;}
|
||||
F32 getRefetchVisCacheTime() {return mRefetchVisCacheTime;}
|
||||
F32 getRefetchVisHTTPTime() {return mRefetchVisHTTPTime;}
|
||||
|
||||
private:
|
||||
void init();
|
||||
void clearTextures();//clear fetching results of all textures.
|
||||
void clearCache();
|
||||
|
||||
void lockFetcher();
|
||||
void unlockFetcher();
|
||||
|
||||
void lockCache();
|
||||
void unlockCache();
|
||||
|
||||
void lockDecoder();
|
||||
void unlockDecoder();
|
||||
|
||||
S32 fillCurlQueue();
|
||||
|
||||
private:
|
||||
static bool sDebuggerEnabled;
|
||||
public:
|
||||
static bool isEnabled() {return sDebuggerEnabled;}
|
||||
};
|
||||
#endif // LL_LLTEXTUREFETCH_H
|
||||
|
||||
|
|
|
|||
|
|
@ -57,8 +57,6 @@
|
|||
extern F32 texmem_lower_bound_scale;
|
||||
|
||||
LLTextureView *gTextureView = NULL;
|
||||
LLTextureSizeView *gTextureSizeView = NULL;
|
||||
LLTextureSizeView *gTextureCategoryView = NULL;
|
||||
|
||||
#define HIGH_PRIORITY 100000000.f
|
||||
|
||||
|
|
@ -512,8 +510,8 @@ void LLGLTexMemBar::draw()
|
|||
F32 discard_bias = LLViewerTexture::sDesiredDiscardBias;
|
||||
F32 cache_usage = (F32)BYTES_TO_MEGA_BYTES(LLAppViewer::getTextureCache()->getUsage()) ;
|
||||
F32 cache_max_usage = (F32)BYTES_TO_MEGA_BYTES(LLAppViewer::getTextureCache()->getMaxUsage()) ;
|
||||
S32 line_height = LLFontGL::getFontMonospace()->getLineHeight();
|
||||
S32 v_offset = (S32)((texture_bar_height + 2.2f) * mTextureView->mNumTextureBars + 2.0f);
|
||||
S32 line_height = (S32)(LLFontGL::getFontMonospace()->getLineHeight() + .5f);
|
||||
S32 v_offset = 0;//(S32)((texture_bar_height + 2.2f) * mTextureView->mNumTextureBars + 2.0f);
|
||||
F32 total_texture_downloaded = (F32)gTotalTextureBytes / (1024 * 1024);
|
||||
F32 total_object_downloaded = (F32)gTotalObjectBytes / (1024 * 1024);
|
||||
U32 total_http_requests = LLAppViewer::getTextureFetch()->getTotalNumHTTPRequests() ;
|
||||
|
|
@ -527,80 +525,24 @@ void LLGLTexMemBar::draw()
|
|||
LLFontGL::getFontMonospace()->renderUTF8(text, 0, 0, v_offset + line_height*6,
|
||||
text_color, LLFontGL::LEFT, LLFontGL::TOP);
|
||||
|
||||
text = llformat("GL Tot: %d/%d MB Bound: %d/%d MB FBO: %d MB Raw Tot: %d MB Bias: %.2f Cache: %.1f/%.1f MB Net Tot Tex: %.1f MB Tot Obj: %.1f MB Tot Htp: %d",
|
||||
text = llformat("GL Tot: %d/%d MB Bound: %d/%d MB FBO: %d MB Raw Tot: %d MB Bias: %.2f Cache: %.1f/%.1f MB",
|
||||
total_mem,
|
||||
max_total_mem,
|
||||
bound_mem,
|
||||
max_bound_mem,
|
||||
LLRenderTarget::sBytesAllocated/(1024*1024),
|
||||
LLImageRaw::sGlobalRawMemory >> 20, discard_bias,
|
||||
cache_usage, cache_max_usage, total_texture_downloaded, total_object_downloaded, total_http_requests);
|
||||
//, cache_entries, cache_max_entries
|
||||
cache_usage, cache_max_usage);
|
||||
LLFontGL::getFontMonospace()->renderUTF8(text, 0, 0, v_offset + line_height*4,
|
||||
text_color, LLFontGL::LEFT, LLFontGL::TOP);
|
||||
|
||||
text = llformat("Net Tot Tex: %.1f MB Tot Obj: %.1f MB Tot Htp: %d",
|
||||
total_texture_downloaded, total_object_downloaded, total_http_requests);
|
||||
//, cache_entries, cache_max_entries
|
||||
LLFontGL::getFontMonospace()->renderUTF8(text, 0, 0, v_offset + line_height*3,
|
||||
text_color, LLFontGL::LEFT, LLFontGL::TOP);
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
#if 0
|
||||
S32 bar_left = 400;
|
||||
S32 bar_width = 200;
|
||||
S32 top = line_height*3 - 2 + v_offset;
|
||||
S32 bottom = top - 6;
|
||||
S32 left = bar_left;
|
||||
S32 right = left + bar_width;
|
||||
F32 bar_scale;
|
||||
|
||||
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
|
||||
|
||||
// GL Mem Bar
|
||||
|
||||
left = bar_left;
|
||||
text = "GL";
|
||||
LLFontGL::getFontMonospace()->renderUTF8(text, 0, left, line_height*3,
|
||||
text_color, LLFontGL::LEFT, LLFontGL::TOP);
|
||||
|
||||
left = bar_left+20;
|
||||
right = left + bar_width;
|
||||
|
||||
gGL.color4f(0.5f, 0.5f, 0.5f, 0.75f); // grey
|
||||
gl_rect_2d(left, top, right, bottom);
|
||||
|
||||
bar_scale = (F32)bar_width / (max_total_mem * 1.5f);
|
||||
right = left + llfloor(total_mem * bar_scale);
|
||||
right = llclamp(right, bar_left, bar_left + bar_width);
|
||||
|
||||
color = (total_mem < llfloor(max_total_mem * texmem_lower_bound_scale)) ? LLColor4::green :
|
||||
(total_mem < max_total_mem) ? LLColor4::yellow : LLColor4::red;
|
||||
color[VALPHA] = .75f;
|
||||
gGL.diffuseColor4fv(color.mV);
|
||||
|
||||
gl_rect_2d(left, top, right, bottom); // red/yellow/green
|
||||
|
||||
//
|
||||
bar_left += bar_width + bar_space;
|
||||
//top = bottom - 2; bottom = top - 6;
|
||||
|
||||
// Bound Mem Bar
|
||||
|
||||
left = bar_left;
|
||||
text = "GL";
|
||||
LLFontGL::getFontMonospace()->renderUTF8(text, 0, left, line_height*3,
|
||||
text_color, LLFontGL::LEFT, LLFontGL::TOP);
|
||||
left = bar_left + 20;
|
||||
right = left + bar_width;
|
||||
|
||||
gGL.color4f(0.5f, 0.5f, 0.5f, 0.75f);
|
||||
gl_rect_2d(left, top, right, bottom);
|
||||
|
||||
color = (bound_mem < llfloor(max_bound_mem * texmem_lower_bound_scale)) ? LLColor4::green :
|
||||
(bound_mem < max_bound_mem) ? LLColor4::yellow : LLColor4::red;
|
||||
color[VALPHA] = .75f;
|
||||
gGL.diffuseColor4fv(color.mV);
|
||||
|
||||
gl_rect_2d(left, top, right, bottom);
|
||||
#else
|
||||
S32 left = 0 ;
|
||||
#endif
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
text = llformat("Textures: %d Fetch: %d(%d) Pkts:%d(%d) Cache R/W: %d/%d LFS:%d RAW:%d HTP:%d DEC:%d CRE:%d",
|
||||
|
|
@ -669,8 +611,7 @@ BOOL LLGLTexMemBar::handleMouseDown(S32 x, S32 y, MASK mask)
|
|||
LLRect LLGLTexMemBar::getRequiredRect()
|
||||
{
|
||||
LLRect rect;
|
||||
//rect.mTop = 50;
|
||||
rect.mTop = 0;
|
||||
rect.mTop = 50; //LLFontGL::getFontMonospace()->getLineHeight() * 6;
|
||||
return rect;
|
||||
}
|
||||
|
||||
|
|
@ -954,9 +895,11 @@ void LLTextureView::draw()
|
|||
LLRect tmbr;
|
||||
tmbp.name("gl texmem bar");
|
||||
tmbp.rect(tmbr);
|
||||
tmbp.follows.flags = FOLLOWS_LEFT|FOLLOWS_TOP;
|
||||
tmbp.texture_view(this);
|
||||
mGLTexMemBar = LLUICtrlFactory::create<LLGLTexMemBar>(tmbp);
|
||||
addChildInBack(mGLTexMemBar);
|
||||
addChild(mGLTexMemBar);
|
||||
sendChildToFront(mGLTexMemBar);
|
||||
|
||||
LLAvatarTexBar::Params atbp;
|
||||
LLRect atbr;
|
||||
|
|
@ -965,16 +908,13 @@ void LLTextureView::draw()
|
|||
atbp.rect(atbr);
|
||||
mAvatarTexBar = LLUICtrlFactory::create<LLAvatarTexBar>(atbp);
|
||||
addChild(mAvatarTexBar);
|
||||
sendChildToFront(mAvatarTexBar);
|
||||
|
||||
reshape(getRect().getWidth(), getRect().getHeight(), TRUE);
|
||||
|
||||
/*
|
||||
count = gTextureList.getNumImages();
|
||||
std::string info_string;
|
||||
info_string = llformat("Global Info:\nTexture Count: %d", count);
|
||||
mInfoTextp->setText(info_string);
|
||||
*/
|
||||
|
||||
LLUI::popMatrix();
|
||||
LLUI::pushMatrix();
|
||||
LLUI::translate((F32)getRect().mLeft, (F32)getRect().mBottom);
|
||||
|
||||
for (child_list_const_iter_t child_iter = getChildList()->begin();
|
||||
child_iter != getChildList()->end(); ++child_iter)
|
||||
|
|
@ -1049,302 +989,4 @@ BOOL LLTextureView::handleKey(KEY key, MASK mask, BOOL called_from_parent)
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------
|
||||
LLTextureSizeView::LLTextureSizeView(const LLTextureSizeView::Params& p) : LLContainerView(p)
|
||||
{
|
||||
setVisible(FALSE) ;
|
||||
|
||||
mTextureSizeBarWidth = 30 ;
|
||||
}
|
||||
|
||||
LLTextureSizeView::~LLTextureSizeView()
|
||||
{
|
||||
if(mTextureSizeBar.size())
|
||||
{
|
||||
for(U32 i = 0 ; i < mTextureSizeBar.size() ; i++)
|
||||
{
|
||||
delete mTextureSizeBar[i] ;
|
||||
}
|
||||
mTextureSizeBar.clear() ;
|
||||
}
|
||||
}
|
||||
void LLTextureSizeView::draw()
|
||||
{
|
||||
if(mType == TEXTURE_MEM_OVER_SIZE)
|
||||
{
|
||||
drawTextureSizeGraph();
|
||||
}
|
||||
else
|
||||
{
|
||||
drawTextureCategoryGraph() ;
|
||||
}
|
||||
|
||||
LLView::draw();
|
||||
}
|
||||
|
||||
BOOL LLTextureSizeView::handleHover(S32 x, S32 y, MASK mask)
|
||||
{
|
||||
if(x > mTextureSizeBarRect.mLeft && x < mTextureSizeBarRect.mRight)
|
||||
{
|
||||
mTextureSizeBar[(x - mTextureSizeBarRect.mLeft) / mTextureSizeBarWidth]->handleHover(x, y, mask, (mType == TEXTURE_MEM_OVER_SIZE)) ;
|
||||
}
|
||||
|
||||
return TRUE ;
|
||||
}
|
||||
|
||||
//draw real-time texture mem bar over size
|
||||
void LLTextureSizeView::drawTextureSizeGraph()
|
||||
{
|
||||
if(mTextureSizeBar.size() == 0)
|
||||
{
|
||||
S32 line_height = LLFontGL::getFontMonospace()->getLineHeight();
|
||||
mTextureSizeBar.resize(LLImageGL::sTextureLoadedCounter.size()) ;
|
||||
mTextureSizeBarRect.set(700, line_height * 2 + 400, 700 + mTextureSizeBar.size() * mTextureSizeBarWidth, line_height * 2) ;
|
||||
|
||||
for(U32 i = 0 ; i < mTextureSizeBar.size() ; i++)
|
||||
{
|
||||
mTextureSizeBar[i] = new LLGLTexSizeBar(i, mTextureSizeBarRect.mLeft + i * mTextureSizeBarWidth ,
|
||||
line_height * 2, mTextureSizeBarRect.mLeft + (i + 1) * mTextureSizeBarWidth, line_height) ;
|
||||
}
|
||||
}
|
||||
|
||||
F32 size_bar_scale = drawTextureSizeDistributionGraph() ;
|
||||
for(U32 i = 0 ; i < mTextureSizeBar.size() ; i++)
|
||||
{
|
||||
mTextureSizeBar[i]->setTop(LLImageGL::sTextureLoadedCounter[i], LLImageGL::sTextureBoundCounter[i], size_bar_scale) ;
|
||||
mTextureSizeBar[i]->draw() ;
|
||||
}
|
||||
LLImageGL::resetCurTexSizebar();
|
||||
}
|
||||
|
||||
//draw background of texture size bar graph
|
||||
F32 LLTextureSizeView::drawTextureSizeDistributionGraph()
|
||||
{
|
||||
//scale
|
||||
F32 scale = 1.0f ;
|
||||
|
||||
LLGLSUIDefault gls_ui;
|
||||
|
||||
{
|
||||
S32 count = 0 ;
|
||||
for(U32 i = 0 ; i < LLImageGL::sTextureLoadedCounter.size() ; i++)
|
||||
{
|
||||
if(LLImageGL::sTextureLoadedCounter[i] > count)
|
||||
{
|
||||
count = LLImageGL::sTextureLoadedCounter[i] ;
|
||||
}
|
||||
}
|
||||
if(count > mTextureSizeBarRect.getHeight())
|
||||
{
|
||||
scale = (F32)mTextureSizeBarRect.getHeight() / count ;
|
||||
}
|
||||
}
|
||||
|
||||
S32 line_height = LLFontGL::getFontMonospace()->getLineHeight();
|
||||
S32 left = mTextureSizeBarRect.mLeft ;
|
||||
S32 bottom = mTextureSizeBarRect.mBottom ;
|
||||
S32 right = mTextureSizeBarRect.mRight ;
|
||||
S32 top = mTextureSizeBarRect.mTop ;
|
||||
|
||||
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
|
||||
|
||||
//background rect
|
||||
gl_rect_2d(left - 25, top + 30, right + 100, bottom - 25, LLColor4(0.0f, 0.0f, 0.0f, 0.25f)) ;
|
||||
|
||||
//--------------------------------------------------
|
||||
gGL.color4f(1.0f, 0.5f, 0.5f, 0.75f);
|
||||
gl_line_2d(left, bottom, right, bottom) ; //x axis
|
||||
gl_line_2d(left, bottom, left, top) ; //y axis
|
||||
|
||||
//ruler
|
||||
//--------------------------------------------------
|
||||
gGL.color4f(1.0f, 0.5f, 0.5f, 0.5f);
|
||||
for(S32 i = bottom + 50 ; i <= top ; i += 50)
|
||||
{
|
||||
gl_line_2d(left, i, right, i) ;
|
||||
}
|
||||
|
||||
//texts
|
||||
//--------------------------------------------------
|
||||
F32 text_color[] = {1.f, 1.f, 1.f, 0.75f};
|
||||
std::string text;
|
||||
|
||||
//-------
|
||||
//x axis: size label
|
||||
text = llformat("%d", 0) ;
|
||||
LLFontGL::getFontMonospace()->renderUTF8(text, 0, left + 12, bottom - line_height / 2,
|
||||
text_color, LLFontGL::LEFT, LLFontGL::TOP);
|
||||
for(U32 i = 1 ; i < mTextureSizeBar.size() ; i++)
|
||||
{
|
||||
text = llformat("%d", (1 << (i / 2)) + ((i & 1) ? ((1 << (i / 2)) >> 1) : 0)) ;
|
||||
LLFontGL::getFontMonospace()->renderUTF8(text, 0, left + i * mTextureSizeBarWidth + 12, bottom - line_height / 2,
|
||||
text_color, LLFontGL::LEFT, LLFontGL::TOP);
|
||||
}
|
||||
text = llformat("(w + h)/2") ;
|
||||
LLFontGL::getFontMonospace()->renderUTF8(text, 0, right + 10, bottom - line_height / 2,
|
||||
text_color, LLFontGL::LEFT, LLFontGL::TOP);
|
||||
//-------
|
||||
|
||||
//y axis: number label
|
||||
for(S32 i = bottom + 50 ; i <= top ; i += 50)
|
||||
{
|
||||
text = llformat("%d", (S32)((i - bottom) / scale)) ;
|
||||
LLFontGL::getFontMonospace()->renderUTF8(text, 0, left - 20, i + line_height / 2 ,
|
||||
text_color, LLFontGL::LEFT, LLFontGL::TOP);
|
||||
LLFontGL::getFontMonospace()->renderUTF8(text, 0, right + 5, i + line_height / 2 ,
|
||||
text_color, LLFontGL::LEFT, LLFontGL::TOP);
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
F32 loaded_color[] = {1.0f, 0.0f, 0.0f, 0.75f};
|
||||
gl_rect_2d(left + 70, top + line_height * 2, left + 90, top + line_height, loaded_color) ;
|
||||
text = llformat("Loaded") ;
|
||||
LLFontGL::getFontMonospace()->renderUTF8(text, 0, left + 100, top + line_height * 2,
|
||||
loaded_color, LLFontGL::LEFT, LLFontGL::TOP);
|
||||
|
||||
F32 bound_color[] = {1.0f, 1.0f, 0.0f, 0.75f};
|
||||
gl_rect_2d(left + 170, top + line_height * 2, left + 190, top + line_height, bound_color) ;
|
||||
text = llformat("Bound") ;
|
||||
LLFontGL::getFontMonospace()->renderUTF8(text, 0, left + 200, top + line_height * 2,
|
||||
bound_color, LLFontGL::LEFT, LLFontGL::TOP);
|
||||
|
||||
//--------------------------------------------------
|
||||
|
||||
//title
|
||||
text = llformat("Texture Size Distribution") ;
|
||||
LLFontGL::getFontMonospace()->renderUTF8(text, 0, left + 250, top + line_height * 3,
|
||||
text_color, LLFontGL::LEFT, LLFontGL::TOP);
|
||||
return scale ;
|
||||
}
|
||||
|
||||
//draw real-time texture mem bar over category
|
||||
void LLTextureSizeView::drawTextureCategoryGraph()
|
||||
{
|
||||
if(mTextureSizeBar.size() == 0)
|
||||
{
|
||||
S32 line_height = LLFontGL::getFontMonospace()->getLineHeight();
|
||||
mTextureSizeBar.resize(LLViewerTexture::getTotalNumOfCategories()) ;
|
||||
mTextureSizeBarRect.set(700, line_height * 2 + 400, 700 + mTextureSizeBar.size() * mTextureSizeBarWidth, line_height * 2) ;
|
||||
|
||||
for(U32 i = 0 ; i < mTextureSizeBar.size() ; i++)
|
||||
{
|
||||
mTextureSizeBar[i] = new LLGLTexSizeBar(i, mTextureSizeBarRect.mLeft + i * mTextureSizeBarWidth ,
|
||||
line_height * 2, mTextureSizeBarRect.mLeft + (i + 1) * mTextureSizeBarWidth, line_height) ;
|
||||
}
|
||||
}
|
||||
|
||||
F32 size_bar_scale = drawTextureCategoryDistributionGraph() ;
|
||||
for(U32 i = 0 ; i < mTextureSizeBar.size() ; i++)
|
||||
{
|
||||
U32 k = LLViewerTexture::getIndexFromCategory(i) ;
|
||||
mTextureSizeBar[i]->setTop(LLImageGL::sTextureMemByCategory[k] >> 20, LLImageGL::sTextureMemByCategoryBound[k] >> 20, size_bar_scale) ;
|
||||
mTextureSizeBar[i]->draw() ;
|
||||
}
|
||||
LLImageGL::resetCurTexSizebar();
|
||||
}
|
||||
|
||||
//draw background for TEXTURE_MEM_OVER_CATEGORY
|
||||
F32 LLTextureSizeView::drawTextureCategoryDistributionGraph()
|
||||
{
|
||||
//scale
|
||||
F32 scale = 4.0f ;
|
||||
|
||||
LLGLSUIDefault gls_ui;
|
||||
|
||||
{
|
||||
S32 count = 0 ;
|
||||
for(U32 i = 0 ; i < LLImageGL::sTextureMemByCategory.size() ; i++)
|
||||
{
|
||||
S32 tmp = LLImageGL::sTextureMemByCategory[i] >> 20 ;
|
||||
if(tmp > count)
|
||||
{
|
||||
count = tmp ;
|
||||
}
|
||||
}
|
||||
if(count > mTextureSizeBarRect.getHeight() * 0.25f)
|
||||
{
|
||||
scale = (F32)mTextureSizeBarRect.getHeight() * 0.25f / count ;
|
||||
}
|
||||
}
|
||||
|
||||
S32 line_height = LLFontGL::getFontMonospace()->getLineHeight();
|
||||
S32 left = mTextureSizeBarRect.mLeft ;
|
||||
S32 bottom = mTextureSizeBarRect.mBottom ;
|
||||
S32 right = mTextureSizeBarRect.mRight ;
|
||||
S32 top = mTextureSizeBarRect.mTop ;
|
||||
|
||||
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
|
||||
|
||||
//background rect
|
||||
gl_rect_2d(left - 25, top + 30, right + 100, bottom - 25, LLColor4(0.0f, 0.0f, 0.0f, 0.25f)) ;
|
||||
|
||||
//--------------------------------------------------
|
||||
gGL.color4f(1.0f, 0.5f, 0.5f, 0.75f);
|
||||
gl_line_2d(left, bottom, right, bottom) ; //x axis
|
||||
gl_line_2d(left, bottom, left, top) ; //y axis
|
||||
|
||||
//ruler
|
||||
//--------------------------------------------------
|
||||
gGL.color4f(1.0f, 0.5f, 0.5f, 0.5f);
|
||||
for(S32 i = bottom + 50 ; i <= top ; i += 50)
|
||||
{
|
||||
gl_line_2d(left, i, right, i) ;
|
||||
}
|
||||
|
||||
//texts
|
||||
//--------------------------------------------------
|
||||
F32 text_color[] = {1.f, 1.f, 1.f, 0.75f};
|
||||
std::string text;
|
||||
|
||||
//-------
|
||||
//x axis: size label
|
||||
static char category[LLViewerTexture::MAX_GL_IMAGE_CATEGORY][4] =
|
||||
{"Non", "Bak", "Av", "Cld", "Scp", "Hi", "Trn", "Slt", "Hud", "Bsf", "UI", "Pvw", "Map", "Mvs", "Slf", "Loc", "Scr", "Dyn", "Mdi", "ALT", "Oth" } ;
|
||||
|
||||
text = llformat("%s", category[0]) ;
|
||||
LLFontGL::getFontMonospace()->renderUTF8(text, 0, left + 12, bottom - line_height / 2,
|
||||
text_color, LLFontGL::LEFT, LLFontGL::TOP);
|
||||
for(U32 i = 1 ; i < mTextureSizeBar.size() ; i++)
|
||||
{
|
||||
text = llformat("%s", category[i]) ;
|
||||
LLFontGL::getFontMonospace()->renderUTF8(text, 0, left + i * mTextureSizeBarWidth + 12, bottom - line_height / 2,
|
||||
text_color, LLFontGL::LEFT, LLFontGL::TOP);
|
||||
}
|
||||
//-------
|
||||
|
||||
//y axis: number label
|
||||
for(S32 i = bottom + 50 ; i <= top ; i += 50)
|
||||
{
|
||||
text = llformat("%d", (S32)((i - bottom) / scale)) ;
|
||||
LLFontGL::getFontMonospace()->renderUTF8(text, 0, left - 20, i + line_height / 2 ,
|
||||
text_color, LLFontGL::LEFT, LLFontGL::TOP);
|
||||
LLFontGL::getFontMonospace()->renderUTF8(text, 0, right + 5, i + line_height / 2 ,
|
||||
text_color, LLFontGL::LEFT, LLFontGL::TOP);
|
||||
}
|
||||
|
||||
text = llformat("MB") ;
|
||||
LLFontGL::getFontMonospace()->renderUTF8(text, 0, left - 20, top + line_height * 2 ,
|
||||
text_color, LLFontGL::LEFT, LLFontGL::TOP);
|
||||
//--------------------------------------------------
|
||||
F32 loaded_color[] = {1.0f, 0.0f, 0.0f, 0.75f};
|
||||
gl_rect_2d(left + 70, top + line_height * 2, left + 90, top + line_height, loaded_color) ;
|
||||
text = llformat("Loaded") ;
|
||||
LLFontGL::getFontMonospace()->renderUTF8(text, 0, left + 100, top + line_height * 2,
|
||||
loaded_color,
|
||||
LLFontGL::LEFT, LLFontGL::TOP);
|
||||
|
||||
F32 bound_color[] = {1.0f, 1.0f, 0.0f, 0.75f};
|
||||
gl_rect_2d(left + 170, top + line_height * 2, left + 190, top + line_height, bound_color) ;
|
||||
text = llformat("Bound") ;
|
||||
LLFontGL::getFontMonospace()->renderUTF8(text, 0, left + 200, top + line_height * 2,
|
||||
bound_color, LLFontGL::LEFT, LLFontGL::TOP);
|
||||
|
||||
//--------------------------------------------------
|
||||
|
||||
//title
|
||||
text = llformat("Texture Category Distribution") ;
|
||||
LLFontGL::getFontMonospace()->renderUTF8(text, 0, left + 250, top + line_height * 3,
|
||||
text_color, LLFontGL::LEFT, LLFontGL::TOP);
|
||||
|
||||
return scale ;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -75,41 +75,6 @@ public:
|
|||
};
|
||||
|
||||
class LLGLTexSizeBar;
|
||||
class LLTextureSizeView : public LLContainerView
|
||||
{
|
||||
protected:
|
||||
LLTextureSizeView(const Params&);
|
||||
friend class LLUICtrlFactory;
|
||||
public:
|
||||
~LLTextureSizeView();
|
||||
|
||||
/*virtual*/ void draw();
|
||||
/*virtual*/ BOOL handleHover(S32 x, S32 y, MASK mask) ;
|
||||
|
||||
void setType(S32 type) {mType = type ;}
|
||||
enum
|
||||
{
|
||||
TEXTURE_MEM_OVER_SIZE,
|
||||
TEXTURE_MEM_OVER_CATEGORY
|
||||
};
|
||||
private:
|
||||
//draw background for TEXTURE_MEM_OVER_SIZE
|
||||
F32 drawTextureSizeDistributionGraph() ;
|
||||
//draw real-time texture mem bar over size
|
||||
void drawTextureSizeGraph();
|
||||
|
||||
//draw background for TEXTURE_MEM_OVER_CATEGORY
|
||||
F32 drawTextureCategoryDistributionGraph() ;
|
||||
//draw real-time texture mem bar over category
|
||||
void drawTextureCategoryGraph();
|
||||
|
||||
private:
|
||||
std::vector<LLGLTexSizeBar*> mTextureSizeBar ;
|
||||
LLRect mTextureSizeBarRect ;
|
||||
S32 mTextureSizeBarWidth ;
|
||||
S32 mType ;
|
||||
};
|
||||
extern LLTextureView *gTextureView;
|
||||
extern LLTextureSizeView *gTextureSizeView;
|
||||
extern LLTextureSizeView *gTextureCategoryView;
|
||||
#endif // LL_TEXTURE_VIEW_H
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@
|
|||
#include "llregionhandle.h"
|
||||
|
||||
#include "stdtypes.h"
|
||||
#include "llvoavatar.h"
|
||||
|
||||
/*
|
||||
* Classes and utility functions for per-thread and per-region
|
||||
|
|
@ -126,6 +127,8 @@ LLViewerAssetStats::PerRegionStats::merge(const LLViewerAssetStats::PerRegionSta
|
|||
mFPS.merge(src.mFPS);
|
||||
}
|
||||
|
||||
// Avatar stats - data all comes from main thread, so leave alone.
|
||||
|
||||
// Requests
|
||||
for (int i = 0; i < LL_ARRAY_SIZE(mRequests); ++i)
|
||||
{
|
||||
|
|
@ -133,6 +136,7 @@ LLViewerAssetStats::PerRegionStats::merge(const LLViewerAssetStats::PerRegionSta
|
|||
mRequests[i].mDequeued.merge(src.mRequests[i].mDequeued);
|
||||
mRequests[i].mResponse.merge(src.mRequests[i].mResponse);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -156,7 +160,9 @@ LLViewerAssetStats::LLViewerAssetStats()
|
|||
|
||||
LLViewerAssetStats::LLViewerAssetStats(const LLViewerAssetStats & src)
|
||||
: mRegionHandle(src.mRegionHandle),
|
||||
mResetTimestamp(src.mResetTimestamp)
|
||||
mResetTimestamp(src.mResetTimestamp),
|
||||
mPhaseStats(src.mPhaseStats),
|
||||
mAvatarRezStates(src.mAvatarRezStates)
|
||||
{
|
||||
const PerRegionContainer::const_iterator it_end(src.mRegionStats.end());
|
||||
for (PerRegionContainer::const_iterator it(src.mRegionStats.begin()); it_end != it; ++it)
|
||||
|
|
@ -252,6 +258,17 @@ LLViewerAssetStats::recordFPS(F32 fps)
|
|||
mCurRegionStats->mFPS.record(fps);
|
||||
}
|
||||
|
||||
void
|
||||
LLViewerAssetStats::recordAvatarStats()
|
||||
{
|
||||
std::vector<S32> rez_counts;
|
||||
LLVOAvatar::getNearbyRezzedStats(rez_counts);
|
||||
mAvatarRezStates = rez_counts;
|
||||
mPhaseStats.clear();
|
||||
mPhaseStats["cloud"] = LLViewerStats::PhaseMap::getPhaseStats("cloud");
|
||||
mPhaseStats["cloud-or-gray"] = LLViewerStats::PhaseMap::getPhaseStats("cloud-or-gray");
|
||||
}
|
||||
|
||||
LLSD
|
||||
LLViewerAssetStats::asLLSD(bool compact_output)
|
||||
{
|
||||
|
|
@ -282,6 +299,11 @@ LLViewerAssetStats::asLLSD(bool compact_output)
|
|||
static const LLSD::String max_tag("max");
|
||||
static const LLSD::String mean_tag("mean");
|
||||
|
||||
// Avatar sub-tags
|
||||
static const LLSD::String avatar_tag("avatar");
|
||||
static const LLSD::String avatar_nearby_tag("nearby");
|
||||
static const LLSD::String avatar_phase_stats_tag("phase_stats");
|
||||
|
||||
const duration_t now = LLViewerAssetStatsFF::get_timestamp();
|
||||
mCurRegionStats->accumulateTime(now);
|
||||
|
||||
|
|
@ -329,7 +351,6 @@ LLViewerAssetStats::asLLSD(bool compact_output)
|
|||
slot[max_tag] = LLSD(F64(stats.mFPS.getMax()));
|
||||
slot[mean_tag] = LLSD(F64(stats.mFPS.getMean()));
|
||||
}
|
||||
|
||||
U32 grid_x(0), grid_y(0);
|
||||
grid_from_region_handle(it->first, &grid_x, &grid_y);
|
||||
reg_stat["grid_x"] = LLSD::Integer(grid_x);
|
||||
|
|
@ -341,6 +362,16 @@ LLViewerAssetStats::asLLSD(bool compact_output)
|
|||
LLSD ret = LLSD::emptyMap();
|
||||
ret["regions"] = regions;
|
||||
ret["duration"] = LLSD::Real((now - mResetTimestamp) * 1.0e-6);
|
||||
LLSD avatar_info;
|
||||
avatar_info[avatar_nearby_tag] = LLSD::emptyArray();
|
||||
for (S32 rez_stat=0; rez_stat < mAvatarRezStates.size(); ++rez_stat)
|
||||
{
|
||||
std::string rez_status_name = LLVOAvatar::rezStatusToString(rez_stat);
|
||||
avatar_info[avatar_nearby_tag][rez_status_name] = mAvatarRezStates[rez_stat];
|
||||
}
|
||||
avatar_info[avatar_phase_stats_tag]["cloud"] = mPhaseStats["cloud"].getData();
|
||||
avatar_info[avatar_phase_stats_tag]["cloud-or-gray"] = mPhaseStats["cloud-or-gray"].getData();
|
||||
ret[avatar_tag] = avatar_info;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -439,6 +470,14 @@ record_fps_main(F32 fps)
|
|||
gViewerAssetStatsMain->recordFPS(fps);
|
||||
}
|
||||
|
||||
void
|
||||
record_avatar_stats()
|
||||
{
|
||||
if (! gViewerAssetStatsMain)
|
||||
return;
|
||||
|
||||
gViewerAssetStatsMain->recordAvatarStats();
|
||||
}
|
||||
|
||||
// 'thread1' - should be for TextureFetch thread
|
||||
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@
|
|||
#include "llviewerassetstorage.h"
|
||||
#include "llsimplestat.h"
|
||||
#include "llsd.h"
|
||||
#include "llvoavatar.h"
|
||||
|
||||
/**
|
||||
* @class LLViewerAssetStats
|
||||
|
|
@ -181,6 +182,9 @@ public:
|
|||
// Frames-Per-Second Samples
|
||||
void recordFPS(F32 fps);
|
||||
|
||||
// Avatar-related statistics
|
||||
void recordAvatarStats();
|
||||
|
||||
// Merge a source instance into a destination instance. This is
|
||||
// conceptually an 'operator+=()' method:
|
||||
// - counts are added
|
||||
|
|
@ -252,6 +256,10 @@ protected:
|
|||
|
||||
// Time of last reset
|
||||
duration_t mResetTimestamp;
|
||||
|
||||
// Nearby avatar stats
|
||||
std::vector<S32> mAvatarRezStates;
|
||||
LLViewerStats::phase_stats_t mPhaseStats;
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -310,6 +318,7 @@ void record_response_main(LLViewerAssetType::EType at, bool with_http, bool is_t
|
|||
|
||||
void record_fps_main(F32 fps);
|
||||
|
||||
void record_avatar_stats();
|
||||
|
||||
/**
|
||||
* Region context, event and duration loggers for Thread 1.
|
||||
|
|
|
|||
|
|
@ -87,7 +87,6 @@ std::string gLastRunVersion;
|
|||
|
||||
extern BOOL gResizeScreenTexture;
|
||||
extern BOOL gDebugGL;
|
||||
extern BOOL gAuditTexture;
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// Listeners
|
||||
|
||||
|
|
@ -411,12 +410,6 @@ static bool handleRenderUseImpostorsChanged(const LLSD& newvalue)
|
|||
return true;
|
||||
}
|
||||
|
||||
static bool handleAuditTextureChanged(const LLSD& newvalue)
|
||||
{
|
||||
gAuditTexture = newvalue.asBoolean();
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool handleRenderDebugGLChanged(const LLSD& newvalue)
|
||||
{
|
||||
gDebugGL = newvalue.asBoolean() || gDebugSession;
|
||||
|
|
@ -618,7 +611,6 @@ void settings_setup_listeners()
|
|||
gSavedSettings.getControl("RenderDeferredSSAO")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _2));
|
||||
gSavedSettings.getControl("RenderPerformanceTest")->getSignal()->connect(boost::bind(&handleRenderPerfTestChanged, _2));
|
||||
gSavedSettings.getControl("TextureMemory")->getSignal()->connect(boost::bind(&handleVideoMemoryChanged, _2));
|
||||
gSavedSettings.getControl("AuditTexture")->getSignal()->connect(boost::bind(&handleAuditTextureChanged, _2));
|
||||
gSavedSettings.getControl("ChatFontSize")->getSignal()->connect(boost::bind(&handleChatFontSizeChanged, _2));
|
||||
gSavedSettings.getControl("ChatPersistTime")->getSignal()->connect(boost::bind(&handleChatPersistTimeChanged, _2));
|
||||
gSavedSettings.getControl("ConsoleMaxLines")->getSignal()->connect(boost::bind(&handleConsoleMaxLinesChanged, _2));
|
||||
|
|
|
|||
|
|
@ -103,6 +103,7 @@
|
|||
#include "llfloatertelehub.h"
|
||||
#include "llfloatertestinspectors.h"
|
||||
#include "llfloatertestlistview.h"
|
||||
#include "llfloatertexturefetchdebugger.h"
|
||||
#include "llfloatertools.h"
|
||||
#include "llfloatertos.h"
|
||||
#include "llfloatertopobjects.h"
|
||||
|
|
@ -227,6 +228,11 @@ void LLViewerFloaterReg::registerFloaters()
|
|||
LLFloaterReg::add("land_holdings", "floater_land_holdings.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterLandHoldings>);
|
||||
|
||||
LLFloaterReg::add("mem_leaking", "floater_mem_leaking.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterMemLeak>);
|
||||
|
||||
if(gSavedSettings.getBOOL("TextureFetchDebuggerEnabled"))
|
||||
{
|
||||
LLFloaterReg::add("tex_fetch_debugger", "floater_texture_fetch_debugger.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterTextureFetchDebugger>);
|
||||
}
|
||||
LLFloaterReg::add("media_settings", "floater_media_settings.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterMediaSettings>);
|
||||
LLFloaterReg::add("message_critical", "floater_critical.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterTOS>);
|
||||
LLFloaterReg::add("message_tos", "floater_tos.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterTOS>);
|
||||
|
|
|
|||
|
|
@ -342,8 +342,8 @@ void LLViewerInventoryItem::cloneViewerItem(LLPointer<LLViewerInventoryItem>& ne
|
|||
|
||||
void LLViewerInventoryItem::removeFromServer()
|
||||
{
|
||||
llinfos << "Removing inventory item " << mUUID << " from server."
|
||||
<< llendl;
|
||||
lldebugs << "Removing inventory item " << mUUID << " from server."
|
||||
<< llendl;
|
||||
|
||||
LLInventoryModel::LLCategoryUpdate up(mParentUUID, -1);
|
||||
gInventory.accountForUpdate(up);
|
||||
|
|
|
|||
|
|
@ -576,7 +576,6 @@ U32 LLViewerJointMesh::drawShape( F32 pixelArea, BOOL first_pass, BOOL is_dummy)
|
|||
{
|
||||
old_mode = mTexture->getAddressMode();
|
||||
}
|
||||
gGL.getTexUnit(diffuse_channel)->bind(mTexture.get());
|
||||
gGL.getTexUnit(diffuse_channel)->bind(mTexture);
|
||||
gGL.getTexUnit(diffuse_channel)->setTextureAddressMode(LLTexUnit::TAM_CLAMP);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -61,6 +61,7 @@ public:
|
|||
//-----------------------------------------------------------------------------
|
||||
class LLViewerJointMesh : public LLViewerJoint
|
||||
{
|
||||
friend class LLVOAvatar;
|
||||
protected:
|
||||
LLColor4 mColor; // color value
|
||||
// LLColor4 mSpecular; // specular color (always white for now)
|
||||
|
|
|
|||
|
|
@ -516,14 +516,6 @@ class LLAdvancedToggleConsole : public view_listener_t
|
|||
{
|
||||
toggle_visibility( (void*)static_cast<LLUICtrl*>(gDebugView->mDebugConsolep));
|
||||
}
|
||||
else if (gTextureSizeView && "texture size" == console_type)
|
||||
{
|
||||
toggle_visibility( (void*)gTextureSizeView );
|
||||
}
|
||||
else if (gTextureCategoryView && "texture category" == console_type)
|
||||
{
|
||||
toggle_visibility( (void*)gTextureCategoryView );
|
||||
}
|
||||
else if ("fast timers" == console_type)
|
||||
{
|
||||
LLFloaterReg::toggleInstance("fast_timers");
|
||||
|
|
@ -556,14 +548,6 @@ class LLAdvancedCheckConsole : public view_listener_t
|
|||
{
|
||||
new_value = get_visibility( (void*)((LLView*)gDebugView->mDebugConsolep) );
|
||||
}
|
||||
else if (gTextureSizeView && "texture size" == console_type)
|
||||
{
|
||||
new_value = get_visibility( (void*)gTextureSizeView );
|
||||
}
|
||||
else if (gTextureCategoryView && "texture category" == console_type)
|
||||
{
|
||||
new_value = get_visibility( (void*)gTextureCategoryView );
|
||||
}
|
||||
else if ("fast timers" == console_type)
|
||||
{
|
||||
new_value = LLFloaterReg::instanceVisible("fast_timers");
|
||||
|
|
@ -866,6 +850,73 @@ class LLAdvancedCheckFeature : public view_listener_t
|
|||
}
|
||||
};
|
||||
|
||||
class LLAdvancedCheckDisplayTextureDensity : public view_listener_t
|
||||
{
|
||||
bool handleEvent(const LLSD& userdata)
|
||||
{
|
||||
std::string mode = userdata.asString();
|
||||
if (!gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_TEXEL_DENSITY))
|
||||
{
|
||||
return mode == "none";
|
||||
}
|
||||
if (mode == "current")
|
||||
{
|
||||
return LLViewerTexture::sDebugTexelsMode == LLViewerTexture::DEBUG_TEXELS_CURRENT;
|
||||
}
|
||||
else if (mode == "desired")
|
||||
{
|
||||
return LLViewerTexture::sDebugTexelsMode == LLViewerTexture::DEBUG_TEXELS_DESIRED;
|
||||
}
|
||||
else if (mode == "full")
|
||||
{
|
||||
return LLViewerTexture::sDebugTexelsMode == LLViewerTexture::DEBUG_TEXELS_FULL;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
class LLAdvancedSetDisplayTextureDensity : public view_listener_t
|
||||
{
|
||||
bool handleEvent(const LLSD& userdata)
|
||||
{
|
||||
std::string mode = userdata.asString();
|
||||
if (mode == "none")
|
||||
{
|
||||
if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_TEXEL_DENSITY) == TRUE)
|
||||
{
|
||||
gPipeline.toggleRenderDebug((void*)LLPipeline::RENDER_DEBUG_TEXEL_DENSITY);
|
||||
}
|
||||
LLViewerTexture::sDebugTexelsMode = LLViewerTexture::DEBUG_TEXELS_OFF;
|
||||
}
|
||||
else if (mode == "current")
|
||||
{
|
||||
if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_TEXEL_DENSITY) == FALSE)
|
||||
{
|
||||
gPipeline.toggleRenderDebug((void*)LLPipeline::RENDER_DEBUG_TEXEL_DENSITY);
|
||||
}
|
||||
LLViewerTexture::sDebugTexelsMode = LLViewerTexture::DEBUG_TEXELS_CURRENT;
|
||||
}
|
||||
else if (mode == "desired")
|
||||
{
|
||||
if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_TEXEL_DENSITY) == FALSE)
|
||||
{
|
||||
gPipeline.toggleRenderDebug((void*)LLPipeline::RENDER_DEBUG_TEXEL_DENSITY);
|
||||
}
|
||||
gPipeline.setRenderDebugFeatureControl(LLPipeline::RENDER_DEBUG_TEXEL_DENSITY, true);
|
||||
LLViewerTexture::sDebugTexelsMode = LLViewerTexture::DEBUG_TEXELS_DESIRED;
|
||||
}
|
||||
else if (mode == "full")
|
||||
{
|
||||
if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_TEXEL_DENSITY) == FALSE)
|
||||
{
|
||||
gPipeline.toggleRenderDebug((void*)LLPipeline::RENDER_DEBUG_TEXEL_DENSITY);
|
||||
}
|
||||
LLViewerTexture::sDebugTexelsMode = LLViewerTexture::DEBUG_TEXELS_FULL;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
//////////////////
|
||||
// INFO DISPLAY //
|
||||
|
|
@ -980,6 +1031,10 @@ U32 info_display_from_string(std::string info_display)
|
|||
{
|
||||
return LLPipeline::RENDER_DEBUG_WIND_VECTORS;
|
||||
}
|
||||
else if ("texel density" == info_display)
|
||||
{
|
||||
return LLPipeline::RENDER_DEBUG_TEXEL_DENSITY;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
|
|
@ -2245,6 +2300,14 @@ class LLDevelopSetLoggingLevel : public view_listener_t
|
|||
}
|
||||
};
|
||||
|
||||
class LLDevelopTextureFetchDebugger : public view_listener_t
|
||||
{
|
||||
bool handleEvent(const LLSD& userdata)
|
||||
{
|
||||
return gSavedSettings.getBOOL("TextureFetchDebuggerEnabled");
|
||||
}
|
||||
};
|
||||
|
||||
//////////////////
|
||||
// ADMIN MENU //
|
||||
//////////////////
|
||||
|
|
@ -8164,6 +8227,10 @@ void initialize_menus()
|
|||
//// Advanced > Render > Features
|
||||
view_listener_t::addMenu(new LLAdvancedToggleFeature(), "Advanced.ToggleFeature");
|
||||
view_listener_t::addMenu(new LLAdvancedCheckFeature(), "Advanced.CheckFeature");
|
||||
|
||||
view_listener_t::addMenu(new LLAdvancedCheckDisplayTextureDensity(), "Advanced.CheckDisplayTextureDensity");
|
||||
view_listener_t::addMenu(new LLAdvancedSetDisplayTextureDensity(), "Advanced.SetDisplayTextureDensity");
|
||||
|
||||
// Advanced > Render > Info Displays
|
||||
view_listener_t::addMenu(new LLAdvancedToggleInfoDisplay(), "Advanced.ToggleInfoDisplay");
|
||||
view_listener_t::addMenu(new LLAdvancedCheckInfoDisplay(), "Advanced.CheckInfoDisplay");
|
||||
|
|
@ -8295,6 +8362,9 @@ void initialize_menus()
|
|||
// Develop >Set logging level
|
||||
view_listener_t::addMenu(new LLDevelopCheckLoggingLevel(), "Develop.CheckLoggingLevel");
|
||||
view_listener_t::addMenu(new LLDevelopSetLoggingLevel(), "Develop.SetLoggingLevel");
|
||||
|
||||
//Develop (Texture Fetch Debug Console)
|
||||
view_listener_t::addMenu(new LLDevelopTextureFetchDebugger(), "Develop.SetTexFetchDebugger");
|
||||
|
||||
// Admin >Object
|
||||
view_listener_t::addMenu(new LLAdminForceTakeCopy(), "Admin.ForceTakeCopy");
|
||||
|
|
|
|||
|
|
@ -91,8 +91,9 @@ extern LLPipeline gPipeline;
|
|||
|
||||
// Statics for object lookup tables.
|
||||
U32 LLViewerObjectList::sSimulatorMachineIndex = 1; // Not zero deliberately, to speed up index check.
|
||||
std::map<U64, U32> LLViewerObjectList::sIPAndPortToIndex;
|
||||
std::map<U64, U32> LLViewerObjectList::sIPAndPortToIndex;
|
||||
std::map<U64, LLUUID> LLViewerObjectList::sIndexAndLocalIDToUUID;
|
||||
LLStat LLViewerObjectList::sCacheHitRate("object_cache_hits", 128);
|
||||
|
||||
LLViewerObjectList::LLViewerObjectList()
|
||||
{
|
||||
|
|
@ -542,6 +543,8 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys,
|
|||
}
|
||||
justCreated = TRUE;
|
||||
mNumNewObjects++;
|
||||
sCacheHitRate.addValue(cached ? 100.f : 0.f);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -192,6 +192,8 @@ protected:
|
|||
std::vector<OrphanInfo> mOrphanChildren; // UUID's of orphaned objects
|
||||
S32 mNumOrphans;
|
||||
|
||||
static LLStat sCacheHitRate;
|
||||
|
||||
typedef std::vector<LLPointer<LLViewerObject> > vobj_list_t;
|
||||
|
||||
vobj_list_t mObjects;
|
||||
|
|
|
|||
|
|
@ -860,3 +860,110 @@ void send_stats()
|
|||
LLHTTPClient::post(url, body, new ViewerStatsResponder());
|
||||
}
|
||||
|
||||
LLFrameTimer& LLViewerStats::PhaseMap::getPhaseTimer(const std::string& phase_name)
|
||||
{
|
||||
phase_map_t::iterator iter = mPhaseMap.find(phase_name);
|
||||
if (iter == mPhaseMap.end())
|
||||
{
|
||||
LLFrameTimer timer;
|
||||
mPhaseMap[phase_name] = timer;
|
||||
}
|
||||
LLFrameTimer& timer = mPhaseMap[phase_name];
|
||||
return timer;
|
||||
}
|
||||
|
||||
void LLViewerStats::PhaseMap::startPhase(const std::string& phase_name)
|
||||
{
|
||||
LLFrameTimer& timer = getPhaseTimer(phase_name);
|
||||
lldebugs << "startPhase " << phase_name << llendl;
|
||||
timer.unpause();
|
||||
}
|
||||
|
||||
void LLViewerStats::PhaseMap::stopPhase(const std::string& phase_name)
|
||||
{
|
||||
phase_map_t::iterator iter = mPhaseMap.find(phase_name);
|
||||
if (iter != mPhaseMap.end())
|
||||
{
|
||||
if (iter->second.getStarted())
|
||||
{
|
||||
// Going from started to paused state - record stats.
|
||||
recordPhaseStat(phase_name,iter->second.getElapsedTimeF32());
|
||||
}
|
||||
lldebugs << "stopPhase " << phase_name << llendl;
|
||||
iter->second.pause();
|
||||
}
|
||||
else
|
||||
{
|
||||
lldebugs << "stopPhase " << phase_name << " is not started, no-op" << llendl;
|
||||
}
|
||||
}
|
||||
|
||||
void LLViewerStats::PhaseMap::stopAllPhases()
|
||||
{
|
||||
for (phase_map_t::iterator iter = mPhaseMap.begin();
|
||||
iter != mPhaseMap.end(); ++iter)
|
||||
{
|
||||
const std::string& phase_name = iter->first;
|
||||
if (iter->second.getStarted())
|
||||
{
|
||||
// Going from started to paused state - record stats.
|
||||
recordPhaseStat(phase_name,iter->second.getElapsedTimeF32());
|
||||
}
|
||||
lldebugs << "stopPhase (all) " << phase_name << llendl;
|
||||
iter->second.pause();
|
||||
}
|
||||
}
|
||||
|
||||
void LLViewerStats::PhaseMap::clearPhases()
|
||||
{
|
||||
lldebugs << "clearPhases" << llendl;
|
||||
|
||||
mPhaseMap.clear();
|
||||
}
|
||||
|
||||
LLSD LLViewerStats::PhaseMap::dumpPhases()
|
||||
{
|
||||
LLSD result;
|
||||
for (phase_map_t::iterator iter = mPhaseMap.begin(); iter != mPhaseMap.end(); ++iter)
|
||||
{
|
||||
const std::string& phase_name = iter->first;
|
||||
result[phase_name]["completed"] = !(iter->second.getStarted());
|
||||
result[phase_name]["elapsed"] = iter->second.getElapsedTimeF32();
|
||||
#if 0 // global stats for each phase seem like overkill here
|
||||
phase_stats_t::iterator stats_iter = sPhaseStats.find(phase_name);
|
||||
if (stats_iter != sPhaseStats.end())
|
||||
{
|
||||
result[phase_name]["stats"] = stats_iter->second.getData();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// static initializer
|
||||
//static
|
||||
LLViewerStats::phase_stats_t LLViewerStats::PhaseMap::sStats;
|
||||
|
||||
LLViewerStats::PhaseMap::PhaseMap()
|
||||
{
|
||||
}
|
||||
|
||||
// static
|
||||
LLViewerStats::StatsAccumulator& LLViewerStats::PhaseMap::getPhaseStats(const std::string& phase_name)
|
||||
{
|
||||
phase_stats_t::iterator it = sStats.find(phase_name);
|
||||
if (it == sStats.end())
|
||||
{
|
||||
LLViewerStats::StatsAccumulator new_stats;
|
||||
sStats[phase_name] = new_stats;
|
||||
}
|
||||
return sStats[phase_name];
|
||||
}
|
||||
|
||||
// static
|
||||
void LLViewerStats::PhaseMap::recordPhaseStat(const std::string& phase_name, F32 value)
|
||||
{
|
||||
LLViewerStats::StatsAccumulator& stats = getPhaseStats(phase_name);
|
||||
stats.push(value);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -244,7 +244,7 @@ public:
|
|||
inline F32 getStdDev() const
|
||||
{
|
||||
const F32 mean = getMean();
|
||||
return (mCount == 0) ? 0.f : sqrt( mSumOfSquares/mCount - (mean * mean) );
|
||||
return (mCount < 2) ? 0.f : sqrt(llmax(0.f,mSumOfSquares/mCount - (mean * mean)));
|
||||
}
|
||||
|
||||
inline U32 getCount() const
|
||||
|
|
@ -274,7 +274,28 @@ public:
|
|||
};
|
||||
|
||||
StatsAccumulator mAgentPositionSnaps;
|
||||
|
||||
|
||||
// Phase tracking (originally put in for avatar rezzing), tracking
|
||||
// progress of active/completed phases for activities like outfit changing.
|
||||
typedef std::map<std::string,LLFrameTimer> phase_map_t;
|
||||
typedef std::map<std::string,StatsAccumulator> phase_stats_t;
|
||||
class PhaseMap
|
||||
{
|
||||
private:
|
||||
phase_map_t mPhaseMap;
|
||||
static phase_stats_t sStats;
|
||||
public:
|
||||
PhaseMap();
|
||||
LLFrameTimer& getPhaseTimer(const std::string& phase_name);
|
||||
void startPhase(const std::string& phase_name);
|
||||
void stopPhase(const std::string& phase_name);
|
||||
void stopAllPhases();
|
||||
void clearPhases();
|
||||
LLSD dumpPhases();
|
||||
static StatsAccumulator& getPhaseStats(const std::string& phase_name);
|
||||
static void recordPhaseStat(const std::string& phase_name, F32 value);
|
||||
};
|
||||
|
||||
private:
|
||||
F64 mStats[ST_COUNT];
|
||||
|
||||
|
|
|
|||
|
|
@ -67,6 +67,7 @@
|
|||
// statics
|
||||
LLPointer<LLViewerTexture> LLViewerTexture::sNullImagep = NULL;
|
||||
LLPointer<LLViewerTexture> LLViewerTexture::sBlackImagep = NULL;
|
||||
LLPointer<LLViewerTexture> LLViewerTexture::sCheckerBoardImagep = NULL;
|
||||
LLPointer<LLViewerFetchedTexture> LLViewerFetchedTexture::sMissingAssetImagep = NULL;
|
||||
LLPointer<LLViewerFetchedTexture> LLViewerFetchedTexture::sWhiteImagep = NULL;
|
||||
LLPointer<LLViewerFetchedTexture> LLViewerFetchedTexture::sDefaultImagep = NULL;
|
||||
|
|
@ -87,6 +88,7 @@ S32 LLViewerTexture::sMaxBoundTextureMemInMegaBytes = 0;
|
|||
S32 LLViewerTexture::sMaxTotalTextureMemInMegaBytes = 0;
|
||||
S32 LLViewerTexture::sMaxDesiredTextureMemInBytes = 0 ;
|
||||
S8 LLViewerTexture::sCameraMovingDiscardBias = 0 ;
|
||||
F32 LLViewerTexture::sCameraMovingBias = 0.0f ;
|
||||
S32 LLViewerTexture::sMaxSculptRez = 128 ; //max sculpt image size
|
||||
const S32 MAX_CACHED_RAW_IMAGE_AREA = 64 * 64 ;
|
||||
const S32 MAX_CACHED_RAW_SCULPT_IMAGE_AREA = LLViewerTexture::sMaxSculptRez * LLViewerTexture::sMaxSculptRez ;
|
||||
|
|
@ -96,6 +98,9 @@ S32 LLViewerTexture::sMaxSmallImageSize = MAX_CACHED_RAW_IMAGE_AREA ;
|
|||
BOOL LLViewerTexture::sFreezeImageScalingDown = FALSE ;
|
||||
F32 LLViewerTexture::sCurrentTime = 0.0f ;
|
||||
BOOL LLViewerTexture::sUseTextureAtlas = FALSE ;
|
||||
F32 LLViewerTexture::sTexelPixelRatio = 1.0f;
|
||||
|
||||
LLViewerTexture::EDebugTexels LLViewerTexture::sDebugTexelsMode = LLViewerTexture::DEBUG_TEXELS_OFF;
|
||||
|
||||
const F32 desired_discard_bias_min = -2.0f; // -max number of levels to improve image quality by
|
||||
const F32 desired_discard_bias_max = (F32)MAX_DISCARD_LEVEL; // max number of levels to reduce image quality by
|
||||
|
|
@ -175,7 +180,12 @@ LLViewerTexture* LLViewerTextureManager::findTexture(const LLUUID& id)
|
|||
}
|
||||
return tex ;
|
||||
}
|
||||
|
||||
|
||||
LLViewerFetchedTexture* LLViewerTextureManager::findFetchedTexture(const LLUUID& id)
|
||||
{
|
||||
return gTextureList.findImage(id);
|
||||
}
|
||||
|
||||
LLViewerMediaTexture* LLViewerTextureManager::findMediaTexture(const LLUUID &media_id)
|
||||
{
|
||||
return LLViewerMediaTexture::findMediaTexture(media_id) ;
|
||||
|
|
@ -347,6 +357,21 @@ void LLViewerTextureManager::init()
|
|||
LLViewerFetchedTexture::sSmokeImagep = LLViewerTextureManager::getFetchedTexture(IMG_SMOKE, TRUE, LLViewerTexture::BOOST_UI);
|
||||
LLViewerFetchedTexture::sSmokeImagep->setNoDelete() ;
|
||||
|
||||
image_raw = new LLImageRaw(32,32,3);
|
||||
data = image_raw->getData();
|
||||
|
||||
for (S32 i = 0; i < (32*32*3); i+=3)
|
||||
{
|
||||
S32 x = (i % (32*3)) / (3*16);
|
||||
S32 y = i / (32*3*16);
|
||||
U8 color = ((x + y) % 2) * 255;
|
||||
data[i] = color;
|
||||
data[i+1] = color;
|
||||
data[i+2] = color;
|
||||
}
|
||||
|
||||
LLViewerTexture::sCheckerBoardImagep = LLViewerTextureManager::getLocalTexture(image_raw.get(), TRUE);
|
||||
|
||||
LLViewerTexture::initClass() ;
|
||||
|
||||
if (LLMetricPerformanceTesterBasic::isMetricLogRequested(sTesterName) && !LLMetricPerformanceTesterBasic::getTester(sTesterName))
|
||||
|
|
@ -367,6 +392,7 @@ void LLViewerTextureManager::cleanup()
|
|||
LLImageGL::sDefaultGLTexture = NULL ;
|
||||
LLViewerTexture::sNullImagep = NULL;
|
||||
LLViewerTexture::sBlackImagep = NULL;
|
||||
LLViewerTexture::sCheckerBoardImagep = NULL;
|
||||
LLViewerFetchedTexture::sDefaultImagep = NULL;
|
||||
LLViewerFetchedTexture::sSmokeImagep = NULL;
|
||||
LLViewerFetchedTexture::sMissingAssetImagep = NULL;
|
||||
|
|
@ -383,11 +409,7 @@ void LLViewerTextureManager::cleanup()
|
|||
void LLViewerTexture::initClass()
|
||||
{
|
||||
LLImageGL::sDefaultGLTexture = LLViewerFetchedTexture::sDefaultImagep->getGLTexture() ;
|
||||
|
||||
if(gAuditTexture)
|
||||
{
|
||||
LLImageGL::setHighlightTexture(LLViewerTexture::OTHER) ;
|
||||
}
|
||||
sTexelPixelRatio = gSavedSettings.getF32("TexelPixelRatio");
|
||||
}
|
||||
|
||||
// static
|
||||
|
|
@ -534,7 +556,8 @@ void LLViewerTexture::updateClass(const F32 velocity, const F32 angular_velocity
|
|||
|
||||
F32 camera_moving_speed = LLViewerCamera::getInstance()->getAverageSpeed() ;
|
||||
F32 camera_angular_speed = LLViewerCamera::getInstance()->getAverageAngularSpeed();
|
||||
sCameraMovingDiscardBias = (S8)llmax(0.2f * camera_moving_speed, 2.0f * camera_angular_speed - 1) ;
|
||||
sCameraMovingBias = llmax(0.2f * camera_moving_speed, 2.0f * camera_angular_speed - 1);
|
||||
sCameraMovingDiscardBias = (S8)(sCameraMovingBias);
|
||||
|
||||
LLViewerTexture::sFreezeImageScalingDown = (BYTES_TO_MEGA_BYTES(sBoundTextureMemoryInBytes) < 0.75f * sMaxBoundTextureMemInMegaBytes * texmem_middle_bound_scale) &&
|
||||
(BYTES_TO_MEGA_BYTES(sTotalTextureMemoryInBytes) < 0.75f * sMaxTotalTextureMemInMegaBytes * texmem_middle_bound_scale) ;
|
||||
|
|
@ -655,10 +678,6 @@ void LLViewerTexture::setBoostLevel(S32 level)
|
|||
{
|
||||
setNoDelete() ;
|
||||
}
|
||||
if(gAuditTexture)
|
||||
{
|
||||
setCategory(mBoostLevel);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -712,6 +731,7 @@ void LLViewerTexture::addTextureStats(F32 virtual_size, BOOL needs_gltexture) co
|
|||
mNeedsGLTexture = TRUE ;
|
||||
}
|
||||
|
||||
virtual_size *= sTexelPixelRatio;
|
||||
if(!mMaxVirtualSizeResetCounter)
|
||||
{
|
||||
//flag to reset the values because the old values are used.
|
||||
|
|
@ -1287,6 +1307,7 @@ void LLViewerFetchedTexture::cleanup()
|
|||
mCachedRawDiscardLevel = -1 ;
|
||||
mCachedRawImageReady = FALSE ;
|
||||
mSavedRawImage = NULL ;
|
||||
mSavedRawDiscardLevel = -1;
|
||||
}
|
||||
|
||||
void LLViewerFetchedTexture::setForSculpt()
|
||||
|
|
@ -1880,6 +1901,8 @@ S32 LLViewerFetchedTexture::getCurrentDiscardLevelForFetching()
|
|||
bool LLViewerFetchedTexture::updateFetch()
|
||||
{
|
||||
static LLCachedControl<bool> textures_decode_disabled(gSavedSettings,"TextureDecodeDisabled");
|
||||
static LLCachedControl<F32> sCameraMotionThreshold(gSavedSettings,"TextureCameraMotionThreshold");
|
||||
static LLCachedControl<S32> sCameraMotionBoost(gSavedSettings,"TextureCameraMotionBoost");
|
||||
if(textures_decode_disabled)
|
||||
{
|
||||
return false ;
|
||||
|
|
@ -2042,18 +2065,24 @@ bool LLViewerFetchedTexture::updateFetch()
|
|||
// make_request = false;
|
||||
//}
|
||||
|
||||
if(make_request)
|
||||
if (make_request)
|
||||
{
|
||||
//load the texture progressively.
|
||||
// Load the texture progressively: we try not to rush to the desired discard too fast.
|
||||
// If the camera is not moving, we do not tweak the discard level notch by notch but go to the desired discard with larger boosted steps
|
||||
// This mitigates the "textures stay blurry" problem when loading while not killing the texture memory while moving around
|
||||
S32 delta_level = (mBoostLevel > LLViewerTexture::BOOST_NONE) ? 2 : 1 ;
|
||||
if(current_discard < 0)
|
||||
if (current_discard < 0)
|
||||
{
|
||||
desired_discard = llmax(desired_discard, getMaxDiscardLevel() - delta_level);
|
||||
}
|
||||
else
|
||||
else if (LLViewerTexture::sCameraMovingBias < sCameraMotionThreshold)
|
||||
{
|
||||
desired_discard = llmax(desired_discard, current_discard - delta_level);
|
||||
desired_discard = llmax(desired_discard, current_discard - sCameraMotionBoost);
|
||||
}
|
||||
else
|
||||
{
|
||||
desired_discard = llmax(desired_discard, current_discard - delta_level);
|
||||
}
|
||||
|
||||
if (mIsFetching)
|
||||
{
|
||||
|
|
@ -2121,6 +2150,30 @@ bool LLViewerFetchedTexture::updateFetch()
|
|||
return mIsFetching ? true : false;
|
||||
}
|
||||
|
||||
void LLViewerFetchedTexture::clearFetchedResults()
|
||||
{
|
||||
llassert_always(!mNeedsCreateTexture && !mIsFetching);
|
||||
|
||||
cleanup();
|
||||
destroyGLTexture();
|
||||
|
||||
if(getDiscardLevel() >= 0) //sculpty texture, force to invalidate
|
||||
{
|
||||
mGLTexturep->forceToInvalidateGLTexture();
|
||||
}
|
||||
}
|
||||
|
||||
void LLViewerFetchedTexture::forceToDeleteRequest()
|
||||
{
|
||||
if (mHasFetcher)
|
||||
{
|
||||
LLAppViewer::getTextureFetch()->deleteRequest(getID(), true);
|
||||
mHasFetcher = FALSE;
|
||||
mIsFetching = FALSE ;
|
||||
resetTextureStats();
|
||||
}
|
||||
}
|
||||
|
||||
void LLViewerFetchedTexture::setIsMissingAsset()
|
||||
{
|
||||
if (mUrl.empty())
|
||||
|
|
|
|||
|
|
@ -139,6 +139,7 @@ public:
|
|||
OTHER,
|
||||
MAX_GL_IMAGE_CATEGORY
|
||||
};
|
||||
|
||||
static S32 getTotalNumOfCategories() ;
|
||||
static S32 getIndexFromCategory(S32 category) ;
|
||||
static S32 getCategoryFromIndex(S32 index) ;
|
||||
|
|
@ -309,6 +310,7 @@ protected:
|
|||
} LLGLTextureState;
|
||||
LLGLTextureState mTextureState ;
|
||||
|
||||
static F32 sTexelPixelRatio;
|
||||
public:
|
||||
static const U32 sCurrentFileVersion;
|
||||
static S32 sImageCount;
|
||||
|
|
@ -323,6 +325,7 @@ public:
|
|||
static S32 sMaxTotalTextureMemInMegaBytes;
|
||||
static S32 sMaxDesiredTextureMemInBytes ;
|
||||
static S8 sCameraMovingDiscardBias;
|
||||
static F32 sCameraMovingBias;
|
||||
static S32 sMaxSculptRez ;
|
||||
static S32 sMinLargeImageSize ;
|
||||
static S32 sMaxSmallImageSize ;
|
||||
|
|
@ -330,8 +333,19 @@ public:
|
|||
static F32 sCurrentTime ;
|
||||
static BOOL sUseTextureAtlas ;
|
||||
|
||||
enum EDebugTexels
|
||||
{
|
||||
DEBUG_TEXELS_OFF,
|
||||
DEBUG_TEXELS_CURRENT,
|
||||
DEBUG_TEXELS_DESIRED,
|
||||
DEBUG_TEXELS_FULL
|
||||
};
|
||||
|
||||
static EDebugTexels sDebugTexelsMode;
|
||||
|
||||
static LLPointer<LLViewerTexture> sNullImagep; // Null texture for non-textured objects.
|
||||
static LLPointer<LLViewerTexture> sBlackImagep; // Texture to show NOTHING (pure black)
|
||||
static LLPointer<LLViewerTexture> sCheckerBoardImagep; // Texture to show NOTHING (pure black)
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -420,6 +434,8 @@ public:
|
|||
|
||||
bool updateFetch();
|
||||
|
||||
void clearFetchedResults(); //clear all fetched results, for debug use.
|
||||
|
||||
// Override the computation of discard levels if we know the exact output
|
||||
// size of the image. Used for UI textures to not decode, even if we have
|
||||
// more data.
|
||||
|
|
@ -478,6 +494,7 @@ public:
|
|||
BOOL hasFetcher() const { return mHasFetcher;}
|
||||
void setCanUseHTTP(bool can_use_http) {mCanUseHTTP = can_use_http;}
|
||||
|
||||
void forceToDeleteRequest();
|
||||
protected:
|
||||
/*virtual*/ void switchToCachedImage();
|
||||
S32 getCurrentDiscardLevelForFetching() ;
|
||||
|
|
@ -687,6 +704,7 @@ public:
|
|||
//"find-texture" just check if the texture exists, if yes, return it, otherwise return null.
|
||||
//
|
||||
static LLViewerTexture* findTexture(const LLUUID& id) ;
|
||||
static LLViewerFetchedTexture* findFetchedTexture(const LLUUID& id) ;
|
||||
static LLViewerMediaTexture* findMediaTexture(const LLUUID& id) ;
|
||||
|
||||
static LLViewerMediaTexture* createMediaTexture(const LLUUID& id, BOOL usemipmaps = TRUE, LLImageGL* gl_image = NULL) ;
|
||||
|
|
|
|||
|
|
@ -58,6 +58,7 @@
|
|||
#include "pipeline.h"
|
||||
#include "llappviewer.h"
|
||||
#include "llxuiparser.h"
|
||||
#include "llagent.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
|
@ -597,6 +598,12 @@ static LLFastTimer::DeclareTimer FTM_IMAGE_STATS("Stats");
|
|||
|
||||
void LLViewerTextureList::updateImages(F32 max_time)
|
||||
{
|
||||
if(gAgent.getTeleportState() != LLAgent::TELEPORT_NONE)
|
||||
{
|
||||
clearFetchingRequests();
|
||||
return;
|
||||
}
|
||||
|
||||
LLAppViewer::getTextureFetch()->setTextureBandwidth(LLViewerStats::getInstance()->mTextureKBitStat.getMeanPerSec());
|
||||
|
||||
LLViewerStats::getInstance()->mNumImagesStat.addValue(sNumImages);
|
||||
|
|
@ -659,6 +666,24 @@ void LLViewerTextureList::updateImages(F32 max_time)
|
|||
}
|
||||
}
|
||||
|
||||
void LLViewerTextureList::clearFetchingRequests()
|
||||
{
|
||||
if (LLAppViewer::getTextureFetch()->getNumRequests() == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for (image_priority_list_t::iterator iter = mImageList.begin();
|
||||
iter != mImageList.end(); ++iter)
|
||||
{
|
||||
LLViewerFetchedTexture* image = *iter;
|
||||
if(image->hasFetcher())
|
||||
{
|
||||
image->forceToDeleteRequest() ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LLViewerTextureList::updateImagesDecodePriorities()
|
||||
{
|
||||
// Update the decode priority for N images each frame
|
||||
|
|
@ -1030,7 +1055,6 @@ LLPointer<LLImageJ2C> LLViewerTextureList::convertToUploadFile(LLPointer<LLImage
|
|||
{
|
||||
raw_image->biasedScaleToPowerOfTwo(LLViewerFetchedTexture::MAX_IMAGE_SIZE_DEFAULT);
|
||||
LLPointer<LLImageJ2C> compressedImage = new LLImageJ2C();
|
||||
compressedImage->setRate(0.f);
|
||||
|
||||
if (gSavedSettings.getBOOL("LosslessJ2CUpload") &&
|
||||
(raw_image->getWidth() * raw_image->getHeight() <= LL_IMAGE_REZ_LOSSLESS_CUTOFF * LL_IMAGE_REZ_LOSSLESS_CUTOFF))
|
||||
|
|
|
|||
|
|
@ -110,6 +110,8 @@ public:
|
|||
void doPreloadImages();
|
||||
void doPrefetchImages();
|
||||
|
||||
void clearFetchingRequests();
|
||||
|
||||
static S32 getMinVideoRamSetting();
|
||||
static S32 getMaxVideoRamSetting(bool get_recommended = false);
|
||||
|
||||
|
|
@ -164,7 +166,7 @@ private:
|
|||
// Request image from a specific host, used for baked avatar textures.
|
||||
// Implemented in header in case someone changes default params above. JC
|
||||
LLViewerFetchedTexture* getImageFromHost(const LLUUID& image_id, LLHost host)
|
||||
{ return getImage(image_id, TRUE, LLViewerTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE, 0, 0, host); }
|
||||
{ return getImage(image_id, TRUE, LLViewerTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE, 0, 0, host); }
|
||||
|
||||
public:
|
||||
typedef std::set<LLPointer<LLViewerFetchedTexture> > image_list_t;
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -48,6 +48,7 @@
|
|||
#include "lltexglobalcolor.h"
|
||||
#include "lldriverparam.h"
|
||||
#include "material_codes.h" // LL_MCODE_END
|
||||
#include "llviewerstats.h"
|
||||
|
||||
extern const LLUUID ANIM_AGENT_BODY_NOISE;
|
||||
extern const LLUUID ANIM_AGENT_BREATHE_ROT;
|
||||
|
|
@ -277,14 +278,27 @@ public:
|
|||
public:
|
||||
BOOL isFullyLoaded() const;
|
||||
bool isTooComplex() const;
|
||||
bool visualParamWeightsAreDefault();
|
||||
bool visualParamWeightsAreDefault();
|
||||
virtual BOOL getIsCloud() const;
|
||||
BOOL isFullyTextured() const;
|
||||
BOOL hasGray() const;
|
||||
S32 getRezzedStatus() const; // 0 = cloud, 1 = gray, 2 = fully textured.
|
||||
void updateRezzedStatusTimers();
|
||||
|
||||
S32 mLastRezzedStatus;
|
||||
|
||||
LLViewerStats::PhaseMap& getPhases()
|
||||
{
|
||||
return mPhases;
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual BOOL getIsCloud();
|
||||
BOOL updateIsFullyLoaded();
|
||||
BOOL processFullyLoadedChange(bool loading);
|
||||
void updateRuthTimer(bool loading);
|
||||
F32 calcMorphAmount();
|
||||
private:
|
||||
BOOL mFirstFullyVisible;
|
||||
BOOL mFullyLoaded;
|
||||
BOOL mPreviousFullyLoaded;
|
||||
BOOL mFullyLoadedInitialized;
|
||||
|
|
@ -292,6 +306,28 @@ private:
|
|||
S32 mVisualComplexity;
|
||||
LLFrameTimer mFullyLoadedTimer;
|
||||
LLFrameTimer mRuthTimer;
|
||||
|
||||
public:
|
||||
class ScopedPhaseSetter
|
||||
{
|
||||
public:
|
||||
ScopedPhaseSetter(LLVOAvatar *avatarp, std::string phase_name):
|
||||
mAvatar(avatarp), mPhaseName(phase_name)
|
||||
{
|
||||
if (mAvatar) { mAvatar->getPhases().startPhase(mPhaseName); }
|
||||
}
|
||||
~ScopedPhaseSetter()
|
||||
{
|
||||
if (mAvatar) { mAvatar->getPhases().stopPhase(mPhaseName); }
|
||||
}
|
||||
private:
|
||||
std::string mPhaseName;
|
||||
LLVOAvatar* mAvatar;
|
||||
};
|
||||
|
||||
private:
|
||||
LLViewerStats::PhaseMap mPhases;
|
||||
|
||||
protected:
|
||||
LLFrameTimer mInvisibleTimer;
|
||||
|
||||
|
|
@ -518,9 +554,10 @@ public:
|
|||
virtual BOOL isTextureVisible(LLVOAvatarDefines::ETextureIndex type, U32 index = 0) const;
|
||||
virtual BOOL isTextureVisible(LLVOAvatarDefines::ETextureIndex type, LLWearable *wearable) const;
|
||||
|
||||
protected:
|
||||
BOOL isFullyBaked();
|
||||
static BOOL areAllNearbyInstancesBaked(S32& grey_avatars);
|
||||
static void getNearbyRezzedStats(std::vector<S32>& counts);
|
||||
static std::string rezStatusToString(S32 status);
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// Baked textures
|
||||
|
|
@ -882,6 +919,7 @@ private:
|
|||
|
||||
public:
|
||||
std::string getFullname() const; // Returns "FirstName LastName"
|
||||
std::string avString() const; // Frequently used string in log messages "Avatar '<full name'"
|
||||
protected:
|
||||
static void getAnimLabels(LLDynamicArray<std::string>* labels);
|
||||
static void getAnimNames(LLDynamicArray<std::string>* names);
|
||||
|
|
@ -983,7 +1021,9 @@ private:
|
|||
// Avatar Rez Metrics
|
||||
//--------------------------------------------------------------------
|
||||
public:
|
||||
void debugAvatarRezTime(std::string notification_name, std::string comment = "");
|
||||
F32 debugGetExistenceTimeElapsedF32() const { return mDebugExistenceTimer.getElapsedTimeF32(); }
|
||||
|
||||
protected:
|
||||
LLFrameTimer mRuthDebugTimer; // For tracking how long it takes for av to rez
|
||||
LLFrameTimer mDebugExistenceTimer; // Debugging for how long the avatar has been in memory.
|
||||
|
|
|
|||
|
|
@ -58,6 +58,8 @@
|
|||
#include "llappearancemgr.h"
|
||||
#include "llmeshrepository.h"
|
||||
#include "llvovolume.h"
|
||||
#include "llsdutil.h"
|
||||
#include "llstartup.h"
|
||||
|
||||
#if LL_MSVC
|
||||
// disable boost::lexical_cast warning
|
||||
|
|
@ -75,6 +77,39 @@ BOOL isAgentAvatarValid()
|
|||
(!gAgentAvatarp->isDead()));
|
||||
}
|
||||
|
||||
void selfStartPhase(const std::string& phase_name)
|
||||
{
|
||||
if (isAgentAvatarValid())
|
||||
{
|
||||
gAgentAvatarp->getPhases().startPhase(phase_name);
|
||||
}
|
||||
}
|
||||
|
||||
void selfStopPhase(const std::string& phase_name)
|
||||
{
|
||||
if (isAgentAvatarValid())
|
||||
{
|
||||
gAgentAvatarp->getPhases().stopPhase(phase_name);
|
||||
}
|
||||
}
|
||||
|
||||
void selfClearPhases()
|
||||
{
|
||||
if (isAgentAvatarValid())
|
||||
{
|
||||
gAgentAvatarp->getPhases().clearPhases();
|
||||
gAgentAvatarp->mLastRezzedStatus = -1;
|
||||
}
|
||||
}
|
||||
|
||||
void selfStopAllPhases()
|
||||
{
|
||||
if (isAgentAvatarValid())
|
||||
{
|
||||
gAgentAvatarp->getPhases().stopAllPhases();
|
||||
}
|
||||
}
|
||||
|
||||
using namespace LLVOAvatarDefines;
|
||||
|
||||
/*********************************************************************************
|
||||
|
|
@ -131,7 +166,8 @@ LLVOAvatarSelf::LLVOAvatarSelf(const LLUUID& id,
|
|||
LLVOAvatar(id, pcode, regionp),
|
||||
mScreenp(NULL),
|
||||
mLastRegionHandle(0),
|
||||
mRegionCrossingCount(0)
|
||||
mRegionCrossingCount(0),
|
||||
mInitialBakesLoaded(false)
|
||||
{
|
||||
gAgentWearables.setAvatarObject(this);
|
||||
|
||||
|
|
@ -164,6 +200,7 @@ void LLVOAvatarSelf::initInstance()
|
|||
{
|
||||
mDebugBakedTextureTimes[i][0] = -1.0f;
|
||||
mDebugBakedTextureTimes[i][1] = -1.0f;
|
||||
mInitialBakeIDs[i] = LLUUID::null;
|
||||
}
|
||||
|
||||
status &= buildMenus();
|
||||
|
|
@ -762,6 +799,41 @@ void LLVOAvatarSelf::stopMotionFromSource(const LLUUID& source_id)
|
|||
}
|
||||
}
|
||||
|
||||
//virtual
|
||||
U32 LLVOAvatarSelf::processUpdateMessage(LLMessageSystem *mesgsys,
|
||||
void **user_data,
|
||||
U32 block_num,
|
||||
const EObjectUpdateType update_type,
|
||||
LLDataPacker *dp)
|
||||
{
|
||||
U32 retval = LLVOAvatar::processUpdateMessage(mesgsys,user_data,block_num,update_type,dp);
|
||||
|
||||
if (mInitialBakesLoaded == false && retval == 0x0)
|
||||
{
|
||||
// call update textures to force the images to be created
|
||||
updateMeshTextures();
|
||||
|
||||
// unpack the texture UUIDs to the texture slots
|
||||
retval = unpackTEMessage(mesgsys, _PREHASH_ObjectData, block_num);
|
||||
|
||||
// need to trigger a few operations to get the avatar to use the new bakes
|
||||
for (U32 i = 0; i < mBakedTextureDatas.size(); i++)
|
||||
{
|
||||
const LLVOAvatarDefines::ETextureIndex te = mBakedTextureDatas[i].mTextureIndex;
|
||||
LLUUID texture_id = getTEImage(te)->getID();
|
||||
setNewBakedTexture(te, texture_id);
|
||||
mInitialBakeIDs[i] = texture_id;
|
||||
}
|
||||
|
||||
onFirstTEMessageReceived();
|
||||
|
||||
mInitialBakesLoaded = true;
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
void LLVOAvatarSelf::setLocalTextureTE(U8 te, LLViewerTexture* image, U32 index)
|
||||
{
|
||||
if (te >= TEX_NUM_INDICES)
|
||||
|
|
@ -1889,7 +1961,7 @@ void LLVOAvatarSelf::dumpTotalLocalTextureByteCount()
|
|||
llinfos << "Total Avatar LocTex GL:" << (gl_bytes/1024) << "KB" << llendl;
|
||||
}
|
||||
|
||||
BOOL LLVOAvatarSelf::getIsCloud()
|
||||
BOOL LLVOAvatarSelf::getIsCloud() const
|
||||
{
|
||||
// do we have our body parts?
|
||||
if (gAgentWearables.getWearableCount(LLWearableType::WT_SHAPE) == 0 ||
|
||||
|
|
@ -2055,6 +2127,80 @@ const std::string LLVOAvatarSelf::debugDumpAllLocalTextureDataInfo() const
|
|||
return text;
|
||||
}
|
||||
|
||||
// Dump avatar metrics data.
|
||||
LLSD LLVOAvatarSelf::metricsData()
|
||||
{
|
||||
// runway - add region info
|
||||
LLSD result;
|
||||
result["id"] = getID();
|
||||
result["rez_status"] = LLVOAvatar::rezStatusToString(getRezzedStatus());
|
||||
result["is_self"] = isSelf();
|
||||
std::vector<S32> rez_counts;
|
||||
LLVOAvatar::getNearbyRezzedStats(rez_counts);
|
||||
result["nearby"] = LLSD::emptyMap();
|
||||
for (S32 i=0; i<rez_counts.size(); ++i)
|
||||
{
|
||||
std::string rez_status_name = LLVOAvatar::rezStatusToString(i);
|
||||
result["nearby"][rez_status_name] = rez_counts[i];
|
||||
}
|
||||
result["timers"]["debug_existence"] = mDebugExistenceTimer.getElapsedTimeF32();
|
||||
result["timers"]["ruth_debug"] = mRuthDebugTimer.getElapsedTimeF32();
|
||||
result["timers"]["ruth"] = mRuthTimer.getElapsedTimeF32();
|
||||
result["timers"]["invisible"] = mInvisibleTimer.getElapsedTimeF32();
|
||||
result["timers"]["fully_loaded"] = mFullyLoadedTimer.getElapsedTimeF32();
|
||||
result["phases"] = getPhases().dumpPhases();
|
||||
result["startup"] = LLStartUp::getPhases().dumpPhases();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
class ViewerAppearanceChangeMetricsResponder: public LLCurl::Responder
|
||||
{
|
||||
public:
|
||||
ViewerAppearanceChangeMetricsResponder()
|
||||
{
|
||||
}
|
||||
|
||||
virtual void completed(U32 status,
|
||||
const std::string& reason,
|
||||
const LLSD& content)
|
||||
{
|
||||
if (isGoodStatus(status))
|
||||
{
|
||||
LL_DEBUGS("Avatar") << "OK" << LL_ENDL;
|
||||
result(content);
|
||||
}
|
||||
else
|
||||
{
|
||||
LL_WARNS("Avatar") << "Failed " << status << " reason " << reason << LL_ENDL;
|
||||
error(status,reason);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
void LLVOAvatarSelf::sendAppearanceChangeMetrics()
|
||||
{
|
||||
// gAgentAvatarp->stopAllPhases();
|
||||
|
||||
LLSD msg = metricsData();
|
||||
msg["message"] = "ViewerAppearanceChangeMetrics";
|
||||
|
||||
LL_DEBUGS("Avatar") << avString() << "message: " << ll_pretty_print_sd(msg) << LL_ENDL;
|
||||
std::string caps_url;
|
||||
if (getRegion())
|
||||
{
|
||||
// runway - change here to activate.
|
||||
caps_url = getRegion()->getCapability("ViewerMetrics");
|
||||
}
|
||||
if (!caps_url.empty())
|
||||
{
|
||||
LLCurlRequest::headers_t headers;
|
||||
LLHTTPClient::post(caps_url,
|
||||
msg,
|
||||
new ViewerAppearanceChangeMetricsResponder);
|
||||
}
|
||||
}
|
||||
|
||||
const LLUUID& LLVOAvatarSelf::grabBakedTexture(EBakedTextureIndex baked_index) const
|
||||
{
|
||||
if (canGrabBakedTexture(baked_index))
|
||||
|
|
@ -2253,11 +2399,25 @@ void LLVOAvatarSelf::setNewBakedTexture( ETextureIndex te, const LLUUID& uuid )
|
|||
if (isAllLocalTextureDataFinal())
|
||||
{
|
||||
LLNotificationsUtil::add("AvatarRezSelfBakedDoneNotification",args);
|
||||
LL_DEBUGS("Avatar") << "REZTIME: [ " << (U32)mDebugExistenceTimer.getElapsedTimeF32()
|
||||
<< "sec ]"
|
||||
<< avString()
|
||||
<< "RuthTimer " << (U32)mRuthDebugTimer.getElapsedTimeF32()
|
||||
<< " SelfLoadTimer " << (U32)mDebugSelfLoadTimer.getElapsedTimeF32()
|
||||
<< " Notification " << "AvatarRezSelfBakedDoneNotification"
|
||||
<< llendl;
|
||||
}
|
||||
else
|
||||
{
|
||||
args["STATUS"] = debugDumpAllLocalTextureDataInfo();
|
||||
LLNotificationsUtil::add("AvatarRezSelfBakedUpdateNotification",args);
|
||||
LL_DEBUGS("Avatar") << "REZTIME: [ " << (U32)mDebugExistenceTimer.getElapsedTimeF32()
|
||||
<< "sec ]"
|
||||
<< avString()
|
||||
<< "RuthTimer " << (U32)mRuthDebugTimer.getElapsedTimeF32()
|
||||
<< " SelfLoadTimer " << (U32)mDebugSelfLoadTimer.getElapsedTimeF32()
|
||||
<< " Notification " << "AvatarRezSelfBakedUpdateNotification"
|
||||
<< llendl;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -2265,7 +2425,7 @@ void LLVOAvatarSelf::setNewBakedTexture( ETextureIndex te, const LLUUID& uuid )
|
|||
}
|
||||
}
|
||||
|
||||
// FIXME: This is never called. Something may be broken.
|
||||
// FIXME: This is not called consistently. Something may be broken.
|
||||
void LLVOAvatarSelf::outputRezDiagnostics() const
|
||||
{
|
||||
if(!gSavedSettings.getBOOL("DebugAvatarLocalTexLoadedTime"))
|
||||
|
|
@ -2274,11 +2434,11 @@ void LLVOAvatarSelf::outputRezDiagnostics() const
|
|||
}
|
||||
|
||||
const F32 final_time = mDebugSelfLoadTimer.getElapsedTimeF32();
|
||||
llinfos << "REZTIME: Myself rez stats:" << llendl;
|
||||
llinfos << "\t Time from avatar creation to load wearables: " << (S32)mDebugTimeWearablesLoaded << llendl;
|
||||
llinfos << "\t Time from avatar creation to de-cloud: " << (S32)mDebugTimeAvatarVisible << llendl;
|
||||
llinfos << "\t Time from avatar creation to de-cloud for others: " << (S32)final_time << llendl;
|
||||
llinfos << "\t Load time for each texture: " << llendl;
|
||||
LL_DEBUGS("Avatar") << "REZTIME: Myself rez stats:" << llendl;
|
||||
LL_DEBUGS("Avatar") << "\t Time from avatar creation to load wearables: " << (S32)mDebugTimeWearablesLoaded << llendl;
|
||||
LL_DEBUGS("Avatar") << "\t Time from avatar creation to de-cloud: " << (S32)mDebugTimeAvatarVisible << llendl;
|
||||
LL_DEBUGS("Avatar") << "\t Time from avatar creation to de-cloud for others: " << (S32)final_time << llendl;
|
||||
LL_DEBUGS("Avatar") << "\t Load time for each texture: " << llendl;
|
||||
for (U32 i = 0; i < LLVOAvatarDefines::TEX_NUM_INDICES; ++i)
|
||||
{
|
||||
std::stringstream out;
|
||||
|
|
@ -2302,12 +2462,14 @@ void LLVOAvatarSelf::outputRezDiagnostics() const
|
|||
|
||||
// Don't print out non-existent textures.
|
||||
if (j != 0)
|
||||
llinfos << out.str() << llendl;
|
||||
{
|
||||
LL_DEBUGS("Avatar") << out.str() << LL_ENDL;
|
||||
}
|
||||
}
|
||||
llinfos << "\t Time points for each upload (start / finish)" << llendl;
|
||||
LL_DEBUGS("Avatar") << "\t Time points for each upload (start / finish)" << llendl;
|
||||
for (U32 i = 0; i < LLVOAvatarDefines::BAKED_NUM_INDICES; ++i)
|
||||
{
|
||||
llinfos << "\t\t (" << i << ") \t" << (S32)mDebugBakedTextureTimes[i][0] << " / " << (S32)mDebugBakedTextureTimes[i][1] << llendl;
|
||||
LL_DEBUGS("Avatar") << "\t\t (" << i << ") \t" << (S32)mDebugBakedTextureTimes[i][0] << " / " << (S32)mDebugBakedTextureTimes[i][1] << llendl;
|
||||
}
|
||||
|
||||
for (LLVOAvatarDefines::LLVOAvatarDictionary::BakedTextures::const_iterator baked_iter = LLVOAvatarDefines::LLVOAvatarDictionary::getInstance()->getBakedTextures().begin();
|
||||
|
|
@ -2319,15 +2481,16 @@ void LLVOAvatarSelf::outputRezDiagnostics() const
|
|||
if (!layerset) continue;
|
||||
const LLTexLayerSetBuffer *layerset_buffer = layerset->getComposite();
|
||||
if (!layerset_buffer) continue;
|
||||
llinfos << layerset_buffer->dumpTextureInfo() << llendl;
|
||||
LL_DEBUGS("Avatar") << layerset_buffer->dumpTextureInfo() << llendl;
|
||||
}
|
||||
}
|
||||
|
||||
void LLVOAvatarSelf::outputRezTiming(const std::string& msg) const
|
||||
{
|
||||
LL_DEBUGS("Avatar Rez")
|
||||
LL_INFOS("Avatar")
|
||||
<< avString()
|
||||
<< llformat("%s. Time from avatar creation: %.2f", msg.c_str(), mDebugSelfLoadTimer.getElapsedTimeF32())
|
||||
<< llendl;
|
||||
<< LL_ENDL;
|
||||
}
|
||||
|
||||
void LLVOAvatarSelf::reportAvatarRezTime() const
|
||||
|
|
@ -2351,6 +2514,18 @@ void LLVOAvatarSelf::setCachedBakedTexture( ETextureIndex te, const LLUUID& uuid
|
|||
{
|
||||
if ( mBakedTextureDatas[i].mTextureIndex == te && mBakedTextureDatas[i].mTexLayerSet)
|
||||
{
|
||||
if (mInitialBakeIDs[i] != LLUUID::null)
|
||||
{
|
||||
if (mInitialBakeIDs[i] == uuid)
|
||||
{
|
||||
llinfos << "baked texture correctly loaded at login! " << i << llendl;
|
||||
}
|
||||
else
|
||||
{
|
||||
llwarns << "baked texture does not match id loaded at login!" << i << llendl;
|
||||
}
|
||||
mInitialBakeIDs[i] = LLUUID::null;
|
||||
}
|
||||
mBakedTextureDatas[i].mTexLayerSet->cancelUpload();
|
||||
}
|
||||
}
|
||||
|
|
@ -2478,6 +2653,20 @@ LLTexLayerSet* LLVOAvatarSelf::getLayerSet(ETextureIndex index) const
|
|||
return NULL;
|
||||
}
|
||||
|
||||
LLTexLayerSet* LLVOAvatarSelf::getLayerSet(EBakedTextureIndex baked_index) const
|
||||
{
|
||||
/* switch(index)
|
||||
case TEX_HEAD_BAKED:
|
||||
case TEX_HEAD_BODYPAINT:
|
||||
return mHeadLayerSet; */
|
||||
if (baked_index >= 0 && baked_index < BAKED_NUM_INDICES)
|
||||
{
|
||||
return mBakedTextureDatas[baked_index].mTexLayerSet;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
// static
|
||||
void LLVOAvatarSelf::onCustomizeStart()
|
||||
{
|
||||
|
|
@ -2558,49 +2747,6 @@ BOOL LLVOAvatarSelf::needsRenderBeam()
|
|||
// static
|
||||
void LLVOAvatarSelf::deleteScratchTextures()
|
||||
{
|
||||
if(gAuditTexture)
|
||||
{
|
||||
S32 total_tex_size = sScratchTexBytes ;
|
||||
S32 tex_size = SCRATCH_TEX_WIDTH * SCRATCH_TEX_HEIGHT ;
|
||||
|
||||
if( sScratchTexNames.checkData( GL_LUMINANCE ) )
|
||||
{
|
||||
LLImageGL::decTextureCounter(tex_size, 1, LLViewerTexture::AVATAR_SCRATCH_TEX) ;
|
||||
total_tex_size -= tex_size ;
|
||||
}
|
||||
if( sScratchTexNames.checkData( GL_ALPHA ) )
|
||||
{
|
||||
LLImageGL::decTextureCounter(tex_size, 1, LLViewerTexture::AVATAR_SCRATCH_TEX) ;
|
||||
total_tex_size -= tex_size ;
|
||||
}
|
||||
if( sScratchTexNames.checkData( GL_COLOR_INDEX ) )
|
||||
{
|
||||
LLImageGL::decTextureCounter(tex_size, 1, LLViewerTexture::AVATAR_SCRATCH_TEX) ;
|
||||
total_tex_size -= tex_size ;
|
||||
}
|
||||
if( sScratchTexNames.checkData( LLRender::sGLCoreProfile ? GL_RG : GL_LUMINANCE_ALPHA ) )
|
||||
{
|
||||
LLImageGL::decTextureCounter(tex_size, 2, LLViewerTexture::AVATAR_SCRATCH_TEX) ;
|
||||
total_tex_size -= 2 * tex_size ;
|
||||
}
|
||||
if( sScratchTexNames.checkData( GL_RGB ) )
|
||||
{
|
||||
LLImageGL::decTextureCounter(tex_size, 3, LLViewerTexture::AVATAR_SCRATCH_TEX) ;
|
||||
total_tex_size -= 3 * tex_size ;
|
||||
}
|
||||
if( sScratchTexNames.checkData( GL_RGBA ) )
|
||||
{
|
||||
LLImageGL::decTextureCounter(tex_size, 4, LLViewerTexture::AVATAR_SCRATCH_TEX) ;
|
||||
total_tex_size -= 4 * tex_size ;
|
||||
}
|
||||
//others
|
||||
while(total_tex_size > 0)
|
||||
{
|
||||
LLImageGL::decTextureCounter(tex_size, 4, LLViewerTexture::AVATAR_SCRATCH_TEX) ;
|
||||
total_tex_size -= 4 * tex_size ;
|
||||
}
|
||||
}
|
||||
|
||||
for( LLGLuint* namep = sScratchTexNames.getFirstData();
|
||||
namep;
|
||||
namep = sScratchTexNames.getNextData() )
|
||||
|
|
|
|||
|
|
@ -93,15 +93,27 @@ public:
|
|||
/*virtual*/ void updateVisualParams();
|
||||
/*virtual*/ void idleUpdateAppearanceAnimation();
|
||||
|
||||
/*virtual*/ U32 processUpdateMessage(LLMessageSystem *mesgsys,
|
||||
void **user_data,
|
||||
U32 block_num,
|
||||
const EObjectUpdateType update_type,
|
||||
LLDataPacker *dp);
|
||||
|
||||
private:
|
||||
// helper function. Passed in param is assumed to be in avatar's parameter list.
|
||||
BOOL setParamWeight(LLViewerVisualParam *param, F32 weight, BOOL upload_bake = FALSE );
|
||||
|
||||
|
||||
|
||||
/** Initialization
|
||||
** **
|
||||
*******************************************************************************/
|
||||
|
||||
private:
|
||||
LLUUID mInitialBakeIDs[6];
|
||||
bool mInitialBakesLoaded;
|
||||
|
||||
|
||||
/********************************************************************************
|
||||
** **
|
||||
** STATE
|
||||
|
|
@ -121,7 +133,7 @@ public:
|
|||
// Loading state
|
||||
//--------------------------------------------------------------------
|
||||
public:
|
||||
/*virtual*/ BOOL getIsCloud();
|
||||
/*virtual*/ BOOL getIsCloud() const;
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// Region state
|
||||
|
|
@ -229,6 +241,7 @@ public:
|
|||
void requestLayerSetUpload(LLVOAvatarDefines::EBakedTextureIndex i);
|
||||
void requestLayerSetUpdate(LLVOAvatarDefines::ETextureIndex i);
|
||||
LLTexLayerSet* getLayerSet(LLVOAvatarDefines::ETextureIndex index) const;
|
||||
LLTexLayerSet* getLayerSet(LLVOAvatarDefines::EBakedTextureIndex baked_index) const;
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// Composites
|
||||
|
|
@ -369,6 +382,8 @@ public:
|
|||
const LLTexLayerSet* debugGetLayerSet(LLVOAvatarDefines::EBakedTextureIndex index) const { return mBakedTextureDatas[index].mTexLayerSet; }
|
||||
const std::string debugDumpLocalTextureDataInfo(const LLTexLayerSet* layerset) const; // Lists out state of this particular baked texture layer
|
||||
const std::string debugDumpAllLocalTextureDataInfo() const; // Lists out which baked textures are at highest LOD
|
||||
LLSD metricsData();
|
||||
void sendAppearanceChangeMetrics(); // send data associated with completing a change.
|
||||
private:
|
||||
LLFrameTimer mDebugSelfLoadTimer;
|
||||
F32 mDebugTimeWearablesLoaded;
|
||||
|
|
@ -387,4 +402,9 @@ extern LLPointer<LLVOAvatarSelf> gAgentAvatarp;
|
|||
|
||||
BOOL isAgentAvatarValid();
|
||||
|
||||
void selfStartPhase(const std::string& phase_name);
|
||||
void selfStopPhase(const std::string& phase_name);
|
||||
void selfStopAllPhases();
|
||||
void selfClearPhases();
|
||||
|
||||
#endif // LL_VO_AVATARSELF_H
|
||||
|
|
|
|||
|
|
@ -464,6 +464,7 @@ public:
|
|||
RENDER_DEBUG_LOD_INFO = 0x04000000,
|
||||
RENDER_DEBUG_RENDER_COMPLEXITY = 0x08000000,
|
||||
RENDER_DEBUG_ATTACHMENT_BYTES = 0x10000000,
|
||||
RENDER_DEBUG_TEXEL_DENSITY = 0x20000000
|
||||
};
|
||||
|
||||
public:
|
||||
|
|
|
|||
|
|
@ -149,13 +149,52 @@
|
|||
show_per_sec="true"
|
||||
show_bar="false">
|
||||
</stat_bar>
|
||||
<stat_bar
|
||||
name="object_cache_hits"
|
||||
label="Object Cache Hit Rate"
|
||||
stat="object_cache_hits"
|
||||
bar_min="0"
|
||||
bar_max="100"
|
||||
unit_label="%"
|
||||
tick_spacing="20"
|
||||
label_spacing="20"
|
||||
show_history="true"
|
||||
show_per_sec="false"
|
||||
show_bar="false">
|
||||
</stat_bar>
|
||||
</stat_view>
|
||||
<!--Texture Stats-->
|
||||
<stat_view
|
||||
name="texture"
|
||||
label="Texture"
|
||||
show_label="true">
|
||||
<stat_bar
|
||||
<stat_bar
|
||||
name="texture_cache_hits"
|
||||
label="Cache Hit Rate"
|
||||
stat="texture_cache_hits"
|
||||
bar_min="0.f"
|
||||
bar_max="100.f"
|
||||
unit_label="%"
|
||||
tick_spacing="20"
|
||||
label_spacing="20"
|
||||
show_history="true"
|
||||
show_per_sec="false"
|
||||
show_bar="false">
|
||||
</stat_bar>
|
||||
<stat_bar
|
||||
name="texture_cache_read_latency"
|
||||
label="Cache Read Latency"
|
||||
unit_label="msec"
|
||||
stat="texture_cache_read_latency"
|
||||
bar_min="0.f"
|
||||
bar_max="1000.f"
|
||||
tick_spacing="100"
|
||||
label_spacing="200"
|
||||
show_history="true"
|
||||
show_per_sec="false"
|
||||
show_bar="false">
|
||||
</stat_bar>
|
||||
<stat_bar
|
||||
name="numimagesstat"
|
||||
label="Count"
|
||||
stat="numimagesstat"
|
||||
|
|
|
|||
|
|
@ -0,0 +1,341 @@
|
|||
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
|
||||
<floater
|
||||
legacy_header_height="18"
|
||||
can_minimize="false"
|
||||
height="550"
|
||||
layout="topleft"
|
||||
name="TexFetchDebugger"
|
||||
help_topic="texfetchdebugger"
|
||||
title="Texture Fetching Debugger"
|
||||
width="540">
|
||||
<text
|
||||
type="string"
|
||||
length="1"
|
||||
follows="left|top"
|
||||
height="25"
|
||||
layout="topleft"
|
||||
left="10"
|
||||
name="total_num_fetched_label"
|
||||
top="30"
|
||||
width="400">
|
||||
1, Total number of fetched textures: [NUM]
|
||||
</text>
|
||||
<text
|
||||
type="string"
|
||||
length="1"
|
||||
follows="left|top"
|
||||
height="25"
|
||||
layout="topleft"
|
||||
left_delta="0"
|
||||
name="total_num_fetching_requests_label"
|
||||
top_delta="25"
|
||||
width="400">
|
||||
2, Total number of fetching requests: [NUM]
|
||||
</text>
|
||||
<text
|
||||
type="string"
|
||||
length="1"
|
||||
follows="left|top"
|
||||
height="25"
|
||||
layout="topleft"
|
||||
left_delta="0"
|
||||
name="total_num_cache_hits_label"
|
||||
top_delta="25"
|
||||
width="400">
|
||||
3, Total number of cache hits: [NUM]
|
||||
</text>
|
||||
<text
|
||||
type="string"
|
||||
length="1"
|
||||
follows="left|top"
|
||||
height="25"
|
||||
layout="topleft"
|
||||
left_delta="0"
|
||||
name="total_num_visible_tex_label"
|
||||
top_delta="25"
|
||||
width="400">
|
||||
4, Total number of visible textures: [NUM]
|
||||
</text>
|
||||
<text
|
||||
type="string"
|
||||
length="1"
|
||||
follows="left|top"
|
||||
height="25"
|
||||
layout="topleft"
|
||||
left_delta="0"
|
||||
name="total_num_visible_tex_fetch_req_label"
|
||||
top_delta="25"
|
||||
width="450">
|
||||
5, Total number of visible texture fetching requests: [NUM]
|
||||
</text>
|
||||
<text
|
||||
type="string"
|
||||
length="1"
|
||||
follows="left|top"
|
||||
height="25"
|
||||
layout="topleft"
|
||||
left_delta="0"
|
||||
name="total_fetched_data_label"
|
||||
top_delta="25"
|
||||
width="530">
|
||||
6, Total number of fetched data: [SIZE1]KB, Decoded Data: [SIZE2]KB, [PIXEL]MPixels
|
||||
</text>
|
||||
<text
|
||||
type="string"
|
||||
length="1"
|
||||
follows="left|top"
|
||||
height="25"
|
||||
layout="topleft"
|
||||
left_delta="0"
|
||||
name="total_fetched_vis_data_label"
|
||||
top_delta="25"
|
||||
width="480">
|
||||
7, Total number of visible data: [SIZE1]KB, Decoded Data: [SIZE2]KB
|
||||
</text>
|
||||
<text
|
||||
type="string"
|
||||
length="1"
|
||||
follows="left|top"
|
||||
height="25"
|
||||
layout="topleft"
|
||||
left_delta="0"
|
||||
name="total_fetched_rendered_data_label"
|
||||
top_delta="25"
|
||||
width="530">
|
||||
8, Total number of rendered data: [SIZE1]KB, Decoded Data: [SIZE2]KB, [PIXEL]MPixels
|
||||
</text>
|
||||
<text
|
||||
type="string"
|
||||
length="1"
|
||||
follows="left|top"
|
||||
height="25"
|
||||
layout="topleft"
|
||||
left_delta="0"
|
||||
name="total_time_cache_read_label"
|
||||
top_delta="25"
|
||||
width="400">
|
||||
9, Total time on cache readings: [TIME] seconds
|
||||
</text>
|
||||
<text
|
||||
type="string"
|
||||
length="1"
|
||||
follows="left|top"
|
||||
height="25"
|
||||
layout="topleft"
|
||||
left_delta="0"
|
||||
name="total_time_cache_write_label"
|
||||
top_delta="25"
|
||||
width="400">
|
||||
10, Total time on cache writings: [TIME] seconds
|
||||
</text>
|
||||
<text
|
||||
type="string"
|
||||
length="1"
|
||||
follows="left|top"
|
||||
height="25"
|
||||
layout="topleft"
|
||||
left_delta="0"
|
||||
name="total_time_decode_label"
|
||||
top_delta="25"
|
||||
width="400">
|
||||
11, Total time on decodings: [TIME] seconds
|
||||
</text>
|
||||
<text
|
||||
type="string"
|
||||
length="1"
|
||||
follows="left|top"
|
||||
height="25"
|
||||
layout="topleft"
|
||||
left_delta="0"
|
||||
name="total_time_gl_label"
|
||||
top_delta="25"
|
||||
width="400">
|
||||
12, Total time on gl texture creation: [TIME] seconds
|
||||
</text>
|
||||
<text
|
||||
type="string"
|
||||
length="1"
|
||||
follows="left|top"
|
||||
height="25"
|
||||
layout="topleft"
|
||||
left_delta="0"
|
||||
name="total_time_http_label"
|
||||
top_delta="25"
|
||||
width="400">
|
||||
13, Total time on HTTP fetching: [TIME] seconds
|
||||
</text>
|
||||
<text
|
||||
type="string"
|
||||
length="1"
|
||||
follows="left|top"
|
||||
height="25"
|
||||
layout="topleft"
|
||||
left_delta="0"
|
||||
name="total_time_fetch_label"
|
||||
top_delta="25"
|
||||
width="400">
|
||||
14, Total time on entire fetching: [TIME] seconds
|
||||
</text>
|
||||
<text
|
||||
type="string"
|
||||
length="1"
|
||||
follows="left|top"
|
||||
height="25"
|
||||
layout="topleft"
|
||||
left_delta="0"
|
||||
name="total_time_refetch_vis_cache_label"
|
||||
top_delta="25"
|
||||
width="540">
|
||||
15, Refetching visibles from cache, Time: [TIME] seconds, Fetched: [SIZE]KB, [PIXEL]MPixels
|
||||
</text>
|
||||
<text
|
||||
type="string"
|
||||
length="1"
|
||||
follows="left|top"
|
||||
height="25"
|
||||
layout="topleft"
|
||||
left_delta="0"
|
||||
name="total_time_refetch_vis_http_label"
|
||||
top_delta="25"
|
||||
width="540">
|
||||
16, Refetching visibles from HTTP, Time: [TIME] seconds, Fetched: [SIZE]KB, [PIXEL]MPixels
|
||||
</text>
|
||||
<spinner
|
||||
decimal_digits="2"
|
||||
follows="left|top"
|
||||
height="20"
|
||||
increment="0.01"
|
||||
initial_value="1.0"
|
||||
label="17, Ratio of Texel/Pixel:"
|
||||
label_width="130"
|
||||
layout="topleft"
|
||||
left_delta="0"
|
||||
max_val="10.0"
|
||||
min_val="0.01"
|
||||
name="texel_pixel_ratio"
|
||||
top_delta="30"
|
||||
width="200">
|
||||
<spinner.commit_callback
|
||||
function="TexFetchDebugger.ChangeTexelPixelRatio" />
|
||||
</spinner>
|
||||
<button
|
||||
follows="left|top"
|
||||
height="20"
|
||||
label="Start"
|
||||
layout="topleft"
|
||||
left_delta="0"
|
||||
name="start_btn"
|
||||
top_delta="30"
|
||||
width="70">
|
||||
<button.commit_callback
|
||||
function="TexFetchDebugger.Start" />
|
||||
</button>
|
||||
<button
|
||||
follows="left|top"
|
||||
height="20"
|
||||
label="Reset"
|
||||
layout="topleft"
|
||||
left_pad="7"
|
||||
name="clear_btn"
|
||||
top_delta="0"
|
||||
width="70">
|
||||
<button.commit_callback
|
||||
function="TexFetchDebugger.Clear" />
|
||||
</button>
|
||||
<button
|
||||
follows="left|top"
|
||||
height="20"
|
||||
label="Close"
|
||||
layout="topleft"
|
||||
left_pad="7"
|
||||
name="close_btn"
|
||||
top_delta="0"
|
||||
width="70">
|
||||
<button.commit_callback
|
||||
function="TexFetchDebugger.Close" />
|
||||
</button>
|
||||
<button
|
||||
follows="left|top"
|
||||
height="20"
|
||||
label="Cache Read"
|
||||
layout="topleft"
|
||||
left="10"
|
||||
name="cacheread_btn"
|
||||
top_delta="30"
|
||||
width="80">
|
||||
<button.commit_callback
|
||||
function="TexFetchDebugger.CacheRead" />
|
||||
</button>
|
||||
<button
|
||||
follows="left|top"
|
||||
height="20"
|
||||
label="Cache Write"
|
||||
layout="topleft"
|
||||
left_pad="7"
|
||||
name="cachewrite_btn"
|
||||
top_delta="0"
|
||||
width="80">
|
||||
<button.commit_callback
|
||||
function="TexFetchDebugger.CacheWrite" />
|
||||
</button>
|
||||
<button
|
||||
follows="left|top"
|
||||
height="20"
|
||||
label="HTTP"
|
||||
layout="topleft"
|
||||
left_pad="7"
|
||||
name="http_btn"
|
||||
top_delta="0"
|
||||
width="70">
|
||||
<button.commit_callback
|
||||
function="TexFetchDebugger.HTTPLoad" />
|
||||
</button>
|
||||
<button
|
||||
follows="left|top"
|
||||
height="20"
|
||||
label="Decode"
|
||||
layout="topleft"
|
||||
left_pad="7"
|
||||
name="decode_btn"
|
||||
top_delta="0"
|
||||
width="70">
|
||||
<button.commit_callback
|
||||
function="TexFetchDebugger.Decode" />
|
||||
</button>
|
||||
<button
|
||||
follows="left|top"
|
||||
height="20"
|
||||
label="GL Texture"
|
||||
layout="topleft"
|
||||
left_pad="7"
|
||||
name="gl_btn"
|
||||
top_delta="0"
|
||||
width="70">
|
||||
<button.commit_callback
|
||||
function="TexFetchDebugger.GLTexture" />
|
||||
</button>
|
||||
<button
|
||||
follows="left|top"
|
||||
height="20"
|
||||
label="Refetch Vis Cache"
|
||||
layout="topleft"
|
||||
left="10"
|
||||
name="refetchviscache_btn"
|
||||
top_delta="30"
|
||||
width="120">
|
||||
<button.commit_callback
|
||||
function="TexFetchDebugger.RefetchVisCache" />
|
||||
</button>
|
||||
<button
|
||||
follows="left|top"
|
||||
height="20"
|
||||
label="Refetch Vis HTTP"
|
||||
layout="topleft"
|
||||
left_pad="7"
|
||||
name="refetchvishttp_btn"
|
||||
top_delta="0"
|
||||
width="120">
|
||||
<button.commit_callback
|
||||
function="TexFetchDebugger.RefetchVisHTTP" />
|
||||
</button>
|
||||
</floater>
|
||||
|
|
@ -1876,7 +1876,7 @@
|
|||
<menu_item_check.on_click
|
||||
function="Advanced.ToggleConsole"
|
||||
parameter="texture" />
|
||||
</menu_item_check>
|
||||
</menu_item_check>
|
||||
<menu_item_check
|
||||
label="Debug Console"
|
||||
name="Debug Console"
|
||||
|
|
@ -1897,28 +1897,6 @@
|
|||
function="Floater.Toggle"
|
||||
parameter="notifications_console" />
|
||||
</menu_item_call>
|
||||
<menu_item_check
|
||||
label="Texture Size Console"
|
||||
name="Texture Size"
|
||||
shortcut="control|shift|6">
|
||||
<menu_item_check.on_check
|
||||
function="Advanced.CheckConsole"
|
||||
parameter="texture size" />
|
||||
<menu_item_check.on_click
|
||||
function="Advanced.ToggleConsole"
|
||||
parameter="texture size" />
|
||||
</menu_item_check>
|
||||
<menu_item_check
|
||||
label="Texture Category Console"
|
||||
name="Texture Category"
|
||||
shortcut="control|shift|7">
|
||||
<menu_item_check.on_check
|
||||
function="Advanced.CheckConsole"
|
||||
parameter="texture category" />
|
||||
<menu_item_check.on_click
|
||||
function="Advanced.ToggleConsole"
|
||||
parameter="texture category" />
|
||||
</menu_item_check>
|
||||
<menu_item_check
|
||||
label="Fast Timers"
|
||||
name="Fast Timers"
|
||||
|
|
@ -1953,7 +1931,20 @@
|
|||
function="Advanced.ToggleConsole"
|
||||
parameter="scene view" />
|
||||
</menu_item_check>
|
||||
|
||||
<menu_item_call
|
||||
enabled="false"
|
||||
visible="false"
|
||||
label="Texture Fetch Debug Console"
|
||||
name="Texture Fetch Debug Console">
|
||||
<menu_item_call.on_click
|
||||
function="Floater.Show"
|
||||
parameter="tex_fetch_debugger" />
|
||||
<on_enable
|
||||
function="Develop.SetTexFetchDebugger" />
|
||||
<on_visible
|
||||
function="Develop.SetTexFetchDebugger" />
|
||||
</menu_item_call>
|
||||
|
||||
<menu_item_separator/>
|
||||
|
||||
<menu_item_call
|
||||
|
|
@ -2439,6 +2430,52 @@
|
|||
function="Advanced.ToggleInfoDisplay"
|
||||
parameter="sculpt" />
|
||||
</menu_item_check>
|
||||
<menu
|
||||
create_jump_keys="true"
|
||||
label="Texture Density"
|
||||
name="Texture Density"
|
||||
tear_off="true">
|
||||
<menu_item_check
|
||||
label="None"
|
||||
name="None">
|
||||
<menu_item_check.on_check
|
||||
function="Advanced.CheckDisplayTextureDensity"
|
||||
parameter="none" />
|
||||
<menu_item_check.on_click
|
||||
function="Advanced.SetDisplayTextureDensity"
|
||||
parameter="none" />
|
||||
</menu_item_check>
|
||||
<menu_item_check
|
||||
label="Current"
|
||||
name="Current">
|
||||
<menu_item_check.on_check
|
||||
function="Advanced.CheckDisplayTextureDensity"
|
||||
parameter="current" />
|
||||
<menu_item_check.on_click
|
||||
function="Advanced.SetDisplayTextureDensity"
|
||||
parameter="current" />
|
||||
</menu_item_check>
|
||||
<menu_item_check
|
||||
label="Desired"
|
||||
name="Desired">
|
||||
<menu_item_check.on_check
|
||||
function="Advanced.CheckDisplayTextureDensity"
|
||||
parameter="desired" />
|
||||
<menu_item_check.on_click
|
||||
function="Advanced.SetDisplayTextureDensity"
|
||||
parameter="desired" />
|
||||
</menu_item_check>
|
||||
<menu_item_check
|
||||
label="Full"
|
||||
name="Full">
|
||||
<menu_item_check.on_check
|
||||
function="Advanced.CheckDisplayTextureDensity"
|
||||
parameter="full" />
|
||||
<menu_item_check.on_click
|
||||
function="Advanced.SetDisplayTextureDensity"
|
||||
parameter="full" />
|
||||
</menu_item_check>
|
||||
</menu>
|
||||
</menu>
|
||||
<menu
|
||||
create_jump_keys="true"
|
||||
|
|
@ -2605,16 +2642,6 @@
|
|||
function="ToggleControl"
|
||||
parameter="TextureLoadFullRes" />
|
||||
</menu_item_check>
|
||||
<menu_item_check
|
||||
label="Audit Textures"
|
||||
name="Audit Textures">
|
||||
<menu_item_check.on_check
|
||||
function="CheckControl"
|
||||
parameter="AuditTexture" />
|
||||
<menu_item_check.on_click
|
||||
function="ToggleControl"
|
||||
parameter="AuditTexture" />
|
||||
</menu_item_check>
|
||||
<menu_item_check
|
||||
label="Texture Atlas (experimental)"
|
||||
name="Texture Atlas">
|
||||
|
|
|
|||
|
|
@ -35,6 +35,31 @@
|
|||
#include "lluuid.h"
|
||||
#include "llsdutil.h"
|
||||
#include "llregionhandle.h"
|
||||
#include "../llvoavatar.h"
|
||||
|
||||
void LLVOAvatar::getNearbyRezzedStats(std::vector<S32>& counts)
|
||||
{
|
||||
counts.resize(3);
|
||||
counts[0] = 0;
|
||||
counts[1] = 0;
|
||||
counts[2] = 1;
|
||||
}
|
||||
|
||||
// static
|
||||
std::string LLVOAvatar::rezStatusToString(S32 rez_status)
|
||||
{
|
||||
if (rez_status==0) return "cloud";
|
||||
if (rez_status==1) return "gray";
|
||||
if (rez_status==2) return "textured";
|
||||
return "unknown";
|
||||
}
|
||||
|
||||
// static
|
||||
LLViewerStats::StatsAccumulator& LLViewerStats::PhaseMap::getPhaseStats(const std::string& phase_name)
|
||||
{
|
||||
static LLViewerStats::StatsAccumulator junk;
|
||||
return junk;
|
||||
}
|
||||
|
||||
static const char * all_keys[] =
|
||||
{
|
||||
|
|
@ -104,18 +129,25 @@ is_single_key_map(const LLSD & sd, const std::string & key)
|
|||
{
|
||||
return sd.isMap() && 1 == sd.size() && sd.has(key);
|
||||
}
|
||||
#endif
|
||||
|
||||
static bool
|
||||
is_double_key_map(const LLSD & sd, const std::string & key1, const std::string & key2)
|
||||
{
|
||||
return sd.isMap() && 2 == sd.size() && sd.has(key1) && sd.has(key2);
|
||||
}
|
||||
#endif
|
||||
|
||||
static bool
|
||||
is_triple_key_map(const LLSD & sd, const std::string & key1, const std::string & key2, const std::string& key3)
|
||||
{
|
||||
return sd.isMap() && 3 == sd.size() && sd.has(key1) && sd.has(key2) && sd.has(key3);
|
||||
}
|
||||
|
||||
|
||||
static bool
|
||||
is_no_stats_map(const LLSD & sd)
|
||||
{
|
||||
return is_double_key_map(sd, "duration", "regions");
|
||||
return is_triple_key_map(sd, "duration", "regions", "avatar");
|
||||
}
|
||||
|
||||
static bool
|
||||
|
|
@ -226,7 +258,7 @@ namespace tut
|
|||
// Once the region is set, we will get a response even with no data collection
|
||||
it->setRegion(region1_handle);
|
||||
sd_full = it->asLLSD(false);
|
||||
ensure("Correct single-key LLSD map root", is_double_key_map(sd_full, "duration", "regions"));
|
||||
ensure("Correct single-key LLSD map root", is_triple_key_map(sd_full, "duration", "regions", "avatar"));
|
||||
ensure("Correct single-slot LLSD array regions", is_single_slot_array(sd_full["regions"], region1_handle));
|
||||
|
||||
LLSD sd = sd_full["regions"][0];
|
||||
|
|
@ -267,7 +299,7 @@ namespace tut
|
|||
it->setRegion(region1_handle);
|
||||
|
||||
LLSD sd = it->asLLSD(false);
|
||||
ensure("Correct single-key LLSD map root", is_double_key_map(sd, "regions", "duration"));
|
||||
ensure("Correct single-key LLSD map root", is_triple_key_map(sd, "regions", "duration", "avatar"));
|
||||
ensure("Correct single-slot LLSD array regions", is_single_slot_array(sd["regions"], region1_handle));
|
||||
sd = sd[0];
|
||||
|
||||
|
|
@ -292,7 +324,7 @@ namespace tut
|
|||
LLViewerAssetStatsFF::record_dequeue_main(LLViewerAssetType::AT_BODYPART, false, false);
|
||||
|
||||
LLSD sd = gViewerAssetStatsMain->asLLSD(false);
|
||||
ensure("Correct single-key LLSD map root", is_double_key_map(sd, "regions", "duration"));
|
||||
ensure("Correct single-key LLSD map root", is_triple_key_map(sd, "regions", "duration", "avatar"));
|
||||
ensure("Correct single-slot LLSD array regions", is_single_slot_array(sd["regions"], region1_handle));
|
||||
sd = sd["regions"][0];
|
||||
|
||||
|
|
@ -332,7 +364,7 @@ namespace tut
|
|||
LLSD sd = gViewerAssetStatsThread1->asLLSD(false);
|
||||
ensure("Other collector is empty", is_no_stats_map(sd));
|
||||
sd = gViewerAssetStatsMain->asLLSD(false);
|
||||
ensure("Correct single-key LLSD map root", is_double_key_map(sd, "regions", "duration"));
|
||||
ensure("Correct single-key LLSD map root", is_triple_key_map(sd, "regions", "duration", "avatar"));
|
||||
ensure("Correct single-slot LLSD array regions", is_single_slot_array(sd["regions"], region1_handle));
|
||||
sd = sd["regions"][0];
|
||||
|
||||
|
|
@ -382,7 +414,7 @@ namespace tut
|
|||
|
||||
// std::cout << sd << std::endl;
|
||||
|
||||
ensure("Correct double-key LLSD map root", is_double_key_map(sd, "duration", "regions"));
|
||||
ensure("Correct double-key LLSD map root", is_triple_key_map(sd, "duration", "regions", "avatar"));
|
||||
ensure("Correct double-slot LLSD array regions", is_double_slot_array(sd["regions"], region1_handle, region2_handle));
|
||||
LLSD sd1 = get_region(sd, region1_handle);
|
||||
LLSD sd2 = get_region(sd, region2_handle);
|
||||
|
|
@ -405,7 +437,7 @@ namespace tut
|
|||
// Reset leaves current region in place
|
||||
gViewerAssetStatsMain->reset();
|
||||
sd = gViewerAssetStatsMain->asLLSD(false);
|
||||
ensure("Correct single-key LLSD map root", is_double_key_map(sd, "regions", "duration"));
|
||||
ensure("Correct single-key LLSD map root", is_triple_key_map(sd, "regions", "duration", "avatar"));
|
||||
ensure("Correct single-slot LLSD array regions (p2)", is_single_slot_array(sd["regions"], region2_handle));
|
||||
sd2 = sd["regions"][0];
|
||||
|
||||
|
|
@ -454,7 +486,7 @@ namespace tut
|
|||
|
||||
LLSD sd = gViewerAssetStatsMain->asLLSD(false);
|
||||
|
||||
ensure("Correct double-key LLSD map root", is_double_key_map(sd, "duration", "regions"));
|
||||
ensure("Correct double-key LLSD map root", is_triple_key_map(sd, "duration", "regions", "avatar"));
|
||||
ensure("Correct double-slot LLSD array regions", is_double_slot_array(sd["regions"], region1_handle, region2_handle));
|
||||
LLSD sd1 = get_region(sd, region1_handle);
|
||||
LLSD sd2 = get_region(sd, region2_handle);
|
||||
|
|
@ -477,7 +509,7 @@ namespace tut
|
|||
// Reset leaves current region in place
|
||||
gViewerAssetStatsMain->reset();
|
||||
sd = gViewerAssetStatsMain->asLLSD(false);
|
||||
ensure("Correct single-key LLSD map root", is_double_key_map(sd, "duration", "regions"));
|
||||
ensure("Correct single-key LLSD map root", is_triple_key_map(sd, "duration", "regions", "avatar"));
|
||||
ensure("Correct single-slot LLSD array regions (p2)", is_single_slot_array(sd["regions"], region2_handle));
|
||||
sd2 = get_region(sd, region2_handle);
|
||||
ensure("Region2 is present in results", sd2.isMap());
|
||||
|
|
@ -523,7 +555,7 @@ namespace tut
|
|||
LLSD sd = gViewerAssetStatsThread1->asLLSD(false);
|
||||
ensure("Other collector is empty", is_no_stats_map(sd));
|
||||
sd = gViewerAssetStatsMain->asLLSD(false);
|
||||
ensure("Correct single-key LLSD map root", is_double_key_map(sd, "regions", "duration"));
|
||||
ensure("Correct single-key LLSD map root", is_triple_key_map(sd, "regions", "duration", "avatar"));
|
||||
ensure("Correct single-slot LLSD array regions", is_single_slot_array(sd["regions"], region1_handle));
|
||||
sd = get_region(sd, region1_handle);
|
||||
ensure("Region1 is present in results", sd.isMap());
|
||||
|
|
|
|||
Loading…
Reference in New Issue