Merge branch 'DRTVWR-600-maint-A' of https://github.com/secondlife/viewer
# Conflicts: # indra/llimage/llimage.cpp # indra/llimage/llimage.h # indra/llkdu/llimagej2ckdu.cpp # indra/newview/app_settings/settings.xml # indra/newview/llfavoritesbar.cpp # indra/newview/llfloaterpreference.cpp # indra/newview/llfloaterpreference.h # scripts/messages/message_template.msg.sha1master
commit
a831237e29
|
|
@ -5,7 +5,7 @@
|
|||
#
|
||||
# Platform variables:
|
||||
#
|
||||
# DARWIN - Mac OS X
|
||||
# DARWIN - macOS
|
||||
# LINUX - Linux
|
||||
# WINDOWS - Windows
|
||||
|
||||
|
|
|
|||
|
|
@ -116,7 +116,7 @@ BASE_ARGUMENTS=[
|
|||
dict(name='build', description='Build directory.', default=DEFAULT_SRCTREE),
|
||||
dict(name='buildtype', description='Build type (i.e. Debug, Release, RelWithDebInfo).', default=None),
|
||||
dict(name='bundleid',
|
||||
description="""The Mac OS X Bundle identifier.""",
|
||||
description="""The macOS Bundle identifier.""",
|
||||
default="com.secondlife.indra.viewer"),
|
||||
dict(name='channel',
|
||||
description="""The channel to use for updates, packaging, settings name, etc.""",
|
||||
|
|
@ -146,7 +146,7 @@ BASE_ARGUMENTS=[
|
|||
dict(name='signature',
|
||||
description="""This specifies an identity to sign the viewer with, if any.
|
||||
If no value is supplied, the default signature will be used, if any. Currently
|
||||
only used on Mac OS X.""",
|
||||
only used on macOS.""",
|
||||
default=None),
|
||||
dict(name='source',
|
||||
description='Source directory.',
|
||||
|
|
|
|||
|
|
@ -247,7 +247,7 @@ public:
|
|||
//--------------------------------------------------------------------
|
||||
public:
|
||||
void addMaskedMorph(LLAvatarAppearanceDefines::EBakedTextureIndex index, LLVisualParam* morph_target, BOOL invert, std::string layer);
|
||||
virtual void applyMorphMask(U8* tex_data, S32 width, S32 height, S32 num_components, LLAvatarAppearanceDefines::EBakedTextureIndex index = LLAvatarAppearanceDefines::BAKED_NUM_INDICES) = 0;
|
||||
virtual void applyMorphMask(const U8* tex_data, S32 width, S32 height, S32 num_components, LLAvatarAppearanceDefines::EBakedTextureIndex index = LLAvatarAppearanceDefines::BAKED_NUM_INDICES) = 0;
|
||||
|
||||
/** Rendering
|
||||
** **
|
||||
|
|
|
|||
|
|
@ -661,7 +661,7 @@ void LLPolyMorphTarget::apply( ESex avatar_sex )
|
|||
//-----------------------------------------------------------------------------
|
||||
// applyMask()
|
||||
//-----------------------------------------------------------------------------
|
||||
void LLPolyMorphTarget::applyMask(U8 *maskTextureData, S32 width, S32 height, S32 num_components, BOOL invert)
|
||||
void LLPolyMorphTarget::applyMask(const U8 *maskTextureData, S32 width, S32 height, S32 num_components, BOOL invert)
|
||||
{
|
||||
LLVector4a *clothing_weights = getInfo()->mIsClothingMorph ? mMesh->getWritableClothingWeights() : NULL;
|
||||
|
||||
|
|
@ -782,7 +782,7 @@ LLPolyVertexMask::~LLPolyVertexMask()
|
|||
//-----------------------------------------------------------------------------
|
||||
// generateMask()
|
||||
//-----------------------------------------------------------------------------
|
||||
void LLPolyVertexMask::generateMask(U8 *maskTextureData, S32 width, S32 height, S32 num_components, BOOL invert, LLVector4a *clothing_weights)
|
||||
void LLPolyVertexMask::generateMask(const U8 *maskTextureData, S32 width, S32 height, S32 num_components, BOOL invert, LLVector4a *clothing_weights)
|
||||
{
|
||||
// RN debug output that uses Image Debugger (http://www.cs.unc.edu/~baxter/projects/imdebug/)
|
||||
// BOOL debugImg = FALSE;
|
||||
|
|
|
|||
|
|
@ -84,7 +84,7 @@ public:
|
|||
LLPolyVertexMask(const LLPolyVertexMask& pOther);
|
||||
~LLPolyVertexMask();
|
||||
|
||||
void generateMask(U8 *maskData, S32 width, S32 height, S32 num_components, BOOL invert, LLVector4a *clothing_weights);
|
||||
void generateMask(const U8 *maskData, S32 width, S32 height, S32 num_components, BOOL invert, LLVector4a *clothing_weights);
|
||||
F32* getMorphMaskWeights();
|
||||
|
||||
|
||||
|
|
@ -170,7 +170,7 @@ public:
|
|||
/*virtual*/ const LLVector4a* getFirstDistortion(U32 *index, LLPolyMesh **poly_mesh);
|
||||
/*virtual*/ const LLVector4a* getNextDistortion(U32 *index, LLPolyMesh **poly_mesh);
|
||||
|
||||
void applyMask(U8 *maskData, S32 width, S32 height, S32 num_components, BOOL invert);
|
||||
void applyMask(const U8 *maskData, S32 width, S32 height, S32 num_components, BOOL invert);
|
||||
void addPendingMorphMask() { mNumMorphMasksPending++; }
|
||||
|
||||
void applyVolumeChanges(F32 delta_weight); // SL-315 - for resetSkeleton()
|
||||
|
|
|
|||
|
|
@ -535,7 +535,7 @@ void LLTexLayerSet::renderAlphaMaskTextures(S32 x, S32 y, S32 width, S32 height,
|
|||
gGL.setSceneBlendType(LLRender::BT_ALPHA);
|
||||
}
|
||||
|
||||
void LLTexLayerSet::applyMorphMask(U8* tex_data, S32 width, S32 height, S32 num_components)
|
||||
void LLTexLayerSet::applyMorphMask(const U8* tex_data, S32 width, S32 height, S32 num_components)
|
||||
{
|
||||
mAvatarAppearance->applyMorphMask(tex_data, width, height, num_components, mBakedTexIndex);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -203,7 +203,7 @@ public:
|
|||
void renderAlphaMaskTextures(S32 x, S32 y, S32 width, S32 height, LLRenderTarget* bound_target = nullptr, bool forceClear = false);
|
||||
|
||||
BOOL isBodyRegion(const std::string& region) const;
|
||||
void applyMorphMask(U8* tex_data, S32 width, S32 height, S32 num_components);
|
||||
void applyMorphMask(const U8* tex_data, S32 width, S32 height, S32 num_components);
|
||||
BOOL isMorphValid() const;
|
||||
virtual void requestUpdate() = 0;
|
||||
void invalidateMorphMasks();
|
||||
|
|
|
|||
|
|
@ -581,7 +581,7 @@ S32 LLAPRFile::readEx(const std::string& filename, void *buf, S32 offset, S32 nb
|
|||
}
|
||||
|
||||
//static
|
||||
S32 LLAPRFile::writeEx(const std::string& filename, void *buf, S32 offset, S32 nbytes, LLVolatileAPRPool* pool)
|
||||
S32 LLAPRFile::writeEx(const std::string& filename, const void *buf, S32 offset, S32 nbytes, LLVolatileAPRPool* pool)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED;
|
||||
apr_int32_t flags = APR_CREATE|APR_WRITE|APR_BINARY;
|
||||
|
|
|
|||
|
|
@ -199,7 +199,7 @@ public:
|
|||
|
||||
// Returns bytes read/written, 0 if read/write fails:
|
||||
static S32 readEx(const std::string& filename, void *buf, S32 offset, S32 nbytes, LLVolatileAPRPool* pool = NULL);
|
||||
static S32 writeEx(const std::string& filename, void *buf, S32 offset, S32 nbytes, LLVolatileAPRPool* pool = NULL); // offset<0 means append
|
||||
static S32 writeEx(const std::string& filename, const void *buf, S32 offset, S32 nbytes, LLVolatileAPRPool* pool = NULL); // offset<0 means append
|
||||
//*******************************************************************************************************************************
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -711,7 +711,7 @@ namespace
|
|||
bool shouldLogToStderr()
|
||||
{
|
||||
#if LL_DARWIN
|
||||
// On Mac OS X, stderr from apps launched from the Finder goes to the
|
||||
// On macOS, stderr from apps launched from the Finder goes to the
|
||||
// console log. It's generally considered bad form to spam too much
|
||||
// there. That scenario can be detected by noticing that stderr is a
|
||||
// character device (S_IFCHR).
|
||||
|
|
|
|||
|
|
@ -29,19 +29,20 @@
|
|||
#include "llthread.h"
|
||||
#include "lltimer.h"
|
||||
|
||||
//============================================================================
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
//
|
||||
// LLMutex
|
||||
//
|
||||
LLMutex::LLMutex() :
|
||||
mCount(0)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
LLMutex::~LLMutex()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void LLMutex::lock()
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD
|
||||
|
|
@ -112,7 +113,7 @@ LLThread::id_t LLMutex::lockingThread() const
|
|||
bool LLMutex::trylock()
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD
|
||||
if(isSelfLocked())
|
||||
if (isSelfLocked())
|
||||
{ //redundant lock
|
||||
mCount++;
|
||||
return true;
|
||||
|
|
@ -135,19 +136,194 @@ bool LLMutex::trylock()
|
|||
return true;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
//
|
||||
// LLSharedMutex
|
||||
//
|
||||
LLSharedMutex::LLSharedMutex()
|
||||
: mLockingThreads(2) // Reserve 2 slots in the map hash table
|
||||
, mIsShared(false)
|
||||
{
|
||||
}
|
||||
|
||||
bool LLSharedMutex::isLocked() const
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD
|
||||
std::lock_guard<std::mutex> lock(mLockMutex);
|
||||
|
||||
return !mLockingThreads.empty();
|
||||
}
|
||||
|
||||
bool LLSharedMutex::isThreadLocked() const
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD
|
||||
LLThread::id_t current_thread = LLThread::currentID();
|
||||
std::lock_guard<std::mutex> lock(mLockMutex);
|
||||
|
||||
const_iterator it = mLockingThreads.find(current_thread);
|
||||
return it != mLockingThreads.end();
|
||||
}
|
||||
|
||||
void LLSharedMutex::lockShared()
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD
|
||||
LLThread::id_t current_thread = LLThread::currentID();
|
||||
|
||||
mLockMutex.lock();
|
||||
iterator it = mLockingThreads.find(current_thread);
|
||||
if (it != mLockingThreads.end())
|
||||
{
|
||||
it->second++;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Acquire the mutex immediately if the mutex is not locked exclusively
|
||||
// or enter a locking state if the mutex is already locked exclusively
|
||||
mLockMutex.unlock();
|
||||
mSharedMutex.lock_shared();
|
||||
mLockMutex.lock();
|
||||
// Continue after acquiring the mutex
|
||||
mLockingThreads.emplace(std::make_pair(current_thread, 1));
|
||||
mIsShared = true;
|
||||
}
|
||||
mLockMutex.unlock();
|
||||
}
|
||||
|
||||
void LLSharedMutex::lockExclusive()
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD
|
||||
LLThread::id_t current_thread = LLThread::currentID();
|
||||
|
||||
mLockMutex.lock();
|
||||
iterator it = mLockingThreads.find(current_thread);
|
||||
if (it != mLockingThreads.end())
|
||||
{
|
||||
if (mIsShared)
|
||||
{
|
||||
// The mutex is already locked in the current thread
|
||||
// but this lock is SHARED (not EXCLISIVE)
|
||||
// We can't lock it again, the lock stays shared
|
||||
// This can lead to a collision (theoretically)
|
||||
llassert_always(!"The current thread is already locked SHARED and can't be locked EXCLUSIVE");
|
||||
}
|
||||
it->second++;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Acquire the mutex immediately if mLockingThreads is empty
|
||||
// or enter a locking state if mLockingThreads is not empty
|
||||
mLockMutex.unlock();
|
||||
mSharedMutex.lock();
|
||||
mLockMutex.lock();
|
||||
// Continue after acquiring the mutex (and possible quitting the locking state)
|
||||
mLockingThreads.emplace(std::make_pair(current_thread, 1));
|
||||
mIsShared = false;
|
||||
}
|
||||
mLockMutex.unlock();
|
||||
}
|
||||
|
||||
bool LLSharedMutex::trylockShared()
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD
|
||||
LLThread::id_t current_thread = LLThread::currentID();
|
||||
std::lock_guard<std::mutex> lock(mLockMutex);
|
||||
|
||||
iterator it = mLockingThreads.find(current_thread);
|
||||
if (it != mLockingThreads.end())
|
||||
{
|
||||
it->second++;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!mSharedMutex.try_lock_shared())
|
||||
return false;
|
||||
|
||||
mLockingThreads.emplace(std::make_pair(current_thread, 1));
|
||||
mIsShared = true;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool LLSharedMutex::trylockExclusive()
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD
|
||||
LLThread::id_t current_thread = LLThread::currentID();
|
||||
std::lock_guard<std::mutex> lock(mLockMutex);
|
||||
|
||||
if (mLockingThreads.size() == 1 && mLockingThreads.begin()->first == current_thread)
|
||||
{
|
||||
mLockingThreads.begin()->second++;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!mSharedMutex.try_lock())
|
||||
return false;
|
||||
|
||||
mLockingThreads.emplace(std::make_pair(current_thread, 1));
|
||||
mIsShared = false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void LLSharedMutex::unlockShared()
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD
|
||||
LLThread::id_t current_thread = LLThread::currentID();
|
||||
std::lock_guard<std::mutex> lock(mLockMutex);
|
||||
|
||||
iterator it = mLockingThreads.find(current_thread);
|
||||
if (it != mLockingThreads.end())
|
||||
{
|
||||
if (it->second > 1)
|
||||
{
|
||||
it->second--;
|
||||
}
|
||||
else
|
||||
{
|
||||
mLockingThreads.erase(it);
|
||||
mSharedMutex.unlock_shared();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LLSharedMutex::unlockExclusive()
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD
|
||||
LLThread::id_t current_thread = LLThread::currentID();
|
||||
std::lock_guard<std::mutex> lock(mLockMutex);
|
||||
|
||||
iterator it = mLockingThreads.find(current_thread);
|
||||
if (it != mLockingThreads.end())
|
||||
{
|
||||
if (it->second > 1)
|
||||
{
|
||||
it->second--;
|
||||
}
|
||||
else
|
||||
{
|
||||
mLockingThreads.erase(it);
|
||||
mSharedMutex.unlock();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
//
|
||||
// LLCondition
|
||||
//
|
||||
LLCondition::LLCondition() :
|
||||
LLMutex()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
LLCondition::~LLCondition()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void LLCondition::wait()
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD
|
||||
|
|
@ -168,7 +344,10 @@ void LLCondition::broadcast()
|
|||
}
|
||||
|
||||
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
//
|
||||
// LLMutexTrylock
|
||||
//
|
||||
LLMutexTrylock::LLMutexTrylock(LLMutex* mutex)
|
||||
: mMutex(mutex),
|
||||
mLocked(false)
|
||||
|
|
|
|||
|
|
@ -32,6 +32,8 @@
|
|||
#include <boost/noncopyable.hpp>
|
||||
|
||||
#include "mutex.h"
|
||||
#include <shared_mutex>
|
||||
#include <unordered_map>
|
||||
#include <condition_variable>
|
||||
|
||||
//============================================================================
|
||||
|
|
@ -66,6 +68,45 @@ protected:
|
|||
#endif
|
||||
};
|
||||
|
||||
//============================================================================
|
||||
|
||||
class LL_COMMON_API LLSharedMutex
|
||||
{
|
||||
public:
|
||||
LLSharedMutex();
|
||||
|
||||
bool isLocked() const;
|
||||
bool isThreadLocked() const;
|
||||
bool isShared() const { return mIsShared; }
|
||||
|
||||
void lockShared();
|
||||
void lockExclusive();
|
||||
template<bool SHARED> void lock();
|
||||
template<> void lock<true>() { lockShared(); }
|
||||
template<> void lock<false>() { lockExclusive(); }
|
||||
|
||||
bool trylockShared();
|
||||
bool trylockExclusive();
|
||||
template<bool SHARED> bool trylock();
|
||||
template<> bool trylock<true>() { return trylockShared(); }
|
||||
template<> bool trylock<false>() { return trylockExclusive(); }
|
||||
|
||||
void unlockShared();
|
||||
void unlockExclusive();
|
||||
template<bool SHARED> void unlock();
|
||||
template<> void unlock<true>() { unlockShared(); }
|
||||
template<> void unlock<false>() { unlockExclusive(); }
|
||||
|
||||
private:
|
||||
std::shared_mutex mSharedMutex;
|
||||
mutable std::mutex mLockMutex;
|
||||
std::unordered_map<LLThread::id_t, U32> mLockingThreads;
|
||||
bool mIsShared;
|
||||
|
||||
using iterator = std::unordered_map<LLThread::id_t, U32>::iterator;
|
||||
using const_iterator = std::unordered_map<LLThread::id_t, U32>::const_iterator;
|
||||
};
|
||||
|
||||
// Actually a condition/mutex pair (since each condition needs to be associated with a mutex).
|
||||
class LL_COMMON_API LLCondition : public LLMutex
|
||||
{
|
||||
|
|
@ -81,27 +122,57 @@ protected:
|
|||
std::condition_variable mCond;
|
||||
};
|
||||
|
||||
//============================================================================
|
||||
|
||||
class LLMutexLock
|
||||
{
|
||||
public:
|
||||
LLMutexLock(LLMutex* mutex)
|
||||
{
|
||||
mMutex = mutex;
|
||||
|
||||
if(mMutex)
|
||||
|
||||
if (mMutex)
|
||||
mMutex->lock();
|
||||
}
|
||||
|
||||
~LLMutexLock()
|
||||
{
|
||||
if(mMutex)
|
||||
if (mMutex)
|
||||
mMutex->unlock();
|
||||
}
|
||||
|
||||
private:
|
||||
LLMutex* mMutex;
|
||||
};
|
||||
|
||||
//============================================================================
|
||||
|
||||
template<bool SHARED>
|
||||
class LLSharedMutexLockTemplate
|
||||
{
|
||||
public:
|
||||
LLSharedMutexLockTemplate(LLSharedMutex* mutex)
|
||||
: mSharedMutex(mutex)
|
||||
{
|
||||
if (mSharedMutex)
|
||||
mSharedMutex->lock<SHARED>();
|
||||
}
|
||||
|
||||
~LLSharedMutexLockTemplate()
|
||||
{
|
||||
if (mSharedMutex)
|
||||
mSharedMutex->unlock<SHARED>();
|
||||
}
|
||||
|
||||
private:
|
||||
LLSharedMutex* mSharedMutex;
|
||||
};
|
||||
|
||||
using LLSharedMutexLock = LLSharedMutexLockTemplate<true>;
|
||||
using LLExclusiveMutexLock = LLSharedMutexLockTemplate<false>;
|
||||
|
||||
//============================================================================
|
||||
|
||||
// Scoped locking class similar in function to LLMutexLock but uses
|
||||
// the trylock() method to conditionally acquire lock without
|
||||
// blocking. Caller resolves the resulting condition by calling
|
||||
|
|
@ -127,6 +198,8 @@ private:
|
|||
bool mLocked;
|
||||
};
|
||||
|
||||
//============================================================================
|
||||
|
||||
/**
|
||||
* @class LLScopedLock
|
||||
* @brief Small class to help lock and unlock mutexes.
|
||||
|
|
|
|||
|
|
@ -280,9 +280,9 @@ LLOSInfo::LLOSInfo() :
|
|||
#elif LL_DARWIN
|
||||
|
||||
// Initialize mOSStringSimple to something like:
|
||||
// "Mac OS X 10.6.7"
|
||||
// "macOS 10.13.1"
|
||||
{
|
||||
const char * DARWIN_PRODUCT_NAME = "Mac OS X";
|
||||
const char * DARWIN_PRODUCT_NAME = "macOS";
|
||||
|
||||
int64_t major_version, minor_version, bugfix_version = 0;
|
||||
|
||||
|
|
@ -305,7 +305,7 @@ LLOSInfo::LLOSInfo() :
|
|||
}
|
||||
|
||||
// Initialize mOSString to something like:
|
||||
// "Mac OS X 10.6.7 Darwin Kernel Version 10.7.0: Sat Jan 29 15:17:16 PST 2011; root:xnu-1504.9.37~1/RELEASE_I386 i386"
|
||||
// "macOS 10.13.1 Darwin Kernel Version 10.7.0: Sat Jan 29 15:17:16 PST 2011; root:xnu-1504.9.37~1/RELEASE_I386 i386"
|
||||
struct utsname un;
|
||||
if(uname(&un) != -1)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -27,38 +27,12 @@
|
|||
#import "llsys_objc.h"
|
||||
#import <AppKit/AppKit.h>
|
||||
|
||||
static auto intAtStringIndex(NSArray *array, int index)
|
||||
{
|
||||
return [(NSString *)[array objectAtIndex:index] integerValue];
|
||||
}
|
||||
|
||||
bool LLGetDarwinOSInfo(int64_t &major, int64_t &minor, int64_t &patch)
|
||||
{
|
||||
if (NSAppKitVersionNumber > NSAppKitVersionNumber10_8)
|
||||
{
|
||||
NSOperatingSystemVersion osVersion = [[NSProcessInfo processInfo] operatingSystemVersion];
|
||||
major = osVersion.majorVersion;
|
||||
minor = osVersion.minorVersion;
|
||||
patch = osVersion.patchVersion;
|
||||
}
|
||||
else
|
||||
{
|
||||
NSString* versionString = [[NSDictionary dictionaryWithContentsOfFile:
|
||||
@"/System/Library/CoreServices/SystemVersion.plist"] objectForKey:@"ProductVersion"];
|
||||
NSArray* versions = [versionString componentsSeparatedByString:@"."];
|
||||
NSUInteger count = [versions count];
|
||||
if (count > 0)
|
||||
{
|
||||
major = intAtStringIndex(versions, 0);
|
||||
if (count > 1)
|
||||
{
|
||||
minor = intAtStringIndex(versions, 1);
|
||||
if (count > 2)
|
||||
{
|
||||
patch = intAtStringIndex(versions, 2);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -512,7 +512,7 @@ S32 LLUUID::getNodeID(unsigned char* node_id)
|
|||
}
|
||||
|
||||
#elif LL_DARWIN
|
||||
// Mac OS X version of the UUID generation code...
|
||||
// macOS version of the UUID generation code...
|
||||
/*
|
||||
* Get an ethernet hardware address, if we can find it...
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
* @file lldir_mac.cpp
|
||||
* @brief Implementation of directory utilities for Mac OS X
|
||||
* @brief Implementation of directory utilities for macOS
|
||||
*
|
||||
* $LicenseInfo:firstyear=2002&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
* @file lldir_mac.h
|
||||
* @brief Definition of directory utilities class for Mac OS X
|
||||
* @brief Definition of directory utilities class for macOS
|
||||
*
|
||||
* $LicenseInfo:firstyear=2000&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
* @file lldir_utils_objc.h
|
||||
* @brief Definition of directory utilities class for Mac OS X
|
||||
* @brief Definition of directory utilities class for macOS
|
||||
*
|
||||
* $LicenseInfo:firstyear=2020&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
* @file lldir_utils_objc.mm
|
||||
* @brief Cocoa implementation of directory utilities for Mac OS X
|
||||
* @brief Cocoa implementation of directory utilities for macOS
|
||||
*
|
||||
* $LicenseInfo:firstyear=2020&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
|
|
|
|||
|
|
@ -614,7 +614,6 @@ const std::string& LLImage::getLastError()
|
|||
//static
|
||||
void LLImage::setLastError(const std::string& message)
|
||||
{
|
||||
LLMutexLock m(sMutex);
|
||||
sLastErrorMessage = message;
|
||||
}
|
||||
|
||||
|
|
@ -759,7 +758,7 @@ U8* LLImageBase::reallocateData(S32 size)
|
|||
return mData;
|
||||
}
|
||||
|
||||
const U8* LLImageBase::getData() const
|
||||
const U8* LLImageBase::getData() const
|
||||
{
|
||||
if(mBadBufferAllocation)
|
||||
{
|
||||
|
|
@ -770,7 +769,7 @@ const U8* LLImageBase::getData() const
|
|||
return mData;
|
||||
} // read only
|
||||
|
||||
U8* LLImageBase::getData()
|
||||
U8* LLImageBase::getData()
|
||||
{
|
||||
if(mBadBufferAllocation)
|
||||
{
|
||||
|
|
@ -783,7 +782,7 @@ U8* LLImageBase::getData()
|
|||
|
||||
bool LLImageBase::isBufferInvalid() const
|
||||
{
|
||||
return mBadBufferAllocation || mData == NULL ;
|
||||
return mBadBufferAllocation || mData == NULL;
|
||||
}
|
||||
|
||||
void LLImageBase::setSize(S32 width, S32 height, S32 ncomponents)
|
||||
|
|
@ -873,6 +872,8 @@ LLImageRaw::~LLImageRaw()
|
|||
// virtual
|
||||
U8* LLImageRaw::allocateData(S32 size)
|
||||
{
|
||||
LLImageDataLock lock(this);
|
||||
|
||||
U8* res = LLImageBase::allocateData(size);
|
||||
return res;
|
||||
}
|
||||
|
|
@ -880,12 +881,16 @@ U8* LLImageRaw::allocateData(S32 size)
|
|||
// virtual
|
||||
U8* LLImageRaw::reallocateData(S32 size)
|
||||
{
|
||||
LLImageDataLock lock(this);
|
||||
|
||||
U8* res = LLImageBase::reallocateData(size);
|
||||
return res;
|
||||
}
|
||||
|
||||
void LLImageRaw::releaseData()
|
||||
{
|
||||
LLImageDataLock lock(this);
|
||||
|
||||
LLImageBase::setSize(0, 0, 0);
|
||||
LLImageBase::setDataAndSize(nullptr, 0);
|
||||
}
|
||||
|
|
@ -893,11 +898,15 @@ void LLImageRaw::releaseData()
|
|||
// virtual
|
||||
void LLImageRaw::deleteData()
|
||||
{
|
||||
LLImageDataLock lock(this);
|
||||
|
||||
LLImageBase::deleteData();
|
||||
}
|
||||
|
||||
void LLImageRaw::setDataAndSize(U8 *data, S32 width, S32 height, S8 components)
|
||||
{
|
||||
{
|
||||
LLImageDataLock lock(this);
|
||||
|
||||
if(data == getData())
|
||||
{
|
||||
return ;
|
||||
|
|
@ -911,6 +920,8 @@ void LLImageRaw::setDataAndSize(U8 *data, S32 width, S32 height, S8 components)
|
|||
|
||||
bool LLImageRaw::resize(U16 width, U16 height, S8 components)
|
||||
{
|
||||
LLImageDataLock lock(this);
|
||||
|
||||
if ((getWidth() == width) && (getHeight() == height) && (getComponents() == components) && !isBufferInvalid())
|
||||
{
|
||||
return true;
|
||||
|
|
@ -926,6 +937,8 @@ bool LLImageRaw::resize(U16 width, U16 height, S8 components)
|
|||
bool LLImageRaw::setSubImage(U32 x_pos, U32 y_pos, U32 width, U32 height,
|
||||
const U8 *data, U32 stride, bool reverse_y)
|
||||
{
|
||||
LLImageDataLock lock(this);
|
||||
|
||||
if (!getData())
|
||||
{
|
||||
return false;
|
||||
|
|
@ -953,6 +966,9 @@ bool LLImageRaw::setSubImage(U32 x_pos, U32 y_pos, U32 width, U32 height,
|
|||
void LLImageRaw::clear(U8 r, U8 g, U8 b, U8 a)
|
||||
{
|
||||
llassert( getComponents() <= 4 );
|
||||
|
||||
LLImageDataLock lock(this);
|
||||
|
||||
// This is fairly bogus, but it'll do for now.
|
||||
if (isBufferInvalid())
|
||||
{
|
||||
|
|
@ -993,6 +1009,8 @@ void LLImageRaw::clear(U8 r, U8 g, U8 b, U8 a)
|
|||
// Reverses the order of the rows in the image
|
||||
void LLImageRaw::verticalFlip()
|
||||
{
|
||||
LLImageDataLock lock(this);
|
||||
|
||||
S32 row_bytes = getWidth() * getComponents();
|
||||
llassert(row_bytes > 0);
|
||||
std::vector<U8> line_buffer(row_bytes);
|
||||
|
|
@ -1010,6 +1028,8 @@ void LLImageRaw::verticalFlip()
|
|||
|
||||
bool LLImageRaw::optimizeAwayAlpha()
|
||||
{
|
||||
LLImageDataLock lock(this);
|
||||
|
||||
if (getComponents() == 4)
|
||||
{
|
||||
U8* data = getData();
|
||||
|
|
@ -1047,6 +1067,8 @@ bool LLImageRaw::optimizeAwayAlpha()
|
|||
|
||||
void LLImageRaw::expandToPowerOfTwo(S32 max_dim, bool scale_image)
|
||||
{
|
||||
LLImageDataLock lock(this);
|
||||
|
||||
// Find new sizes
|
||||
S32 new_width = expandDimToPowerOfTwo(getWidth(), max_dim);
|
||||
S32 new_height = expandDimToPowerOfTwo(getHeight(), max_dim);
|
||||
|
|
@ -1056,6 +1078,8 @@ void LLImageRaw::expandToPowerOfTwo(S32 max_dim, bool scale_image)
|
|||
|
||||
void LLImageRaw::contractToPowerOfTwo(S32 max_dim, bool scale_image)
|
||||
{
|
||||
LLImageDataLock lock(this);
|
||||
|
||||
// Find new sizes
|
||||
S32 new_width = contractDimToPowerOfTwo(getWidth(), MIN_IMAGE_SIZE);
|
||||
S32 new_height = contractDimToPowerOfTwo(getHeight(), MIN_IMAGE_SIZE);
|
||||
|
|
@ -1105,6 +1129,8 @@ S32 LLImageRaw::contractDimToPowerOfTwo(S32 curr_dim, S32 min_dim)
|
|||
|
||||
void LLImageRaw::biasedScaleToPowerOfTwo(S32 max_dim)
|
||||
{
|
||||
LLImageDataLock lock(this);
|
||||
|
||||
// Find new sizes
|
||||
S32 new_width = biasedDimToPowerOfTwo(getWidth(),max_dim);
|
||||
S32 new_height = biasedDimToPowerOfTwo(getHeight(),max_dim);
|
||||
|
|
@ -1112,6 +1138,7 @@ void LLImageRaw::biasedScaleToPowerOfTwo(S32 max_dim)
|
|||
scale( new_width, new_height );
|
||||
}
|
||||
|
||||
// static
|
||||
// Calculates (U8)(255*(a/255.f)*(b/255.f) + 0.5f). Thanks, Jim Blinn!
|
||||
inline U8 LLImageRaw::fastFractionalMult( U8 a, U8 b )
|
||||
{
|
||||
|
|
@ -1120,10 +1147,13 @@ inline U8 LLImageRaw::fastFractionalMult( U8 a, U8 b )
|
|||
}
|
||||
|
||||
|
||||
void LLImageRaw::composite( LLImageRaw* src )
|
||||
void LLImageRaw::composite( const LLImageRaw* src )
|
||||
{
|
||||
LLImageRaw* dst = this; // Just for clarity.
|
||||
|
||||
LLImageDataSharedLock lockIn(src);
|
||||
LLImageDataLock lockOut(this);
|
||||
|
||||
if (!validateSrcAndDst("LLImageRaw::composite", src, dst))
|
||||
{
|
||||
return;
|
||||
|
|
@ -1163,12 +1193,14 @@ void LLImageRaw::composite( LLImageRaw* src )
|
|||
|
||||
|
||||
// Src and dst can be any size. Src has 4 components. Dst has 3 components.
|
||||
void LLImageRaw::compositeScaled4onto3(LLImageRaw* src)
|
||||
void LLImageRaw::compositeScaled4onto3(const LLImageRaw* src)
|
||||
{
|
||||
LL_INFOS() << "compositeScaled4onto3" << LL_ENDL;
|
||||
|
||||
LLImageRaw* dst = this; // Just for clarity.
|
||||
|
||||
LLImageDataLock lock(this);
|
||||
|
||||
llassert( (4 == src->getComponents()) && (3 == dst->getComponents()) );
|
||||
|
||||
S32 temp_data_size = src->getWidth() * dst->getHeight() * src->getComponents();
|
||||
|
|
@ -1190,17 +1222,19 @@ void LLImageRaw::compositeScaled4onto3(LLImageRaw* src)
|
|||
|
||||
|
||||
// Src and dst are same size. Src has 4 components. Dst has 3 components.
|
||||
void LLImageRaw::compositeUnscaled4onto3( LLImageRaw* src )
|
||||
void LLImageRaw::compositeUnscaled4onto3( const LLImageRaw* src )
|
||||
{
|
||||
LLImageRaw* dst = this; // Just for clarity.
|
||||
|
||||
LLImageDataLock lock(this);
|
||||
|
||||
// <FS:Beq> Correct bad assertion
|
||||
// llassert( (3 == src->getComponents()) || (4 == src->getComponents()) );
|
||||
llassert( (4 == src->getComponents()) || (3 == dst->getComponents()) );
|
||||
// </FS:Beq>
|
||||
llassert( (src->getWidth() == dst->getWidth()) && (src->getHeight() == dst->getHeight()) );
|
||||
|
||||
U8* src_data = src->getData();
|
||||
const U8* src_data = src->getData();
|
||||
U8* dst_data = dst->getData();
|
||||
S32 pixels = getWidth() * getHeight();
|
||||
// <FS:Beq> suspicious crash avoid potential causes.
|
||||
|
|
@ -1249,10 +1283,13 @@ void LLImageRaw::compositeUnscaled4onto3( LLImageRaw* src )
|
|||
}
|
||||
|
||||
|
||||
void LLImageRaw::copyUnscaledAlphaMask( LLImageRaw* src, const LLColor4U& fill)
|
||||
void LLImageRaw::copyUnscaledAlphaMask( const LLImageRaw* src, const LLColor4U& fill)
|
||||
{
|
||||
LLImageRaw* dst = this; // Just for clarity.
|
||||
|
||||
LLImageDataSharedLock lockIn(src);
|
||||
LLImageDataLock lockOut(this);
|
||||
|
||||
if (!validateSrcAndDst("LLImageRaw::copyUnscaledAlphaMask", src, dst))
|
||||
{
|
||||
return;
|
||||
|
|
@ -1263,7 +1300,7 @@ void LLImageRaw::copyUnscaledAlphaMask( LLImageRaw* src, const LLColor4U& fill)
|
|||
llassert( (src->getWidth() == dst->getWidth()) && (src->getHeight() == dst->getHeight()) );
|
||||
|
||||
S32 pixels = getWidth() * getHeight();
|
||||
U8* src_data = src->getData();
|
||||
const U8* src_data = src->getData();
|
||||
U8* dst_data = dst->getData();
|
||||
for ( S32 i = 0; i < pixels; i++ )
|
||||
{
|
||||
|
|
@ -1280,6 +1317,8 @@ void LLImageRaw::copyUnscaledAlphaMask( LLImageRaw* src, const LLColor4U& fill)
|
|||
// Fill the buffer with a constant color
|
||||
void LLImageRaw::fill( const LLColor4U& color )
|
||||
{
|
||||
LLImageDataLock lock(this);
|
||||
|
||||
if (isBufferInvalid())
|
||||
{
|
||||
LL_WARNS() << "Invalid image buffer" << LL_ENDL;
|
||||
|
|
@ -1317,16 +1356,21 @@ LLPointer<LLImageRaw> LLImageRaw::duplicate()
|
|||
return this; //nobody else refences to this image, no need to duplicate.
|
||||
}
|
||||
|
||||
LLImageDataSharedLock lock(this);
|
||||
|
||||
//make a duplicate
|
||||
LLPointer<LLImageRaw> dup = new LLImageRaw(getData(), getWidth(), getHeight(), getComponents());
|
||||
return dup;
|
||||
}
|
||||
|
||||
// Src and dst can be any size. Src and dst can each have 3 or 4 components.
|
||||
void LLImageRaw::copy(LLImageRaw* src)
|
||||
void LLImageRaw::copy(const LLImageRaw* src)
|
||||
{
|
||||
LLImageRaw* dst = this; // Just for clarity.
|
||||
|
||||
LLImageDataSharedLock lockIn(src);
|
||||
LLImageDataLock lockOut(this);
|
||||
|
||||
if (!validateSrcAndDst("LLImageRaw::copy", src, dst))
|
||||
{
|
||||
return;
|
||||
|
|
@ -1372,10 +1416,12 @@ void LLImageRaw::copy(LLImageRaw* src)
|
|||
}
|
||||
|
||||
// Src and dst are same size. Src and dst have same number of components.
|
||||
void LLImageRaw::copyUnscaled(LLImageRaw* src)
|
||||
void LLImageRaw::copyUnscaled(const LLImageRaw* src)
|
||||
{
|
||||
LLImageRaw* dst = this; // Just for clarity.
|
||||
|
||||
LLImageDataLock lock(this);
|
||||
|
||||
llassert( (1 == src->getComponents()) || (3 == src->getComponents()) || (4 == src->getComponents()) );
|
||||
llassert( src->getComponents() == dst->getComponents() );
|
||||
llassert( (src->getWidth() == dst->getWidth()) && (src->getHeight() == dst->getHeight()) );
|
||||
|
|
@ -1385,7 +1431,7 @@ void LLImageRaw::copyUnscaled(LLImageRaw* src)
|
|||
|
||||
|
||||
// Src and dst can be any size. Src has 3 components. Dst has 4 components.
|
||||
void LLImageRaw::copyScaled3onto4(LLImageRaw* src)
|
||||
void LLImageRaw::copyScaled3onto4(const LLImageRaw* src)
|
||||
{
|
||||
llassert( (3 == src->getComponents()) && (4 == getComponents()) );
|
||||
|
||||
|
|
@ -1397,7 +1443,7 @@ void LLImageRaw::copyScaled3onto4(LLImageRaw* src)
|
|||
|
||||
|
||||
// Src and dst can be any size. Src has 4 components. Dst has 3 components.
|
||||
void LLImageRaw::copyScaled4onto3(LLImageRaw* src)
|
||||
void LLImageRaw::copyScaled4onto3(const LLImageRaw* src)
|
||||
{
|
||||
llassert( (4 == src->getComponents()) && (3 == getComponents()) );
|
||||
|
||||
|
|
@ -1409,15 +1455,17 @@ void LLImageRaw::copyScaled4onto3(LLImageRaw* src)
|
|||
|
||||
|
||||
// Src and dst are same size. Src has 4 components. Dst has 3 components.
|
||||
void LLImageRaw::copyUnscaled4onto3( LLImageRaw* src )
|
||||
void LLImageRaw::copyUnscaled4onto3( const LLImageRaw* src )
|
||||
{
|
||||
LLImageRaw* dst = this; // Just for clarity.
|
||||
|
||||
LLImageDataLock lock(this);
|
||||
|
||||
llassert( (3 == dst->getComponents()) && (4 == src->getComponents()) );
|
||||
llassert( (src->getWidth() == dst->getWidth()) && (src->getHeight() == dst->getHeight()) );
|
||||
|
||||
S32 pixels = getWidth() * getHeight();
|
||||
U8* src_data = src->getData();
|
||||
const U8* src_data = src->getData();
|
||||
U8* dst_data = dst->getData();
|
||||
for( S32 i=0; i<pixels; i++ )
|
||||
{
|
||||
|
|
@ -1431,15 +1479,18 @@ void LLImageRaw::copyUnscaled4onto3( LLImageRaw* src )
|
|||
|
||||
|
||||
// Src and dst are same size. Src has 3 components. Dst has 4 components.
|
||||
void LLImageRaw::copyUnscaled3onto4( LLImageRaw* src )
|
||||
void LLImageRaw::copyUnscaled3onto4( const LLImageRaw* src )
|
||||
{
|
||||
LLImageRaw* dst = this; // Just for clarity.
|
||||
|
||||
LLImageDataLock lock(this);
|
||||
|
||||
llassert( 3 == src->getComponents() );
|
||||
llassert( 4 == dst->getComponents() );
|
||||
llassert( (src->getWidth() == dst->getWidth()) && (src->getHeight() == dst->getHeight()) );
|
||||
|
||||
S32 pixels = getWidth() * getHeight();
|
||||
U8* src_data = src->getData();
|
||||
const U8* src_data = src->getData();
|
||||
U8* dst_data = dst->getData();
|
||||
for( S32 i=0; i<pixels; i++ )
|
||||
{
|
||||
|
|
@ -1454,10 +1505,13 @@ void LLImageRaw::copyUnscaled3onto4( LLImageRaw* src )
|
|||
|
||||
|
||||
// Src and dst can be any size. Src and dst have same number of components.
|
||||
void LLImageRaw::copyScaled( LLImageRaw* src )
|
||||
void LLImageRaw::copyScaled( const LLImageRaw* src )
|
||||
{
|
||||
LLImageRaw* dst = this; // Just for clarity.
|
||||
|
||||
LLImageDataSharedLock lockIn(src);
|
||||
LLImageDataLock lockOut(this);
|
||||
|
||||
if (!validateSrcAndDst("LLImageRaw::copyScaled", src, dst))
|
||||
{
|
||||
return;
|
||||
|
|
@ -1499,6 +1553,8 @@ void LLImageRaw::copyScaled( LLImageRaw* src )
|
|||
|
||||
bool LLImageRaw::scale( S32 new_width, S32 new_height, bool scale_image_data )
|
||||
{
|
||||
LLImageDataLock lock(this);
|
||||
|
||||
S32 components = getComponents();
|
||||
if (components != 1 && components != 3 && components != 4)
|
||||
{
|
||||
|
|
@ -1585,6 +1641,8 @@ LLPointer<LLImageRaw> LLImageRaw::scaled(S32 new_width, S32 new_height)
|
|||
{
|
||||
LLPointer<LLImageRaw> result;
|
||||
|
||||
LLImageDataLock lock(this);
|
||||
|
||||
S32 components = getComponents();
|
||||
if (components != 1 && components != 3 && components != 4)
|
||||
{
|
||||
|
|
@ -1630,7 +1688,7 @@ LLPointer<LLImageRaw> LLImageRaw::scaled(S32 new_width, S32 new_height)
|
|||
return result;
|
||||
}
|
||||
|
||||
void LLImageRaw::copyLineScaled( U8* in, U8* out, S32 in_pixel_len, S32 out_pixel_len, S32 in_pixel_step, S32 out_pixel_step )
|
||||
void LLImageRaw::copyLineScaled( const U8* in, U8* out, S32 in_pixel_len, S32 out_pixel_len, S32 in_pixel_step, S32 out_pixel_step )
|
||||
{
|
||||
const S32 components = getComponents();
|
||||
llassert( components >= 1 && components <= 4 );
|
||||
|
|
@ -1657,7 +1715,7 @@ void LLImageRaw::copyLineScaled( U8* in, U8* out, S32 in_pixel_len, S32 out_pixe
|
|||
S32 t0 = x * out_pixel_step * components;
|
||||
S32 t1 = index0 * in_pixel_step * components;
|
||||
U8* outp = out + t0;
|
||||
U8* inp = in + t1;
|
||||
const U8* inp = in + t1;
|
||||
for (S32 i = 0; i < components; ++i)
|
||||
{
|
||||
*outp = *inp;
|
||||
|
|
@ -1745,7 +1803,7 @@ void LLImageRaw::copyLineScaled( U8* in, U8* out, S32 in_pixel_len, S32 out_pixe
|
|||
}
|
||||
}
|
||||
|
||||
void LLImageRaw::compositeRowScaled4onto3( U8* in, U8* out, S32 in_pixel_len, S32 out_pixel_len )
|
||||
void LLImageRaw::compositeRowScaled4onto3( const U8* in, U8* out, S32 in_pixel_len, S32 out_pixel_len )
|
||||
{
|
||||
llassert( getComponents() == 3 );
|
||||
|
||||
|
|
@ -1841,8 +1899,12 @@ void LLImageRaw::compositeRowScaled4onto3( U8* in, U8* out, S32 in_pixel_len, S3
|
|||
}
|
||||
}
|
||||
|
||||
bool LLImageRaw::validateSrcAndDst(std::string func, LLImageRaw* src, LLImageRaw* dst)
|
||||
// static
|
||||
bool LLImageRaw::validateSrcAndDst(std::string func, const LLImageRaw* src, const LLImageRaw* dst)
|
||||
{
|
||||
LLImageDataSharedLock lockIn(src);
|
||||
LLImageDataLock lockOut(dst);
|
||||
|
||||
if (!src || !dst || src->isBufferInvalid() || dst->isBufferInvalid())
|
||||
{
|
||||
LL_WARNS() << func << ": Source: ";
|
||||
|
|
@ -2155,6 +2217,8 @@ bool LLImageFormatted::decodeChannels(LLImageRaw* raw_image,F32 decode_time, S3
|
|||
// virtual
|
||||
U8* LLImageFormatted::allocateData(S32 size)
|
||||
{
|
||||
LLImageDataLock lock(this);
|
||||
|
||||
U8* res = LLImageBase::allocateData(size); // calls deleteData()
|
||||
if(res)
|
||||
sGlobalFormattedMemory += getDataSize();
|
||||
|
|
@ -2164,6 +2228,8 @@ U8* LLImageFormatted::allocateData(S32 size)
|
|||
// virtual
|
||||
U8* LLImageFormatted::reallocateData(S32 size)
|
||||
{
|
||||
LLImageDataLock lock(this);
|
||||
|
||||
sGlobalFormattedMemory -= getDataSize();
|
||||
U8* res = LLImageBase::reallocateData(size);
|
||||
if(res)
|
||||
|
|
@ -2174,6 +2240,12 @@ U8* LLImageFormatted::reallocateData(S32 size)
|
|||
// virtual
|
||||
void LLImageFormatted::deleteData()
|
||||
{
|
||||
LLImageDataLock lock(this);
|
||||
|
||||
if (mDecoding)
|
||||
{
|
||||
LL_ERRS() << "LLImageFormatted::deleteData() is called during decoding" << LL_ENDL;
|
||||
}
|
||||
sGlobalFormattedMemory -= getDataSize();
|
||||
LLImageBase::deleteData();
|
||||
}
|
||||
|
|
@ -2200,6 +2272,8 @@ void LLImageFormatted::sanityCheck()
|
|||
|
||||
bool LLImageFormatted::copyData(U8 *data, S32 size)
|
||||
{
|
||||
LLImageDataLock lock(this);
|
||||
|
||||
if ( data && ((data != getData()) || (size != getDataSize())) )
|
||||
{
|
||||
deleteData();
|
||||
|
|
@ -2212,6 +2286,8 @@ bool LLImageFormatted::copyData(U8 *data, S32 size)
|
|||
// LLImageFormatted becomes the owner of data
|
||||
void LLImageFormatted::setData(U8 *data, S32 size)
|
||||
{
|
||||
LLImageDataLock lock(this);
|
||||
|
||||
if (data && data != getData())
|
||||
{
|
||||
deleteData();
|
||||
|
|
@ -2225,6 +2301,8 @@ void LLImageFormatted::appendData(U8 *data, S32 size)
|
|||
{
|
||||
if (data)
|
||||
{
|
||||
LLImageDataLock lock(this);
|
||||
|
||||
if (!getData())
|
||||
{
|
||||
setData(data, size);
|
||||
|
|
@ -2271,6 +2349,9 @@ bool LLImageFormatted::load(const std::string &filename, int load_size)
|
|||
{
|
||||
load_size = file_size;
|
||||
}
|
||||
|
||||
LLImageDataLock lock(this);
|
||||
|
||||
bool res;
|
||||
U8 *data = allocateData(load_size);
|
||||
if (data)
|
||||
|
|
@ -2308,8 +2389,10 @@ bool LLImageFormatted::save(const std::string &filename)
|
|||
setLastError("Unable to open file for writing", filename);
|
||||
return false;
|
||||
}
|
||||
|
||||
outfile.write(getData(), getDataSize());
|
||||
|
||||
LLImageDataSharedLock lock(this);
|
||||
|
||||
outfile.write(getData(), getDataSize());
|
||||
outfile.close() ;
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -116,7 +116,11 @@ class LLImageBase
|
|||
{
|
||||
protected:
|
||||
virtual ~LLImageBase();
|
||||
|
||||
|
||||
virtual void deleteData();
|
||||
virtual U8* allocateData(S32 size = -1);
|
||||
virtual U8* reallocateData(S32 size = -1);
|
||||
|
||||
public:
|
||||
LLImageBase();
|
||||
|
||||
|
|
@ -126,10 +130,6 @@ public:
|
|||
TYPE_AVATAR_BAKE = 1,
|
||||
};
|
||||
|
||||
virtual void deleteData();
|
||||
virtual U8* allocateData(S32 size = -1);
|
||||
virtual U8* reallocateData(S32 size = -1);
|
||||
|
||||
virtual void dump();
|
||||
virtual void sanityCheck();
|
||||
|
||||
|
|
@ -171,8 +171,22 @@ private:
|
|||
|
||||
S8 mComponents;
|
||||
|
||||
bool mBadBufferAllocation ;
|
||||
bool mAllowOverSize ;
|
||||
bool mBadBufferAllocation;
|
||||
bool mAllowOverSize;
|
||||
|
||||
private:
|
||||
mutable LLSharedMutex mDataMutex;
|
||||
|
||||
public:
|
||||
template<bool SHARED>
|
||||
class DataLock : LLSharedMutexLockTemplate<SHARED>
|
||||
{
|
||||
public:
|
||||
DataLock(const LLImageBase* image)
|
||||
: LLSharedMutexLockTemplate<SHARED>(image ? &image->mDataMutex : nullptr)
|
||||
{
|
||||
}
|
||||
};
|
||||
public:
|
||||
// <FS:ND> Report amount of failed buffer allocations
|
||||
static void addAllocationError();
|
||||
|
|
@ -182,6 +196,9 @@ private:
|
|||
// </FS:ND>
|
||||
};
|
||||
|
||||
using LLImageDataLock = LLImageBase::DataLock<false>;
|
||||
using LLImageDataSharedLock = LLImageBase::DataLock<true>;
|
||||
|
||||
// Raw representation of an image (used for textures, and other uncompressed formats
|
||||
class LLImageRaw : public LLImageBase
|
||||
{
|
||||
|
|
@ -238,51 +255,51 @@ public:
|
|||
LLPointer<LLImageRaw> duplicate();
|
||||
|
||||
// Src and dst can be any size. Src and dst can each have 3 or 4 components.
|
||||
void copy( LLImageRaw* src );
|
||||
void copy( const LLImageRaw* src );
|
||||
|
||||
// Src and dst are same size. Src and dst have same number of components.
|
||||
void copyUnscaled( LLImageRaw* src );
|
||||
void copyUnscaled( const LLImageRaw* src );
|
||||
|
||||
// Src and dst are same size. Src has 4 components. Dst has 3 components.
|
||||
void copyUnscaled4onto3( LLImageRaw* src );
|
||||
void copyUnscaled4onto3( const LLImageRaw* src );
|
||||
|
||||
// Src and dst are same size. Src has 3 components. Dst has 4 components.
|
||||
void copyUnscaled3onto4( LLImageRaw* src );
|
||||
void copyUnscaled3onto4( const LLImageRaw* src );
|
||||
|
||||
// Src and dst are same size. Src has 1 component. Dst has 4 components.
|
||||
// Alpha component is set to source alpha mask component.
|
||||
// RGB components are set to fill color.
|
||||
void copyUnscaledAlphaMask( LLImageRaw* src, const LLColor4U& fill);
|
||||
void copyUnscaledAlphaMask( const LLImageRaw* src, const LLColor4U& fill);
|
||||
|
||||
// Src and dst can be any size. Src and dst have same number of components.
|
||||
void copyScaled( LLImageRaw* src );
|
||||
|
||||
// Src and dst can be any size. Src has 3 components. Dst has 4 components.
|
||||
void copyScaled3onto4( LLImageRaw* src );
|
||||
|
||||
// Src and dst can be any size. Src has 4 components. Dst has 3 components.
|
||||
void copyScaled4onto3( LLImageRaw* src );
|
||||
void copyScaled( const LLImageRaw* src );
|
||||
|
||||
|
||||
// Composite operations
|
||||
|
||||
// Src and dst can be any size. Src and dst can each have 3 or 4 components.
|
||||
void composite( LLImageRaw* src );
|
||||
|
||||
// Src and dst can be any size. Src has 4 components. Dst has 3 components.
|
||||
void compositeScaled4onto3( LLImageRaw* src );
|
||||
|
||||
// Src and dst are same size. Src has 4 components. Dst has 3 components.
|
||||
void compositeUnscaled4onto3( LLImageRaw* src );
|
||||
void composite( const LLImageRaw* src );
|
||||
|
||||
protected:
|
||||
// Src and dst can be any size. Src has 4 components. Dst has 3 components.
|
||||
void compositeScaled4onto3( const LLImageRaw* src );
|
||||
|
||||
// Src and dst are same size. Src has 4 components. Dst has 3 components.
|
||||
void compositeUnscaled4onto3( const LLImageRaw* src );
|
||||
|
||||
// Src and dst can be any size. Src has 3 components. Dst has 4 components.
|
||||
void copyScaled3onto4( const LLImageRaw* src );
|
||||
|
||||
// Src and dst can be any size. Src has 4 components. Dst has 3 components.
|
||||
void copyScaled4onto3( const LLImageRaw* src );
|
||||
|
||||
// Create an image from a local file (generally used in tools)
|
||||
//bool createFromFile(const std::string& filename, bool j2c_lowest_mip_only = false);
|
||||
|
||||
void copyLineScaled( U8* in, U8* out, S32 in_pixel_len, S32 out_pixel_len, S32 in_pixel_step, S32 out_pixel_step );
|
||||
void compositeRowScaled4onto3( U8* in, U8* out, S32 in_pixel_len, S32 out_pixel_len );
|
||||
void copyLineScaled( const U8* in, U8* out, S32 in_pixel_len, S32 out_pixel_len, S32 in_pixel_step, S32 out_pixel_step );
|
||||
void compositeRowScaled4onto3( const U8* in, U8* out, S32 in_pixel_len, S32 out_pixel_len );
|
||||
|
||||
U8 fastFractionalMult(U8 a,U8 b);
|
||||
static U8 fastFractionalMult(U8 a, U8 b);
|
||||
|
||||
void setDataAndSize(U8 *data, S32 width, S32 height, S8 components) ;
|
||||
|
||||
|
|
@ -293,7 +310,7 @@ public:
|
|||
// </FS:Techwolf Lupindo>
|
||||
|
||||
private:
|
||||
bool validateSrcAndDst(std::string func, LLImageRaw* src, LLImageRaw* dst);
|
||||
static bool validateSrcAndDst(std::string func, const LLImageRaw* src, const LLImageRaw* dst);
|
||||
};
|
||||
|
||||
// Compressed representation of image.
|
||||
|
|
@ -366,7 +383,7 @@ protected:
|
|||
S8 mDecoded; // unused, but changing LLImage layout requires recompiling static Mac/Linux libs. 2009-01-30 JC
|
||||
S8 mDiscardLevel; // Current resolution level worked on. 0 = full res, 1 = half res, 2 = quarter res, etc...
|
||||
S8 mLevels; // Number of resolution levels in that image. Min is 1. 0 means unknown.
|
||||
|
||||
|
||||
public:
|
||||
static S32 sGlobalFormattedMemory;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -96,6 +96,8 @@ bool LLImageBMP::updateData()
|
|||
{
|
||||
resetLastError();
|
||||
|
||||
LLImageDataLock lock(this);
|
||||
|
||||
// Check to make sure that this instance has been initialized with data
|
||||
U8* mdata = getData();
|
||||
if (!mdata || (0 == getDataSize()))
|
||||
|
|
@ -336,8 +338,11 @@ bool LLImageBMP::decode(LLImageRaw* raw_image, F32 decode_time)
|
|||
|
||||
resetLastError();
|
||||
|
||||
LLImageDataLock lockIn(this);
|
||||
LLImageDataLock lockOut(raw_image);
|
||||
|
||||
// Check to make sure that this instance has been initialized with data
|
||||
U8* mdata = getData();
|
||||
const U8* mdata = getData();
|
||||
if (!mdata || (0 == getDataSize()))
|
||||
{
|
||||
setLastError("llimagebmp trying to decode an image with no data!");
|
||||
|
|
@ -350,7 +355,7 @@ bool LLImageBMP::decode(LLImageRaw* raw_image, F32 decode_time)
|
|||
return false;
|
||||
}
|
||||
|
||||
U8* src = mdata + mBitmapOffset;
|
||||
const U8* src = mdata + mBitmapOffset;
|
||||
U8* dst = raw_image->getData();
|
||||
|
||||
bool success = false;
|
||||
|
|
@ -397,7 +402,7 @@ U32 LLImageBMP::countTrailingZeros( U32 m )
|
|||
}
|
||||
|
||||
|
||||
bool LLImageBMP::decodeColorMask16( U8* dst, U8* src )
|
||||
bool LLImageBMP::decodeColorMask16( U8* dst, const U8* src )
|
||||
{
|
||||
llassert( 16 == mBitsPerPixel );
|
||||
|
||||
|
|
@ -433,7 +438,7 @@ bool LLImageBMP::decodeColorMask16( U8* dst, U8* src )
|
|||
return true;
|
||||
}
|
||||
|
||||
bool LLImageBMP::decodeColorMask32( U8* dst, U8* src )
|
||||
bool LLImageBMP::decodeColorMask32( U8* dst, const U8* src )
|
||||
{
|
||||
// Note: alpha is not supported
|
||||
|
||||
|
|
@ -477,7 +482,7 @@ bool LLImageBMP::decodeColorMask32( U8* dst, U8* src )
|
|||
}
|
||||
|
||||
|
||||
bool LLImageBMP::decodeColorTable8( U8* dst, U8* src )
|
||||
bool LLImageBMP::decodeColorTable8( U8* dst, const U8* src )
|
||||
{
|
||||
llassert( (8 == mBitsPerPixel) && (mColorPaletteColors >= 256) );
|
||||
|
||||
|
|
@ -507,7 +512,7 @@ bool LLImageBMP::decodeColorTable8( U8* dst, U8* src )
|
|||
}
|
||||
|
||||
|
||||
bool LLImageBMP::decodeTruecolor24( U8* dst, U8* src )
|
||||
bool LLImageBMP::decodeTruecolor24( U8* dst, const U8* src )
|
||||
{
|
||||
llassert( 24 == mBitsPerPixel );
|
||||
llassert( 3 == getComponents() );
|
||||
|
|
@ -541,6 +546,9 @@ bool LLImageBMP::encode(const LLImageRaw* raw_image, F32 encode_time)
|
|||
|
||||
resetLastError();
|
||||
|
||||
LLImageDataSharedLock lockIn(raw_image);
|
||||
LLImageDataLock lockOut(this);
|
||||
|
||||
S32 src_components = raw_image->getComponents();
|
||||
S32 dst_components = ( src_components < 3 ) ? 1 : 3;
|
||||
|
||||
|
|
|
|||
|
|
@ -45,10 +45,10 @@ public:
|
|||
/*virtual*/ bool encode(const LLImageRaw* raw_image, F32 encode_time);
|
||||
|
||||
protected:
|
||||
bool decodeColorTable8( U8* dst, U8* src );
|
||||
bool decodeColorMask16( U8* dst, U8* src );
|
||||
bool decodeTruecolor24( U8* dst, U8* src );
|
||||
bool decodeColorMask32( U8* dst, U8* src );
|
||||
bool decodeColorTable8( U8* dst, const U8* src );
|
||||
bool decodeColorMask16( U8* dst, const U8* src );
|
||||
bool decodeTruecolor24( U8* dst, const U8* src );
|
||||
bool decodeColorMask32( U8* dst, const U8* src );
|
||||
|
||||
U32 countTrailingZeros( U32 m );
|
||||
|
||||
|
|
|
|||
|
|
@ -176,6 +176,8 @@ bool LLImageDXT::updateData()
|
|||
{
|
||||
resetLastError();
|
||||
|
||||
LLImageDataLock lock(this);
|
||||
|
||||
U8* data = getData();
|
||||
S32 data_size = getDataSize();
|
||||
|
||||
|
|
@ -268,7 +270,10 @@ bool LLImageDXT::decode(LLImageRaw* raw_image, F32 time)
|
|||
LL_WARNS() << "Attempt to decode compressed LLImageDXT to Raw (unsupported)" << LL_ENDL;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
LLImageDataSharedLock lockIn(this);
|
||||
LLImageDataLock lockOut(raw_image);
|
||||
|
||||
S32 width = getWidth(), height = getHeight();
|
||||
S32 ncomponents = getComponents();
|
||||
U8* data = NULL;
|
||||
|
|
@ -309,6 +314,9 @@ bool LLImageDXT::getMipData(LLPointer<LLImageRaw>& raw, S32 discard)
|
|||
{
|
||||
LL_ERRS() << "Request for invalid discard level" << LL_ENDL;
|
||||
}
|
||||
|
||||
LLImageDataSharedLock lock(this);
|
||||
|
||||
U8* data = getData() + getMipOffset(discard);
|
||||
S32 width = 0;
|
||||
S32 height = 0;
|
||||
|
|
@ -339,6 +347,8 @@ bool LLImageDXT::encodeDXT(const LLImageRaw* raw_image, F32 time, bool explicit_
|
|||
return 0;
|
||||
}
|
||||
|
||||
LLImageDataLock lock(this);
|
||||
|
||||
S32 width = raw_image->getWidth();
|
||||
S32 height = raw_image->getHeight();
|
||||
|
||||
|
|
@ -430,6 +440,9 @@ bool LLImageDXT::convertToDXR()
|
|||
return false;
|
||||
}
|
||||
mFileFormat = newformat;
|
||||
|
||||
LLImageDataLock lock(this);
|
||||
|
||||
S32 width = getWidth(), height = getHeight();
|
||||
S32 nmips = calcNumMips(width,height);
|
||||
S32 total_bytes = getDataSize();
|
||||
|
|
|
|||
|
|
@ -87,7 +87,9 @@ LLImageFilter::~LLImageFilter()
|
|||
void LLImageFilter::executeFilter(LLPointer<LLImageRaw> raw_image)
|
||||
{
|
||||
mImage = raw_image;
|
||||
|
||||
|
||||
LLImageDataLock lock(mImage);
|
||||
|
||||
//std::cout << "Filter : size = " << mFilterData.size() << std::endl;
|
||||
for (S32 i = 0; i < mFilterData.size(); ++i)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -107,6 +107,8 @@ bool LLImageJ2C::updateData()
|
|||
bool res = true;
|
||||
resetLastError();
|
||||
|
||||
LLImageDataLock lock(this);
|
||||
|
||||
// Check to make sure that this instance has been initialized with data
|
||||
if (!getData() || (getDataSize() < 16))
|
||||
{
|
||||
|
|
@ -157,36 +159,48 @@ bool LLImageJ2C::decodeChannels(LLImageRaw *raw_imagep, F32 decode_time, S32 fir
|
|||
LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
|
||||
LLTimer elapsed;
|
||||
|
||||
bool res = true;
|
||||
|
||||
resetLastError();
|
||||
|
||||
// Check to make sure that this instance has been initialized with data
|
||||
if (!getData() || (getDataSize() < 16))
|
||||
bool res;
|
||||
{
|
||||
setLastError("LLImageJ2C uninitialized");
|
||||
res = true; // done
|
||||
}
|
||||
else
|
||||
{
|
||||
// Update the raw discard level
|
||||
updateRawDiscardLevel();
|
||||
LLImageDataLock lock(this);
|
||||
|
||||
mDecoding = true;
|
||||
res = mImpl->decodeImpl(*this, *raw_imagep, decode_time, first_channel, max_channel_count);
|
||||
// Check to make sure that this instance has been initialized with data
|
||||
if (!getData() || (getDataSize() < 16))
|
||||
{
|
||||
setLastError("LLImageJ2C uninitialized");
|
||||
res = true; // done
|
||||
}
|
||||
else
|
||||
{
|
||||
// Update the raw discard level
|
||||
updateRawDiscardLevel();
|
||||
res = mImpl->decodeImpl(*this, *raw_imagep, decode_time, first_channel, max_channel_count);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (res)
|
||||
{
|
||||
if (!mDecoding)
|
||||
{
|
||||
// Failed
|
||||
raw_imagep->deleteData();
|
||||
res = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
mDecoding = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (mDecoding)
|
||||
{
|
||||
LL_WARNS() << "decodeImpl failed but mDecoding is TRUE" << LL_ENDL;
|
||||
mDecoding = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!mLastError.empty())
|
||||
{
|
||||
|
|
@ -411,9 +425,10 @@ bool LLImageJ2C::loadAndValidate(const std::string &filename)
|
|||
|
||||
bool LLImageJ2C::validate(U8 *data, U32 file_size)
|
||||
{
|
||||
|
||||
resetLastError();
|
||||
|
||||
|
||||
LLImageDataLock lock(this);
|
||||
|
||||
setData(data, file_size);
|
||||
|
||||
bool res = updateData();
|
||||
|
|
|
|||
|
|
@ -50,6 +50,8 @@ bool LLImageJPEG::updateData()
|
|||
{
|
||||
resetLastError();
|
||||
|
||||
LLImageDataLock lock(this);
|
||||
|
||||
// Check to make sure that this instance has been initialized with data
|
||||
if (!getData() || (0 == getDataSize()))
|
||||
{
|
||||
|
|
@ -188,7 +190,10 @@ bool LLImageJPEG::decode(LLImageRaw* raw_image, F32 decode_time)
|
|||
llassert_always(raw_image);
|
||||
|
||||
resetLastError();
|
||||
|
||||
|
||||
LLImageDataLock lockIn(this);
|
||||
LLImageDataLock lockOut(raw_image);
|
||||
|
||||
// Check to make sure that this instance has been initialized with data
|
||||
if (!getData() || (0 == getDataSize()))
|
||||
{
|
||||
|
|
@ -408,6 +413,8 @@ void LLImageJPEG::encodeTermDestination( j_compress_ptr cinfo )
|
|||
{
|
||||
LLImageJPEG* self = (LLImageJPEG*) cinfo->client_data;
|
||||
|
||||
LLImageDataLock lock(self);
|
||||
|
||||
S32 file_bytes = (S32)(self->mOutputBufferSize - cinfo->dest->free_in_buffer);
|
||||
if(self->allocateData(file_bytes))
|
||||
memcpy( self->getData(), self->mOutputBuffer, file_bytes ); /* Flawfinder: ignore */
|
||||
|
|
@ -485,6 +492,9 @@ bool LLImageJPEG::encode( const LLImageRaw* raw_image, F32 encode_time )
|
|||
|
||||
resetLastError();
|
||||
|
||||
LLImageDataSharedLock lockIn(raw_image);
|
||||
LLImageDataLock lockOut(this);
|
||||
|
||||
switch( raw_image->getComponents() )
|
||||
{
|
||||
case 1:
|
||||
|
|
|
|||
|
|
@ -73,8 +73,6 @@ public:
|
|||
static void errorEmitMessage(j_common_ptr cinfo, int msg_level);
|
||||
static void errorOutputMessage(j_common_ptr cinfo);
|
||||
|
||||
static bool decompress(LLImageJPEG* imagep);
|
||||
|
||||
protected:
|
||||
U8* mOutputBuffer; // temp buffer used during encoding
|
||||
S32 mOutputBufferSize; // bytes in mOuputBuffer
|
||||
|
|
|
|||
|
|
@ -51,6 +51,8 @@ bool LLImagePNG::updateData()
|
|||
{
|
||||
resetLastError();
|
||||
|
||||
LLImageDataLock lock(this);
|
||||
|
||||
// Check to make sure that this instance has been initialized with data
|
||||
if (!getData() || (0 == getDataSize()))
|
||||
{
|
||||
|
|
@ -87,6 +89,9 @@ bool LLImagePNG::decode(LLImageRaw* raw_image, F32 decode_time)
|
|||
|
||||
resetLastError();
|
||||
|
||||
LLImageDataSharedLock lockIn(this);
|
||||
LLImageDataLock lockOut(raw_image);
|
||||
|
||||
// Check to make sure that this instance has been initialized with data
|
||||
if (!getData() || (0 == getDataSize()))
|
||||
{
|
||||
|
|
@ -119,6 +124,9 @@ bool LLImagePNG::encode(const LLImageRaw* raw_image, F32 encode_time)
|
|||
|
||||
resetLastError();
|
||||
|
||||
LLImageDataSharedLock lockIn(raw_image);
|
||||
LLImageDataLock lockOut(this);
|
||||
|
||||
// Image logical size
|
||||
setSize(raw_image->getWidth(), raw_image->getHeight(), raw_image->getComponents());
|
||||
|
||||
|
|
|
|||
|
|
@ -108,6 +108,8 @@ bool LLImageTGA::updateData()
|
|||
{
|
||||
resetLastError();
|
||||
|
||||
LLImageDataLock lock(this);
|
||||
|
||||
// Check to make sure that this instance has been initialized with data
|
||||
if (!getData() || (0 == getDataSize()))
|
||||
{
|
||||
|
|
@ -326,7 +328,10 @@ bool LLImageTGA::updateData()
|
|||
bool LLImageTGA::decode(LLImageRaw* raw_image, F32 decode_time)
|
||||
{
|
||||
llassert_always(raw_image);
|
||||
|
||||
|
||||
LLImageDataSharedLock lockIn(this);
|
||||
LLImageDataLock lockOut(raw_image);
|
||||
|
||||
// Check to make sure that this instance has been initialized with data
|
||||
if (!getData() || (0 == getDataSize()))
|
||||
{
|
||||
|
|
@ -657,7 +662,10 @@ bool LLImageTGA::decodeColorMap( LLImageRaw* raw_image, bool rle, bool flipped )
|
|||
bool LLImageTGA::encode(const LLImageRaw* raw_image, F32 encode_time)
|
||||
{
|
||||
llassert_always(raw_image);
|
||||
|
||||
|
||||
LLImageDataSharedLock lockIn(raw_image);
|
||||
LLImageDataLock lockOut(this);
|
||||
|
||||
deleteData();
|
||||
|
||||
setSize(raw_image->getWidth(), raw_image->getHeight(), raw_image->getComponents());
|
||||
|
|
@ -1076,6 +1084,9 @@ bool LLImageTGA::decodeAndProcess( LLImageRaw* raw_image, F32 domain, F32 weight
|
|||
// --+---Input--------------------------------
|
||||
// |
|
||||
|
||||
LLImageDataSharedLock lockIn(this);
|
||||
LLImageDataLock lockOut(raw_image);
|
||||
|
||||
if (!getData() || (0 == getDataSize()))
|
||||
{
|
||||
setLastError("LLImageTGA trying to decode an image with no data!");
|
||||
|
|
|
|||
|
|
@ -149,9 +149,18 @@ ImageRequest::~ImageRequest()
|
|||
bool ImageRequest::processRequest()
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
|
||||
|
||||
if (mFormattedImage.isNull())
|
||||
return true;
|
||||
|
||||
const F32 decode_time_slice = 0.f; //disable time slicing
|
||||
bool done = true;
|
||||
if (!mDecodedRaw && mFormattedImage.notNull())
|
||||
|
||||
LLImageDataLock lockFormatted(mFormattedImage);
|
||||
LLImageDataLock lockDecodedRaw(mDecodedImageRaw);
|
||||
LLImageDataLock lockDecodedAux(mDecodedImageAux);
|
||||
|
||||
if (!mDecodedRaw)
|
||||
{
|
||||
// Decode primary channels
|
||||
if (mDecodedImageRaw.isNull())
|
||||
|
|
@ -189,7 +198,7 @@ bool ImageRequest::processRequest()
|
|||
// some decoders are removing data when task is complete and there were errors
|
||||
mDecodedRaw = done && mDecodedImageRaw->getData();
|
||||
}
|
||||
if (done && mNeedsAux && !mDecodedAux && mFormattedImage.notNull())
|
||||
if (done && mNeedsAux && !mDecodedAux)
|
||||
{
|
||||
// Decode aux channel
|
||||
if (!mDecodedImageAux)
|
||||
|
|
|
|||
|
|
@ -173,6 +173,8 @@ BOOL LLPngWrapper::readPng(U8* src, S32 dataSize, LLImageRaw* rawImage, ImageInf
|
|||
// data space
|
||||
if (rawImage != NULL)
|
||||
{
|
||||
LLImageDataLock lock(rawImage);
|
||||
|
||||
if (!rawImage->resize(static_cast<U16>(mWidth),
|
||||
static_cast<U16>(mHeight), mChannels))
|
||||
{
|
||||
|
|
|
|||
|
|
@ -492,6 +492,9 @@ public:
|
|||
|
||||
bool encode(const LLImageRaw& rawImageIn, LLImageJ2C &compressedImageOut)
|
||||
{
|
||||
LLImageDataSharedLock lockIn(&rawImageIn);
|
||||
LLImageDataLock lockOut(&compressedImageOut);
|
||||
|
||||
setImage(rawImageIn);
|
||||
|
||||
encoder = opj_create_compress(OPJ_CODEC_J2K);
|
||||
|
|
@ -735,6 +738,9 @@ bool LLImageJ2COJ::initEncode(LLImageJ2C &base, LLImageRaw &raw_image, int block
|
|||
|
||||
bool LLImageJ2COJ::decodeImpl(LLImageJ2C &base, LLImageRaw &raw_image, F32 decode_time, S32 first_channel, S32 max_channel_count)
|
||||
{
|
||||
LLImageDataLock lockIn(&base);
|
||||
LLImageDataLock lockOut(&raw_image);
|
||||
|
||||
JPEG2KDecode decoder(0);
|
||||
|
||||
// <FS:Techwolf Lupindo> texture comment metadata reader
|
||||
|
|
@ -878,6 +884,8 @@ bool LLImageJ2COJ::encodeImpl(LLImageJ2C &base, const LLImageRaw &raw_image, con
|
|||
|
||||
bool LLImageJ2COJ::getMetadata(LLImageJ2C &base)
|
||||
{
|
||||
LLImageDataLock lock(&base);
|
||||
|
||||
JPEG2KDecode decode(0);
|
||||
|
||||
S32 width = 0;
|
||||
|
|
|
|||
|
|
@ -288,6 +288,8 @@ void transfer_bytes(kdu_byte *dest, kdu_line_buf &src, int gap, int precision);
|
|||
void LLImageJ2CKDU::setupCodeStream(LLImageJ2C &base, bool keep_codestream, ECodeStreamMode mode)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; // <FS:Beq> instrument image decodes
|
||||
LLImageDataLock lock(&base);
|
||||
|
||||
S32 data_size = base.getDataSize();
|
||||
S32 max_bytes = (base.getMaxBytes() ? base.getMaxBytes() : data_size);
|
||||
|
||||
|
|
@ -528,8 +530,13 @@ bool LLImageJ2CKDU::initDecode(LLImageJ2C &base, LLImageRaw &raw_image, F32 deco
|
|||
bool LLImageJ2CKDU::decodeImpl(LLImageJ2C &base, LLImageRaw &raw_image, F32 decode_time, S32 first_channel, S32 max_channel_count)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
|
||||
|
||||
LLImageDataLock lockIn(&base);
|
||||
LLImageDataLock lockOut(&raw_image);
|
||||
|
||||
ECodeStreamMode mode = MODE_FAST;
|
||||
|
||||
bool limit_time = decode_time > 0.0f;
|
||||
LLTimer decode_timer;
|
||||
|
||||
if (!mCodeStreamp->exists())
|
||||
|
|
@ -553,7 +560,7 @@ bool LLImageJ2CKDU::decodeImpl(LLImageJ2C &base, LLImageRaw &raw_image, F32 deco
|
|||
|
||||
// These can probably be grabbed from what's saved in the class.
|
||||
kdu_dims dims;
|
||||
mCodeStreamp->get_dims(0,dims);
|
||||
mCodeStreamp->get_dims(0, dims);
|
||||
|
||||
// Now we are ready to walk through the tiles processing them one-by-one.
|
||||
kdu_byte *buffer = raw_image.getData();
|
||||
|
|
@ -603,16 +610,18 @@ bool LLImageJ2CKDU::decodeImpl(LLImageJ2C &base, LLImageRaw &raw_image, F32 deco
|
|||
mCodeStreamp.get()));
|
||||
}
|
||||
// Do the actual processing
|
||||
F32 remaining_time = decode_time - decode_timer.getElapsedTimeF32();
|
||||
F32 remaining_time = limit_time ? decode_time - decode_timer.getElapsedTimeF32().value() : 0.0f;
|
||||
// This is where we do the actual decode. If we run out of time, return false.
|
||||
if (mDecodeState->processTileDecode(remaining_time, (decode_time > 0.0f)))
|
||||
if (mDecodeState->processTileDecode(remaining_time, limit_time))
|
||||
{
|
||||
mDecodeState.reset();
|
||||
}
|
||||
else
|
||||
{
|
||||
// Not finished decoding yet.
|
||||
// setLastError("Ran out of time while decoding");
|
||||
base.setLastError("Ran out of time while decoding");
|
||||
base.decodeFailed();
|
||||
cleanupCodeStream();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -310,12 +310,15 @@ void LLMessageSystem::loadTemplateFile(const std::string& filename, bool failure
|
|||
LLTemplateTokenizer tokens(template_body);
|
||||
LLTemplateParser parsed(tokens);
|
||||
mMessageFileVersionNumber = parsed.getVersion();
|
||||
S32 count = 0;
|
||||
for(LLTemplateParser::message_iterator iter = parsed.getMessagesBegin();
|
||||
iter != parsed.getMessagesEnd();
|
||||
iter++)
|
||||
{
|
||||
addTemplate(*iter);
|
||||
count++;
|
||||
}
|
||||
LL_INFOS("Messaging") << "Read " << count << " messages from " << filename << LL_ENDL;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -77,7 +77,7 @@ const char* LOOPBACK_ADDRESS_STRING = "127.0.0.1";
|
|||
const char* BROADCAST_ADDRESS_STRING = "255.255.255.255";
|
||||
|
||||
#if LL_DARWIN
|
||||
// Mac OS X returns an error when trying to set these to 400000. Smaller values succeed.
|
||||
// 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
|
||||
|
|
|
|||
|
|
@ -47,16 +47,49 @@ const char* const LLGLTFMaterial::GLTF_FILE_EXTENSION_TRANSFORM_ROTATION = "rota
|
|||
// special UUID that indicates a null UUID in override data
|
||||
const LLUUID LLGLTFMaterial::GLTF_OVERRIDE_NULL_UUID = LLUUID("ffffffff-ffff-ffff-ffff-ffffffffffff");
|
||||
|
||||
LLGLTFMaterial::LLGLTFMaterial()
|
||||
{
|
||||
// IMPORTANT: since we use the hash of the member variables memory block of
|
||||
// this class to detect changes, we must ensure that all its padding bytes
|
||||
// have been zeroed out. But of course, we must leave the LLRefCount member
|
||||
// variable untouched (and skip it when hashing), and we cannot either
|
||||
// touch the local texture overrides map (else we destroy pointers, and
|
||||
// sundry private data, which would lead to a crash when using that map).
|
||||
// The variable members have therefore been arranged so that anything,
|
||||
// starting at mLocalTexDataDigest and up to the end of the members, can be
|
||||
// safely zeroed. HB
|
||||
const size_t offset = intptr_t(&mLocalTexDataDigest) - intptr_t(this);
|
||||
memset((void*)((const char*)this + offset), 0, sizeof(*this) - offset);
|
||||
|
||||
// Now that we zeroed out our member variables, we can set the ones that
|
||||
// should not be zero to their default value. HB
|
||||
mBaseColor.set(1.f, 1.f, 1.f, 1.f);
|
||||
mMetallicFactor = mRoughnessFactor = 1.f;
|
||||
mAlphaCutoff = 0.5f;
|
||||
for (U32 i = 0; i < GLTF_TEXTURE_INFO_COUNT; ++i)
|
||||
{
|
||||
mTextureTransform[i].mScale.set(1.f, 1.f);
|
||||
#if 0
|
||||
mTextureTransform[i].mOffset.clear();
|
||||
mTextureTransform[i].mRotation = 0.f;
|
||||
#endif
|
||||
}
|
||||
#if 0
|
||||
mLocalTexDataDigest = 0;
|
||||
mAlphaMode = ALPHA_MODE_OPAQUE; // This is 0
|
||||
mOverrideDoubleSided = mOverrideAlphaMode = false;
|
||||
#endif
|
||||
}
|
||||
|
||||
void LLGLTFMaterial::TextureTransform::getPacked(F32 (&packed)[8]) const
|
||||
{
|
||||
packed[0] = mScale.mV[VX];
|
||||
packed[1] = mScale.mV[VY];
|
||||
packed[2] = mRotation;
|
||||
// packed[3] = unused
|
||||
packed[4] = mOffset.mV[VX];
|
||||
packed[5] = mOffset.mV[VY];
|
||||
// packed[6] = unused
|
||||
// packed[7] = unused
|
||||
// Not used but nonetheless zeroed for proper hashing. HB
|
||||
packed[3] = packed[6] = packed[7] = 0.f;
|
||||
}
|
||||
|
||||
bool LLGLTFMaterial::TextureTransform::operator==(const TextureTransform& other) const
|
||||
|
|
@ -89,13 +122,37 @@ LLGLTFMaterial& LLGLTFMaterial::operator=(const LLGLTFMaterial& rhs)
|
|||
mOverrideDoubleSided = rhs.mOverrideDoubleSided;
|
||||
mOverrideAlphaMode = rhs.mOverrideAlphaMode;
|
||||
|
||||
mTrackingIdToLocalTexture = rhs.mTrackingIdToLocalTexture;
|
||||
|
||||
updateTextureTracking();
|
||||
if (rhs.mTrackingIdToLocalTexture.empty())
|
||||
{
|
||||
mTrackingIdToLocalTexture.clear();
|
||||
mLocalTexDataDigest = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
mTrackingIdToLocalTexture = rhs.mTrackingIdToLocalTexture;
|
||||
updateLocalTexDataDigest();
|
||||
updateTextureTracking();
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
void LLGLTFMaterial::updateLocalTexDataDigest()
|
||||
{
|
||||
mLocalTexDataDigest = 0;
|
||||
if (!mTrackingIdToLocalTexture.empty())
|
||||
{
|
||||
for (local_tex_map_t::const_iterator
|
||||
it = mTrackingIdToLocalTexture.begin(),
|
||||
end = mTrackingIdToLocalTexture.end();
|
||||
it != end; ++it)
|
||||
{
|
||||
mLocalTexDataDigest ^= it->first.getDigest64() ^
|
||||
it->second.getDigest64();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool LLGLTFMaterial::operator==(const LLGLTFMaterial& rhs) const
|
||||
{
|
||||
return mTextureId == rhs.mTextureId &&
|
||||
|
|
@ -547,7 +604,7 @@ void LLGLTFMaterial::applyOverride(const LLGLTFMaterial& override_mat)
|
|||
{
|
||||
LL_PROFILE_ZONE_SCOPED;
|
||||
|
||||
for (int i = 0; i < GLTF_TEXTURE_INFO_COUNT; ++i)
|
||||
for (U32 i = 0; i < GLTF_TEXTURE_INFO_COUNT; ++i)
|
||||
{
|
||||
LLUUID& texture_id = mTextureId[i];
|
||||
const LLUUID& override_texture_id = override_mat.mTextureId[i];
|
||||
|
|
@ -588,7 +645,7 @@ void LLGLTFMaterial::applyOverride(const LLGLTFMaterial& override_mat)
|
|||
mDoubleSided = override_mat.mDoubleSided;
|
||||
}
|
||||
|
||||
for (int i = 0; i < GLTF_TEXTURE_INFO_COUNT; ++i)
|
||||
for (U32 i = 0; i < GLTF_TEXTURE_INFO_COUNT; ++i)
|
||||
{
|
||||
if (override_mat.mTextureTransform[i].mOffset != getDefaultTextureOffset())
|
||||
{
|
||||
|
|
@ -606,9 +663,13 @@ void LLGLTFMaterial::applyOverride(const LLGLTFMaterial& override_mat)
|
|||
}
|
||||
}
|
||||
|
||||
mTrackingIdToLocalTexture.insert(override_mat.mTrackingIdToLocalTexture.begin(), override_mat.mTrackingIdToLocalTexture.begin());
|
||||
|
||||
updateTextureTracking();
|
||||
if (!override_mat.mTrackingIdToLocalTexture.empty())
|
||||
{
|
||||
auto it = override_mat.mTrackingIdToLocalTexture.begin();
|
||||
mTrackingIdToLocalTexture.insert(it, it);
|
||||
updateLocalTexDataDigest();
|
||||
updateTextureTracking();
|
||||
}
|
||||
}
|
||||
|
||||
void LLGLTFMaterial::getOverrideLLSD(const LLGLTFMaterial& override_mat, LLSD& data)
|
||||
|
|
@ -618,7 +679,7 @@ void LLGLTFMaterial::getOverrideLLSD(const LLGLTFMaterial& override_mat, LLSD& d
|
|||
|
||||
// make every effort to shave bytes here
|
||||
|
||||
for (int i = 0; i < GLTF_TEXTURE_INFO_COUNT; ++i)
|
||||
for (U32 i = 0; i < GLTF_TEXTURE_INFO_COUNT; ++i)
|
||||
{
|
||||
LLUUID& texture_id = mTextureId[i];
|
||||
const LLUUID& override_texture_id = override_mat.mTextureId[i];
|
||||
|
|
@ -663,7 +724,7 @@ void LLGLTFMaterial::getOverrideLLSD(const LLGLTFMaterial& override_mat, LLSD& d
|
|||
data["ds"] = override_mat.mDoubleSided;
|
||||
}
|
||||
|
||||
for (int i = 0; i < GLTF_TEXTURE_INFO_COUNT; ++i)
|
||||
for (U32 i = 0; i < GLTF_TEXTURE_INFO_COUNT; ++i)
|
||||
{
|
||||
if (override_mat.mTextureTransform[i].mOffset != getDefaultTextureOffset())
|
||||
{
|
||||
|
|
@ -767,7 +828,7 @@ void LLGLTFMaterial::applyOverrideLLSD(const LLSD& data)
|
|||
const LLSD& ti = data["ti"];
|
||||
if (ti.isArray())
|
||||
{
|
||||
for (int i = 0; i < GLTF_TEXTURE_INFO_COUNT; ++i)
|
||||
for (U32 i = 0; i < GLTF_TEXTURE_INFO_COUNT; ++i)
|
||||
{
|
||||
const LLSD& o = ti[i]["o"];
|
||||
if (o.isDefined())
|
||||
|
|
@ -793,27 +854,36 @@ void LLGLTFMaterial::applyOverrideLLSD(const LLSD& data)
|
|||
LLUUID LLGLTFMaterial::getHash() const
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
|
||||
// HACK - hash the bytes of this object but don't include the ref count
|
||||
LLUUID hash;
|
||||
HBXXH128::digest(hash, (unsigned char*)this + sizeof(LLRefCount), sizeof(*this) - sizeof(LLRefCount));
|
||||
return hash;
|
||||
// *HACK: hash the bytes of this object but do not include the ref count
|
||||
// neither the local texture overrides (which is a map, with pointers to
|
||||
// key/value pairs that would change from one LLGLTFMaterial instance to
|
||||
// the other, even though the key/value pairs could be the same, and stored
|
||||
// elsewhere in the memory heap or on the stack).
|
||||
// Note: this does work properly to compare two LLGLTFMaterial instances
|
||||
// only because the padding bytes between their member variables have been
|
||||
// dutifully zeroed in the constructor. HB
|
||||
const size_t offset = intptr_t(&mLocalTexDataDigest) - intptr_t(this);
|
||||
return HBXXH128::digest((const void*)((const char*)this + offset),
|
||||
sizeof(*this) - offset);
|
||||
}
|
||||
|
||||
void LLGLTFMaterial::addLocalTextureTracking(const LLUUID& tracking_id, const LLUUID& tex_id)
|
||||
{
|
||||
mTrackingIdToLocalTexture[tracking_id] = tex_id;
|
||||
updateLocalTexDataDigest();
|
||||
}
|
||||
|
||||
void LLGLTFMaterial::removeLocalTextureTracking(const LLUUID& tracking_id)
|
||||
{
|
||||
mTrackingIdToLocalTexture.erase(tracking_id);
|
||||
updateLocalTexDataDigest();
|
||||
}
|
||||
|
||||
bool LLGLTFMaterial::replaceLocalTexture(const LLUUID& tracking_id, const LLUUID& old_id, const LLUUID& new_id)
|
||||
{
|
||||
bool res = false;
|
||||
|
||||
for (int i = 0; i < GLTF_TEXTURE_INFO_COUNT; ++i)
|
||||
for (U32 i = 0; i < GLTF_TEXTURE_INFO_COUNT; ++i)
|
||||
{
|
||||
if (mTextureId[i] == old_id)
|
||||
{
|
||||
|
|
@ -834,6 +904,7 @@ bool LLGLTFMaterial::replaceLocalTexture(const LLUUID& tracking_id, const LLUUID
|
|||
{
|
||||
mTrackingIdToLocalTexture.erase(tracking_id);
|
||||
}
|
||||
updateLocalTexDataDigest();
|
||||
|
||||
return res;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -81,7 +81,7 @@ public:
|
|||
ALPHA_MODE_MASK
|
||||
};
|
||||
|
||||
LLGLTFMaterial() {}
|
||||
LLGLTFMaterial();
|
||||
LLGLTFMaterial(const LLGLTFMaterial& rhs);
|
||||
|
||||
LLGLTFMaterial& operator=(const LLGLTFMaterial& rhs);
|
||||
|
|
@ -110,25 +110,6 @@ public:
|
|||
static const char* const GLTF_FILE_EXTENSION_TRANSFORM_ROTATION;
|
||||
static const LLUUID GLTF_OVERRIDE_NULL_UUID;
|
||||
|
||||
std::array<LLUUID, GLTF_TEXTURE_INFO_COUNT> mTextureId;
|
||||
std::array<TextureTransform, GLTF_TEXTURE_INFO_COUNT> mTextureTransform;
|
||||
|
||||
// NOTE: initialize values to defaults according to the GLTF spec
|
||||
// NOTE: these values should be in linear color space
|
||||
LLColor4 mBaseColor = LLColor4(1, 1, 1, 1);
|
||||
LLColor3 mEmissiveColor = LLColor3(0, 0, 0);
|
||||
|
||||
F32 mMetallicFactor = 1.f;
|
||||
F32 mRoughnessFactor = 1.f;
|
||||
F32 mAlphaCutoff = 0.5f;
|
||||
|
||||
bool mDoubleSided = false;
|
||||
AlphaMode mAlphaMode = ALPHA_MODE_OPAQUE;
|
||||
|
||||
// override specific flags for state that can't use off-by-epsilon or UUID hack
|
||||
bool mOverrideDoubleSided = false;
|
||||
bool mOverrideAlphaMode = false;
|
||||
|
||||
// get a UUID based on a hash of this LLGLTFMaterial
|
||||
LLUUID getHash() const;
|
||||
|
||||
|
|
@ -229,10 +210,6 @@ public:
|
|||
virtual bool replaceLocalTexture(const LLUUID& tracking_id, const LLUUID &old_id, const LLUUID& new_id);
|
||||
virtual void updateTextureTracking();
|
||||
|
||||
// These fields are local to viewer and are a part of local bitmap support
|
||||
typedef std::map<LLUUID, LLUUID> local_tex_map_t;
|
||||
local_tex_map_t mTrackingIdToLocalTexture;
|
||||
|
||||
protected:
|
||||
static LLVector2 vec2FromJson(const std::map<std::string, tinygltf::Value>& object, const char* key, const LLVector2& default_value);
|
||||
static F32 floatFromJson(const std::map<std::string, tinygltf::Value>& object, const char* key, const F32 default_value);
|
||||
|
|
@ -249,4 +226,41 @@ protected:
|
|||
void writeToTexture(tinygltf::Model& model, T& texture_info, TextureInfo texture_info_id, bool force_write = false) const;
|
||||
template<typename T>
|
||||
static void writeToTexture(tinygltf::Model& model, T& texture_info, const LLUUID& texture_id, const TextureTransform& transform, bool force_write = false);
|
||||
|
||||
// Used to update the digest of the mTrackingIdToLocalTexture map each time
|
||||
// it is changed; this way, that digest can be used by the fast getHash()
|
||||
// method intsead of having to hash all individual keys and values. HB
|
||||
void updateLocalTexDataDigest();
|
||||
|
||||
public:
|
||||
// These fields are local to viewer and are a part of local bitmap support
|
||||
// IMPORTANT: do not move this member down (and do not move
|
||||
// mLocalTexDataDigest either): the getHash() method does rely on the
|
||||
// current ordering. HB
|
||||
typedef std::map<LLUUID, LLUUID> local_tex_map_t;
|
||||
local_tex_map_t mTrackingIdToLocalTexture;
|
||||
|
||||
// Used to store a digest of mTrackingIdToLocalTexture when the latter is
|
||||
// not empty, or zero otherwise. HB
|
||||
U64 mLocalTexDataDigest;
|
||||
|
||||
std::array<LLUUID, GLTF_TEXTURE_INFO_COUNT> mTextureId;
|
||||
std::array<TextureTransform, GLTF_TEXTURE_INFO_COUNT> mTextureTransform;
|
||||
|
||||
// NOTE: initialize values to defaults according to the GLTF spec
|
||||
// NOTE: these values should be in linear color space
|
||||
LLColor4 mBaseColor;
|
||||
LLColor3 mEmissiveColor;
|
||||
|
||||
F32 mMetallicFactor;
|
||||
F32 mRoughnessFactor;
|
||||
F32 mAlphaCutoff;
|
||||
|
||||
AlphaMode mAlphaMode;
|
||||
bool mDoubleSided;
|
||||
|
||||
// Override specific flags for state that can't use off-by-epsilon or UUID
|
||||
// hack
|
||||
bool mOverrideDoubleSided;
|
||||
bool mOverrideAlphaMode;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -111,6 +111,9 @@ void LLCubeMap::initRawData(const std::vector<LLPointer<LLImageRaw> >& rawimages
|
|||
// Yes, I know that this is inefficient! - djs 08/08/02
|
||||
for (int i = 0; i < 6; i++)
|
||||
{
|
||||
LLImageDataSharedLock lockIn(rawimages[i]);
|
||||
LLImageDataLock lockOut(mRawImages[i]);
|
||||
|
||||
const U8 *sd = rawimages[i]->getData();
|
||||
U8 *td = mRawImages[i]->getData();
|
||||
|
||||
|
|
|
|||
|
|
@ -772,6 +772,7 @@ U8 LLFontFreetype::getStyle() const
|
|||
void LLFontFreetype::setSubImageLuminanceAlpha(U32 x, U32 y, U32 bitmap_num, U32 width, U32 height, U8 *data, S32 stride) const
|
||||
{
|
||||
LLImageRaw *image_raw = mFontBitmapCachep->getImageRaw(bitmap_num);
|
||||
LLImageDataLock lock(image_raw);
|
||||
|
||||
llassert(!mIsFallback);
|
||||
llassert(image_raw && (image_raw->getComponents() == 2));
|
||||
|
|
|
|||
|
|
@ -1214,7 +1214,7 @@ LLFontGL* LLFontGL::getFontDefault()
|
|||
std::string LLFontGL::getFontPathSystem()
|
||||
{
|
||||
#if LL_DARWIN
|
||||
// HACK for Mac OS X
|
||||
// HACK for macOS
|
||||
return "/System/Library/Fonts/";
|
||||
|
||||
#elif LL_WINDOWS
|
||||
|
|
|
|||
|
|
@ -56,7 +56,7 @@ const F32 MIN_TEXTURE_LIFETIME = 10.f;
|
|||
U32 wpo2(U32 i);
|
||||
|
||||
|
||||
// texture memory accounting (for OS X)
|
||||
// texture memory accounting (for macOS)
|
||||
static LLMutex sTexMemMutex;
|
||||
static std::unordered_map<U32, U64> sTextureAllocs;
|
||||
static U64 sTextureBytes = 0;
|
||||
|
|
@ -1887,6 +1887,8 @@ BOOL LLImageGL::readBackRaw(S32 discard_level, LLImageRaw* imageraw, bool compre
|
|||
}
|
||||
//-----------------------------------------------------------------------------------------------
|
||||
|
||||
LLImageDataLock lock(imageraw);
|
||||
|
||||
if (is_compressed)
|
||||
{
|
||||
LLGLint glbytes;
|
||||
|
|
|
|||
|
|
@ -51,14 +51,6 @@ char LLResMgr::getDecimalPoint() const
|
|||
{
|
||||
char decimal = localeconv()->decimal_point[0];
|
||||
|
||||
#if LL_DARWIN
|
||||
// On the Mac, locale support is broken before 10.4, which causes things to go all pear-shaped.
|
||||
if(decimal == 0)
|
||||
{
|
||||
decimal = '.';
|
||||
}
|
||||
#endif
|
||||
|
||||
return decimal;
|
||||
}
|
||||
|
||||
|
|
@ -66,14 +58,6 @@ char LLResMgr::getThousandsSeparator() const
|
|||
{
|
||||
char separator = localeconv()->thousands_sep[0];
|
||||
|
||||
#if LL_DARWIN
|
||||
// On the Mac, locale support is broken before 10.4, which causes things to go all pear-shaped.
|
||||
if(separator == 0)
|
||||
{
|
||||
separator = ',';
|
||||
}
|
||||
#endif
|
||||
|
||||
return separator;
|
||||
}
|
||||
|
||||
|
|
@ -81,14 +65,6 @@ char LLResMgr::getMonetaryDecimalPoint() const
|
|||
{
|
||||
char decimal = localeconv()->mon_decimal_point[0];
|
||||
|
||||
#if LL_DARWIN
|
||||
// On the Mac, locale support is broken before 10.4, which causes things to go all pear-shaped.
|
||||
if(decimal == 0)
|
||||
{
|
||||
decimal = '.';
|
||||
}
|
||||
#endif
|
||||
|
||||
return decimal;
|
||||
}
|
||||
|
||||
|
|
@ -96,14 +72,6 @@ char LLResMgr::getMonetaryThousandsSeparator() const
|
|||
{
|
||||
char separator = localeconv()->mon_thousands_sep[0];
|
||||
|
||||
#if LL_DARWIN
|
||||
// On the Mac, locale support is broken before 10.4, which causes things to go all pear-shaped.
|
||||
if(separator == 0)
|
||||
{
|
||||
separator = ',';
|
||||
}
|
||||
#endif
|
||||
|
||||
return separator;
|
||||
}
|
||||
|
||||
|
|
@ -115,29 +83,6 @@ std::string LLResMgr::getMonetaryString( S32 input ) const
|
|||
|
||||
LLLocale locale(LLLocale::USER_LOCALE);
|
||||
struct lconv *conv = localeconv();
|
||||
|
||||
#if LL_DARWIN
|
||||
// On the Mac, locale support is broken before 10.4, which causes things to go all pear-shaped.
|
||||
// Fake up a conv structure with some reasonable values for the fields this function uses.
|
||||
struct lconv fakeconv;
|
||||
char fake_neg[2] = "-";
|
||||
char fake_mon_group[4] = "\x03\x03\x00"; // commas every 3 digits
|
||||
if(conv->negative_sign[0] == 0) // Real locales all seem to have something here...
|
||||
{
|
||||
fakeconv = *conv; // start with what's there.
|
||||
switch(mLocale)
|
||||
{
|
||||
default: // Unknown -- use the US defaults.
|
||||
case LLLOCALE_USA:
|
||||
case LLLOCALE_UK: // UK ends up being the same as US for the items used here.
|
||||
fakeconv.negative_sign = fake_neg;
|
||||
fakeconv.mon_grouping = fake_mon_group;
|
||||
fakeconv.n_sign_posn = 1; // negative sign before the string
|
||||
break;
|
||||
}
|
||||
conv = &fakeconv;
|
||||
}
|
||||
#endif
|
||||
|
||||
char* negative_sign = conv->negative_sign;
|
||||
char separator = getMonetaryThousandsSeparator();
|
||||
|
|
|
|||
|
|
@ -154,24 +154,24 @@ protected:
|
|||
// We shouldn't ever need to set this directly
|
||||
//virtual void setViewModel(const LLViewModelPtr&);
|
||||
|
||||
virtual BOOL postBuild();
|
||||
/*virtual*/ BOOL postBuild() override;
|
||||
|
||||
public:
|
||||
// LLView interface
|
||||
/*virtual*/ BOOL setLabelArg( const std::string& key, const LLStringExplicit& text );
|
||||
/*virtual*/ BOOL isCtrl() const;
|
||||
/*virtual*/ void onMouseEnter(S32 x, S32 y, MASK mask);
|
||||
/*virtual*/ void onMouseLeave(S32 x, S32 y, MASK mask);
|
||||
/*virtual*/ BOOL canFocusChildren() const;
|
||||
/*virtual*/ BOOL handleMouseDown(S32 x, S32 y, MASK mask);
|
||||
/*virtual*/ BOOL handleMouseUp(S32 x, S32 y, MASK mask);
|
||||
/*virtual*/ BOOL handleRightMouseDown(S32 x, S32 y, MASK mask);
|
||||
/*virtual*/ BOOL handleRightMouseUp(S32 x, S32 y, MASK mask);
|
||||
/*virtual*/ BOOL handleDoubleClick(S32 x, S32 y, MASK mask);
|
||||
/*virtual*/ BOOL setLabelArg( const std::string& key, const LLStringExplicit& text ) override;
|
||||
/*virtual*/ BOOL isCtrl() const override;
|
||||
/*virtual*/ void onMouseEnter(S32 x, S32 y, MASK mask) override;
|
||||
/*virtual*/ void onMouseLeave(S32 x, S32 y, MASK mask) override;
|
||||
/*virtual*/ BOOL canFocusChildren() const override;
|
||||
/*virtual*/ BOOL handleMouseDown(S32 x, S32 y, MASK mask) override;
|
||||
/*virtual*/ BOOL handleMouseUp(S32 x, S32 y, MASK mask) override;
|
||||
/*virtual*/ BOOL handleRightMouseDown(S32 x, S32 y, MASK mask) override;
|
||||
/*virtual*/ BOOL handleRightMouseUp(S32 x, S32 y, MASK mask) override;
|
||||
/*virtual*/ BOOL handleDoubleClick(S32 x, S32 y, MASK mask) override;
|
||||
|
||||
// From LLFocusableElement
|
||||
/*virtual*/ void setFocus( BOOL b );
|
||||
/*virtual*/ BOOL hasFocus() const;
|
||||
/*virtual*/ void setFocus( BOOL b ) override;
|
||||
/*virtual*/ BOOL hasFocus() const override;
|
||||
|
||||
// New virtuals
|
||||
|
||||
|
|
@ -334,7 +334,7 @@ protected:
|
|||
static F32 sActiveControlTransparency;
|
||||
static F32 sInactiveControlTransparency;
|
||||
|
||||
virtual void addInfo(LLSD & info);
|
||||
/*virtual*/ void addInfo(LLSD & info) override;
|
||||
|
||||
private:
|
||||
|
||||
|
|
|
|||
|
|
@ -92,7 +92,7 @@ public:
|
|||
// </FS:ND>
|
||||
|
||||
#ifdef LL_DARWIN
|
||||
// We only actually use this for OS X.
|
||||
// We only actually use this for macOS.
|
||||
virtual void handleModifier(MASK mask) = 0;
|
||||
#endif // LL_DARWIN
|
||||
|
||||
|
|
|
|||
|
|
@ -1259,7 +1259,7 @@ F32 LLWindowMacOSX::getNativeAspectRatio()
|
|||
|
||||
F32 LLWindowMacOSX::getPixelAspectRatio()
|
||||
{
|
||||
//OS X always enforces a 1:1 pixel aspect ratio, regardless of video mode
|
||||
//macOS always enforces a 1:1 pixel aspect ratio, regardless of video mode
|
||||
return 1.f;
|
||||
}
|
||||
|
||||
|
|
@ -1291,7 +1291,7 @@ void LLWindowMacOSX::afterDialog()
|
|||
|
||||
void LLWindowMacOSX::flashIcon(F32 seconds)
|
||||
{
|
||||
// For consistency with OS X conventions, the number of seconds given is ignored and
|
||||
// For consistency with macOS conventions, the number of seconds given is ignored and
|
||||
// left up to the OS (which will actually bounce it for one second).
|
||||
requestUserAttention();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
* @file mac_volume_catcher.cpp
|
||||
* @brief A Mac OS X specific hack to control the volume level of all audio channels opened by a process.
|
||||
* @brief A macOS specific hack to control the volume level of all audio channels opened by a process.
|
||||
*
|
||||
* @cond
|
||||
* $LicenseInfo:firstyear=2010&license=viewerlgpl$
|
||||
|
|
|
|||
|
|
@ -827,7 +827,7 @@ void MediaPluginCEF::receiveMessage(const char* message_string)
|
|||
S32 y = message_in.getValueS32("y");
|
||||
|
||||
// only even send left mouse button events to the CEF library
|
||||
// (partially prompted by crash in OS X CEF when sending right button events)
|
||||
// (partially prompted by crash in macOS CEF when sending right button events)
|
||||
// we catch the right click in viewer and display our own context menu anyway
|
||||
S32 button = message_in.getValueS32("button");
|
||||
dullahan::EMouseButton btn = dullahan::MB_MOUSE_BUTTON_LEFT;
|
||||
|
|
|
|||
|
|
@ -11959,7 +11959,7 @@ Change of this parameter will affect the layout of buttons in notification toast
|
|||
<key>RenderHiDPI</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Enable support for HiDPI displays, like Retina (MacOS X ONLY, requires restart)</string>
|
||||
<string>Enable support for HiDPI displays, like Retina (macOS ONLY, requires restart)</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
|
|
|
|||
|
|
@ -121,9 +121,9 @@ void FSPanelPrefs::apply()
|
|||
}
|
||||
}
|
||||
|
||||
void FSPanelPrefs::cancel()
|
||||
void FSPanelPrefs::cancel(const std::vector<std::string> settings_to_skip)
|
||||
{
|
||||
LLPanelPreference::cancel();
|
||||
LLPanelPreference::cancel(settings_to_skip);
|
||||
}
|
||||
|
||||
void FSPanelPrefs::refreshBeamLists()
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ public:
|
|||
/*virtual*/ BOOL postBuild();
|
||||
/*virtual*/ void onOpen(const LLSD& key);
|
||||
/*virtual*/ void apply();
|
||||
/*virtual*/ void cancel();
|
||||
/*virtual*/ void cancel(const std::vector<std::string> settings_to_skip = {});
|
||||
|
||||
void refreshBeamLists();
|
||||
|
||||
|
|
|
|||
|
|
@ -1679,8 +1679,9 @@ void LLAgent::pitch(F32 angle)
|
|||
// after left-clicking the mouse on the avatar and dragging down
|
||||
//
|
||||
// The issue is observed on angle below 10 degrees
|
||||
bool isMouseLookOn = mControlFlags & AGENT_CONTROL_MOUSELOOK;
|
||||
const F32 look_down_limit = 179.f * DEG_TO_RAD;
|
||||
const F32 look_up_limit = 10.f * DEG_TO_RAD;
|
||||
const F32 look_up_limit = (isMouseLookOn ? 1.f : 10.f) * DEG_TO_RAD;
|
||||
|
||||
F32 angle_from_skyward = acos(mFrameAgent.getAtAxis() * skyward);
|
||||
|
||||
|
|
|
|||
|
|
@ -2740,6 +2740,7 @@ void LLAppViewer::initLoggingAndGetLastDuration()
|
|||
|
||||
// Set the log file to SecondLife.log
|
||||
LLError::logToFile(log_file);
|
||||
LL_INFOS() << "Started logging to " << log_file << LL_ENDL;
|
||||
if (!duration_log_msg.empty())
|
||||
{
|
||||
LL_WARNS("MarkerFile") << duration_log_msg << LL_ENDL;
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@
|
|||
*/
|
||||
|
||||
#if !defined LL_DARWIN
|
||||
#error "Use only with Mac OS X"
|
||||
#error "Use only with macOS"
|
||||
#endif
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@
|
|||
#include "llviewerprecompiledheaders.h"
|
||||
|
||||
#if !defined LL_DARWIN
|
||||
#error "Use only with Mac OS X"
|
||||
#error "Use only with macOS"
|
||||
#endif
|
||||
|
||||
#define LL_CARBON_CRASH_HANDLER 1
|
||||
|
|
|
|||
|
|
@ -852,11 +852,14 @@ void LLBumpImageList::onSourceStandardLoaded( BOOL success, LLViewerFetchedTextu
|
|||
|
||||
void LLBumpImageList::generateNormalMapFromAlpha(LLImageRaw* src, LLImageRaw* nrm_image)
|
||||
{
|
||||
LLImageDataSharedLock lockIn(src);
|
||||
LLImageDataLock lockOut(nrm_image);
|
||||
|
||||
U8* nrm_data = nrm_image->getData();
|
||||
S32 resX = src->getWidth();
|
||||
S32 resY = src->getHeight();
|
||||
|
||||
U8* src_data = src->getData();
|
||||
const U8* src_data = src->getData();
|
||||
|
||||
S32 src_cmp = src->getComponents();
|
||||
|
||||
|
|
@ -918,6 +921,7 @@ void LLBumpImageList::onSourceLoaded( BOOL success, LLViewerTexture *src_vi, LLI
|
|||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL;
|
||||
|
||||
LLImageDataSharedLock lock(src);
|
||||
|
||||
bump_image_map_t& entries_list(bump_code == BE_BRIGHTNESS ? gBumpImageList.mBrightnessEntries : gBumpImageList.mDarknessEntries );
|
||||
bump_image_map_t::iterator iter = entries_list.find(source_asset_id);
|
||||
|
|
@ -940,7 +944,7 @@ void LLBumpImageList::onSourceLoaded( BOOL success, LLViewerTexture *src_vi, LLI
|
|||
U8* dst_data = dst_image->getData();
|
||||
S32 dst_data_size = dst_image->getDataSize();
|
||||
|
||||
U8* src_data = src->getData();
|
||||
const U8* src_data = src->getData();
|
||||
S32 src_data_size = src->getDataSize();
|
||||
|
||||
S32 src_components = src->getComponents();
|
||||
|
|
|
|||
|
|
@ -472,6 +472,8 @@ void saveChart(const std::string& label, const char* suffix, LLImageRaw* scratch
|
|||
// disable use of glReadPixels which messes up nVidia nSight graphics debugging
|
||||
if (!LLRender::sNsightDebugSupport)
|
||||
{
|
||||
LLImageDataSharedLock lock(scratch);
|
||||
|
||||
//read result back into raw image
|
||||
glReadPixels(0, 0, 1024, 512, GL_RGB, GL_UNSIGNED_BYTE, scratch->getData());
|
||||
|
||||
|
|
|
|||
|
|
@ -97,7 +97,7 @@ public:
|
|||
}
|
||||
|
||||
void setLandmarkID(const LLUUID& id) { mLandmarkID = id; }
|
||||
const LLUUID& getLandmarkId() const { return mLandmarkID; }
|
||||
const LLUUID& getLandmarkID() const { return mLandmarkID; }
|
||||
|
||||
const std::string& getName()
|
||||
{
|
||||
|
|
@ -299,7 +299,7 @@ public:
|
|||
}
|
||||
|
||||
void setLandmarkID(const LLUUID& id){ mLandmarkInfoGetter.setLandmarkID(id); }
|
||||
const LLUUID& getLandmarkId() const { return mLandmarkInfoGetter.getLandmarkId(); }
|
||||
const LLUUID& getLandmarkID() const { return mLandmarkInfoGetter.getLandmarkID(); }
|
||||
|
||||
void onMouseEnter(S32 x, S32 y, MASK mask)
|
||||
{
|
||||
|
|
@ -363,7 +363,8 @@ public:
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
void setLandmarkID(const LLUUID& id){ mLandmarkInfoGetter.setLandmarkID(id); }
|
||||
const LLUUID& getLandmarkID() const { return mLandmarkInfoGetter.getLandmarkID(); }
|
||||
void setLandmarkID(const LLUUID& id) { mLandmarkInfoGetter.setLandmarkID(id); }
|
||||
|
||||
virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask)
|
||||
{
|
||||
|
|
@ -411,15 +412,44 @@ private:
|
|||
class LLFavoriteLandmarkToggleableMenu : public LLToggleableMenu
|
||||
{
|
||||
public:
|
||||
virtual BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
|
||||
EDragAndDropType cargo_type,
|
||||
void* cargo_data,
|
||||
EAcceptance* accept,
|
||||
std::string& tooltip_msg)
|
||||
{
|
||||
*accept = ACCEPT_NO;
|
||||
return TRUE;
|
||||
}
|
||||
// virtual
|
||||
BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, EDragAndDropType cargo_type,
|
||||
void* cargo_data, EAcceptance* accept, std::string& tooltip_msg) override
|
||||
{
|
||||
mToolbar->handleDragAndDropToMenu(x, y, mask, drop, cargo_type, cargo_data, accept, tooltip_msg);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// virtual
|
||||
BOOL handleHover(S32 x, S32 y, MASK mask) override
|
||||
{
|
||||
mIsHovering = true;
|
||||
LLToggleableMenu::handleHover(x, y, mask);
|
||||
mIsHovering = false;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// virtual
|
||||
void setVisible(BOOL visible) override
|
||||
{
|
||||
// Avoid of hiding the menu during hovering
|
||||
if (visible || !mIsHovering)
|
||||
{
|
||||
LLToggleableMenu::setVisible(visible);
|
||||
}
|
||||
}
|
||||
|
||||
void setToolbar(LLFavoritesBarCtrl* toolbar)
|
||||
{
|
||||
mToolbar = toolbar;
|
||||
}
|
||||
|
||||
~LLFavoriteLandmarkToggleableMenu()
|
||||
{
|
||||
// Enable subsequent setVisible(FALSE)
|
||||
mIsHovering = false;
|
||||
setVisible(FALSE);
|
||||
}
|
||||
|
||||
protected:
|
||||
LLFavoriteLandmarkToggleableMenu(const LLToggleableMenu::Params& p):
|
||||
|
|
@ -427,6 +457,10 @@ protected:
|
|||
{
|
||||
}
|
||||
|
||||
private:
|
||||
LLFavoritesBarCtrl* mToolbar { nullptr };
|
||||
bool mIsHovering { false };
|
||||
|
||||
friend class LLUICtrlFactory;
|
||||
};
|
||||
|
||||
|
|
@ -507,12 +541,12 @@ LLFavoritesBarCtrl::LLFavoritesBarCtrl(const LLFavoritesBarCtrl::Params& p)
|
|||
mOverflowMenuHandle(),
|
||||
mContextMenuHandle(),
|
||||
mImageDragIndication(p.image_drag_indication),
|
||||
mShowDragMarker(FALSE),
|
||||
mShowDragMarker(false),
|
||||
mLandingTab(NULL),
|
||||
mLastTab(NULL),
|
||||
mTabsHighlightEnabled(TRUE),
|
||||
mUpdateDropDownItems(true),
|
||||
mRestoreOverflowMenu(false),
|
||||
mDragToOverflowMenu(false),
|
||||
mGetPrevItems(true),
|
||||
mMouseX(0),
|
||||
mMouseY(0),
|
||||
|
|
@ -563,17 +597,16 @@ LLFavoritesBarCtrl::LLFavoritesBarCtrl(const LLFavoritesBarCtrl::Params& p)
|
|||
|
||||
LLFavoritesBarCtrl::~LLFavoritesBarCtrl()
|
||||
{
|
||||
gInventory.removeObserver(this);
|
||||
gInventory.removeObserver(this);
|
||||
|
||||
if (mOverflowMenuHandle.get()) mOverflowMenuHandle.get()->die();
|
||||
if (mContextMenuHandle.get()) mContextMenuHandle.get()->die();
|
||||
if (mOverflowMenuHandle.get())
|
||||
mOverflowMenuHandle.get()->die();
|
||||
if (mContextMenuHandle.get())
|
||||
mContextMenuHandle.get()->die();
|
||||
}
|
||||
|
||||
BOOL LLFavoritesBarCtrl::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
|
||||
EDragAndDropType cargo_type,
|
||||
void* cargo_data,
|
||||
EAcceptance* accept,
|
||||
std::string& tooltip_msg)
|
||||
EDragAndDropType cargo_type, void* cargo_data, EAcceptance* accept, std::string& tooltip_msg)
|
||||
{
|
||||
*accept = ACCEPT_NO;
|
||||
|
||||
|
|
@ -599,26 +632,52 @@ BOOL LLFavoritesBarCtrl::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
|
|||
// Copy the item into the favorites folder (if it's not already there).
|
||||
LLInventoryItem *item = (LLInventoryItem *)cargo_data;
|
||||
|
||||
if (LLFavoriteLandmarkButton* dest = dynamic_cast<LLFavoriteLandmarkButton*>(findChildByLocalCoords(x, y)))
|
||||
if (mDragToOverflowMenu)
|
||||
{
|
||||
setLandingTab(dest);
|
||||
LLView* overflow_menu = mOverflowMenuHandle.get();
|
||||
if (overflow_menu && !overflow_menu->isDead() && overflow_menu->getVisible())
|
||||
{
|
||||
overflow_menu->handleHover(x, y, mask);
|
||||
}
|
||||
}
|
||||
else if (mLastTab && (x >= mLastTab->getRect().mRight))
|
||||
else // Drag to the toolbar itself
|
||||
{
|
||||
/*
|
||||
* the condition dest == NULL can be satisfied not only in the case
|
||||
* of dragging to the right from the last tab of the favbar. there is a
|
||||
* small gap between each tab. if the user drags something exactly there
|
||||
* then mLandingTab will be set to NULL and the dragged item will be pushed
|
||||
* to the end of the favorites bar. this is incorrect behavior. that's why
|
||||
* we need an additional check which excludes the case described previously
|
||||
* making sure that the mouse pointer is beyond the last tab.
|
||||
*/
|
||||
setLandingTab(NULL);
|
||||
// Drag to a landmark button?
|
||||
if (LLFavoriteLandmarkButton* dest = dynamic_cast<LLFavoriteLandmarkButton*>(findChildByLocalCoords(x, y)))
|
||||
{
|
||||
setLandingTab(dest);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Drag to the "More" button?
|
||||
if (mMoreCtrl && mMoreCtrl->getVisible() && mMoreCtrl->getRect().pointInRect(x, y))
|
||||
{
|
||||
LLView* overflow_menu = mOverflowMenuHandle.get();
|
||||
if (!overflow_menu || overflow_menu->isDead() || !overflow_menu->getVisible())
|
||||
{
|
||||
showDropDownMenu();
|
||||
}
|
||||
}
|
||||
|
||||
// Drag to the right of the last landmark button?
|
||||
if (mLastTab && (x >= mLastTab->getRect().mRight))
|
||||
{
|
||||
/*
|
||||
* the condition dest == NULL can be satisfied not only in the case
|
||||
* of dragging to the right from the last tab of the favbar. there is a
|
||||
* small gap between each tab. if the user drags something exactly there
|
||||
* then mLandingTab will be set to NULL and the dragged item will be pushed
|
||||
* to the end of the favorites bar. this is incorrect behavior. that's why
|
||||
* we need an additional check which excludes the case described previously
|
||||
* making sure that the mouse pointer is beyond the last tab.
|
||||
*/
|
||||
setLandingTab(NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// check if we are dragging an existing item from the favorites bar
|
||||
bool existing_drop = false;
|
||||
// Check whether we are dragging an existing item from the favorites bar
|
||||
bool existing_item = false;
|
||||
if (item && mDragItemId == item->getUUID())
|
||||
{
|
||||
// There is a chance of mDragItemId being obsolete
|
||||
|
|
@ -626,21 +685,19 @@ BOOL LLFavoritesBarCtrl::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
|
|||
// results in viewer not geting a 'mouse up' signal
|
||||
for (LLInventoryModel::item_array_t::iterator i = mItems.begin(); i != mItems.end(); ++i)
|
||||
{
|
||||
LLViewerInventoryItem* currItem = *i;
|
||||
|
||||
if (currItem->getUUID() == mDragItemId)
|
||||
if ((*i)->getUUID() == mDragItemId)
|
||||
{
|
||||
existing_drop = true;
|
||||
existing_item = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (existing_drop)
|
||||
if (existing_item)
|
||||
{
|
||||
*accept = ACCEPT_YES_SINGLE;
|
||||
|
||||
showDragMarker(TRUE);
|
||||
showDragMarker(true);
|
||||
|
||||
if (drop)
|
||||
{
|
||||
|
|
@ -658,14 +715,14 @@ BOOL LLFavoritesBarCtrl::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
|
|||
|
||||
*accept = ACCEPT_YES_COPY_MULTI;
|
||||
|
||||
showDragMarker(TRUE);
|
||||
showDragMarker(true);
|
||||
|
||||
if (drop)
|
||||
{
|
||||
if (mItems.empty())
|
||||
{
|
||||
setLandingTab(NULL);
|
||||
mLastTab = NULL;
|
||||
mLastTab = NULL;
|
||||
}
|
||||
handleNewFavoriteDragAndDrop(item, favorites_id, x, y);
|
||||
}
|
||||
|
|
@ -679,82 +736,56 @@ BOOL LLFavoritesBarCtrl::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
bool LLFavoritesBarCtrl::handleDragAndDropToMenu(S32 x, S32 y, MASK mask, BOOL drop,
|
||||
EDragAndDropType cargo_type, void* cargo_data, EAcceptance* accept, std::string& tooltip_msg)
|
||||
{
|
||||
mDragToOverflowMenu = true;
|
||||
BOOL handled = handleDragAndDrop(x, y, mask, drop, cargo_type, cargo_data, accept, tooltip_msg);
|
||||
mDragToOverflowMenu = false;
|
||||
return handled;
|
||||
}
|
||||
|
||||
void LLFavoritesBarCtrl::handleExistingFavoriteDragAndDrop(S32 x, S32 y)
|
||||
{
|
||||
if (mItems.empty())
|
||||
{
|
||||
// Isn't supposed to be empty
|
||||
if (LL_UNLIKELY(mItems.empty()))
|
||||
return;
|
||||
|
||||
LLUUID target_id;
|
||||
bool insert_before = false;
|
||||
if (!findDragAndDropTarget(target_id, insert_before, x, y))
|
||||
return;
|
||||
|
||||
// There is no need to handle if an item was dragged onto itself
|
||||
if (target_id == mDragItemId)
|
||||
return;
|
||||
|
||||
// Move the dragged item to the right place in the array
|
||||
LLInventoryModel::updateItemsOrder(mItems, mDragItemId, target_id, insert_before);
|
||||
LLFavoritesOrderStorage::instance().saveItemsOrder(mItems);
|
||||
|
||||
LLView* menu = mOverflowMenuHandle.get();
|
||||
if (menu && !menu->isDead() && menu->getVisible())
|
||||
{
|
||||
updateOverflowMenuItems();
|
||||
positionAndShowOverflowMenu();
|
||||
}
|
||||
|
||||
// Identify the button hovered and the side to drop
|
||||
LLFavoriteLandmarkButton* dest = dynamic_cast<LLFavoriteLandmarkButton*>(mLandingTab);
|
||||
bool insert_before = true;
|
||||
if (!dest)
|
||||
{
|
||||
insert_before = false;
|
||||
dest = dynamic_cast<LLFavoriteLandmarkButton*>(mLastTab);
|
||||
}
|
||||
|
||||
// There is no need to handle if an item was dragged onto itself
|
||||
if (dest && dest->getLandmarkId() == mDragItemId)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Insert the dragged item in the right place
|
||||
if (dest)
|
||||
{
|
||||
LLInventoryModel::updateItemsOrder(mItems, mDragItemId, dest->getLandmarkId(), insert_before);
|
||||
}
|
||||
else
|
||||
{
|
||||
// This can happen when the item list is empty
|
||||
mItems.push_back(gInventory.getItem(mDragItemId));
|
||||
}
|
||||
|
||||
LLFavoritesOrderStorage::instance().saveItemsOrder(mItems);
|
||||
|
||||
LLToggleableMenu* menu = (LLToggleableMenu*) mOverflowMenuHandle.get();
|
||||
|
||||
if (menu && menu->getVisible())
|
||||
{
|
||||
menu->setVisible(FALSE);
|
||||
showDropDownMenu();
|
||||
}
|
||||
}
|
||||
|
||||
void LLFavoritesBarCtrl::handleNewFavoriteDragAndDrop(LLInventoryItem *item, const LLUUID& favorites_id, S32 x, S32 y)
|
||||
{
|
||||
// Identify the button hovered and the side to drop
|
||||
LLFavoriteLandmarkButton* dest = NULL;
|
||||
bool insert_before = true;
|
||||
if (!mItems.empty())
|
||||
{
|
||||
// [MAINT-2386] When multiple landmarks are selected and dragged onto an empty favorites bar,
|
||||
// the viewer would crash when casting mLastTab below, as mLastTab is still null when the
|
||||
// second landmark is being added.
|
||||
// To ensure mLastTab is valid, we need to call updateButtons() at the end of this function
|
||||
dest = dynamic_cast<LLFavoriteLandmarkButton*>(mLandingTab);
|
||||
if (!dest)
|
||||
{
|
||||
insert_before = false;
|
||||
dest = dynamic_cast<LLFavoriteLandmarkButton*>(mLastTab);
|
||||
}
|
||||
}
|
||||
|
||||
// There is no need to handle if an item was dragged onto itself
|
||||
if (dest && dest->getLandmarkId() == mDragItemId)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
LLUUID target_id;
|
||||
bool insert_before = false;
|
||||
// There is no need to handle if an item was dragged onto itself
|
||||
if (findDragAndDropTarget(target_id, insert_before, x, y) && (target_id == mDragItemId))
|
||||
return;
|
||||
|
||||
LLPointer<LLViewerInventoryItem> viewer_item = new LLViewerInventoryItem(item);
|
||||
|
||||
// Insert the dragged item in the right place
|
||||
if (dest)
|
||||
// Insert the dragged item to the right place
|
||||
if (target_id.notNull())
|
||||
{
|
||||
insertItem(mItems, dest->getLandmarkId(), viewer_item, insert_before);
|
||||
insertItem(mItems, target_id, viewer_item, insert_before);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -810,10 +841,75 @@ void LLFavoritesBarCtrl::handleNewFavoriteDragAndDrop(LLInventoryItem *item, con
|
|||
// This also ensures that mLastTab will be valid when dropping multiple
|
||||
// landmarks to an empty favorites bar.
|
||||
updateButtons();
|
||||
|
||||
|
||||
LLView* overflow_menu = mOverflowMenuHandle.get();
|
||||
if (overflow_menu && !overflow_menu->isDead() && overflow_menu->getVisible())
|
||||
{
|
||||
updateOverflowMenuItems();
|
||||
positionAndShowOverflowMenu();
|
||||
}
|
||||
|
||||
LL_INFOS("FavoritesBar") << "Copied inventory item #" << item->getUUID() << " to favorites." << LL_ENDL;
|
||||
}
|
||||
|
||||
bool LLFavoritesBarCtrl::findDragAndDropTarget(LLUUID& target_id, bool& insert_before, S32 x, S32 y)
|
||||
{
|
||||
if (mItems.empty())
|
||||
return false;
|
||||
|
||||
if (mDragToOverflowMenu)
|
||||
{
|
||||
LLView* overflow_menu = mOverflowMenuHandle.get();
|
||||
if (LL_UNLIKELY(!overflow_menu || overflow_menu->isDead() || !overflow_menu->getVisible()))
|
||||
return false;
|
||||
|
||||
// Identify the menu item hovered and the side to drop
|
||||
LLFavoriteLandmarkMenuItem* target_item = dynamic_cast<LLFavoriteLandmarkMenuItem*>(overflow_menu->childFromPoint(x, y));
|
||||
if (target_item)
|
||||
{
|
||||
insert_before = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Choose the bottom landmark menu item
|
||||
auto begin = overflow_menu->getChildList()->begin();
|
||||
auto end = overflow_menu->getChildList()->end();
|
||||
auto check = [](const LLView* child) -> bool
|
||||
{
|
||||
return dynamic_cast<const LLFavoriteLandmarkMenuItem*>(child);
|
||||
};
|
||||
// Menu items are placed in the backward order, so the bottom goes first
|
||||
auto it = std::find_if(begin, end, check);
|
||||
if (LL_UNLIKELY(it == end))
|
||||
return false;
|
||||
target_item = (LLFavoriteLandmarkMenuItem*)*it;
|
||||
insert_before = false;
|
||||
}
|
||||
target_id = target_item->getLandmarkID();
|
||||
}
|
||||
else
|
||||
{
|
||||
// Identify the button hovered and the side to drop
|
||||
LLFavoriteLandmarkButton* hovered_button = dynamic_cast<LLFavoriteLandmarkButton*>(mLandingTab);
|
||||
if (hovered_button)
|
||||
{
|
||||
insert_before = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Choose the right landmark button
|
||||
hovered_button = dynamic_cast<LLFavoriteLandmarkButton*>(mLastTab);
|
||||
if (LL_UNLIKELY(!hovered_button))
|
||||
return false;
|
||||
|
||||
insert_before = false;
|
||||
}
|
||||
target_id = hovered_button->getLandmarkID();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//virtual
|
||||
void LLFavoritesBarCtrl::changed(U32 mask)
|
||||
{
|
||||
|
|
@ -884,7 +980,7 @@ void LLFavoritesBarCtrl::draw()
|
|||
mImageDragIndication->draw(rect.mRight, rect.getHeight(), w, h);
|
||||
}
|
||||
// Once drawn, mark this false so we won't draw it again (unless we hit the favorite bar again)
|
||||
mShowDragMarker = FALSE;
|
||||
mShowDragMarker = false;
|
||||
}
|
||||
if (mItemsChangedTimer.getStarted())
|
||||
{
|
||||
|
|
@ -980,7 +1076,7 @@ void LLFavoritesBarCtrl::updateButtons(bool force_update)
|
|||
if (item)
|
||||
{
|
||||
// an child's order and mItems should be same
|
||||
if (button->getLandmarkId() != item->getUUID() // sort order has been changed
|
||||
if (button->getLandmarkID() != item->getUUID() // sort order has been changed
|
||||
|| button->getLabelSelected() != item->getName()) // favorite's name has been changed
|
||||
{
|
||||
break;
|
||||
|
|
@ -1060,11 +1156,7 @@ void LLFavoritesBarCtrl::updateButtons(bool force_update)
|
|||
{
|
||||
// mMoreTextBox was removed, so LLFavoriteLandmarkButtons
|
||||
// should be the only ones in the list
|
||||
LLFavoriteLandmarkButton* button = dynamic_cast<LLFavoriteLandmarkButton*> (childs->back());
|
||||
if (button)
|
||||
{
|
||||
mLastTab = button;
|
||||
}
|
||||
mLastTab = dynamic_cast<LLFavoriteLandmarkButton*>(childs->back());
|
||||
}
|
||||
|
||||
mFirstDropDownItem = j;
|
||||
|
|
@ -1072,23 +1164,20 @@ void LLFavoritesBarCtrl::updateButtons(bool force_update)
|
|||
if (mFirstDropDownItem < mItems.size())
|
||||
{
|
||||
// if updateButton had been called it means:
|
||||
//or there are some new favorites, or width had been changed
|
||||
// or there are some new favorites, or width had been changed
|
||||
// so if we need to display chevron button, we must update dropdown items too.
|
||||
mUpdateDropDownItems = true;
|
||||
S32 buttonHGap = button_params.rect.left; // default value
|
||||
LLRect rect;
|
||||
// Chevron button should stay right aligned
|
||||
// <FS:Ansariel> Allow V3 and FS style favorites bar
|
||||
//rect.setOriginAndSize(getRect().mRight - mMoreTextBox->getRect().getWidth() - buttonHGap, 0,
|
||||
// mMoreTextBox->getRect().getWidth(),
|
||||
// mMoreTextBox->getRect().getHeight());
|
||||
//LLRect rect(mMoreTextBox->getRect());
|
||||
//rect.translate(getRect().mRight - rect.mRight - buttonHGap, 0);
|
||||
|
||||
//addChild(mMoreTextBox);
|
||||
//mMoreTextBox->setRect(rect);
|
||||
//mMoreTextBox->setVisible(TRUE);
|
||||
rect.setOriginAndSize(getRect().mRight - mMoreCtrl->getRect().getWidth() - buttonHGap, 0,
|
||||
mMoreCtrl->getRect().getWidth(),
|
||||
mMoreCtrl->getRect().getHeight());
|
||||
LLRect rect(mMoreCtrl->getRect());
|
||||
rect.translate(getRect().mRight - rect.mRight - buttonHGap, 0);
|
||||
|
||||
addChild(mMoreCtrl);
|
||||
mMoreCtrl->setRect(rect);
|
||||
|
|
@ -1225,17 +1314,19 @@ void LLFavoritesBarCtrl::showDropDownMenu()
|
|||
{
|
||||
if (mUpdateDropDownItems)
|
||||
{
|
||||
updateMenuItems(menu);
|
||||
updateOverflowMenuItems();
|
||||
}
|
||||
else
|
||||
{
|
||||
menu->buildDrawLabels();
|
||||
}
|
||||
|
||||
menu->buildDrawLabels();
|
||||
menu->updateParent(LLMenuGL::sMenuContainer);
|
||||
// <FS:Ansariel> Allow V3 and FS style favorites bar
|
||||
//menu->setButtonRect(mMoreTextBox->getRect(), this);
|
||||
menu->setButtonRect(mMoreCtrl->getRect(), this);
|
||||
// </FS:Ansariel>
|
||||
positionAndShowMenu(menu);
|
||||
mDropDownItemsCount = menu->getItemCount();
|
||||
positionAndShowOverflowMenu();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1249,12 +1340,14 @@ void LLFavoritesBarCtrl::createOverflowMenu()
|
|||
menu_p.max_scrollable_items = 10;
|
||||
menu_p.preferred_width = DROP_DOWN_MENU_WIDTH;
|
||||
|
||||
LLToggleableMenu* menu = LLUICtrlFactory::create<LLFavoriteLandmarkToggleableMenu>(menu_p);
|
||||
LLFavoriteLandmarkToggleableMenu* menu = LLUICtrlFactory::create<LLFavoriteLandmarkToggleableMenu>(menu_p);
|
||||
menu->setToolbar(this);
|
||||
mOverflowMenuHandle = menu->getHandle();
|
||||
}
|
||||
|
||||
void LLFavoritesBarCtrl::updateMenuItems(LLToggleableMenu* menu)
|
||||
void LLFavoritesBarCtrl::updateOverflowMenuItems()
|
||||
{
|
||||
LLToggleableMenu* menu = (LLToggleableMenu*)mOverflowMenuHandle.get();
|
||||
menu->empty();
|
||||
|
||||
U32 widest_item = 0;
|
||||
|
|
@ -1283,6 +1376,8 @@ void LLFavoritesBarCtrl::updateMenuItems(LLToggleableMenu* menu)
|
|||
menu->addChild(menu_item);
|
||||
}
|
||||
|
||||
menu->buildDrawLabels();
|
||||
mDropDownItemsCount = menu->getItemCount();
|
||||
addOpenLandmarksMenuItem(menu);
|
||||
mUpdateDropDownItems = false;
|
||||
}
|
||||
|
|
@ -1339,8 +1434,9 @@ void LLFavoritesBarCtrl::addOpenLandmarksMenuItem(LLToggleableMenu* menu)
|
|||
menu->addChild(menu_item);
|
||||
}
|
||||
|
||||
void LLFavoritesBarCtrl::positionAndShowMenu(LLToggleableMenu* menu)
|
||||
void LLFavoritesBarCtrl::positionAndShowOverflowMenu()
|
||||
{
|
||||
LLToggleableMenu* menu = (LLToggleableMenu*)mOverflowMenuHandle.get();
|
||||
U32 max_width = llmin(DROP_DOWN_MENU_WIDTH, getRect().getWidth());
|
||||
|
||||
S32 menu_x = getRect().getWidth() - max_width;
|
||||
|
|
@ -1631,7 +1727,7 @@ void LLFavoritesBarCtrl::onButtonMouseDown(LLUUID id, LLUICtrl* ctrl, S32 x, S32
|
|||
}
|
||||
|
||||
mDragItemId = id;
|
||||
mStartDrag = TRUE;
|
||||
mStartDrag = true;
|
||||
|
||||
S32 screenX, screenY;
|
||||
localPointToScreen(x, y, &screenX, &screenY);
|
||||
|
|
@ -1641,7 +1737,7 @@ void LLFavoritesBarCtrl::onButtonMouseDown(LLUUID id, LLUICtrl* ctrl, S32 x, S32
|
|||
|
||||
void LLFavoritesBarCtrl::onButtonMouseUp(LLUUID id, LLUICtrl* ctrl, S32 x, S32 y, MASK mask)
|
||||
{
|
||||
mStartDrag = FALSE;
|
||||
mStartDrag = false;
|
||||
mDragItemId = LLUUID::null;
|
||||
}
|
||||
|
||||
|
|
@ -1649,7 +1745,7 @@ void LLFavoritesBarCtrl::onEndDrag()
|
|||
{
|
||||
mEndDragConnection.disconnect();
|
||||
|
||||
showDragMarker(FALSE);
|
||||
showDragMarker(false);
|
||||
mDragItemId = LLUUID::null;
|
||||
LLView::getWindow()->setCursor(UI_CURSOR_ARROW);
|
||||
}
|
||||
|
|
@ -1667,7 +1763,7 @@ BOOL LLFavoritesBarCtrl::handleHover(S32 x, S32 y, MASK mask)
|
|||
DAD_LANDMARK, mDragItemId,
|
||||
LLToolDragAndDrop::SOURCE_LIBRARY);
|
||||
|
||||
mStartDrag = FALSE;
|
||||
mStartDrag = false;
|
||||
|
||||
return LLToolDragAndDrop::getInstance()->handleHover(x, y, mask);
|
||||
}
|
||||
|
|
@ -1696,6 +1792,7 @@ LLUICtrl* LLFavoritesBarCtrl::findChildByLocalCoords(S32 x, S32 y)
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ctrl;
|
||||
}
|
||||
|
||||
|
|
@ -2333,8 +2430,10 @@ bool LLFavoritesOrderStorage::isStorageUpdateNeeded()
|
|||
|
||||
void AddFavoriteLandmarkCallback::fire(const LLUUID& inv_item_id)
|
||||
{
|
||||
if (mTargetLandmarkId.isNull()) return;
|
||||
|
||||
LLFavoritesOrderStorage::instance().rearrangeFavoriteLandmarks(inv_item_id, mTargetLandmarkId);
|
||||
if (!mTargetLandmarkId.isNull())
|
||||
{
|
||||
LLFavoritesOrderStorage::instance().rearrangeFavoriteLandmarks(inv_item_id, mTargetLandmarkId);
|
||||
}
|
||||
}
|
||||
|
||||
// EOF
|
||||
|
|
|
|||
|
|
@ -59,22 +59,21 @@ protected:
|
|||
public:
|
||||
virtual ~LLFavoritesBarCtrl();
|
||||
|
||||
/*virtual*/ BOOL postBuild();
|
||||
/*virtual*/ BOOL postBuild() override;
|
||||
|
||||
/*virtual*/ BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
|
||||
EDragAndDropType cargo_type,
|
||||
void* cargo_data,
|
||||
EAcceptance* accept,
|
||||
std::string& tooltip_msg);
|
||||
EDragAndDropType cargo_type, void* cargo_data, EAcceptance* accept, std::string& tooltip_msg) override;
|
||||
bool handleDragAndDropToMenu(S32 x, S32 y, MASK mask, BOOL drop,
|
||||
EDragAndDropType cargo_type, void* cargo_data, EAcceptance* accept, std::string& tooltip_msg);
|
||||
|
||||
/*virtual*/ BOOL handleHover(S32 x, S32 y, MASK mask);
|
||||
/*virtual*/ BOOL handleRightMouseDown(S32 x, S32 y, MASK mask);
|
||||
/*virtual*/ BOOL handleHover(S32 x, S32 y, MASK mask) override;
|
||||
/*virtual*/ BOOL handleRightMouseDown(S32 x, S32 y, MASK mask) override;
|
||||
// LLInventoryObserver observer trigger
|
||||
virtual void changed(U32 mask);
|
||||
virtual void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE);
|
||||
virtual void draw();
|
||||
/*virtual*/ void changed(U32 mask) override;
|
||||
/*virtual*/ void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE) override;
|
||||
/*virtual*/ void draw() override;
|
||||
|
||||
void showDragMarker(BOOL show) { mShowDragMarker = show; }
|
||||
void showDragMarker(bool show) { mShowDragMarker = show; }
|
||||
void setLandingTab(LLUICtrl* tab) { mLandingTab = tab; }
|
||||
|
||||
protected:
|
||||
|
|
@ -111,7 +110,7 @@ protected:
|
|||
S32 mDropDownItemsCount;
|
||||
bool mUpdateDropDownItems;
|
||||
bool mRestoreOverflowMenu;
|
||||
|
||||
bool mDragToOverflowMenu;
|
||||
bool mGetPrevItems;
|
||||
|
||||
LLUUID mSelectedItemID;
|
||||
|
|
@ -121,19 +120,21 @@ protected:
|
|||
private:
|
||||
/*
|
||||
* Helper function to make code more readable. It handles all drag and drop
|
||||
* operations of the existing favorites items on the favorites bar.
|
||||
* operations of the existing favorites items to the favorites bar to on the overflow menu.
|
||||
*/
|
||||
void handleExistingFavoriteDragAndDrop(S32 x, S32 y);
|
||||
|
||||
/*
|
||||
* Helper function to make code more readable. It handles all drag and drop
|
||||
* operations of the new landmark to the favorites bar.
|
||||
* operations of the new landmark to the favorites bar or to the overflow menu.
|
||||
*/
|
||||
void handleNewFavoriteDragAndDrop(LLInventoryItem *item, const LLUUID& favorites_id, S32 x, S32 y);
|
||||
|
||||
// finds a control under the specified LOCAL point
|
||||
LLUICtrl* findChildByLocalCoords(S32 x, S32 y);
|
||||
|
||||
bool findDragAndDropTarget(LLUUID &target_id, bool &insert_before, S32 x, S32 y);
|
||||
|
||||
// checks if the current order of the favorites items must be saved
|
||||
BOOL needToSaveItemsOrder(const LLInventoryModel::item_array_t& items);
|
||||
|
||||
|
|
@ -148,16 +149,16 @@ private:
|
|||
|
||||
void createOverflowMenu();
|
||||
|
||||
void updateMenuItems(LLToggleableMenu* menu);
|
||||
void updateOverflowMenuItems();
|
||||
|
||||
// Fits menu item label width with favorites menu width
|
||||
void fitLabelWidth(LLMenuItemCallGL* menu_item);
|
||||
|
||||
void addOpenLandmarksMenuItem(LLToggleableMenu* menu);
|
||||
|
||||
void positionAndShowMenu(LLToggleableMenu* menu);
|
||||
void positionAndShowOverflowMenu();
|
||||
|
||||
BOOL mShowDragMarker;
|
||||
bool mShowDragMarker;
|
||||
LLUICtrl* mLandingTab;
|
||||
LLUICtrl* mLastTab;
|
||||
// <FS:Ansariel> Allow V3 and FS style favorites bar
|
||||
|
|
@ -168,11 +169,9 @@ private:
|
|||
LLTextBox* mBarLabel;
|
||||
|
||||
LLUUID mDragItemId;
|
||||
BOOL mStartDrag;
|
||||
bool mStartDrag;
|
||||
LLInventoryModel::item_array_t mItems;
|
||||
|
||||
BOOL mTabsHighlightEnabled;
|
||||
|
||||
S32 mMouseX;
|
||||
S32 mMouseY;
|
||||
|
||||
|
|
|
|||
|
|
@ -371,6 +371,8 @@ void LLFloater360Capture::encodeAndSave(LLPointer<LLImageRaw> raw_image, const s
|
|||
int jpeg_encode_quality = gSavedSettings.getU32("360CaptureJPEGEncodeQuality");
|
||||
LLPointer<LLImageJPEG> jpeg_image = new LLImageJPEG(jpeg_encode_quality);
|
||||
|
||||
LLImageDataSharedLock lock(raw_image);
|
||||
|
||||
// Actually encode the JPEG image. This is where a lot of time
|
||||
// is spent now that the snapshot capture process has been
|
||||
// optimized. The encode_time parameter doesn't appear to be
|
||||
|
|
@ -421,6 +423,8 @@ void LLFloater360Capture::suspendForAFrame()
|
|||
// Probably not needed anymore but saving here just in case.
|
||||
void LLFloater360Capture::mockSnapShot(LLImageRaw* raw)
|
||||
{
|
||||
LLImageDataLock lock(raw);
|
||||
|
||||
unsigned int width = raw->getWidth();
|
||||
unsigned int height = raw->getHeight();
|
||||
unsigned int depth = raw->getComponents();
|
||||
|
|
|
|||
|
|
@ -193,6 +193,8 @@ void LLFloaterAuction::onClickSnapshot(void* data)
|
|||
|
||||
if (success)
|
||||
{
|
||||
LLImageDataLock lock(raw);
|
||||
|
||||
self->mTransactionID.generate();
|
||||
self->mImageID = self->mTransactionID.makeAssetID(gAgent.getSecureSessionID());
|
||||
|
||||
|
|
|
|||
|
|
@ -138,6 +138,8 @@ void LLFloaterColorPicker::createUI ()
|
|||
// create RGB type area (not really RGB but it's got R,G & B in it.,..
|
||||
|
||||
LLPointer<LLImageRaw> raw = new LLImageRaw ( mRGBViewerImageWidth, mRGBViewerImageHeight, mComponents );
|
||||
LLImageDataLock lock(raw);
|
||||
|
||||
U8* bits = raw->getData();
|
||||
S32 linesize = mRGBViewerImageWidth * mComponents;
|
||||
for ( S32 y = 0; y < mRGBViewerImageHeight; ++y )
|
||||
|
|
|
|||
|
|
@ -981,6 +981,7 @@ void LLImagePreviewSculpted::setPreviewTarget(LLImageRaw* imagep, F32 distance)
|
|||
|
||||
if (imagep)
|
||||
{
|
||||
LLImageDataSharedLock lock(imagep);
|
||||
mVolume->sculpt(imagep->getWidth(), imagep->getHeight(), imagep->getComponents(), imagep->getData(), 0, false);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1050,7 +1050,7 @@ void LLFloaterPreference::apply()
|
|||
saveGraphicsPreset(gSavedSettings.getString("PresetGraphicActive"));
|
||||
}
|
||||
|
||||
void LLFloaterPreference::cancel()
|
||||
void LLFloaterPreference::cancel(const std::vector<std::string> settings_to_skip)
|
||||
{
|
||||
LLTabContainer* tabcontainer = getChild<LLTabContainer>("pref core");
|
||||
// Call cancel() on all panels that derive from LLPanelPreference
|
||||
|
|
@ -1060,7 +1060,7 @@ void LLFloaterPreference::cancel()
|
|||
LLView* view = *iter;
|
||||
LLPanelPreference* panel = dynamic_cast<LLPanelPreference*>(view);
|
||||
if (panel)
|
||||
panel->cancel();
|
||||
panel->cancel(settings_to_skip);
|
||||
}
|
||||
// hide joystick pref floater
|
||||
LLFloaterReg::hideInstance("pref_joystick");
|
||||
|
|
@ -1627,14 +1627,16 @@ void LLFloaterPreference::onBtnCancel(const LLSD& userdata)
|
|||
}
|
||||
refresh();
|
||||
}
|
||||
cancel();
|
||||
|
||||
if (userdata.asString() == "closeadvanced")
|
||||
{
|
||||
cancel({"RenderQualityPerformance"});
|
||||
LLFloaterReg::hideInstance("prefs_graphics_advanced");
|
||||
updateMaxComplexity();
|
||||
}
|
||||
else
|
||||
{
|
||||
cancel();
|
||||
closeFloater();
|
||||
}
|
||||
}
|
||||
|
|
@ -3630,7 +3632,7 @@ void LLPanelPreference::onCheckContactListColumnMode()
|
|||
}
|
||||
// </FS:Ansariel>
|
||||
|
||||
void LLPanelPreference::cancel()
|
||||
void LLPanelPreference::cancel(const std::vector<std::string> settings_to_skip)
|
||||
{
|
||||
LLPresetsManager::instance().setIsLoadingPreset(true); // <FS:Ansariel> Graphic preset controls independent from XUI
|
||||
|
||||
|
|
@ -3645,6 +3647,12 @@ void LLPanelPreference::cancel()
|
|||
continue;
|
||||
}
|
||||
|
||||
auto found = std::find(settings_to_skip.begin(), settings_to_skip.end(), control->getName());
|
||||
if (found != settings_to_skip.end())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
control->set(ctrl_value);
|
||||
}
|
||||
|
||||
|
|
@ -4035,11 +4043,11 @@ void LLPanelPreferenceGraphics::resetDirtyChilds()
|
|||
}
|
||||
}
|
||||
|
||||
void LLPanelPreferenceGraphics::cancel()
|
||||
void LLPanelPreferenceGraphics::cancel(const std::vector<std::string> settings_to_skip)
|
||||
{
|
||||
// <FS:Ansariel> Improved graphics preferences
|
||||
resetDirtyChilds();
|
||||
LLPanelPreference::cancel();
|
||||
LLPanelPreference::cancel(settings_to_skip);
|
||||
}
|
||||
void LLPanelPreferenceGraphics::saveSettings()
|
||||
{
|
||||
|
|
@ -4331,7 +4339,7 @@ void LLPanelPreferenceControls::apply()
|
|||
}
|
||||
}
|
||||
|
||||
void LLPanelPreferenceControls::cancel()
|
||||
void LLPanelPreferenceControls::cancel(const std::vector<std::string> settings_to_skip)
|
||||
{
|
||||
for (U32 i = 0; i < LLKeyConflictHandler::MODE_COUNT - 1; ++i)
|
||||
{
|
||||
|
|
@ -5081,7 +5089,7 @@ void LLPanelPreferenceCrashReports::apply()
|
|||
gCrashSettings.setBOOL("CrashSubmitName", pSendName->get());
|
||||
}
|
||||
|
||||
void LLPanelPreferenceCrashReports::cancel()
|
||||
void LLPanelPreferenceCrashReports::cancel(const std::vector<std::string> settings_to_skip)
|
||||
{
|
||||
}
|
||||
// [/SL:KB]
|
||||
|
|
@ -5204,7 +5212,7 @@ void LLPanelPreferenceSkins::callbackRestart(const LLSD& notification, const LLS
|
|||
}
|
||||
}
|
||||
|
||||
void LLPanelPreferenceSkins::cancel()
|
||||
void LLPanelPreferenceSkins::cancel(const std::vector<std::string> settings_to_skip)
|
||||
{
|
||||
m_Skin = gSavedSettings.getString("SkinCurrent");
|
||||
m_SkinTheme = gSavedSettings.getString("SkinCurrentTheme");
|
||||
|
|
@ -6101,7 +6109,7 @@ void LLPanelPreferenceOpensim::apply()
|
|||
FSPanelLogin::updateServer();
|
||||
}
|
||||
|
||||
void LLPanelPreferenceOpensim::cancel()
|
||||
void LLPanelPreferenceOpensim::cancel(const std::vector<std::string> settings_to_skip)
|
||||
{
|
||||
LLGridManager::getInstance()->resetGrids();
|
||||
LLGridManager::getInstance()->setGridChoice(mCurrentGrid);
|
||||
|
|
|
|||
|
|
@ -86,7 +86,7 @@ public:
|
|||
~LLFloaterPreference();
|
||||
|
||||
void apply();
|
||||
void cancel();
|
||||
void cancel(const std::vector<std::string> settings_to_skip = {});
|
||||
// <FS:Zi> FIRE-19539 - Include the alert messages in Prefs>Notifications>Alerts in preference Search.
|
||||
// /*virtual*/ void draw();
|
||||
// </FS:Zi>
|
||||
|
|
@ -353,7 +353,7 @@ public:
|
|||
virtual ~LLPanelPreference();
|
||||
|
||||
virtual void apply();
|
||||
virtual void cancel();
|
||||
virtual void cancel(const std::vector<std::string> settings_to_skip = {});
|
||||
// void setControlFalse(const LLSD& user_data); //<FS:KC> Handled centrally now
|
||||
virtual void setHardwareDefaults();
|
||||
|
||||
|
|
@ -416,14 +416,12 @@ class LLPanelPreferenceGraphics : public LLPanelPreference
|
|||
public:
|
||||
BOOL postBuild();
|
||||
void draw();
|
||||
void cancel();
|
||||
void cancel(const std::vector<std::string> settings_to_skip = {});
|
||||
void saveSettings();
|
||||
void resetDirtyChilds();
|
||||
void setHardwareDefaults();
|
||||
void setPresetText();
|
||||
|
||||
static const std::string getPresetsPath();
|
||||
|
||||
protected:
|
||||
bool hasDirtyChilds();
|
||||
|
||||
|
|
@ -443,7 +441,7 @@ public:
|
|||
BOOL postBuild();
|
||||
|
||||
void apply();
|
||||
void cancel();
|
||||
void cancel(const std::vector<std::string> settings_to_skip = {});
|
||||
void saveSettings();
|
||||
void resetDirtyChilds();
|
||||
|
||||
|
|
@ -508,7 +506,7 @@ public:
|
|||
|
||||
/*virtual*/ BOOL postBuild();
|
||||
/*virtual*/ void apply();
|
||||
/*virtual*/ void cancel();
|
||||
/*virtual*/ void cancel(const std::vector<std::string> settings_to_skip = {});
|
||||
void callbackRestart(const LLSD& notification, const LLSD& response); // <FS:CR> Callback for restart dialogs
|
||||
protected:
|
||||
void onSkinChanged();
|
||||
|
|
@ -540,7 +538,7 @@ public:
|
|||
|
||||
/*virtual*/ BOOL postBuild();
|
||||
/*virtual*/ void apply();
|
||||
/*virtual*/ void cancel();
|
||||
/*virtual*/ void cancel(const std::vector<std::string> settings_to_skip = {});
|
||||
|
||||
void refresh();
|
||||
|
||||
|
|
@ -587,7 +585,7 @@ public:
|
|||
|
||||
#ifdef OPENSIM
|
||||
/*virtual*/ void apply();
|
||||
/*virtual*/ void cancel();
|
||||
/*virtual*/ void cancel(const std::vector<std::string> settings_to_skip = {});
|
||||
|
||||
protected:
|
||||
boost::signals2::connection mGridListChangedCallbackConnection;
|
||||
|
|
|
|||
|
|
@ -94,7 +94,7 @@ void LLFloaterPreferenceGraphicsAdvanced::onClickCloseBtn(bool app_quitting)
|
|||
LLFloaterPreference* instance = LLFloaterReg::findTypedInstance<LLFloaterPreference>("preferences");
|
||||
if (instance)
|
||||
{
|
||||
instance->cancel();
|
||||
instance->cancel({"RenderQualityPerformance"});
|
||||
}
|
||||
updateMaxComplexity();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4804,12 +4804,10 @@ void LLFolderBridge::buildContextMenuOptions(U32 flags, menuentry_vec_t& items
|
|||
if (!isInboxFolder() // don't allow creation in inbox
|
||||
&& outfits_id != mUUID)
|
||||
{
|
||||
bool menu_items_added = false;
|
||||
// Do not allow to create 2-level subfolder in the Calling Card/Friends folder. EXT-694.
|
||||
if (!LLFriendCardsManager::instance().isCategoryInFriendFolder(cat))
|
||||
{
|
||||
items.push_back(std::string("New Folder"));
|
||||
menu_items_added = true;
|
||||
}
|
||||
// <FS:Ansariel> Fix "outfits" context menu
|
||||
//if (!isMarketplaceListingsFolder())
|
||||
|
|
@ -4829,10 +4827,6 @@ void LLFolderBridge::buildContextMenuOptions(U32 flags, menuentry_vec_t& items
|
|||
{
|
||||
disabled_items.push_back("New Settings");
|
||||
}
|
||||
}
|
||||
if (menu_items_added)
|
||||
{
|
||||
items.push_back(std::string("Create Separator"));
|
||||
}
|
||||
}
|
||||
getClipboardEntries(false, items, disabled_items, flags);
|
||||
|
|
|
|||
|
|
@ -2028,6 +2028,39 @@ void LLInventoryGallery::pasteAsLink(const LLUUID& dest,
|
|||
}
|
||||
}
|
||||
|
||||
void LLInventoryGallery::doCreate(const LLUUID& dest, const LLSD& userdata)
|
||||
{
|
||||
|
||||
LLViewerInventoryCategory* cat = gInventory.getCategory(dest);
|
||||
if (cat && mFolderID != dest)
|
||||
{
|
||||
menu_create_inventory_item(NULL, dest, userdata, LLUUID::null);
|
||||
}
|
||||
else
|
||||
{
|
||||
// todo: needs to reset current floater's filter,
|
||||
// like reset_inventory_filter()
|
||||
|
||||
LLHandle<LLPanel> handle = getHandle();
|
||||
std::function<void(const LLUUID&)> callback_cat_created =
|
||||
[handle](const LLUUID& new_id)
|
||||
{
|
||||
gInventory.notifyObservers();
|
||||
LLInventoryGallery* panel = static_cast<LLInventoryGallery*>(handle.get());
|
||||
if (panel && new_id.notNull())
|
||||
{
|
||||
panel->clearSelection();
|
||||
if (panel->mItemMap.count(new_id) != 0)
|
||||
{
|
||||
panel->addItemSelection(new_id, true);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
menu_create_inventory_item(NULL, mFolderID, userdata, LLUUID::null, callback_cat_created);
|
||||
}
|
||||
}
|
||||
|
||||
void LLInventoryGallery::claimEditHandler()
|
||||
{
|
||||
gEditMenuHandler = this;
|
||||
|
|
|
|||
|
|
@ -166,6 +166,7 @@ public:
|
|||
void deleteSelection();
|
||||
bool canDeleteSelection();
|
||||
void pasteAsLink();
|
||||
void doCreate(const LLUUID& dest, const LLSD& userdata);
|
||||
|
||||
void setSortOrder(U32 order, bool update = false);
|
||||
U32 getSortOrder() { return mSortOrder; };
|
||||
|
|
|
|||
|
|
@ -32,9 +32,11 @@
|
|||
#include "llappearancemgr.h"
|
||||
#include "llavataractions.h"
|
||||
#include "llclipboard.h"
|
||||
#include "llenvironment.h"
|
||||
#include "llfloaterreg.h"
|
||||
#include "llfloatersidepanelcontainer.h"
|
||||
#include "llfloaterworldmap.h"
|
||||
#include "llfriendcard.h"
|
||||
#include "llinventorybridge.h"
|
||||
#include "llinventoryfunctions.h"
|
||||
#include "llinventorymodel.h"
|
||||
|
|
@ -48,6 +50,41 @@
|
|||
#include "llviewerwindow.h"
|
||||
#include "llvoavatarself.h"
|
||||
|
||||
|
||||
void modify_outfit(BOOL append, const LLUUID& cat_id, LLInventoryModel* model)
|
||||
{
|
||||
LLViewerInventoryCategory* cat = model->getCategory(cat_id);
|
||||
if (!cat) return;
|
||||
|
||||
// checking amount of items to wear
|
||||
static LLCachedControl<U32> max_items(gSavedSettings, "WearFolderLimit", 125);
|
||||
LLInventoryModel::cat_array_t cats;
|
||||
LLInventoryModel::item_array_t items;
|
||||
LLFindWearablesEx not_worn(/*is_worn=*/ false, /*include_body_parts=*/ false);
|
||||
model->collectDescendentsIf(cat_id,
|
||||
cats,
|
||||
items,
|
||||
LLInventoryModel::EXCLUDE_TRASH,
|
||||
not_worn);
|
||||
|
||||
if (items.size() > max_items())
|
||||
{
|
||||
LLSD args;
|
||||
args["AMOUNT"] = llformat("%u", max_items());
|
||||
LLNotificationsUtil::add("TooManyWearables", args);
|
||||
return;
|
||||
}
|
||||
if (model->isObjectDescendentOf(cat_id, gInventory.getRootFolderID()))
|
||||
{
|
||||
LLAppearanceMgr::instance().wearInventoryCategory(cat, FALSE, append);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Library, we need to copy content first
|
||||
LLAppearanceMgr::instance().wearInventoryCategory(cat, TRUE, append);
|
||||
}
|
||||
}
|
||||
|
||||
LLContextMenu* LLInventoryGalleryContextMenu::createMenu()
|
||||
{
|
||||
LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar;
|
||||
|
|
@ -57,11 +94,33 @@ LLContextMenu* LLInventoryGalleryContextMenu::createMenu()
|
|||
registrar.add("Inventory.FileUploadLocation", boost::bind(&LLInventoryGalleryContextMenu::fileUploadLocation, this, _2));
|
||||
registrar.add("Inventory.EmptyTrash", boost::bind(&LLInventoryModel::emptyFolderType, &gInventory, "ConfirmEmptyTrash", LLFolderType::FT_TRASH));
|
||||
registrar.add("Inventory.EmptyLostAndFound", boost::bind(&LLInventoryModel::emptyFolderType, &gInventory, "ConfirmEmptyLostAndFound", LLFolderType::FT_LOST_AND_FOUND));
|
||||
registrar.add("Inventory.DoCreate", [this](LLUICtrl*, const LLSD& data)
|
||||
{
|
||||
if (mRootFolder)
|
||||
{
|
||||
mGallery->doCreate(mGallery->getRootFolder(), data);
|
||||
}
|
||||
else
|
||||
{
|
||||
mGallery->doCreate(mUUIDs.front(), data);
|
||||
}
|
||||
});
|
||||
|
||||
std::set<LLUUID> uuids(mUUIDs.begin(), mUUIDs.end());
|
||||
registrar.add("Inventory.Share", boost::bind(&LLAvatarActions::shareWithAvatars, uuids, gFloaterView->getParentFloater(mGallery)));
|
||||
|
||||
enable_registrar.add("Inventory.CanSetUploadLocation", boost::bind(&LLInventoryGalleryContextMenu::canSetUploadLocation, this, _2));
|
||||
enable_registrar.add("Inventory.EnvironmentEnabled", [](LLUICtrl*, const LLSD&)
|
||||
{
|
||||
return LLEnvironment::instance().isInventoryEnabled();
|
||||
});
|
||||
enable_registrar.add("Inventory.MaterialsEnabled", [](LLUICtrl*, const LLSD&)
|
||||
{
|
||||
std::string agent_url = gAgent.getRegionCapability("UpdateMaterialAgentInventory");
|
||||
std::string task_url = gAgent.getRegionCapability("UpdateMaterialTaskInventory");
|
||||
|
||||
return (!agent_url.empty() && !task_url.empty());
|
||||
});
|
||||
|
||||
LLContextMenu* menu = createFromFile("menu_gallery_inventory.xml");
|
||||
|
||||
|
|
@ -186,6 +245,22 @@ void LLInventoryGalleryContextMenu::doToSelected(const LLSD& userdata)
|
|||
{
|
||||
ungroup_folder_items(mUUIDs.front());
|
||||
}
|
||||
else if ("replaceoutfit" == action)
|
||||
{
|
||||
modify_outfit(FALSE, mUUIDs.front(), &gInventory);
|
||||
}
|
||||
else if ("addtooutfit" == action)
|
||||
{
|
||||
modify_outfit(TRUE, mUUIDs.front(), &gInventory);
|
||||
}
|
||||
else if ("removefromoutfit" == action)
|
||||
{
|
||||
LLViewerInventoryCategory* cat = gInventory.getCategory(mUUIDs.front());
|
||||
if (cat)
|
||||
{
|
||||
LLAppearanceMgr::instance().takeOffOutfit(cat->getLinkedUUID());
|
||||
}
|
||||
}
|
||||
else if ("take_off" == action || "detach" == action)
|
||||
{
|
||||
for (LLUUID& selected_id : mUUIDs)
|
||||
|
|
@ -307,6 +382,54 @@ void LLInventoryGalleryContextMenu::doToSelected(const LLSD& userdata)
|
|||
preview_texture->saveAs();
|
||||
}
|
||||
}
|
||||
else if (("copy_to_marketplace_listings" == action)
|
||||
|| ("move_to_marketplace_listings" == action))
|
||||
{
|
||||
LLViewerInventoryItem* itemp = gInventory.getItem(mUUIDs.front());
|
||||
bool copy_operation = "copy_to_marketplace_listings" == action;
|
||||
bool can_copy = itemp ? itemp->getPermissions().allowOperationBy(PERM_COPY, gAgent.getID(), gAgent.getGroupID()) : false;
|
||||
|
||||
|
||||
if (can_copy)
|
||||
{
|
||||
const LLUUID& marketplacelistings_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS);
|
||||
if (itemp)
|
||||
{
|
||||
move_item_to_marketplacelistings(itemp, marketplacelistings_id, copy_operation);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
uuid_vec_t lamdba_list = mUUIDs;
|
||||
LLNotificationsUtil::add(
|
||||
"ConfirmCopyToMarketplace",
|
||||
LLSD(),
|
||||
LLSD(),
|
||||
[lamdba_list](const LLSD& notification, const LLSD& response)
|
||||
{
|
||||
S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
|
||||
// option == 0 Move no copy item(s)
|
||||
// option == 1 Don't move no copy item(s) (leave them behind)
|
||||
bool copy_and_move = option == 0;
|
||||
const LLUUID& marketplacelistings_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS);
|
||||
|
||||
// main inventory only allows one item?
|
||||
LLViewerInventoryItem* itemp = gInventory.getItem(lamdba_list.front());
|
||||
if (itemp)
|
||||
{
|
||||
if (itemp->getPermissions().allowOperationBy(PERM_COPY, gAgent.getID(), gAgent.getGroupID()))
|
||||
{
|
||||
move_item_to_marketplacelistings(itemp, marketplacelistings_id, true);
|
||||
}
|
||||
else if (copy_and_move)
|
||||
{
|
||||
move_item_to_marketplacelistings(itemp, marketplacelistings_id, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LLInventoryGalleryContextMenu::rename(const LLUUID& item_id)
|
||||
|
|
@ -400,6 +523,56 @@ bool is_inbox_folder(LLUUID item_id)
|
|||
return gInventory.isObjectDescendentOf(item_id, inbox_id);
|
||||
}
|
||||
|
||||
bool can_list_on_marketplace(const LLUUID &id)
|
||||
{
|
||||
const LLInventoryObject* obj = gInventory.getObject(id);
|
||||
bool can_list = (obj != NULL);
|
||||
|
||||
if (can_list)
|
||||
{
|
||||
const LLUUID& object_id = obj->getLinkedUUID();
|
||||
can_list = object_id.notNull();
|
||||
|
||||
if (can_list)
|
||||
{
|
||||
std::string error_msg;
|
||||
const LLUUID& marketplacelistings_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS);
|
||||
if (marketplacelistings_id.notNull())
|
||||
{
|
||||
LLViewerInventoryCategory* master_folder = gInventory.getCategory(marketplacelistings_id);
|
||||
LLInventoryCategory* cat = gInventory.getCategory(id);
|
||||
if (cat)
|
||||
{
|
||||
can_list = can_move_folder_to_marketplace(master_folder, master_folder, cat, error_msg);
|
||||
}
|
||||
else
|
||||
{
|
||||
LLInventoryItem* item = gInventory.getItem(id);
|
||||
can_list = (item ? can_move_item_to_marketplace(master_folder, master_folder, item, error_msg) : false);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
can_list = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return can_list;
|
||||
}
|
||||
|
||||
bool check_folder_for_contents_of_type(const LLUUID &id, LLInventoryModel* model, LLInventoryCollectFunctor& is_type)
|
||||
{
|
||||
LLInventoryModel::cat_array_t cat_array;
|
||||
LLInventoryModel::item_array_t item_array;
|
||||
model->collectDescendentsIf(id,
|
||||
cat_array,
|
||||
item_array,
|
||||
LLInventoryModel::EXCLUDE_TRASH,
|
||||
is_type);
|
||||
return item_array.size() > 0;
|
||||
}
|
||||
|
||||
void LLInventoryGalleryContextMenu::updateMenuItemsVisibility(LLContextMenu* menu)
|
||||
{
|
||||
LLUUID selected_id = mUUIDs.front();
|
||||
|
|
@ -421,6 +594,7 @@ void LLInventoryGalleryContextMenu::updateMenuItemsVisibility(LLContextMenu* men
|
|||
bool is_in_trash = gInventory.isObjectDescendentOf(selected_id, gInventory.findCategoryUUIDForType(LLFolderType::FT_TRASH));
|
||||
bool is_lost_and_found = (selected_id == gInventory.findCategoryUUIDForType(LLFolderType::FT_LOST_AND_FOUND));
|
||||
bool is_outfits= (selected_id == gInventory.findCategoryUUIDForType(LLFolderType::FT_MY_OUTFITS));
|
||||
bool is_in_favorites = gInventory.isObjectDescendentOf(selected_id, gInventory.findCategoryUUIDForType(LLFolderType::FT_FAVORITE));
|
||||
//bool is_favorites= (selected_id == gInventory.findCategoryUUIDForType(LLFolderType::FT_FAVORITE));
|
||||
|
||||
bool is_system_folder = false;
|
||||
|
|
@ -468,6 +642,49 @@ void LLInventoryGalleryContextMenu::updateMenuItemsVisibility(LLContextMenu* men
|
|||
items.push_back(std::string("open_in_new_window"));
|
||||
items.push_back(std::string("Open Folder Separator"));
|
||||
}
|
||||
|
||||
// wearables related functionality for folders.
|
||||
LLFindWearables is_wearable;
|
||||
LLIsType is_object(LLAssetType::AT_OBJECT);
|
||||
LLIsType is_gesture(LLAssetType::AT_GESTURE);
|
||||
|
||||
if (check_folder_for_contents_of_type(selected_id, &gInventory, is_wearable)
|
||||
|| check_folder_for_contents_of_type(selected_id, &gInventory, is_object)
|
||||
|| check_folder_for_contents_of_type(selected_id, &gInventory, is_gesture))
|
||||
{
|
||||
// Only enable add/replace outfit for non-system folders.
|
||||
if (!is_system_folder)
|
||||
{
|
||||
// Adding an outfit onto another (versus replacing) doesn't make sense.
|
||||
if (folder_type != LLFolderType::FT_OUTFIT)
|
||||
{
|
||||
items.push_back(std::string("Add To Outfit"));
|
||||
if (!LLAppearanceMgr::instance().getCanAddToCOF(selected_id))
|
||||
{
|
||||
disabled_items.push_back(std::string("Add To Outfit"));
|
||||
}
|
||||
}
|
||||
|
||||
items.push_back(std::string("Replace Outfit"));
|
||||
if (!LLAppearanceMgr::instance().getCanReplaceCOF(selected_id))
|
||||
{
|
||||
disabled_items.push_back(std::string("Replace Outfit"));
|
||||
}
|
||||
}
|
||||
if (is_agent_inventory)
|
||||
{
|
||||
items.push_back(std::string("Folder Wearables Separator"));
|
||||
// Note: If user tries to unwear "My Inventory", it's going to deactivate everything including gestures
|
||||
// Might be safer to disable this for "My Inventory"
|
||||
items.push_back(std::string("Remove From Outfit"));
|
||||
if (folder_type != LLFolderType::FT_ROOT_INVENTORY // Unless COF is empty, whih shouldn't be, warrantied to have worn items
|
||||
&& !LLAppearanceMgr::getCanRemoveFromCOF(selected_id)) // expensive from root!
|
||||
{
|
||||
disabled_items.push_back(std::string("Remove From Outfit"));
|
||||
}
|
||||
}
|
||||
items.push_back(std::string("Outfit Separator"));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -515,11 +732,30 @@ void LLInventoryGalleryContextMenu::updateMenuItemsVisibility(LLContextMenu* men
|
|||
}
|
||||
else
|
||||
{
|
||||
if (is_agent_inventory && !is_inbox && !is_cof && !is_in_favorites && !is_outfits)
|
||||
{
|
||||
LLViewerInventoryCategory* category = gInventory.getCategory(selected_id);
|
||||
if (!category || !LLFriendCardsManager::instance().isCategoryInFriendFolder(category))
|
||||
{
|
||||
items.push_back(std::string("New Folder"));
|
||||
}
|
||||
|
||||
items.push_back(std::string("create_new"));
|
||||
items.push_back(std::string("New Script"));
|
||||
items.push_back(std::string("New Note"));
|
||||
items.push_back(std::string("New Gesture"));
|
||||
items.push_back(std::string("New Material"));
|
||||
items.push_back(std::string("New Clothes"));
|
||||
items.push_back(std::string("New Body Parts"));
|
||||
items.push_back(std::string("New Settings"));
|
||||
}
|
||||
|
||||
if(can_share_item(selected_id))
|
||||
{
|
||||
items.push_back(std::string("Share"));
|
||||
}
|
||||
if (LLClipboard::instance().hasContents() && is_agent_inventory && !is_cof && !is_inbox_folder(selected_id))
|
||||
|
||||
if (LLClipboard::instance().hasContents() && is_agent_inventory && !is_cof && !is_inbox)
|
||||
{
|
||||
items.push_back(std::string("Paste"));
|
||||
|
||||
|
|
@ -531,7 +767,7 @@ void LLInventoryGalleryContextMenu::updateMenuItemsVisibility(LLContextMenu* men
|
|||
}
|
||||
if (is_folder && is_agent_inventory)
|
||||
{
|
||||
if (!is_cof && (folder_type != LLFolderType::FT_OUTFIT) && !is_outfits && !is_inbox_folder(selected_id))
|
||||
if (!is_cof && (folder_type != LLFolderType::FT_OUTFIT) && !is_outfits && !is_inbox)
|
||||
{
|
||||
if (!gInventory.isObjectDescendentOf(selected_id, gInventory.findCategoryUUIDForType(LLFolderType::FT_CALLINGCARD)) && !isRootFolder())
|
||||
{
|
||||
|
|
@ -721,6 +957,54 @@ void LLInventoryGalleryContextMenu::updateMenuItemsVisibility(LLContextMenu* men
|
|||
|
||||
disabled_items.push_back(std::string("New Folder"));
|
||||
disabled_items.push_back(std::string("upload_def"));
|
||||
disabled_items.push_back(std::string("create_new"));
|
||||
}
|
||||
|
||||
if (is_agent_inventory && !mRootFolder)
|
||||
{
|
||||
items.push_back(std::string("New folder from selected"));
|
||||
items.push_back(std::string("Subfolder Separator"));
|
||||
if (!is_only_items_selected(mUUIDs) && !is_only_cats_selected(mUUIDs))
|
||||
{
|
||||
disabled_items.push_back(std::string("New folder from selected"));
|
||||
}
|
||||
}
|
||||
|
||||
// Marketplace
|
||||
bool can_list = false;
|
||||
const LLUUID marketplacelistings_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS);
|
||||
if (marketplacelistings_id.notNull() && !is_inbox && !obj->getIsLinkType())
|
||||
{
|
||||
if (is_folder)
|
||||
{
|
||||
LLViewerInventoryCategory* cat = gInventory.getCategory(selected_id);
|
||||
if (cat
|
||||
&& !LLFolderType::lookupIsProtectedType(cat->getPreferredType())
|
||||
&& gInventory.isObjectDescendentOf(selected_id, gInventory.getRootFolderID()))
|
||||
{
|
||||
can_list = true;
|
||||
}
|
||||
}
|
||||
else if (selected_item
|
||||
&& selected_item->getPermissions().allowOperationBy(PERM_TRANSFER, gAgent.getID())
|
||||
&& selected_item->getPermissions().getOwner() != ALEXANDRIA_LINDEN_ID
|
||||
&& LLAssetType::AT_CALLINGCARD != selected_item->getType())
|
||||
{
|
||||
can_list = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (can_list)
|
||||
{
|
||||
items.push_back(std::string("Marketplace Separator"));
|
||||
items.push_back(std::string("Marketplace Copy"));
|
||||
items.push_back(std::string("Marketplace Move"));
|
||||
|
||||
if (!can_list_on_marketplace(selected_id))
|
||||
{
|
||||
disabled_items.push_back(std::string("Marketplace Copy"));
|
||||
disabled_items.push_back(std::string("Marketplace Move"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2231,7 +2231,7 @@ bool LLMaterialEditor::canModifyObjectsMaterial()
|
|||
LLSelectedTEGetMatData func(true);
|
||||
LLPermissions permissions;
|
||||
LLViewerInventoryItem* item_out;
|
||||
return can_use_objects_material(func, std::vector({PERM_MODIFY}), ItemSource::OBJECT, permissions, item_out);
|
||||
return can_use_objects_material(func, std::vector<PermissionBit>({PERM_MODIFY}), ItemSource::OBJECT, permissions, item_out);
|
||||
}
|
||||
|
||||
bool LLMaterialEditor::canSaveObjectsMaterial()
|
||||
|
|
@ -2239,7 +2239,7 @@ bool LLMaterialEditor::canSaveObjectsMaterial()
|
|||
LLSelectedTEGetMatData func(true);
|
||||
LLPermissions permissions;
|
||||
LLViewerInventoryItem* item_out;
|
||||
return can_use_objects_material(func, std::vector({PERM_COPY, PERM_MODIFY}), ItemSource::AGENT, permissions, item_out);
|
||||
return can_use_objects_material(func, std::vector<PermissionBit>({PERM_COPY, PERM_MODIFY}), ItemSource::AGENT, permissions, item_out);
|
||||
}
|
||||
|
||||
bool LLMaterialEditor::canClipboardObjectsMaterial()
|
||||
|
|
@ -2265,7 +2265,7 @@ bool LLMaterialEditor::canClipboardObjectsMaterial()
|
|||
LLSelectedTEGetMatData func(true);
|
||||
LLPermissions permissions;
|
||||
LLViewerInventoryItem* item_out;
|
||||
return can_use_objects_material(func, std::vector({PERM_COPY, PERM_MODIFY, PERM_TRANSFER}), ItemSource::OBJECT, permissions, item_out);
|
||||
return can_use_objects_material(func, std::vector<PermissionBit>({PERM_COPY, PERM_MODIFY, PERM_TRANSFER}), ItemSource::OBJECT, permissions, item_out);
|
||||
}
|
||||
|
||||
void LLMaterialEditor::saveObjectsMaterialAs()
|
||||
|
|
@ -2273,7 +2273,7 @@ void LLMaterialEditor::saveObjectsMaterialAs()
|
|||
LLSelectedTEGetMatData func(true);
|
||||
LLPermissions permissions;
|
||||
LLViewerInventoryItem* item = nullptr;
|
||||
bool allowed = can_use_objects_material(func, std::vector({PERM_COPY, PERM_MODIFY}), ItemSource::AGENT, permissions, item);
|
||||
bool allowed = can_use_objects_material(func, std::vector<PermissionBit>({PERM_COPY, PERM_MODIFY}), ItemSource::AGENT, permissions, item);
|
||||
if (!allowed)
|
||||
{
|
||||
LL_WARNS("MaterialEditor") << "Failed to save GLTF material from object" << LL_ENDL;
|
||||
|
|
@ -3482,6 +3482,8 @@ void LLMaterialEditor::inventoryChanged(LLViewerObject* object,
|
|||
|
||||
void LLMaterialEditor::saveTexture(LLImageJ2C* img, const std::string& name, const LLUUID& asset_id, upload_callback_f cb)
|
||||
{
|
||||
LLImageDataSharedLock lock(img);
|
||||
|
||||
if (asset_id.isNull()
|
||||
|| img == nullptr
|
||||
|| img->getDataSize() == 0)
|
||||
|
|
|
|||
|
|
@ -2465,17 +2465,19 @@ void LLMeshUploadThread::wholeModelToLLSD(LLSD& dest, bool include_textures)
|
|||
std::stringstream texture_str;
|
||||
if (texture != NULL && include_textures && mUploadTextures)
|
||||
{
|
||||
if(texture->hasSavedRawImage())
|
||||
{
|
||||
if (texture->hasSavedRawImage())
|
||||
{
|
||||
LLImageDataLock lock(texture->getSavedRawImage());
|
||||
|
||||
LLPointer<LLImageJ2C> upload_file =
|
||||
LLViewerTextureList::convertToUploadFile(texture->getSavedRawImage());
|
||||
|
||||
if (!upload_file.isNull() && upload_file->getDataSize())
|
||||
{
|
||||
texture_str.write((const char*) upload_file->getData(), upload_file->getDataSize());
|
||||
texture_str.write((const char*) upload_file->getData(), upload_file->getDataSize());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (texture != NULL &&
|
||||
mUploadTextures &&
|
||||
|
|
@ -2619,17 +2621,19 @@ void LLMeshUploadThread::wholeModelToLLSD(LLSD& dest, bool include_textures)
|
|||
std::stringstream texture_str;
|
||||
if (texture != NULL && include_textures && mUploadTextures)
|
||||
{
|
||||
if(texture->hasSavedRawImage())
|
||||
{
|
||||
if (texture->hasSavedRawImage())
|
||||
{
|
||||
LLImageDataLock lock(texture->getSavedRawImage());
|
||||
|
||||
LLPointer<LLImageJ2C> upload_file =
|
||||
LLViewerTextureList::convertToUploadFile(texture->getSavedRawImage());
|
||||
|
||||
if (!upload_file.isNull() && upload_file->getDataSize())
|
||||
{
|
||||
texture_str.write((const char*) upload_file->getData(), upload_file->getDataSize());
|
||||
texture_str.write((const char*) upload_file->getData(), upload_file->getDataSize());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (texture != NULL &&
|
||||
mUploadTextures &&
|
||||
|
|
|
|||
|
|
@ -620,6 +620,7 @@ void LLNetMap::draw()
|
|||
// [/SL:KB]
|
||||
|
||||
// Create the base texture.
|
||||
LLImageDataLock lock(mObjectRawImagep);
|
||||
U8 *default_texture = mObjectRawImagep->getData();
|
||||
memset( default_texture, 0, mObjectImagep->getWidth() * mObjectImagep->getHeight() * mObjectImagep->getComponents() );
|
||||
|
||||
|
|
@ -1469,6 +1470,7 @@ void LLNetMap::renderPoint(const LLVector3 &pos_local, const LLColor4U &color,
|
|||
return;
|
||||
}
|
||||
|
||||
LLImageDataLock lock(mObjectRawImagep);
|
||||
U8 *datap = mObjectRawImagep->getData();
|
||||
|
||||
S32 neg_radius = diameter / 2;
|
||||
|
|
|
|||
|
|
@ -39,11 +39,6 @@ LLProfileDropTarget::LLProfileDropTarget(const LLProfileDropTarget::Params& p)
|
|||
mAgentID(p.agent_id)
|
||||
{}
|
||||
|
||||
void LLProfileDropTarget::doDrop(EDragAndDropType cargo_type, void* cargo_data)
|
||||
{
|
||||
LL_INFOS() << "LLProfileDropTarget::doDrop()" << LL_ENDL;
|
||||
}
|
||||
|
||||
BOOL LLProfileDropTarget::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
|
||||
EDragAndDropType cargo_type,
|
||||
void* cargo_data,
|
||||
|
|
|
|||
|
|
@ -59,8 +59,6 @@ public:
|
|||
LLProfileDropTarget(const Params&);
|
||||
~LLProfileDropTarget() {}
|
||||
|
||||
void doDrop(EDragAndDropType cargo_type, void* cargo_data);
|
||||
|
||||
//
|
||||
// LLView functionality
|
||||
virtual BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
|
||||
|
|
|
|||
|
|
@ -91,8 +91,6 @@ public:
|
|||
LLGroupDropTarget(const Params&);
|
||||
~LLGroupDropTarget() {};
|
||||
|
||||
void doDrop(EDragAndDropType cargo_type, void* cargo_data);
|
||||
|
||||
//
|
||||
// LLView functionality
|
||||
virtual BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
|
||||
|
|
@ -116,11 +114,6 @@ LLGroupDropTarget::LLGroupDropTarget(const LLGroupDropTarget::Params& p)
|
|||
mGroupID(p.group_id)
|
||||
{}
|
||||
|
||||
void LLGroupDropTarget::doDrop(EDragAndDropType cargo_type, void* cargo_data)
|
||||
{
|
||||
LL_INFOS() << "LLGroupDropTarget::doDrop()" << LL_ENDL;
|
||||
}
|
||||
|
||||
BOOL LLGroupDropTarget::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
|
||||
EDragAndDropType cargo_type,
|
||||
void* cargo_data,
|
||||
|
|
|
|||
|
|
@ -56,6 +56,7 @@
|
|||
#include "lltrans.h"
|
||||
#include "llviewermenu.h"
|
||||
#include "llviewertexturelist.h"
|
||||
#include "llviewerinventory.h"
|
||||
#include "llsidepanelinventory.h"
|
||||
#include "llfolderview.h"
|
||||
#include "llradiogroup.h"
|
||||
|
|
|
|||
|
|
@ -46,6 +46,7 @@
|
|||
#include "lltexteditor.h"
|
||||
#include "lltexturectrl.h"
|
||||
#include "lltoggleablemenu.h"
|
||||
#include "lltooldraganddrop.h"
|
||||
#include "llgrouplist.h"
|
||||
#include "llurlaction.h"
|
||||
|
||||
|
|
@ -1142,6 +1143,51 @@ void LLPanelProfileSecondLife::onOpen(const LLSD& key)
|
|||
mAvatarNameCacheConnection = LLAvatarNameCache::get(getAvatarId(), boost::bind(&LLPanelProfileSecondLife::onAvatarNameCache, this, _1, _2));
|
||||
}
|
||||
|
||||
|
||||
BOOL LLPanelProfileSecondLife::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
|
||||
EDragAndDropType cargo_type,
|
||||
void* cargo_data,
|
||||
EAcceptance* accept,
|
||||
std::string& tooltip_msg)
|
||||
{
|
||||
// Try children first
|
||||
if (LLPanelProfileTab::handleDragAndDrop(x, y, mask, drop, cargo_type, cargo_data, accept, tooltip_msg)
|
||||
&& *accept != ACCEPT_NO)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// No point sharing with own profile
|
||||
if (getSelfProfile())
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// Exclude fields that look like they are editable.
|
||||
S32 child_x = 0;
|
||||
S32 child_y = 0;
|
||||
if (localPointToOtherView(x, y, &child_x, &child_y, mDescriptionEdit)
|
||||
&& mDescriptionEdit->pointInView(child_x, child_y))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (localPointToOtherView(x, y, &child_x, &child_y, mGroupList)
|
||||
&& mGroupList->pointInView(child_x, child_y))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// Share
|
||||
LLToolDragAndDrop::handleGiveDragAndDrop(getAvatarId(),
|
||||
LLUUID::null,
|
||||
drop,
|
||||
cargo_type,
|
||||
cargo_data,
|
||||
accept);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void LLPanelProfileSecondLife::updateData()
|
||||
{
|
||||
LLUUID avatar_id = getAvatarId();
|
||||
|
|
|
|||
|
|
@ -93,6 +93,12 @@ public:
|
|||
|
||||
void onOpen(const LLSD& key) override;
|
||||
|
||||
BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
|
||||
EDragAndDropType cargo_type,
|
||||
void* cargo_data,
|
||||
EAcceptance* accept,
|
||||
std::string& tooltip_msg) override;
|
||||
|
||||
/**
|
||||
* LLFriendObserver trigger
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -881,6 +881,8 @@ void LLSnapshotLivePreview::prepareFreezeFrame()
|
|||
// Get the decoded version of the formatted image
|
||||
getEncodedImage();
|
||||
|
||||
LLImageDataSharedLock lock(mPreviewImageEncoded);
|
||||
|
||||
// We need to scale that a bit for display...
|
||||
LLPointer<LLImageRaw> scaled = new LLImageRaw(
|
||||
mPreviewImageEncoded->getData(),
|
||||
|
|
@ -940,13 +942,15 @@ LLPointer<LLImageRaw> LLSnapshotLivePreview::getEncodedImage()
|
|||
{
|
||||
if (!mPreviewImageEncoded)
|
||||
{
|
||||
LLImageDataSharedLock lock(mPreviewImage);
|
||||
|
||||
mPreviewImageEncoded = new LLImageRaw;
|
||||
|
||||
|
||||
mPreviewImageEncoded->resize(
|
||||
mPreviewImage->getWidth(),
|
||||
mPreviewImage->getHeight(),
|
||||
mPreviewImage->getComponents());
|
||||
|
||||
|
||||
if (getSnapshotType() == LLSnapshotModel::SNAPSHOT_TEXTURE)
|
||||
{
|
||||
// We don't store the intermediate formatted image in mFormattedImage in the J2C case
|
||||
|
|
@ -1093,6 +1097,8 @@ void LLSnapshotLivePreview::getSize(S32& w, S32& h) const
|
|||
|
||||
void LLSnapshotLivePreview::saveTexture(BOOL outfit_snapshot, std::string name)
|
||||
{
|
||||
LLImageDataSharedLock lock(mPreviewImage);
|
||||
|
||||
LL_DEBUGS("Snapshot") << "saving texture: " << mPreviewImage->getWidth() << "x" << mPreviewImage->getHeight() << LL_ENDL;
|
||||
// gen a new uuid for this asset
|
||||
LLTransactionID tid;
|
||||
|
|
|
|||
|
|
@ -742,7 +742,6 @@ class LLControlAVBridge : public LLVolumeBridge
|
|||
using super = LLVolumeBridge;
|
||||
public:
|
||||
LLControlAVBridge(LLDrawable* drawablep, LLViewerRegion* regionp);
|
||||
virtual void updateSpatialExtents();
|
||||
};
|
||||
|
||||
class LLHUDBridge : public LLVolumeBridge
|
||||
|
|
|
|||
|
|
@ -96,7 +96,7 @@ private:
|
|||
|
||||
public:
|
||||
LLTextureCacheWorker(LLTextureCache* cache, const LLUUID& id,
|
||||
U8* data, S32 datasize, S32 offset,
|
||||
const U8* data, S32 datasize, S32 offset,
|
||||
S32 imagesize, // for writes
|
||||
LLTextureCache::Responder* responder)
|
||||
: LLWorkerClass(cache, "LLTextureCacheWorker"),
|
||||
|
|
@ -145,7 +145,7 @@ protected:
|
|||
LLUUID mID;
|
||||
|
||||
U8* mReadData;
|
||||
U8* mWriteData;
|
||||
const U8* mWriteData;
|
||||
S32 mDataSize;
|
||||
S32 mOffset;
|
||||
S32 mImageSize;
|
||||
|
|
@ -239,7 +239,7 @@ class LLTextureCacheRemoteWorker : public LLTextureCacheWorker
|
|||
{
|
||||
public:
|
||||
LLTextureCacheRemoteWorker(LLTextureCache* cache, const LLUUID& id,
|
||||
U8* data, S32 datasize, S32 offset,
|
||||
const U8* data, S32 datasize, S32 offset,
|
||||
S32 imagesize, // for writes
|
||||
LLPointer<LLImageRaw> raw, S32 discardlevel,
|
||||
LLTextureCache::Responder* responder)
|
||||
|
|
@ -1993,7 +1993,7 @@ bool LLTextureCache::readComplete(handle_t handle, bool abort)
|
|||
}
|
||||
|
||||
LLTextureCache::handle_t LLTextureCache::writeToCache(const LLUUID& id,
|
||||
U8* data, S32 datasize, S32 imagesize,
|
||||
const U8* data, S32 datasize, S32 imagesize,
|
||||
LLPointer<LLImageRaw> rawimage, S32 discardlevel,
|
||||
WriteResponder* responder)
|
||||
{
|
||||
|
|
@ -2089,6 +2089,9 @@ LLPointer<LLImageRaw> LLTextureCache::readFromFastCache(const LLUUID& id, S32& d
|
|||
bool LLTextureCache::writeToFastCache(LLUUID image_id, S32 id, LLPointer<LLImageRaw> raw, S32 discardlevel)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
|
||||
|
||||
LLImageDataSharedLock lock(raw);
|
||||
|
||||
//rescale image if needed
|
||||
if (raw.isNull() || raw->isBufferInvalid() || !raw->getData())
|
||||
{
|
||||
|
|
|
|||
|
|
@ -125,7 +125,7 @@ public:
|
|||
handle_t readFromCache(const LLUUID& id, S32 offset, S32 size,
|
||||
ReadResponder* responder);
|
||||
bool readComplete(handle_t handle, bool abort);
|
||||
handle_t writeToCache(const LLUUID& id, U8* data, S32 datasize, S32 imagesize, LLPointer<LLImageRaw> rawimage, S32 discardlevel,
|
||||
handle_t writeToCache(const LLUUID& id, const U8* data, S32 datasize, S32 imagesize, LLPointer<LLImageRaw> rawimage, S32 discardlevel,
|
||||
WriteResponder* responder);
|
||||
LLPointer<LLImageRaw> readFromFastCache(const LLUUID& id, S32& discardlevel);
|
||||
bool writeComplete(handle_t handle, bool abort = false);
|
||||
|
|
|
|||
|
|
@ -1860,7 +1860,9 @@ bool LLTextureFetchWorker::doWork(S32 param)
|
|||
mFormattedImage = new LLImageJ2C; // default
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
LLImageDataLock lock(mFormattedImage);
|
||||
|
||||
if (mHaveAllData) //the image file is fully loaded.
|
||||
{
|
||||
mFileSize = total_size;
|
||||
|
|
@ -2018,6 +2020,9 @@ bool LLTextureFetchWorker::doWork(S32 param)
|
|||
//return false;
|
||||
return doWork(param);
|
||||
}
|
||||
|
||||
LLImageDataSharedLock lock(mFormattedImage);
|
||||
|
||||
S32 datasize = mFormattedImage->getDataSize();
|
||||
if(mFileSize < datasize)//This could happen when http fetching and sim fetching mixed.
|
||||
{
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@
|
|||
#include "llviewertexture.h"
|
||||
#include "llviewertexturelist.h"
|
||||
|
||||
void strip_alpha_channel(LLPointer<LLImageRaw>& img)
|
||||
static void strip_alpha_channel(LLPointer<LLImageRaw>& img)
|
||||
{
|
||||
if (img->getComponents() == 4)
|
||||
{
|
||||
|
|
@ -45,13 +45,13 @@ void strip_alpha_channel(LLPointer<LLImageRaw>& img)
|
|||
// PRECONDITIONS:
|
||||
// dst_img must be 3 component
|
||||
// src_img and dst_image must have the same dimensions
|
||||
void copy_red_channel(LLPointer<LLImageRaw>& src_img, LLPointer<LLImageRaw>& dst_img)
|
||||
static void copy_red_channel(const LLPointer<LLImageRaw>& src_img, LLPointer<LLImageRaw>& dst_img)
|
||||
{
|
||||
llassert(src_img->getWidth() == dst_img->getWidth() && src_img->getHeight() == dst_img->getHeight());
|
||||
llassert(dst_img->getComponents() == 3);
|
||||
|
||||
U32 pixel_count = dst_img->getWidth() * dst_img->getHeight();
|
||||
U8* src = src_img->getData();
|
||||
const U8* src = src_img->getData();
|
||||
U8* dst = dst_img->getData();
|
||||
S8 src_components = src_img->getComponents();
|
||||
|
||||
|
|
@ -95,6 +95,8 @@ void LLTinyGLTFHelper::initFetchedTextures(tinygltf::Material& material,
|
|||
int mr_idx = material.pbrMetallicRoughness.metallicRoughnessTexture.index;
|
||||
if (occlusion_idx != mr_idx)
|
||||
{
|
||||
LLImageDataLock lockIn(occlusion_img);
|
||||
LLImageDataLock lockOut(mr_img);
|
||||
//scale occlusion image to match resolution of mr image
|
||||
occlusion_img->scale(mr_img->getWidth(), mr_img->getHeight());
|
||||
|
||||
|
|
@ -104,6 +106,7 @@ void LLTinyGLTFHelper::initFetchedTextures(tinygltf::Material& material,
|
|||
}
|
||||
else if (occlusion_img)
|
||||
{
|
||||
LLImageDataSharedLock lock(occlusion_img);
|
||||
//no mr but occlusion exists, make a white mr_img and copy occlusion red channel over
|
||||
mr_img = new LLImageRaw(occlusion_img->getWidth(), occlusion_img->getHeight(), 3);
|
||||
mr_img->clear(255, 255, 255);
|
||||
|
|
|
|||
|
|
@ -47,6 +47,7 @@
|
|||
#include "llinventorybridge.h"
|
||||
#include "llinventorydefines.h"
|
||||
#include "llinventoryfunctions.h"
|
||||
#include "llinventorymodelbackgroundfetch.h"
|
||||
#include "llpreviewnotecard.h"
|
||||
#include "llrootview.h"
|
||||
#include "llselectmgr.h"
|
||||
|
|
@ -329,6 +330,16 @@ void LLToolDragAndDrop::beginDrag(EDragAndDropType type,
|
|||
LL_WARNS() << "Attempted to start drag without a cargo type" << LL_ENDL;
|
||||
return;
|
||||
}
|
||||
|
||||
if (type != DAD_CATEGORY)
|
||||
{
|
||||
LLViewerInventoryItem* item = gInventory.getItem(cargo_id);
|
||||
if (item && !item->isFinished())
|
||||
{
|
||||
LLInventoryModelBackgroundFetch::instance().start(item->getUUID(), false);
|
||||
}
|
||||
}
|
||||
|
||||
mCargoTypes.clear();
|
||||
mCargoTypes.push_back(type);
|
||||
mCargoIDs.clear();
|
||||
|
|
|
|||
|
|
@ -683,6 +683,8 @@ LLBufferedAssetUploadInfo::LLBufferedAssetUploadInfo(LLUUID itemId, LLPointer<LL
|
|||
{
|
||||
setItemId(itemId);
|
||||
|
||||
LLImageDataSharedLock lock(image);
|
||||
|
||||
EImageCodec codec = static_cast<EImageCodec>(image->getCodec());
|
||||
|
||||
switch (codec)
|
||||
|
|
|
|||
|
|
@ -541,6 +541,7 @@ static bool handleLogFileChanged(const LLSD& newvalue)
|
|||
std::string log_filename = newvalue.asString();
|
||||
LLFile::remove(log_filename);
|
||||
LLError::logToFile(log_filename);
|
||||
LL_INFOS() << "Logging switched to " << log_filename << LL_ENDL;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1474,7 +1474,7 @@ void LLViewerJoystick::setSNDefaults()
|
|||
#if LL_DARWIN || LL_LINUX
|
||||
const float platformScale = 20.f;
|
||||
const float platformScaleAvXZ = 1.f;
|
||||
// The SpaceNavigator doesn't act as a 3D cursor on OS X / Linux.
|
||||
// The SpaceNavigator doesn't act as a 3D cursor on macOS / Linux.
|
||||
const bool is_3d_cursor = false;
|
||||
#else
|
||||
const float platformScale = 1.f;
|
||||
|
|
|
|||
|
|
@ -294,6 +294,7 @@ BOOL enable_take();
|
|||
void handle_object_show_inspector();
|
||||
void handle_avatar_show_inspector();
|
||||
bool confirm_take(const LLSD& notification, const LLSD& response, LLObjectSelectionHandle selection_handle);
|
||||
bool confirm_take_separate(const LLSD ¬ification, const LLSD &response, LLObjectSelectionHandle selection_handle);
|
||||
|
||||
void handle_buy_object(LLSaleInfo sale_info);
|
||||
void handle_buy_contents(LLSaleInfo sale_info);
|
||||
|
|
@ -6075,6 +6076,24 @@ static void derez_objects(EDeRezDestination dest, const LLUUID& dest_id)
|
|||
derez_objects(dest, dest_id, first_region, error, NULL);
|
||||
}
|
||||
|
||||
static void derez_objects_separate(EDeRezDestination dest, const LLUUID &dest_id)
|
||||
{
|
||||
std::vector<LLViewerObjectPtr> derez_object_list;
|
||||
std::string error;
|
||||
LLViewerRegion* first_region = NULL;
|
||||
if (!get_derezzable_objects(dest, error, first_region, &derez_object_list, false))
|
||||
{
|
||||
LL_WARNS() << "No objects to derez" << LL_ENDL;
|
||||
return;
|
||||
}
|
||||
for (LLViewerObject *opjectp : derez_object_list)
|
||||
{
|
||||
std::vector<LLViewerObjectPtr> buf_list;
|
||||
buf_list.push_back(opjectp);
|
||||
derez_objects(dest, dest_id, first_region, error, &buf_list);
|
||||
}
|
||||
}
|
||||
|
||||
void handle_take_copy()
|
||||
{
|
||||
if (LLSelectMgr::getInstance()->getSelection()->isEmpty()) return;
|
||||
|
|
@ -6094,6 +6113,15 @@ void handle_take_copy()
|
|||
derez_objects(DRD_ACQUIRE_TO_AGENT_INVENTORY, category_id);
|
||||
}
|
||||
|
||||
void handle_take_separate_copy()
|
||||
{
|
||||
if (LLSelectMgr::getInstance()->getSelection()->isEmpty())
|
||||
return;
|
||||
|
||||
const LLUUID category_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_OBJECT);
|
||||
derez_objects_separate(DRD_ACQUIRE_TO_AGENT_INVENTORY, category_id);
|
||||
}
|
||||
|
||||
void handle_link_objects()
|
||||
{
|
||||
// <FS:Ansariel> We don't use a shortcut for two completely different functions based on context
|
||||
|
|
@ -6198,7 +6226,7 @@ void force_take_copy(void*)
|
|||
derez_objects(DRD_FORCE_TO_GOD_INVENTORY, category_id);
|
||||
}
|
||||
|
||||
void handle_take()
|
||||
void handle_take(bool take_separate)
|
||||
{
|
||||
// we want to use the folder this was derezzed from if it's
|
||||
// available. Otherwise, derez to the normal place.
|
||||
|
|
@ -6301,7 +6329,17 @@ void handle_take()
|
|||
// MAINT-290
|
||||
// Reason: Showing the confirmation dialog resets object selection, thus there is nothing to derez.
|
||||
// Fix: pass selection to the confirm_take, so that selection doesn't "die" after confirmation dialog is opened
|
||||
params.functor.function(boost::bind(confirm_take, _1, _2, LLSelectMgr::instance().getSelection()));
|
||||
params.functor.function([take_separate](const LLSD ¬ification, const LLSD &response)
|
||||
{
|
||||
if (take_separate)
|
||||
{
|
||||
confirm_take_separate(notification, response, LLSelectMgr::instance().getSelection());
|
||||
}
|
||||
else
|
||||
{
|
||||
confirm_take(notification, response, LLSelectMgr::instance().getSelection());
|
||||
}
|
||||
});
|
||||
|
||||
if(locked_but_takeable_object ||
|
||||
!you_own_everything)
|
||||
|
|
@ -6364,6 +6402,16 @@ bool confirm_take(const LLSD& notification, const LLSD& response, LLObjectSelect
|
|||
return false;
|
||||
}
|
||||
|
||||
bool confirm_take_separate(const LLSD ¬ification, const LLSD &response, LLObjectSelectionHandle selection_handle)
|
||||
{
|
||||
S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
|
||||
if (enable_take() && (option == 0))
|
||||
{
|
||||
derez_objects_separate(DRD_TAKE_INTO_AGENT_INVENTORY, notification["payload"]["folder_id"].asUUID());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// You can take an item when it is public and transferrable, or when
|
||||
// you own it. We err on the side of enabling the item when at least
|
||||
// one item selected can be copied to inventory.
|
||||
|
|
@ -6449,6 +6497,11 @@ bool visible_take_object()
|
|||
return !is_selection_buy_not_take() && enable_take();
|
||||
}
|
||||
|
||||
bool visible_take_objects()
|
||||
{
|
||||
return visible_take_object() && (LLSelectMgr::getInstance()->getSelection()->getRootObjectCount() > 1);
|
||||
}
|
||||
|
||||
bool tools_visible_buy_object()
|
||||
{
|
||||
return is_selection_buy_not_take();
|
||||
|
|
@ -10111,6 +10164,10 @@ bool enable_object_take_copy()
|
|||
return all_valid;
|
||||
}
|
||||
|
||||
bool visible_take_copy_objects()
|
||||
{
|
||||
return enable_object_take_copy() && (LLSelectMgr::getInstance()->getSelection()->getRootObjectCount() > 1);
|
||||
}
|
||||
|
||||
class LLHasAsset : public LLInventoryCollectFunctor
|
||||
{
|
||||
|
|
@ -12228,6 +12285,7 @@ void initialize_menus()
|
|||
enable.add("Tools.EnableUnlink", boost::bind(&LLSelectMgr::enableUnlinkObjects, LLSelectMgr::getInstance()));
|
||||
view_listener_t::addMenu(new LLToolsEnableBuyOrTake(), "Tools.EnableBuyOrTake");
|
||||
enable.add("Tools.EnableTakeCopy", boost::bind(&enable_object_take_copy));
|
||||
enable.add("Tools.VisibleCopySeparate", boost::bind(&visible_take_copy_objects));
|
||||
enable.add("Tools.VisibleBuyObject", boost::bind(&tools_visible_buy_object));
|
||||
enable.add("Tools.VisibleTakeObject", boost::bind(&tools_visible_take_object));
|
||||
view_listener_t::addMenu(new LLToolsEnableSaveToObjectInventory(), "Tools.EnableSaveToObjectInventory");
|
||||
|
|
@ -12536,6 +12594,7 @@ void initialize_menus()
|
|||
view_listener_t::addMenu(new LLEnableEditParticleSource(), "Object.EnableEditParticles");
|
||||
|
||||
enable.add("Object.VisibleTake", boost::bind(&visible_take_object));
|
||||
enable.add("Object.VisibleTakeMultiple", boost::bind(&visible_take_objects));
|
||||
enable.add("Object.VisibleBuy", boost::bind(&visible_buy_object));
|
||||
|
||||
commit.add("Object.Buy", boost::bind(&handle_buy));
|
||||
|
|
@ -12544,7 +12603,9 @@ void initialize_menus()
|
|||
commit.add("Object.EditGLTFMaterial", boost::bind(&handle_object_edit_gltf_material));
|
||||
commit.add("Object.Inspect", boost::bind(&handle_object_inspect));
|
||||
commit.add("Object.Open", boost::bind(&handle_object_open));
|
||||
commit.add("Object.Take", boost::bind(&handle_take));
|
||||
commit.add("Object.Take", boost::bind(&handle_take, false));
|
||||
commit.add("Object.TakeSeparate", boost::bind(&handle_take, true));
|
||||
commit.add("Object.TakeSeparateCopy", boost::bind(&handle_take_separate_copy));
|
||||
commit.add("Object.ShowInspector", boost::bind(&handle_object_show_inspector));
|
||||
enable.add("Object.EnableInspect", boost::bind(&enable_object_inspect));
|
||||
enable.add("Object.EnableEditGLTFMaterial", boost::bind(&enable_object_edit_gltf_material));
|
||||
|
|
|
|||
|
|
@ -113,7 +113,7 @@ bool enable_object_delete();
|
|||
|
||||
// Buy either contents or object itself
|
||||
void handle_buy();
|
||||
void handle_take();
|
||||
void handle_take(bool take_separate = false);
|
||||
void handle_take_copy();
|
||||
void handle_look_at_selection(const LLSD& param);
|
||||
void handle_script_info();
|
||||
|
|
|
|||
|
|
@ -1213,6 +1213,20 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,
|
|||
LL_DEBUGS("ObjectUpdate") << " mesgsys " << mesgsys << " dp " << dp << " id " << getID() << " update_type " << (S32) update_type << LL_ENDL;
|
||||
dumpStack("ObjectUpdateStack");
|
||||
|
||||
// The new OBJECTDATA_FIELD_SIZE_124, OBJECTDATA_FIELD_SIZE_140, OBJECTDATA_FIELD_SIZE_80
|
||||
// and OBJECTDATA_FIELD_SIZE_64 lengths should be supported in the existing cases below.
|
||||
// Each case should start at the beginning of the buffer and extract all known
|
||||
// values, and ignore any unknown data at the end of the buffer.
|
||||
// This allows new data in the future without breaking current viewers.
|
||||
const S32 OBJECTDATA_FIELD_SIZE_140 = 140; // Full precision avatar update for future extended data
|
||||
const S32 OBJECTDATA_FIELD_SIZE_124 = 124; // Full precision object update for future extended data
|
||||
const S32 OBJECTDATA_FIELD_SIZE_76 = 76; // Full precision avatar update
|
||||
const S32 OBJECTDATA_FIELD_SIZE_60 = 60; // Full precision object update
|
||||
const S32 OBJECTDATA_FIELD_SIZE_80 = 80; // Terse avatar update, 16 bit precision for future extended data
|
||||
const S32 OBJECTDATA_FIELD_SIZE_64 = 64; // Terse object update, 16 bit precision for future extended data
|
||||
const S32 OBJECTDATA_FIELD_SIZE_48 = 48; // Terse avatar update, 16 bit precision
|
||||
const S32 OBJECTDATA_FIELD_SIZE_32 = 32; // Terse object update, 16 bit precision
|
||||
|
||||
U32 retval = 0x0;
|
||||
|
||||
// If region is removed from the list it is also deleted.
|
||||
|
|
@ -1260,7 +1274,7 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,
|
|||
U32 x, y;
|
||||
from_region_handle(region_handle, &x, &y);
|
||||
|
||||
LL_ERRS() << "Object has invalid region " << x << ":" << y << "!" << LL_ENDL;
|
||||
LL_WARNS("UpdateFail") << "Object has invalid region " << x << ":" << y << "!" << LL_ENDL;
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
|
@ -1290,8 +1304,8 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,
|
|||
// </FS:CR> Aurora Sim
|
||||
const F32 MAX_HEIGHT = LLWorld::getInstance()->getRegionMaxHeight();
|
||||
const F32 MIN_HEIGHT = LLWorld::getInstance()->getRegionMinHeight();
|
||||
S32 length;
|
||||
S32 count;
|
||||
S32 length = 0;
|
||||
S32 count = 0;
|
||||
S32 this_update_precision = 32; // in bits
|
||||
|
||||
// Temporaries, because we need to compare w/ previous to set dirty flags...
|
||||
|
|
@ -1352,6 +1366,7 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,
|
|||
mesgsys->getVector3Fast(_PREHASH_ObjectData, _PREHASH_Scale, new_scale, block_num );
|
||||
length = mesgsys->getSizeFast(_PREHASH_ObjectData, block_num, _PREHASH_ObjectData);
|
||||
mesgsys->getBinaryDataFast(_PREHASH_ObjectData, _PREHASH_ObjectData, data, length, block_num, MAX_OBJECT_BINARY_DATA_SIZE);
|
||||
length = llmin(length, MAX_OBJECT_BINARY_DATA_SIZE); // getBinaryDataFast() safely fills the buffer to max_size
|
||||
|
||||
mTotalCRC = crc;
|
||||
// Might need to update mSourceMuted here to properly pick up new radius
|
||||
|
|
@ -1371,20 +1386,22 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,
|
|||
}
|
||||
setClickAction(click_action);
|
||||
|
||||
count = 0;
|
||||
LLVector4 collision_plane;
|
||||
|
||||
count = 0;
|
||||
LLVector4 collision_plane;
|
||||
|
||||
switch(length)
|
||||
{
|
||||
case (60 + 16):
|
||||
case OBJECTDATA_FIELD_SIZE_140:
|
||||
case OBJECTDATA_FIELD_SIZE_76:
|
||||
// pull out collision normal for avatar
|
||||
htolememcpy(collision_plane.mV, &data[count], MVT_LLVector4, sizeof(LLVector4));
|
||||
((LLVOAvatar*)this)->setFootPlane(collision_plane);
|
||||
count += sizeof(LLVector4);
|
||||
// fall through
|
||||
case 60:
|
||||
|
||||
case OBJECTDATA_FIELD_SIZE_124:
|
||||
case OBJECTDATA_FIELD_SIZE_60:
|
||||
this_update_precision = 32;
|
||||
// this is a terse update
|
||||
// this is a full precision update
|
||||
// pos
|
||||
htolememcpy(new_pos_parent.mV, &data[count], MVT_LLVector3, sizeof(LLVector3));
|
||||
count += sizeof(LLVector3);
|
||||
|
|
@ -1409,117 +1426,21 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,
|
|||
resetRot();
|
||||
}
|
||||
setAngularVelocity(new_angv);
|
||||
count += sizeof(LLVector3);
|
||||
#if LL_DARWIN
|
||||
if (length == 76)
|
||||
if (length == OBJECTDATA_FIELD_SIZE_76 ||
|
||||
length == OBJECTDATA_FIELD_SIZE_140)
|
||||
{
|
||||
setAngularVelocity(LLVector3::zero);
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
case(32 + 16):
|
||||
// pull out collision normal for avatar
|
||||
htolememcpy(collision_plane.mV, &data[count], MVT_LLVector4, sizeof(LLVector4));
|
||||
((LLVOAvatar*)this)->setFootPlane(collision_plane);
|
||||
count += sizeof(LLVector4);
|
||||
// fall through
|
||||
case 32:
|
||||
this_update_precision = 16;
|
||||
test_pos_parent.quantize16(-0.5f*size, 1.5f*size, MIN_HEIGHT, MAX_HEIGHT);
|
||||
|
||||
// This is a terse 16 update, so treat data as an array of U16's.
|
||||
#ifdef LL_BIG_ENDIAN
|
||||
htolememcpy(valswizzle, &data[count], MVT_U16Vec3, 6);
|
||||
val = valswizzle;
|
||||
#else
|
||||
val = (U16 *) &data[count];
|
||||
#endif
|
||||
count += sizeof(U16)*3;
|
||||
new_pos_parent.mV[VX] = U16_to_F32(val[VX], -0.5f*size, 1.5f*size);
|
||||
new_pos_parent.mV[VY] = U16_to_F32(val[VY], -0.5f*size, 1.5f*size);
|
||||
new_pos_parent.mV[VZ] = U16_to_F32(val[VZ], MIN_HEIGHT, MAX_HEIGHT);
|
||||
|
||||
#ifdef LL_BIG_ENDIAN
|
||||
htolememcpy(valswizzle, &data[count], MVT_U16Vec3, 6);
|
||||
val = valswizzle;
|
||||
#else
|
||||
val = (U16 *) &data[count];
|
||||
#endif
|
||||
count += sizeof(U16)*3;
|
||||
setVelocity(LLVector3(U16_to_F32(val[VX], -size, size),
|
||||
U16_to_F32(val[VY], -size, size),
|
||||
U16_to_F32(val[VZ], -size, size)));
|
||||
|
||||
#ifdef LL_BIG_ENDIAN
|
||||
htolememcpy(valswizzle, &data[count], MVT_U16Vec3, 6);
|
||||
val = valswizzle;
|
||||
#else
|
||||
val = (U16 *) &data[count];
|
||||
#endif
|
||||
count += sizeof(U16)*3;
|
||||
setAcceleration(LLVector3(U16_to_F32(val[VX], -size, size),
|
||||
U16_to_F32(val[VY], -size, size),
|
||||
U16_to_F32(val[VZ], -size, size)));
|
||||
|
||||
#ifdef LL_BIG_ENDIAN
|
||||
htolememcpy(valswizzle, &data[count], MVT_U16Quat, 4);
|
||||
val = valswizzle;
|
||||
#else
|
||||
val = (U16 *) &data[count];
|
||||
#endif
|
||||
count += sizeof(U16)*4;
|
||||
new_rot.mQ[VX] = U16_to_F32(val[VX], -1.f, 1.f);
|
||||
new_rot.mQ[VY] = U16_to_F32(val[VY], -1.f, 1.f);
|
||||
new_rot.mQ[VZ] = U16_to_F32(val[VZ], -1.f, 1.f);
|
||||
new_rot.mQ[VW] = U16_to_F32(val[VW], -1.f, 1.f);
|
||||
|
||||
#ifdef LL_BIG_ENDIAN
|
||||
htolememcpy(valswizzle, &data[count], MVT_U16Vec3, 6);
|
||||
val = valswizzle;
|
||||
#else
|
||||
val = (U16 *) &data[count];
|
||||
#endif
|
||||
new_angv.setVec(U16_to_F32(val[VX], -size, size),
|
||||
U16_to_F32(val[VY], -size, size),
|
||||
U16_to_F32(val[VZ], -size, size));
|
||||
if (new_angv.isExactlyZero())
|
||||
{
|
||||
// reset rotation time
|
||||
resetRot();
|
||||
}
|
||||
setAngularVelocity(new_angv);
|
||||
break;
|
||||
|
||||
case 16:
|
||||
this_update_precision = 8;
|
||||
test_pos_parent.quantize8(-0.5f*size, 1.5f*size, MIN_HEIGHT, MAX_HEIGHT);
|
||||
// this is a terse 8 update
|
||||
new_pos_parent.mV[VX] = U8_to_F32(data[0], -0.5f*size, 1.5f*size);
|
||||
new_pos_parent.mV[VY] = U8_to_F32(data[1], -0.5f*size, 1.5f*size);
|
||||
new_pos_parent.mV[VZ] = U8_to_F32(data[2], MIN_HEIGHT, MAX_HEIGHT);
|
||||
|
||||
setVelocity(U8_to_F32(data[3], -size, size),
|
||||
U8_to_F32(data[4], -size, size),
|
||||
U8_to_F32(data[5], -size, size) );
|
||||
|
||||
setAcceleration(U8_to_F32(data[6], -size, size),
|
||||
U8_to_F32(data[7], -size, size),
|
||||
U8_to_F32(data[8], -size, size) );
|
||||
|
||||
new_rot.mQ[VX] = U8_to_F32(data[9], -1.f, 1.f);
|
||||
new_rot.mQ[VY] = U8_to_F32(data[10], -1.f, 1.f);
|
||||
new_rot.mQ[VZ] = U8_to_F32(data[11], -1.f, 1.f);
|
||||
new_rot.mQ[VW] = U8_to_F32(data[12], -1.f, 1.f);
|
||||
|
||||
new_angv.setVec(U8_to_F32(data[13], -size, size),
|
||||
U8_to_F32(data[14], -size, size),
|
||||
U8_to_F32(data[15], -size, size) );
|
||||
if (new_angv.isExactlyZero())
|
||||
{
|
||||
// reset rotation time
|
||||
resetRot();
|
||||
}
|
||||
setAngularVelocity(new_angv);
|
||||
break;
|
||||
// length values 48, 32 and 16 were once in viewer code but
|
||||
// are never sent by the SL simulator
|
||||
default:
|
||||
LL_WARNS("UpdateFail") << "Unexpected ObjectData buffer size " << length
|
||||
<< " for " << getID() << " with OUT_FULL message" << LL_ENDL;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////
|
||||
|
|
@ -1553,20 +1474,45 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,
|
|||
if (mData)
|
||||
{
|
||||
delete [] mData;
|
||||
}
|
||||
mData = NULL;
|
||||
}
|
||||
|
||||
// Check for appended generic data
|
||||
S32 data_size = mesgsys->getSizeFast(_PREHASH_ObjectData, block_num, _PREHASH_Data);
|
||||
if (data_size <= 0)
|
||||
{
|
||||
mData = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
// ...has generic data
|
||||
mData = new U8[data_size];
|
||||
mesgsys->getBinaryDataFast(_PREHASH_ObjectData, _PREHASH_Data, mData, data_size, block_num);
|
||||
}
|
||||
// Dec 2023 new generic data:
|
||||
// Trees work as before, this field contains genome data
|
||||
// Not a tree: root objects send 1 byte with the number of
|
||||
// total prims in the linkset
|
||||
// If the generic data size is zero, then number of prims is 1
|
||||
//
|
||||
// Viewers should not check for specific data sizes exactly, but if
|
||||
// the field has data, process it from the start and ignore the remainder.
|
||||
|
||||
// Check for appended generic data
|
||||
const S32 GENERIC_DATA_BUFFER_SIZE = 16;
|
||||
S32 data_size = mesgsys->getSizeFast(_PREHASH_ObjectData, block_num, _PREHASH_Data);
|
||||
if (data_size > 0)
|
||||
{ // has generic data
|
||||
if (getPCode() == LL_PCODE_LEGACY_TREE || getPCode() == LL_PCODE_TREE_NEW)
|
||||
{
|
||||
mData = new U8[data_size];
|
||||
mesgsys->getBinaryDataFast(_PREHASH_ObjectData, _PREHASH_Data, mData, data_size, block_num);
|
||||
LL_DEBUGS("NewObjectData") << "Read " << data_size << " bytes tree genome data for " << getID() << ", pcode "
|
||||
<< getPCodeString() << ", value " << (S32) mData[0] << LL_ENDL;
|
||||
}
|
||||
else
|
||||
{ // Extract number of prims
|
||||
U8 generic_data[GENERIC_DATA_BUFFER_SIZE];
|
||||
mesgsys->getBinaryDataFast(_PREHASH_ObjectData, _PREHASH_Data,
|
||||
&generic_data[0], llmin(data_size, GENERIC_DATA_BUFFER_SIZE), block_num);
|
||||
// This is sample code to extract the number of prims
|
||||
// Future viewers should use it for their own purposes
|
||||
if (!isAvatar())
|
||||
{
|
||||
S32 num_prims = (S32) generic_data[0];
|
||||
LL_DEBUGS("NewObjectData") << "Root prim " << getID() << " has "
|
||||
<< num_prims << " prims in linkset" << LL_ENDL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
S32 text_size = mesgsys->getSizeFast(_PREHASH_ObjectData, block_num, _PREHASH_Text);
|
||||
if (text_size > 1)
|
||||
|
|
@ -1668,60 +1614,23 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,
|
|||
#endif
|
||||
length = mesgsys->getSizeFast(_PREHASH_ObjectData, block_num, _PREHASH_ObjectData);
|
||||
mesgsys->getBinaryDataFast(_PREHASH_ObjectData, _PREHASH_ObjectData, data, length, block_num, MAX_OBJECT_BINARY_DATA_SIZE);
|
||||
count = 0;
|
||||
length = llmin(length, MAX_OBJECT_BINARY_DATA_SIZE); // getBinaryDataFast() safely fills the buffer to max_size
|
||||
count = 0;
|
||||
LLVector4 collision_plane;
|
||||
|
||||
|
||||
switch(length)
|
||||
{
|
||||
case(60 + 16):
|
||||
case OBJECTDATA_FIELD_SIZE_80:
|
||||
case OBJECTDATA_FIELD_SIZE_48:
|
||||
// pull out collision normal for avatar
|
||||
htolememcpy(collision_plane.mV, &data[count], MVT_LLVector4, sizeof(LLVector4));
|
||||
((LLVOAvatar*)this)->setFootPlane(collision_plane);
|
||||
count += sizeof(LLVector4);
|
||||
// fall through
|
||||
case 60:
|
||||
// this is a terse 32 update
|
||||
// pos
|
||||
this_update_precision = 32;
|
||||
htolememcpy(new_pos_parent.mV, &data[count], MVT_LLVector3, sizeof(LLVector3));
|
||||
count += sizeof(LLVector3);
|
||||
// vel
|
||||
htolememcpy((void*)getVelocity().mV, &data[count], MVT_LLVector3, sizeof(LLVector3));
|
||||
count += sizeof(LLVector3);
|
||||
// acc
|
||||
htolememcpy((void*)getAcceleration().mV, &data[count], MVT_LLVector3, sizeof(LLVector3));
|
||||
count += sizeof(LLVector3);
|
||||
// theta
|
||||
{
|
||||
LLVector3 vec;
|
||||
htolememcpy(vec.mV, &data[count], MVT_LLVector3, sizeof(LLVector3));
|
||||
new_rot.unpackFromVector3(vec);
|
||||
}
|
||||
count += sizeof(LLVector3);
|
||||
// omega
|
||||
htolememcpy((void*)new_angv.mV, &data[count], MVT_LLVector3, sizeof(LLVector3));
|
||||
if (new_angv.isExactlyZero())
|
||||
{
|
||||
// reset rotation time
|
||||
resetRot();
|
||||
}
|
||||
setAngularVelocity(new_angv);
|
||||
#if LL_DARWIN
|
||||
if (length == 76)
|
||||
{
|
||||
setAngularVelocity(LLVector3::zero);
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
case(32 + 16):
|
||||
// pull out collision normal for avatar
|
||||
htolememcpy(collision_plane.mV, &data[count], MVT_LLVector4, sizeof(LLVector4));
|
||||
((LLVOAvatar*)this)->setFootPlane(collision_plane);
|
||||
count += sizeof(LLVector4);
|
||||
// fall through
|
||||
case 32:
|
||||
// this is a terse 16 update
|
||||
this_update_precision = 16;
|
||||
|
||||
case OBJECTDATA_FIELD_SIZE_64:
|
||||
case OBJECTDATA_FIELD_SIZE_32:
|
||||
// this is a terse 16 bit quantized update
|
||||
this_update_precision = 16;
|
||||
test_pos_parent.quantize16(-0.5f*size, 1.5f*size, MIN_HEIGHT, MAX_HEIGHT);
|
||||
|
||||
#ifdef LL_BIG_ENDIAN
|
||||
|
|
@ -1781,33 +1690,14 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,
|
|||
setAngularVelocity(new_angv);
|
||||
break;
|
||||
|
||||
case 16:
|
||||
// this is a terse 8 update
|
||||
this_update_precision = 8;
|
||||
test_pos_parent.quantize8(-0.5f*size, 1.5f*size, MIN_HEIGHT, MAX_HEIGHT);
|
||||
new_pos_parent.mV[VX] = U8_to_F32(data[0], -0.5f*size, 1.5f*size);
|
||||
new_pos_parent.mV[VY] = U8_to_F32(data[1], -0.5f*size, 1.5f*size);
|
||||
new_pos_parent.mV[VZ] = U8_to_F32(data[2], MIN_HEIGHT, MAX_HEIGHT);
|
||||
|
||||
setVelocity(U8_to_F32(data[3], -size, size),
|
||||
U8_to_F32(data[4], -size, size),
|
||||
U8_to_F32(data[5], -size, size) );
|
||||
|
||||
setAcceleration(U8_to_F32(data[6], -size, size),
|
||||
U8_to_F32(data[7], -size, size),
|
||||
U8_to_F32(data[8], -size, size) );
|
||||
|
||||
new_rot.mQ[VX] = U8_to_F32(data[9], -1.f, 1.f);
|
||||
new_rot.mQ[VY] = U8_to_F32(data[10], -1.f, 1.f);
|
||||
new_rot.mQ[VZ] = U8_to_F32(data[11], -1.f, 1.f);
|
||||
new_rot.mQ[VW] = U8_to_F32(data[12], -1.f, 1.f);
|
||||
|
||||
new_angv.set(U8_to_F32(data[13], -size, size),
|
||||
U8_to_F32(data[14], -size, size),
|
||||
U8_to_F32(data[15], -size, size) );
|
||||
setAngularVelocity(new_angv);
|
||||
break;
|
||||
}
|
||||
// Previous viewers had code for length 76, 60 or 16 byte length
|
||||
// with full precision or 8 bit quanitzation, but the
|
||||
// SL servers will never send those data formats. If you ever see this
|
||||
// warning in Second Life, please file a bug report
|
||||
default:
|
||||
LL_WARNS("UpdateFail") << "Unexpected ObjectData buffer size " << length << " for " << getID()
|
||||
<< " with OUT_FULL message" << LL_ENDL;
|
||||
}
|
||||
|
||||
U8 state;
|
||||
mesgsys->getU8Fast(_PREHASH_ObjectData, _PREHASH_State, state, block_num );
|
||||
|
|
@ -1816,13 +1706,13 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,
|
|||
}
|
||||
|
||||
default:
|
||||
LL_WARNS("UpdateFail") << "Unknown uncompressed update type " << update_type << " for " << getID() << LL_ENDL;
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// handle the compressed case
|
||||
// handle the compressed case - have dp datapacker
|
||||
LLUUID sound_uuid;
|
||||
LLUUID owner_id;
|
||||
F32 gain = 0;
|
||||
|
|
@ -2082,6 +1972,7 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,
|
|||
break;
|
||||
|
||||
default:
|
||||
LL_WARNS("UpdateFail") << "Unknown compressed update type " << update_type << " for " << getID() << LL_ENDL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -2129,7 +2020,8 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,
|
|||
if (sent_parentp && sent_parentp->getParent() == this)
|
||||
{
|
||||
// Try to recover if we attempt to attach a parent to its child
|
||||
LL_WARNS() << "Attempt to attach a parent to it's child: " << this->getID() << " to " << sent_parentp->getID() << LL_ENDL;
|
||||
LL_WARNS("UpdateFail") << "Attempt to attach a parent to it's child: " << this->getID() << " to "
|
||||
<< sent_parentp->getID() << LL_ENDL;
|
||||
this->removeChild(sent_parentp);
|
||||
sent_parentp->setDrawableParent(NULL);
|
||||
}
|
||||
|
|
@ -2153,7 +2045,7 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,
|
|||
{
|
||||
if (mDrawable->isDead() || !mDrawable->getVObj())
|
||||
{
|
||||
LL_WARNS() << "Drawable is dead or no VObj!" << LL_ENDL;
|
||||
LL_WARNS("UpdateFail") << "Drawable is dead or no VObj!" << LL_ENDL;
|
||||
sent_parentp->addChild(this);
|
||||
}
|
||||
else
|
||||
|
|
@ -2163,9 +2055,9 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,
|
|||
// Bad, we got a cycle somehow.
|
||||
// Kill both the parent and the child, and
|
||||
// set cache misses for both of them.
|
||||
LL_WARNS() << "Attempting to recover from parenting cycle!" << LL_ENDL;
|
||||
LL_WARNS() << "Killing " << sent_parentp->getID() << " and " << getID() << LL_ENDL;
|
||||
LL_WARNS() << "Adding to cache miss list" << LL_ENDL;
|
||||
LL_WARNS("UpdateFail") << "Attempting to recover from parenting cycle! "
|
||||
<< "Killing " << sent_parentp->getID() << " and " << getID()
|
||||
<< ", Adding to cache miss list" << LL_ENDL;
|
||||
setParent(NULL);
|
||||
sent_parentp->setParent(NULL);
|
||||
getRegion()->addCacheMissFull(getLocalID());
|
||||
|
|
@ -2868,22 +2760,6 @@ void LLViewerObject::interpolateLinearMotion(const F64SecondsImplicit& frame_tim
|
|||
|
||||
|
||||
|
||||
BOOL LLViewerObject::setData(const U8 *datap, const U32 data_size)
|
||||
{
|
||||
delete [] mData;
|
||||
|
||||
if (datap)
|
||||
{
|
||||
mData = new U8[data_size];
|
||||
if (!mData)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
memcpy(mData, datap, data_size); /* Flawfinder: ignore */
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// delete an item in the inventory, but don't tell the server. This is
|
||||
// used internally by remove, update, and savescript.
|
||||
// This will only delete the first item with an item_id in the list
|
||||
|
|
|
|||
|
|
@ -799,8 +799,6 @@ protected:
|
|||
|
||||
static LLViewerObject *createObject(const LLUUID &id, LLPCode pcode, LLViewerRegion *regionp, S32 flags = 0);
|
||||
|
||||
BOOL setData(const U8 *datap, const U32 data_size);
|
||||
|
||||
// Hide or show HUD, icon and particles
|
||||
void hideExtraDisplayItems( BOOL hidden );
|
||||
|
||||
|
|
|
|||
|
|
@ -351,6 +351,8 @@ void LLViewerParcelOverlay::updateOverlayTexture()
|
|||
const LLColor4U for_sale = LLUIColorTable::instance().getColor("PropertyColorForSale").get();
|
||||
const LLColor4U auction = LLUIColorTable::instance().getColor("PropertyColorAuction").get();
|
||||
|
||||
LLImageDataLock lock(mImageRaw);
|
||||
|
||||
// Create the base texture.
|
||||
U8 *raw = mImageRaw->getData();
|
||||
const S32 COUNT = mParcelGridsPerEdge * mParcelGridsPerEdge;
|
||||
|
|
|
|||
|
|
@ -299,6 +299,7 @@ LLPointer<LLViewerTexture> LLViewerTextureManager::getLocalTexture(const U32 wid
|
|||
|
||||
LLViewerFetchedTexture* LLViewerTextureManager::getFetchedTexture(const LLImageRaw* raw, FTType type, bool usemipmaps)
|
||||
{
|
||||
LLImageDataSharedLock lock(raw);
|
||||
LLViewerFetchedTexture* ret = new LLViewerFetchedTexture(raw, type, usemipmaps);
|
||||
gTextureList.addImage(ret, TEX_LIST_STANDARD);
|
||||
return ret;
|
||||
|
|
@ -2994,6 +2995,8 @@ void LLViewerFetchedTexture::saveRawImage()
|
|||
return;
|
||||
}
|
||||
|
||||
LLImageDataSharedLock lock(mRawImage);
|
||||
|
||||
mSavedRawDiscardLevel = mRawDiscardLevel;
|
||||
if (mBoostLevel == LLGLTexture::BOOST_ICON)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1269,6 +1269,8 @@ bool LLViewerTextureList::createUploadFile(LLPointer<LLImageRaw> raw_image,
|
|||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
|
||||
|
||||
LLImageDataSharedLock lock(raw_image);
|
||||
|
||||
// make a copy, since convertToUploadFile scales raw image
|
||||
LLPointer<LLImageRaw> scale_image = new LLImageRaw(
|
||||
raw_image->getData(),
|
||||
|
|
@ -1374,6 +1376,8 @@ BOOL LLViewerTextureList::createUploadFile(const std::string& filename,
|
|||
LLPointer<LLImageJ2C> LLViewerTextureList::convertToUploadFile(LLPointer<LLImageRaw> raw_image, const S32 max_image_dimentions, bool force_square, bool force_lossless)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
|
||||
LLImageDataLock lock(raw_image);
|
||||
|
||||
if (force_square)
|
||||
{
|
||||
S32 biggest_side = llmax(raw_image->getWidth(), raw_image->getHeight());
|
||||
|
|
|
|||
|
|
@ -6047,6 +6047,7 @@ BOOL LLViewerWindow::rawSnapshot(LLImageRaw *raw, S32 image_width, S32 image_hei
|
|||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
//check if there is enough memory for the snapshot image
|
||||
if(image_width * image_height > (1 << 22)) //if snapshot image is larger than 2K by 2K
|
||||
{
|
||||
|
|
@ -6175,6 +6176,9 @@ BOOL LLViewerWindow::rawSnapshot(LLImageRaw *raw, S32 image_width, S32 image_hei
|
|||
image_buffer_x = llfloor(snapshot_width * scale_factor) ;
|
||||
image_buffer_y = llfloor(snapshot_height * scale_factor) ;
|
||||
}
|
||||
|
||||
LLImageDataLock lock(raw);
|
||||
|
||||
if ((image_buffer_x > 0) && (image_buffer_y > 0))
|
||||
{
|
||||
raw->resize(image_buffer_x, image_buffer_y, 3);
|
||||
|
|
@ -6477,6 +6481,8 @@ BOOL LLViewerWindow::simpleSnapshot(LLImageRaw* raw, S32 image_width, S32 image_
|
|||
display(do_rebuild, zoom, subfield, for_snapshot);
|
||||
}
|
||||
|
||||
LLImageDataSharedLock lock(raw);
|
||||
|
||||
glReadPixels(
|
||||
0, 0,
|
||||
image_width,
|
||||
|
|
|
|||
|
|
@ -9857,7 +9857,7 @@ void LLVOAvatar::clearChat()
|
|||
}
|
||||
|
||||
|
||||
void LLVOAvatar::applyMorphMask(U8* tex_data, S32 width, S32 height, S32 num_components, LLAvatarAppearanceDefines::EBakedTextureIndex index)
|
||||
void LLVOAvatar::applyMorphMask(const U8* tex_data, S32 width, S32 height, S32 num_components, LLAvatarAppearanceDefines::EBakedTextureIndex index)
|
||||
{
|
||||
if (index >= BAKED_NUM_INDICES)
|
||||
{
|
||||
|
|
@ -10254,7 +10254,7 @@ void LLVOAvatar::parseAppearanceMessage(LLMessageSystem* mesgsys, LLAppearanceMe
|
|||
//mesgsys->getU32Fast(_PREHASH_AppearanceData, _PREHASH_Flags, appearance_flags, 0);
|
||||
}
|
||||
|
||||
// Parse the AppearanceData field, if any.
|
||||
// Parse the AppearanceHover field, if any.
|
||||
contents.mHoverOffsetWasSet = false;
|
||||
if (mesgsys->has(_PREHASH_AppearanceHover))
|
||||
{
|
||||
|
|
@ -10264,7 +10264,24 @@ void LLVOAvatar::parseAppearanceMessage(LLMessageSystem* mesgsys, LLAppearanceMe
|
|||
contents.mHoverOffset = hover;
|
||||
contents.mHoverOffsetWasSet = true;
|
||||
}
|
||||
|
||||
|
||||
// Get attachment info, if sent
|
||||
LLUUID attachment_id;
|
||||
U8 attach_point;
|
||||
S32 attach_count = mesgsys->getNumberOfBlocksFast(_PREHASH_AttachmentBlock);
|
||||
LL_DEBUGS("AVAppearanceAttachments") << "Agent " << getID() << " has "
|
||||
<< attach_count << " attachments" << LL_ENDL;
|
||||
|
||||
for (S32 attach_i = 0; attach_i < attach_count; attach_i++)
|
||||
{
|
||||
mesgsys->getUUIDFast(_PREHASH_AttachmentBlock, _PREHASH_ID, attachment_id, attach_i);
|
||||
mesgsys->getU8Fast(_PREHASH_AttachmentBlock, _PREHASH_AttachmentPoint, attach_point, attach_i);
|
||||
LL_DEBUGS("AVAppearanceAttachments") << "AV " << getID() << " has attachment " << attach_i << " "
|
||||
<< (attachment_id.isNull() ? "pending" : attachment_id.asString())
|
||||
<< " on point " << (S32)attach_point << LL_ENDL;
|
||||
// To do - store and use this information as needed
|
||||
}
|
||||
|
||||
// Parse visual params, if any.
|
||||
S32 num_blocks = mesgsys->getNumberOfBlocksFast(_PREHASH_VisualParam);
|
||||
static LLCachedControl<bool> block_some_avatars(gSavedSettings, "BlockSomeAvatarAppearanceVisualParams");
|
||||
|
|
@ -10825,6 +10842,8 @@ void LLVOAvatar::onBakedTextureMasksLoaded( BOOL success, LLViewerFetchedTexture
|
|||
{
|
||||
if(aux_src && aux_src->getComponents() == 1)
|
||||
{
|
||||
LLImageDataSharedLock lock(aux_src);
|
||||
|
||||
if (!aux_src->getData())
|
||||
{
|
||||
// <FS:Ansariel> FIRE-16122: Don't crash if we didn't receive any data
|
||||
|
|
|
|||
|
|
@ -614,7 +614,7 @@ public:
|
|||
// Morph masks
|
||||
//--------------------------------------------------------------------
|
||||
public:
|
||||
/*virtual*/ void applyMorphMask(U8* tex_data, S32 width, S32 height, S32 num_components, LLAvatarAppearanceDefines::EBakedTextureIndex index = LLAvatarAppearanceDefines::BAKED_NUM_INDICES);
|
||||
/*virtual*/ void applyMorphMask(const U8* tex_data, S32 width, S32 height, S32 num_components, LLAvatarAppearanceDefines::EBakedTextureIndex index = LLAvatarAppearanceDefines::BAKED_NUM_INDICES);
|
||||
BOOL morphMaskNeedsUpdate(LLAvatarAppearanceDefines::EBakedTextureIndex index = LLAvatarAppearanceDefines::BAKED_NUM_INDICES);
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -5476,7 +5476,7 @@ std::string LLVivoxVoiceClient::nameFromID(const LLUUID &uuid)
|
|||
LLStringUtil::replaceChar(result, '+', '-');
|
||||
LLStringUtil::replaceChar(result, '/', '_');
|
||||
|
||||
// If you need to transform a GUID to this form on the Mac OS X command line, this will do so:
|
||||
// If you need to transform a GUID to this form on the macOS command line, this will do so:
|
||||
// echo -n x && (echo e669132a-6c43-4ee1-a78d-6c82fff59f32 |xxd -r -p |openssl base64|tr '/+' '_-')
|
||||
|
||||
// The reverse transform can be done with:
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue