Merge some changes from develop-linux

typo >w>
meow-7.2.2
livie 2025-12-21 08:02:08 +02:00
parent 9564195712
commit 2dc91356dc
18 changed files with 96 additions and 119 deletions

View File

@ -262,6 +262,8 @@ void LLMD5::raw_digest(unsigned char* s) const
void LLMD5::hex_digest(char* s) const
{
if (!s) return;
if (!finalized)
{
std::cerr << "LLMD5::hex_digest: Can't get digest if you haven't "

View File

@ -58,9 +58,27 @@
* to restore uniform distribution.
*/
// gRandomGenerator is a stateful static object, which is therefore not
// pRandomGenerator is a stateful static object, which is therefore not
// inherently thread-safe.
static thread_local LLRandLagFib2281 gRandomGenerator(LLUUID::getRandomSeed());
// We use a pointer to not construct a huge object in the TLS space, sadly this is necessary
// due to libcef.so on Linux being compiled with TLS model initial-exec (resulting in
// FLAG STATIC_TLS, see readelf libcef.so). CEFs own TLS objects + LLRandLagFib2281 then will exhaust the
// available TLS space, causing media failure.
//static thread_local LLRandLagFib2281 gRandomGenerator(LLUUID::getRandomSeed());
static thread_local std::unique_ptr<LLRandLagFib2281> pRandomGenerator = nullptr;
namespace
{
F64 ll_internal_get_rand()
{
if (!pRandomGenerator)
{
pRandomGenerator.reset(new LLRandLagFib2281(LLUUID::getRandomSeed()));
}
return(*pRandomGenerator)();
}
}
// no default implementation, only specific F64 and F32 specializations
template <typename REAL>
@ -73,7 +91,7 @@ inline F64 ll_internal_random<F64>()
// CPUs (or at least multi-threaded processes) seem to
// occasionally give an obviously incorrect random number -- like
// 5^15 or something. Sooooo, clamp it as described above.
F64 rv{ gRandomGenerator() };
F64 rv{ ll_internal_get_rand() };
if(!((rv >= 0.0) && (rv < 1.0))) return fmod(rv, 1.0);
return rv;
}
@ -85,7 +103,7 @@ inline F32 ll_internal_random<F32>()
// Per Monty, it's important to clamp using the correct fmodf() rather
// than expanding to F64 for fmod() and then truncating back to F32. Prior
// to this change, we were getting sporadic ll_frand() == 1.0 results.
F32 rv{ narrow<F64>(gRandomGenerator()) };
F32 rv{ narrow<F64>(ll_internal_get_rand()) };
if(!((rv >= 0.0f) && (rv < 1.0f))) return fmodf(rv, 1.0f);
return rv;
}

View File

@ -841,57 +841,8 @@ void LLMemoryInfo::getAvailableMemoryKB(U32Kilobytes& avail_mem_kb)
}
#elif LL_LINUX
// mStatsMap is derived from MEMINFO_FILE:
// $ cat /proc/meminfo
// MemTotal: 4108424 kB
// MemFree: 1244064 kB
// Buffers: 85164 kB
// Cached: 1990264 kB
// SwapCached: 0 kB
// Active: 1176648 kB
// Inactive: 1427532 kB
// Active(anon): 529152 kB
// Inactive(anon): 15924 kB
// Active(file): 647496 kB
// Inactive(file): 1411608 kB
// Unevictable: 16 kB
// Mlocked: 16 kB
// HighTotal: 3266316 kB
// HighFree: 721308 kB
// LowTotal: 842108 kB
// LowFree: 522756 kB
// SwapTotal: 6384632 kB
// SwapFree: 6384632 kB
// Dirty: 28 kB
// Writeback: 0 kB
// AnonPages: 528820 kB
// Mapped: 89472 kB
// Shmem: 16324 kB
// Slab: 159624 kB
// SReclaimable: 145168 kB
// SUnreclaim: 14456 kB
// KernelStack: 2560 kB
// PageTables: 5560 kB
// NFS_Unstable: 0 kB
// Bounce: 0 kB
// WritebackTmp: 0 kB
// CommitLimit: 8438844 kB
// Committed_AS: 1271596 kB
// VmallocTotal: 122880 kB
// VmallocUsed: 65252 kB
// VmallocChunk: 52356 kB
// HardwareCorrupted: 0 kB
// HugePages_Total: 0
// HugePages_Free: 0
// HugePages_Rsvd: 0
// HugePages_Surp: 0
// Hugepagesize: 2048 kB
// DirectMap4k: 434168 kB
// DirectMap2M: 477184 kB
// (could also run 'free', but easier to read a file than run a program)
LLSD statsMap(loadStatsMap());
avail_mem_kb = (U32Kilobytes)statsMap["MemFree"].asInteger();
U64 phys = U64(getpagesize()) * U64(get_avphys_pages());
avail_mem_kb = U64Bytes(phys);
#else
//do not know how to collect available memory info for other systems.
//leave it blank here for now.

