Merge branch 'DRTVWR-544-maint' of https://bitbucket.org/lindenlab/viewer
# Conflicts: # indra/cmake/Copy3rdPartyLibs.cmake # indra/cmake/FMODSTUDIO.cmake # indra/newview/llappviewer.cpp # indra/newview/llviewerregion.cpp # indra/newview/viewer_manifest.pymaster
commit
63238d1fbe
|
|
@ -175,6 +175,16 @@ bool LLAudioEngine_FMODSTUDIO::init(const S32 num_channels, void* userdata, cons
|
|||
<< " expected:" << FMOD_VERSION << LL_ENDL;
|
||||
}
|
||||
|
||||
// <FS:Ansariel> Don't need that...
|
||||
//Check_FMOD_Error(result, "FMOD::System::getVersion");
|
||||
//std::string logfile = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "fmod.log");
|
||||
//result = FMOD::Debug_Initialize(FMOD_DEBUG_LEVEL_LOG, FMOD_DEBUG_MODE_FILE, 0, logfile.c_str());
|
||||
//if (Check_FMOD_Error(result, "FMOD::System_Create"))
|
||||
//{
|
||||
// LL_WARNS() << "Failed to init logging" << LL_ENDL;
|
||||
//}
|
||||
// </FS:Ansariel>
|
||||
|
||||
// In this case, all sounds, PLUS wind and stream will be software.
|
||||
result = mSystem->setSoftwareChannels(num_channels + EXTRA_SOUND_CHANNELS);
|
||||
Check_FMOD_Error(result, "FMOD::System::setSoftwareChannels");
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@
|
|||
// STL headers
|
||||
// std headers
|
||||
#include <atomic>
|
||||
#include <stdexcept>
|
||||
// external library headers
|
||||
#include <boost/bind.hpp>
|
||||
#include <boost/fiber/fiber.hpp>
|
||||
|
|
@ -213,6 +214,22 @@ std::string LLCoros::logname()
|
|||
return data.mName.empty()? data.getKey() : data.mName;
|
||||
}
|
||||
|
||||
void LLCoros::saveException(const std::string& name, std::exception_ptr exc)
|
||||
{
|
||||
mExceptionQueue.emplace(name, exc);
|
||||
}
|
||||
|
||||
void LLCoros::rethrow()
|
||||
{
|
||||
if (! mExceptionQueue.empty())
|
||||
{
|
||||
ExceptionData front = mExceptionQueue.front();
|
||||
mExceptionQueue.pop();
|
||||
LL_WARNS("LLCoros") << "Rethrowing exception from coroutine " << front.name << LL_ENDL;
|
||||
std::rethrow_exception(front.exception);
|
||||
}
|
||||
}
|
||||
|
||||
void LLCoros::setStackSize(S32 stacksize)
|
||||
{
|
||||
LL_DEBUGS("LLCoros") << "Setting coroutine stack size to " << stacksize << LL_ENDL;
|
||||
|
|
@ -290,11 +307,11 @@ U32 cpp_exception_filter(U32 code, struct _EXCEPTION_POINTERS *exception_infop,
|
|||
}
|
||||
}
|
||||
|
||||
void LLCoros::winlevel(const std::string& name, const callable_t& callable)
|
||||
void LLCoros::sehHandle(const std::string& name, const LLCoros::callable_t& callable)
|
||||
{
|
||||
__try
|
||||
{
|
||||
toplevelTryWrapper(name, callable);
|
||||
LLCoros::toplevelTryWrapper(name, callable);
|
||||
}
|
||||
__except (cpp_exception_filter(GetExceptionCode(), GetExceptionInformation(), name))
|
||||
{
|
||||
|
|
@ -309,7 +326,6 @@ void LLCoros::winlevel(const std::string& name, const callable_t& callable)
|
|||
throw std::exception(integer_string);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void LLCoros::toplevelTryWrapper(const std::string& name, const callable_t& callable)
|
||||
|
|
@ -338,11 +354,19 @@ void LLCoros::toplevelTryWrapper(const std::string& name, const callable_t& call
|
|||
}
|
||||
catch (...)
|
||||
{
|
||||
#if LL_WINDOWS
|
||||
// Any OTHER kind of uncaught exception will cause the viewer to
|
||||
// crash, hopefully informatively.
|
||||
// crash, SEH handling should catch it and report to bugsplat.
|
||||
LOG_UNHANDLED_EXCEPTION(STRINGIZE("coroutine " << name));
|
||||
// to not modify callstack
|
||||
throw;
|
||||
#else
|
||||
// Stash any OTHER kind of uncaught exception in the rethrow() queue
|
||||
// to be rethrown by the main fiber.
|
||||
LL_WARNS("LLCoros") << "Capturing uncaught exception in coroutine "
|
||||
<< name << LL_ENDL;
|
||||
LLCoros::instance().saveException(name, std::current_exception());
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -352,8 +376,9 @@ void LLCoros::toplevelTryWrapper(const std::string& name, const callable_t& call
|
|||
void LLCoros::toplevel(std::string name, callable_t callable)
|
||||
{
|
||||
#if LL_WINDOWS
|
||||
// Can not use __try in functions that require unwinding, so use one more wrapper
|
||||
winlevel(name, callable);
|
||||
// Because SEH can's have unwinding, need to call a wrapper
|
||||
// 'try' is inside SEH handling to not catch LLContinue
|
||||
sehHandle(name, callable);
|
||||
#else
|
||||
toplevelTryWrapper(name, callable);
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -38,6 +38,8 @@
|
|||
#include "llinstancetracker.h"
|
||||
#include <boost/function.hpp>
|
||||
#include <string>
|
||||
#include <exception>
|
||||
#include <queue>
|
||||
|
||||
// e.g. #include LLCOROS_MUTEX_HEADER
|
||||
#define LLCOROS_MUTEX_HEADER <boost/fiber/mutex.hpp>
|
||||
|
|
@ -156,6 +158,19 @@ public:
|
|||
* LLCoros::launch()).
|
||||
*/
|
||||
static std::string getName();
|
||||
|
||||
/**
|
||||
* rethrow() is called by the thread's main fiber to propagate an
|
||||
* exception from any coroutine into the main fiber, where it can engage
|
||||
* the normal unhandled-exception machinery, up to and including crash
|
||||
* reporting.
|
||||
*
|
||||
* LLCoros maintains a queue of otherwise-uncaught exceptions from
|
||||
* terminated coroutines. Each call to rethrow() pops the first of those
|
||||
* and rethrows it. When the queue is empty (normal case), rethrow() is a
|
||||
* no-op.
|
||||
*/
|
||||
void rethrow();
|
||||
|
||||
/**
|
||||
* This variation returns a name suitable for log messages: the explicit
|
||||
|
|
@ -292,13 +307,27 @@ public:
|
|||
|
||||
private:
|
||||
std::string generateDistinctName(const std::string& prefix) const;
|
||||
#if LL_WINDOWS
|
||||
void winlevel(const std::string& name, const callable_t& callable);
|
||||
#endif
|
||||
void toplevelTryWrapper(const std::string& name, const callable_t& callable);
|
||||
void toplevel(std::string name, callable_t callable);
|
||||
#if LL_WINDOWS
|
||||
void sehHandle(const std::string& name, const callable_t& callable); // calls toplevelTryWrapper
|
||||
#endif
|
||||
void toplevel(std::string name, callable_t callable); // calls sehHandle or toplevelTryWrapper
|
||||
struct CoroData;
|
||||
static CoroData& get_CoroData(const std::string& caller);
|
||||
void saveException(const std::string& name, std::exception_ptr exc);
|
||||
|
||||
struct ExceptionData
|
||||
{
|
||||
ExceptionData(const std::string& nm, std::exception_ptr exc):
|
||||
name(nm),
|
||||
exception(exc)
|
||||
{}
|
||||
// name of coroutine that originally threw this exception
|
||||
std::string name;
|
||||
// the thrown exception
|
||||
std::exception_ptr exception;
|
||||
};
|
||||
std::queue<ExceptionData> mExceptionQueue;
|
||||
|
||||
S32 mStackSize;
|
||||
|
||||
|
|
|
|||
|
|
@ -846,7 +846,7 @@ LLSD LLModel::writeModel(
|
|||
{
|
||||
LLVector3 pos(face.mPositions[j].getF32ptr());
|
||||
|
||||
weight_list& weights = high->getJointInfluences(pos);
|
||||
weight_list& weights = model[idx]->getJointInfluences(pos);
|
||||
|
||||
S32 count = 0;
|
||||
for (weight_list::iterator iter = weights.begin(); iter != weights.end(); ++iter)
|
||||
|
|
@ -1538,6 +1538,25 @@ LLSD LLMeshSkinInfo::asLLSD(bool include_joints, bool lock_scale_if_joint_positi
|
|||
return ret;
|
||||
}
|
||||
|
||||
U32 LLMeshSkinInfo::sizeBytes() const
|
||||
{
|
||||
U32 res = sizeof(LLUUID); // mMeshID
|
||||
|
||||
res += sizeof(std::vector<std::string>) + sizeof(std::string) * mJointNames.size();
|
||||
for (U32 i = 0; i < mJointNames.size(); ++i)
|
||||
{
|
||||
res += mJointNames[i].size(); // actual size, not capacity
|
||||
}
|
||||
|
||||
res += sizeof(std::vector<S32>) + sizeof(S32) * mJointNums.size();
|
||||
res += sizeof(std::vector<LLMatrix4>) + 16 * sizeof(float) * mInvBindMatrix.size();
|
||||
res += sizeof(std::vector<LLMatrix4>) + 16 * sizeof(float) * mAlternateBindMatrix.size();
|
||||
res += 16 * sizeof(float); //mBindShapeMatrix
|
||||
res += sizeof(float) + 3 * sizeof(bool);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
LLModel::Decomposition::Decomposition(LLSD& data)
|
||||
{
|
||||
fromLLSD(data);
|
||||
|
|
@ -1644,6 +1663,30 @@ void LLModel::Decomposition::fromLLSD(LLSD& decomp)
|
|||
}
|
||||
}
|
||||
|
||||
U32 LLModel::Decomposition::sizeBytes() const
|
||||
{
|
||||
U32 res = sizeof(LLUUID); // mMeshID
|
||||
|
||||
res += sizeof(LLModel::convex_hull_decomposition) + sizeof(std::vector<LLVector3>) * mHull.size();
|
||||
for (U32 i = 0; i < mHull.size(); ++i)
|
||||
{
|
||||
res += mHull[i].size() * sizeof(LLVector3);
|
||||
}
|
||||
|
||||
res += sizeof(LLModel::hull) + sizeof(LLVector3) * mBaseHull.size();
|
||||
|
||||
res += sizeof(std::vector<LLModel::PhysicsMesh>) + sizeof(std::vector<LLModel::PhysicsMesh>) * mMesh.size();
|
||||
for (U32 i = 0; i < mMesh.size(); ++i)
|
||||
{
|
||||
res += mMesh[i].sizeBytes();
|
||||
}
|
||||
|
||||
res += sizeof(std::vector<LLModel::PhysicsMesh>) * 2;
|
||||
res += mBaseHullMesh.sizeBytes() + mPhysicsShapeMesh.sizeBytes();
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
bool LLModel::Decomposition::hasHullList() const
|
||||
{
|
||||
return !mHull.empty() ;
|
||||
|
|
|
|||
|
|
@ -47,6 +47,7 @@ public:
|
|||
LLMeshSkinInfo(LLSD& data);
|
||||
void fromLLSD(LLSD& data);
|
||||
LLSD asLLSD(bool include_joints, bool lock_scale_if_joint_position) const;
|
||||
U32 sizeBytes() const;
|
||||
|
||||
LLUUID mMeshID;
|
||||
//<FS:ND> Query by JointKey rather than just a string, the key can be a U32 index for faster lookup
|
||||
|
|
@ -108,6 +109,14 @@ public:
|
|||
{
|
||||
return mPositions.empty();
|
||||
}
|
||||
|
||||
U32 sizeBytes() const
|
||||
{
|
||||
U32 res = sizeof(std::vector<LLVector3>) * 2;
|
||||
res += sizeof(LLVector3) * mPositions.size();
|
||||
res += sizeof(LLVector3) * mNormals.size();
|
||||
return res;
|
||||
}
|
||||
};
|
||||
|
||||
class Decomposition
|
||||
|
|
@ -118,6 +127,7 @@ public:
|
|||
void fromLLSD(LLSD& data);
|
||||
LLSD asLLSD() const;
|
||||
bool hasHullList() const;
|
||||
U32 sizeBytes() const;
|
||||
|
||||
void merge(const Decomposition* rhs);
|
||||
|
||||
|
|
|
|||
|
|
@ -73,6 +73,7 @@ private:
|
|||
static void display(void* data, void* id);
|
||||
|
||||
/*virtual*/ void setDirty(int left, int top, int right, int bottom) /* override, but that is not supported in gcc 4.6 */;
|
||||
void setDurationDirty();
|
||||
|
||||
static void eventCallbacks(const libvlc_event_t* event, void* ptr);
|
||||
|
||||
|
|
@ -213,6 +214,19 @@ void MediaPluginLibVLC::setDirty(int left, int top, int right, int bottom)
|
|||
sendMessage(message);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// *virtual*
|
||||
void MediaPluginLibVLC::setDurationDirty()
|
||||
{
|
||||
LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "updated");
|
||||
|
||||
message.setValueReal("current_time", mCurTime);
|
||||
message.setValueReal("duration", mDuration);
|
||||
message.setValueReal("current_rate", 1.0f);
|
||||
|
||||
sendMessage(message);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
void MediaPluginLibVLC::eventCallbacks(const libvlc_event_t* event, void* ptr)
|
||||
|
|
@ -233,6 +247,7 @@ void MediaPluginLibVLC::eventCallbacks(const libvlc_event_t* event, void* ptr)
|
|||
parent->mDuration = (float)(libvlc_media_get_duration(parent->mLibVLCMedia)) / 1000.0f;
|
||||
parent->mVlcStatus = STATUS_PLAYING;
|
||||
parent->setVolumeVLC();
|
||||
parent->setDurationDirty();
|
||||
break;
|
||||
|
||||
case libvlc_MediaPlayerPaused:
|
||||
|
|
@ -245,6 +260,8 @@ void MediaPluginLibVLC::eventCallbacks(const libvlc_event_t* event, void* ptr)
|
|||
|
||||
case libvlc_MediaPlayerEndReached:
|
||||
parent->mVlcStatus = STATUS_DONE;
|
||||
parent->mCurTime = parent->mDuration;
|
||||
parent->setDurationDirty();
|
||||
break;
|
||||
|
||||
case libvlc_MediaPlayerEncounteredError:
|
||||
|
|
@ -253,6 +270,11 @@ void MediaPluginLibVLC::eventCallbacks(const libvlc_event_t* event, void* ptr)
|
|||
|
||||
case libvlc_MediaPlayerTimeChanged:
|
||||
parent->mCurTime = (float)libvlc_media_player_get_time(parent->mLibVLCMediaPlayer) / 1000.0f;
|
||||
if (parent->mVlcStatus == STATUS_DONE && libvlc_media_player_is_playing(parent->mLibVLCMediaPlayer))
|
||||
{
|
||||
parent->mVlcStatus = STATUS_PLAYING;
|
||||
}
|
||||
parent->setDurationDirty();
|
||||
break;
|
||||
|
||||
case libvlc_MediaPlayerPositionChanged:
|
||||
|
|
@ -260,6 +282,7 @@ void MediaPluginLibVLC::eventCallbacks(const libvlc_event_t* event, void* ptr)
|
|||
|
||||
case libvlc_MediaPlayerLengthChanged:
|
||||
parent->mDuration = (float)libvlc_media_get_duration(parent->mLibVLCMedia) / 1000.0f;
|
||||
parent->setDurationDirty();
|
||||
break;
|
||||
|
||||
case libvlc_MediaPlayerTitleChanged:
|
||||
|
|
@ -611,6 +634,13 @@ void MediaPluginLibVLC::receiveMessage(const char* message_string)
|
|||
{
|
||||
if (mLibVLCMediaPlayer)
|
||||
{
|
||||
if (mVlcStatus == STATUS_DONE && !libvlc_media_player_is_playing(mLibVLCMediaPlayer))
|
||||
{
|
||||
// stop or vlc will ignore 'play', it will just
|
||||
// make an MediaPlayerEndReached event even if
|
||||
// seek was used
|
||||
libvlc_media_player_stop(mLibVLCMediaPlayer);
|
||||
}
|
||||
libvlc_media_player_play(mLibVLCMediaPlayer);
|
||||
}
|
||||
}
|
||||
|
|
@ -641,7 +671,7 @@ void MediaPluginLibVLC::receiveMessage(const char* message_string)
|
|||
if (!libvlc_media_player_is_playing(mLibVLCMediaPlayer))
|
||||
{
|
||||
// if paused, won't trigger update, update now
|
||||
setDirty(0, 0, mWidth, mHeight);
|
||||
setDurationDirty();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1759,6 +1759,9 @@ bool LLAppViewer::doFrame()
|
|||
{
|
||||
FSZoneN("Main:Coro");
|
||||
llcoro::suspend();
|
||||
// if one of our coroutines threw an uncaught exception, rethrow it now
|
||||
LLCoros::instance().rethrow();
|
||||
|
||||
}
|
||||
}// <FS:Beq> ensure we have the entire top scope of frame covered
|
||||
if (!LLApp::isExiting())
|
||||
|
|
@ -6432,12 +6435,6 @@ void LLAppViewer::forceErrorDriverCrash()
|
|||
glDeleteTextures(1, NULL);
|
||||
}
|
||||
|
||||
void LLAppViewer::forceErrorCoroutineCrash()
|
||||
{
|
||||
LL_WARNS() << "Forcing a crash in LLCoros" << LL_ENDL;
|
||||
LLCoros::instance().launch("LLAppViewer::crashyCoro", [] {throw LLException("A deliberate crash from LLCoros"); });
|
||||
}
|
||||
|
||||
void LLAppViewer::forceErrorThreadCrash()
|
||||
{
|
||||
class LLCrashTestThread : public LLThread
|
||||
|
|
|
|||
|
|
@ -151,7 +151,6 @@ public:
|
|||
virtual void forceErrorInfiniteLoop();
|
||||
virtual void forceErrorSoftwareException();
|
||||
virtual void forceErrorDriverCrash();
|
||||
virtual void forceErrorCoroutineCrash();
|
||||
virtual void forceErrorThreadCrash();
|
||||
|
||||
// The list is found in app_settings/settings_files.xml
|
||||
|
|
|
|||
|
|
@ -399,6 +399,9 @@ U32 LLMeshRepository::sLODPending = 0;
|
|||
|
||||
U32 LLMeshRepository::sCacheBytesRead = 0;
|
||||
U32 LLMeshRepository::sCacheBytesWritten = 0;
|
||||
U32 LLMeshRepository::sCacheBytesHeaders = 0;
|
||||
U32 LLMeshRepository::sCacheBytesSkins = 0;
|
||||
U32 LLMeshRepository::sCacheBytesDecomps = 0;
|
||||
U32 LLMeshRepository::sCacheReads = 0;
|
||||
U32 LLMeshRepository::sCacheWrites = 0;
|
||||
U32 LLMeshRepository::sMaxLockHoldoffs = 0;
|
||||
|
|
@ -1990,6 +1993,7 @@ EMeshProcessingResult LLMeshRepoThread::headerReceived(const LLVolumeParams& mes
|
|||
LLMutexLock lock(mHeaderMutex);
|
||||
mMeshHeaderSize[mesh_id] = header_size;
|
||||
mMeshHeader[mesh_id] = header;
|
||||
LLMeshRepository::sCacheBytesHeaders += header_size;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -3146,27 +3150,6 @@ S32 LLMeshRepository::getActualMeshLOD(LLSD& header, S32 lod)
|
|||
return -1;
|
||||
}
|
||||
|
||||
void LLMeshRepository::cacheOutgoingMesh(LLMeshUploadData& data, LLSD& header)
|
||||
{
|
||||
mThread->mMeshHeader[data.mUUID] = header;
|
||||
|
||||
// we cache the mesh for default parameters
|
||||
LLVolumeParams volume_params;
|
||||
volume_params.setType(LL_PCODE_PROFILE_SQUARE, LL_PCODE_PATH_LINE);
|
||||
volume_params.setSculptID(data.mUUID, LL_SCULPT_TYPE_MESH);
|
||||
|
||||
for (U32 i = 0; i < 4; i++)
|
||||
{
|
||||
if (data.mModel[i].notNull())
|
||||
{
|
||||
LLPointer<LLVolume> volume = new LLVolume(volume_params, LLVolumeLODGroup::getVolumeScaleFromDetail(i));
|
||||
volume->copyVolumeFaces(data.mModel[i]);
|
||||
volume->setMeshAssetLoaded(TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Handle failed or successful requests for mesh assets.
|
||||
//
|
||||
// Support for 200 responses was added for several reasons. One,
|
||||
|
|
@ -4155,6 +4138,8 @@ void LLMeshRepository::notifyLoadedMeshes()
|
|||
void LLMeshRepository::notifySkinInfoReceived(LLMeshSkinInfo& info)
|
||||
{
|
||||
mSkinMap[info.mMeshID] = info;
|
||||
// Alternative: We can get skin size from header
|
||||
sCacheBytesSkins += info.sizeBytes();
|
||||
|
||||
skin_load_map::iterator iter = mLoadingSkins.find(info.mMeshID);
|
||||
if (iter != mLoadingSkins.end())
|
||||
|
|
@ -4178,10 +4163,14 @@ void LLMeshRepository::notifyDecompositionReceived(LLModel::Decomposition* decom
|
|||
{ //just insert decomp into map
|
||||
mDecompositionMap[decomp->mMeshID] = decomp;
|
||||
mLoadingDecompositions.erase(decomp->mMeshID);
|
||||
sCacheBytesDecomps += decomp->sizeBytes();
|
||||
}
|
||||
else
|
||||
{ //merge decomp with existing entry
|
||||
sCacheBytesDecomps -= iter->second->sizeBytes();
|
||||
iter->second->merge(decomp);
|
||||
sCacheBytesDecomps += iter->second->sizeBytes();
|
||||
|
||||
mLoadingDecompositions.erase(decomp->mMeshID);
|
||||
delete decomp;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -573,6 +573,9 @@ public:
|
|||
static U32 sLODProcessing;
|
||||
static U32 sCacheBytesRead;
|
||||
static U32 sCacheBytesWritten;
|
||||
static U32 sCacheBytesHeaders;
|
||||
static U32 sCacheBytesSkins;
|
||||
static U32 sCacheBytesDecomps;
|
||||
static U32 sCacheReads;
|
||||
static U32 sCacheWrites;
|
||||
static U32 sMaxLockHoldoffs; // Maximum sequential locking failures
|
||||
|
|
@ -672,8 +675,6 @@ public:
|
|||
std::queue<LLUUID> mPendingPhysicsShapeRequests;
|
||||
|
||||
U32 mMeshThreadCount;
|
||||
|
||||
void cacheOutgoingMesh(LLMeshUploadData& data, LLSD& header);
|
||||
|
||||
LLMeshRepoThread* mThread;
|
||||
std::vector<LLMeshUploadThread*> mUploads;
|
||||
|
|
|
|||
|
|
@ -2722,7 +2722,6 @@ void LLModelPreview::genBuffers(S32 lod, bool include_skin_weights)
|
|||
continue;
|
||||
}
|
||||
|
||||
LLModel* base_mdl = *base_iter;
|
||||
base_iter++;
|
||||
|
||||
S32 num_faces = mdl->getNumVolumeFaces();
|
||||
|
|
@ -2799,7 +2798,7 @@ void LLModelPreview::genBuffers(S32 lod, bool include_skin_weights)
|
|||
//find closest weight to vf.mVertices[i].mPosition
|
||||
LLVector3 pos(vf.mPositions[i].getF32ptr());
|
||||
|
||||
const LLModel::weight_list& weight_list = base_mdl->getJointInfluences(pos);
|
||||
const LLModel::weight_list& weight_list = mdl->getJointInfluences(pos);
|
||||
llassert(weight_list.size()>0 && weight_list.size() <= 4); // LLModel::loadModel() should guarantee this
|
||||
|
||||
LLVector4 w(0, 0, 0, 0);
|
||||
|
|
|
|||
|
|
@ -34,10 +34,11 @@
|
|||
#include "llviewermenu.h"
|
||||
|
||||
// linden library includes
|
||||
#include "llavatarnamecache.h" // IDEVO
|
||||
#include "llavatarnamecache.h" // IDEVO (I Are Not Men!)
|
||||
#include "llcombobox.h"
|
||||
#include "llcoros.h"
|
||||
#include "llfloaterreg.h"
|
||||
#include "llfloatersidepanelcontainer.h"
|
||||
#include "llcombobox.h"
|
||||
#include "llinventorypanel.h"
|
||||
#include "llnotifications.h"
|
||||
#include "llnotificationsutil.h"
|
||||
|
|
@ -2705,6 +2706,7 @@ class LLAdvancedForceErrorLlerror : public view_listener_t
|
|||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
class LLAdvancedForceErrorBadMemoryAccess : public view_listener_t
|
||||
{
|
||||
bool handleEvent(const LLSD& userdata)
|
||||
|
|
@ -2714,6 +2716,22 @@ class LLAdvancedForceErrorBadMemoryAccess : public view_listener_t
|
|||
}
|
||||
};
|
||||
|
||||
class LLAdvancedForceErrorBadMemoryAccessCoro : public view_listener_t
|
||||
{
|
||||
bool handleEvent(const LLSD& userdata)
|
||||
{
|
||||
LLCoros::instance().launch(
|
||||
"AdvancedForceErrorBadMemoryAccessCoro",
|
||||
[](){
|
||||
// Wait for one mainloop() iteration, letting the enclosing
|
||||
// handleEvent() method return.
|
||||
llcoro::suspend();
|
||||
force_error_bad_memory_access(NULL);
|
||||
});
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
class LLAdvancedForceErrorInfiniteLoop : public view_listener_t
|
||||
{
|
||||
bool handleEvent(const LLSD& userdata)
|
||||
|
|
@ -2732,6 +2750,22 @@ class LLAdvancedForceErrorSoftwareException : public view_listener_t
|
|||
}
|
||||
};
|
||||
|
||||
class LLAdvancedForceErrorSoftwareExceptionCoro : public view_listener_t
|
||||
{
|
||||
bool handleEvent(const LLSD& userdata)
|
||||
{
|
||||
LLCoros::instance().launch(
|
||||
"AdvancedForceErrorSoftwareExceptionCoro",
|
||||
[](){
|
||||
// Wait for one mainloop() iteration, letting the enclosing
|
||||
// handleEvent() method return.
|
||||
llcoro::suspend();
|
||||
force_error_software_exception(NULL);
|
||||
});
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
class LLAdvancedForceErrorDriverCrash : public view_listener_t
|
||||
{
|
||||
bool handleEvent(const LLSD& userdata)
|
||||
|
|
@ -2741,15 +2775,6 @@ class LLAdvancedForceErrorDriverCrash : public view_listener_t
|
|||
}
|
||||
};
|
||||
|
||||
class LLAdvancedForceErrorCoroutineCrash : public view_listener_t
|
||||
{
|
||||
bool handleEvent(const LLSD& userdata)
|
||||
{
|
||||
force_error_coroutine_crash(NULL);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
class LLAdvancedForceErrorThreadCrash : public view_listener_t
|
||||
{
|
||||
bool handleEvent(const LLSD& userdata)
|
||||
|
|
@ -10417,11 +10442,6 @@ void force_error_driver_crash(void *)
|
|||
LLAppViewer::instance()->forceErrorDriverCrash();
|
||||
}
|
||||
|
||||
void force_error_coroutine_crash(void *)
|
||||
{
|
||||
LLAppViewer::instance()->forceErrorCoroutineCrash();
|
||||
}
|
||||
|
||||
void force_error_thread_crash(void *)
|
||||
{
|
||||
LLAppViewer::instance()->forceErrorThreadCrash();
|
||||
|
|
@ -12024,10 +12044,11 @@ void initialize_menus()
|
|||
view_listener_t::addMenu(new LLAdvancedForceErrorBreakpoint(), "Advanced.ForceErrorBreakpoint");
|
||||
view_listener_t::addMenu(new LLAdvancedForceErrorLlerror(), "Advanced.ForceErrorLlerror");
|
||||
view_listener_t::addMenu(new LLAdvancedForceErrorBadMemoryAccess(), "Advanced.ForceErrorBadMemoryAccess");
|
||||
view_listener_t::addMenu(new LLAdvancedForceErrorBadMemoryAccessCoro(), "Advanced.ForceErrorBadMemoryAccessCoro");
|
||||
view_listener_t::addMenu(new LLAdvancedForceErrorInfiniteLoop(), "Advanced.ForceErrorInfiniteLoop");
|
||||
view_listener_t::addMenu(new LLAdvancedForceErrorSoftwareException(), "Advanced.ForceErrorSoftwareException");
|
||||
view_listener_t::addMenu(new LLAdvancedForceErrorSoftwareExceptionCoro(), "Advanced.ForceErrorSoftwareExceptionCoro");
|
||||
view_listener_t::addMenu(new LLAdvancedForceErrorDriverCrash(), "Advanced.ForceErrorDriverCrash");
|
||||
view_listener_t::addMenu(new LLAdvancedForceErrorCoroutineCrash(), "Advanced.ForceErrorCoroutineCrash");
|
||||
view_listener_t::addMenu(new LLAdvancedForceErrorThreadCrash(), "Advanced.ForceErrorThreadCrash");
|
||||
view_listener_t::addMenu(new LLAdvancedForceErrorDisconnectViewer(), "Advanced.ForceErrorDisconnectViewer");
|
||||
|
||||
|
|
|
|||
|
|
@ -829,6 +829,12 @@ public:
|
|||
// </FS:Ansariel>
|
||||
|
||||
addText(xpos, ypos, llformat("%.3f/%.3f MB Mesh Cache Read/Write ", LLMeshRepository::sCacheBytesRead/(1024.f*1024.f), LLMeshRepository::sCacheBytesWritten/(1024.f*1024.f)));
|
||||
ypos += y_inc;
|
||||
|
||||
addText(xpos, ypos, llformat("%.3f/%.3f MB Mesh Skins/Decompositions Memory", LLMeshRepository::sCacheBytesSkins / (1024.f*1024.f), LLMeshRepository::sCacheBytesDecomps / (1024.f*1024.f)));
|
||||
ypos += y_inc;
|
||||
|
||||
addText(xpos, ypos, llformat("%.3f MB Mesh Headers Memory", LLMeshRepository::sCacheBytesHeaders / (1024.f*1024.f)));
|
||||
|
||||
ypos += y_inc;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3893,6 +3893,12 @@
|
|||
<menu_item_call.on_click
|
||||
function="Advanced.ForceErrorBadMemoryAccess" />
|
||||
</menu_item_call>
|
||||
<menu_item_call
|
||||
label="Force Bad Memory Access in Coroutine"
|
||||
name="Force Bad Memory Access in Coroutine">
|
||||
<menu_item_call.on_click
|
||||
function="Advanced.ForceErrorBadMemoryAccessCoro" />
|
||||
</menu_item_call>
|
||||
<menu_item_call
|
||||
label="Force Infinite Loop"
|
||||
name="Force Infinite Loop">
|
||||
|
|
@ -3912,10 +3918,10 @@
|
|||
function="Advanced.ForceErrorSoftwareException" />
|
||||
</menu_item_call>
|
||||
<menu_item_call
|
||||
label="Force a Crash in a Coroutine"
|
||||
name="Force a Crash in a Coroutine">
|
||||
label="Force Software Exception in Coroutine"
|
||||
name="Force Software Exception in Coroutine">
|
||||
<menu_item_call.on_click
|
||||
function="Advanced.ForceErrorCoroutineCrash" />
|
||||
function="Advanced.ForceErrorSoftwareExceptionCoro" />
|
||||
</menu_item_call>
|
||||
<menu_item_call
|
||||
label="Force a Crash in a Thread"
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ Placa gráfica: [GRAPHICS_CARD]
|
|||
Memória de Placa gráfica: [GRAPHICS_CARD_MEMORY] MB
|
||||
</string>
|
||||
<string name="AboutDriver">
|
||||
Versão do driver de vídeo Windows: [GRAPHICS_CARD_VENDOR]
|
||||
Versão do driver de vídeo Windows: [GRAPHICS_DRIVER_VERSION]
|
||||
</string>
|
||||
<string name="AboutOGL">
|
||||
Versão OpenGL: [OPENGL_VERSION]
|
||||
|
|
|
|||
Loading…
Reference in New Issue