Ansariel 2021-06-07 20:55:41 +02:00
commit bc7c4fb82a
30 changed files with 405 additions and 80 deletions

View File

@ -45,6 +45,7 @@
#define FSZoneNC( name, color ) ZoneNamedNC( ___tracy_scoped_zone, name, color, FSTelemetry::active)
#define FSPlot( name, value ) TracyPlot( name, value)
#define FSFrameMark FrameMark
#define FSThreadName( name ) tracy::SetThreadName( name )
#define FSTelemetryIsConnected TracyIsConnected
#else // (no telemetry)
@ -58,6 +59,7 @@
#define FSZoneNC( name, color )
#define FSPlot( name, value )
#define FSFrameMark
#define FSThreadName( name )
#define FSTelemetryIsConnected
#endif // TRACY_ENABLE

View File

@ -35,6 +35,7 @@
#include "lltrace.h"
#include "lltracethreadrecorder.h"
#include "llexception.h"
#include "fstelemetry.h" // <FS:Beq> allow thread naming
#if LL_LINUX
#include <sched.h>
@ -140,7 +141,10 @@ void LLThread::threadRun()
// for now, hard code all LLThreads to report to single master thread recorder, which is known to be running on main thread
mRecorder = new LLTrace::ThreadRecorder(*LLTrace::get_master_thread_recorder());
// <FS:Beq> - Add threadnames to telemetry
LL_INFOS("THREAD") << "Started thread " << mName << LL_ENDL;
FSThreadName( mName.c_str() );
// </FS:Beq>
// Run the user supplied function
do
{

View File

@ -197,7 +197,7 @@ class LLDiskCache :
class FSPurgeDiskCacheThread : public LLThread
{
public:
FSPurgeDiskCacheThread::FSPurgeDiskCacheThread();
FSPurgeDiskCacheThread();
protected:
void run() override;

View File

@ -25,7 +25,7 @@
*/
#include "linden_common.h"
#include "fstelemetry.h" // <FS:Beq> add telemetry support.
#include "llimageworker.h"
#include "llimagedxt.h"
@ -135,7 +135,12 @@ LLImageDecodeThread::~LLImageDecodeThread()
// virtual
S32 LLImageDecodeThread::update(F32 max_time_ms)
{
FSZoneC(tracy::Color::Blue); // <FS:Beq/> instrument image decodes
LLMutexLock lock(mCreationMutex);
// <FS:Beq> instrument image decodes
{
FSZoneC(tracy::Color::Blue1);
// </FS:Beq>
for (creation_list_t::iterator iter = mCreationList.begin();
iter != mCreationList.end(); ++iter)
{
@ -155,16 +160,49 @@ S32 LLImageDecodeThread::update(F32 max_time_ms)
}
}
mCreationList.clear();
// <FS:Beq> instrument image decodes
}
{
FSZoneC(tracy::Color::Blue2);
// </FS:Beq>
S32 res = LLQueuedThread::update(max_time_ms);
// FSPlot("img_decode_pending", (int64_t)res); // <FS:Beq/> instrument image decodes
return res;
} // <FS:Beq/> instrument image decodes
}
LLImageDecodeThread::handle_t LLImageDecodeThread::decodeImage(LLImageFormatted* image,
U32 priority, S32 discard, BOOL needs_aux, Responder* responder)
{
LLMutexLock lock(mCreationMutex);
FSZoneC(tracy::Color::Orange); // <FS:Beq> instrument the image decode pipeline
// <FS:Beq> De-couple texture threading from mainloop
// LLMutexLock lock(mCreationMutex);
// handle_t handle = generateHandle();
// mCreationList.push_back(creation_info(handle, image, priority, discard, needs_aux, responder));
handle_t handle = generateHandle();
mCreationList.push_back(creation_info(handle, image, priority, discard, needs_aux, responder));
// If we have a thread pool dispatch this directly.
// Note: addRequest could cause the handling to take place on the fetch thread, this is unlikely to be an issue.
// if this is an actual problem we move the fallback to here and place the unfulfilled request into the legacy queue
if (s_ChildThreads > 0)
{
FSZoneNC("DecodeDecoupled", tracy::Color::Orange); // <FS:Beq> instrument the image decode pipeline
ImageRequest* req = new ImageRequest(handle, image,
priority, discard, needs_aux,
responder, this);
bool res = addRequest(req);
if (!res)
{
LL_WARNS() << "Decode request not added because we are exiting." << LL_ENDL;
return 0;
}
}
else
{
FSZoneNC("DecodeQueued", tracy::Color::Orange); // <FS:Beq> instrument the image decode pipeline
LLMutexLock lock(mCreationMutex);
mCreationList.push_back(creation_info(handle, image, priority, discard, needs_aux, responder));
}
// </FS:Beq>
return handle;
}
@ -230,10 +268,19 @@ bool LLImageDecodeThread::ImageRequest::processRequest()
bool LLImageDecodeThread::ImageRequest::processRequestIntern()
{
const F32 decode_time_slice = .1f;
// <FS:Beq> allow longer timeout for async and add instrumentation
// const F32 decode_time_slice = .1f;
FSZoneC(tracy::Color::DarkOrange);
F32 decode_time_slice = .1f;
if(mFlags & FLAG_ASYNC)
{
decode_time_slice = 10.0f;// long time out as this is not an issue with async
}
// </FS:Beq>
bool done = true;
if (!mDecodedRaw && mFormattedImage.notNull())
{
FSZoneC(tracy::Color::DarkOrange1); // <FS:Beq> instrument the image decode pipeline
// Decode primary channels
if (mDecodedImageRaw.isNull())
{
@ -272,6 +319,7 @@ bool LLImageDecodeThread::ImageRequest::processRequestIntern()
}
if (done && mNeedsAux && !mDecodedAux && mFormattedImage.notNull())
{
FSZoneC(tracy::Color::DarkOrange2); // <FS:Beq> instrument the image decode pipeline
// Decode aux channel
if (!mDecodedImageAux)
{
@ -282,7 +330,12 @@ bool LLImageDecodeThread::ImageRequest::processRequestIntern()
done = mFormattedImage->decodeChannels(mDecodedImageAux, decode_time_slice, 4, 4); // 1ms
mDecodedAux = done && mDecodedImageAux->getData();
}
// <FS:Beq> report timeout on async thread (which leads to worker abort errors)
if(!done)
{
LL_WARNS("ImageDecode") << "Image decoding failed to complete with time slice=" << decode_time_slice << LL_ENDL;
}
// </FS:Beq>
//<FS:ND> Image thread pool from CoolVL
if (mFlags & FLAG_ASYNC)
{

View File

@ -25,6 +25,7 @@
*/
#include "linden_common.h"
#include "fstelemetry.h" // <FS:Beq> instrument image decodes
#include "llimagej2coj.h"
#define OPENJPEG2
@ -258,10 +259,11 @@ bool LLImageJ2COJ::initEncode(LLImageJ2C &base, LLImageRaw &raw_image, int block
bool LLImageJ2COJ::decodeImpl(LLImageJ2C &base, LLImageRaw &raw_image, F32 decode_time, S32 first_channel, S32 max_channel_count)
{
// <FS:Techwolf Lupindo> texture comment metadata reader
FSZone; // <FS:Beq> instrument image decodes
U8* c_data = base.getData();
S32 c_size = base.getDataSize();
S32 position = 0;
while (position < 1024 && position < (c_size - 7)) // the comment field should be in the first 1024 bytes.
{
if (c_data[position] == 0xff && c_data[position + 1] == 0x64)

View File

@ -32,7 +32,7 @@
#include "llpointer.h"
#include "llmath.h"
#include "llkdumem.h"
#include "fstelemetry.h" // <FS:Beq> instrument image decodes
#define kdu_xxxx "kdu_block_coding.h"
#include "include_kdu_xxxx.h"
@ -287,6 +287,7 @@ void transfer_bytes(kdu_byte *dest, kdu_line_buf &src, int gap, int precision);
// as well, when that still existed, with keep_codestream true and MODE_FAST.
void LLImageJ2CKDU::setupCodeStream(LLImageJ2C &base, bool keep_codestream, ECodeStreamMode mode)
{
FSZone; // <FS:Beq> instrument image decodes
S32 data_size = base.getDataSize();
S32 max_bytes = (base.getMaxBytes() ? base.getMaxBytes() : data_size);
@ -436,6 +437,7 @@ bool LLImageJ2CKDU::initEncode(LLImageJ2C &base, LLImageRaw &raw_image, int bloc
// decodeImpl() usage matters for production.
bool LLImageJ2CKDU::initDecode(LLImageJ2C &base, LLImageRaw &raw_image, F32 decode_time, ECodeStreamMode mode, S32 first_channel, S32 max_channel_count, int discard_level, int* region)
{
FSZone; // <FS:Beq> instrument image decodes
base.resetLastError();
// *FIX: kdu calls our callback function if there's an error, and then bombs.
@ -519,6 +521,7 @@ bool LLImageJ2CKDU::initDecode(LLImageJ2C &base, LLImageRaw &raw_image, F32 deco
// Returns true to mean done, whether successful or not.
bool LLImageJ2CKDU::decodeImpl(LLImageJ2C &base, LLImageRaw &raw_image, F32 decode_time, S32 first_channel, S32 max_channel_count)
{
FSZone; // <FS:Beq> instrument image decodes
ECodeStreamMode mode = MODE_FAST;
LLTimer decode_timer;

View File

@ -1220,7 +1220,13 @@ bool LLModel::isMaterialListSubset( LLModel* ref )
{
int refCnt = ref->mMaterialList.size();
int modelCnt = mMaterialList.size();
// <FS:Beq> FIRE-30965 Cleanup braindead mesh parsing error handlers
if(modelCnt > refCnt)
{
// this model cannot be a strict subset if it has more materials than the reference
return FALSE;
}
// </FS:Beq>
for (U32 src = 0; src < modelCnt; ++src)
{
bool foundRef = false;
@ -1264,77 +1270,80 @@ bool LLModel::needToAddFaces( LLModel* ref, int& refFaceCnt, int& modelFaceCnt )
return changed;
}
bool LLModel::matchMaterialOrder(LLModel* ref, int& refFaceCnt, int& modelFaceCnt )
{
//Is this a subset?
//LODs cannot currently add new materials, e.g.
//1. ref = a,b,c lod1 = d,e => This is not permitted
//2. ref = a,b,c lod1 = c => This would be permitted
// <FS:Beq> FIRE-30965 Improve mesh upload error handling
// function moved to llmodelpreview
// bool LLModel::matchMaterialOrder(LLModel* ref, int& refFaceCnt, int& modelFaceCnt )
// {
// //Is this a subset?
// //LODs cannot currently add new materials, e.g.
// //1. ref = a,b,c lod1 = d,e => This is not permitted
// //2. ref = a,b,c lod1 = c => This would be permitted
bool isASubset = isMaterialListSubset( ref );
if ( !isASubset )
{
LL_INFOS("MESHSKININFO")<<"Material of model is not a subset of reference."<<LL_ENDL;
return false;
}
// bool isASubset = isMaterialListSubset( ref );
// if ( !isASubset )
// {
// LL_INFOS("MESHSKININFO")<<"Material of model is not a subset of reference."<<LL_ENDL;
// return false;
// }
if (mMaterialList.size() > ref->mMaterialList.size())
{
LL_INFOS("MESHSKININFO") << "Material of model has more materials than a reference." << LL_ENDL;
// We passed isMaterialListSubset, so materials are a subset, but subset isn't supposed to be
// larger than original and if we keep going, reordering will cause a crash
return false;
}
// if (mMaterialList.size() > ref->mMaterialList.size())
// {
// LL_INFOS("MESHSKININFO") << "Material of model has more materials than a reference." << LL_ENDL;
// // We passed isMaterialListSubset, so materials are a subset, but subset isn't supposed to be
// // larger than original and if we keep going, reordering will cause a crash
// return false;
// }
std::map<std::string, U32> index_map;
// std::map<std::string, U32> index_map;
//build a map of material slot names to face indexes
bool reorder = false;
// //build a map of material slot names to face indexes
// bool reorder = false;
std::set<std::string> base_mat;
std::set<std::string> cur_mat;
// std::set<std::string> base_mat;
// std::set<std::string> cur_mat;
for (U32 i = 0; i < mMaterialList.size(); i++)
{
index_map[ref->mMaterialList[i]] = i;
//if any material name does not match reference, we need to reorder
reorder |= ref->mMaterialList[i] != mMaterialList[i];
base_mat.insert(ref->mMaterialList[i]);
cur_mat.insert(mMaterialList[i]);
}
// for (U32 i = 0; i < mMaterialList.size(); i++)
// {
// index_map[ref->mMaterialList[i]] = i;
// //if any material name does not match reference, we need to reorder
// reorder |= ref->mMaterialList[i] != mMaterialList[i];
// base_mat.insert(ref->mMaterialList[i]);
// cur_mat.insert(mMaterialList[i]);
// }
if (reorder && (base_mat == cur_mat)) //don't reorder if material name sets don't match
{
std::vector<LLVolumeFace> new_face_list;
new_face_list.resize(mMaterialList.size());
// if (reorder && (base_mat == cur_mat)) //don't reorder if material name sets don't match
// {
// std::vector<LLVolumeFace> new_face_list;
// new_face_list.resize(mMaterialList.size());
std::vector<std::string> new_material_list;
new_material_list.resize(mMaterialList.size());
// std::vector<std::string> new_material_list;
// new_material_list.resize(mMaterialList.size());
//rebuild face list so materials have the same order
//as the reference model
for (U32 i = 0; i < mMaterialList.size(); ++i)
{
U32 ref_idx = index_map[mMaterialList[i]];
// //rebuild face list so materials have the same order
// //as the reference model
// for (U32 i = 0; i < mMaterialList.size(); ++i)
// {
// U32 ref_idx = index_map[mMaterialList[i]];
if (i < mVolumeFaces.size())
{
new_face_list[ref_idx] = mVolumeFaces[i];
}
new_material_list[ref_idx] = mMaterialList[i];
}
// if (i < mVolumeFaces.size())
// {
// new_face_list[ref_idx] = mVolumeFaces[i];
// }
// new_material_list[ref_idx] = mMaterialList[i];
// }
llassert(new_material_list == ref->mMaterialList);
// llassert(new_material_list == ref->mMaterialList);
mVolumeFaces = new_face_list;
// mVolumeFaces = new_face_list;
//override material list with reference model ordering
mMaterialList = ref->mMaterialList;
}
// //override material list with reference model ordering
// mMaterialList = ref->mMaterialList;
// }
return true;
}
// return true;
// }
// </FS:Beq>
bool LLModel::loadSkinInfo(LLSD& header, std::istream &is)
{

View File

@ -187,7 +187,7 @@ public:
//reorder face list based on mMaterialList in this and reference so
//order matches that of reference (material ordering touchup)
bool matchMaterialOrder(LLModel* ref, int& refFaceCnt, int& modelFaceCnt );
// bool matchMaterialOrder(LLModel* ref, int& refFaceCnt, int& modelFaceCnt ); // <FS:Beq/> FIRE-30965 error handling improvements (function relocated)
bool isMaterialListSubset( LLModel* ref );
bool needToAddFaces( LLModel* ref, int& refFaceCnt, int& modelFaceCnt );

View File

@ -87,7 +87,7 @@ public:
DONE,
WARNING_BIND_SHAPE_ORIENTATION,
ERROR_PARSING, //basically loading failed
ERROR_MATERIALS,
ERROR_MATERIALS_NOT_A_SUBSET, // <FS:Beq/> FIRE-30965 - better error differentiation
ERROR_PASSWORD_REQUIRED,
ERROR_NEED_MORE_MEMORY,
ERROR_INVALID_FILE,
@ -96,6 +96,7 @@ public:
ERROR_OUT_OF_RANGE,
ERROR_FILE_VERSION_INVALID,
ERROR_LOD_MODEL_MISMATCH, // <FS:Beq/> clean up and improve error reporting
ERROR_HIGH_LOD_MODEL_MISSING, // <FS:Beq/> clean up and improve error reporting
ERROR_MODEL // this error should always be last in this list, error code is passed as ERROR_MODEL+error_code
} eLoadState;

View File

@ -25672,5 +25672,27 @@ Change of this parameter will affect the layout of buttons in notification toast
<key>Value</key>
<integer>1</integer>
</map>
<key>FSAutoUnmuteSounds</key>
<map>
<key>Comment</key>
<string>If Sound Effects are muted, unmute on TP. Default (false)</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
<integer>0</integer>
</map>
<key>FSAutoUnmuteAmbient</key>
<map>
<key>Comment</key>
<string>If Ambient sounds are muted, unmute on TP. Default (false)</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
<integer>0</integer>
</map>
</map>
</llsd>

View File

@ -25,6 +25,7 @@
uniform mat3 normal_matrix;
uniform mat4 texture_matrix0;
uniform vec4 ambient_color; // <FS:Beq/> add ambient color to preview shader
uniform mat4 modelview_matrix;
uniform mat4 modelview_projection_matrix;
@ -87,7 +88,7 @@ void main()
vec3 norm = normalize(normal_matrix * normal);
vec4 col = vec4(0,0,0,1);
vec4 col = ambient_color; // <FS:Beq/> add ambient color to preview shader
// Collect normal lights (need to be divided by two, as we later multiply by 2)
col.rgb += light_diffuse[1].rgb * calcDirectionalLight(norm, light_position[1].xyz);

View File

@ -1879,8 +1879,13 @@ bool LLAppViewer::doFrame()
S32 work_pending = 0;
S32 io_pending = 0;
F32 max_time = llmin(gFrameIntervalSeconds.value() *10.f, 1.f);
// <FS:Beq> instrument image decodes
{
FSZoneN("updateTextureThreads");
// FSPlot("max_time_ms",max_time);
// <FS:Beq/>
work_pending += updateTextureThreads(max_time);
} // <FS:Beq/> instrument image decodes
{
LL_RECORD_BLOCK_TIME(FTM_LFS);
@ -3827,6 +3832,7 @@ LLSD LLAppViewer::getViewerInfo() const
// CPU
info["CPU"] = gSysCPU.getCPUString();
info["MEMORY_MB"] = LLSD::Integer(gSysMemory.getPhysicalMemoryKB().valueInUnits<LLUnits::Megabytes>());
info["CONCURRENCY"] = LLSD::Integer((S32)boost::thread::hardware_concurrency()); // <FS:Beq> Add hardware concurrency to info
// Moved hack adjustment to Windows memory size into llsys.cpp
info["OS_VERSION"] = LLOSInfo::instance().getOSString();
info["GRAPHICS_CARD_VENDOR"] = ll_safe_string((const char*)(glGetString(GL_VENDOR)));

View File

@ -864,7 +864,7 @@ void LLFloaterModelPreview::draw()
if (!mModelPreview->mLoading)
{
if ( mModelPreview->getLoadState() == LLModelLoader::ERROR_MATERIALS )
if ( mModelPreview->getLoadState() == LLModelLoader::ERROR_MATERIALS_NOT_A_SUBSET )// <FS:Beq/> Improve error reporting
{
// <FS:Beq> cleanup/improve errors - this error is effectively duplicated, the unused one was actually better
// childSetTextArg("status", "[STATUS]", getString("status_material_mismatch"));

View File

@ -2234,6 +2234,22 @@ bool LLInventoryModel::loadSkeleton(
LLFile::remove(inventory_filename);
}
// also delete library cache if inventory cache is purged, so issues with EEP settings going missing
// and bridge objects not being found can be resolved
inventory_filename = getInvCacheAddres(ALEXANDRIA_LINDEN_ID);
if (LLFile::isfile(inventory_filename))
{
LL_INFOS("LLInventoryModel") << "Purging library cache file: " << inventory_filename << LL_ENDL;
LLFile::remove(inventory_filename);
}
inventory_filename.append(".gz");
if (LLFile::isfile(inventory_filename))
{
LL_INFOS("LLInventoryModel") << "Purging library cache file: " << inventory_filename << LL_ENDL;
LLFile::remove(inventory_filename);
}
LL_INFOS("LLInventoryModel") << "Clear inventory cache marker removed: " << delete_cache_marker << LL_ENDL;
LLFile::remove(delete_cache_marker);
}

View File

@ -368,6 +368,118 @@ U32 LLModelPreview::calcResourceCost()
return (U32)streaming_cost;
}
// <FS:Beq> relocate from llmodel and rewrite so it does what it is meant to
// Material matching should work as the comment below states (subsets are allowed)
// prior to this a mess in multiple places meant that all LODs are forced to carry unwanted triangles for unused materials
bool LLModelPreview::matchMaterialOrder(LLModel* lod, LLModel* ref, int& refFaceCnt, int& modelFaceCnt )
{
//Is this a subset?
//LODs cannot currently add new materials, e.g.
//1. ref = a,b,c lod1 = d,e => This is not permitted
//2. ref = a,b,c lod1 = c => This would be permitted
LL_INFOS("MESHSKININFO") << "In matchMaterialOrder." << LL_ENDL;
bool isASubset = lod->isMaterialListSubset( ref );
if ( !isASubset )
{
LL_INFOS("MESHSKININFO")<<"Material of model is not a subset of reference."<<LL_ENDL;
std::ostringstream out;
out << "LOD model " << lod->getName() << "'s materials are not a subset of the High LOD (reference) model " << ref->getName();
LL_INFOS() << out.str() << LL_ENDL;
LLFloaterModelPreview::addStringToLog(out, true);
return false;
}
LL_DEBUGS("MESHSKININFO") << "subset check passed." << LL_ENDL;
std::map<std::string, U32> index_map;
//build a map of material slot names to face indexes
bool reorder = false;
auto max_lod_mats = lod->mMaterialList.size();
for ( U32 i = 0; i < ref->mMaterialList.size(); i++ )
{
// create the reference map for later
index_map[ref->mMaterialList[i]] = i;
LL_DEBUGS("MESHSKININFO") << "setting reference material " << ref->mMaterialList[i] << " as index " << i << LL_ENDL;
if( i >= max_lod_mats || lod->mMaterialList[i] != ref->mMaterialList[i] )
{
// i is already out of range of the original material sets in this LOD OR is not matching.
LL_DEBUGS("MESHSKININFO") << "mismatch at " << i << " " << ref->mMaterialList[i]
<< " != " << ((i >= max_lod_mats)? "Out-of-range":lod->mMaterialList[i]) << LL_ENDL;
// we have a misalignment/ordering
// check that ref[i] is in cur and if not add a blank
U32 j{0};
for ( ; j < max_lod_mats; j++ )
{
if( i != j && lod->mMaterialList[j] == ref->mMaterialList[i] )
{
LL_DEBUGS("MESHSKININFO") << "material " << ref->mMaterialList[i]
<< " found at " << j << LL_ENDL;
// we found it but in the wrong place.
reorder = true;
break;
}
}
if( j >= max_lod_mats )
{
std::ostringstream out;
out << "material " << ref->mMaterialList[i]
<< " not found in lod adding placeholder";
LL_DEBUGS("MESHSKININFO") << out.str() << LL_ENDL;
if (mImporterDebug)
{
LLFloaterModelPreview::addStringToLog(out, false);
}
// The material is not in the submesh, add a placeholder.
// this is appended to the existing data so we'll need to reorder
// Note that this placeholder will be eliminated on the writeData (upload) and replaced with
// "NoGeometry" in the LLSD
reorder = true;
LLVolumeFace face;
face.resizeIndices(3);
face.resizeVertices(1);
face.mPositions->clear();
face.mNormals->clear();
face.mTexCoords->setZero();
memset(face.mIndices, 0, sizeof(U16)*3);
lod->addFace(face);
lod->mMaterialList.push_back( ref->mMaterialList[i] );
}
}
//if any material name does not match reference, we need to reorder
}
LL_DEBUGS("MESHSKININFO") << "finished parsing materials" << LL_ENDL;
for ( U32 i = 0; i < lod->mMaterialList.size(); i++ )
{
LL_DEBUGS("MESHSKININFO") << "lod material " << lod->mMaterialList[i] << " has index " << i << LL_ENDL;
}
// Sanity check. We have added placeholders for any mats in ref that are not in this.
// the mat count MUST be equal now.
if (lod->mMaterialList.size() != ref->mMaterialList.size())
{
std::ostringstream out;
out << "Material of LOD model " << lod->getName() << " has more materials than the reference " << ref->getName() << ".";
LL_INFOS("MESHSKININFO") << out.str() << LL_ENDL;
LLFloaterModelPreview::addStringToLog(out, true);
return false;
}
// <FS:Beq> Fix up material matching badness
// if (reorder && (base_mat == cur_mat)) //don't reorder if material name sets don't match
if ( reorder )
{
LL_INFOS("MESHSKININFO") << "re-ordering." << LL_ENDL;
lod->sortVolumeFacesByMaterialName();
lod->mMaterialList = ref->mMaterialList;
}
return true;
}
//</FS:Beq>
void LLModelPreview::rebuildUploadData()
{
assert_main_thread();
@ -582,7 +694,7 @@ void LLModelPreview::rebuildUploadData()
if (!high_lod_model)
{
LLFloaterModelPreview::addStringToLog("Model " + instance.mLabel + " has no High Lod (LOD3).", true);
load_state = LLModelLoader::ERROR_MATERIALS;
load_state = LLModelLoader::ERROR_HIGH_LOD_MODEL_MISSING; // <FS:Beq/> FIRE-30965 Cleanup braindead mesh parsing error handlers
mFMP->childDisable("calculate_btn");
}
else
@ -592,10 +704,13 @@ void LLModelPreview::rebuildUploadData()
int refFaceCnt = 0;
int modelFaceCnt = 0;
llassert(instance.mLOD[i]);
if (instance.mLOD[i] && !instance.mLOD[i]->matchMaterialOrder(high_lod_model, refFaceCnt, modelFaceCnt))
// <FS:Beq> Fix material matching algorithm to work as per design
// if (instance.mLOD[i] && !instance.mLOD[i]->matchMaterialOrder(high_lod_model, refFaceCnt, modelFaceCnt))
if (instance.mLOD[i] && !matchMaterialOrder(instance.mLOD[i],high_lod_model, refFaceCnt, modelFaceCnt))
// </FS:Beq>
{
LLFloaterModelPreview::addStringToLog("Model " + instance.mLabel + " has mismatching materials between lods." , true);
load_state = LLModelLoader::ERROR_MATERIALS;
load_state = LLModelLoader::ERROR_MATERIALS_NOT_A_SUBSET; // <FS:Beq/> more descriptive errors
mFMP->childDisable("calculate_btn");
}
}
@ -664,7 +779,12 @@ void LLModelPreview::rebuildUploadData()
// encountered issues
setLoadState(load_state);
}
else if (getLoadState() == LLModelLoader::ERROR_MATERIALS
// <FS:Beq> FIRE-30965 Cleanup braindead mesh parsing error handlers
// else if (getLoadState() == LLModelLoader::ERROR_MATERIALS
else if (getLoadState() == LLModelLoader::ERROR_MATERIALS_NOT_A_SUBSET
|| getLoadState() == LLModelLoader::ERROR_HIGH_LOD_MODEL_MISSING
|| getLoadState() == LLModelLoader::ERROR_LOD_MODEL_MISMATCH
// </FS:Beq>
|| getLoadState() == LLModelLoader::WARNING_BIND_SHAPE_ORIENTATION)
{
// This is only valid for these two error types because they are
@ -1873,7 +1993,7 @@ void LLModelPreview::updateStatusMessages()
LLModel* model_high_lod = instance.mLOD[LLModel::LOD_HIGH];
if (!model_high_lod)
{
setLoadState(LLModelLoader::ERROR_MATERIALS);
setLoadState(LLModelLoader::ERROR_HIGH_LOD_MODEL_MISSING); // <FS:Beq/> FIRE-30965 Cleanup braindead mesh parsing error handlers
mFMP->childDisable("calculate_btn");
continue;
}
@ -1883,7 +2003,7 @@ void LLModelPreview::updateStatusMessages()
LLModel* lod_model = instance.mLOD[i];
if (!lod_model)
{
setLoadState(LLModelLoader::ERROR_MATERIALS);
setLoadState(LLModelLoader::ERROR_LOD_MODEL_MISMATCH); // <FS:Beq/> FIRE-30965 Cleanup braindead mesh parsing error handlers
mFMP->childDisable("calculate_btn");
}
else
@ -3253,6 +3373,7 @@ BOOL LLModelPreview::render()
gGL.loadIdentity();
gPipeline.enableLightsPreview();
gObjectPreviewProgram.uniform4fv(LLShaderMgr::AMBIENT, 1, LLPipeline::PreviewAmbientColor.mV); // <FS:Beq> pass ambient setting to shader
LLQuaternion camera_rot = LLQuaternion(mCameraPitch, LLVector3::y_axis) *
LLQuaternion(mCameraYaw, LLVector3::z_axis);

View File

@ -200,7 +200,7 @@ public:
bool mHasDegenerate;
protected:
bool matchMaterialOrder(LLModel* lod, LLModel* ref, int& refFaceCnt, int& modelFaceCnt ); // <FS:Beq/> FIRE-30965 Cleanup mesh material parsing
static void loadedCallback(LLModelLoader::scene& scene, LLModelLoader::model_list& model_list, S32 lod, void* opaque);
static void stateChangedCallback(U32 state, void* opaque);

View File

@ -235,4 +235,28 @@ void LLPreviewAnim::onClose(bool app_quitting)
// }
// }
//}
// virtual
void LLPreviewAnim::refreshFromItem()
{
LLPreview::refreshFromItem();
const LLInventoryItem* item = getItem();
if (item)
{
pMotion = gAgentAvatarp->createMotion(item->getAssetUUID()); // preload the animation
if (pMotion)
{
LLTextBox* stats_box_left = getChild<LLTextBox>("AdvancedStatsLeft");
LLTextBox* stats_box_right = getChild<LLTextBox>("AdvancedStatsRight");
stats_box_left->setTextArg("[PRIORITY]", llformat("%d", pMotion->getPriority()));
stats_box_left->setTextArg("[DURATION]", llformat("%.2f", pMotion->getDuration()));
stats_box_left->setTextArg("[IS_LOOP]", (pMotion->getLoop() ? LLTrans::getString("PermYes") : LLTrans::getString("PermNo")));
stats_box_right->setTextArg("[EASE_IN]", llformat("%.2f", pMotion->getEaseInDuration()));
stats_box_right->setTextArg("[EASE_OUT]", llformat("%.2f", pMotion->getEaseOutDuration()));
stats_box_right->setTextArg("[NUM_JOINTS]", llformat("%d", pMotion->getNumJointMotions()));
}
}
}
// </FS:Ansariel>

View File

@ -45,6 +45,7 @@ public:
void play(const LLSD& param);
// <FS:Ansariel> Improved animation preview
//void showAdvanced();
/*virtual*/ void refreshFromItem();
protected:

View File

@ -3956,6 +3956,13 @@ void process_agent_movement_complete(LLMessageSystem* msg, void**)
gSavedPerAccountSettings.setBOOL("FSRenderFriendsOnly", FALSE);
}
// </FS:Beq>
// <FS:Beq pp Becca> FIRE-30947: Auto-Unmute
if (gSavedSettings.getBOOL("MuteSounds") && gSavedSettings.getBOOL("FSAutoUnmuteSounds"))
gSavedSettings.setBOOL("MuteSounds", FALSE);
if (gSavedSettings.getBOOL("MuteAmbient") && gSavedSettings.getBOOL("FSAutoUnmuteAmbient"))
gSavedSettings.setBOOL("MuteAmbient", FALSE);
// </FS:Beq pp Becca>
if (gAgent.getTeleportKeepsLookAt())
{
// *NOTE: the LookAt data we get from the sim here doesn't

View File

@ -3219,7 +3219,7 @@ BOOL LLViewerShaderMgr::loadShadersObject()
if (success)
{
gObjectPreviewProgram.mName = "Simple Shader";
gObjectPreviewProgram.mName = "Preview Shader"; // <FS:Beq> update preview shader name
gObjectPreviewProgram.mFeatures.calculatesLighting = false;
gObjectPreviewProgram.mFeatures.calculatesAtmospherics = false;
gObjectPreviewProgram.mFeatures.hasGamma = false;

View File

@ -393,6 +393,7 @@
</text>
<color_swatch label="Hintergrund" tool_tip="Hintergrundfarbe für den Uploader" name="mesh_preview_canvas_color"/>
<color_swatch label="Modell-Kanten" tool_tip="Farbe für Kanten des Modells im Vorschau-Fenster" name="mesh_preview_edge_color"/>
<color_swatch label="Umgebungslicht" tool_tip="Umgebungslicht im Vorschau-Fenster (hat ebenfalls Auswirkung u.a. auf Vorschau für Animationsupload)" name="preview_ambient_color"/>
<text name="physics_settings_label">
Physik:
</text>

View File

@ -25,6 +25,11 @@
<check_box label="Aktiviert" name="enable_media"/>
<slider label="Voice-Chat" name="Voice Volume"/>
<check_box label="Aktiviert" name="enable_voice_check_volume"/>
<text name="auto_unmute_label">
Stummschaltung nach Teleport automatisch aufheben:
</text>
<check_box name="FSAutoUnmuteAmbient" label="Umgebung" tool_tip="Automatisch Stummschaltung für Umgebungsgeräusche nach Teleport aufheben, falls stummgeschaltet (Standard: Aus)"/>
<check_box name="FSAutoUnmuteSounds" label="Klänge" tool_tip="Automatisch Stummschaltung für Klänge nach Teleport aufheben, falls stummgeschaltet (Standard: Aus)"/>
<text name="friends_logon_sounds_label">
Klang abspielen wenn sich Freunde:
</text>

View File

@ -53,6 +53,7 @@ SLURL: &lt;nolink&gt;[SLURL]&lt;/nolink&gt;
<string name="AboutSystem">
CPU: [CPU]
Speicher: [MEMORY_MB] MB
Parallelität: [CONCURRENCY]
Betriebssystemversion: [OS_VERSION]
Grafikkartenhersteller: [GRAPHICS_CARD_VENDOR]
Grafikkarte: [GRAPHICS_CARD]

View File

@ -165,7 +165,7 @@ Additional code generously contributed to Firestorm by:
top_pad="4"
width="450"
wrap="true">
Albatroz Hird, Alexie Birman, Andromeda Rage, Angeldark Raymaker, Animats, Armin Weatherwax, Beq Janus, Casper Warden, Chalice Yao, Chaser Zaks, Chorazin Allen, Cron Stardust, Damian Zhaoying, Dan Threebeards, Dawa Gurbux, Denver Maksim, Drake Arconis, Felyza Wishbringer, f0rbidden, Fractured Crystal, Geenz Spad, Gibson Firehawk, Hitomi Tiponi, Inusaito Sayori, Jean Severine, Katharine Berry, Kittin Ninetails, Kool Koolhoven, Lance Corrimal, Lassie, Latif Khalifa, Laurent Bechir, Magne Metaverse LLC, Magus Freston, Manami Hokkigai, MartinRJ Fayray, McCabe Maxstead, Melancholy Lemon, Melysmile, Mimika Oh, Mister Acacia, MorganMegan, mygoditsfullofstars, Mysty Saunders, Nagi Michinaga, Name Short, nhede Core, NiranV Dean, Nogardrevlis Lectar, Oren Hurvitz, Paladin Forzane, paperwork, Penny Patton, Peyton Menges, programmtest, Qwerty Venom, Revolution Smythe, Romka Swallowtail, Sahkolihaa Contepomi, sal Kaligawa, Samm Florian, Satomi Ahn, Sei Lisa, Sempervirens Oddfellow, Shin Wasp, Shyotl Kuhr, Sione Lomu, Skills Hak, StarlightShining, Sunset Faulkes, Testicular Slingshot, Thickbrick Sleaford, Ubit Umarov, Vaalith Jinn, Vincent Sylvester, Whirly Fizzle, Xenhat Liamano, Zwagoth Klaar and others.
Albatroz Hird, Alexie Birman, Andromeda Rage, Angeldark Raymaker, Animats, Armin Weatherwax, Beq Janus, Casper Warden, Chalice Yao, Chaser Zaks, Chorazin Allen, Cron Stardust, Damian Zhaoying, Dan Threebeards, Dawa Gurbux, Denver Maksim, Drake Arconis, Felyza Wishbringer, f0rbidden, Fractured Crystal, Geenz Spad, Gibson Firehawk, Hitomi Tiponi, Inusaito Sayori, Jean Severine, Katharine Berry, Kittin Ninetails, Kool Koolhoven, Lance Corrimal, Lassie, Latif Khalifa, Laurent Bechir, Magne Metaverse LLC, Magus Freston, Manami Hokkigai, MartinRJ Fayray, McCabe Maxstead, Melancholy Lemon, Melysmile, Mimika Oh, Mister Acacia, MorganMegan, mygoditsfullofstars, Mysty Saunders, Nagi Michinaga, Name Short, nhede Core, NiranV Dean, Nogardrevlis Lectar, Oren Hurvitz, Paladin Forzane, paperwork, Penny Patton, Peyton Menges, programmtest, Qwerty Venom, Rebecca Ashbourne, Revolution Smythe, Romka Swallowtail, Sahkolihaa Contepomi, sal Kaligawa, Samm Florian, Satomi Ahn, Sei Lisa, Sempervirens Oddfellow, Shin Wasp, Shyotl Kuhr, Sione Lomu, Skills Hak, StarlightShining, Sunset Faulkes, Testicular Slingshot, Thickbrick Sleaford, Ubit Umarov, Vaalith Jinn, Vincent Sylvester, Whirly Fizzle, Xenhat Liamano, Zwagoth Klaar and others.
</text>
<text
follows="top|left"

View File

@ -1492,6 +1492,16 @@
label="Model Edge"
tool_tip="Edge color for the model in preview window on the Mesh uploader"
name="mesh_preview_edge_color"/>
<color_swatch
control_name="PreviewAmbientColor"
follows="top|left"
left_pad="24"
height="64"
width="120"
can_apply_immediately="true"
label="Ambient Light"
tool_tip="Ambient light level in preview window (also affects animation preview etc)"
name="preview_ambient_color"/>
<text
type="string"
length="1"

View File

@ -363,6 +363,38 @@
width="110"/>
<text
type="string"
length="1"
follows="top|left"
height="15"
layout="topleft"
left="26"
top_pad="15"
name="auto_unmute_label"
width="430">
Automatically unmute after teleport:
</text>
<check_box
control_name="FSAutoUnmuteAmbient"
name="FSAutoUnmuteAmbient"
label="Ambient"
tool_tip="Automatically unmute Ambient after teleporting, if muted (default: off)"
layout="topleft"
top_pad="5"
left_delta="5"
height="16"
width="85" />
<check_box
control_name="FSAutoUnmuteSounds"
name="FSAutoUnmuteSounds"
label="Sound Effects"
tool_tip="Automatically unmute Sound Effects after teleporting, if muted (default: off)"
layout="topleft"
left_pad="0"
height="18"
width="85" />
<text
type="string"
length="1"
follows="top|left"

View File

@ -51,6 +51,7 @@ You are in [REGION]
<string name="AboutSystem">
CPU: [CPU]
Memory: [MEMORY_MB] MB
Concurrency: [CONCURRENCY]
OS Version: [OS_VERSION]
Graphics Card Vendor: [GRAPHICS_CARD_VENDOR]
Graphics Card: [GRAPHICS_CARD]

View File

@ -213,6 +213,7 @@
</text>
<color_swatch label="Tło" tool_tip="Kolor tła przesyłania modelu" name="mesh_preview_canvas_color" />
<color_swatch label="Krawędź modelu" tool_tip="Kolor krawędzi modelu w oknie podglądu podczas przesyłania meszu" name="mesh_preview_edge_color" />
<color_swatch label="Światła otoczenia" tool_tip="Poziom oświetlenia otoczenia w oknie podglądu (wpływa również na podgląd animacji itp.)" name="preview_ambient_color" />
<text name="physics_settings_label">
Fizyka:
</text>

View File

@ -121,6 +121,7 @@
<slider label="Dodatkowy zapas pamięci podręcznej tekstur (%):" name="FSDynamicTextureMemoryCacheReserve" tool_tip="Procent fizycznej pamięci wideo zarezerwowanej dla tekstur ładowanych do pamięci podręcznej, które obecnie nie są wyświetlane." />
<slider label="Fizyczny zapas pamięci wideo (%):" name="FSDynamicTextureMemoryGPUReserve" tool_tip="Procent fizycznej pamięci wideo zarezerwowanej do innego użytku." />
<spinner label="Stosunek odległości dla mgły:" name="fog"/>
<spinner label="Wątki dekodowania obrazów:" name="image_decode_threads" tool_tip="Liczba wątków używanych do dekodowania obrazów. 0 = Auto, 1 = Synchroniczne, 2+ = określone przez użytkownika. Zalecane 0 lub 1." />
</panel>
<panel name="Rendering">
<text name="World Updating">

View File

@ -42,6 +42,7 @@ Położenie: [REGION]
<string name="AboutSystem">
Procesor (CPU): [CPU]
Pamięć (Memory): [MEMORY_MB] MB
Wątki dekodowania (Concurrency): [CONCURRENCY]
System operacyjny (OS Version): [OS_VERSION]
Dostawca karty graficznej (Graphics Card Vendor): [GRAPHICS_CARD_VENDOR]
Karta graficzna (Graphics Card): [GRAPHICS_CARD]