View File

@ -120,6 +120,9 @@ void LLTemplateMessageReader::getData(const char *blockname, const char *varname
{
switch( vardata_size )
{
case 0:
// This is here to prevent a memcpy from a null value, which is undefined behaviour.
break;
case 1:
*((U8*)datap) = *((U8*)vardata.getData());
break;

View File

@ -72,15 +72,6 @@ bool LLRender::sNsightDebugSupport = false;
LLVector2 LLRender::sUIGLScaleFactor = LLVector2(1.f, 1.f);
bool LLRender::sClassicMode = false;
struct LLVBCache
{
LLPointer<LLVertexBuffer> vb;
std::chrono::steady_clock::time_point touched;
};
static std::unordered_map<U64, LLVBCache> sVBCache;
static thread_local std::list<LLVertexBufferData> *sBufferDataList = nullptr;
static const GLenum sGLTextureType[] =
{
GL_TEXTURE_2D,
@ -921,7 +912,9 @@ void LLRender::initVertexBuffer()
void LLRender::resetVertexBuffer()
{
mBuffer = NULL;
mBuffer = nullptr;
mBufferDataList = nullptr;
mVBCache.clear();
}
void LLRender::shutdown()
@ -1118,7 +1111,7 @@ void LLRender::syncMatrices()
S32 loc = shader->getUniformLocation(LLShaderMgr::MODELVIEW_PROJECTION_MATRIX);
if (loc > -1)
{
if (cached_mvp_mdv_hash != mMatHash[MM_PROJECTION] || cached_mvp_proj_hash != mMatHash[MM_PROJECTION])
if (cached_mvp_mdv_hash != mMatHash[MM_MODELVIEW] || cached_mvp_proj_hash != mMatHash[MM_PROJECTION])
{
U32 mdv = MM_MODELVIEW;
cached_mvp = mat;
@ -1547,21 +1540,21 @@ void LLRender::clearErrors()
void LLRender::beginList(std::list<LLVertexBufferData> *list)
{
if (sBufferDataList)
if (mBufferDataList)
{
LL_ERRS() << "beginList called while another list is open." << LL_ENDL;
}
llassert(LLGLSLShader::sCurBoundShaderPtr == &gUIProgram);
flush();
sBufferDataList = list;
mBufferDataList = list;
}
void LLRender::endList()
{
if (sBufferDataList)
if (mBufferDataList)
{
flush();
sBufferDataList = nullptr;
mBufferDataList = nullptr;
}
else
{
@ -1649,10 +1642,10 @@ void LLRender::flush()
U32 attribute_mask = LLGLSLShader::sCurBoundShaderPtr->mAttributeMask;
if (sBufferDataList)
if (mBufferDataList)
{
vb = genBuffer(attribute_mask, count);
sBufferDataList->emplace_back(
mBufferDataList->emplace_back(
vb,
mMode,
count,
@ -1712,9 +1705,9 @@ LLVertexBuffer* LLRender::bufferfromCache(U32 attribute_mask, U32 count)
// To leverage this, we maintain a running hash of the vertex stream being
// built up before a flush, and then check that hash against a VB
// cache just before creating a vertex buffer in VRAM
std::unordered_map<U64, LLVBCache>::iterator cache = sVBCache.find(vhash);
std::unordered_map<U64, LLVBCache>::iterator cache = mVBCache.find(vhash);
if (cache != sVBCache.end())
if (cache != mVBCache.end())
{
LL_PROFILE_ZONE_NAMED_CATEGORY_VERTEX("vb cache hit");
// cache hit, just use the cached buffer
@ -1726,7 +1719,7 @@ LLVertexBuffer* LLRender::bufferfromCache(U32 attribute_mask, U32 count)
LL_PROFILE_ZONE_NAMED_CATEGORY_VERTEX("vb cache miss");
vb = genBuffer(attribute_mask, count);
sVBCache[vhash] = { vb , std::chrono::steady_clock::now() };
mVBCache[vhash] = { vb , std::chrono::steady_clock::now() };
static U32 miss_count = 0;
miss_count++;
@ -1738,11 +1731,11 @@ LLVertexBuffer* LLRender::bufferfromCache(U32 attribute_mask, U32 count)
using namespace std::chrono_literals;
// every 1024 misses, clean the cache of any VBs that haven't been touched in the last second
for (std::unordered_map<U64, LLVBCache>::iterator iter = sVBCache.begin(); iter != sVBCache.end(); )
for (std::unordered_map<U64, LLVBCache>::iterator iter = mVBCache.begin(); iter != mVBCache.end(); )
{
if (now - iter->second.touched > 1s)
{
iter = sVBCache.erase(iter);
iter = mVBCache.erase(iter);
}
else
{

View File

@ -46,7 +46,9 @@
#include <boost/align/aligned_allocator.hpp>
#include <array>
#include <chrono>
#include <list>
#include <vector>
class LLVertexBuffer;
class LLCubeMap;
@ -536,6 +538,15 @@ private:
std::vector<LLVector4a, boost::alignment::aligned_allocator<LLVector4a, 16> > mUIOffset;
std::vector<LLVector4a, boost::alignment::aligned_allocator<LLVector4a, 16> > mUIScale;
struct LLVBCache
{
LLPointer<LLVertexBuffer> vb;
std::chrono::steady_clock::time_point touched;
};
std::unordered_map<U64, LLVBCache> mVBCache;
std::list<LLVertexBufferData>* mBufferDataList = nullptr;
};
extern F32 gGLModelView[16];

View File

@ -1054,7 +1054,7 @@ void LLShaderMgr::clearShaderCache()
LL_INFOS("ShaderMgr") << "Removing shader cache at " << shader_cache << LL_ENDL;
const std::string mask = "*";
gDirUtilp->deleteFilesInDir(shader_cache, mask);
LLFile::rmdir(shader_cache);
//LLFile::rmdir(shader_cache);
mShaderBinaryCache.clear();
}

View File

@ -12,7 +12,7 @@ function install_desktop_entry()
local desktop_entry="\
[Desktop Entry]\n\
Name=Firestorm Viewer\n\
Name=Firestorm Viewer - Compiled\n\
Comment=Client for accessing 3D virtual worlds\n\
Exec=${installation_prefix}/firestorm\n\
Icon=${installation_prefix}/firestorm_icon.png\n\

View File

@ -15,6 +15,9 @@ exportMutliArchDRIPath() {
fi
}
## GL Driver Options
export mesa_glthread=true
## Here are some configuration options for Linux Client Testers.
## These options are for self-assisted troubleshooting during this beta

View File

@ -151,7 +151,6 @@ void LLVolumeImplFlexible::remapSections(LLFlexibleObjectSection *source, S32 so
{
S32 num_output_sections = 1<<dest_sections;
LLVector3 scale = mVO->mDrawable->getScale();
F32 source_section_length = scale.mV[VZ] / (F32)(1<<source_sections);
F32 section_length = scale.mV[VZ] / (F32)num_output_sections;
if (source_sections == -1)
{
@ -183,6 +182,7 @@ void LLVolumeImplFlexible::remapSections(LLFlexibleObjectSection *source, S32 so
// Iterate from right to left since it may be an in-place computation
S32 step_shift = dest_sections-source_sections;
S32 num_steps = 1<<step_shift;
F32 source_section_length = scale.mV[VZ] / (F32)(1<<source_sections);
for (S32 section=num_output_sections-num_steps; section>=0; section -= num_steps)
{
LLFlexibleObjectSection *last_source_section = &source[section>>step_shift];

View File

@ -45,7 +45,6 @@ LLFloaterNotificationsTabbed::LLFloaterNotificationsTabbed(const LLSD& key) : LL
mGroupNoticeMessageList(NULL),
mTransactionMessageList(NULL),
mSystemMessageList(NULL),
mNotificationsSeparator(NULL),
mNotificationsTabContainer(NULL),
mNotificationsToGo(), // <FS:Beq/> FIRE-35130 bugsplat in notification::idle updates.
NOTIFICATION_TABBED_ANCHOR_NAME("notification_well_panel"),
@ -55,7 +54,7 @@ LLFloaterNotificationsTabbed::LLFloaterNotificationsTabbed(const LLSD& key) : LL
{
setOverlapsScreenChannel(true);
mNotificationUpdates.reset(new NotificationTabbedChannel(this));
mNotificationsSeparator = new LLNotificationSeparator();
mNotificationsSeparator = std::make_unique<LLNotificationSeparator>();
}
//---------------------------------------------------------------------------------
@ -120,6 +119,7 @@ void LLFloaterNotificationsTabbed::setSysWellChiclet(LLSysWellChiclet* chiclet)
//---------------------------------------------------------------------------------
LLFloaterNotificationsTabbed::~LLFloaterNotificationsTabbed()
{
mNotificationsSeparator.reset();
// <FS:Ansariel> Remember last tab used
gSavedPerAccountSettings.setS32("FSLastNotificationsTab", mNotificationsTabContainer->getCurrentPanelIndex());
}

View File

@ -164,7 +164,7 @@ private:
LLNotificationListView* mGroupNoticeMessageList;
LLNotificationListView* mTransactionMessageList;
LLNotificationListView* mSystemMessageList;
LLNotificationSeparator* mNotificationsSeparator;
std::unique_ptr<LLNotificationSeparator> mNotificationsSeparator;
LLTabContainer* mNotificationsTabContainer;
LLButton* mDeleteAllBtn;
LLButton* mCollapseAllBtn;

View File

@ -451,17 +451,14 @@ LLMarketplaceInventoryImporter::LLMarketplaceInventoryImporter()
, mImportInProgress(false)
, mInitialized(false)
, mMarketPlaceStatus(MarketplaceStatusCodes::MARKET_PLACE_NOT_INITIALIZED)
, mErrorInitSignal(NULL)
, mStatusChangedSignal(NULL)
, mStatusReportSignal(NULL)
{
}
boost::signals2::connection LLMarketplaceInventoryImporter::setInitializationErrorCallback(const status_report_signal_t::slot_type& cb)
{
if (mErrorInitSignal == NULL)
if (mErrorInitSignal == nullptr)
{
mErrorInitSignal = new status_report_signal_t();
mErrorInitSignal = std::make_unique<status_report_signal_t>();
}
return mErrorInitSignal->connect(cb);
@ -469,9 +466,9 @@ boost::signals2::connection LLMarketplaceInventoryImporter::setInitializationErr
boost::signals2::connection LLMarketplaceInventoryImporter::setStatusChangedCallback(const status_changed_signal_t::slot_type& cb)
{
if (mStatusChangedSignal == NULL)
if (mStatusChangedSignal == nullptr)
{
mStatusChangedSignal = new status_changed_signal_t();
mStatusChangedSignal = std::make_unique<status_changed_signal_t>();
}
return mStatusChangedSignal->connect(cb);
@ -479,9 +476,9 @@ boost::signals2::connection LLMarketplaceInventoryImporter::setStatusChangedCall
boost::signals2::connection LLMarketplaceInventoryImporter::setStatusReportCallback(const status_report_signal_t::slot_type& cb)
{
if (mStatusReportSignal == NULL)
if (mStatusReportSignal == nullptr)
{
mStatusReportSignal = new status_report_signal_t();
mStatusReportSignal = std::make_unique<status_report_signal_t>();
}
return mStatusReportSignal->connect(cb);
@ -718,8 +715,6 @@ LLMarketplaceTuple::LLMarketplaceTuple(const LLUUID& folder_id, S32 listing_id,
LLMarketplaceData::LLMarketplaceData() :
mMarketPlaceStatus(MarketplaceStatusCodes::MARKET_PLACE_NOT_INITIALIZED),
mMarketPlaceDataFetched(MarketplaceFetchCodes::MARKET_FETCH_NOT_DONE),
mStatusUpdatedSignal(NULL),
mDataFetchedSignal(NULL),
mDirtyCount(false)
{
mInventoryObserver = new LLMarketplaceInventoryObserver;
@ -753,9 +748,9 @@ LLSD LLMarketplaceData::getMarketplaceStringSubstitutions()
void LLMarketplaceData::initializeSLM(const status_updated_signal_t::slot_type& cb)
{
if (mStatusUpdatedSignal == NULL)
if (mStatusUpdatedSignal == nullptr)
{
mStatusUpdatedSignal = new status_updated_signal_t();
mStatusUpdatedSignal = std::make_unique<status_updated_signal_t>();
}
mStatusUpdatedSignal->connect(cb);
@ -841,9 +836,9 @@ void LLMarketplaceData::getMerchantStatusCoro()
void LLMarketplaceData::setDataFetchedSignal(const status_updated_signal_t::slot_type& cb)
{
if (mDataFetchedSignal == NULL)
if (mDataFetchedSignal == nullptr)
{
mDataFetchedSignal = new status_updated_signal_t();
mDataFetchedSignal = std::make_unique<status_updated_signal_t>();
}
mDataFetchedSignal->connect(cb);
}

View File

@ -113,9 +113,9 @@ private:
bool mInitialized;
U32 mMarketPlaceStatus;
status_report_signal_t * mErrorInitSignal;
status_changed_signal_t * mStatusChangedSignal;
status_report_signal_t * mStatusReportSignal;
std::unique_ptr<status_report_signal_t> mErrorInitSignal;
std::unique_ptr<status_changed_signal_t> mStatusChangedSignal;
std::unique_ptr<status_report_signal_t> mStatusReportSignal;
};
@ -276,13 +276,13 @@ private:
// Handling Marketplace connection and inventory connection
U32 mMarketPlaceStatus;
std::string mMarketPlaceFailureReason;
status_updated_signal_t* mStatusUpdatedSignal;
std::unique_ptr<status_updated_signal_t> mStatusUpdatedSignal;
LLInventoryObserver* mInventoryObserver;
bool mDirtyCount; // If true, stock count value need to be updated at the next check
// Update data
U32 mMarketPlaceDataFetched;
status_updated_signal_t* mDataFetchedSignal;
std::unique_ptr<status_updated_signal_t> mDataFetchedSignal;
std::set<LLUUID> mPendingUpdateSet;
// Listing folders waiting for validation

View File

@ -234,7 +234,7 @@ boost::signals2::connection LLMaterialMgr::get(const LLUUID& region_id, const LL
get_callback_map_t::iterator itCallback = mGetCallbacks.find(material_id);
if (itCallback == mGetCallbacks.end())
{
std::pair<get_callback_map_t::iterator, bool> ret = mGetCallbacks.insert(std::pair<LLMaterialID, get_callback_t*>(material_id, new get_callback_t()));
std::pair<get_callback_map_t::iterator, bool> ret = mGetCallbacks.emplace(material_id, std::make_unique<get_callback_t>());
itCallback = ret.first;
}
connection = itCallback->second->connect(cb);;
@ -279,7 +279,7 @@ boost::signals2::connection LLMaterialMgr::getTE(const LLUUID& region_id, const
get_callback_te_map_t::iterator itCallback = mGetTECallbacks.find(te_mat_pair);
if (itCallback == mGetTECallbacks.end())
{
std::pair<get_callback_te_map_t::iterator, bool> ret = mGetTECallbacks.insert(std::pair<TEMaterialPair, get_callback_te_t*>(te_mat_pair, new get_callback_te_t()));
std::pair<get_callback_te_map_t::iterator, bool> ret = mGetTECallbacks.emplace(te_mat_pair, std::make_unique<get_callback_te_t>());
itCallback = ret.first;
}
connection = itCallback->second->connect(cb);
@ -317,7 +317,7 @@ boost::signals2::connection LLMaterialMgr::getAll(const LLUUID& region_id, LLMat
getall_callback_map_t::iterator itCallback = mGetAllCallbacks.find(region_id);
if (mGetAllCallbacks.end() == itCallback)
{
std::pair<getall_callback_map_t::iterator, bool> ret = mGetAllCallbacks.insert(std::pair<LLUUID, getall_callback_t*>(region_id, new getall_callback_t()));
std::pair<getall_callback_map_t::iterator, bool> ret = mGetAllCallbacks.emplace(region_id, std::make_unique<getall_callback_t>());
itCallback = ret.first;
}
return itCallback->second->connect(cb);;
@ -329,8 +329,8 @@ void LLMaterialMgr::put(const LLUUID& object_id, const U8 te, const LLMaterial&
if (mPutQueue.end() == itQueue)
{
LL_DEBUGS("Materials") << "mPutQueue insert object " << object_id << LL_ENDL;
mPutQueue.insert(std::pair<LLUUID, facematerial_map_t>(object_id, facematerial_map_t()));
itQueue = mPutQueue.find(object_id);
auto ret = mPutQueue.emplace(object_id, facematerial_map_t());
itQueue = ret.first;
}
facematerial_map_t::iterator itFace = itQueue->second.find(te);
@ -361,7 +361,7 @@ void LLMaterialMgr::setLocalMaterial(const LLUUID& region_id, LLMaterialPtr mate
}
LL_DEBUGS("Materials") << "region " << region_id << "new local material id " << material_id << LL_ENDL;
mMaterials.insert(std::pair<LLMaterialID, LLMaterialPtr>(material_id, material_ptr));
mMaterials.emplace(material_id, material_ptr);
setMaterialCallbacks(material_id, material_ptr);
@ -376,7 +376,7 @@ const LLMaterialPtr LLMaterialMgr::setMaterial(const LLUUID& region_id, const LL
{
LL_DEBUGS("Materials") << "new material" << LL_ENDL;
LLMaterialPtr newMaterial(new LLMaterial(material_data));
std::pair<material_map_t::const_iterator, bool> ret = mMaterials.insert(std::pair<LLMaterialID, LLMaterialPtr>(material_id, newMaterial));
std::pair<material_map_t::const_iterator, bool> ret = mMaterials.emplace(material_id, newMaterial);
itMaterial = ret.first;
}
@ -400,7 +400,6 @@ void LLMaterialMgr::setMaterialCallbacks(const LLMaterialID& material_id, const
if (itCallbackTE != mGetTECallbacks.end())
{
(*itCallbackTE->second)(material_id, material_ptr, te_mat_pair.te);
delete itCallbackTE->second;
mGetTECallbacks.erase(itCallbackTE);
}
}
@ -410,7 +409,6 @@ void LLMaterialMgr::setMaterialCallbacks(const LLMaterialID& material_id, const
{
(*itCallback->second)(material_id, material_ptr);
delete itCallback->second;
mGetCallbacks.erase(itCallback);
}
}
@ -509,7 +507,6 @@ void LLMaterialMgr::onGetAllResponse(bool success, const LLSD& content, const LL
{
(*itCallback->second)(region_id, materials);
delete itCallback->second;
mGetAllCallbacks.erase(itCallback);
}

View File

@ -110,13 +110,13 @@ private:
typedef std::map<LLUUID, material_queue_t> get_queue_t;
typedef std::pair<const LLUUID, LLMaterialID> pending_material_t;
typedef std::map<const pending_material_t, F64> get_pending_map_t;
typedef std::map<LLMaterialID, get_callback_t*> get_callback_map_t;
typedef std::map<LLMaterialID, std::unique_ptr<get_callback_t>> get_callback_map_t;
typedef boost::unordered_map<TEMaterialPair, get_callback_te_t*> get_callback_te_map_t;
typedef boost::unordered_map<TEMaterialPair, std::unique_ptr<get_callback_te_t>> get_callback_te_map_t;
typedef std::set<LLUUID> getall_queue_t;
typedef std::map<LLUUID, F64> getall_pending_map_t;
typedef std::map<LLUUID, getall_callback_t*> getall_callback_map_t;
typedef std::map<LLUUID, std::unique_ptr<getall_callback_t>> getall_callback_map_t;
typedef std::map<U8, LLMaterial> facematerial_map_t;
typedef std::map<LLUUID, facematerial_map_t> put_queue_t;

View File

@ -4742,7 +4742,7 @@ bool LLModelPreview::render()
LLPhysicsDecomp* decomp = gMeshRepo.mDecompThread;
if (decomp)
{
LLMutexLock(decomp->mMutex);
LLMutexLock decomp_lock(decomp->mMutex);
LLModel::Decomposition& physics = model->mPhysics;
@ -4872,7 +4872,7 @@ bool LLModelPreview::render()
LLPhysicsDecomp* decomp = gMeshRepo.mDecompThread;
if (decomp)
{
LLMutexLock(decomp->mMutex);
LLMutexLock decomp_lock(decomp->mMutex);
LLModel::Decomposition& physics = model->mPhysics;

View File

@ -587,6 +587,7 @@ void LLViewerShaderMgr::setShaders()
unloadShaders();
LLPipeline::sRenderGlow = gSavedSettings.getBOOL("RenderGlow");
LLPipeline::sRenderTransparentWater = gSavedSettings.getBOOL("RenderTransparentWater");
if (gViewerWindow)
{
@ -1006,7 +1007,10 @@ bool LLViewerShaderMgr::loadShadersWater()
return loadShadersWater();
}
LLWorld::getInstance()->updateWaterObjects();
if (LLWorld::instanceExists())
{
LLWorld::getInstance()->updateWaterObjects();
}
return true;
}