Merge branch 'release/2025.03' of https://github.com/secondlife/viewer
# Conflicts: # indra/newview/llappviewer.cpp # indra/newview/llgiveinventory.cpp # indra/newview/llstartup.cpp # indra/newview/lltooldraganddrop.cpp # indra/newview/llvoavatar.cpp # indra/newview/skins/default/xui/fr/floater_avatar_textures.xml # indra/newview/skins/default/xui/it/floater_avatar_textures.xml # indra/newview/skins/default/xui/ja/floater_avatar_textures.xml # indra/newview/skins/default/xui/pl/floater_avatar_textures.xml # indra/newview/skins/default/xui/zh/floater_avatar_textures.xmlmaster
commit
d19e6abc5e
|
|
@ -815,7 +815,6 @@ void LLAvatarAppearance::buildCharacter()
|
|||
bool status = loadAvatar();
|
||||
stop_glerror();
|
||||
|
||||
// gPrintMessagesThisFrame = true;
|
||||
LL_DEBUGS() << "Avatar load took " << timer.getElapsedTimeF32() << " seconds." << LL_ENDL;
|
||||
|
||||
if (!status)
|
||||
|
|
|
|||
|
|
@ -282,7 +282,7 @@ public:
|
|||
LLRunner& getRunner() { return mRunner; }
|
||||
|
||||
#ifdef LL_WINDOWS
|
||||
virtual void reportCrashToBugsplat(void* pExcepInfo /*EXCEPTION_POINTERS*/) { }
|
||||
virtual bool reportCrashToBugsplat(void* pExcepInfo /*EXCEPTION_POINTERS*/) { return false; }
|
||||
#endif
|
||||
|
||||
public:
|
||||
|
|
|
|||
|
|
@ -228,22 +228,6 @@ 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;
|
||||
|
|
@ -310,18 +294,25 @@ namespace
|
|||
|
||||
static const U32 STATUS_MSC_EXCEPTION = 0xE06D7363; // compiler specific
|
||||
|
||||
U32 exception_filter(U32 code, struct _EXCEPTION_POINTERS *exception_infop)
|
||||
U32 exception_filter(U32 code, struct _EXCEPTION_POINTERS* exception_infop)
|
||||
{
|
||||
if (code == STATUS_MSC_EXCEPTION)
|
||||
if (LLApp::instance()->reportCrashToBugsplat((void*)exception_infop))
|
||||
{
|
||||
// Handled
|
||||
return EXCEPTION_CONTINUE_SEARCH;
|
||||
}
|
||||
else if (code == STATUS_MSC_EXCEPTION)
|
||||
{
|
||||
// C++ exception, go on
|
||||
return EXCEPTION_CONTINUE_SEARCH;
|
||||
}
|
||||
else
|
||||
{
|
||||
// handle it
|
||||
// handle it, convert to std::exception
|
||||
return EXCEPTION_EXECUTE_HANDLER;
|
||||
}
|
||||
|
||||
return EXCEPTION_CONTINUE_SEARCH;
|
||||
}
|
||||
|
||||
void sehandle(const LLCoros::callable_t& callable)
|
||||
|
|
@ -379,14 +370,7 @@ void LLCoros::toplevel(std::string name, callable_t callable)
|
|||
// viewer will carry on.
|
||||
LOG_UNHANDLED_EXCEPTION(STRINGIZE("coroutine " << name));
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
// 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());
|
||||
}
|
||||
// uncaught exception by default will cause std::terminate()
|
||||
}
|
||||
|
||||
//static
|
||||
|
|
|
|||
|
|
@ -170,19 +170,6 @@ public:
|
|||
*/
|
||||
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
|
||||
* name for an explicitly-launched coroutine, or "mainN" for the default
|
||||
|
|
@ -327,20 +314,6 @@ private:
|
|||
void toplevel(std::string name, callable_t callable);
|
||||
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;
|
||||
|
||||
|
|
|
|||
|
|
@ -301,12 +301,12 @@ LLCoprocedurePool::LLCoprocedurePool(const std::string &poolName, size_t size):
|
|||
mPoolSize(size),
|
||||
mActiveCoprocsCount(0),
|
||||
mPending(0),
|
||||
mPendingCoprocs(std::make_shared<CoprocQueue_t>(LLCoprocedureManager::DEFAULT_QUEUE_SIZE)),
|
||||
mHTTPPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID),
|
||||
mCoroMapping()
|
||||
{
|
||||
try
|
||||
{
|
||||
mPendingCoprocs = std::make_shared<CoprocQueue_t>(LLCoprocedureManager::DEFAULT_QUEUE_SIZE);
|
||||
// store in our LLTempBoundListener so that when the LLCoprocedurePool is
|
||||
// destroyed, we implicitly disconnect from this LLEventPump
|
||||
// Monitores application status
|
||||
|
|
@ -339,6 +339,11 @@ LLCoprocedurePool::LLCoprocedurePool(const std::string &poolName, size_t size):
|
|||
|
||||
llassert(0); // Fix Me! Ignoring missing listener!
|
||||
}
|
||||
catch (std::bad_alloc&)
|
||||
{
|
||||
LLError::LLUserWarningMsg::showOutOfMemory();
|
||||
LL_ERRS("CoProcMgr") << "Bad memory allocation in LLCoprocedurePool::LLCoprocedurePool!" << LL_ENDL;
|
||||
}
|
||||
|
||||
for (size_t count = 0; count < mPoolSize; ++count)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -295,7 +295,15 @@ void HttpCoroHandler::onCompleted(LLCore::HttpHandle handle, LLCore::HttpRespons
|
|||
}
|
||||
else
|
||||
{
|
||||
result = this->handleSuccess(response, status);
|
||||
try
|
||||
{
|
||||
result = this->handleSuccess(response, status);
|
||||
}
|
||||
catch (std::bad_alloc&)
|
||||
{
|
||||
LLError::LLUserWarningMsg::showOutOfMemory();
|
||||
LL_ERRS("CoreHTTP") << "Failed to allocate memory for response handling." << LL_ENDL;
|
||||
}
|
||||
}
|
||||
|
||||
buildStatusEntry(response, status, result);
|
||||
|
|
|
|||
|
|
@ -32,8 +32,6 @@
|
|||
#include "lltimer.h"
|
||||
#include "llhost.h"
|
||||
|
||||
///////////////////////////////////////////////////////////
|
||||
|
||||
LLPacketBuffer::LLPacketBuffer(const LLHost &host, const char *datap, const S32 size) : mHost(host)
|
||||
{
|
||||
mSize = 0;
|
||||
|
|
@ -41,7 +39,7 @@ LLPacketBuffer::LLPacketBuffer(const LLHost &host, const char *datap, const S32
|
|||
|
||||
if (size > NET_BUFFER_SIZE)
|
||||
{
|
||||
LL_ERRS() << "Sending packet > " << NET_BUFFER_SIZE << " of size " << size << LL_ENDL;
|
||||
LL_ERRS() << "Constructing packet with size=" << size << " > " << NET_BUFFER_SIZE << LL_ENDL;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -51,7 +49,6 @@ LLPacketBuffer::LLPacketBuffer(const LLHost &host, const char *datap, const S32
|
|||
mSize = size;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
LLPacketBuffer::LLPacketBuffer (S32 hSocket)
|
||||
|
|
@ -59,18 +56,29 @@ LLPacketBuffer::LLPacketBuffer (S32 hSocket)
|
|||
init(hSocket);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////
|
||||
|
||||
LLPacketBuffer::~LLPacketBuffer ()
|
||||
{
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////
|
||||
|
||||
void LLPacketBuffer::init (S32 hSocket)
|
||||
void LLPacketBuffer::init(S32 hSocket)
|
||||
{
|
||||
mSize = receive_packet(hSocket, mData);
|
||||
mHost = ::get_sender();
|
||||
mReceivingIF = ::get_receiving_interface();
|
||||
}
|
||||
|
||||
void LLPacketBuffer::init(const char* buffer, S32 data_size, const LLHost& host)
|
||||
{
|
||||
if (data_size > NET_BUFFER_SIZE)
|
||||
{
|
||||
LL_ERRS() << "Initializing packet with size=" << data_size << " > " << NET_BUFFER_SIZE << LL_ENDL;
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy(mData, buffer, data_size);
|
||||
mSize = data_size;
|
||||
mHost = host;
|
||||
mReceivingIF = ::get_receiving_interface();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -35,20 +35,22 @@ class LLPacketBuffer
|
|||
{
|
||||
public:
|
||||
LLPacketBuffer(const LLHost &host, const char *datap, const S32 size);
|
||||
LLPacketBuffer(S32 hSocket); // receive a packet
|
||||
LLPacketBuffer(S32 hSocket); // receive a packet
|
||||
~LLPacketBuffer();
|
||||
|
||||
S32 getSize() const { return mSize; }
|
||||
const char *getData() const { return mData; }
|
||||
LLHost getHost() const { return mHost; }
|
||||
LLHost getReceivingInterface() const { return mReceivingIF; }
|
||||
|
||||
void init(S32 hSocket);
|
||||
void init(const char* buffer, S32 data_size, const LLHost& host);
|
||||
|
||||
protected:
|
||||
char mData[NET_BUFFER_SIZE]; // packet data /* Flawfinder : ignore */
|
||||
S32 mSize; // size of buffer in bytes
|
||||
LLHost mHost; // source/dest IP and port
|
||||
LLHost mReceivingIF; // source/dest IP and port
|
||||
char mData[NET_BUFFER_SIZE]; // packet data /* Flawfinder : ignore */
|
||||
S32 mSize; // size of buffer in bytes
|
||||
LLHost mHost; // source/dest IP and port
|
||||
LLHost mReceivingIF; // source/dest IP and port
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
* @file llpacketring.cpp
|
||||
* @brief implementation of LLPacketRing class for a packet.
|
||||
* @brief implementation of LLPacketRing class.
|
||||
*
|
||||
* $LicenseInfo:firstyear=2001&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
|
|
@ -43,313 +43,44 @@
|
|||
#include "message.h"
|
||||
#include "u64.h"
|
||||
|
||||
///////////////////////////////////////////////////////////
|
||||
LLPacketRing::LLPacketRing () :
|
||||
mUseInThrottle(false),
|
||||
mUseOutThrottle(false),
|
||||
mInThrottle(256000.f),
|
||||
mOutThrottle(64000.f),
|
||||
mActualBitsIn(0),
|
||||
mActualBitsOut(0),
|
||||
mMaxBufferLength(64000),
|
||||
mInBufferLength(0),
|
||||
mOutBufferLength(0),
|
||||
mDropPercentage(0.0f),
|
||||
mPacketsToDrop(0x0)
|
||||
constexpr S16 MAX_BUFFER_RING_SIZE = 1024;
|
||||
constexpr S16 DEFAULT_BUFFER_RING_SIZE = 256;
|
||||
|
||||
LLPacketRing::LLPacketRing ()
|
||||
: mPacketRing(DEFAULT_BUFFER_RING_SIZE, nullptr)
|
||||
{
|
||||
LLHost invalid_host;
|
||||
for (size_t i = 0; i < mPacketRing.size(); ++i)
|
||||
{
|
||||
mPacketRing[i] = new LLPacketBuffer(invalid_host, nullptr, 0);
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////
|
||||
LLPacketRing::~LLPacketRing ()
|
||||
{
|
||||
cleanup();
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////
|
||||
void LLPacketRing::cleanup ()
|
||||
{
|
||||
LLPacketBuffer *packetp;
|
||||
|
||||
while (!mReceiveQueue.empty())
|
||||
for (auto packet : mPacketRing)
|
||||
{
|
||||
packetp = mReceiveQueue.front();
|
||||
delete packetp;
|
||||
mReceiveQueue.pop();
|
||||
}
|
||||
|
||||
while (!mSendQueue.empty())
|
||||
{
|
||||
packetp = mSendQueue.front();
|
||||
delete packetp;
|
||||
mSendQueue.pop();
|
||||
delete packet;
|
||||
}
|
||||
mPacketRing.clear();
|
||||
mNumBufferedPackets = 0;
|
||||
mNumBufferedBytes = 0;
|
||||
mHeadIndex = 0;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////
|
||||
void LLPacketRing::dropPackets (U32 num_to_drop)
|
||||
{
|
||||
mPacketsToDrop += num_to_drop;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////
|
||||
void LLPacketRing::setDropPercentage (F32 percent_to_drop)
|
||||
{
|
||||
mDropPercentage = percent_to_drop;
|
||||
}
|
||||
|
||||
void LLPacketRing::setUseInThrottle(const bool use_throttle)
|
||||
{
|
||||
mUseInThrottle = use_throttle;
|
||||
}
|
||||
|
||||
void LLPacketRing::setUseOutThrottle(const bool use_throttle)
|
||||
{
|
||||
mUseOutThrottle = use_throttle;
|
||||
}
|
||||
|
||||
void LLPacketRing::setInBandwidth(const F32 bps)
|
||||
{
|
||||
mInThrottle.setRate(bps);
|
||||
}
|
||||
|
||||
void LLPacketRing::setOutBandwidth(const F32 bps)
|
||||
{
|
||||
mOutThrottle.setRate(bps);
|
||||
}
|
||||
///////////////////////////////////////////////////////////
|
||||
S32 LLPacketRing::receiveFromRing (S32 socket, char *datap)
|
||||
{
|
||||
|
||||
if (mInThrottle.checkOverflow(0))
|
||||
{
|
||||
// We don't have enough bandwidth, don't give them a packet.
|
||||
return 0;
|
||||
}
|
||||
|
||||
LLPacketBuffer *packetp = NULL;
|
||||
if (mReceiveQueue.empty())
|
||||
{
|
||||
// No packets on the queue, don't give them any.
|
||||
return 0;
|
||||
}
|
||||
|
||||
S32 packet_size = 0;
|
||||
packetp = mReceiveQueue.front();
|
||||
mReceiveQueue.pop();
|
||||
packet_size = packetp->getSize();
|
||||
if (packetp->getData() != NULL)
|
||||
{
|
||||
memcpy(datap, packetp->getData(), packet_size); /*Flawfinder: ignore*/
|
||||
}
|
||||
// need to set sender IP/port!!
|
||||
mLastSender = packetp->getHost();
|
||||
mLastReceivingIF = packetp->getReceivingInterface();
|
||||
delete packetp;
|
||||
|
||||
this->mInBufferLength -= packet_size;
|
||||
|
||||
// Adjust the throttle
|
||||
mInThrottle.throttleOverflow(packet_size * 8.f);
|
||||
return packet_size;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////
|
||||
S32 LLPacketRing::receivePacket (S32 socket, char *datap)
|
||||
{
|
||||
S32 packet_size = 0;
|
||||
|
||||
// If using the throttle, simulate a limited size input buffer.
|
||||
if (mUseInThrottle)
|
||||
{
|
||||
bool done = false;
|
||||
|
||||
// push any current net packet (if any) onto delay ring
|
||||
while (!done)
|
||||
{
|
||||
LLPacketBuffer *packetp;
|
||||
packetp = new LLPacketBuffer(socket);
|
||||
|
||||
if (packetp->getSize())
|
||||
{
|
||||
mActualBitsIn += packetp->getSize() * 8;
|
||||
|
||||
// Fake packet loss
|
||||
if (mDropPercentage && (ll_frand(100.f) < mDropPercentage))
|
||||
{
|
||||
mPacketsToDrop++;
|
||||
}
|
||||
|
||||
if (mPacketsToDrop)
|
||||
{
|
||||
delete packetp;
|
||||
packetp = NULL;
|
||||
packet_size = 0;
|
||||
mPacketsToDrop--;
|
||||
}
|
||||
}
|
||||
|
||||
// If we faked packet loss, then we don't have a packet
|
||||
// to use for buffer overflow testing
|
||||
if (packetp)
|
||||
{
|
||||
if (mInBufferLength + packetp->getSize() > mMaxBufferLength)
|
||||
{
|
||||
// Toss it.
|
||||
LL_WARNS() << "Throwing away packet, overflowing buffer" << LL_ENDL;
|
||||
delete packetp;
|
||||
packetp = NULL;
|
||||
}
|
||||
else if (packetp->getSize())
|
||||
{
|
||||
mReceiveQueue.push(packetp);
|
||||
mInBufferLength += packetp->getSize();
|
||||
}
|
||||
else
|
||||
{
|
||||
delete packetp;
|
||||
packetp = NULL;
|
||||
done = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// No packetp, keep going? - no packetp == faked packet loss
|
||||
}
|
||||
}
|
||||
|
||||
// Now, grab data off of the receive queue according to our
|
||||
// throttled bandwidth settings.
|
||||
packet_size = receiveFromRing(socket, datap);
|
||||
}
|
||||
else
|
||||
{
|
||||
// no delay, pull straight from net
|
||||
if (LLProxy::isSOCKSProxyEnabled())
|
||||
{
|
||||
U8 buffer[NET_BUFFER_SIZE + SOCKS_HEADER_SIZE];
|
||||
packet_size = receive_packet(socket, static_cast<char*>(static_cast<void*>(buffer)));
|
||||
|
||||
if (packet_size > SOCKS_HEADER_SIZE)
|
||||
{
|
||||
// *FIX We are assuming ATYP is 0x01 (IPv4), not 0x03 (hostname) or 0x04 (IPv6)
|
||||
memcpy(datap, buffer + SOCKS_HEADER_SIZE, packet_size - SOCKS_HEADER_SIZE);
|
||||
proxywrap_t * header = static_cast<proxywrap_t*>(static_cast<void*>(buffer));
|
||||
mLastSender.setAddress(header->addr);
|
||||
mLastSender.setPort(ntohs(header->port));
|
||||
|
||||
packet_size -= SOCKS_HEADER_SIZE; // The unwrapped packet size
|
||||
}
|
||||
else
|
||||
{
|
||||
packet_size = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
packet_size = receive_packet(socket, datap);
|
||||
mLastSender = ::get_sender();
|
||||
}
|
||||
|
||||
mLastReceivingIF = ::get_receiving_interface();
|
||||
|
||||
if (packet_size) // did we actually get a packet?
|
||||
{
|
||||
if (mDropPercentage && (ll_frand(100.f) < mDropPercentage))
|
||||
{
|
||||
mPacketsToDrop++;
|
||||
}
|
||||
|
||||
if (mPacketsToDrop)
|
||||
{
|
||||
packet_size = 0;
|
||||
mPacketsToDrop--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return packet_size;
|
||||
bool drop = computeDrop();
|
||||
return (mNumBufferedPackets > 0) ?
|
||||
receiveOrDropBufferedPacket(datap, drop) :
|
||||
receiveOrDropPacket(socket, datap, drop);
|
||||
}
|
||||
|
||||
bool LLPacketRing::sendPacket(int h_socket, char * send_buffer, S32 buf_size, LLHost host)
|
||||
bool send_packet_helper(int socket, const char * datap, S32 data_size, LLHost host)
|
||||
{
|
||||
bool status = true;
|
||||
if (!mUseOutThrottle)
|
||||
{
|
||||
return sendPacketImpl(h_socket, send_buffer, buf_size, host );
|
||||
}
|
||||
else
|
||||
{
|
||||
mActualBitsOut += buf_size * 8;
|
||||
LLPacketBuffer *packetp = NULL;
|
||||
// See if we've got enough throttle to send a packet.
|
||||
while (!mOutThrottle.checkOverflow(0.f))
|
||||
{
|
||||
// While we have enough bandwidth, send a packet from the queue or the current packet
|
||||
|
||||
S32 packet_size = 0;
|
||||
if (!mSendQueue.empty())
|
||||
{
|
||||
// Send a packet off of the queue
|
||||
LLPacketBuffer *packetp = mSendQueue.front();
|
||||
mSendQueue.pop();
|
||||
|
||||
mOutBufferLength -= packetp->getSize();
|
||||
packet_size = packetp->getSize();
|
||||
|
||||
status = sendPacketImpl(h_socket, packetp->getData(), packet_size, packetp->getHost());
|
||||
|
||||
delete packetp;
|
||||
// Update the throttle
|
||||
mOutThrottle.throttleOverflow(packet_size * 8.f);
|
||||
}
|
||||
else
|
||||
{
|
||||
// If the queue's empty, we can just send this packet right away.
|
||||
status = sendPacketImpl(h_socket, send_buffer, buf_size, host );
|
||||
packet_size = buf_size;
|
||||
|
||||
// Update the throttle
|
||||
mOutThrottle.throttleOverflow(packet_size * 8.f);
|
||||
|
||||
// This was the packet we're sending now, there are no other packets
|
||||
// that we need to send
|
||||
return status;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// We haven't sent the incoming packet, add it to the queue
|
||||
if (mOutBufferLength + buf_size > mMaxBufferLength)
|
||||
{
|
||||
// Nuke this packet, we overflowed the buffer.
|
||||
// Toss it.
|
||||
LL_WARNS() << "Throwing away outbound packet, overflowing buffer" << LL_ENDL;
|
||||
}
|
||||
else
|
||||
{
|
||||
static LLTimer queue_timer;
|
||||
if ((mOutBufferLength > 4192) && queue_timer.getElapsedTimeF32() > 1.f)
|
||||
{
|
||||
// Add it to the queue
|
||||
LL_INFOS() << "Outbound packet queue " << mOutBufferLength << " bytes" << LL_ENDL;
|
||||
queue_timer.reset();
|
||||
}
|
||||
packetp = new LLPacketBuffer(host, send_buffer, buf_size);
|
||||
|
||||
mOutBufferLength += packetp->getSize();
|
||||
mSendQueue.push(packetp);
|
||||
}
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
bool LLPacketRing::sendPacketImpl(int h_socket, const char * send_buffer, S32 buf_size, LLHost host)
|
||||
{
|
||||
|
||||
if (!LLProxy::isSOCKSProxyEnabled())
|
||||
{
|
||||
return send_packet(h_socket, send_buffer, buf_size, host.getAddress(), host.getPort());
|
||||
return send_packet(socket, datap, data_size, host.getAddress(), host.getPort());
|
||||
}
|
||||
|
||||
char headered_send_buffer[NET_BUFFER_SIZE + SOCKS_HEADER_SIZE];
|
||||
|
|
@ -361,11 +92,252 @@ bool LLPacketRing::sendPacketImpl(int h_socket, const char * send_buffer, S32 bu
|
|||
socks_header->atype = ADDRESS_IPV4;
|
||||
socks_header->frag = 0;
|
||||
|
||||
memcpy(headered_send_buffer + SOCKS_HEADER_SIZE, send_buffer, buf_size);
|
||||
memcpy(headered_send_buffer + SOCKS_HEADER_SIZE, datap, data_size);
|
||||
|
||||
return send_packet( h_socket,
|
||||
return send_packet( socket,
|
||||
headered_send_buffer,
|
||||
buf_size + SOCKS_HEADER_SIZE,
|
||||
data_size + SOCKS_HEADER_SIZE,
|
||||
LLProxy::getInstance()->getUDPProxy().getAddress(),
|
||||
LLProxy::getInstance()->getUDPProxy().getPort());
|
||||
}
|
||||
|
||||
bool LLPacketRing::sendPacket(int socket, const char * datap, S32 data_size, LLHost host)
|
||||
{
|
||||
mActualBytesOut += data_size;
|
||||
return send_packet_helper(socket, datap, data_size, host);
|
||||
}
|
||||
|
||||
void LLPacketRing::dropPackets (U32 num_to_drop)
|
||||
{
|
||||
mPacketsToDrop += num_to_drop;
|
||||
}
|
||||
|
||||
void LLPacketRing::setDropPercentage (F32 percent_to_drop)
|
||||
{
|
||||
mDropPercentage = percent_to_drop;
|
||||
}
|
||||
|
||||
bool LLPacketRing::computeDrop()
|
||||
{
|
||||
bool drop= (mDropPercentage > 0.0f && (ll_frand(100.f) < mDropPercentage));
|
||||
if (drop)
|
||||
{
|
||||
++mPacketsToDrop;
|
||||
}
|
||||
if (mPacketsToDrop > 0)
|
||||
{
|
||||
--mPacketsToDrop;
|
||||
drop = true;
|
||||
}
|
||||
return drop;
|
||||
}
|
||||
|
||||
S32 LLPacketRing::receiveOrDropPacket(S32 socket, char *datap, bool drop)
|
||||
{
|
||||
S32 packet_size = 0;
|
||||
|
||||
// pull straight from socket
|
||||
if (LLProxy::isSOCKSProxyEnabled())
|
||||
{
|
||||
char buffer[NET_BUFFER_SIZE + SOCKS_HEADER_SIZE]; /* Flawfinder ignore */
|
||||
packet_size = receive_packet(socket, buffer);
|
||||
if (packet_size > 0)
|
||||
{
|
||||
mActualBytesIn += packet_size;
|
||||
}
|
||||
|
||||
if (packet_size > SOCKS_HEADER_SIZE)
|
||||
{
|
||||
if (drop)
|
||||
{
|
||||
packet_size = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
// *FIX We are assuming ATYP is 0x01 (IPv4), not 0x03 (hostname) or 0x04 (IPv6)
|
||||
packet_size -= SOCKS_HEADER_SIZE; // The unwrapped packet size
|
||||
memcpy(datap, buffer + SOCKS_HEADER_SIZE, packet_size);
|
||||
proxywrap_t * header = static_cast<proxywrap_t*>(static_cast<void*>(buffer));
|
||||
mLastSender.setAddress(header->addr);
|
||||
mLastSender.setPort(ntohs(header->port));
|
||||
mLastReceivingIF = ::get_receiving_interface();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
packet_size = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
packet_size = receive_packet(socket, datap);
|
||||
if (packet_size > 0)
|
||||
{
|
||||
mActualBytesIn += packet_size;
|
||||
if (drop)
|
||||
{
|
||||
packet_size = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
mLastSender = ::get_sender();
|
||||
mLastReceivingIF = ::get_receiving_interface();
|
||||
}
|
||||
}
|
||||
}
|
||||
return packet_size;
|
||||
}
|
||||
|
||||
S32 LLPacketRing::receiveOrDropBufferedPacket(char *datap, bool drop)
|
||||
{
|
||||
assert(mNumBufferedPackets > 0);
|
||||
S32 packet_size = 0;
|
||||
|
||||
S16 ring_size = (S16)(mPacketRing.size());
|
||||
S16 packet_index = (mHeadIndex + ring_size - mNumBufferedPackets) % ring_size;
|
||||
LLPacketBuffer* packet = mPacketRing[packet_index];
|
||||
packet_size = packet->getSize();
|
||||
mLastSender = packet->getHost();
|
||||
mLastReceivingIF = packet->getReceivingInterface();
|
||||
|
||||
--mNumBufferedPackets;
|
||||
mNumBufferedBytes -= packet_size;
|
||||
if (mNumBufferedPackets == 0)
|
||||
{
|
||||
assert(mNumBufferedBytes == 0);
|
||||
}
|
||||
|
||||
if (!drop)
|
||||
{
|
||||
assert(packet_size > 0);
|
||||
memcpy(datap, packet->getData(), packet_size);
|
||||
}
|
||||
else
|
||||
{
|
||||
packet_size = 0;
|
||||
}
|
||||
return packet_size;
|
||||
}
|
||||
|
||||
S32 LLPacketRing::bufferInboundPacket(S32 socket)
|
||||
{
|
||||
if (mNumBufferedPackets == mPacketRing.size() && mNumBufferedPackets < MAX_BUFFER_RING_SIZE)
|
||||
{
|
||||
expandRing();
|
||||
}
|
||||
|
||||
LLPacketBuffer* packet = mPacketRing[mHeadIndex];
|
||||
S32 old_packet_size = packet->getSize();
|
||||
S32 packet_size = 0;
|
||||
if (LLProxy::isSOCKSProxyEnabled())
|
||||
{
|
||||
char buffer[NET_BUFFER_SIZE + SOCKS_HEADER_SIZE]; /* Flawfinder ignore */
|
||||
packet_size = receive_packet(socket, buffer);
|
||||
if (packet_size > 0)
|
||||
{
|
||||
mActualBytesIn += packet_size;
|
||||
if (packet_size > SOCKS_HEADER_SIZE)
|
||||
{
|
||||
// *FIX We are assuming ATYP is 0x01 (IPv4), not 0x03 (hostname) or 0x04 (IPv6)
|
||||
|
||||
proxywrap_t * header = static_cast<proxywrap_t*>(static_cast<void*>(buffer));
|
||||
LLHost sender;
|
||||
sender.setAddress(header->addr);
|
||||
sender.setPort(ntohs(header->port));
|
||||
|
||||
packet_size -= SOCKS_HEADER_SIZE; // The unwrapped packet size
|
||||
packet->init(buffer + SOCKS_HEADER_SIZE, packet_size, sender);
|
||||
|
||||
mHeadIndex = (mHeadIndex + 1) % (S16)(mPacketRing.size());
|
||||
if (mNumBufferedPackets < MAX_BUFFER_RING_SIZE)
|
||||
{
|
||||
++mNumBufferedPackets;
|
||||
mNumBufferedBytes += packet_size;
|
||||
}
|
||||
else
|
||||
{
|
||||
// we overwrote an older packet
|
||||
mNumBufferedBytes += packet_size - old_packet_size;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
packet_size = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
packet->init(socket);
|
||||
packet_size = packet->getSize();
|
||||
if (packet_size > 0)
|
||||
{
|
||||
mActualBytesIn += packet_size;
|
||||
|
||||
mHeadIndex = (mHeadIndex + 1) % (S16)(mPacketRing.size());
|
||||
if (mNumBufferedPackets < MAX_BUFFER_RING_SIZE)
|
||||
{
|
||||
++mNumBufferedPackets;
|
||||
mNumBufferedBytes += packet_size;
|
||||
}
|
||||
else
|
||||
{
|
||||
// we overwrote an older packet
|
||||
mNumBufferedBytes += packet_size - old_packet_size;
|
||||
}
|
||||
}
|
||||
}
|
||||
return packet_size;
|
||||
}
|
||||
|
||||
S32 LLPacketRing::drainSocket(S32 socket)
|
||||
{
|
||||
// drain into buffer
|
||||
S32 packet_size = 1;
|
||||
S32 num_loops = 0;
|
||||
S32 old_num_packets = mNumBufferedPackets;
|
||||
while (packet_size > 0)
|
||||
{
|
||||
packet_size = bufferInboundPacket(socket);
|
||||
++num_loops;
|
||||
}
|
||||
S32 num_dropped_packets = (num_loops - 1 + old_num_packets) - mNumBufferedPackets;
|
||||
if (num_dropped_packets > 0)
|
||||
{
|
||||
LL_WARNS("Messaging") << "dropped " << num_dropped_packets << " UDP packets" << LL_ENDL;
|
||||
}
|
||||
return (S32)(mNumBufferedPackets);
|
||||
}
|
||||
|
||||
bool LLPacketRing::expandRing()
|
||||
{
|
||||
// compute larger size
|
||||
constexpr S16 BUFFER_RING_EXPANSION = 256;
|
||||
S16 old_size = (S16)(mPacketRing.size());
|
||||
S16 new_size = llmin(old_size + BUFFER_RING_EXPANSION, MAX_BUFFER_RING_SIZE);
|
||||
if (new_size == old_size)
|
||||
{
|
||||
// mPacketRing is already maxed out
|
||||
return false;
|
||||
}
|
||||
|
||||
// make a larger ring and copy packet pointers
|
||||
std::vector<LLPacketBuffer*> new_ring(new_size, nullptr);
|
||||
for (S16 i = 0; i < old_size; ++i)
|
||||
{
|
||||
S16 j = (mHeadIndex + i) % old_size;
|
||||
new_ring[i] = mPacketRing[j];
|
||||
}
|
||||
|
||||
// allocate new packets for the remainder of new_ring
|
||||
LLHost invalid_host;
|
||||
for (S16 i = old_size; i < new_size; ++i)
|
||||
{
|
||||
new_ring[i] = new LLPacketBuffer(invalid_host, nullptr, 0);
|
||||
}
|
||||
|
||||
// swap the rings and reset mHeadIndex
|
||||
mPacketRing.swap(new_ring);
|
||||
mHeadIndex = mNumBufferedPackets;
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,16 +25,14 @@
|
|||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#ifndef LL_LLPACKETRING_H
|
||||
#define LL_LLPACKETRING_H
|
||||
#pragma once
|
||||
|
||||
#include <queue>
|
||||
#include <vector>
|
||||
|
||||
#include "llhost.h"
|
||||
#include "llpacketbuffer.h"
|
||||
#include "llproxy.h"
|
||||
#include "llthrottle.h"
|
||||
#include "net.h"
|
||||
|
||||
|
||||
class LLPacketRing
|
||||
{
|
||||
|
|
@ -42,60 +40,65 @@ public:
|
|||
LLPacketRing();
|
||||
~LLPacketRing();
|
||||
|
||||
void cleanup();
|
||||
// receive one packet: either buffered or from the socket
|
||||
S32 receivePacket (S32 socket, char *datap);
|
||||
|
||||
// send one packet
|
||||
bool sendPacket(int h_socket, const char * send_buffer, S32 buf_size, LLHost host);
|
||||
|
||||
// drains packets from socket and returns final mNumBufferedPackets
|
||||
S32 drainSocket(S32 socket);
|
||||
|
||||
void dropPackets(U32);
|
||||
void setDropPercentage (F32 percent_to_drop);
|
||||
void setUseInThrottle(const bool use_throttle);
|
||||
void setUseOutThrottle(const bool use_throttle);
|
||||
void setInBandwidth(const F32 bps);
|
||||
void setOutBandwidth(const F32 bps);
|
||||
S32 receivePacket (S32 socket, char *datap);
|
||||
S32 receiveFromRing (S32 socket, char *datap);
|
||||
|
||||
bool sendPacket(int h_socket, char * send_buffer, S32 buf_size, LLHost host);
|
||||
inline LLHost getLastSender() const;
|
||||
inline LLHost getLastReceivingInterface() const;
|
||||
|
||||
inline LLHost getLastSender();
|
||||
inline LLHost getLastReceivingInterface();
|
||||
S32 getActualInBytes() const { return mActualBytesIn; }
|
||||
S32 getActualOutBytes() const { return mActualBytesOut; }
|
||||
S32 getAndResetActualInBits() { S32 bits = mActualBytesIn * 8; mActualBytesIn = 0; return bits;}
|
||||
S32 getAndResetActualOutBits() { S32 bits = mActualBytesOut * 8; mActualBytesOut = 0; return bits;}
|
||||
|
||||
S32 getAndResetActualInBits() { S32 bits = mActualBitsIn; mActualBitsIn = 0; return bits;}
|
||||
S32 getAndResetActualOutBits() { S32 bits = mActualBitsOut; mActualBitsOut = 0; return bits;}
|
||||
S32 getNumBufferedPackets() const { return (S32)(mNumBufferedPackets); }
|
||||
S32 getNumBufferedBytes() const { return mNumBufferedBytes; }
|
||||
protected:
|
||||
bool mUseInThrottle;
|
||||
bool mUseOutThrottle;
|
||||
// returns 'true' if we should intentionally drop a packet
|
||||
bool computeDrop();
|
||||
|
||||
// For simulating a lower-bandwidth connection - BPS
|
||||
LLThrottle mInThrottle;
|
||||
LLThrottle mOutThrottle;
|
||||
// returns packet_size of received packet, zero or less if no packet found
|
||||
S32 receiveOrDropPacket(S32 socket, char *datap, bool drop);
|
||||
S32 receiveOrDropBufferedPacket(char *datap, bool drop);
|
||||
|
||||
S32 mActualBitsIn;
|
||||
S32 mActualBitsOut;
|
||||
S32 mMaxBufferLength; // How much data can we queue up before dropping data.
|
||||
S32 mInBufferLength; // Current incoming buffer length
|
||||
S32 mOutBufferLength; // Current outgoing buffer length
|
||||
// returns packet_size of packet buffered
|
||||
S32 bufferInboundPacket(S32 socket);
|
||||
|
||||
F32 mDropPercentage; // % of packets to drop
|
||||
U32 mPacketsToDrop; // drop next n packets
|
||||
// returns 'true' if ring was expanded
|
||||
bool expandRing();
|
||||
|
||||
std::queue<LLPacketBuffer *> mReceiveQueue;
|
||||
std::queue<LLPacketBuffer *> mSendQueue;
|
||||
protected:
|
||||
std::vector<LLPacketBuffer*> mPacketRing;
|
||||
S16 mHeadIndex { 0 };
|
||||
S16 mNumBufferedPackets { 0 };
|
||||
S32 mNumBufferedBytes { 0 };
|
||||
|
||||
S32 mActualBytesIn { 0 };
|
||||
S32 mActualBytesOut { 0 };
|
||||
F32 mDropPercentage { 0.0f }; // % of inbound packets to drop
|
||||
U32 mPacketsToDrop { 0 }; // drop next inbound n packets
|
||||
|
||||
// These are the sender and receiving_interface for the last packet delivered by receivePacket()
|
||||
LLHost mLastSender;
|
||||
LLHost mLastReceivingIF;
|
||||
|
||||
private:
|
||||
bool sendPacketImpl(int h_socket, const char * send_buffer, S32 buf_size, LLHost host);
|
||||
};
|
||||
|
||||
|
||||
inline LLHost LLPacketRing::getLastSender()
|
||||
inline LLHost LLPacketRing::getLastSender() const
|
||||
{
|
||||
return mLastSender;
|
||||
}
|
||||
|
||||
inline LLHost LLPacketRing::getLastReceivingInterface()
|
||||
inline LLHost LLPacketRing::getLastReceivingInterface() const
|
||||
{
|
||||
return mLastReceivingIF;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -659,8 +659,7 @@ bool LLMessageSystem::checkMessages(LockMessageChecker&, S64 frame_count )
|
|||
|
||||
// UseCircuitCode is allowed in even from an invalid circuit, so that
|
||||
// we can toss circuits around.
|
||||
if(
|
||||
valid_packet &&
|
||||
else if (
|
||||
!cdp &&
|
||||
(mTemplateMessageReader->getMessageName() !=
|
||||
_PREHASH_UseCircuitCode))
|
||||
|
|
@ -670,8 +669,7 @@ bool LLMessageSystem::checkMessages(LockMessageChecker&, S64 frame_count )
|
|||
valid_packet = false;
|
||||
}
|
||||
|
||||
if(
|
||||
valid_packet &&
|
||||
if ( valid_packet &&
|
||||
cdp &&
|
||||
!cdp->getTrusted() &&
|
||||
mTemplateMessageReader->isTrusted())
|
||||
|
|
@ -683,7 +681,7 @@ bool LLMessageSystem::checkMessages(LockMessageChecker&, S64 frame_count )
|
|||
valid_packet = false;
|
||||
}
|
||||
|
||||
if( valid_packet )
|
||||
if ( valid_packet )
|
||||
{
|
||||
logValidMsg(cdp, host, recv_reliable, recv_resent, acks>0 );
|
||||
|
||||
|
|
@ -832,6 +830,11 @@ void LLMessageSystem::processAcks(LockMessageChecker&, F32 collect_time)
|
|||
}
|
||||
}
|
||||
|
||||
S32 LLMessageSystem::drainUdpSocket()
|
||||
{
|
||||
return mPacketRing.drainSocket(mSocket);
|
||||
}
|
||||
|
||||
void LLMessageSystem::copyMessageReceivedToSend()
|
||||
{
|
||||
// NOTE: babbage: switch builder to match reader to avoid
|
||||
|
|
|
|||
|
|
@ -417,6 +417,9 @@ public:
|
|||
bool checkMessages(LockMessageChecker&, S64 frame_count = 0 );
|
||||
void processAcks(LockMessageChecker&, F32 collect_time = 0.f);
|
||||
|
||||
// returns total number of buffered packets after the drain
|
||||
S32 drainUdpSocket();
|
||||
|
||||
bool isMessageFast(const char *msg);
|
||||
bool isMessage(const char *msg)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -76,14 +76,8 @@ static U32 gsnReceivingIFAddr = INVALID_HOST_IP_ADDRESS; // Address to which dat
|
|||
const char* LOOPBACK_ADDRESS_STRING = "127.0.0.1";
|
||||
const char* BROADCAST_ADDRESS_STRING = "255.255.255.255";
|
||||
|
||||
#if LL_DARWIN
|
||||
// macOS returns an error when trying to set these to 400000. Smaller values succeed.
|
||||
const int SEND_BUFFER_SIZE = 200000;
|
||||
const int RECEIVE_BUFFER_SIZE = 200000;
|
||||
#else // LL_DARWIN
|
||||
const int SEND_BUFFER_SIZE = 400000;
|
||||
const int RECEIVE_BUFFER_SIZE = 400000;
|
||||
#endif // LL_DARWIN
|
||||
const int SEND_BUFFER_SIZE = 200000;
|
||||
const int RECEIVE_BUFFER_SIZE = 800000;
|
||||
|
||||
// universal functions (cross-platform)
|
||||
|
||||
|
|
|
|||
|
|
@ -2536,12 +2536,15 @@ void LLGLState::checkStates(GLboolean writeAlpha)
|
|||
return;
|
||||
}
|
||||
|
||||
GLint src;
|
||||
GLint dst;
|
||||
glGetIntegerv(GL_BLEND_SRC, &src);
|
||||
glGetIntegerv(GL_BLEND_DST, &dst);
|
||||
llassert_always(src == GL_SRC_ALPHA);
|
||||
llassert_always(dst == GL_ONE_MINUS_SRC_ALPHA);
|
||||
GLint srcRGB, dstRGB, srcAlpha, dstAlpha;
|
||||
glGetIntegerv(GL_BLEND_SRC_RGB, &srcRGB);
|
||||
glGetIntegerv(GL_BLEND_DST_RGB, &dstRGB);
|
||||
glGetIntegerv(GL_BLEND_SRC_ALPHA, &srcAlpha);
|
||||
glGetIntegerv(GL_BLEND_DST_ALPHA, &dstAlpha);
|
||||
llassert_always(srcRGB == GL_SRC_ALPHA);
|
||||
llassert_always(srcAlpha == GL_SRC_ALPHA);
|
||||
llassert_always(dstRGB == GL_ONE_MINUS_SRC_ALPHA);
|
||||
llassert_always(dstAlpha == GL_ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
// disable for now until usage is consistent
|
||||
//GLboolean colorMask[4];
|
||||
|
|
|
|||
|
|
@ -3081,7 +3081,10 @@ void LLAgent::endAnimationUpdateUI()
|
|||
gAgentAvatarp->updateAttachmentVisibility(gAgentCamera.getCameraMode());
|
||||
}
|
||||
|
||||
gFloaterTools->dirty();
|
||||
if (gFloaterTools)
|
||||
{
|
||||
gFloaterTools->dirty();
|
||||
}
|
||||
|
||||
// Don't let this be called more than once if the camera
|
||||
// mode hasn't changed. --JC
|
||||
|
|
|
|||
|
|
@ -382,10 +382,6 @@ std::string gLastVersionChannel;
|
|||
LLVector3 gWindVec(3.0, 3.0, 0.0);
|
||||
LLVector3 gRelativeWindVec(0.0, 0.0, 0.0);
|
||||
|
||||
U32 gPacketsIn = 0;
|
||||
|
||||
bool gPrintMessagesThisFrame = false;
|
||||
|
||||
bool gRandomizeFramerate = false;
|
||||
bool gPeriodicSlowFrame = false;
|
||||
|
||||
|
|
@ -393,6 +389,7 @@ bool gCrashOnStartup = false;
|
|||
bool gLogoutInProgress = false;
|
||||
|
||||
bool gSimulateMemLeak = false;
|
||||
bool gDoDisconnect = false;
|
||||
|
||||
// We don't want anyone, especially threads working on the graphics pipeline,
|
||||
// to have to block due to this WorkQueue being full.
|
||||
|
|
@ -428,11 +425,6 @@ const std::string MARKER_FILE_NAME(SAFE_FILE_NAME_PREFIX + ".exec_marker"); //FS
|
|||
const std::string START_MARKER_FILE_NAME(SAFE_FILE_NAME_PREFIX + ".start_marker"); //FS new modified LL new
|
||||
const std::string ERROR_MARKER_FILE_NAME(SAFE_FILE_NAME_PREFIX + ".error_marker"); //FS orig modified LL
|
||||
const std::string LOGOUT_MARKER_FILE_NAME(SAFE_FILE_NAME_PREFIX + ".logout_marker"); //FS orig modified LL
|
||||
|
||||
//static bool gDoDisconnect = false;
|
||||
// [RLVa:KB] - Checked: RLVa-2.3
|
||||
bool gDoDisconnect = false;
|
||||
// [/RLVa:KB]
|
||||
static std::string gLaunchFileOnQuit;
|
||||
|
||||
// Used on Win32 for other apps to identify our window (eg, win_setup)
|
||||
|
|
@ -1669,8 +1661,6 @@ bool LLAppViewer::doFrame()
|
|||
LL_PROFILE_ZONE_NAMED_CATEGORY_APP("df suspend");
|
||||
// give listeners a chance to run
|
||||
llcoro::suspend();
|
||||
// if one of our coroutines threw an uncaught exception, rethrow it now
|
||||
LLCoros::instance().rethrow();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -5045,7 +5035,7 @@ U32 LLAppViewer::getTextureCacheVersion()
|
|||
U32 LLAppViewer::getDiskCacheVersion()
|
||||
{
|
||||
// Viewer disk cache version intorduced in Simple Cache Viewer, change if the cache format changes.
|
||||
const U32 DISK_CACHE_VERSION = 1;
|
||||
const U32 DISK_CACHE_VERSION = 2;
|
||||
|
||||
return DISK_CACHE_VERSION ;
|
||||
}
|
||||
|
|
@ -5814,6 +5804,20 @@ void LLAppViewer::idle()
|
|||
|
||||
if (gTeleportDisplay)
|
||||
{
|
||||
if (gAgent.getTeleportState() == LLAgent::TELEPORT_ARRIVING)
|
||||
{
|
||||
// Teleported, but waiting for things to load, start processing surface data
|
||||
{
|
||||
LL_RECORD_BLOCK_TIME(FTM_NETWORK);
|
||||
gVLManager.unpackData();
|
||||
}
|
||||
{
|
||||
LL_RECORD_BLOCK_TIME(FTM_REGION_UPDATE);
|
||||
const F32 max_region_update_time = .001f; // 1ms
|
||||
LLWorld::getInstance()->updateRegions(max_region_update_time);
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -6251,13 +6255,10 @@ void LLAppViewer::idleNameCache()
|
|||
// Handle messages, and all message related stuff
|
||||
//
|
||||
|
||||
#define TIME_THROTTLE_MESSAGES
|
||||
|
||||
#ifdef TIME_THROTTLE_MESSAGES
|
||||
#define CHECK_MESSAGES_DEFAULT_MAX_TIME .020f // 50 ms = 50 fps (just for messages!)
|
||||
constexpr F32 CHECK_MESSAGES_DEFAULT_MAX_TIME = 0.020f; // 50 ms = 50 fps (just for messages!)
|
||||
#define CHECK_MESSAGES_MAX_TIME_LIMIT 1.0f // 1 second, a long time but still able to stay connected
|
||||
static F32 CheckMessagesMaxTime = CHECK_MESSAGES_DEFAULT_MAX_TIME;
|
||||
#endif
|
||||
|
||||
static LLTrace::BlockTimerStatHandle FTM_IDLE_NETWORK("Idle Network");
|
||||
static LLTrace::BlockTimerStatHandle FTM_MESSAGE_ACKS("Message Acks");
|
||||
|
|
@ -6285,6 +6286,7 @@ void LLAppViewer::idleNetwork()
|
|||
F32 total_time = 0.0f;
|
||||
|
||||
{
|
||||
bool needs_drain = false;
|
||||
LockMessageChecker lmc(gMessageSystem);
|
||||
while (lmc.checkAllMessages(frame_count, gServicePump))
|
||||
{
|
||||
|
|
@ -6297,67 +6299,44 @@ void LLAppViewer::idleNetwork()
|
|||
}
|
||||
|
||||
total_decoded++;
|
||||
gPacketsIn++;
|
||||
|
||||
if (total_decoded > MESSAGE_MAX_PER_FRAME)
|
||||
{
|
||||
needs_drain = true;
|
||||
break;
|
||||
}
|
||||
|
||||
#ifdef TIME_THROTTLE_MESSAGES
|
||||
// Prevent slow packets from completely destroying the frame rate.
|
||||
// This usually happens due to clumps of avatars taking huge amount
|
||||
// of network processing time (which needs to be fixed, but this is
|
||||
// a good limit anyway).
|
||||
total_time = check_message_timer.getElapsedTimeF32();
|
||||
if (total_time >= CheckMessagesMaxTime)
|
||||
{
|
||||
needs_drain = true;
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
if (needs_drain || gMessageSystem->mPacketRing.getNumBufferedPackets() > 0)
|
||||
{
|
||||
// Rather than allow packets to silently backup on the socket
|
||||
// we drain them into our own buffer so we know how many exist.
|
||||
S32 num_buffered_packets = gMessageSystem->drainUdpSocket();
|
||||
if (num_buffered_packets > 0)
|
||||
{
|
||||
// Increase CheckMessagesMaxTime so that we will eventually catch up
|
||||
CheckMessagesMaxTime *= 1.035f; // 3.5% ~= 2x in 20 frames, ~8x in 60 frames
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Reset CheckMessagesMaxTime to default value
|
||||
CheckMessagesMaxTime = CHECK_MESSAGES_DEFAULT_MAX_TIME;
|
||||
}
|
||||
|
||||
// Handle per-frame message system processing.
|
||||
lmc.processAcks(gSavedSettings.getF32("AckCollectTime"));
|
||||
}
|
||||
|
||||
#ifdef TIME_THROTTLE_MESSAGES
|
||||
if (total_time >= CheckMessagesMaxTime)
|
||||
{
|
||||
// <FS:Beq> Don't allow busy network to excessively starve rendering loop
|
||||
// // Increase CheckMessagesMaxTime so that we will eventually catch up
|
||||
// CheckMessagesMaxTime *= 1.035f; // 3.5% ~= x2 in 20 frames, ~8x in 60 frames
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
if( CheckMessagesMaxTime < CHECK_MESSAGES_MAX_TIME_LIMIT ) // cap the increase to avoid logout through ping starvation
|
||||
{// Increase CheckMessagesMaxTime so that we will eventually catch up
|
||||
CheckMessagesMaxTime *= 1.035f; // 3.5% ~= x2 in 20 frames, ~8x in 60 frames
|
||||
}
|
||||
else
|
||||
{
|
||||
CheckMessagesMaxTime = CHECK_MESSAGES_MAX_TIME_LIMIT;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// </FS:Beq>
|
||||
// Reset CheckMessagesMaxTime to default value
|
||||
CheckMessagesMaxTime = CHECK_MESSAGES_DEFAULT_MAX_TIME;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Decode enqueued messages...
|
||||
S32 remaining_possible_decodes = MESSAGE_MAX_PER_FRAME - total_decoded;
|
||||
|
||||
if( remaining_possible_decodes <= 0 )
|
||||
{
|
||||
LL_INFOS() << "Maxed out number of messages per frame at " << MESSAGE_MAX_PER_FRAME << LL_ENDL;
|
||||
}
|
||||
|
||||
if (gPrintMessagesThisFrame)
|
||||
{
|
||||
LL_INFOS() << "Decoded " << total_decoded << " msgs this frame!" << LL_ENDL;
|
||||
gPrintMessagesThisFrame = false;
|
||||
}
|
||||
}
|
||||
add(LLStatViewer::NUM_NEW_OBJECTS, gObjectList.mNumNewObjects);
|
||||
|
||||
|
|
|
|||
|
|
@ -446,11 +446,10 @@ extern std::string gLastVersionChannel;
|
|||
|
||||
extern LLVector3 gWindVec;
|
||||
extern LLVector3 gRelativeWindVec;
|
||||
extern U32 gPacketsIn;
|
||||
extern bool gPrintMessagesThisFrame;
|
||||
|
||||
extern bool gRandomizeFramerate;
|
||||
extern bool gPeriodicSlowFrame;
|
||||
extern bool gDoDisconnect;
|
||||
|
||||
extern bool gSimulateMemLeak;
|
||||
|
||||
|
|
|
|||
|
|
@ -1022,14 +1022,16 @@ bool LLAppViewerWin32::cleanup()
|
|||
return result;
|
||||
}
|
||||
|
||||
void LLAppViewerWin32::reportCrashToBugsplat(void* pExcepInfo)
|
||||
bool LLAppViewerWin32::reportCrashToBugsplat(void* pExcepInfo)
|
||||
{
|
||||
#if defined(LL_BUGSPLAT)
|
||||
if (sBugSplatSender)
|
||||
{
|
||||
sBugSplatSender->createReport((EXCEPTION_POINTERS*)pExcepInfo);
|
||||
return true;
|
||||
}
|
||||
#endif // LL_BUGSPLAT
|
||||
return false;
|
||||
}
|
||||
|
||||
void LLAppViewerWin32::initLoggingAndGetLastDuration()
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ public:
|
|||
bool init() override; // Override to do application initialization
|
||||
bool cleanup() override;
|
||||
|
||||
void reportCrashToBugsplat(void* pExcepInfo) override;
|
||||
bool reportCrashToBugsplat(void* pExcepInfo) override;
|
||||
|
||||
protected:
|
||||
void initLoggingAndGetLastDuration() override; // Override to clean stack_trace info.
|
||||
|
|
|
|||
|
|
@ -477,7 +477,11 @@ bool LLGiveInventory::commitGiveInventoryItem(const LLUUID& to_agent,
|
|||
effectp->setDuration(LL_HUD_DUR_SHORT);
|
||||
effectp->setColor(LLColor4U(gAgent.getEffectColor()));
|
||||
}
|
||||
gFloaterTools->dirty();
|
||||
|
||||
if (gFloaterTools)
|
||||
{
|
||||
gFloaterTools->dirty();
|
||||
}
|
||||
|
||||
LLMuteList::getInstance()->autoRemove(to_agent, LLMuteList::AR_INVENTORY);
|
||||
|
||||
|
|
@ -674,7 +678,11 @@ bool LLGiveInventory::commitGiveInventoryCategory(const LLUUID& to_agent,
|
|||
effectp->setDuration(LL_HUD_DUR_SHORT);
|
||||
effectp->setColor(LLColor4U(gAgent.getEffectColor()));
|
||||
}
|
||||
gFloaterTools->dirty();
|
||||
|
||||
if (gFloaterTools)
|
||||
{
|
||||
gFloaterTools->dirty();
|
||||
}
|
||||
|
||||
LLMuteList::getInstance()->autoRemove(to_agent, LLMuteList::AR_INVENTORY);
|
||||
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -63,6 +63,16 @@ typedef enum e_mesh_processing_result_enum
|
|||
MESH_UNKNOWN
|
||||
} EMeshProcessingResult;
|
||||
|
||||
typedef enum e_mesh_request_type_enum
|
||||
{
|
||||
MESH_REQUEST_HEADER,
|
||||
MESH_REQUEST_LOD,
|
||||
MESH_REQUEST_SKIN,
|
||||
MESH_REQUEST_DECOMPOSITION,
|
||||
MESH_REQUEST_PHYSICS,
|
||||
MESH_REQUEST_UKNOWN
|
||||
} EMeshRequestType;
|
||||
|
||||
class LLMeshUploadData
|
||||
{
|
||||
public:
|
||||
|
|
@ -183,7 +193,8 @@ public:
|
|||
class RequestStats
|
||||
{
|
||||
public:
|
||||
RequestStats() : mRetries(0) {};
|
||||
|
||||
RequestStats() :mRetries(0) {};
|
||||
|
||||
void updateTime();
|
||||
bool canRetry() const;
|
||||
|
|
@ -195,6 +206,67 @@ private:
|
|||
LLFrameTimer mTimer;
|
||||
};
|
||||
|
||||
|
||||
class PendingRequestBase
|
||||
{
|
||||
public:
|
||||
struct CompareScoreGreater
|
||||
{
|
||||
bool operator()(const std::unique_ptr<PendingRequestBase>& lhs, const std::unique_ptr<PendingRequestBase>& rhs)
|
||||
{
|
||||
return lhs->mScore > rhs->mScore; // greatest = first
|
||||
}
|
||||
};
|
||||
|
||||
PendingRequestBase() : mScore(0.f) {};
|
||||
virtual ~PendingRequestBase() {}
|
||||
|
||||
bool operator<(const PendingRequestBase& rhs) const
|
||||
{
|
||||
return mId < rhs.mId;
|
||||
}
|
||||
|
||||
void setScore(F32 score) { mScore = score; }
|
||||
F32 getScore() const { return mScore; }
|
||||
LLUUID getId() const { return mId; }
|
||||
virtual EMeshRequestType getRequestType() const = 0;
|
||||
|
||||
protected:
|
||||
F32 mScore;
|
||||
LLUUID mId;
|
||||
};
|
||||
|
||||
class PendingRequestLOD : public PendingRequestBase
|
||||
{
|
||||
public:
|
||||
LLVolumeParams mMeshParams;
|
||||
S32 mLOD;
|
||||
|
||||
PendingRequestLOD(const LLVolumeParams& mesh_params, S32 lod)
|
||||
: PendingRequestBase(), mMeshParams(mesh_params), mLOD(lod)
|
||||
{
|
||||
mId = mMeshParams.getSculptID();
|
||||
}
|
||||
|
||||
EMeshRequestType getRequestType() const override { return MESH_REQUEST_LOD; }
|
||||
};
|
||||
|
||||
class PendingRequestUUID : public PendingRequestBase
|
||||
{
|
||||
public:
|
||||
|
||||
PendingRequestUUID(const LLUUID& id, EMeshRequestType type)
|
||||
: PendingRequestBase(), mRequestType(type)
|
||||
{
|
||||
mId = id;
|
||||
}
|
||||
|
||||
EMeshRequestType getRequestType() const override { return mRequestType; }
|
||||
|
||||
private:
|
||||
EMeshRequestType mRequestType;
|
||||
};
|
||||
|
||||
class LLMeshHeader
|
||||
{
|
||||
public:
|
||||
|
|
@ -242,19 +314,67 @@ public:
|
|||
}
|
||||
// </FS:Ansariel>
|
||||
}
|
||||
private:
|
||||
|
||||
enum EDiskCacheFlags {
|
||||
FLAG_SKIN = 1 << LLModel::NUM_LODS,
|
||||
FLAG_PHYSCONVEX = 1 << (LLModel::NUM_LODS + 1),
|
||||
FLAG_PHYSMESH = 1 << (LLModel::NUM_LODS + 2),
|
||||
};
|
||||
public:
|
||||
U32 getFlags()
|
||||
{
|
||||
U32 flags = 0;
|
||||
for (U32 i = 0; i < LLModel::NUM_LODS; i++)
|
||||
{
|
||||
if (mLodInCache[i])
|
||||
{
|
||||
flags |= 1 << i;
|
||||
}
|
||||
}
|
||||
if (mSkinInCache)
|
||||
{
|
||||
flags |= FLAG_SKIN;
|
||||
}
|
||||
if (mPhysicsConvexInCache)
|
||||
{
|
||||
flags |= FLAG_PHYSCONVEX;
|
||||
}
|
||||
if (mPhysicsMeshInCache)
|
||||
{
|
||||
flags |= FLAG_PHYSMESH;
|
||||
}
|
||||
return flags;
|
||||
}
|
||||
|
||||
void setFromFlags(U32 flags)
|
||||
{
|
||||
for (U32 i = 0; i < LLModel::NUM_LODS; i++)
|
||||
{
|
||||
mLodInCache[i] = (flags & (1 << i)) != 0;
|
||||
}
|
||||
mSkinInCache = (flags & FLAG_SKIN) != 0;
|
||||
mPhysicsConvexInCache = (flags & FLAG_PHYSCONVEX) != 0;
|
||||
mPhysicsMeshInCache = (flags & FLAG_PHYSMESH) != 0;
|
||||
}
|
||||
|
||||
S32 mVersion = -1;
|
||||
S32 mSkinOffset = -1;
|
||||
S32 mSkinSize = -1;
|
||||
bool mSkinInCache = false;
|
||||
|
||||
S32 mPhysicsConvexOffset = -1;
|
||||
S32 mPhysicsConvexSize = -1;
|
||||
bool mPhysicsConvexInCache = false;
|
||||
|
||||
S32 mPhysicsMeshOffset = -1;
|
||||
S32 mPhysicsMeshSize = -1;
|
||||
bool mPhysicsMeshInCache = false;
|
||||
|
||||
S32 mLodOffset[4] = { -1 };
|
||||
S32 mLodSize[4] = { -1 };
|
||||
S32 mLodOffset[LLModel::NUM_LODS] = { -1 };
|
||||
S32 mLodSize[LLModel::NUM_LODS] = { -1 };
|
||||
bool mLodInCache[LLModel::NUM_LODS] = { false };
|
||||
S32 mHeaderSize = -1;
|
||||
|
||||
bool m404 = false;
|
||||
|
||||
|
|
@ -268,6 +388,7 @@ public:
|
|||
|
||||
static std::atomic<S32> sActiveHeaderRequests;
|
||||
static std::atomic<S32> sActiveLODRequests;
|
||||
static std::atomic<S32> sActiveSkinRequests;
|
||||
static U32 sMaxConcurrentRequests;
|
||||
static S32 sRequestLowWater;
|
||||
static S32 sRequestHighWater;
|
||||
|
|
@ -275,10 +396,13 @@ public:
|
|||
|
||||
LLMutex* mMutex;
|
||||
LLMutex* mHeaderMutex;
|
||||
LLMutex* mLoadedMutex;
|
||||
LLMutex* mPendingMutex;
|
||||
LLMutex* mSkinMapMutex;
|
||||
LLCondition* mSignal;
|
||||
|
||||
//map of known mesh headers
|
||||
typedef boost::unordered_map<LLUUID, std::pair<U32, LLMeshHeader>> mesh_header_map; // pair is header_size and data
|
||||
typedef boost::unordered_map<LLUUID, LLMeshHeader> mesh_header_map; // pair is header_size and data
|
||||
mesh_header_map mMeshHeader;
|
||||
|
||||
class HeaderRequest : public RequestStats
|
||||
|
|
@ -302,22 +426,13 @@ public:
|
|||
public:
|
||||
LLVolumeParams mMeshParams;
|
||||
S32 mLOD;
|
||||
F32 mScore;
|
||||
|
||||
LODRequest(const LLVolumeParams& mesh_params, S32 lod)
|
||||
: RequestStats(), mMeshParams(mesh_params), mLOD(lod), mScore(0.f)
|
||||
: RequestStats(), mMeshParams(mesh_params), mLOD(lod)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
struct CompareScoreGreater
|
||||
{
|
||||
bool operator()(const LODRequest& lhs, const LODRequest& rhs)
|
||||
{
|
||||
return lhs.mScore > rhs.mScore; // greatest = first
|
||||
}
|
||||
};
|
||||
|
||||
class UUIDBasedRequest : public RequestStats
|
||||
{
|
||||
public:
|
||||
|
|
@ -379,7 +494,7 @@ public:
|
|||
std::deque<LoadedMesh> mLoadedQ;
|
||||
|
||||
//map of pending header requests and currently desired LODs
|
||||
typedef std::unordered_map<LLUUID, std::vector<S32> > pending_lod_map;
|
||||
typedef std::unordered_map<LLUUID, std::array<S32, LLModel::NUM_LODS> > pending_lod_map;
|
||||
pending_lod_map mPendingLOD;
|
||||
|
||||
// map of mesh ID to skin info (mirrors LLMeshRepository::mSkinMap)
|
||||
|
|
@ -389,6 +504,8 @@ public:
|
|||
|
||||
// workqueue for processing generic requests
|
||||
LL::WorkQueue mWorkQueue;
|
||||
// lods have their own thread due to costly cacheOptimize() calls
|
||||
std::unique_ptr<LL::ThreadPool> mMeshThreadPool;
|
||||
|
||||
// llcorehttp library interface objects.
|
||||
LLCore::HttpStatus mHttpStatus;
|
||||
|
|
@ -418,16 +535,16 @@ public:
|
|||
void lockAndLoadMeshLOD(const LLVolumeParams& mesh_params, S32 lod);
|
||||
void loadMeshLOD(const LLVolumeParams& mesh_params, S32 lod);
|
||||
|
||||
bool fetchMeshHeader(const LLVolumeParams& mesh_params, bool can_retry = true);
|
||||
bool fetchMeshLOD(const LLVolumeParams& mesh_params, S32 lod, bool can_retry = true);
|
||||
EMeshProcessingResult headerReceived(const LLVolumeParams& mesh_params, U8* data, S32 data_size);
|
||||
bool fetchMeshHeader(const LLVolumeParams& mesh_params);
|
||||
bool fetchMeshLOD(const LLVolumeParams& mesh_params, S32 lod);
|
||||
EMeshProcessingResult headerReceived(const LLVolumeParams& mesh_params, U8* data, S32 data_size, U32 flags = 0);
|
||||
EMeshProcessingResult lodReceived(const LLVolumeParams& mesh_params, S32 lod, U8* data, S32 data_size);
|
||||
bool skinInfoReceived(const LLUUID& mesh_id, U8* data, S32 data_size);
|
||||
bool decompositionReceived(const LLUUID& mesh_id, U8* data, S32 data_size);
|
||||
EMeshProcessingResult physicsShapeReceived(const LLUUID& mesh_id, U8* data, S32 data_size);
|
||||
bool hasPhysicsShapeInHeader(const LLUUID& mesh_id);
|
||||
bool hasSkinInfoInHeader(const LLUUID& mesh_id);
|
||||
bool hasHeader(const LLUUID& mesh_id);
|
||||
bool hasPhysicsShapeInHeader(const LLUUID& mesh_id) const;
|
||||
bool hasSkinInfoInHeader(const LLUUID& mesh_id) const;
|
||||
bool hasHeader(const LLUUID& mesh_id) const;
|
||||
|
||||
void notifyLoadedMeshes();
|
||||
S32 getActualMeshLOD(const LLVolumeParams& mesh_params, S32 lod);
|
||||
|
|
@ -438,7 +555,7 @@ public:
|
|||
|
||||
//send request for skin info, returns true if header info exists
|
||||
// (should hold onto mesh_id and try again later if header info does not exist)
|
||||
bool fetchMeshSkinInfo(const LLUUID& mesh_id, bool can_retry = true);
|
||||
bool fetchMeshSkinInfo(const LLUUID& mesh_id);
|
||||
|
||||
//send request for decomposition, returns true if header info exists
|
||||
// (should hold onto mesh_id and try again later if header info does not exist)
|
||||
|
|
@ -452,6 +569,8 @@ public:
|
|||
static void decActiveLODRequests();
|
||||
static void incActiveHeaderRequests();
|
||||
static void decActiveHeaderRequests();
|
||||
static void incActiveSkinRequests();
|
||||
static void decActiveSkinRequests();
|
||||
|
||||
// Set the caps strings and preferred version for constructing
|
||||
// mesh fetch URLs.
|
||||
|
|
@ -484,6 +603,14 @@ private:
|
|||
// </FS:Ansariel> [UDP Assets]
|
||||
size_t offset, size_t len,
|
||||
const LLCore::HttpHandler::ptr_t &handler);
|
||||
|
||||
// Mutex: acquires mPendingMutex, mMutex and mHeaderMutex as needed
|
||||
void loadMeshLOD(const LLUUID &mesh_id, const LLVolumeParams& mesh_params, S32 lod);
|
||||
|
||||
// Threads: Repo thread only
|
||||
U8* getDiskCacheBuffer(S32 size);
|
||||
S32 mDiskCacheBufferSize = 0;
|
||||
U8* mDiskCacheBuffer = nullptr;
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -596,35 +723,35 @@ public:
|
|||
bool init(const LLMeshHeader& header);
|
||||
|
||||
// Size for given LOD
|
||||
S32 getSizeByLOD(S32 lod);
|
||||
S32 getSizeByLOD(S32 lod) const;
|
||||
|
||||
// Sum of all LOD sizes.
|
||||
S32 getSizeTotal();
|
||||
S32 getSizeTotal() const;
|
||||
|
||||
// Estimated triangle counts for the given LOD.
|
||||
F32 getEstTrisByLOD(S32 lod);
|
||||
F32 getEstTrisByLOD(S32 lod) const;
|
||||
|
||||
// Estimated triangle counts for the largest LOD. Typically this
|
||||
// is also the "high" LOD, but not necessarily.
|
||||
F32 getEstTrisMax();
|
||||
F32 getEstTrisMax() const;
|
||||
|
||||
// Triangle count as computed by original streaming cost
|
||||
// formula. Triangles in each LOD are weighted based on how
|
||||
// frequently they will be seen.
|
||||
// This was called "unscaled_value" in the original getStreamingCost() functions.
|
||||
F32 getRadiusWeightedTris(F32 radius);
|
||||
F32 getRadiusWeightedTris(F32 radius) const;
|
||||
|
||||
// Triangle count used by triangle-based cost formula. Based on
|
||||
// triangles in highest LOD plus potentially partial charges for
|
||||
// lower LODs depending on complexity.
|
||||
F32 getEstTrisForStreamingCost();
|
||||
F32 getEstTrisForStreamingCost() const;
|
||||
|
||||
// Streaming cost. This should match the server-side calculation
|
||||
// for the corresponding volume.
|
||||
F32 getRadiusBasedStreamingCost(F32 radius);
|
||||
F32 getRadiusBasedStreamingCost(F32 radius) const;
|
||||
|
||||
// New streaming cost formula, currently only used for animated objects.
|
||||
F32 getTriangleBasedStreamingCost();
|
||||
F32 getTriangleBasedStreamingCost() const;
|
||||
|
||||
private:
|
||||
// From the "size" field of the mesh header. LOD 0=lowest, 3=highest.
|
||||
|
|
@ -648,12 +775,12 @@ public:
|
|||
static U32 sLODPending;
|
||||
static U32 sLODProcessing;
|
||||
static U32 sCacheBytesRead;
|
||||
static U32 sCacheBytesWritten;
|
||||
static std::atomic<U32> sCacheBytesWritten;
|
||||
static U32 sCacheBytesHeaders;
|
||||
static U32 sCacheBytesSkins;
|
||||
static U32 sCacheBytesDecomps;
|
||||
static U32 sCacheReads;
|
||||
static U32 sCacheWrites;
|
||||
static std::atomic<U32> sCacheWrites;
|
||||
static U32 sMaxLockHoldoffs; // Maximum sequential locking failures
|
||||
|
||||
static LLDeadmanTimer sQuiescentTimer; // Time-to-complete-mesh-downloads after significant events
|
||||
|
|
@ -677,11 +804,11 @@ public:
|
|||
|
||||
void unregisterMesh(LLVOVolume* volume);
|
||||
//mesh management functions
|
||||
S32 loadMesh(LLVOVolume* volume, const LLVolumeParams& mesh_params, S32 detail = 0, S32 last_lod = -1);
|
||||
S32 loadMesh(LLVOVolume* volume, const LLVolumeParams& mesh_params, S32 new_lod = 0, S32 last_lod = -1);
|
||||
|
||||
void notifyLoadedMeshes();
|
||||
void notifyMeshLoaded(const LLVolumeParams& mesh_params, LLVolume* volume);
|
||||
void notifyMeshUnavailable(const LLVolumeParams& mesh_params, S32 lod);
|
||||
void notifyMeshLoaded(const LLVolumeParams& mesh_params, LLVolume* volume, S32 lod);
|
||||
void notifyMeshUnavailable(const LLVolumeParams& mesh_params, S32 request_lod, S32 volume_lod);
|
||||
void notifySkinInfoReceived(LLMeshSkinInfo* info);
|
||||
void notifySkinInfoUnavailable(const LLUUID& info);
|
||||
void notifyDecompositionReceived(LLModel::Decomposition* info);
|
||||
|
|
@ -693,7 +820,7 @@ public:
|
|||
void fetchPhysicsShape(const LLUUID& mesh_id);
|
||||
bool hasPhysicsShape(const LLUUID& mesh_id);
|
||||
bool hasSkinInfo(const LLUUID& mesh_id);
|
||||
bool hasHeader(const LLUUID& mesh_id);
|
||||
bool hasHeader(const LLUUID& mesh_id) const;
|
||||
|
||||
void buildHull(const LLVolumeParams& params, S32 detail);
|
||||
void buildPhysicsMesh(LLModel::Decomposition& decomp);
|
||||
|
|
@ -707,7 +834,7 @@ public:
|
|||
LLHandle<LLWholeModelFeeObserver> fee_observer= (LLHandle<LLWholeModelFeeObserver>()),
|
||||
LLHandle<LLWholeModelUploadObserver> upload_observer = (LLHandle<LLWholeModelUploadObserver>()));
|
||||
|
||||
S32 getMeshSize(const LLUUID& mesh_id, S32 lod);
|
||||
S32 getMeshSize(const LLUUID& mesh_id, S32 lod) const;
|
||||
|
||||
// Quiescent timer management, main thread only.
|
||||
static void metricsStart();
|
||||
|
|
@ -715,7 +842,7 @@ public:
|
|||
static void metricsProgress(unsigned int count);
|
||||
static void metricsUpdate();
|
||||
|
||||
typedef boost::unordered_map<LLUUID, std::vector<LLVOVolume*> > mesh_load_map;
|
||||
typedef std::unordered_map<LLUUID, std::vector<LLVOVolume*> > mesh_load_map;
|
||||
mesh_load_map mLoadingMeshes[4];
|
||||
|
||||
// <FS:Ansariel> DAE export
|
||||
|
|
@ -729,15 +856,13 @@ public:
|
|||
|
||||
LLMutex* mMeshMutex;
|
||||
|
||||
std::vector<LLMeshRepoThread::LODRequest> mPendingRequests;
|
||||
typedef std::vector <std::unique_ptr<PendingRequestBase> > pending_requests_vec;
|
||||
pending_requests_vec mPendingRequests;
|
||||
|
||||
//list of mesh ids awaiting skin info
|
||||
typedef boost::unordered_map<LLUUID, std::vector<LLVOVolume*> > skin_load_map;
|
||||
typedef std::unordered_map<LLUUID, std::vector<LLVOVolume*> > skin_load_map;
|
||||
skin_load_map mLoadingSkins;
|
||||
|
||||
//list of mesh ids that need to send skin info fetch requests
|
||||
std::queue<LLUUID> mPendingSkinRequests;
|
||||
|
||||
//list of mesh ids awaiting decompositions
|
||||
std::unordered_set<LLUUID> mLoadingDecompositions;
|
||||
|
||||
|
|
|
|||
|
|
@ -294,7 +294,7 @@ void LLPanelPrimMediaControls::updateShape()
|
|||
LLViewerMediaImpl* media_impl = getTargetMediaImpl();
|
||||
LLViewerObject* objectp = getTargetObject();
|
||||
|
||||
if(!media_impl || gFloaterTools->getVisible())
|
||||
if(!media_impl || (gFloaterTools && gFloaterTools->getVisible()))
|
||||
{
|
||||
setVisible(false);
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -7524,7 +7524,10 @@ void dialog_refresh_all()
|
|||
// *TODO: Eliminate all calls into outside classes below, make those
|
||||
// objects register with the update signal.
|
||||
|
||||
gFloaterTools->dirty();
|
||||
if (gFloaterTools)
|
||||
{
|
||||
gFloaterTools->dirty();
|
||||
}
|
||||
|
||||
gMenuObject->needsArrange();
|
||||
|
||||
|
|
|
|||
|
|
@ -351,16 +351,62 @@ void callback_cache_name(const LLUUID& id, const std::string& full_name, bool is
|
|||
// exported functionality
|
||||
//
|
||||
|
||||
void do_startup_frame()
|
||||
{
|
||||
// Until after STATE_AGENT_SEND we don't get very many UDP packets to poll the socket,
|
||||
// and after STATE_PRECACHE the LLAppViewer::idleNetwork() will do UDP processing,
|
||||
// so we only bother to process between those two states.
|
||||
EStartupState state = LLStartUp::getStartupState();
|
||||
if (state > STATE_AGENT_SEND && state < STATE_PRECACHE)
|
||||
{
|
||||
// drain the UDP socket...
|
||||
U64 t0 = totalTime();
|
||||
constexpr U64 MAX_STARTUP_FRAME_TIME = 2000; // usec
|
||||
constexpr U64 MAX_STARTUP_FRAME_MESSAGES = 100;
|
||||
S32 num_messages = 0;
|
||||
bool needs_drain = false;
|
||||
LockMessageChecker lmc(gMessageSystem);
|
||||
while (lmc.checkAllMessages(gFrameCount, gServicePump))
|
||||
{
|
||||
if (gDoDisconnect)
|
||||
{
|
||||
// We're disconnecting, don't process any more messages from the server
|
||||
// We're usually disconnecting due to either network corruption or a
|
||||
// server going down, so this is OK.
|
||||
break;
|
||||
}
|
||||
if (++num_messages >= MAX_STARTUP_FRAME_MESSAGES
|
||||
|| (totalTime() - t0) > MAX_STARTUP_FRAME_TIME)
|
||||
{
|
||||
needs_drain = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (needs_drain || gMessageSystem->mPacketRing.getNumBufferedPackets() > 0)
|
||||
{
|
||||
gMessageSystem->drainUdpSocket();
|
||||
}
|
||||
lmc.processAcks();
|
||||
}
|
||||
// ...then call display_startup()
|
||||
display_startup();
|
||||
}
|
||||
|
||||
void pump_idle_startup_network(void)
|
||||
{
|
||||
// while there are message to process:
|
||||
// process one then call display_startup()
|
||||
S32 num_messages = 0;
|
||||
{
|
||||
LockMessageChecker lmc(gMessageSystem);
|
||||
while (lmc.checkAllMessages(gFrameCount, gServicePump))
|
||||
{
|
||||
display_startup();
|
||||
++num_messages;
|
||||
}
|
||||
lmc.processAcks();
|
||||
}
|
||||
// finally call one last display_startup()
|
||||
display_startup();
|
||||
}
|
||||
|
||||
|
|
@ -899,21 +945,6 @@ bool idle_startup()
|
|||
|
||||
F32 dropPercent = gSavedSettings.getF32("PacketDropPercentage");
|
||||
msg->mPacketRing.setDropPercentage(dropPercent);
|
||||
|
||||
F32 inBandwidth = gSavedSettings.getF32("InBandwidth");
|
||||
F32 outBandwidth = gSavedSettings.getF32("OutBandwidth");
|
||||
if (inBandwidth != 0.f)
|
||||
{
|
||||
LL_DEBUGS("AppInit") << "Setting packetring incoming bandwidth to " << inBandwidth << LL_ENDL;
|
||||
msg->mPacketRing.setUseInThrottle(true);
|
||||
msg->mPacketRing.setInBandwidth(inBandwidth);
|
||||
}
|
||||
if (outBandwidth != 0.f)
|
||||
{
|
||||
LL_DEBUGS("AppInit") << "Setting packetring outgoing bandwidth to " << outBandwidth << LL_ENDL;
|
||||
msg->mPacketRing.setUseOutThrottle(true);
|
||||
msg->mPacketRing.setOutBandwidth(outBandwidth);
|
||||
}
|
||||
}
|
||||
|
||||
LL_INFOS("AppInit") << "Message System Initialized." << LL_ENDL;
|
||||
|
|
@ -1185,7 +1216,7 @@ bool idle_startup()
|
|||
LL_DEBUGS("AppInit") << "STATE_BROWSER_INIT" << LL_ENDL;
|
||||
std::string msg = LLTrans::getString("LoginInitializingBrowser");
|
||||
set_startup_status(0.03f, msg.c_str(), gAgent.mMOTD.c_str());
|
||||
display_startup();
|
||||
do_startup_frame();
|
||||
// LLViewerMedia::initBrowser();
|
||||
LLStartUp::setStartupState( STATE_LOGIN_SHOW );
|
||||
return false;
|
||||
|
|
@ -1262,7 +1293,7 @@ bool idle_startup()
|
|||
LL_DEBUGS("AppInit") << "FirstLoginThisInstall off" << LL_ENDL;
|
||||
}
|
||||
}
|
||||
display_startup();
|
||||
do_startup_frame();
|
||||
LLStartUp::setStartupState( STATE_LOGIN_WAIT ); // Wait for user input
|
||||
}
|
||||
else
|
||||
|
|
@ -1302,7 +1333,7 @@ bool idle_startup()
|
|||
}
|
||||
LL_DEBUGS("AppInit") << "PeekMessage processed" << LL_ENDL;
|
||||
#endif
|
||||
display_startup();
|
||||
do_startup_frame();
|
||||
timeout.reset();
|
||||
return false;
|
||||
}
|
||||
|
|
@ -1317,7 +1348,7 @@ bool idle_startup()
|
|||
// Don't do anything. Wait for the login view to call the login_callback,
|
||||
// which will push us to the next state.
|
||||
|
||||
// display() function will be the one to run display_startup()
|
||||
// display() function will be the one to run do_startup_frame()
|
||||
// Sleep so we don't spin the CPU
|
||||
ms_sleep(1);
|
||||
return false;
|
||||
|
|
@ -1651,7 +1682,7 @@ bool idle_startup()
|
|||
auth_desc = LLTrans::getString("LoginInProgress");
|
||||
set_startup_status(progress, auth_desc, auth_message);
|
||||
progress += 0.02f;
|
||||
display_startup();
|
||||
do_startup_frame();
|
||||
|
||||
// <AW: crash report grid correctness>
|
||||
eLastExecEvent last_exec_event = gLastExecEvent;
|
||||
|
|
@ -1708,7 +1739,7 @@ bool idle_startup()
|
|||
emsg << LLTrans::getString("LoginFailedHeader") << "\n";
|
||||
if(LLLoginInstance::getInstance()->authFailure())
|
||||
{
|
||||
LL_INFOS("LLStartup") << "Login failed, LLLoginInstance::getResponse(): "
|
||||
LL_INFOS("LLStartUp") << "Login failed, LLLoginInstance::getResponse(): "
|
||||
<< LLLoginInstance::getInstance()->getResponse() << LL_ENDL;
|
||||
LLSD response = LLLoginInstance::getInstance()->getResponse();
|
||||
// Still have error conditions that may need some
|
||||
|
|
@ -1780,7 +1811,7 @@ bool idle_startup()
|
|||
// If optional was skipped this case shouldn't
|
||||
// be reached.
|
||||
|
||||
LL_INFOS("LLStartup") << "Forcing a quit due to update." << LL_ENDL;
|
||||
LL_INFOS("LLStartUp") << "Forcing a quit due to update." << LL_ENDL;
|
||||
LLLoginInstance::getInstance()->disconnect();
|
||||
LLAppViewer::instance()->forceQuit();
|
||||
}
|
||||
|
|
@ -1808,7 +1839,7 @@ bool idle_startup()
|
|||
}
|
||||
catch (LLCertException &cert_exception)
|
||||
{
|
||||
LL_WARNS("LLStartup", "SECAPI") << "Caught " << cert_exception.what() << " certificate expception on getCertificate("<< response["certificate"] << ")" << LL_ENDL;
|
||||
LL_WARNS("LLStartUp", "SECAPI") << "Caught " << cert_exception.what() << " certificate expception on getCertificate("<< response["certificate"] << ")" << LL_ENDL;
|
||||
LLSD args;
|
||||
args["REASON"] = LLTrans::getString(cert_exception.what());
|
||||
|
||||
|
|
@ -1863,7 +1894,7 @@ bool idle_startup()
|
|||
// notificatioin message.
|
||||
LLSD args;
|
||||
args["ERROR_MESSAGE"] = emsg.str();
|
||||
LL_INFOS("LLStartup") << "Notification: " << args << LL_ENDL;
|
||||
LL_INFOS("LLStartUp") << "Notification: " << args << LL_ENDL;
|
||||
LLNotificationsUtil::add("ErrorMessage", args, LLSD(), login_alert_done);
|
||||
}
|
||||
}
|
||||
|
|
@ -1903,7 +1934,7 @@ bool idle_startup()
|
|||
{
|
||||
LLSD args;
|
||||
args["ERROR_MESSAGE"] = emsg.str();
|
||||
LL_INFOS("LLStartup") << "Notification: " << args << LL_ENDL;
|
||||
LL_INFOS("LLStartUp") << "Notification: " << args << LL_ENDL;
|
||||
LLNotificationsUtil::add("ErrorMessage", args, LLSD(), login_alert_done);
|
||||
// <FS:Ansariel> Wait for notification confirmation
|
||||
//transition_back_to_login_panel(emsg.str());
|
||||
|
|
@ -1933,7 +1964,7 @@ bool idle_startup()
|
|||
if (STATE_WORLD_INIT == LLStartUp::getStartupState())
|
||||
{
|
||||
set_startup_status(0.30f, LLTrans::getString("LoginInitializingWorld"), gAgent.mMOTD);
|
||||
display_startup();
|
||||
do_startup_frame();
|
||||
// We should have an agent id by this point.
|
||||
llassert(!(gAgentID == LLUUID::null));
|
||||
|
||||
|
|
@ -1957,68 +1988,68 @@ bool idle_startup()
|
|||
|
||||
// Finish agent initialization. (Requires gSavedSettings, builds camera)
|
||||
gAgent.init();
|
||||
display_startup();
|
||||
do_startup_frame();
|
||||
gAgentCamera.init();
|
||||
display_startup();
|
||||
display_startup();
|
||||
do_startup_frame();
|
||||
do_startup_frame();
|
||||
|
||||
// Since we connected, save off the settings so the user doesn't have to
|
||||
// type the name/password again if we crash.
|
||||
gSavedSettings.saveToFile(gSavedSettings.getString("ClientSettingsFile"), true);
|
||||
LLUIColorTable::instance().saveUserSettings();
|
||||
|
||||
display_startup();
|
||||
do_startup_frame();
|
||||
|
||||
//
|
||||
// Initialize classes w/graphics stuff.
|
||||
//
|
||||
LLSurface::initClasses();
|
||||
display_startup();
|
||||
do_startup_frame();
|
||||
|
||||
display_startup();
|
||||
do_startup_frame();
|
||||
|
||||
LLDrawable::initClass();
|
||||
display_startup();
|
||||
do_startup_frame();
|
||||
|
||||
// init the shader managers
|
||||
LLPostProcess::initClass();
|
||||
display_startup();
|
||||
do_startup_frame();
|
||||
|
||||
LLAvatarAppearance::initClass("avatar_lad.xml","avatar_skeleton.xml");
|
||||
display_startup();
|
||||
do_startup_frame();
|
||||
|
||||
LLViewerObject::initVOClasses();
|
||||
display_startup();
|
||||
do_startup_frame();
|
||||
|
||||
// Initialize all our tools. Must be done after saved settings loaded.
|
||||
// NOTE: This also is where gToolMgr used to be instantiated before being turned into a singleton.
|
||||
LLToolMgr::getInstance()->initTools();
|
||||
display_startup();
|
||||
do_startup_frame();
|
||||
|
||||
// Pre-load floaters, like the world map, that are slow to spawn
|
||||
// due to XML complexity.
|
||||
gViewerWindow->initWorldUI();
|
||||
|
||||
display_startup();
|
||||
do_startup_frame();
|
||||
|
||||
// This is where we used to initialize gWorldp. Original comment said:
|
||||
// World initialization must be done after above window init
|
||||
|
||||
// User might have overridden far clip
|
||||
LLWorld::getInstance()->setLandFarClip(gAgentCamera.mDrawDistance);
|
||||
display_startup();
|
||||
do_startup_frame();
|
||||
// Before we create the first region, we need to set the agent's mOriginGlobal
|
||||
// This is necessary because creating objects before this is set will result in a
|
||||
// bad mPositionAgent cache.
|
||||
|
||||
gAgent.initOriginGlobal(from_region_handle(gFirstSimHandle));
|
||||
display_startup();
|
||||
do_startup_frame();
|
||||
|
||||
// <FS:CR> Aurora Sim
|
||||
//LLWorld::getInstance()->addRegion(gFirstSimHandle, gFirstSim);
|
||||
LLWorld::getInstance()->addRegion(gFirstSimHandle, gFirstSim, first_sim_size_x, first_sim_size_y);
|
||||
// </FS:CR> Aurora Sim
|
||||
display_startup();
|
||||
do_startup_frame();
|
||||
|
||||
LLViewerRegion *regionp = LLWorld::getInstance()->getRegionFromHandle(gFirstSimHandle);
|
||||
LL_INFOS("AppInit") << "Adding initial simulator " << regionp->getOriginGlobal() << LL_ENDL;
|
||||
|
|
@ -2027,18 +2058,18 @@ bool idle_startup()
|
|||
<< gFirstSimSeedCap << LL_ENDL;
|
||||
regionp->setSeedCapability(gFirstSimSeedCap);
|
||||
LL_DEBUGS("AppInit") << "Waiting for seed grant ...." << LL_ENDL;
|
||||
display_startup();
|
||||
do_startup_frame();
|
||||
// Set agent's initial region to be the one we just created.
|
||||
gAgent.setRegion(regionp);
|
||||
display_startup();
|
||||
do_startup_frame();
|
||||
// Set agent's initial position, which will be read by LLVOAvatar when the avatar
|
||||
// object is created. I think this must be done after setting the region. JC
|
||||
gAgent.setPositionAgent(agent_start_position_region);
|
||||
|
||||
display_startup();
|
||||
do_startup_frame();
|
||||
LLStartUp::initExperiences();
|
||||
|
||||
display_startup();
|
||||
do_startup_frame();
|
||||
|
||||
// If logging should be enebled, turns it on and loads history from disk
|
||||
// Note: does not happen on init of singleton because preferences can use
|
||||
|
|
@ -2059,7 +2090,7 @@ bool idle_startup()
|
|||
{
|
||||
LLStartUp::multimediaInit();
|
||||
LLStartUp::setStartupState( STATE_FONT_INIT );
|
||||
display_startup();
|
||||
do_startup_frame();
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -2068,7 +2099,7 @@ bool idle_startup()
|
|||
{
|
||||
LLStartUp::fontInit();
|
||||
LLStartUp::setStartupState( STATE_SEED_GRANTED_WAIT );
|
||||
display_startup();
|
||||
do_startup_frame();
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -2140,7 +2171,7 @@ bool idle_startup()
|
|||
set_startup_status(0.4f, LLTrans::getString("LoginRequestSeedCapGrant"), gAgent.mMOTD.c_str());
|
||||
}
|
||||
}
|
||||
display_startup();
|
||||
do_startup_frame();
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -2151,7 +2182,7 @@ bool idle_startup()
|
|||
//---------------------------------------------------------------------
|
||||
if (STATE_SEED_CAP_GRANTED == LLStartUp::getStartupState())
|
||||
{
|
||||
display_startup();
|
||||
do_startup_frame();
|
||||
|
||||
// These textures are not warrantied to be cached, so needs
|
||||
// to hapen with caps granted
|
||||
|
|
@ -2160,9 +2191,9 @@ bool idle_startup()
|
|||
// will init images, should be done with caps, but before gSky.init()
|
||||
LLEnvironment::getInstance()->initSingleton();
|
||||
|
||||
display_startup();
|
||||
do_startup_frame();
|
||||
update_texture_fetch();
|
||||
display_startup();
|
||||
do_startup_frame();
|
||||
|
||||
if ( gViewerWindow != NULL)
|
||||
{ // This isn't the first logon attempt, so show the UI
|
||||
|
|
@ -2170,15 +2201,15 @@ bool idle_startup()
|
|||
}
|
||||
gLoginMenuBarView->setVisible( false );
|
||||
gLoginMenuBarView->setEnabled( false );
|
||||
display_startup();
|
||||
do_startup_frame();
|
||||
|
||||
// direct logging to the debug console's line buffer
|
||||
LLError::logToFixedBuffer(gDebugView->mDebugConsolep);
|
||||
display_startup();
|
||||
do_startup_frame();
|
||||
|
||||
// set initial visibility of debug console
|
||||
gDebugView->mDebugConsolep->setVisible(gSavedSettings.getBOOL("ShowDebugConsole"));
|
||||
display_startup();
|
||||
do_startup_frame();
|
||||
|
||||
//
|
||||
// Set message handlers
|
||||
|
|
@ -2187,23 +2218,23 @@ bool idle_startup()
|
|||
|
||||
// register callbacks for messages. . . do this after initial handshake to make sure that we don't catch any unwanted
|
||||
register_viewer_callbacks(gMessageSystem);
|
||||
display_startup();
|
||||
do_startup_frame();
|
||||
|
||||
// Debugging info parameters
|
||||
gMessageSystem->setMaxMessageTime( 0.5f ); // Spam if decoding all msgs takes more than 500 ms
|
||||
display_startup();
|
||||
do_startup_frame();
|
||||
|
||||
#ifndef LL_RELEASE_FOR_DOWNLOAD
|
||||
gMessageSystem->setTimeDecodes( true ); // Time the decode of each msg
|
||||
gMessageSystem->setTimeDecodesSpamThreshold( 0.05f ); // Spam if a single msg takes over 50ms to decode
|
||||
#endif
|
||||
display_startup();
|
||||
do_startup_frame();
|
||||
|
||||
gXferManager->registerCallbacks(gMessageSystem);
|
||||
display_startup();
|
||||
do_startup_frame();
|
||||
|
||||
LLStartUp::initNameCache();
|
||||
display_startup();
|
||||
do_startup_frame();
|
||||
|
||||
// update the voice settings *after* gCacheName initialization
|
||||
// so that we can construct voice UI that relies on the name cache
|
||||
|
|
@ -2211,7 +2242,7 @@ bool idle_startup()
|
|||
{
|
||||
LLVoiceClient::getInstance()->updateSettings();
|
||||
}
|
||||
display_startup();
|
||||
do_startup_frame();
|
||||
|
||||
// <FS:Ansariel> OpenSim support: Init with defaults - we get the OpenSimExtras later during login
|
||||
LFSimFeatureHandler::instance();
|
||||
|
|
@ -2286,12 +2317,12 @@ bool idle_startup()
|
|||
// register null callbacks for audio until the audio system is initialized
|
||||
gMessageSystem->setHandlerFuncFast(_PREHASH_SoundTrigger, null_message_callback, NULL);
|
||||
gMessageSystem->setHandlerFuncFast(_PREHASH_AttachedSound, null_message_callback, NULL);
|
||||
display_startup();
|
||||
do_startup_frame();
|
||||
|
||||
//reset statistics
|
||||
LLViewerStats::instance().resetStats();
|
||||
|
||||
display_startup();
|
||||
do_startup_frame();
|
||||
//
|
||||
// Set up region and surface defaults
|
||||
//
|
||||
|
|
@ -2316,7 +2347,7 @@ bool idle_startup()
|
|||
LLViewerCamera::getInstance()->setAspect(gViewerWindow->getWorldViewAspectRatio());
|
||||
// Initialize FOV
|
||||
LLViewerCamera::getInstance()->setDefaultFOV(gSavedSettings.getF32("CameraAngle"));
|
||||
display_startup();
|
||||
do_startup_frame();
|
||||
|
||||
// Move agent to starting location. The position handed to us by
|
||||
// the space server is in global coordinates, but the agent frame
|
||||
|
|
@ -2327,7 +2358,7 @@ bool idle_startup()
|
|||
gAgent.resetAxes(gAgentStartLookAt);
|
||||
gAgentCamera.stopCameraAnimation();
|
||||
gAgentCamera.resetCamera();
|
||||
display_startup();
|
||||
do_startup_frame();
|
||||
|
||||
// Initialize global class data needed for surfaces (i.e. textures)
|
||||
LL_DEBUGS("AppInit") << "Initializing sky..." << LL_ENDL;
|
||||
|
|
@ -2338,7 +2369,7 @@ bool idle_startup()
|
|||
|
||||
LLGLState::checkStates();
|
||||
|
||||
display_startup();
|
||||
do_startup_frame();
|
||||
|
||||
LL_DEBUGS("AppInit") << "Decoding images..." << LL_ENDL;
|
||||
// For all images pre-loaded into viewer cache, init
|
||||
|
|
@ -2352,12 +2383,12 @@ bool idle_startup()
|
|||
{
|
||||
F32 frac = (F32)i / (F32)DECODE_TIME_SEC;
|
||||
set_startup_status(0.45f + frac*0.1f, LLTrans::getString("LoginDecodingImages"), gAgent.mMOTD);
|
||||
display_startup();
|
||||
do_startup_frame();
|
||||
gTextureList.decodeAllImages(1.f);
|
||||
}
|
||||
LLStartUp::setStartupState( STATE_WORLD_WAIT );
|
||||
|
||||
display_startup();
|
||||
do_startup_frame();
|
||||
|
||||
// JC - Do this as late as possible to increase likelihood Purify
|
||||
// will run.
|
||||
|
|
@ -2386,7 +2417,7 @@ bool idle_startup()
|
|||
NULL);
|
||||
|
||||
timeout.reset();
|
||||
display_startup();
|
||||
do_startup_frame();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
|
@ -2413,7 +2444,7 @@ bool idle_startup()
|
|||
{
|
||||
LL_DEBUGS("AppInit") << "Connecting to region..." << LL_ENDL;
|
||||
set_startup_status(0.60f, LLTrans::getString("LoginConnectingToRegion"), gAgent.mMOTD);
|
||||
display_startup();
|
||||
do_startup_frame();
|
||||
// register with the message system so it knows we're
|
||||
// expecting this message
|
||||
LLMessageSystem* msg = gMessageSystem;
|
||||
|
|
@ -2436,7 +2467,7 @@ bool idle_startup()
|
|||
#endif
|
||||
// </FS:Ansariel>
|
||||
}
|
||||
display_startup();
|
||||
do_startup_frame();
|
||||
|
||||
// Create login effect
|
||||
// But not on first login, because you can't see your avatar then
|
||||
|
|
@ -2451,7 +2482,7 @@ bool idle_startup()
|
|||
LLStartUp::setStartupState( STATE_AGENT_WAIT ); // Go to STATE_AGENT_WAIT
|
||||
|
||||
timeout.reset();
|
||||
display_startup();
|
||||
do_startup_frame();
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -2460,35 +2491,13 @@ bool idle_startup()
|
|||
//---------------------------------------------------------------------
|
||||
if (STATE_AGENT_WAIT == LLStartUp::getStartupState())
|
||||
{
|
||||
{
|
||||
LockMessageChecker lmc(gMessageSystem);
|
||||
while (lmc.checkAllMessages(gFrameCount, gServicePump))
|
||||
{
|
||||
if (gAgentMovementCompleted)
|
||||
{
|
||||
// Sometimes we have more than one message in the
|
||||
// queue. break out of this loop and continue
|
||||
// processing. If we don't, then this could skip one
|
||||
// or more login steps.
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
LL_DEBUGS("AppInit") << "Awaiting AvatarInitComplete, got "
|
||||
<< gMessageSystem->getMessageName() << LL_ENDL;
|
||||
}
|
||||
display_startup();
|
||||
}
|
||||
lmc.processAcks();
|
||||
}
|
||||
|
||||
display_startup();
|
||||
do_startup_frame();
|
||||
|
||||
if (gAgentMovementCompleted)
|
||||
{
|
||||
LLStartUp::setStartupState( STATE_INVENTORY_SEND );
|
||||
}
|
||||
display_startup();
|
||||
do_startup_frame();
|
||||
|
||||
if (!gAgentMovementCompleted && timeout.getElapsedTimeF32() > STATE_AGENT_WAIT_TIMEOUT)
|
||||
{
|
||||
|
|
@ -2521,7 +2530,7 @@ bool idle_startup()
|
|||
if (STATE_INVENTORY_SEND == LLStartUp::getStartupState())
|
||||
{
|
||||
LL_PROFILE_ZONE_NAMED("State inventory send")
|
||||
display_startup();
|
||||
do_startup_frame();
|
||||
|
||||
// request mute list
|
||||
LL_INFOS() << "Requesting Mute List" << LL_ENDL;
|
||||
|
|
@ -2531,7 +2540,7 @@ bool idle_startup()
|
|||
LL_INFOS() << "Requesting Money Balance" << LL_ENDL;
|
||||
LLStatusBar::sendMoneyBalanceRequest();
|
||||
|
||||
display_startup();
|
||||
do_startup_frame();
|
||||
// <FS:Ansariel> Moved before inventory creation.
|
||||
// request all group information
|
||||
LL_INFOS("Agent_GroupData") << "GROUPDEBUG: Requesting Agent Data during startup" << LL_ENDL;
|
||||
|
|
@ -2541,7 +2550,7 @@ bool idle_startup()
|
|||
// Inform simulator of our language preference
|
||||
LLAgentLanguage::update();
|
||||
|
||||
display_startup();
|
||||
do_startup_frame();
|
||||
// unpack thin inventory
|
||||
LLSD response = LLLoginInstance::getInstance()->getResponse();
|
||||
//bool dump_buffer = false;
|
||||
|
|
@ -2556,7 +2565,7 @@ bool idle_startup()
|
|||
gInventory.setLibraryRootFolderID(id.asUUID());
|
||||
}
|
||||
}
|
||||
display_startup();
|
||||
do_startup_frame();
|
||||
|
||||
LLSD inv_lib_owner = response["inventory-lib-owner"];
|
||||
if(inv_lib_owner.isDefined())
|
||||
|
|
@ -2568,9 +2577,9 @@ bool idle_startup()
|
|||
gInventory.setLibraryOwnerID(LLUUID(id.asUUID()));
|
||||
}
|
||||
}
|
||||
display_startup();
|
||||
do_startup_frame();
|
||||
LLStartUp::setStartupState(STATE_INVENTORY_SKEL);
|
||||
display_startup();
|
||||
do_startup_frame();
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -2589,7 +2598,7 @@ bool idle_startup()
|
|||
LL_WARNS("AppInit") << "Problem loading inventory-skel-lib" << LL_ENDL;
|
||||
}
|
||||
}
|
||||
display_startup();
|
||||
do_startup_frame();
|
||||
|
||||
LLSD inv_skeleton = response["inventory-skeleton"];
|
||||
if (inv_skeleton.isDefined())
|
||||
|
|
@ -2600,9 +2609,9 @@ bool idle_startup()
|
|||
LL_WARNS("AppInit") << "Problem loading inventory-skel-targets" << LL_ENDL;
|
||||
}
|
||||
}
|
||||
display_startup();
|
||||
do_startup_frame();
|
||||
LLStartUp::setStartupState(STATE_INVENTORY_SEND2);
|
||||
display_startup();
|
||||
do_startup_frame();
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -2657,7 +2666,7 @@ bool idle_startup()
|
|||
list[agent_id] = new LLRelationship(given_rights, has_rights, false);
|
||||
}
|
||||
LLAvatarTracker::instance().addBuddyList(list);
|
||||
display_startup();
|
||||
do_startup_frame();
|
||||
}
|
||||
|
||||
// <FS:Ansariel> Contact sets
|
||||
|
|
@ -2691,7 +2700,7 @@ bool idle_startup()
|
|||
//}
|
||||
}
|
||||
}
|
||||
display_startup();
|
||||
do_startup_frame();
|
||||
|
||||
// Either we want to show tutorial because this is the first login
|
||||
// to a Linden Help Island or the user quit with the tutorial
|
||||
|
|
@ -2700,21 +2709,21 @@ bool idle_startup()
|
|||
{
|
||||
LLFloaterReg::showInstance("hud", LLSD(), false);
|
||||
}
|
||||
display_startup();
|
||||
do_startup_frame();
|
||||
|
||||
LLSD event_notifications = response["event_notifications"];
|
||||
if(event_notifications.isDefined())
|
||||
{
|
||||
gEventNotifier.load(event_notifications);
|
||||
}
|
||||
display_startup();
|
||||
do_startup_frame();
|
||||
|
||||
LLSD classified_categories = response["classified_categories"];
|
||||
if(classified_categories.isDefined())
|
||||
{
|
||||
LLClassifiedInfo::loadCategories(classified_categories);
|
||||
}
|
||||
display_startup();
|
||||
do_startup_frame();
|
||||
|
||||
// This method MUST be called before gInventory.findCategoryUUIDForType because of
|
||||
// gInventory.mIsAgentInvUsable is set to true in the gInventory.buildParentChildMap.
|
||||
|
|
@ -2733,7 +2742,7 @@ bool idle_startup()
|
|||
LLInventoryModelBackgroundFetch::instance().start();
|
||||
gInventory.createCommonSystemCategories();
|
||||
LLStartUp::setStartupState(STATE_INVENTORY_CALLBACKS );
|
||||
display_startup();
|
||||
do_startup_frame();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
|
@ -2745,7 +2754,7 @@ bool idle_startup()
|
|||
{
|
||||
if (!LLInventoryModel::isSysFoldersReady())
|
||||
{
|
||||
display_startup();
|
||||
do_startup_frame();
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -2770,7 +2779,7 @@ bool idle_startup()
|
|||
gInventory.addChangedMask(LLInventoryObserver::ALL, LLUUID::null);
|
||||
gInventory.notifyObservers();
|
||||
|
||||
display_startup();
|
||||
do_startup_frame();
|
||||
|
||||
// set up callbacks
|
||||
LL_INFOS() << "Registering Callbacks" << LL_ENDL;
|
||||
|
|
@ -2781,18 +2790,18 @@ bool idle_startup()
|
|||
LLAvatarTracker::instance().registerCallbacks(msg);
|
||||
LL_INFOS() << " Landmark" << LL_ENDL;
|
||||
LLLandmark::registerCallbacks(msg);
|
||||
display_startup();
|
||||
do_startup_frame();
|
||||
|
||||
// <FS:Ansariel> Moved before inventory creation.
|
||||
//// request all group information
|
||||
//LL_INFOS() << "Requesting Agent Data" << LL_ENDL;
|
||||
//gAgent.sendAgentDataUpdateRequest();
|
||||
//display_startup();
|
||||
//do_startup_frame();
|
||||
// </FS:Ansariel>
|
||||
// Create the inventory views
|
||||
LL_INFOS() << "Creating Inventory Views" << LL_ENDL;
|
||||
LLFloaterReg::getInstance("inventory");
|
||||
//display_startup();
|
||||
//do_startup_frame();
|
||||
|
||||
// [RLVa:KB] - Checked: RLVa-1.1.0
|
||||
if (RlvHandler::isEnabled())
|
||||
|
|
@ -2803,7 +2812,7 @@ bool idle_startup()
|
|||
// [/RLVa:KB]
|
||||
|
||||
LLStartUp::setStartupState( STATE_MISC );
|
||||
display_startup();
|
||||
do_startup_frame();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
|
@ -2858,7 +2867,7 @@ bool idle_startup()
|
|||
|
||||
}
|
||||
|
||||
display_startup();
|
||||
do_startup_frame();
|
||||
|
||||
// Load stored local environment if needed.
|
||||
LLEnvironment::instance().loadFromSettings();
|
||||
|
|
@ -2866,7 +2875,7 @@ bool idle_startup()
|
|||
// *TODO : Uncomment that line once the whole grid migrated to SLM and suppress it from LLAgent::handleTeleportFinished() (llagent.cpp)
|
||||
//check_merchant_status();
|
||||
|
||||
display_startup();
|
||||
do_startup_frame();
|
||||
|
||||
// <FS:CR> Compatibility with old backups
|
||||
// Put gSavedPerAccountSettings here, put gSavedSettings in llappviewer.cpp
|
||||
|
|
@ -2891,7 +2900,7 @@ bool idle_startup()
|
|||
LLViewerHelp::instance().showTopic("");
|
||||
}
|
||||
|
||||
display_startup();
|
||||
do_startup_frame();
|
||||
|
||||
// We're successfully logged in.
|
||||
gSavedSettings.setBOOL("FirstLoginThisInstall", false);
|
||||
|
|
@ -2900,7 +2909,7 @@ bool idle_startup()
|
|||
|
||||
LLFloaterGridStatus::getInstance()->startGridStatusTimer();
|
||||
|
||||
display_startup();
|
||||
do_startup_frame();
|
||||
|
||||
// <FS:Ansariel> [FS Login Panel]
|
||||
// based on the comments, we've successfully logged in so we can delete the 'forced'
|
||||
|
|
@ -2917,10 +2926,10 @@ bool idle_startup()
|
|||
};
|
||||
// </FS:Ansariel> [FS Login Panel]
|
||||
|
||||
display_startup();
|
||||
do_startup_frame();
|
||||
// JC: Initializing audio requests many sounds for download.
|
||||
init_audio();
|
||||
display_startup();
|
||||
do_startup_frame();
|
||||
|
||||
// JC: Initialize "active" gestures. This may also trigger
|
||||
// many gesture downloads, if this is the user's first
|
||||
|
|
@ -2958,7 +2967,7 @@ bool idle_startup()
|
|||
LLGestureMgr::instance().startFetch();
|
||||
}
|
||||
gDisplaySwapBuffers = true;
|
||||
display_startup();
|
||||
do_startup_frame();
|
||||
|
||||
LLMessageSystem* msg = gMessageSystem;
|
||||
msg->setHandlerFuncFast(_PREHASH_SoundTrigger, process_sound_trigger);
|
||||
|
|
@ -3036,10 +3045,10 @@ bool idle_startup()
|
|||
}
|
||||
}
|
||||
|
||||
display_startup();
|
||||
do_startup_frame();
|
||||
//DEV-17797. get null folder. Any items found here moved to Lost and Found
|
||||
LLInventoryModelBackgroundFetch::instance().findLostItems();
|
||||
display_startup();
|
||||
do_startup_frame();
|
||||
|
||||
// <FS:CR> Load dynamic script library from xml
|
||||
#ifdef OPENSIM
|
||||
|
|
@ -3068,7 +3077,7 @@ bool idle_startup()
|
|||
|
||||
if (STATE_PRECACHE == LLStartUp::getStartupState())
|
||||
{
|
||||
display_startup();
|
||||
do_startup_frame();
|
||||
F32 timeout_frac = timeout.getElapsedTimeF32()/PRECACHING_DELAY;
|
||||
|
||||
// We now have an inventory skeleton, so if this is a user's first
|
||||
|
|
@ -3100,7 +3109,7 @@ bool idle_startup()
|
|||
callAfterCOFFetch(set_flags_and_update_appearance);
|
||||
}
|
||||
|
||||
display_startup();
|
||||
do_startup_frame();
|
||||
|
||||
// wait precache-delay and for agent's avatar or a lot longer.
|
||||
if ((timeout_frac > 1.f) && isAgentAvatarValid())
|
||||
|
|
@ -3125,7 +3134,7 @@ bool idle_startup()
|
|||
set_startup_status(0.60f + 0.30f * timeout_frac,
|
||||
LLTrans::getString("LoginPrecaching"),
|
||||
gAgent.mMOTD.c_str());
|
||||
display_startup();
|
||||
do_startup_frame();
|
||||
}
|
||||
|
||||
return true;
|
||||
|
|
@ -3153,7 +3162,7 @@ bool idle_startup()
|
|||
LLStartUp::setStartupState( STATE_CLEANUP );
|
||||
}
|
||||
|
||||
display_startup();
|
||||
do_startup_frame();
|
||||
|
||||
if (gAgent.isOutfitChosen() && (wearables_time > MAX_WEARABLES_TIME))
|
||||
{
|
||||
|
|
@ -3197,7 +3206,7 @@ bool idle_startup()
|
|||
if (STATE_CLEANUP == LLStartUp::getStartupState())
|
||||
{
|
||||
set_startup_status(1.0, "", "");
|
||||
display_startup();
|
||||
do_startup_frame();
|
||||
|
||||
if (!mBenefitsSuccessfullyInit)
|
||||
{
|
||||
|
|
@ -3241,7 +3250,7 @@ bool idle_startup()
|
|||
//gViewerWindow->revealIntroPanel();
|
||||
gViewerWindow->setStartupComplete();
|
||||
gViewerWindow->setProgressCancelButtonVisible(false);
|
||||
display_startup();
|
||||
do_startup_frame();
|
||||
|
||||
// We're not away from keyboard, even though login might have taken
|
||||
// a while. JC
|
||||
|
|
@ -3273,7 +3282,7 @@ bool idle_startup()
|
|||
// LLUserAuth::getInstance()->reset();
|
||||
|
||||
LLStartUp::setStartupState( STATE_STARTED );
|
||||
display_startup();
|
||||
do_startup_frame();
|
||||
|
||||
// <FS:Ansariel> Draw Distance stepping; originally based on SpeedRez by Henri Beauchamp, licensed under LGPL
|
||||
if (gSavedSettings.getBOOL("FSRenderFarClipStepping"))
|
||||
|
|
@ -3306,7 +3315,7 @@ bool idle_startup()
|
|||
// <FS:Ansariel> [FS communication UI]
|
||||
FSFloaterIM::initIMFloater();
|
||||
// </FS:Ansariel> [FS communication UI]
|
||||
display_startup();
|
||||
do_startup_frame();
|
||||
|
||||
llassert(LLPathfindingManager::getInstance() != NULL);
|
||||
LLPathfindingManager::getInstance()->initSystem();
|
||||
|
|
@ -3984,9 +3993,7 @@ std::string LLStartUp::startupStateToString(EStartupState state)
|
|||
// static
|
||||
void LLStartUp::setStartupState( EStartupState state )
|
||||
{
|
||||
LL_INFOS("AppInit") << "Startup state changing from " <<
|
||||
getStartupStateString() << " to " <<
|
||||
startupStateToString(state) << LL_ENDL;
|
||||
LL_INFOS("AppInit") << getStartupStateString() << " --> " << startupStateToString(state) << LL_ENDL;
|
||||
|
||||
getPhases().stopPhase(getStartupStateString());
|
||||
gStartupState = state;
|
||||
|
|
@ -4059,7 +4066,7 @@ void LLStartUp::multimediaInit()
|
|||
LL_DEBUGS("AppInit") << "Initializing Multimedia...." << LL_ENDL;
|
||||
std::string msg = LLTrans::getString("LoginInitializingMultimedia");
|
||||
set_startup_status(0.42f, msg.c_str(), gAgent.mMOTD.c_str());
|
||||
display_startup();
|
||||
do_startup_frame();
|
||||
|
||||
// Also initialise the stream titles.
|
||||
StreamTitleDisplay::instance();
|
||||
|
|
@ -4071,7 +4078,7 @@ void LLStartUp::fontInit()
|
|||
LL_DEBUGS("AppInit") << "Initializing fonts...." << LL_ENDL;
|
||||
std::string msg = LLTrans::getString("LoginInitializingFonts");
|
||||
set_startup_status(0.45f, msg.c_str(), gAgent.mMOTD.c_str());
|
||||
display_startup();
|
||||
do_startup_frame();
|
||||
|
||||
LLFontGL::loadDefaultFonts();
|
||||
}
|
||||
|
|
@ -4847,14 +4854,14 @@ bool process_login_success_response(U32 &first_sim_size_x, U32 &first_sim_size_y
|
|||
{
|
||||
// We got an answer from the grid -> use that for map for the current session
|
||||
gSavedSettings.setString("CurrentMapServerURL", map_server_url);
|
||||
LL_INFOS("LLStartup") << "map-server-url : we got an answer from the grid : " << map_server_url << LL_ENDL;
|
||||
LL_INFOS("LLStartUp") << "map-server-url : we got an answer from the grid : " << map_server_url << LL_ENDL;
|
||||
}
|
||||
else
|
||||
{
|
||||
// No answer from the grid -> use the default setting for current session
|
||||
map_server_url = gSavedSettings.getString("MapServerURL");
|
||||
gSavedSettings.setString("CurrentMapServerURL", map_server_url);
|
||||
LL_INFOS("LLStartup") << "map-server-url : no map-server-url answer, we use the default setting for the map : " << map_server_url << LL_ENDL;
|
||||
LL_INFOS("LLStartUp") << "map-server-url : no map-server-url answer, we use the default setting for the map : " << map_server_url << LL_ENDL;
|
||||
}
|
||||
|
||||
// <FS:CR> FIRE-8063: Read Aurora web profile url from login data
|
||||
|
|
|
|||
|
|
@ -749,7 +749,7 @@ void LLGLTexMemBar::draw()
|
|||
text = llformat("Mesh: Reqs(Tot/Htp/Big): %u/%u/%u Rtr/Err: %u/%u Cread/Cwrite: %u/%u Low/At/High: %d/%d/%d",
|
||||
LLMeshRepository::sMeshRequestCount, LLMeshRepository::sHTTPRequestCount, LLMeshRepository::sHTTPLargeRequestCount,
|
||||
LLMeshRepository::sHTTPRetryCount, LLMeshRepository::sHTTPErrorCount,
|
||||
LLMeshRepository::sCacheReads, LLMeshRepository::sCacheWrites,
|
||||
(U32)LLMeshRepository::sCacheReads, (U32)LLMeshRepository::sCacheWrites,
|
||||
LLMeshRepoThread::sRequestLowWater, LLMeshRepoThread::sRequestWaterLevel, LLMeshRepoThread::sRequestHighWater);
|
||||
LLFontGL::getFontMonospace()->renderUTF8(text, 0, 0, v_offset + line_height*2,
|
||||
text_color, LLFontGL::LEFT, LLFontGL::TOP);
|
||||
|
|
|
|||
|
|
@ -447,7 +447,10 @@ void LLToolBrushLand::handleSelect()
|
|||
{
|
||||
gEditMenuHandler = this;
|
||||
|
||||
gFloaterTools->setStatusText("modifyland");
|
||||
if (gFloaterTools)
|
||||
{
|
||||
gFloaterTools->setStatusText("modifyland");
|
||||
}
|
||||
// if (!mBrushSelected)
|
||||
{
|
||||
mBrushSelected = true;
|
||||
|
|
|
|||
|
|
@ -1267,6 +1267,7 @@ void LLToolDragAndDrop::dropMaterial(LLViewerObject* hit_obj,
|
|||
// If user dropped a material onto face it implies
|
||||
// applying texture now without cancel, save to selection
|
||||
if (nodep
|
||||
&& gFloaterTools
|
||||
&& gFloaterTools->getVisible()
|
||||
&& nodep->mSavedGLTFMaterialIds.size() > hit_face)
|
||||
{
|
||||
|
|
@ -1443,11 +1444,14 @@ void LLToolDragAndDrop::dropTexture(LLViewerObject* hit_obj,
|
|||
|
||||
// If user dropped a texture onto face it implies
|
||||
// applying texture now without cancel, save to selection
|
||||
// LLPanelFace* panel_face = gFloaterTools->getPanelFace(); // <FS:Zi> switchable edit texture/materials panel
|
||||
//LLPanelFace* panel_face = gFloaterTools ? gFloaterTools->getPanelFace() : nullptr; // <FS:Zi> switchable edit texture/materials panel
|
||||
if (nodep
|
||||
// <FS:Zi> switchable edit texture/materials panel
|
||||
//&& panel_face
|
||||
&& gFloaterTools
|
||||
// <FS:Zi>
|
||||
&& gFloaterTools->getVisible()
|
||||
// <FS:Zi> switchable edit texture/materials panel
|
||||
// && panel_face
|
||||
// && panel_face->getTextureDropChannel() == 0 /*texture*/
|
||||
&& gFloaterTools->getTextureDropChannel() == 0 /*texture*/
|
||||
// <FS:Zi>
|
||||
|
|
@ -1506,12 +1510,12 @@ void LLToolDragAndDrop::dropTextureOneFace(LLViewerObject* hit_obj,
|
|||
{
|
||||
LLGLTFMaterial::TextureInfo drop_channel = LLGLTFMaterial::GLTF_TEXTURE_INFO_BASE_COLOR;
|
||||
// <FS:Zi> switchable edit texture/materials panel
|
||||
// LLPanelFace* panel_face = gFloaterTools->getPanelFace();
|
||||
// if (gFloaterTools->getVisible() && panel_face)
|
||||
// LLPanelFace* panel_face = gFloaterTools ? gFloaterTools->getPanelFace() : nullptr;
|
||||
// if (panel_face && gFloaterTools->getVisible())
|
||||
// {
|
||||
// drop_channel = panel_face->getPBRDropChannel();
|
||||
// }
|
||||
if (gFloaterTools->getVisible())
|
||||
if (gFloaterTools && gFloaterTools->getVisible() && gFloaterTools->getPBRDropChannel() != LLGLTFMaterial::GLTF_TEXTURE_INFO_COUNT)
|
||||
{
|
||||
drop_channel = gFloaterTools->getPBRDropChannel();
|
||||
}
|
||||
|
|
@ -1544,10 +1548,10 @@ void LLToolDragAndDrop::dropTextureOneFace(LLViewerObject* hit_obj,
|
|||
LLTextureEntry* tep = hit_obj->getTE(hit_face);
|
||||
|
||||
// <FS:Zi> switchable edit texture/materials panel
|
||||
// LLPanelFace* panel_face = gFloaterTools->getPanelFace();
|
||||
// LLPanelFace* panel_face = gFloaterTools ? gFloaterTools->getPanelFace() : nullptr;
|
||||
|
||||
// if (gFloaterTools->getVisible() && panel_face)
|
||||
if (gFloaterTools->getVisible())
|
||||
// if (panel_face && gFloaterTools->getVisible())
|
||||
if (gFloaterTools && gFloaterTools->getVisible() && gFloaterTools->getTextureDropChannel() != LLRender::NUM_TEXTURE_CHANNELS)
|
||||
// </FS:Zi>
|
||||
{
|
||||
// <FS:Zi> switchable edit texture/materials panel
|
||||
|
|
@ -1649,7 +1653,10 @@ void LLToolDragAndDrop::dropScript(LLViewerObject* hit_obj,
|
|||
}
|
||||
}
|
||||
hit_obj->saveScript(new_script, active, true);
|
||||
gFloaterTools->dirty();
|
||||
if (gFloaterTools)
|
||||
{
|
||||
gFloaterTools->dirty();
|
||||
}
|
||||
|
||||
// VEFFECT: SetScript
|
||||
LLHUDEffectSpiral *effectp = (LLHUDEffectSpiral *)LLHUDManager::getInstance()->createViewerEffect(LLHUDObject::LL_HUD_EFFECT_BEAM, true);
|
||||
|
|
@ -1896,7 +1903,10 @@ void LLToolDragAndDrop::dropInventory(LLViewerObject* hit_obj,
|
|||
effectp->setTargetObject(hit_obj);
|
||||
effectp->setDuration(LL_HUD_DUR_SHORT);
|
||||
effectp->setColor(LLColor4U(gAgent.getEffectColor()));
|
||||
gFloaterTools->dirty();
|
||||
if (gFloaterTools)
|
||||
{
|
||||
gFloaterTools->dirty();
|
||||
}
|
||||
}
|
||||
|
||||
// accessor that looks at permissions, copyability, and names of
|
||||
|
|
|
|||
|
|
@ -621,7 +621,10 @@ bool LLToolPlacer::handleHover(S32 x, S32 y, MASK mask)
|
|||
|
||||
void LLToolPlacer::handleSelect()
|
||||
{
|
||||
gFloaterTools->setStatusText("place");
|
||||
if (gFloaterTools)
|
||||
{
|
||||
gFloaterTools->setStatusText("place");
|
||||
}
|
||||
}
|
||||
|
||||
void LLToolPlacer::handleDeselect()
|
||||
|
|
|
|||
|
|
@ -207,7 +207,10 @@ void LLToolSelectLand::render()
|
|||
|
||||
void LLToolSelectLand::handleSelect()
|
||||
{
|
||||
gFloaterTools->setStatusText("selectland");
|
||||
if (gFloaterTools)
|
||||
{
|
||||
gFloaterTools->setStatusText("selectland");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -3853,7 +3853,11 @@ void handle_object_edit()
|
|||
LLFloaterReg::showInstance("build");
|
||||
|
||||
LLToolMgr::getInstance()->setCurrentToolset(gBasicToolset);
|
||||
gFloaterTools->setEditTool( LLToolCompTranslate::getInstance() );
|
||||
|
||||
if (gFloaterTools)
|
||||
{
|
||||
gFloaterTools->setEditTool( LLToolCompTranslate::getInstance() );
|
||||
}
|
||||
|
||||
LLViewerJoystick::getInstance()->moveObjects(true);
|
||||
LLViewerJoystick::getInstance()->setNeedsReset(true);
|
||||
|
|
|
|||
|
|
@ -4064,7 +4064,9 @@ void send_agent_update(bool force_send, bool send_reliable)
|
|||
LL_PROFILE_ZONE_SCOPED;
|
||||
llassert(!gCubeSnapshot);
|
||||
|
||||
if (gAgent.getTeleportState() != LLAgent::TELEPORT_NONE)
|
||||
LLAgent::ETeleportState tp_state = gAgent.getTeleportState();
|
||||
if (tp_state != LLAgent::TELEPORT_NONE
|
||||
&& tp_state != LLAgent::TELEPORT_ARRIVING)
|
||||
{
|
||||
// We don't care if they want to send an agent update, they're not allowed
|
||||
// until the target simulator is ready to receive them
|
||||
|
|
@ -4242,7 +4244,36 @@ void send_agent_update(bool force_send, bool send_reliable)
|
|||
msg->addVector3Fast(_PREHASH_CameraAtAxis, camera_at);
|
||||
msg->addVector3Fast(_PREHASH_CameraLeftAxis, LLViewerCamera::getInstance()->getLeftAxis());
|
||||
msg->addVector3Fast(_PREHASH_CameraUpAxis, LLViewerCamera::getInstance()->getUpAxis());
|
||||
msg->addF32Fast(_PREHASH_Far, gAgentCamera.mDrawDistance);
|
||||
|
||||
static F32 last_draw_disatance_step = 1024;
|
||||
if (tp_state == LLAgent::TELEPORT_ARRIVING || LLStartUp::getStartupState() < STATE_MISC)
|
||||
{
|
||||
// Inform interest list, prioritize closer area.
|
||||
// Reason: currently server doesn't distance sort attachments, by restricting range
|
||||
// we reduce the number of attachments sent to the viewer, thus prioritizing
|
||||
// closer ones.
|
||||
// Todo: revise and remove once server gets distance sorting.
|
||||
last_draw_disatance_step = llmax((F32)(gAgentCamera.mDrawDistance / 2.f), 50.f);
|
||||
msg->addF32Fast(_PREHASH_Far, last_draw_disatance_step);
|
||||
}
|
||||
else if (last_draw_disatance_step < gAgentCamera.mDrawDistance)
|
||||
{
|
||||
static LLFrameTimer last_step_time;
|
||||
if (last_step_time.getElapsedTimeF32() > 1.f)
|
||||
{
|
||||
// gradually increase draw distance
|
||||
// Idealy this should be not per second, but based on how loaded
|
||||
// mesh thread is, but hopefully this is temporary.
|
||||
last_step_time.reset();
|
||||
F32 step = gAgentCamera.mDrawDistance * 0.1f;
|
||||
last_draw_disatance_step = llmin(last_draw_disatance_step + step, gAgentCamera.mDrawDistance);
|
||||
}
|
||||
msg->addF32Fast(_PREHASH_Far, last_draw_disatance_step);
|
||||
}
|
||||
else
|
||||
{
|
||||
msg->addF32Fast(_PREHASH_Far, gAgentCamera.mDrawDistance);
|
||||
}
|
||||
|
||||
msg->addU32Fast(_PREHASH_ControlFlags, control_flags);
|
||||
|
||||
|
|
|
|||
|
|
@ -1347,7 +1347,7 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,
|
|||
#endif
|
||||
//clear cost and linkset cost
|
||||
setObjectCostStale();
|
||||
if (isSelected())
|
||||
if (isSelected() && gFloaterTools)
|
||||
{
|
||||
gFloaterTools->dirty();
|
||||
}
|
||||
|
|
@ -1792,7 +1792,7 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,
|
|||
#endif
|
||||
setObjectCostStale();
|
||||
|
||||
if (isSelected())
|
||||
if (isSelected() && gFloaterTools)
|
||||
{
|
||||
gFloaterTools->dirty();
|
||||
}
|
||||
|
|
@ -3905,7 +3905,7 @@ void LLViewerObject::setObjectCost(F32 cost)
|
|||
mObjectCost = cost;
|
||||
mCostStale = false;
|
||||
|
||||
if (isSelected())
|
||||
if (isSelected() && gFloaterTools)
|
||||
{
|
||||
gFloaterTools->dirty();
|
||||
}
|
||||
|
|
@ -3925,7 +3925,7 @@ void LLViewerObject::setLinksetCost(F32 cost)
|
|||
iter++;
|
||||
}
|
||||
|
||||
if (needs_refresh)
|
||||
if (needs_refresh && gFloaterTools)
|
||||
{
|
||||
gFloaterTools->dirty();
|
||||
}
|
||||
|
|
@ -3936,7 +3936,7 @@ void LLViewerObject::setPhysicsCost(F32 cost)
|
|||
mPhysicsCost = cost;
|
||||
mCostStale = false;
|
||||
|
||||
if (isSelected())
|
||||
if (isSelected() && gFloaterTools)
|
||||
{
|
||||
gFloaterTools->dirty();
|
||||
}
|
||||
|
|
@ -3947,7 +3947,7 @@ void LLViewerObject::setLinksetPhysicsCost(F32 cost)
|
|||
mLinksetPhysicsCost = cost;
|
||||
mCostStale = false;
|
||||
|
||||
if (isSelected())
|
||||
if (isSelected() && gFloaterTools)
|
||||
{
|
||||
gFloaterTools->dirty();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@
|
|||
|
||||
#include "llviewertexturelist.h"
|
||||
|
||||
#include "llagent.h"
|
||||
#include "llgl.h" // fot gathering stats from GL
|
||||
#include "llimagegl.h"
|
||||
#include "llimagebmp.h"
|
||||
|
|
@ -828,10 +829,19 @@ void LLViewerTextureList::updateImages(F32 max_time)
|
|||
clearFetchingRequests();
|
||||
gPipeline.clearRebuildGroups();
|
||||
cleared = true;
|
||||
return;
|
||||
}
|
||||
// ARRIVING is a delay to let things decode, cache and process,
|
||||
// so process textures like normal despite gTeleportDisplay
|
||||
if (gAgent.getTeleportState() != LLAgent::TELEPORT_ARRIVING)
|
||||
{
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
cleared = false;
|
||||
else
|
||||
{
|
||||
cleared = false;
|
||||
}
|
||||
|
||||
LLAppViewer::getTextureFetch()->setTextureBandwidth((F32)LLTrace::get_frame_recording().getPeriodMeanPerSec(LLStatViewer::TEXTURE_NETWORK_DATA_RECEIVED).value());
|
||||
|
||||
|
|
|
|||
|
|
@ -712,7 +712,7 @@ LLVOAvatar::LLVOAvatar(const LLUUID& id,
|
|||
mFullyLoaded(false),
|
||||
mPreviousFullyLoaded(false),
|
||||
mFullyLoadedInitialized(false),
|
||||
mLastCloudAttachmentCount(0),
|
||||
mLastCloudAttachmentCount(-1),
|
||||
mVisualComplexity(VISUAL_COMPLEXITY_UNKNOWN),
|
||||
mLoadedCallbacksPaused(false),
|
||||
mLoadedCallbackTextures(0),
|
||||
|
|
@ -2950,7 +2950,10 @@ void LLVOAvatar::idleUpdate(LLAgent &agent, const F64 &time)
|
|||
}
|
||||
|
||||
// attach objects that were waiting for a drawable
|
||||
lazyAttach();
|
||||
if (!mPendingAttachment.empty())
|
||||
{
|
||||
lazyAttach();
|
||||
}
|
||||
|
||||
// animate the character
|
||||
// store off last frame's root position to be consistent with camera position
|
||||
|
|
@ -3416,6 +3419,7 @@ void LLVOAvatar::idleUpdateLoadingEffect()
|
|||
if (mFirstFullyVisible)
|
||||
{
|
||||
mFirstFullyVisible = false;
|
||||
mLastCloudAttachmentCount = (S32)mSimAttachments.size();
|
||||
mFirstDecloudTime = mFirstAppearanceMessageTimer.getElapsedTimeF32();
|
||||
if (isSelf())
|
||||
{
|
||||
|
|
@ -8519,85 +8523,102 @@ void LLVOAvatar::cleanupAttachedMesh( LLViewerObject* pVO )
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
// <FS:Beq> remove mesh rezzing delay
|
||||
// bool LLVOAvatar::hasPendingAttachedMeshes()
|
||||
// {
|
||||
// for (attachment_map_t::iterator iter = mAttachmentPoints.begin();
|
||||
// iter != mAttachmentPoints.end();
|
||||
// ++iter)
|
||||
// {
|
||||
// LLViewerJointAttachment* attachment = iter->second;
|
||||
// if (attachment)
|
||||
// {
|
||||
// for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin();
|
||||
// attachment_iter != attachment->mAttachedObjects.end();
|
||||
// ++attachment_iter)
|
||||
// {
|
||||
// LLViewerObject* objectp = attachment_iter->get();
|
||||
// if (objectp)
|
||||
// {
|
||||
// LLViewerObject::const_child_list_t& child_list = objectp->getChildren();
|
||||
// for (LLViewerObject::child_list_t::const_iterator iter1 = child_list.begin();
|
||||
// iter1 != child_list.end(); ++iter1)
|
||||
// {
|
||||
// LLViewerObject* objectchild = *iter1;
|
||||
// if (objectchild && objectchild->getVolume())
|
||||
// {
|
||||
// const LLUUID& mesh_id = objectchild->getVolume()->getParams().getSculptID();
|
||||
// if (mesh_id.isNull())
|
||||
// {
|
||||
// // No mesh nor skin info needed
|
||||
// continue;
|
||||
// }
|
||||
|
||||
// if (objectchild->getVolume()->isMeshAssetUnavaliable())
|
||||
// {
|
||||
// // Mesh failed to load, do not expect it
|
||||
// continue;
|
||||
// }
|
||||
|
||||
// if (objectchild->mDrawable)
|
||||
// {
|
||||
// LLVOVolume* pvobj = objectchild->mDrawable->getVOVolume();
|
||||
// if (pvobj)
|
||||
// {
|
||||
// if (!pvobj->isMesh())
|
||||
// {
|
||||
// // Not a mesh
|
||||
// continue;
|
||||
// }
|
||||
|
||||
// if (!objectchild->getVolume()->isMeshAssetLoaded())
|
||||
// {
|
||||
// // Waiting for mesh
|
||||
// return true;
|
||||
// }
|
||||
|
||||
// const LLMeshSkinInfo* skin_data = pvobj->getSkinInfo();
|
||||
// if (skin_data)
|
||||
// {
|
||||
// // Skin info present, done
|
||||
// continue;
|
||||
// }
|
||||
|
||||
// if (pvobj->isSkinInfoUnavaliable())
|
||||
// {
|
||||
// // Load failed or info not present, don't expect it
|
||||
// continue;
|
||||
// }
|
||||
// }
|
||||
|
||||
// // objectchild is not ready
|
||||
// return true;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// return false;
|
||||
// }
|
||||
// //bool check_object_for_mesh_loading(LLViewerObject* objectp)
|
||||
//{
|
||||
// if (!objectp || !objectp->getVolume())
|
||||
// {
|
||||
// return false;
|
||||
// }
|
||||
// LLVolume* volp = objectp->getVolume();
|
||||
// const LLUUID& mesh_id = volp->getParams().getSculptID();
|
||||
// if (mesh_id.isNull())
|
||||
// {
|
||||
// // No mesh nor skin info needed
|
||||
// return false;
|
||||
// }
|
||||
//
|
||||
// if (volp->isMeshAssetUnavaliable())
|
||||
// {
|
||||
// // Mesh failed to load, do not expect it
|
||||
// return false;
|
||||
// }
|
||||
//
|
||||
// if (!objectp->mDrawable)
|
||||
// {
|
||||
// return false;
|
||||
// }
|
||||
//
|
||||
// LLVOVolume* pvobj = objectp->mDrawable->getVOVolume();
|
||||
// if (pvobj)
|
||||
// {
|
||||
// if (!pvobj->isMesh())
|
||||
// {
|
||||
// // Not a mesh
|
||||
// return false;
|
||||
// }
|
||||
//
|
||||
// if (!volp->isMeshAssetLoaded())
|
||||
// {
|
||||
// // Waiting for mesh
|
||||
// return true;
|
||||
// }
|
||||
//
|
||||
// const LLMeshSkinInfo* skin_data = pvobj->getSkinInfo();
|
||||
// if (skin_data)
|
||||
// {
|
||||
// // Skin info present, done
|
||||
// return false;
|
||||
// }
|
||||
//
|
||||
// if (pvobj->isSkinInfoUnavaliable())
|
||||
// {
|
||||
// // Load failed or info not present, don't expect it
|
||||
// return false;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// // object is not ready
|
||||
// return true;
|
||||
//}
|
||||
//
|
||||
//bool LLVOAvatar::hasPendingAttachedMeshes()
|
||||
//{
|
||||
// for (attachment_map_t::iterator iter = mAttachmentPoints.begin();
|
||||
// iter != mAttachmentPoints.end();
|
||||
// ++iter)
|
||||
// {
|
||||
// LLViewerJointAttachment* attachment = iter->second;
|
||||
// if (attachment)
|
||||
// {
|
||||
// for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin();
|
||||
// attachment_iter != attachment->mAttachedObjects.end();
|
||||
// ++attachment_iter)
|
||||
// {
|
||||
// LLViewerObject* objectp = attachment_iter->get();
|
||||
// if (objectp && !objectp->isDead())
|
||||
// {
|
||||
// if (check_object_for_mesh_loading(objectp))
|
||||
// {
|
||||
// return true;
|
||||
// }
|
||||
// LLViewerObject::const_child_list_t& child_list = objectp->getChildren();
|
||||
// for (LLViewerObject::child_list_t::const_iterator iter1 = child_list.begin();
|
||||
// iter1 != child_list.end(); ++iter1)
|
||||
// {
|
||||
// LLViewerObject* objectchild = *iter1;
|
||||
// if (check_object_for_mesh_loading(objectchild))
|
||||
// {
|
||||
// return true;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// return false;
|
||||
//}
|
||||
// </FS:Beq>
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
|
@ -9276,7 +9297,7 @@ bool LLVOAvatar::updateIsFullyLoaded()
|
|||
);
|
||||
|
||||
// compare amount of attachments to one reported by simulator
|
||||
if (!loading && !isSelf() && rez_status < 4 && mLastCloudAttachmentCount < mSimAttachments.size())
|
||||
if (!isSelf() && mLastCloudAttachmentCount < mSimAttachments.size() && mSimAttachments.size() > 0)
|
||||
{
|
||||
S32 attachment_count = getAttachmentCount();
|
||||
if (mLastCloudAttachmentCount != attachment_count)
|
||||
|
|
@ -9294,6 +9315,11 @@ bool LLVOAvatar::updateIsFullyLoaded()
|
|||
// waiting
|
||||
loading = true;
|
||||
}
|
||||
else if (!loading)
|
||||
{
|
||||
// for hasFirstFullAttachmentData
|
||||
mLastCloudAttachmentCount = (S32)mSimAttachments.size();
|
||||
}
|
||||
}
|
||||
}
|
||||
updateRezzedStatusTimers(rez_status);
|
||||
|
|
@ -9407,6 +9433,12 @@ bool LLVOAvatar::isFullyLoaded() const
|
|||
return (mRenderUnloadedAvatar || mFullyLoaded);
|
||||
}
|
||||
|
||||
bool LLVOAvatar::hasFirstFullAttachmentData() const
|
||||
{
|
||||
return !mFirstFullyVisible // Avatar is fully visible, have all data
|
||||
|| mLastCloudAttachmentCount >= (S32)mSimAttachments.size();
|
||||
}
|
||||
|
||||
bool LLVOAvatar::isTooComplex() const
|
||||
{
|
||||
bool too_complex;
|
||||
|
|
|
|||
|
|
@ -403,6 +403,7 @@ public:
|
|||
//--------------------------------------------------------------------
|
||||
public:
|
||||
bool isFullyLoaded() const;
|
||||
bool hasFirstFullAttachmentData() const;
|
||||
F32 getFirstDecloudTime() const {return mFirstDecloudTime;}
|
||||
|
||||
// check and return current state relative to limits
|
||||
|
|
|
|||
|
|
@ -100,8 +100,16 @@ LLSkyTex::LLSkyTex() :
|
|||
void LLSkyTex::init(bool isShiny)
|
||||
{
|
||||
mIsShiny = isShiny;
|
||||
mSkyData = new LLColor4[(U32)(SKYTEX_RESOLUTION * SKYTEX_RESOLUTION)];
|
||||
mSkyDirs = new LLVector3[(U32)(SKYTEX_RESOLUTION * SKYTEX_RESOLUTION)];
|
||||
try
|
||||
{
|
||||
mSkyData = new LLColor4[(U32)(SKYTEX_RESOLUTION * SKYTEX_RESOLUTION)];
|
||||
mSkyDirs = new LLVector3[(U32)(SKYTEX_RESOLUTION * SKYTEX_RESOLUTION)];
|
||||
}
|
||||
catch (std::bad_alloc&)
|
||||
{
|
||||
LLError::LLUserWarningMsg::showOutOfMemory();
|
||||
LL_ERRS() << "Failed to allocate memory for sky texture data" << LL_ENDL;
|
||||
}
|
||||
|
||||
for (S32 i = 0; i < 2; ++i)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1545,7 +1545,18 @@ void LLPipeline::createLUTBuffers()
|
|||
{
|
||||
U32 lightResX = gSavedSettings.getU32("RenderSpecularResX");
|
||||
U32 lightResY = gSavedSettings.getU32("RenderSpecularResY");
|
||||
F32* ls = new F32[lightResX*lightResY];
|
||||
F32* ls = nullptr;
|
||||
try
|
||||
{
|
||||
ls = new F32[lightResX*lightResY];
|
||||
}
|
||||
catch (std::bad_alloc&)
|
||||
{
|
||||
LLError::LLUserWarningMsg::showOutOfMemory();
|
||||
// might be better to set the error into mFatalMessage and rethrow
|
||||
LL_ERRS() << "Bad memory allocation in createLUTBuffers! lightResX: "
|
||||
<< lightResX << " lightResY: " << lightResY << LL_ENDL;
|
||||
}
|
||||
F32 specExp = gSavedSettings.getF32("RenderSpecularExponent");
|
||||
// Calculate the (normalized) blinn-phong specular lookup texture. (with a few tweaks)
|
||||
for (U32 y = 0; y < lightResY; ++y)
|
||||
|
|
@ -7412,7 +7423,7 @@ void LLPipeline::tonemap(LLRenderTarget* src, LLRenderTarget* dst)
|
|||
|
||||
LLSettingsSky::ptr_t psky = LLEnvironment::instance().getCurrentSky();
|
||||
|
||||
bool no_post = gSnapshotNoPost || psky->getReflectionProbeAmbiance(should_auto_adjust) == 0.f || (buildNoPost && gFloaterTools->isAvailable());
|
||||
bool no_post = gSnapshotNoPost || psky->getReflectionProbeAmbiance(should_auto_adjust) == 0.f || (buildNoPost && gFloaterTools && gFloaterTools->isAvailable());
|
||||
LLGLSLShader& shader = no_post ? gNoPostTonemapProgram : gDeferredPostTonemapProgram;
|
||||
|
||||
shader.bind();
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ teksturer
|
|||
teksturer
|
||||
</text>
|
||||
<button label="Vis IDs på skærm" label_selected="Dump" name="Dump"/>
|
||||
<panel name="scroll_content_panel">
|
||||
<panel name="scroll_content_panel2">
|
||||
<texture_picker label="Hår" name="hair-baked"/>
|
||||
<texture_picker label="Hår" name="hair_grain"/>
|
||||
<texture_picker label="Alpha - hår" name="hair_alpha"/>
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ Texturen
|
|||
Texturen
|
||||
</text>
|
||||
<button label="IDs an Konsole ausgeben" label_selected="Abladen" name="Dump"/>
|
||||
<panel name="scroll_content_panel">
|
||||
<panel name="scroll_content_panel2">
|
||||
<texture_picker label="Haare" name="hair-baked"/>
|
||||
<texture_picker label="Haare" name="hair_grain"/>
|
||||
<texture_picker label="Alpha: Haare" name="hair_alpha"/>
|
||||
|
|
|
|||
|
|
@ -71,13 +71,13 @@ Textures
|
|||
width="150" />
|
||||
|
||||
<panel
|
||||
name="scroll_content_panel"
|
||||
name="scroll_content_panel2"
|
||||
follows="left|top"
|
||||
min_height="300"
|
||||
layout="topleft"
|
||||
top="43"
|
||||
top="60"
|
||||
background_visible="false"
|
||||
height="930"
|
||||
height="1113"
|
||||
left="0"
|
||||
width="1230">
|
||||
|
||||
|
|
@ -87,7 +87,7 @@ Textures
|
|||
layout="topleft"
|
||||
left="10"
|
||||
name="hair-baked"
|
||||
top="17"
|
||||
top="3"
|
||||
width="92" />
|
||||
<texture_picker
|
||||
height="103"
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
<text name="label">Texturas obtenidas mediante bake</text>
|
||||
<text name="composite_label">Texturas compuestas</text>
|
||||
<button label="Volcar IDs a la consola" label_selected="Volcado" name="Dump"/>
|
||||
<panel name="scroll_content_panel">
|
||||
<panel name="scroll_content_panel2">
|
||||
<texture_picker label="Pelo" name="hair-baked"/>
|
||||
<texture_picker label="Pelo" name="hair_grain"/>
|
||||
<texture_picker label="Alfa del pelo" name="hair_alpha"/>
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@
|
|||
Textures composites
|
||||
</text>
|
||||
<button label="Sauvegarder les IDs dans la console" label_selected="Sauvegarder" name="Dump"/>
|
||||
<panel name="scroll_content_panel">
|
||||
<panel name="scroll_content_panel2">
|
||||
<texture_picker label="Cheveux" name="hair-baked"/>
|
||||
<texture_picker label="Cheveux" name="hair_grain"/>
|
||||
<texture_picker label="Alpha cheveux" name="hair_alpha"/>
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ bake
|
|||
composite
|
||||
</text>
|
||||
<button label="Dump degli ID in console" label_selected="Dump" name="Dump"/>
|
||||
<panel name="scroll_content_panel">
|
||||
<panel name="scroll_content_panel2">
|
||||
<texture_picker label="Capelli" name="hair-baked"/>
|
||||
<texture_picker label="Capelli" name="hair_grain"/>
|
||||
<texture_picker label="Alfa capelli" name="hair_alpha"/>
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@
|
|||
<text name="composite_label">合成
|
||||
テクスチャ</text>
|
||||
<button label="ID をコンソールにダンプ" label_selected="ダンプ" name="Dump"/>
|
||||
<panel name="scroll_content_panel">
|
||||
<panel name="scroll_content_panel2">
|
||||
<texture_picker label="髪" name="hair-baked"/>
|
||||
<texture_picker label="髪" name="hair_grain"/>
|
||||
<texture_picker label="髪のアルファ" name="hair_alpha"/>
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ prerenderowane
|
|||
kompozytowe
|
||||
</text>
|
||||
<button label="Zrzuć ID do Konsoli" label_selected="Zrzuć" name="Dump"/>
|
||||
<panel name="scroll_content_panel">
|
||||
<panel name="scroll_content_panel2">
|
||||
<texture_picker label="Włosy" name="hair-baked"/>
|
||||
<texture_picker label="Włosy" name="hair_grain"/>
|
||||
<texture_picker label="Alpha włosów" name="hair_alpha"/>
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ Texturas</text>
|
|||
<text name="composite_label">Compósito:
|
||||
Texturas</text>
|
||||
<button label="Enviar IDs para painel" label_selected="Dump" name="Dump"/>
|
||||
<panel name="scroll_content_panel">
|
||||
<panel name="scroll_content_panel2">
|
||||
<texture_picker label="Cabelo" name="hair-baked"/>
|
||||
<texture_picker label="Cabelo" name="hair_grain"/>
|
||||
<texture_picker label="Cabelo alpha" name="hair_alpha"/>
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@
|
|||
Текстуры
|
||||
</text>
|
||||
<button label="Вывод ID на консоль" label_selected="Вывод" name="Dump"/>
|
||||
<panel name="scroll_content_panel">
|
||||
<panel name="scroll_content_panel2">
|
||||
<texture_picker label="Волосы" name="hair-baked"/>
|
||||
<texture_picker label="Волосы" name="hair_grain"/>
|
||||
<texture_picker label="Альфа волос" name="hair_alpha"/>
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ Dokular
|
|||
Dokular
|
||||
</text>
|
||||
<button label="Kimlikleri Konsole Yığ" label_selected="Yığ" name="Dump"/>
|
||||
<panel name="scroll_content_panel">
|
||||
<panel name="scroll_content_panel2">
|
||||
<texture_picker label="Saç" name="hair-baked"/>
|
||||
<texture_picker label="Saç" name="hair_grain"/>
|
||||
<texture_picker label="Saç Alfası" name="hair_alpha"/>
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@
|
|||
混合紋理
|
||||
</text>
|
||||
<button label="轉儲 ID 到控制台" label_selected="轉儲" name="Dump" />
|
||||
<panel name="scroll_content_panel">
|
||||
<panel name="scroll_content_panel2">
|
||||
<texture_picker label="頭髮" name="hair-baked" />
|
||||
<texture_picker label="頭髮" name="hair_grain" />
|
||||
<texture_picker label="頭髮Alpha" name="hair_alpha" />
|
||||
|
|
|
|||
Loading…
Reference in New Issue