Merge. Pull in viewer-release after 3.6.7 release.
commit
6f5790da38
|
|
@ -33,6 +33,7 @@ indra/newview/app_settings/static_*.db2
|
|||
indra/newview/browser_profile
|
||||
indra/newview/character
|
||||
indra/newview/fmod.dll
|
||||
indra/newview/fmod.log
|
||||
indra/newview/mozilla-theme
|
||||
indra/newview/mozilla-universal-darwin.tgz
|
||||
indra/newview/res/ll_icon.*
|
||||
|
|
|
|||
2
.hgtags
2
.hgtags
|
|
@ -465,4 +465,4 @@ fe4f7c5e9fd27e09d03deb1cc9ab3e5093f6309e 3.6.3-release
|
|||
83357f31d8dbf048a8bfdc323f363bf4d588aca1 CHOP-951-a
|
||||
91ed595b716f14f07409595b734fda891a59379e 3.6.4-release
|
||||
bf6d453046011a11de2643fac610cc5258650f82 3.6.5-release
|
||||
b62e417982d9d4f3ec49d0de3b3c2e37c6d394c1 3.6.6-release
|
||||
ae457ece77001767ae9613148c495e7b98cc0f4a 3.6.7-release
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ codeticket_since = 3.3.0-release
|
|||
|
||||
# Override build system default toolchain
|
||||
# Note that this will only affect automated builds.
|
||||
Linux.distcc_version =
|
||||
Linux.gcc_version = /usr/bin/gcc-4.6
|
||||
Linux.cxx_version = /usr/bin/g++-4.6
|
||||
|
||||
|
|
|
|||
|
|
@ -924,8 +924,11 @@ Nicky Dasmijn
|
|||
MAINT-873
|
||||
SUN-72
|
||||
BUG-2432
|
||||
STORM-1935
|
||||
STORM-1936
|
||||
BUG-3605
|
||||
CHUIBUG-197
|
||||
STORM-1937
|
||||
Nicky Perian
|
||||
OPEN-1
|
||||
STORM-1087
|
||||
|
|
|
|||
|
|
@ -131,6 +131,17 @@ if (LINUX)
|
|||
# Let's actually get a numerical version of gxx's version
|
||||
STRING(REGEX REPLACE ".* ([0-9])\\.([0-9])\\.([0-9]).*" "\\1\\2\\3" CXX_VERSION_NUMBER ${CXX_VERSION})
|
||||
|
||||
# Hacks to work around gcc 4.1 TC build pool machines which can't process pragma warning disables
|
||||
# This is pure rubbish; I wish there was another way.
|
||||
#
|
||||
if(${CXX_VERSION_NUMBER} LESS 420)
|
||||
set(CMAKE_CXX_FLAGS "-Wno-deprecated -Wno-uninitialized -Wno-unused-variable -Wno-unused-function ${CMAKE_CXX_FLAGS}")
|
||||
endif (${CXX_VERSION_NUMBER} LESS 420)
|
||||
|
||||
if(${CXX_VERSION_NUMBER} GREATER 459)
|
||||
set(CMAKE_CXX_FLAGS "-Wno-deprecated -Wno-unused-but-set-variable -Wno-unused-variable ${CMAKE_CXX_FLAGS}")
|
||||
endif (${CXX_VERSION_NUMBER} GREATER 459)
|
||||
|
||||
# gcc 4.3 and above don't like the LL boost and also
|
||||
# cause warnings due to our use of deprecated headers
|
||||
if(${CXX_VERSION_NUMBER} GREATER 429)
|
||||
|
|
|
|||
|
|
@ -270,6 +270,7 @@ elseif(LINUX)
|
|||
libdb-5.1.so
|
||||
libexpat.so
|
||||
libexpat.so.1
|
||||
libfreetype.so.6
|
||||
libGLOD.so
|
||||
libgmock_main.so
|
||||
libgmock.so.0
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ if (STANDALONE)
|
|||
pkg_check_modules(FREETYPE REQUIRED freetype2)
|
||||
else (STANDALONE)
|
||||
use_prebuilt_binary(freetype)
|
||||
set(FREETYPE_INCLUDE_DIRS ${LIBS_PREBUILT_DIR}/include)
|
||||
set(FREETYPE_INCLUDE_DIRS ${LIBS_PREBUILT_DIR}/include)
|
||||
set(FREETYPE_LIBRARIES freetype)
|
||||
endif (STANDALONE)
|
||||
|
||||
|
|
|
|||
|
|
@ -258,3 +258,4 @@ void LLEditingMotion::onDeactivate()
|
|||
|
||||
|
||||
// End
|
||||
|
||||
|
|
|
|||
|
|
@ -530,3 +530,4 @@ void LLEyeMotion::onDeactivate()
|
|||
}
|
||||
|
||||
// End
|
||||
|
||||
|
|
|
|||
|
|
@ -672,7 +672,8 @@ BOOL LLKeyframeMotion::onActivate()
|
|||
//-----------------------------------------------------------------------------
|
||||
BOOL LLKeyframeMotion::onUpdate(F32 time, U8* joint_mask)
|
||||
{
|
||||
llassert(time >= 0.f);
|
||||
// llassert(time >= 0.f); // This will fire
|
||||
time = llmax(0.f, time);
|
||||
|
||||
if (mJointMotionList->mLoop)
|
||||
{
|
||||
|
|
@ -2304,3 +2305,4 @@ LLKeyframeMotion::JointConstraint::~JointConstraint()
|
|||
}
|
||||
|
||||
// End
|
||||
|
||||
|
|
|
|||
|
|
@ -390,3 +390,4 @@ BOOL LLFlyAdjustMotion::onUpdate(F32 time, U8* joint_mask)
|
|||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -169,3 +169,4 @@ BOOL LLMotion::canDeprecate()
|
|||
}
|
||||
|
||||
// End
|
||||
|
||||
|
|
|
|||
|
|
@ -169,3 +169,4 @@ void LLTargetingMotion::onDeactivate()
|
|||
|
||||
|
||||
// End
|
||||
|
||||
|
|
|
|||
|
|
@ -124,6 +124,7 @@ set(llcommon_HEADER_FILES
|
|||
linden_common.h
|
||||
linked_lists.h
|
||||
llaccountingcost.h
|
||||
llalignedarray.h
|
||||
llallocator.h
|
||||
llallocator_heap_profile.h
|
||||
llagentconstants.h
|
||||
|
|
@ -241,6 +242,7 @@ set(llcommon_HEADER_FILES
|
|||
llstrider.h
|
||||
llstring.h
|
||||
llstringtable.h
|
||||
llstaticstringtable.h
|
||||
llsys.h
|
||||
llthread.h
|
||||
llthreadsafequeue.h
|
||||
|
|
|
|||
|
|
@ -0,0 +1,139 @@
|
|||
/**
|
||||
* @file llalignedarray.h
|
||||
* @brief A static array which obeys alignment restrictions and mimics std::vector accessors.
|
||||
*
|
||||
* $LicenseInfo:firstyear=2002&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2010, Linden Research, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#ifndef LL_LLALIGNEDARRAY_H
|
||||
#define LL_LLALIGNEDARRAY_H
|
||||
|
||||
#include "llmemory.h"
|
||||
|
||||
template <class T, U32 alignment>
|
||||
class LLAlignedArray
|
||||
{
|
||||
public:
|
||||
T* mArray;
|
||||
U32 mElementCount;
|
||||
U32 mCapacity;
|
||||
|
||||
LLAlignedArray();
|
||||
~LLAlignedArray();
|
||||
|
||||
void push_back(const T& elem);
|
||||
U32 size() const { return mElementCount; }
|
||||
void resize(U32 size);
|
||||
T* append(S32 N);
|
||||
T& operator[](int idx);
|
||||
const T& operator[](int idx) const;
|
||||
};
|
||||
|
||||
template <class T, U32 alignment>
|
||||
LLAlignedArray<T, alignment>::LLAlignedArray()
|
||||
{
|
||||
llassert(alignment >= 16);
|
||||
mArray = NULL;
|
||||
mElementCount = 0;
|
||||
mCapacity = 0;
|
||||
}
|
||||
|
||||
template <class T, U32 alignment>
|
||||
LLAlignedArray<T, alignment>::~LLAlignedArray()
|
||||
{
|
||||
ll_aligned_free(mArray);
|
||||
mArray = NULL;
|
||||
mElementCount = 0;
|
||||
mCapacity = 0;
|
||||
}
|
||||
|
||||
template <class T, U32 alignment>
|
||||
void LLAlignedArray<T, alignment>::push_back(const T& elem)
|
||||
{
|
||||
T* old_buf = NULL;
|
||||
if (mCapacity <= mElementCount)
|
||||
{
|
||||
mCapacity++;
|
||||
mCapacity *= 2;
|
||||
T* new_buf = (T*) ll_aligned_malloc(mCapacity*sizeof(T), alignment);
|
||||
if (mArray)
|
||||
{
|
||||
ll_memcpy_nonaliased_aligned_16((char*)new_buf, (char*)mArray, sizeof(T)*mElementCount);
|
||||
}
|
||||
old_buf = mArray;
|
||||
mArray = new_buf;
|
||||
}
|
||||
|
||||
mArray[mElementCount++] = elem;
|
||||
|
||||
//delete old array here to prevent error on a.push_back(a[0])
|
||||
ll_aligned_free(old_buf);
|
||||
}
|
||||
|
||||
template <class T, U32 alignment>
|
||||
void LLAlignedArray<T, alignment>::resize(U32 size)
|
||||
{
|
||||
if (mCapacity < size)
|
||||
{
|
||||
mCapacity = size+mCapacity*2;
|
||||
T* new_buf = mCapacity > 0 ? (T*) ll_aligned_malloc(mCapacity*sizeof(T), alignment) : NULL;
|
||||
if (mArray)
|
||||
{
|
||||
ll_memcpy_nonaliased_aligned_16((char*) new_buf, (char*) mArray, sizeof(T)*mElementCount);
|
||||
ll_aligned_free(mArray);
|
||||
}
|
||||
|
||||
/*for (U32 i = mElementCount; i < mCapacity; ++i)
|
||||
{
|
||||
new(new_buf+i) T();
|
||||
}*/
|
||||
mArray = new_buf;
|
||||
}
|
||||
|
||||
mElementCount = size;
|
||||
}
|
||||
|
||||
|
||||
template <class T, U32 alignment>
|
||||
T& LLAlignedArray<T, alignment>::operator[](int idx)
|
||||
{
|
||||
llassert(idx < mElementCount);
|
||||
return mArray[idx];
|
||||
}
|
||||
|
||||
template <class T, U32 alignment>
|
||||
const T& LLAlignedArray<T, alignment>::operator[](int idx) const
|
||||
{
|
||||
llassert(idx < mElementCount);
|
||||
return mArray[idx];
|
||||
}
|
||||
|
||||
template <class T, U32 alignment>
|
||||
T* LLAlignedArray<T, alignment>::append(S32 N)
|
||||
{
|
||||
U32 sz = size();
|
||||
resize(sz+N);
|
||||
return &((*this)[sz]);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
|
@ -164,14 +164,20 @@ public:
|
|||
~LLAtomic32<Type>() {};
|
||||
|
||||
operator const Type() { apr_uint32_t data = apr_atomic_read32(&mData); return Type(data); }
|
||||
|
||||
Type CurrentValue() const { apr_uint32_t data = apr_atomic_read32(const_cast< volatile apr_uint32_t* >(&mData)); return Type(data); }
|
||||
|
||||
Type operator =(const Type& x) { apr_atomic_set32(&mData, apr_uint32_t(x)); return Type(mData); }
|
||||
void operator -=(Type x) { apr_atomic_sub32(&mData, apr_uint32_t(x)); }
|
||||
void operator +=(Type x) { apr_atomic_add32(&mData, apr_uint32_t(x)); }
|
||||
Type operator ++(int) { return apr_atomic_inc32(&mData); } // Type++
|
||||
Type operator --(int) { return apr_atomic_dec32(&mData); } // approximately --Type (0 if final is 0, non-zero otherwise)
|
||||
|
||||
Type operator ++() { return apr_atomic_inc32(&mData); } // Type++
|
||||
Type operator --() { return apr_atomic_dec32(&mData); } // approximately --Type (0 if final is 0, non-zero otherwise)
|
||||
|
||||
private:
|
||||
apr_uint32_t mData;
|
||||
volatile apr_uint32_t mData;
|
||||
};
|
||||
|
||||
typedef LLAtomic32<U32> LLAtomicU32;
|
||||
|
|
|
|||
|
|
@ -44,6 +44,7 @@ void LLCommon::initClass()
|
|||
}
|
||||
LLTimer::initClass();
|
||||
LLThreadSafeRefCount::initThreadSafeRefCount();
|
||||
assert_main_thread(); // Make sure we record the main thread
|
||||
// LLWorkerThread::initClass();
|
||||
// LLFrameCallbackManager::initClass();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -87,3 +87,4 @@ F32 LLCriticalDamp::getInterpolant(const F32 time_constant, BOOL use_cache)
|
|||
|
||||
return interpolant;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -47,6 +47,7 @@ class LL_COMMON_API LLEventAPI: public LLDispatchListener,
|
|||
typedef LLInstanceTracker<LLEventAPI, std::string> ibase;
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* @param name LLEventPump name on which this LLEventAPI will listen. This
|
||||
* also serves as the LLInstanceTracker instance key.
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@
|
|||
class LL_COMMON_API LLEventTimer : public LLInstanceTracker<LLEventTimer>
|
||||
{
|
||||
public:
|
||||
|
||||
LLEventTimer(F32 period); // period is the amount of time between each call to tick() in seconds
|
||||
LLEventTimer(const LLDate& time);
|
||||
virtual ~LLEventTimer();
|
||||
|
|
|
|||
|
|
@ -107,17 +107,13 @@ class NamedTimerFactory : public LLSingleton<NamedTimerFactory>
|
|||
{
|
||||
public:
|
||||
NamedTimerFactory()
|
||||
: mTimerRoot(NULL)
|
||||
{}
|
||||
|
||||
/*virtual */ void initSingleton()
|
||||
: mTimerRoot(new LLFastTimer::NamedTimer("root"))
|
||||
{
|
||||
mTimerRoot = new LLFastTimer::NamedTimer("root");
|
||||
mRootFrameState.setNamedTimer(mTimerRoot);
|
||||
mTimerRoot->setFrameState(&mRootFrameState);
|
||||
mTimerRoot->mParent = mTimerRoot;
|
||||
mTimerRoot->setCollapsed(false);
|
||||
mRootFrameState.mParent = &mRootFrameState;
|
||||
mRootFrameState.mParent = &mRootFrameState;
|
||||
}
|
||||
|
||||
~NamedTimerFactory()
|
||||
|
|
|
|||
|
|
@ -139,10 +139,11 @@ public:
|
|||
|
||||
// used to statically declare a new named timer
|
||||
class LL_COMMON_API DeclareTimer
|
||||
: public LLInstanceTracker<DeclareTimer>
|
||||
: public LLInstanceTracker< DeclareTimer >
|
||||
{
|
||||
friend class LLFastTimer;
|
||||
public:
|
||||
|
||||
DeclareTimer(const std::string& name, bool open);
|
||||
DeclareTimer(const std::string& name);
|
||||
|
||||
|
|
|
|||
|
|
@ -1952,7 +1952,7 @@ namespace LLInitParam
|
|||
class Mandatory : public TypedParam<T, NAME_VALUE_LOOKUP, false>
|
||||
{
|
||||
typedef TypedParam<T, NAME_VALUE_LOOKUP, false> super_t;
|
||||
typedef Mandatory<T, NAME_VALUE_LOOKUP> self_t;
|
||||
typedef Mandatory<T, NAME_VALUE_LOOKUP> self_t;
|
||||
typedef typename super_t::value_t value_t;
|
||||
typedef typename super_t::default_value_t default_value_t;
|
||||
|
||||
|
|
|
|||
|
|
@ -32,18 +32,3 @@
|
|||
// external library headers
|
||||
// other Linden headers
|
||||
|
||||
//static
|
||||
void * & LLInstanceTrackerBase::getInstances(std::type_info const & info)
|
||||
{
|
||||
typedef std::map<std::string, void *> InstancesMap;
|
||||
static InstancesMap instances;
|
||||
|
||||
// std::map::insert() is just what we want here. You attempt to insert a
|
||||
// (key, value) pair. If the specified key doesn't yet exist, it inserts
|
||||
// the pair and returns a std::pair of (iterator, true). If the specified
|
||||
// key DOES exist, insert() simply returns (iterator, false). One lookup
|
||||
// handles both cases.
|
||||
return instances.insert(InstancesMap::value_type(info.name(),
|
||||
InstancesMap::mapped_type()))
|
||||
.first->second;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -46,21 +46,7 @@
|
|||
class LL_COMMON_API LLInstanceTrackerBase
|
||||
{
|
||||
protected:
|
||||
/// Get a process-unique void* pointer slot for the specified type_info
|
||||
static void * & getInstances(std::type_info const & info);
|
||||
|
||||
/// Find or create a STATICDATA instance for the specified TRACKED class.
|
||||
/// STATICDATA must be default-constructible.
|
||||
template<typename STATICDATA, class TRACKED>
|
||||
static STATICDATA& getStatic()
|
||||
{
|
||||
void *& instances = getInstances(typeid(TRACKED));
|
||||
if (! instances)
|
||||
{
|
||||
instances = new STATICDATA;
|
||||
}
|
||||
return *static_cast<STATICDATA*>(instances);
|
||||
}
|
||||
|
||||
/// It's not essential to derive your STATICDATA (for use with
|
||||
/// getStatic()) from StaticBase; it's just that both known
|
||||
|
|
@ -74,6 +60,8 @@ protected:
|
|||
};
|
||||
};
|
||||
|
||||
LL_COMMON_API void assert_main_thread();
|
||||
|
||||
/// This mix-in class adds support for tracking all instances of the specified class parameter T
|
||||
/// The (optional) key associates a value of type KEY with a given instance of T, for quick lookup
|
||||
/// If KEY is not provided, then instances are stored in a simple set
|
||||
|
|
@ -81,14 +69,18 @@ protected:
|
|||
template<typename T, typename KEY = T*>
|
||||
class LLInstanceTracker : public LLInstanceTrackerBase
|
||||
{
|
||||
typedef LLInstanceTracker<T, KEY> MyT;
|
||||
typedef LLInstanceTracker<T, KEY> self_t;
|
||||
typedef typename std::map<KEY, T*> InstanceMap;
|
||||
struct StaticData: public StaticBase
|
||||
{
|
||||
InstanceMap sMap;
|
||||
};
|
||||
static StaticData& getStatic() { return LLInstanceTrackerBase::getStatic<StaticData, MyT>(); }
|
||||
static InstanceMap& getMap_() { return getStatic().sMap; }
|
||||
static StaticData& getStatic() { static StaticData sData; return sData;}
|
||||
static InstanceMap& getMap_()
|
||||
{
|
||||
// assert_main_thread(); fwiw this class is not thread safe, and it used by multiple threads. Bad things happen.
|
||||
return getStatic().sMap;
|
||||
}
|
||||
|
||||
public:
|
||||
class instance_iter : public boost::iterator_facade<instance_iter, T, boost::forward_traversal_tag>
|
||||
|
|
@ -220,7 +212,11 @@ private:
|
|||
}
|
||||
void remove_()
|
||||
{
|
||||
getMap_().erase(mInstanceKey);
|
||||
typename InstanceMap::iterator iter = getMap_().find(mInstanceKey);
|
||||
if (iter != getMap_().end())
|
||||
{
|
||||
getMap_().erase(iter);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
|
|
@ -232,13 +228,13 @@ private:
|
|||
template<typename T>
|
||||
class LLInstanceTracker<T, T*> : public LLInstanceTrackerBase
|
||||
{
|
||||
typedef LLInstanceTracker<T, T*> MyT;
|
||||
typedef LLInstanceTracker<T, T*> self_t;
|
||||
typedef typename std::set<T*> InstanceSet;
|
||||
struct StaticData: public StaticBase
|
||||
{
|
||||
InstanceSet sSet;
|
||||
};
|
||||
static StaticData& getStatic() { return LLInstanceTrackerBase::getStatic<StaticData, MyT>(); }
|
||||
static StaticData& getStatic() { static StaticData sData; return sData; }
|
||||
static InstanceSet& getSet_() { return getStatic().sSet; }
|
||||
|
||||
public:
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@
|
|||
class LL_COMMON_API LLLeap: public LLInstanceTracker<LLLeap>
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* Pass a brief string description, mostly for logging purposes. The desc
|
||||
* need not be unique, but obviously the clearer we can make it, the
|
||||
|
|
|
|||
|
|
@ -67,6 +67,19 @@ const S32 LSL_PRIM_TEXGEN = 22;
|
|||
const S32 LSL_PRIM_POINT_LIGHT = 23;
|
||||
const S32 LSL_PRIM_CAST_SHADOWS = 24;
|
||||
const S32 LSL_PRIM_GLOW = 25;
|
||||
const S32 LSL_PRIM_TEXT = 26;
|
||||
const S32 LSL_PRIM_NAME = 27;
|
||||
const S32 LSL_PRIM_DESC = 28;
|
||||
const S32 LSL_PRIM_ROT_LOCAL = 29;
|
||||
const S32 LSL_PRIM_PHYSICS_SHAPE_TYPE = 30;
|
||||
const S32 LSL_PRIM_OMEGA = 32;
|
||||
const S32 LSL_PRIM_POS_LOCAL = 33;
|
||||
const S32 LSL_PRIM_LINK_TARGET = 34;
|
||||
const S32 LSL_PRIM_SLICE = 35;
|
||||
|
||||
const S32 LSL_PRIM_PHYSICS_SHAPE_PRIM = 0;
|
||||
const S32 LSL_PRIM_PHYSICS_SHAPE_NONE = 1;
|
||||
const S32 LSL_PRIM_PHYSICS_SHAPE_CONVEX = 2;
|
||||
|
||||
const S32 LSL_PRIM_TYPE_BOX = 0;
|
||||
const S32 LSL_PRIM_TYPE_CYLINDER= 1;
|
||||
|
|
@ -179,6 +192,22 @@ const S32 OBJECT_VELOCITY = 5;
|
|||
const S32 OBJECT_OWNER = 6;
|
||||
const S32 OBJECT_GROUP = 7;
|
||||
const S32 OBJECT_CREATOR = 8;
|
||||
const S32 OBJECT_RUNNING_SCRIPT_COUNT = 9;
|
||||
const S32 OBJECT_TOTAL_SCRIPT_COUNT = 10;
|
||||
const S32 OBJECT_SCRIPT_MEMORY = 11;
|
||||
const S32 OBJECT_SCRIPT_TIME = 12;
|
||||
const S32 OBJECT_PRIM_EQUIVALENCE = 13;
|
||||
const S32 OBJECT_SERVER_COST = 14;
|
||||
const S32 OBJECT_STREAMING_COST = 15;
|
||||
const S32 OBJECT_PHYSICS_COST = 16;
|
||||
const S32 OBJECT_CHARACTER_TIME = 17;
|
||||
const S32 OBJECT_ROOT = 18;
|
||||
const S32 OBJECT_ATTACHED_POINT = 19;
|
||||
const S32 OBJECT_PATHFINDING_TYPE = 20;
|
||||
const S32 OBJECT_PHYSICS = 21;
|
||||
const S32 OBJECT_PHANTOM = 22;
|
||||
const S32 OBJECT_TEMP_ON_REZ = 23;
|
||||
const S32 OBJECT_RENDER_WEIGHT = 24;
|
||||
|
||||
// llTextBox() magic token string - yes this is a hack. sue me.
|
||||
char const* const TEXTBOX_MAGIC_TOKEN = "!!llTextBox!!";
|
||||
|
|
|
|||
|
|
@ -36,19 +36,68 @@ class LLMutex ;
|
|||
#define LL_CHECK_MEMORY
|
||||
#endif
|
||||
|
||||
LL_COMMON_API void ll_assert_aligned_func(uintptr_t ptr,U32 alignment);
|
||||
|
||||
#ifdef SHOW_ASSERT
|
||||
#define ll_assert_aligned(ptr,alignment) ll_assert_aligned_func(reinterpret_cast<uintptr_t>(ptr),((U32)alignment))
|
||||
#else
|
||||
#define ll_assert_aligned(ptr,alignment)
|
||||
#endif
|
||||
|
||||
#include <xmmintrin.h>
|
||||
|
||||
template <typename T> T* LL_NEXT_ALIGNED_ADDRESS(T* address)
|
||||
{
|
||||
return reinterpret_cast<T*>(
|
||||
(reinterpret_cast<uintptr_t>(address) + 0xF) & ~0xF);
|
||||
}
|
||||
|
||||
template <typename T> T* LL_NEXT_ALIGNED_ADDRESS_64(T* address)
|
||||
{
|
||||
return reinterpret_cast<T*>(
|
||||
(reinterpret_cast<uintptr_t>(address) + 0x3F) & ~0x3F);
|
||||
}
|
||||
|
||||
#if LL_LINUX || LL_DARWIN
|
||||
|
||||
#define LL_ALIGN_PREFIX(x)
|
||||
#define LL_ALIGN_POSTFIX(x) __attribute__((aligned(x)))
|
||||
|
||||
#elif LL_WINDOWS
|
||||
|
||||
#define LL_ALIGN_PREFIX(x) __declspec(align(x))
|
||||
#define LL_ALIGN_POSTFIX(x)
|
||||
|
||||
#else
|
||||
#error "LL_ALIGN_PREFIX and LL_ALIGN_POSTFIX undefined"
|
||||
#endif
|
||||
|
||||
#define LL_ALIGN_16(var) LL_ALIGN_PREFIX(16) var LL_ALIGN_POSTFIX(16)
|
||||
|
||||
inline void* ll_aligned_malloc( size_t size, int align )
|
||||
{
|
||||
#if defined(LL_WINDOWS)
|
||||
return _aligned_malloc(size, align);
|
||||
#else
|
||||
void* mem = malloc( size + (align - 1) + sizeof(void*) );
|
||||
char* aligned = ((char*)mem) + sizeof(void*);
|
||||
aligned += align - ((uintptr_t)aligned & (align - 1));
|
||||
|
||||
((void**)aligned)[-1] = mem;
|
||||
return aligned;
|
||||
#endif
|
||||
}
|
||||
|
||||
inline void ll_aligned_free( void* ptr )
|
||||
{
|
||||
free( ((void**)ptr)[-1] );
|
||||
#if defined(LL_WINDOWS)
|
||||
_aligned_free(ptr);
|
||||
#else
|
||||
if (ptr)
|
||||
{
|
||||
free( ((void**)ptr)[-1] );
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#if !LL_USE_TCMALLOC
|
||||
|
|
@ -133,6 +182,78 @@ inline void ll_aligned_free_32(void *p)
|
|||
#endif
|
||||
}
|
||||
|
||||
|
||||
// Copy words 16-byte blocks from src to dst. Source and destination MUST NOT OVERLAP.
|
||||
// Source and dest must be 16-byte aligned and size must be multiple of 16.
|
||||
//
|
||||
inline void ll_memcpy_nonaliased_aligned_16(char* __restrict dst, const char* __restrict src, size_t bytes)
|
||||
{
|
||||
assert(src != NULL);
|
||||
assert(dst != NULL);
|
||||
assert(bytes > 0);
|
||||
assert((bytes % sizeof(F32))== 0);
|
||||
ll_assert_aligned(src,16);
|
||||
ll_assert_aligned(dst,16);
|
||||
assert((src < dst) ? ((src + bytes) < dst) : ((dst + bytes) < src));
|
||||
assert(bytes%16==0);
|
||||
|
||||
char* end = dst + bytes;
|
||||
|
||||
if (bytes > 64)
|
||||
{
|
||||
|
||||
// Find start of 64b aligned area within block
|
||||
//
|
||||
void* begin_64 = LL_NEXT_ALIGNED_ADDRESS_64(dst);
|
||||
|
||||
//at least 64 bytes before the end of the destination, switch to 16 byte copies
|
||||
void* end_64 = end-64;
|
||||
|
||||
// Prefetch the head of the 64b area now
|
||||
//
|
||||
_mm_prefetch((char*)begin_64, _MM_HINT_NTA);
|
||||
_mm_prefetch((char*)begin_64 + 64, _MM_HINT_NTA);
|
||||
_mm_prefetch((char*)begin_64 + 128, _MM_HINT_NTA);
|
||||
_mm_prefetch((char*)begin_64 + 192, _MM_HINT_NTA);
|
||||
|
||||
// Copy 16b chunks until we're 64b aligned
|
||||
//
|
||||
while (dst < begin_64)
|
||||
{
|
||||
|
||||
_mm_store_ps((F32*)dst, _mm_load_ps((F32*)src));
|
||||
dst += 16;
|
||||
src += 16;
|
||||
}
|
||||
|
||||
// Copy 64b chunks up to your tail
|
||||
//
|
||||
// might be good to shmoo the 512b prefetch offset
|
||||
// (characterize performance for various values)
|
||||
//
|
||||
while (dst < end_64)
|
||||
{
|
||||
_mm_prefetch((char*)src + 512, _MM_HINT_NTA);
|
||||
_mm_prefetch((char*)dst + 512, _MM_HINT_NTA);
|
||||
_mm_store_ps((F32*)dst, _mm_load_ps((F32*)src));
|
||||
_mm_store_ps((F32*)(dst + 16), _mm_load_ps((F32*)(src + 16)));
|
||||
_mm_store_ps((F32*)(dst + 32), _mm_load_ps((F32*)(src + 32)));
|
||||
_mm_store_ps((F32*)(dst + 48), _mm_load_ps((F32*)(src + 48)));
|
||||
dst += 64;
|
||||
src += 64;
|
||||
}
|
||||
}
|
||||
|
||||
// Copy remainder 16b tail chunks (or ALL 16b chunks for sub-64b copies)
|
||||
//
|
||||
while (dst < end)
|
||||
{
|
||||
_mm_store_ps((F32*)dst, _mm_load_ps((F32*)src));
|
||||
dst += 16;
|
||||
src += 16;
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef __DEBUG_PRIVATE_MEM__
|
||||
#define __DEBUG_PRIVATE_MEM__ 0
|
||||
#endif
|
||||
|
|
@ -541,13 +662,7 @@ void LLPrivateMemoryPoolTester::operator delete[](void* addr)
|
|||
|
||||
// LLSingleton moved to llsingleton.h
|
||||
|
||||
LL_COMMON_API void ll_assert_aligned_func(uintptr_t ptr,U32 alignment);
|
||||
|
||||
#ifdef SHOW_ASSERT
|
||||
#define ll_assert_aligned(ptr,alignment) ll_assert_aligned_func(reinterpret_cast<uintptr_t>(ptr),((U32)alignment))
|
||||
#else
|
||||
#define ll_assert_aligned(ptr,alignment)
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -28,5 +28,4 @@
|
|||
|
||||
#include "llsingleton.h"
|
||||
|
||||
std::map<std::string, void *> * LLSingletonRegistry::sSingletonMap = NULL;
|
||||
|
||||
|
|
|
|||
|
|
@ -30,38 +30,6 @@
|
|||
#include <typeinfo>
|
||||
#include <boost/noncopyable.hpp>
|
||||
|
||||
/// @brief A global registry of all singletons to prevent duplicate allocations
|
||||
/// across shared library boundaries
|
||||
class LL_COMMON_API LLSingletonRegistry {
|
||||
private:
|
||||
typedef std::map<std::string, void *> TypeMap;
|
||||
static TypeMap * sSingletonMap;
|
||||
|
||||
static void checkInit()
|
||||
{
|
||||
if(sSingletonMap == NULL)
|
||||
{
|
||||
sSingletonMap = new TypeMap();
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
template<typename T> static void * & get()
|
||||
{
|
||||
std::string name(typeid(T).name());
|
||||
|
||||
checkInit();
|
||||
|
||||
// the first entry of the pair returned by insert will be either the existing
|
||||
// iterator matching our key, or the newly inserted NULL initialized entry
|
||||
// see "Insert element" in http://www.sgi.com/tech/stl/UniqueAssociativeContainer.html
|
||||
TypeMap::iterator result =
|
||||
sSingletonMap->insert(std::make_pair(name, (void*)NULL)).first;
|
||||
|
||||
return result->second;
|
||||
}
|
||||
};
|
||||
|
||||
// LLSingleton implements the getInstance() method part of the Singleton
|
||||
// pattern. It can't make the derived class constructors protected, though, so
|
||||
// you have to do that yourself.
|
||||
|
|
@ -101,20 +69,23 @@ private:
|
|||
} EInitState;
|
||||
|
||||
// stores pointer to singleton instance
|
||||
// and tracks initialization state of singleton
|
||||
struct SingletonInstanceData
|
||||
struct SingletonLifetimeManager
|
||||
{
|
||||
EInitState mInitState;
|
||||
DERIVED_TYPE* mSingletonInstance;
|
||||
|
||||
SingletonInstanceData()
|
||||
: mSingletonInstance(NULL),
|
||||
mInitState(UNINITIALIZED)
|
||||
{}
|
||||
|
||||
~SingletonInstanceData()
|
||||
SingletonLifetimeManager()
|
||||
{
|
||||
if (mInitState != DELETED)
|
||||
construct();
|
||||
}
|
||||
|
||||
static void construct()
|
||||
{
|
||||
sData.mInitState = CONSTRUCTING;
|
||||
sData.mInstance = new DERIVED_TYPE();
|
||||
sData.mInitState = INITIALIZING;
|
||||
}
|
||||
|
||||
~SingletonLifetimeManager()
|
||||
{
|
||||
if (sData.mInitState != DELETED)
|
||||
{
|
||||
deleteSingleton();
|
||||
}
|
||||
|
|
@ -124,9 +95,8 @@ private:
|
|||
public:
|
||||
virtual ~LLSingleton()
|
||||
{
|
||||
SingletonInstanceData& data = getData();
|
||||
data.mSingletonInstance = NULL;
|
||||
data.mInitState = DELETED;
|
||||
sData.mInstance = NULL;
|
||||
sData.mInitState = DELETED;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -151,50 +121,46 @@ public:
|
|||
*/
|
||||
static void deleteSingleton()
|
||||
{
|
||||
delete getData().mSingletonInstance;
|
||||
getData().mSingletonInstance = NULL;
|
||||
getData().mInitState = DELETED;
|
||||
delete sData.mInstance;
|
||||
sData.mInstance = NULL;
|
||||
sData.mInitState = DELETED;
|
||||
}
|
||||
|
||||
static SingletonInstanceData& getData()
|
||||
{
|
||||
// this is static to cache the lookup results
|
||||
static void * & registry = LLSingletonRegistry::get<DERIVED_TYPE>();
|
||||
|
||||
// *TODO - look into making this threadsafe
|
||||
if(NULL == registry)
|
||||
{
|
||||
static SingletonInstanceData data;
|
||||
registry = &data;
|
||||
}
|
||||
|
||||
return *static_cast<SingletonInstanceData *>(registry);
|
||||
}
|
||||
|
||||
static DERIVED_TYPE* getInstance()
|
||||
{
|
||||
SingletonInstanceData& data = getData();
|
||||
static SingletonLifetimeManager sLifeTimeMgr;
|
||||
|
||||
if (data.mInitState == CONSTRUCTING)
|
||||
switch (sData.mInitState)
|
||||
{
|
||||
case UNINITIALIZED:
|
||||
// should never be uninitialized at this point
|
||||
llassert(false);
|
||||
return NULL;
|
||||
case CONSTRUCTING:
|
||||
llerrs << "Tried to access singleton " << typeid(DERIVED_TYPE).name() << " from singleton constructor!" << llendl;
|
||||
return NULL;
|
||||
case INITIALIZING:
|
||||
// go ahead and flag ourselves as initialized so we can be reentrant during initialization
|
||||
sData.mInitState = INITIALIZED;
|
||||
sData.mInstance->initSingleton();
|
||||
return sData.mInstance;
|
||||
case INITIALIZED:
|
||||
return sData.mInstance;
|
||||
case DELETED:
|
||||
llwarns << "Trying to access deleted singleton " << typeid(DERIVED_TYPE).name() << " creating new instance" << llendl;
|
||||
SingletonLifetimeManager::construct();
|
||||
sData.mInitState = INITIALIZED;
|
||||
sData.mInstance->initSingleton();
|
||||
return sData.mInstance;
|
||||
}
|
||||
|
||||
if (data.mInitState == DELETED)
|
||||
{
|
||||
llwarns << "Trying to access deleted singleton " << typeid(DERIVED_TYPE).name() << " creating new instance" << llendl;
|
||||
}
|
||||
|
||||
if (!data.mSingletonInstance)
|
||||
{
|
||||
data.mInitState = CONSTRUCTING;
|
||||
data.mSingletonInstance = new DERIVED_TYPE();
|
||||
data.mInitState = INITIALIZING;
|
||||
data.mSingletonInstance->initSingleton();
|
||||
data.mInitState = INITIALIZED;
|
||||
}
|
||||
|
||||
return data.mSingletonInstance;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static DERIVED_TYPE* getIfExists()
|
||||
{
|
||||
return sData.mInstance;
|
||||
}
|
||||
|
||||
// Reference version of getInstance()
|
||||
|
|
@ -208,18 +174,29 @@ public:
|
|||
// Use this to avoid accessing singletons before the can safely be constructed
|
||||
static bool instanceExists()
|
||||
{
|
||||
return getData().mInitState == INITIALIZED;
|
||||
return sData.mInitState == INITIALIZED;
|
||||
}
|
||||
|
||||
// Has this singleton already been deleted?
|
||||
// Use this to avoid accessing singletons from a static object's destructor
|
||||
static bool destroyed()
|
||||
{
|
||||
return getData().mInitState == DELETED;
|
||||
return sData.mInitState == DELETED;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
virtual void initSingleton() {}
|
||||
|
||||
struct SingletonData
|
||||
{
|
||||
EInitState mInitState;
|
||||
DERIVED_TYPE* mInstance;
|
||||
};
|
||||
static SingletonData sData;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
typename LLSingleton<T>::SingletonData LLSingleton<T>::sData;
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -0,0 +1,82 @@
|
|||
/**
|
||||
* @file llstringtable.h
|
||||
* @brief The LLStringTable class provides a _fast_ method for finding
|
||||
* unique copies of strings.
|
||||
*
|
||||
* $LicenseInfo:firstyear=2001&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2010, Linden Research, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#ifndef LL_STATIC_STRING_TABLE_H
|
||||
#define LL_STATIC_STRING_TABLE_H
|
||||
|
||||
#include "lldefs.h"
|
||||
#include <boost/unordered_map.hpp>
|
||||
#include "llstl.h"
|
||||
|
||||
class LLStaticHashedString
|
||||
{
|
||||
public:
|
||||
|
||||
LLStaticHashedString(const std::string& s)
|
||||
{
|
||||
string_hash = makehash(s);
|
||||
string = s;
|
||||
}
|
||||
|
||||
const std::string& String() const { return string; }
|
||||
size_t Hash() const { return string_hash; }
|
||||
|
||||
bool operator==(const LLStaticHashedString& b) const { return Hash() == b.Hash(); }
|
||||
|
||||
protected:
|
||||
|
||||
size_t makehash(const std::string& s)
|
||||
{
|
||||
size_t len = s.size();
|
||||
const char* c = s.c_str();
|
||||
size_t hashval = 0;
|
||||
for (size_t i=0; i<len; i++)
|
||||
{
|
||||
hashval = ((hashval<<5) + hashval) + *c++;
|
||||
}
|
||||
return hashval;
|
||||
}
|
||||
|
||||
std::string string;
|
||||
size_t string_hash;
|
||||
};
|
||||
|
||||
struct LLStaticStringHasher
|
||||
{
|
||||
enum { bucket_size = 8 };
|
||||
size_t operator()(const LLStaticHashedString& key_value) const { return key_value.Hash(); }
|
||||
bool operator()(const LLStaticHashedString& left, const LLStaticHashedString& right) const { return left.Hash() < right.Hash(); }
|
||||
};
|
||||
|
||||
template< typename MappedObject >
|
||||
class LL_COMMON_API LLStaticStringTable
|
||||
: public boost::unordered_map< LLStaticHashedString, MappedObject, LLStaticStringHasher >
|
||||
{
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
|
@ -42,14 +42,6 @@
|
|||
//# define STRING_TABLE_HASH_MAP 1
|
||||
#endif
|
||||
|
||||
#if STRING_TABLE_HASH_MAP
|
||||
# if LL_WINDOWS
|
||||
# include <hash_map>
|
||||
# else
|
||||
# include <ext/hash_map>
|
||||
# endif
|
||||
#endif
|
||||
|
||||
const U32 MAX_STRINGS_LENGTH = 256;
|
||||
|
||||
class LL_COMMON_API LLStringTableEntry
|
||||
|
|
|
|||
|
|
@ -67,7 +67,8 @@ LL_COMMON_API void assert_main_thread()
|
|||
static U32 s_thread_id = LLThread::currentID();
|
||||
if (LLThread::currentID() != s_thread_id)
|
||||
{
|
||||
llerrs << "Illegal execution outside main thread." << llendl;
|
||||
llwarns << "Illegal execution from thread id " << (S32) LLThread::currentID()
|
||||
<< " outside main thread " << (S32) s_thread_id << llendl;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -525,15 +526,7 @@ LLThreadSafeRefCount::LLThreadSafeRefCount() :
|
|||
|
||||
LLThreadSafeRefCount::LLThreadSafeRefCount(const LLThreadSafeRefCount& src)
|
||||
{
|
||||
if (sMutex)
|
||||
{
|
||||
sMutex->lock();
|
||||
}
|
||||
mRef = 0;
|
||||
if (sMutex)
|
||||
{
|
||||
sMutex->unlock();
|
||||
}
|
||||
}
|
||||
|
||||
LLThreadSafeRefCount::~LLThreadSafeRefCount()
|
||||
|
|
|
|||
|
|
@ -284,49 +284,39 @@ public:
|
|||
LLThreadSafeRefCount(const LLThreadSafeRefCount&);
|
||||
LLThreadSafeRefCount& operator=(const LLThreadSafeRefCount& ref)
|
||||
{
|
||||
if (sMutex)
|
||||
{
|
||||
sMutex->lock();
|
||||
}
|
||||
mRef = 0;
|
||||
if (sMutex)
|
||||
{
|
||||
sMutex->unlock();
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void ref()
|
||||
{
|
||||
if (sMutex) sMutex->lock();
|
||||
mRef++;
|
||||
if (sMutex) sMutex->unlock();
|
||||
}
|
||||
|
||||
S32 unref()
|
||||
void unref()
|
||||
{
|
||||
llassert(mRef >= 1);
|
||||
if (sMutex) sMutex->lock();
|
||||
S32 res = --mRef;
|
||||
if (sMutex) sMutex->unlock();
|
||||
if (0 == res)
|
||||
{
|
||||
delete this;
|
||||
return 0;
|
||||
if ((--mRef) == 0) // See note in llapr.h on atomic decrement operator return value.
|
||||
{
|
||||
// If we hit zero, the caller should be the only smart pointer owning the object and we can delete it.
|
||||
// It is technically possible for a vanilla pointer to mess this up, or another thread to
|
||||
// jump in, find this object, create another smart pointer and end up dangling, but if
|
||||
// the code is that bad and not thread-safe, it's trouble already.
|
||||
delete this;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
S32 getNumRefs() const
|
||||
{
|
||||
return mRef;
|
||||
const S32 currentVal = mRef.CurrentValue();
|
||||
return currentVal;
|
||||
}
|
||||
|
||||
private:
|
||||
S32 mRef;
|
||||
LLAtomic32< S32 > mRef;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* intrusive pointer support for LLThreadSafeRefCount
|
||||
* this allows you to use boost::intrusive_ptr with any LLThreadSafeRefCount-derived type
|
||||
|
|
@ -357,4 +347,6 @@ public:
|
|||
|
||||
//============================================================================
|
||||
|
||||
extern LL_COMMON_API void assert_main_thread();
|
||||
|
||||
#endif // LL_LLTHREAD_H
|
||||
|
|
|
|||
|
|
@ -159,9 +159,6 @@ const int HTTP_SERVICE_LOOP_SLEEP_NORMAL_MS = 2;
|
|||
// Block allocation size (a tuning parameter) is found
|
||||
// in bufferarray.h.
|
||||
|
||||
// Compatibility controls
|
||||
const bool HTTP_ENABLE_LINKSYS_WRT54G_V5_DNS_FIX = true;
|
||||
|
||||
} // end namespace LLCore
|
||||
|
||||
#endif // _LLCORE_HTTP_INTERNAL_H_
|
||||
|
|
|
|||
|
|
@ -204,9 +204,11 @@ void HttpOpRequest::stageFromActive(HttpService * service)
|
|||
if (mReplyLength)
|
||||
{
|
||||
// If non-zero, we received and processed a Content-Range
|
||||
// header with the response. Verify that what it says
|
||||
// is consistent with the received data.
|
||||
if (mReplyLength != mReplyBody->size())
|
||||
// header with the response. If there is received data
|
||||
// (and there may not be due to protocol violations,
|
||||
// HEAD requests, etc., see BUG-2295) Verify that what it
|
||||
// says is consistent with the received data.
|
||||
if (mReplyBody && mReplyBody->size() && mReplyLength != mReplyBody->size())
|
||||
{
|
||||
// Not as expected, fail the request
|
||||
mStatus = HttpStatus(HttpStatus::LLCORE, HE_INV_CONTENT_RANGE_HDR);
|
||||
|
|
@ -367,7 +369,6 @@ void HttpOpRequest::setupCommon(HttpRequest::policy_t policy_id,
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
// Sets all libcurl options and data for a request.
|
||||
//
|
||||
// Used both for initial requests and to 'reload' for
|
||||
|
|
@ -411,7 +412,7 @@ HttpStatus HttpOpRequest::prepareRequest(HttpService * service)
|
|||
// Get global policy options
|
||||
HttpPolicyGlobal & policy(service->getPolicy().getGlobalOptions());
|
||||
|
||||
mCurlHandle = curl_easy_init();
|
||||
mCurlHandle = LLCurl::createStandardCurlHandle();
|
||||
if (! mCurlHandle)
|
||||
{
|
||||
// We're in trouble. We'll continue but it won't go well.
|
||||
|
|
@ -432,26 +433,14 @@ HttpStatus HttpOpRequest::prepareRequest(HttpService * service)
|
|||
code = curl_easy_setopt(mCurlHandle, CURLOPT_ENCODING, "");
|
||||
check_curl_easy_code(code, CURLOPT_ENCODING);
|
||||
|
||||
if (HTTP_ENABLE_LINKSYS_WRT54G_V5_DNS_FIX)
|
||||
{
|
||||
// The Linksys WRT54G V5 router has an issue with frequent
|
||||
// DNS lookups from LAN machines. If they happen too often,
|
||||
// like for every HTTP request, the router gets annoyed after
|
||||
// about 700 or so requests and starts issuing TCP RSTs to
|
||||
// new connections. Reuse the DNS lookups for even a few
|
||||
// seconds and no RSTs.
|
||||
code = curl_easy_setopt(mCurlHandle, CURLOPT_DNS_CACHE_TIMEOUT, 15);
|
||||
check_curl_easy_code(code, CURLOPT_DNS_CACHE_TIMEOUT);
|
||||
}
|
||||
else
|
||||
{
|
||||
// *TODO: Revisit this old DNS timeout setting - may no longer be valid
|
||||
// I don't think this is valid anymore, the Multi shared DNS
|
||||
// cache is working well. For the case of naked easy handles,
|
||||
// consider using a shared DNS object.
|
||||
code = curl_easy_setopt(mCurlHandle, CURLOPT_DNS_CACHE_TIMEOUT, 0);
|
||||
check_curl_easy_code(code, CURLOPT_DNS_CACHE_TIMEOUT);
|
||||
}
|
||||
// The Linksys WRT54G V5 router has an issue with frequent
|
||||
// DNS lookups from LAN machines. If they happen too often,
|
||||
// like for every HTTP request, the router gets annoyed after
|
||||
// about 700 or so requests and starts issuing TCP RSTs to
|
||||
// new connections. Reuse the DNS lookups for even a few
|
||||
// seconds and no RSTs.
|
||||
code = curl_easy_setopt(mCurlHandle, CURLOPT_DNS_CACHE_TIMEOUT, 15);
|
||||
check_curl_easy_code(code, CURLOPT_DNS_CACHE_TIMEOUT);
|
||||
code = curl_easy_setopt(mCurlHandle, CURLOPT_AUTOREFERER, 1);
|
||||
check_curl_easy_code(code, CURLOPT_AUTOREFERER);
|
||||
code = curl_easy_setopt(mCurlHandle, CURLOPT_FOLLOWLOCATION, 1);
|
||||
|
|
@ -831,7 +820,7 @@ int HttpOpRequest::debugCallback(CURL * handle, curl_infotype info, char * buffe
|
|||
std::string safe_line;
|
||||
std::string tag;
|
||||
bool logit(false);
|
||||
len = (std::min)(len, size_t(256)); // Keep things reasonable in all cases
|
||||
const size_t log_len((std::min)(len, size_t(256))); // Keep things reasonable in all cases
|
||||
|
||||
switch (info)
|
||||
{
|
||||
|
|
@ -839,7 +828,7 @@ int HttpOpRequest::debugCallback(CURL * handle, curl_infotype info, char * buffe
|
|||
if (op->mTracing >= HTTP_TRACE_CURL_HEADERS)
|
||||
{
|
||||
tag = "TEXT";
|
||||
escape_libcurl_debug_data(buffer, len, true, safe_line);
|
||||
escape_libcurl_debug_data(buffer, log_len, true, safe_line);
|
||||
logit = true;
|
||||
}
|
||||
break;
|
||||
|
|
@ -848,7 +837,7 @@ int HttpOpRequest::debugCallback(CURL * handle, curl_infotype info, char * buffe
|
|||
if (op->mTracing >= HTTP_TRACE_CURL_HEADERS)
|
||||
{
|
||||
tag = "HEADERIN";
|
||||
escape_libcurl_debug_data(buffer, len, true, safe_line);
|
||||
escape_libcurl_debug_data(buffer, log_len, true, safe_line);
|
||||
logit = true;
|
||||
}
|
||||
break;
|
||||
|
|
@ -857,7 +846,7 @@ int HttpOpRequest::debugCallback(CURL * handle, curl_infotype info, char * buffe
|
|||
if (op->mTracing >= HTTP_TRACE_CURL_HEADERS)
|
||||
{
|
||||
tag = "HEADEROUT";
|
||||
escape_libcurl_debug_data(buffer, 2 * len, true, safe_line); // Goes out as one line
|
||||
escape_libcurl_debug_data(buffer, log_len, true, safe_line); // Goes out as one line unlike header_in
|
||||
logit = true;
|
||||
}
|
||||
break;
|
||||
|
|
@ -869,7 +858,7 @@ int HttpOpRequest::debugCallback(CURL * handle, curl_infotype info, char * buffe
|
|||
logit = true;
|
||||
if (op->mTracing >= HTTP_TRACE_CURL_BODIES)
|
||||
{
|
||||
escape_libcurl_debug_data(buffer, len, false, safe_line);
|
||||
escape_libcurl_debug_data(buffer, log_len, false, safe_line);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -887,7 +876,7 @@ int HttpOpRequest::debugCallback(CURL * handle, curl_infotype info, char * buffe
|
|||
logit = true;
|
||||
if (op->mTracing >= HTTP_TRACE_CURL_BODIES)
|
||||
{
|
||||
escape_libcurl_debug_data(buffer, len, false, safe_line);
|
||||
escape_libcurl_debug_data(buffer, log_len, false, safe_line);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
|||
|
|
@ -60,7 +60,6 @@ class HttpOptions;
|
|||
/// the information needed to make a working request which can
|
||||
/// then be enqueued to a request queue.
|
||||
///
|
||||
|
||||
class HttpOpRequest : public HttpOperation
|
||||
{
|
||||
public:
|
||||
|
|
|
|||
|
|
@ -388,33 +388,13 @@ bool HttpPolicy::cancel(HttpHandle handle)
|
|||
|
||||
bool HttpPolicy::stageAfterCompletion(HttpOpRequest * op)
|
||||
{
|
||||
static const HttpStatus cant_connect(HttpStatus::EXT_CURL_EASY, CURLE_COULDNT_CONNECT);
|
||||
static const HttpStatus cant_res_proxy(HttpStatus::EXT_CURL_EASY, CURLE_COULDNT_RESOLVE_PROXY);
|
||||
static const HttpStatus cant_res_host(HttpStatus::EXT_CURL_EASY, CURLE_COULDNT_RESOLVE_HOST);
|
||||
static const HttpStatus send_error(HttpStatus::EXT_CURL_EASY, CURLE_SEND_ERROR);
|
||||
static const HttpStatus recv_error(HttpStatus::EXT_CURL_EASY, CURLE_RECV_ERROR);
|
||||
static const HttpStatus upload_failed(HttpStatus::EXT_CURL_EASY, CURLE_UPLOAD_FAILED);
|
||||
static const HttpStatus op_timedout(HttpStatus::EXT_CURL_EASY, CURLE_OPERATION_TIMEDOUT);
|
||||
static const HttpStatus post_error(HttpStatus::EXT_CURL_EASY, CURLE_HTTP_POST_ERROR);
|
||||
|
||||
// Retry or finalize
|
||||
if (! op->mStatus)
|
||||
{
|
||||
// If this failed, we might want to retry. Have to inspect
|
||||
// the status a little more deeply for those reasons worth retrying...
|
||||
if (op->mPolicyRetries < op->mPolicyRetryLimit &&
|
||||
((op->mStatus.isHttpStatus() && op->mStatus.mType >= 499 && op->mStatus.mType <= 599) ||
|
||||
cant_connect == op->mStatus ||
|
||||
cant_res_proxy == op->mStatus ||
|
||||
cant_res_host == op->mStatus ||
|
||||
send_error == op->mStatus ||
|
||||
recv_error == op->mStatus ||
|
||||
upload_failed == op->mStatus ||
|
||||
op_timedout == op->mStatus ||
|
||||
post_error == op->mStatus))
|
||||
// If this failed, we might want to retry.
|
||||
if (op->mPolicyRetries < op->mPolicyRetryLimit && op->mStatus.isRetryable())
|
||||
{
|
||||
// Okay, worth a retry. We include 499 in this test as
|
||||
// it's the old 'who knows?' error from many grid services...
|
||||
// Okay, worth a retry.
|
||||
retryOp(op);
|
||||
return true; // still active/ready
|
||||
}
|
||||
|
|
|
|||
|
|
@ -117,6 +117,7 @@ std::string HttpStatus::toString() const
|
|||
{ 415, "Unsupported Media Type" },
|
||||
{ 416, "Requested range not satisfiable" },
|
||||
{ 417, "Expectation Failed" },
|
||||
{ 499, "Linden Catch-All" },
|
||||
{ 500, "Internal Server Error" },
|
||||
{ 501, "Not Implemented" },
|
||||
{ 502, "Bad Gateway" },
|
||||
|
|
@ -215,6 +216,34 @@ std::string HttpStatus::toTerseString() const
|
|||
}
|
||||
|
||||
|
||||
|
||||
// Pass true on statuses that might actually be cleared by a
|
||||
// retry. Library failures, calling problems, etc. aren't
|
||||
// going to be fixed by squirting bits all over the Net.
|
||||
bool HttpStatus::isRetryable() const
|
||||
{
|
||||
static const HttpStatus cant_connect(HttpStatus::EXT_CURL_EASY, CURLE_COULDNT_CONNECT);
|
||||
static const HttpStatus cant_res_proxy(HttpStatus::EXT_CURL_EASY, CURLE_COULDNT_RESOLVE_PROXY);
|
||||
static const HttpStatus cant_res_host(HttpStatus::EXT_CURL_EASY, CURLE_COULDNT_RESOLVE_HOST);
|
||||
static const HttpStatus send_error(HttpStatus::EXT_CURL_EASY, CURLE_SEND_ERROR);
|
||||
static const HttpStatus recv_error(HttpStatus::EXT_CURL_EASY, CURLE_RECV_ERROR);
|
||||
static const HttpStatus upload_failed(HttpStatus::EXT_CURL_EASY, CURLE_UPLOAD_FAILED);
|
||||
static const HttpStatus op_timedout(HttpStatus::EXT_CURL_EASY, CURLE_OPERATION_TIMEDOUT);
|
||||
static const HttpStatus post_error(HttpStatus::EXT_CURL_EASY, CURLE_HTTP_POST_ERROR);
|
||||
static const HttpStatus partial_file(HttpStatus::EXT_CURL_EASY, CURLE_PARTIAL_FILE);
|
||||
static const HttpStatus inv_cont_range(HttpStatus::LLCORE, HE_INV_CONTENT_RANGE_HDR);
|
||||
|
||||
return ((isHttpStatus() && mType >= 499 && mType <= 599) || // Include special 499 in retryables
|
||||
*this == cant_connect || // Connection reset/endpoint problems
|
||||
*this == cant_res_proxy || // DNS problems
|
||||
*this == cant_res_host || // DNS problems
|
||||
*this == send_error || // General socket problems
|
||||
*this == recv_error || // General socket problems
|
||||
*this == upload_failed || // Transport problem
|
||||
*this == op_timedout || // Timer expired
|
||||
*this == post_error || // Transport problem
|
||||
*this == partial_file || // Data inconsistency in response
|
||||
*this == inv_cont_range); // Short data read disagrees with content-range
|
||||
}
|
||||
|
||||
} // end namespace LLCore
|
||||
|
||||
|
|
|
|||
|
|
@ -397,6 +397,12 @@ struct HttpStatus
|
|||
{
|
||||
return mType >= type_enum_t(100) && mType <= type_enum_t(999);
|
||||
}
|
||||
|
||||
/// Returns true if the status is one that will be retried
|
||||
/// internally. Provided for external consumption for cases
|
||||
/// where that logic needs to be replicated. Only applies
|
||||
/// to failed statuses, successful statuses will return false.
|
||||
bool isRetryable() const;
|
||||
|
||||
}; // end struct HttpStatus
|
||||
|
||||
|
|
|
|||
|
|
@ -48,8 +48,9 @@ class HttpHeaders;
|
|||
/// individual pieces of the response.
|
||||
///
|
||||
/// Typical usage will have the caller interrogate the object
|
||||
/// and return from the handler callback. Instances are refcounted
|
||||
/// and callers can bump the count and retain the object as needed.
|
||||
/// during the handler callback and then simply returning.
|
||||
/// But instances are refcounted and and callers can add a
|
||||
/// reference and hold onto the object after the callback.
|
||||
///
|
||||
/// Threading: Not intrinsically thread-safe.
|
||||
///
|
||||
|
|
@ -119,6 +120,10 @@ public:
|
|||
/// caller is going to have to make assumptions on receipt of
|
||||
/// a 206 status. The @full value may also be zero in cases of
|
||||
/// parsing problems or a wild-carded length response.
|
||||
///
|
||||
/// These values will not necessarily agree with the data in
|
||||
/// the body itself (if present). The BufferArray object
|
||||
/// is authoritative for actual data length.
|
||||
void getRange(unsigned int * offset, unsigned int * length, unsigned int * full) const
|
||||
{
|
||||
*offset = mReplyOffset;
|
||||
|
|
|
|||
|
|
@ -45,6 +45,15 @@
|
|||
|
||||
using namespace LLCoreInt;
|
||||
|
||||
// spin/sleep waiting times for client/server exchange tests
|
||||
//
|
||||
// These are now fairly generous to try to get around timeout
|
||||
// ('reasonable time') failures during execution on a heavily-
|
||||
// loaded system where the unit test is in competition with
|
||||
// other programs.
|
||||
static const int LOOP_SLEEP_INTERVAL(10000);
|
||||
static const int LOOP_COUNT_SHORT(500); // 5-second dwell time
|
||||
static const int LOOP_COUNT_LONG(3000); // 30-second dwell time
|
||||
|
||||
namespace
|
||||
{
|
||||
|
|
@ -305,11 +314,11 @@ void HttpRequestTestObjectType::test<3>()
|
|||
|
||||
// Run the notification pump.
|
||||
int count(0);
|
||||
int limit(20);
|
||||
int limit(LOOP_COUNT_SHORT);
|
||||
while (count++ < limit && mHandlerCalls < 1)
|
||||
{
|
||||
req->update(1000000);
|
||||
usleep(100000);
|
||||
usleep(LOOP_SLEEP_INTERVAL);
|
||||
}
|
||||
ensure("Request executed in reasonable time", count < limit);
|
||||
ensure("One handler invocation for request", mHandlerCalls == 1);
|
||||
|
|
@ -320,21 +329,21 @@ void HttpRequestTestObjectType::test<3>()
|
|||
|
||||
// Run the notification pump again
|
||||
count = 0;
|
||||
limit = 100;
|
||||
limit = LOOP_COUNT_LONG;
|
||||
while (count++ < limit && mHandlerCalls < 2)
|
||||
{
|
||||
req->update(1000000);
|
||||
usleep(100000);
|
||||
usleep(LOOP_SLEEP_INTERVAL);
|
||||
}
|
||||
ensure("Second request executed in reasonable time", count < limit);
|
||||
ensure("Second handler invocation", mHandlerCalls == 2);
|
||||
|
||||
// See that we actually shutdown the thread
|
||||
count = 0;
|
||||
limit = 10;
|
||||
limit = LOOP_COUNT_SHORT;
|
||||
while (count++ < limit && ! HttpService::isStopped())
|
||||
{
|
||||
usleep(100000);
|
||||
usleep(LOOP_SLEEP_INTERVAL);
|
||||
}
|
||||
ensure("Thread actually stopped running", HttpService::isStopped());
|
||||
|
||||
|
|
@ -403,12 +412,12 @@ void HttpRequestTestObjectType::test<4>()
|
|||
|
||||
// Run the notification pump.
|
||||
int count(0);
|
||||
int limit(20);
|
||||
int limit(LOOP_COUNT_LONG);
|
||||
while (count++ < limit && mHandlerCalls < 2)
|
||||
{
|
||||
req1->update(1000000);
|
||||
req2->update(1000000);
|
||||
usleep(100000);
|
||||
usleep(LOOP_SLEEP_INTERVAL);
|
||||
}
|
||||
ensure("Request executed in reasonable time", count < limit);
|
||||
ensure("One handler invocation for request", mHandlerCalls == 2);
|
||||
|
|
@ -420,22 +429,22 @@ void HttpRequestTestObjectType::test<4>()
|
|||
|
||||
// Run the notification pump again
|
||||
count = 0;
|
||||
limit = 100;
|
||||
limit = LOOP_COUNT_LONG;
|
||||
while (count++ < limit && mHandlerCalls < 3)
|
||||
{
|
||||
req1->update(1000000);
|
||||
req2->update(1000000);
|
||||
usleep(100000);
|
||||
usleep(LOOP_SLEEP_INTERVAL);
|
||||
}
|
||||
ensure("Second request executed in reasonable time", count < limit);
|
||||
ensure("Second handler invocation", mHandlerCalls == 3);
|
||||
|
||||
// See that we actually shutdown the thread
|
||||
count = 0;
|
||||
limit = 10;
|
||||
limit = LOOP_COUNT_SHORT;
|
||||
while (count++ < limit && ! HttpService::isStopped())
|
||||
{
|
||||
usleep(100000);
|
||||
usleep(LOOP_SLEEP_INTERVAL);
|
||||
}
|
||||
ensure("Thread actually stopped running", HttpService::isStopped());
|
||||
|
||||
|
|
@ -504,11 +513,11 @@ void HttpRequestTestObjectType::test<5>()
|
|||
|
||||
// Run the notification pump.
|
||||
int count(0);
|
||||
int limit(10);
|
||||
int limit(LOOP_COUNT_SHORT);
|
||||
while (count++ < limit && mHandlerCalls < 1)
|
||||
{
|
||||
req->update(1000000);
|
||||
usleep(100000);
|
||||
usleep(LOOP_SLEEP_INTERVAL);
|
||||
}
|
||||
ensure("NoOp notification received", mHandlerCalls == 1);
|
||||
|
||||
|
|
@ -580,11 +589,11 @@ void HttpRequestTestObjectType::test<6>()
|
|||
|
||||
// Run the notification pump.
|
||||
int count(0);
|
||||
int limit(10);
|
||||
int limit(LOOP_COUNT_SHORT);
|
||||
while (count++ < limit && mHandlerCalls < 1)
|
||||
{
|
||||
req->update(1000000);
|
||||
usleep(100000);
|
||||
usleep(LOOP_SLEEP_INTERVAL);
|
||||
}
|
||||
ensure("No notifications received", mHandlerCalls == 0);
|
||||
|
||||
|
|
@ -661,11 +670,11 @@ void HttpRequestTestObjectType::test<7>()
|
|||
|
||||
// Run the notification pump.
|
||||
int count(0);
|
||||
int limit(50); // With one retry, should fail quickish
|
||||
int limit(LOOP_COUNT_LONG);
|
||||
while (count++ < limit && mHandlerCalls < 1)
|
||||
{
|
||||
req->update(1000000);
|
||||
usleep(100000);
|
||||
usleep(LOOP_SLEEP_INTERVAL);
|
||||
}
|
||||
ensure("Request executed in reasonable time", count < limit);
|
||||
ensure("One handler invocation for request", mHandlerCalls == 1);
|
||||
|
|
@ -677,21 +686,21 @@ void HttpRequestTestObjectType::test<7>()
|
|||
|
||||
// Run the notification pump again
|
||||
count = 0;
|
||||
limit = 100;
|
||||
limit = LOOP_COUNT_LONG;
|
||||
while (count++ < limit && mHandlerCalls < 2)
|
||||
{
|
||||
req->update(1000000);
|
||||
usleep(100000);
|
||||
usleep(LOOP_SLEEP_INTERVAL);
|
||||
}
|
||||
ensure("Second request executed in reasonable time", count < limit);
|
||||
ensure("Second handler invocation", mHandlerCalls == 2);
|
||||
|
||||
// See that we actually shutdown the thread
|
||||
count = 0;
|
||||
limit = 10;
|
||||
limit = LOOP_COUNT_SHORT;
|
||||
while (count++ < limit && ! HttpService::isStopped())
|
||||
{
|
||||
usleep(100000);
|
||||
usleep(LOOP_SLEEP_INTERVAL);
|
||||
}
|
||||
ensure("Thread actually stopped running", HttpService::isStopped());
|
||||
|
||||
|
|
@ -777,11 +786,11 @@ void HttpRequestTestObjectType::test<8>()
|
|||
|
||||
// Run the notification pump.
|
||||
int count(0);
|
||||
int limit(10);
|
||||
int limit(LOOP_COUNT_LONG);
|
||||
while (count++ < limit && mHandlerCalls < 1)
|
||||
{
|
||||
req->update(1000000);
|
||||
usleep(100000);
|
||||
usleep(LOOP_SLEEP_INTERVAL);
|
||||
}
|
||||
ensure("Request executed in reasonable time", count < limit);
|
||||
ensure("One handler invocation for request", mHandlerCalls == 1);
|
||||
|
|
@ -793,21 +802,21 @@ void HttpRequestTestObjectType::test<8>()
|
|||
|
||||
// Run the notification pump again
|
||||
count = 0;
|
||||
limit = 10;
|
||||
limit = LOOP_COUNT_LONG;
|
||||
while (count++ < limit && mHandlerCalls < 2)
|
||||
{
|
||||
req->update(1000000);
|
||||
usleep(100000);
|
||||
usleep(LOOP_SLEEP_INTERVAL);
|
||||
}
|
||||
ensure("Second request executed in reasonable time", count < limit);
|
||||
ensure("Second handler invocation", mHandlerCalls == 2);
|
||||
|
||||
// See that we actually shutdown the thread
|
||||
count = 0;
|
||||
limit = 10;
|
||||
limit = LOOP_COUNT_SHORT;
|
||||
while (count++ < limit && ! HttpService::isStopped())
|
||||
{
|
||||
usleep(100000);
|
||||
usleep(LOOP_SLEEP_INTERVAL);
|
||||
}
|
||||
ensure("Thread actually stopped running", HttpService::isStopped());
|
||||
|
||||
|
|
@ -887,11 +896,11 @@ void HttpRequestTestObjectType::test<9>()
|
|||
|
||||
// Run the notification pump.
|
||||
int count(0);
|
||||
int limit(10);
|
||||
int limit(LOOP_COUNT_LONG);
|
||||
while (count++ < limit && mHandlerCalls < 1)
|
||||
{
|
||||
req->update(1000000);
|
||||
usleep(100000);
|
||||
usleep(LOOP_SLEEP_INTERVAL);
|
||||
}
|
||||
ensure("Request executed in reasonable time", count < limit);
|
||||
ensure("One handler invocation for request", mHandlerCalls == 1);
|
||||
|
|
@ -903,21 +912,21 @@ void HttpRequestTestObjectType::test<9>()
|
|||
|
||||
// Run the notification pump again
|
||||
count = 0;
|
||||
limit = 10;
|
||||
limit = LOOP_COUNT_LONG;
|
||||
while (count++ < limit && mHandlerCalls < 2)
|
||||
{
|
||||
req->update(1000000);
|
||||
usleep(100000);
|
||||
usleep(LOOP_SLEEP_INTERVAL);
|
||||
}
|
||||
ensure("Second request executed in reasonable time", count < limit);
|
||||
ensure("Second handler invocation", mHandlerCalls == 2);
|
||||
|
||||
// See that we actually shutdown the thread
|
||||
count = 0;
|
||||
limit = 10;
|
||||
limit = LOOP_COUNT_SHORT;
|
||||
while (count++ < limit && ! HttpService::isStopped())
|
||||
{
|
||||
usleep(100000);
|
||||
usleep(LOOP_SLEEP_INTERVAL);
|
||||
}
|
||||
ensure("Thread actually stopped running", HttpService::isStopped());
|
||||
|
||||
|
|
@ -999,11 +1008,11 @@ void HttpRequestTestObjectType::test<10>()
|
|||
|
||||
// Run the notification pump.
|
||||
int count(0);
|
||||
int limit(10);
|
||||
int limit(LOOP_COUNT_LONG);
|
||||
while (count++ < limit && mHandlerCalls < 1)
|
||||
{
|
||||
req->update(1000000);
|
||||
usleep(100000);
|
||||
usleep(LOOP_SLEEP_INTERVAL);
|
||||
}
|
||||
ensure("Request executed in reasonable time", count < limit);
|
||||
ensure("One handler invocation for request", mHandlerCalls == 1);
|
||||
|
|
@ -1015,21 +1024,21 @@ void HttpRequestTestObjectType::test<10>()
|
|||
|
||||
// Run the notification pump again
|
||||
count = 0;
|
||||
limit = 10;
|
||||
limit = LOOP_COUNT_LONG;
|
||||
while (count++ < limit && mHandlerCalls < 2)
|
||||
{
|
||||
req->update(1000000);
|
||||
usleep(100000);
|
||||
usleep(LOOP_SLEEP_INTERVAL);
|
||||
}
|
||||
ensure("Second request executed in reasonable time", count < limit);
|
||||
ensure("Second handler invocation", mHandlerCalls == 2);
|
||||
|
||||
// See that we actually shutdown the thread
|
||||
count = 0;
|
||||
limit = 10;
|
||||
limit = LOOP_COUNT_SHORT;
|
||||
while (count++ < limit && ! HttpService::isStopped())
|
||||
{
|
||||
usleep(100000);
|
||||
usleep(LOOP_SLEEP_INTERVAL);
|
||||
}
|
||||
ensure("Thread actually stopped running", HttpService::isStopped());
|
||||
|
||||
|
|
@ -1117,11 +1126,11 @@ void HttpRequestTestObjectType::test<11>()
|
|||
|
||||
// Run the notification pump.
|
||||
int count(0);
|
||||
int limit(10);
|
||||
int limit(LOOP_COUNT_LONG);
|
||||
while (count++ < limit && mHandlerCalls < 1)
|
||||
{
|
||||
req->update(1000000);
|
||||
usleep(100000);
|
||||
usleep(LOOP_SLEEP_INTERVAL);
|
||||
}
|
||||
ensure("Request executed in reasonable time", count < limit);
|
||||
ensure("One handler invocation for request", mHandlerCalls == 1);
|
||||
|
|
@ -1133,21 +1142,21 @@ void HttpRequestTestObjectType::test<11>()
|
|||
|
||||
// Run the notification pump again
|
||||
count = 0;
|
||||
limit = 10;
|
||||
limit = LOOP_COUNT_LONG;
|
||||
while (count++ < limit && mHandlerCalls < 2)
|
||||
{
|
||||
req->update(1000000);
|
||||
usleep(100000);
|
||||
usleep(LOOP_SLEEP_INTERVAL);
|
||||
}
|
||||
ensure("Second request executed in reasonable time", count < limit);
|
||||
ensure("Second handler invocation", mHandlerCalls == 2);
|
||||
|
||||
// See that we actually shutdown the thread
|
||||
count = 0;
|
||||
limit = 10;
|
||||
limit = LOOP_COUNT_SHORT;
|
||||
while (count++ < limit && ! HttpService::isStopped())
|
||||
{
|
||||
usleep(100000);
|
||||
usleep(LOOP_SLEEP_INTERVAL);
|
||||
}
|
||||
ensure("Thread actually stopped running", HttpService::isStopped());
|
||||
|
||||
|
|
@ -1237,11 +1246,11 @@ void HttpRequestTestObjectType::test<12>()
|
|||
|
||||
// Run the notification pump.
|
||||
int count(0);
|
||||
int limit(10);
|
||||
int limit(LOOP_COUNT_LONG);
|
||||
while (count++ < limit && mHandlerCalls < 1)
|
||||
{
|
||||
req->update(1000000);
|
||||
usleep(100000);
|
||||
usleep(LOOP_SLEEP_INTERVAL);
|
||||
}
|
||||
ensure("Request executed in reasonable time", count < limit);
|
||||
ensure("One handler invocation for request", mHandlerCalls == 1);
|
||||
|
|
@ -1253,21 +1262,21 @@ void HttpRequestTestObjectType::test<12>()
|
|||
|
||||
// Run the notification pump again
|
||||
count = 0;
|
||||
limit = 10;
|
||||
limit = LOOP_COUNT_LONG;
|
||||
while (count++ < limit && mHandlerCalls < 2)
|
||||
{
|
||||
req->update(1000000);
|
||||
usleep(100000);
|
||||
usleep(LOOP_SLEEP_INTERVAL);
|
||||
}
|
||||
ensure("Second request executed in reasonable time", count < limit);
|
||||
ensure("Second handler invocation", mHandlerCalls == 2);
|
||||
|
||||
// See that we actually shutdown the thread
|
||||
count = 0;
|
||||
limit = 10;
|
||||
limit = LOOP_COUNT_SHORT;
|
||||
while (count++ < limit && ! HttpService::isStopped())
|
||||
{
|
||||
usleep(100000);
|
||||
usleep(LOOP_SLEEP_INTERVAL);
|
||||
}
|
||||
ensure("Thread actually stopped running", HttpService::isStopped());
|
||||
|
||||
|
|
@ -1352,8 +1361,8 @@ void HttpRequestTestObjectType::test<13>()
|
|||
HttpHandle handle = req->requestGetByteRange(HttpRequest::DEFAULT_POLICY_ID,
|
||||
0U,
|
||||
url_base,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
opts,
|
||||
NULL,
|
||||
&handler);
|
||||
|
|
@ -1365,11 +1374,11 @@ void HttpRequestTestObjectType::test<13>()
|
|||
|
||||
// Run the notification pump.
|
||||
int count(0);
|
||||
int limit(10);
|
||||
int limit(LOOP_COUNT_LONG);
|
||||
while (count++ < limit && mHandlerCalls < 1)
|
||||
{
|
||||
req->update(1000000);
|
||||
usleep(100000);
|
||||
usleep(LOOP_SLEEP_INTERVAL);
|
||||
}
|
||||
ensure("Request executed in reasonable time", count < limit);
|
||||
ensure("One handler invocation for request", mHandlerCalls == 1);
|
||||
|
|
@ -1382,21 +1391,21 @@ void HttpRequestTestObjectType::test<13>()
|
|||
|
||||
// Run the notification pump again
|
||||
count = 0;
|
||||
limit = 10;
|
||||
limit = LOOP_COUNT_LONG;
|
||||
while (count++ < limit && mHandlerCalls < 2)
|
||||
{
|
||||
req->update(1000000);
|
||||
usleep(100000);
|
||||
usleep(LOOP_SLEEP_INTERVAL);
|
||||
}
|
||||
ensure("Second request executed in reasonable time", count < limit);
|
||||
ensure("Second handler invocation", mHandlerCalls == 2);
|
||||
|
||||
// See that we actually shutdown the thread
|
||||
count = 0;
|
||||
limit = 10;
|
||||
limit = LOOP_COUNT_SHORT;
|
||||
while (count++ < limit && ! HttpService::isStopped())
|
||||
{
|
||||
usleep(100000);
|
||||
usleep(LOOP_SLEEP_INTERVAL);
|
||||
}
|
||||
ensure("Thread actually stopped running", HttpService::isStopped());
|
||||
|
||||
|
|
@ -1484,11 +1493,11 @@ void HttpRequestTestObjectType::test<14>()
|
|||
|
||||
// Run the notification pump.
|
||||
int count(0);
|
||||
int limit(50); // With one retry, should fail quickish
|
||||
int limit(LOOP_COUNT_LONG);
|
||||
while (count++ < limit && mHandlerCalls < 1)
|
||||
{
|
||||
req->update(1000000);
|
||||
usleep(100000);
|
||||
usleep(LOOP_SLEEP_INTERVAL);
|
||||
}
|
||||
ensure("Request executed in reasonable time", count < limit);
|
||||
ensure("One handler invocation for request", mHandlerCalls == 1);
|
||||
|
|
@ -1500,21 +1509,21 @@ void HttpRequestTestObjectType::test<14>()
|
|||
|
||||
// Run the notification pump again
|
||||
count = 0;
|
||||
limit = 100;
|
||||
limit = LOOP_COUNT_LONG;
|
||||
while (count++ < limit && mHandlerCalls < 2)
|
||||
{
|
||||
req->update(1000000);
|
||||
usleep(100000);
|
||||
usleep(LOOP_SLEEP_INTERVAL);
|
||||
}
|
||||
ensure("Second request executed in reasonable time", count < limit);
|
||||
ensure("Second handler invocation", mHandlerCalls == 2);
|
||||
|
||||
// See that we actually shutdown the thread
|
||||
count = 0;
|
||||
limit = 10;
|
||||
limit = LOOP_COUNT_SHORT;
|
||||
while (count++ < limit && ! HttpService::isStopped())
|
||||
{
|
||||
usleep(100000);
|
||||
usleep(LOOP_SLEEP_INTERVAL);
|
||||
}
|
||||
ensure("Thread actually stopped running", HttpService::isStopped());
|
||||
|
||||
|
|
@ -1607,11 +1616,11 @@ void HttpRequestTestObjectType::test<15>()
|
|||
|
||||
// Run the notification pump.
|
||||
int count(0);
|
||||
int limit(10);
|
||||
int limit(LOOP_COUNT_LONG);
|
||||
while (count++ < limit && mHandlerCalls < 1)
|
||||
{
|
||||
req->update(1000000);
|
||||
usleep(100000);
|
||||
usleep(LOOP_SLEEP_INTERVAL);
|
||||
}
|
||||
ensure("Request executed in reasonable time", count < limit);
|
||||
ensure("One handler invocation for request", mHandlerCalls == 1);
|
||||
|
|
@ -1624,21 +1633,21 @@ void HttpRequestTestObjectType::test<15>()
|
|||
|
||||
// Run the notification pump again
|
||||
count = 0;
|
||||
limit = 10;
|
||||
limit = LOOP_COUNT_LONG;
|
||||
while (count++ < limit && mHandlerCalls < 2)
|
||||
{
|
||||
req->update(1000000);
|
||||
usleep(100000);
|
||||
usleep(LOOP_SLEEP_INTERVAL);
|
||||
}
|
||||
ensure("Second request executed in reasonable time", count < limit);
|
||||
ensure("Second handler invocation", mHandlerCalls == 2);
|
||||
|
||||
// See that we actually shutdown the thread
|
||||
count = 0;
|
||||
limit = 10;
|
||||
limit = LOOP_COUNT_SHORT;
|
||||
while (count++ < limit && ! HttpService::isStopped())
|
||||
{
|
||||
usleep(100000);
|
||||
usleep(LOOP_SLEEP_INTERVAL);
|
||||
}
|
||||
ensure("Thread actually stopped running", HttpService::isStopped());
|
||||
|
||||
|
|
@ -1773,11 +1782,11 @@ void HttpRequestTestObjectType::test<16>()
|
|||
|
||||
// Run the notification pump.
|
||||
int count(0);
|
||||
int limit(10);
|
||||
int limit(LOOP_COUNT_LONG);
|
||||
while (count++ < limit && mHandlerCalls < 1)
|
||||
{
|
||||
req->update(1000000);
|
||||
usleep(100000);
|
||||
usleep(LOOP_SLEEP_INTERVAL);
|
||||
}
|
||||
ensure("Request executed in reasonable time", count < limit);
|
||||
ensure("One handler invocation for request", mHandlerCalls == 1);
|
||||
|
|
@ -1850,11 +1859,11 @@ void HttpRequestTestObjectType::test<16>()
|
|||
|
||||
// Run the notification pump.
|
||||
count = 0;
|
||||
limit = 10;
|
||||
limit = LOOP_COUNT_LONG;
|
||||
while (count++ < limit && mHandlerCalls < 2)
|
||||
{
|
||||
req->update(1000000);
|
||||
usleep(100000);
|
||||
usleep(LOOP_SLEEP_INTERVAL);
|
||||
}
|
||||
ensure("Request executed in reasonable time", count < limit);
|
||||
ensure("One handler invocation for request", mHandlerCalls == 2);
|
||||
|
|
@ -1869,21 +1878,21 @@ void HttpRequestTestObjectType::test<16>()
|
|||
|
||||
// Run the notification pump again
|
||||
count = 0;
|
||||
limit = 10;
|
||||
limit = LOOP_COUNT_LONG;
|
||||
while (count++ < limit && mHandlerCalls < 3)
|
||||
{
|
||||
req->update(1000000);
|
||||
usleep(100000);
|
||||
usleep(LOOP_SLEEP_INTERVAL);
|
||||
}
|
||||
ensure("Second request executed in reasonable time", count < limit);
|
||||
ensure("Second handler invocation", mHandlerCalls == 3);
|
||||
|
||||
// See that we actually shutdown the thread
|
||||
count = 0;
|
||||
limit = 10;
|
||||
limit = LOOP_COUNT_SHORT;
|
||||
while (count++ < limit && ! HttpService::isStopped())
|
||||
{
|
||||
usleep(100000);
|
||||
usleep(LOOP_SLEEP_INTERVAL);
|
||||
}
|
||||
ensure("Thread actually stopped running", HttpService::isStopped());
|
||||
|
||||
|
|
@ -2048,11 +2057,11 @@ void HttpRequestTestObjectType::test<17>()
|
|||
|
||||
// Run the notification pump.
|
||||
int count(0);
|
||||
int limit(10);
|
||||
int limit(LOOP_COUNT_LONG);
|
||||
while (count++ < limit && mHandlerCalls < 1)
|
||||
{
|
||||
req->update(1000000);
|
||||
usleep(100000);
|
||||
usleep(LOOP_SLEEP_INTERVAL);
|
||||
}
|
||||
ensure("Request executed in reasonable time", count < limit);
|
||||
ensure("One handler invocation for request", mHandlerCalls == 1);
|
||||
|
|
@ -2067,21 +2076,21 @@ void HttpRequestTestObjectType::test<17>()
|
|||
|
||||
// Run the notification pump again
|
||||
count = 0;
|
||||
limit = 10;
|
||||
limit = LOOP_COUNT_LONG;
|
||||
while (count++ < limit && mHandlerCalls < 2)
|
||||
{
|
||||
req->update(1000000);
|
||||
usleep(100000);
|
||||
usleep(LOOP_SLEEP_INTERVAL);
|
||||
}
|
||||
ensure("Second request executed in reasonable time", count < limit);
|
||||
ensure("Second handler invocation", mHandlerCalls == 2);
|
||||
|
||||
// See that we actually shutdown the thread
|
||||
count = 0;
|
||||
limit = 10;
|
||||
limit = LOOP_COUNT_SHORT;
|
||||
while (count++ < limit && ! HttpService::isStopped())
|
||||
{
|
||||
usleep(100000);
|
||||
usleep(LOOP_SLEEP_INTERVAL);
|
||||
}
|
||||
ensure("Thread actually stopped running", HttpService::isStopped());
|
||||
|
||||
|
|
@ -2252,11 +2261,11 @@ void HttpRequestTestObjectType::test<18>()
|
|||
|
||||
// Run the notification pump.
|
||||
int count(0);
|
||||
int limit(10);
|
||||
int limit(LOOP_COUNT_LONG);
|
||||
while (count++ < limit && mHandlerCalls < 1)
|
||||
{
|
||||
req->update(1000000);
|
||||
usleep(100000);
|
||||
usleep(LOOP_SLEEP_INTERVAL);
|
||||
}
|
||||
ensure("Request executed in reasonable time", count < limit);
|
||||
ensure("One handler invocation for request", mHandlerCalls == 1);
|
||||
|
|
@ -2271,21 +2280,21 @@ void HttpRequestTestObjectType::test<18>()
|
|||
|
||||
// Run the notification pump again
|
||||
count = 0;
|
||||
limit = 10;
|
||||
limit = LOOP_COUNT_LONG;
|
||||
while (count++ < limit && mHandlerCalls < 2)
|
||||
{
|
||||
req->update(1000000);
|
||||
usleep(100000);
|
||||
usleep(LOOP_SLEEP_INTERVAL);
|
||||
}
|
||||
ensure("Second request executed in reasonable time", count < limit);
|
||||
ensure("Second handler invocation", mHandlerCalls == 2);
|
||||
|
||||
// See that we actually shutdown the thread
|
||||
count = 0;
|
||||
limit = 10;
|
||||
limit = LOOP_COUNT_SHORT;
|
||||
while (count++ < limit && ! HttpService::isStopped())
|
||||
{
|
||||
usleep(100000);
|
||||
usleep(LOOP_SLEEP_INTERVAL);
|
||||
}
|
||||
ensure("Thread actually stopped running", HttpService::isStopped());
|
||||
|
||||
|
|
@ -2456,11 +2465,11 @@ void HttpRequestTestObjectType::test<19>()
|
|||
|
||||
// Run the notification pump.
|
||||
int count(0);
|
||||
int limit(10);
|
||||
int limit(LOOP_COUNT_LONG);
|
||||
while (count++ < limit && mHandlerCalls < 1)
|
||||
{
|
||||
req->update(1000000);
|
||||
usleep(100000);
|
||||
usleep(LOOP_SLEEP_INTERVAL);
|
||||
}
|
||||
ensure("Request executed in reasonable time", count < limit);
|
||||
ensure("One handler invocation for request", mHandlerCalls == 1);
|
||||
|
|
@ -2474,21 +2483,21 @@ void HttpRequestTestObjectType::test<19>()
|
|||
|
||||
// Run the notification pump again
|
||||
count = 0;
|
||||
limit = 10;
|
||||
limit = LOOP_COUNT_LONG;
|
||||
while (count++ < limit && mHandlerCalls < 2)
|
||||
{
|
||||
req->update(1000000);
|
||||
usleep(100000);
|
||||
usleep(LOOP_SLEEP_INTERVAL);
|
||||
}
|
||||
ensure("Second request executed in reasonable time", count < limit);
|
||||
ensure("Second handler invocation", mHandlerCalls == 2);
|
||||
|
||||
// See that we actually shutdown the thread
|
||||
count = 0;
|
||||
limit = 10;
|
||||
limit = LOOP_COUNT_SHORT;
|
||||
while (count++ < limit && ! HttpService::isStopped())
|
||||
{
|
||||
usleep(100000);
|
||||
usleep(LOOP_SLEEP_INTERVAL);
|
||||
}
|
||||
ensure("Thread actually stopped running", HttpService::isStopped());
|
||||
|
||||
|
|
@ -2673,11 +2682,11 @@ void HttpRequestTestObjectType::test<20>()
|
|||
|
||||
// Run the notification pump.
|
||||
int count(0);
|
||||
int limit(10);
|
||||
int limit(LOOP_COUNT_LONG);
|
||||
while (count++ < limit && mHandlerCalls < 1)
|
||||
{
|
||||
req->update(1000000);
|
||||
usleep(100000);
|
||||
usleep(LOOP_SLEEP_INTERVAL);
|
||||
}
|
||||
ensure("Request executed in reasonable time", count < limit);
|
||||
ensure("One handler invocation for request", mHandlerCalls == 1);
|
||||
|
|
@ -2692,21 +2701,21 @@ void HttpRequestTestObjectType::test<20>()
|
|||
|
||||
// Run the notification pump again
|
||||
count = 0;
|
||||
limit = 10;
|
||||
limit = LOOP_COUNT_LONG;
|
||||
while (count++ < limit && mHandlerCalls < 2)
|
||||
{
|
||||
req->update(1000000);
|
||||
usleep(100000);
|
||||
usleep(LOOP_SLEEP_INTERVAL);
|
||||
}
|
||||
ensure("Second request executed in reasonable time", count < limit);
|
||||
ensure("Second handler invocation", mHandlerCalls == 2);
|
||||
|
||||
// See that we actually shutdown the thread
|
||||
count = 0;
|
||||
limit = 10;
|
||||
limit = LOOP_COUNT_SHORT;
|
||||
while (count++ < limit && ! HttpService::isStopped())
|
||||
{
|
||||
usleep(100000);
|
||||
usleep(LOOP_SLEEP_INTERVAL);
|
||||
}
|
||||
ensure("Thread actually stopped running", HttpService::isStopped());
|
||||
|
||||
|
|
@ -2890,11 +2899,11 @@ void HttpRequestTestObjectType::test<21>()
|
|||
|
||||
// Run the notification pump.
|
||||
int count(0);
|
||||
int limit(10);
|
||||
int limit(LOOP_COUNT_LONG);
|
||||
while (count++ < limit && mHandlerCalls < 1)
|
||||
{
|
||||
req->update(1000000);
|
||||
usleep(100000);
|
||||
usleep(LOOP_SLEEP_INTERVAL);
|
||||
}
|
||||
ensure("Request executed in reasonable time", count < limit);
|
||||
ensure("One handler invocation for request", mHandlerCalls == 1);
|
||||
|
|
@ -2909,21 +2918,21 @@ void HttpRequestTestObjectType::test<21>()
|
|||
|
||||
// Run the notification pump again
|
||||
count = 0;
|
||||
limit = 10;
|
||||
limit = LOOP_COUNT_LONG;
|
||||
while (count++ < limit && mHandlerCalls < 2)
|
||||
{
|
||||
req->update(1000000);
|
||||
usleep(100000);
|
||||
usleep(LOOP_SLEEP_INTERVAL);
|
||||
}
|
||||
ensure("Second request executed in reasonable time", count < limit);
|
||||
ensure("Second handler invocation", mHandlerCalls == 2);
|
||||
|
||||
// See that we actually shutdown the thread
|
||||
count = 0;
|
||||
limit = 10;
|
||||
limit = LOOP_COUNT_SHORT;
|
||||
while (count++ < limit && ! HttpService::isStopped())
|
||||
{
|
||||
usleep(100000);
|
||||
usleep(LOOP_SLEEP_INTERVAL);
|
||||
}
|
||||
ensure("Thread actually stopped running", HttpService::isStopped());
|
||||
|
||||
|
|
@ -2971,12 +2980,206 @@ void HttpRequestTestObjectType::test<21>()
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
// BUG-2295 Tests - Content-Range header received but no body
|
||||
template <> template <>
|
||||
void HttpRequestTestObjectType::test<22>()
|
||||
{
|
||||
ScopedCurlInit ready;
|
||||
|
||||
std::string url_base(get_base_url());
|
||||
// std::cerr << "Base: " << url_base << std::endl;
|
||||
|
||||
set_test_name("BUG-2295");
|
||||
|
||||
// Handler can be stack-allocated *if* there are no dangling
|
||||
// references to it after completion of this method.
|
||||
// Create before memory record as the string copy will bump numbers.
|
||||
TestHandler2 handler(this, "handler");
|
||||
|
||||
// record the total amount of dynamically allocated memory
|
||||
mMemTotal = GetMemTotal();
|
||||
mHandlerCalls = 0;
|
||||
|
||||
HttpOptions * options = NULL;
|
||||
HttpRequest * req = NULL;
|
||||
|
||||
try
|
||||
{
|
||||
// options set
|
||||
options = new HttpOptions();
|
||||
options->setRetries(1); // Partial_File is retryable and can timeout in here
|
||||
|
||||
// Get singletons created
|
||||
HttpRequest::createService();
|
||||
|
||||
// Start threading early so that thread memory is invariant
|
||||
// over the test.
|
||||
HttpRequest::startThread();
|
||||
|
||||
// create a new ref counted object with an implicit reference
|
||||
req = new HttpRequest();
|
||||
ensure("Memory allocated on construction", mMemTotal < GetMemTotal());
|
||||
|
||||
// ======================================
|
||||
// Issue bug2295 GETs that will get a 206
|
||||
// ======================================
|
||||
mStatus = HttpStatus(206);
|
||||
static const int test_count(3);
|
||||
for (int i(0); i < test_count; ++i)
|
||||
{
|
||||
char buffer[128];
|
||||
sprintf(buffer, "/bug2295/%d/", i);
|
||||
HttpHandle handle = req->requestGetByteRange(HttpRequest::DEFAULT_POLICY_ID,
|
||||
0U,
|
||||
url_base + buffer,
|
||||
0,
|
||||
25,
|
||||
options,
|
||||
NULL,
|
||||
&handler);
|
||||
ensure("Valid handle returned for ranged request", handle != LLCORE_HTTP_HANDLE_INVALID);
|
||||
}
|
||||
|
||||
// Run the notification pump.
|
||||
int count(0);
|
||||
int limit(LOOP_COUNT_LONG);
|
||||
while (count++ < limit && mHandlerCalls < test_count)
|
||||
{
|
||||
req->update(1000000);
|
||||
usleep(LOOP_SLEEP_INTERVAL);
|
||||
}
|
||||
ensure("Request executed in reasonable time - ms1", count < limit);
|
||||
ensure("One handler invocation for each request - ms1", mHandlerCalls == test_count);
|
||||
|
||||
// ======================================
|
||||
// Issue bug2295 GETs that will get a libcurl 18 (PARTIAL_FILE)
|
||||
// ======================================
|
||||
mHandlerCalls = 0;
|
||||
mStatus = HttpStatus(HttpStatus::EXT_CURL_EASY, CURLE_PARTIAL_FILE);
|
||||
static const int test2_count(1);
|
||||
for (int i(0); i < test2_count; ++i)
|
||||
{
|
||||
char buffer[128];
|
||||
sprintf(buffer, "/bug2295/00000012/%d/", i);
|
||||
HttpHandle handle = req->requestGetByteRange(HttpRequest::DEFAULT_POLICY_ID,
|
||||
0U,
|
||||
url_base + buffer,
|
||||
0,
|
||||
25,
|
||||
options,
|
||||
NULL,
|
||||
&handler);
|
||||
ensure("Valid handle returned for ranged request", handle != LLCORE_HTTP_HANDLE_INVALID);
|
||||
}
|
||||
|
||||
// Run the notification pump.
|
||||
count = 0;
|
||||
limit = LOOP_COUNT_LONG;
|
||||
while (count++ < limit && mHandlerCalls < test2_count)
|
||||
{
|
||||
req->update(1000000);
|
||||
usleep(LOOP_SLEEP_INTERVAL);
|
||||
}
|
||||
ensure("Request executed in reasonable time - ms2", count < limit);
|
||||
ensure("One handler invocation for each request - ms2", mHandlerCalls == test2_count);
|
||||
|
||||
// ======================================
|
||||
// Issue bug2295 GETs that will get an llcorehttp HE_INV_CONTENT_RANGE_HDR status
|
||||
// ======================================
|
||||
mHandlerCalls = 0;
|
||||
mStatus = HttpStatus(HttpStatus::LLCORE, HE_INV_CONTENT_RANGE_HDR);
|
||||
static const int test3_count(1);
|
||||
for (int i(0); i < test3_count; ++i)
|
||||
{
|
||||
char buffer[128];
|
||||
sprintf(buffer, "/bug2295/inv_cont_range/%d/", i);
|
||||
HttpHandle handle = req->requestGetByteRange(HttpRequest::DEFAULT_POLICY_ID,
|
||||
0U,
|
||||
url_base + buffer,
|
||||
0,
|
||||
25,
|
||||
options,
|
||||
NULL,
|
||||
&handler);
|
||||
ensure("Valid handle returned for ranged request", handle != LLCORE_HTTP_HANDLE_INVALID);
|
||||
}
|
||||
|
||||
// Run the notification pump.
|
||||
count = 0;
|
||||
limit = LOOP_COUNT_LONG;
|
||||
while (count++ < limit && mHandlerCalls < test3_count)
|
||||
{
|
||||
req->update(1000000);
|
||||
usleep(LOOP_SLEEP_INTERVAL);
|
||||
}
|
||||
ensure("Request executed in reasonable time - ms3", count < limit);
|
||||
ensure("One handler invocation for each request - ms3", mHandlerCalls == test3_count);
|
||||
|
||||
// ======================================
|
||||
// Okay, request a shutdown of the servicing thread
|
||||
// ======================================
|
||||
mStatus = HttpStatus();
|
||||
mHandlerCalls = 0;
|
||||
HttpHandle handle = req->requestStopThread(&handler);
|
||||
ensure("Valid handle returned for second request", handle != LLCORE_HTTP_HANDLE_INVALID);
|
||||
|
||||
// Run the notification pump again
|
||||
count = 0;
|
||||
limit = LOOP_COUNT_LONG;
|
||||
while (count++ < limit && mHandlerCalls < 1)
|
||||
{
|
||||
req->update(1000000);
|
||||
usleep(LOOP_SLEEP_INTERVAL);
|
||||
}
|
||||
ensure("Shutdown request executed in reasonable time", count < limit);
|
||||
ensure("Shutdown handler invocation", mHandlerCalls == 1);
|
||||
|
||||
// See that we actually shutdown the thread
|
||||
count = 0;
|
||||
limit = LOOP_COUNT_SHORT;
|
||||
while (count++ < limit && ! HttpService::isStopped())
|
||||
{
|
||||
usleep(LOOP_SLEEP_INTERVAL);
|
||||
}
|
||||
ensure("Thread actually stopped running", HttpService::isStopped());
|
||||
|
||||
// release options
|
||||
if (options)
|
||||
{
|
||||
options->release();
|
||||
options = NULL;
|
||||
}
|
||||
|
||||
// release the request object
|
||||
delete req;
|
||||
req = NULL;
|
||||
|
||||
// Shut down service
|
||||
HttpRequest::destroyService();
|
||||
|
||||
#if defined(WIN32)
|
||||
// Can only do this memory test on Windows. On other platforms,
|
||||
// the LL logging system holds on to memory and produces what looks
|
||||
// like memory leaks...
|
||||
|
||||
// printf("Old mem: %d, New mem: %d\n", mMemTotal, GetMemTotal());
|
||||
ensure("Memory usage back to that at entry", mMemTotal == GetMemTotal());
|
||||
#endif
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
stop_thread(req);
|
||||
delete req;
|
||||
HttpRequest::destroyService();
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
template <> template <>
|
||||
void HttpRequestTestObjectType::test<23>()
|
||||
{
|
||||
ScopedCurlInit ready;
|
||||
|
||||
set_test_name("HttpRequest GET 503s with 'Retry-After'");
|
||||
|
||||
// This tests mainly that the code doesn't fall over if
|
||||
|
|
|
|||
|
|
@ -91,9 +91,6 @@ template <> template <>
|
|||
void HttpStatusTestObjectType::test<2>()
|
||||
{
|
||||
set_test_name("HttpStatus memory structure");
|
||||
#if LL_WINDOWS
|
||||
skip("MAINT-2302: This frequently (though not always) fails on Windows.");
|
||||
#endif
|
||||
|
||||
// Require that an HttpStatus object can be trivially
|
||||
// returned as a function return value in registers.
|
||||
|
|
@ -106,10 +103,7 @@ void HttpStatusTestObjectType::test<2>()
|
|||
template <> template <>
|
||||
void HttpStatusTestObjectType::test<3>()
|
||||
{
|
||||
set_test_name("HttpStatus valid error string conversion");
|
||||
#if LL_WINDOWS
|
||||
skip("MAINT-2302: This frequently (though not always) fails on Windows.");
|
||||
#endif
|
||||
set_test_name("HttpStatus valid status string conversion");
|
||||
|
||||
HttpStatus status;
|
||||
status.mType = HttpStatus::EXT_CURL_EASY;
|
||||
|
|
@ -141,10 +135,7 @@ void HttpStatusTestObjectType::test<3>()
|
|||
template <> template <>
|
||||
void HttpStatusTestObjectType::test<4>()
|
||||
{
|
||||
set_test_name("HttpStatus invalid error string conversion");
|
||||
#if LL_WINDOWS
|
||||
skip("MAINT-2302: This frequently (though not always) fails on Windows.");
|
||||
#endif
|
||||
set_test_name("HttpStatus invalid status string conversion");
|
||||
|
||||
HttpStatus status;
|
||||
status.mType = HttpStatus::EXT_CURL_EASY;
|
||||
|
|
@ -170,9 +161,6 @@ template <> template <>
|
|||
void HttpStatusTestObjectType::test<5>()
|
||||
{
|
||||
set_test_name("HttpStatus equality/inequality testing");
|
||||
#if LL_WINDOWS
|
||||
skip("MAINT-2302: This frequently (though not always) fails on Windows.");
|
||||
#endif
|
||||
|
||||
// Make certain equality/inequality tests do not pass
|
||||
// through the bool conversion. Distinct successful
|
||||
|
|
@ -193,9 +181,6 @@ template <> template <>
|
|||
void HttpStatusTestObjectType::test<6>()
|
||||
{
|
||||
set_test_name("HttpStatus basic HTTP status encoding");
|
||||
#if LL_WINDOWS
|
||||
skip("MAINT-2302: This frequently (though not always) fails on Windows.");
|
||||
#endif
|
||||
|
||||
HttpStatus status;
|
||||
status.mType = 200;
|
||||
|
|
@ -242,10 +227,7 @@ void HttpStatusTestObjectType::test<6>()
|
|||
template <> template <>
|
||||
void HttpStatusTestObjectType::test<7>()
|
||||
{
|
||||
set_test_name("HttpStatus HTTP error text strings");
|
||||
#if LL_WINDOWS
|
||||
skip("MAINT-2302: This frequently (though not always) fails on Windows.");
|
||||
#endif
|
||||
set_test_name("HttpStatus HTTP status text strings");
|
||||
|
||||
HttpStatus status(100, HE_REPLY_ERROR);
|
||||
std::string msg(status.toString());
|
||||
|
|
|
|||
|
|
@ -35,6 +35,10 @@ import time
|
|||
import select
|
||||
import getopt
|
||||
from threading import Thread
|
||||
try:
|
||||
from cStringIO import StringIO
|
||||
except ImportError:
|
||||
from StringIO import StringIO
|
||||
from BaseHTTPServer import HTTPServer, BaseHTTPRequestHandler
|
||||
from SocketServer import ThreadingMixIn
|
||||
|
||||
|
|
@ -48,7 +52,23 @@ class TestHTTPRequestHandler(BaseHTTPRequestHandler):
|
|||
"""This subclass of BaseHTTPRequestHandler is to receive and echo
|
||||
LLSD-flavored messages sent by the C++ LLHTTPClient.
|
||||
|
||||
[Merge with viewer-cat later]
|
||||
Target URLs are fairly free-form and are assembled by
|
||||
concatinating fragments. Currently defined fragments
|
||||
are:
|
||||
- '/reflect/' Request headers are bounced back to caller
|
||||
after prefixing with 'X-Reflect-'
|
||||
- '/fail/' Body of request can contain LLSD with
|
||||
'reason' string and 'status' integer
|
||||
which will become response header.
|
||||
- '/bug2295/' 206 response, no data in body:
|
||||
-- '/bug2295/0/' "Content-Range: bytes 0-75/2983"
|
||||
-- '/bug2295/1/' "Content-Range: bytes 0-75/*"
|
||||
-- '/bug2295/2/' "Content-Range: bytes 0-75/2983",
|
||||
"Content-Length: 0"
|
||||
-- '/bug2295/00000018/0/' Generates PARTIAL_FILE (18) error in libcurl.
|
||||
"Content-Range: bytes 0-75/2983",
|
||||
"Content-Length: 76"
|
||||
-- '/bug2295/inv_cont_range/0/' Generates HE_INVALID_CONTENT_RANGE error in llcorehttp.
|
||||
- '/503/' Generate 503 responses with various kinds
|
||||
of 'retry-after' headers
|
||||
-- '/503/0/' "Retry-After: 2"
|
||||
|
|
@ -58,7 +78,12 @@ class TestHTTPRequestHandler(BaseHTTPRequestHandler):
|
|||
-- '/503/4/' "Retry-After: (*#*(@*(@(")"
|
||||
-- '/503/5/' "Retry-After: aklsjflajfaklsfaklfasfklasdfklasdgahsdhgasdiogaioshdgo"
|
||||
-- '/503/6/' "Retry-After: 1 2 3 4 5 6 7 8 9 10"
|
||||
|
||||
Some combinations make no sense, there's no effort to protect
|
||||
you from that.
|
||||
"""
|
||||
ignore_exceptions = (Exception,)
|
||||
|
||||
def read(self):
|
||||
# The following logic is adapted from the library module
|
||||
# SimpleXMLRPCServer.py.
|
||||
|
|
@ -98,20 +123,29 @@ class TestHTTPRequestHandler(BaseHTTPRequestHandler):
|
|||
|
||||
def do_GET(self, withdata=True):
|
||||
# Of course, don't attempt to read data.
|
||||
self.answer(dict(reply="success", status=200,
|
||||
reason="Your GET operation worked"))
|
||||
try:
|
||||
self.answer(dict(reply="success", status=200,
|
||||
reason="Your GET operation worked"))
|
||||
except self.ignore_exceptions, e:
|
||||
print >> sys.stderr, "Exception during GET (ignoring): %s" % str(e)
|
||||
|
||||
def do_POST(self):
|
||||
# Read the provided POST data.
|
||||
# self.answer(self.read())
|
||||
self.answer(dict(reply="success", status=200,
|
||||
reason=self.read()))
|
||||
try:
|
||||
self.answer(dict(reply="success", status=200,
|
||||
reason=self.read()))
|
||||
except self.ignore_exceptions, e:
|
||||
print >> sys.stderr, "Exception during POST (ignoring): %s" % str(e)
|
||||
|
||||
def do_PUT(self):
|
||||
# Read the provided PUT data.
|
||||
# self.answer(self.read())
|
||||
self.answer(dict(reply="success", status=200,
|
||||
reason=self.read()))
|
||||
try:
|
||||
self.answer(dict(reply="success", status=200,
|
||||
reason=self.read()))
|
||||
except self.ignore_exceptions, e:
|
||||
print >> sys.stderr, "Exception during PUT (ignoring): %s" % str(e)
|
||||
|
||||
def answer(self, data, withdata=True):
|
||||
debug("%s.answer(%s): self.path = %r", self.__class__.__name__, data, self.path)
|
||||
|
|
@ -152,6 +186,41 @@ class TestHTTPRequestHandler(BaseHTTPRequestHandler):
|
|||
self.end_headers()
|
||||
if body:
|
||||
self.wfile.write(body)
|
||||
elif "/bug2295/" in self.path:
|
||||
# Test for https://jira.secondlife.com/browse/BUG-2295
|
||||
#
|
||||
# Client can receive a header indicating data should
|
||||
# appear in the body without actually getting the body.
|
||||
# Library needs to defend against this case.
|
||||
#
|
||||
body = None
|
||||
if "/bug2295/0/" in self.path:
|
||||
self.send_response(206)
|
||||
self.send_header("Content-Range", "bytes 0-75/2983")
|
||||
elif "/bug2295/1/" in self.path:
|
||||
self.send_response(206)
|
||||
self.send_header("Content-Range", "bytes 0-75/*")
|
||||
elif "/bug2295/2/" in self.path:
|
||||
self.send_response(206)
|
||||
self.send_header("Content-Range", "bytes 0-75/2983")
|
||||
self.send_header("Content-Length", "0")
|
||||
elif "/bug2295/00000012/0/" in self.path:
|
||||
self.send_response(206)
|
||||
self.send_header("Content-Range", "bytes 0-75/2983")
|
||||
self.send_header("Content-Length", "76")
|
||||
elif "/bug2295/inv_cont_range/0/" in self.path:
|
||||
self.send_response(206)
|
||||
self.send_header("Content-Range", "bytes 0-75/2983")
|
||||
body = "Some text, but not enough."
|
||||
else:
|
||||
# Unknown request
|
||||
self.send_response(400)
|
||||
if "/reflect/" in self.path:
|
||||
self.reflect_headers()
|
||||
self.send_header("Content-type", "text/plain")
|
||||
self.end_headers()
|
||||
if body:
|
||||
self.wfile.write(body)
|
||||
elif "fail" not in self.path:
|
||||
data = data.copy() # we're going to modify
|
||||
# Ensure there's a "reply" key in data, even if there wasn't before
|
||||
|
|
@ -207,6 +276,17 @@ class Server(ThreadingMixIn, HTTPServer):
|
|||
# operation of freeport() absolutely depends on it being off.
|
||||
allow_reuse_address = False
|
||||
|
||||
# Override of BaseServer.handle_error(). Not too interested
|
||||
# in errors and the default handler emits a scary traceback
|
||||
# to stderr which annoys some. Disable this override to get
|
||||
# default behavior which *shouldn't* cause the program to return
|
||||
# a failure status.
|
||||
def handle_error(self, request, client_address):
|
||||
print '-'*40
|
||||
print 'Ignoring exception during processing of request from',
|
||||
print client_address
|
||||
print '-'*40
|
||||
|
||||
if __name__ == "__main__":
|
||||
do_valgrind = False
|
||||
path_search = False
|
||||
|
|
@ -233,3 +313,4 @@ if __name__ == "__main__":
|
|||
args = ["valgrind", "--log-file=./valgrind.log"] + args
|
||||
path_search = True
|
||||
sys.exit(run(server=Thread(name="httpd", target=httpd.serve_forever), use_path=path_search, *args))
|
||||
|
||||
|
|
|
|||
|
|
@ -107,15 +107,14 @@ public:
|
|||
|
||||
inline void rotate(const LLVector4a& v, LLVector4a& res)
|
||||
{
|
||||
res = _mm_shuffle_ps(v, v, _MM_SHUFFLE(0, 0, 0, 0));
|
||||
res.mul(mMatrix[0]);
|
||||
|
||||
LLVector4a y;
|
||||
y = _mm_shuffle_ps(v, v, _MM_SHUFFLE(1, 1, 1, 1));
|
||||
y.mul(mMatrix[1]);
|
||||
LLVector4a y,z;
|
||||
|
||||
LLVector4a z;
|
||||
res = _mm_shuffle_ps(v, v, _MM_SHUFFLE(0, 0, 0, 0));
|
||||
y = _mm_shuffle_ps(v, v, _MM_SHUFFLE(1, 1, 1, 1));
|
||||
z = _mm_shuffle_ps(v, v, _MM_SHUFFLE(2, 2, 2, 2));
|
||||
|
||||
res.mul(mMatrix[0]);
|
||||
y.mul(mMatrix[1]);
|
||||
z.mul(mMatrix[2]);
|
||||
|
||||
res.add(y);
|
||||
|
|
|
|||
|
|
@ -39,34 +39,6 @@
|
|||
#include <stdint.h>
|
||||
#endif
|
||||
|
||||
template <typename T> T* LL_NEXT_ALIGNED_ADDRESS(T* address)
|
||||
{
|
||||
return reinterpret_cast<T*>(
|
||||
(reinterpret_cast<uintptr_t>(address) + 0xF) & ~0xF);
|
||||
}
|
||||
|
||||
template <typename T> T* LL_NEXT_ALIGNED_ADDRESS_64(T* address)
|
||||
{
|
||||
return reinterpret_cast<T*>(
|
||||
(reinterpret_cast<uintptr_t>(address) + 0x3F) & ~0x3F);
|
||||
}
|
||||
|
||||
#if LL_LINUX || LL_DARWIN
|
||||
|
||||
#define LL_ALIGN_PREFIX(x)
|
||||
#define LL_ALIGN_POSTFIX(x) __attribute__((aligned(x)))
|
||||
|
||||
#elif LL_WINDOWS
|
||||
|
||||
#define LL_ALIGN_PREFIX(x) __declspec(align(x))
|
||||
#define LL_ALIGN_POSTFIX(x)
|
||||
|
||||
#else
|
||||
#error "LL_ALIGN_PREFIX and LL_ALIGN_POSTFIX undefined"
|
||||
#endif
|
||||
|
||||
#define LL_ALIGN_16(var) LL_ALIGN_PREFIX(16) var LL_ALIGN_POSTFIX(16)
|
||||
|
||||
#include <xmmintrin.h>
|
||||
#include <emmintrin.h>
|
||||
|
||||
|
|
|
|||
|
|
@ -41,55 +41,7 @@ extern const LLVector4a LL_V4A_EPSILON = reinterpret_cast<const LLVector4a&> ( F
|
|||
|
||||
/*static */void LLVector4a::memcpyNonAliased16(F32* __restrict dst, const F32* __restrict src, size_t bytes)
|
||||
{
|
||||
assert(src != NULL);
|
||||
assert(dst != NULL);
|
||||
assert(bytes > 0);
|
||||
assert((bytes % sizeof(F32))== 0);
|
||||
ll_assert_aligned(src,16);
|
||||
ll_assert_aligned(dst,16);
|
||||
assert(bytes%16==0);
|
||||
|
||||
F32* end = dst + (bytes / sizeof(F32) );
|
||||
|
||||
if (bytes > 64)
|
||||
{
|
||||
F32* begin_64 = LL_NEXT_ALIGNED_ADDRESS_64(dst);
|
||||
|
||||
//at least 64 (16*4) bytes before the end of the destination, switch to 16 byte copies
|
||||
F32* end_64 = end-16;
|
||||
|
||||
_mm_prefetch((char*)begin_64, _MM_HINT_NTA);
|
||||
_mm_prefetch((char*)begin_64 + 64, _MM_HINT_NTA);
|
||||
_mm_prefetch((char*)begin_64 + 128, _MM_HINT_NTA);
|
||||
_mm_prefetch((char*)begin_64 + 192, _MM_HINT_NTA);
|
||||
|
||||
while (dst < begin_64)
|
||||
{
|
||||
copy4a(dst, src);
|
||||
dst += 4;
|
||||
src += 4;
|
||||
}
|
||||
|
||||
while (dst < end_64)
|
||||
{
|
||||
_mm_prefetch((char*)src + 512, _MM_HINT_NTA);
|
||||
_mm_prefetch((char*)dst + 512, _MM_HINT_NTA);
|
||||
copy4a(dst, src);
|
||||
copy4a(dst+4, src+4);
|
||||
copy4a(dst+8, src+8);
|
||||
copy4a(dst+12, src+12);
|
||||
|
||||
dst += 16;
|
||||
src += 16;
|
||||
}
|
||||
}
|
||||
|
||||
while (dst < end)
|
||||
{
|
||||
copy4a(dst, src);
|
||||
dst += 4;
|
||||
src += 4;
|
||||
}
|
||||
ll_memcpy_nonaliased_aligned_16((char*)dst, (char*)src, bytes);
|
||||
}
|
||||
|
||||
void LLVector4a::setRotated( const LLRotation& rot, const LLVector4a& vec )
|
||||
|
|
|
|||
|
|
@ -480,16 +480,13 @@ inline void LLVector4a::setMax(const LLVector4a& lhs, const LLVector4a& rhs)
|
|||
mQ = _mm_max_ps(lhs.mQ, rhs.mQ);
|
||||
}
|
||||
|
||||
// Set this to (c * lhs) + rhs * ( 1 - c)
|
||||
// Set this to lhs + (rhs-lhs)*c
|
||||
inline void LLVector4a::setLerp(const LLVector4a& lhs, const LLVector4a& rhs, F32 c)
|
||||
{
|
||||
LLVector4a a = lhs;
|
||||
a.mul(c);
|
||||
|
||||
LLVector4a b = rhs;
|
||||
b.mul(1.f-c);
|
||||
|
||||
setAdd(a, b);
|
||||
LLVector4a t;
|
||||
t.setSub(rhs,lhs);
|
||||
t.mul(c);
|
||||
setAdd(lhs, t);
|
||||
}
|
||||
|
||||
inline LLBool32 LLVector4a::isFinite3() const
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -37,7 +37,6 @@ class LLPath;
|
|||
|
||||
template <class T> class LLOctreeNode;
|
||||
|
||||
class LLVector4a;
|
||||
class LLVolumeFace;
|
||||
class LLVolume;
|
||||
class LLVolumeTriangle;
|
||||
|
|
@ -50,12 +49,15 @@ class LLVolumeTriangle;
|
|||
#include "v3math.h"
|
||||
#include "v3dmath.h"
|
||||
#include "v4math.h"
|
||||
#include "llvector4a.h"
|
||||
#include "llmatrix4a.h"
|
||||
#include "llquaternion.h"
|
||||
#include "llstrider.h"
|
||||
#include "v4coloru.h"
|
||||
#include "llrefcount.h"
|
||||
#include "llpointer.h"
|
||||
#include "llfile.h"
|
||||
#include "llalignedarray.h"
|
||||
|
||||
//============================================================================
|
||||
|
||||
|
|
@ -708,16 +710,16 @@ public:
|
|||
LLFaceID mFaceID;
|
||||
};
|
||||
|
||||
std::vector<LLVector3> mProfile;
|
||||
std::vector<LLVector2> mNormals;
|
||||
LLAlignedArray<LLVector4a, 64> mProfile;
|
||||
//LLAlignedArray<LLVector4a, 64> mNormals;
|
||||
std::vector<Face> mFaces;
|
||||
std::vector<LLVector3> mEdgeNormals;
|
||||
std::vector<LLVector3> mEdgeCenters;
|
||||
|
||||
//LLAlignedArray<LLVector4a, 64> mEdgeNormals;
|
||||
//LLAlignedArray<LLVector4a, 64> mEdgeCenters;
|
||||
|
||||
friend std::ostream& operator<<(std::ostream &s, const LLProfile &profile);
|
||||
|
||||
protected:
|
||||
void genNormals(const LLProfileParams& params);
|
||||
static S32 getNumNGonPoints(const LLProfileParams& params, S32 sides, F32 offset=0.0f, F32 bevel = 0.0f, F32 ang_scale = 1.f, S32 split = 0);
|
||||
void genNGon(const LLProfileParams& params, S32 sides, F32 offset=0.0f, F32 bevel = 0.0f, F32 ang_scale = 1.f, S32 split = 0);
|
||||
|
||||
|
|
@ -741,13 +743,29 @@ protected:
|
|||
class LLPath
|
||||
{
|
||||
public:
|
||||
struct PathPt
|
||||
class PathPt
|
||||
{
|
||||
LLVector3 mPos;
|
||||
LLVector2 mScale;
|
||||
LLQuaternion mRot;
|
||||
public:
|
||||
LLMatrix4a mRot;
|
||||
LLVector4a mPos;
|
||||
|
||||
LLVector4a mScale;
|
||||
F32 mTexT;
|
||||
PathPt() { mPos.setVec(0,0,0); mTexT = 0; mScale.setVec(0,0); mRot.loadIdentity(); }
|
||||
F32 pad[3]; //for alignment
|
||||
PathPt()
|
||||
{
|
||||
mPos.clear();
|
||||
mTexT = 0;
|
||||
mScale.clear();
|
||||
mRot.setRows(LLVector4a(1,0,0,0),
|
||||
LLVector4a(0,1,0,0),
|
||||
LLVector4a(0,0,1,0));
|
||||
|
||||
//distinguished data in the pad for debugging
|
||||
pad[0] = 3.14159f;
|
||||
pad[1] = -3.14159f;
|
||||
pad[2] = 0.585f;
|
||||
}
|
||||
};
|
||||
|
||||
public:
|
||||
|
|
@ -779,7 +797,7 @@ public:
|
|||
friend std::ostream& operator<<(std::ostream &s, const LLPath &path);
|
||||
|
||||
public:
|
||||
std::vector<PathPt> mPath;
|
||||
LLAlignedArray<PathPt, 64> mPath;
|
||||
|
||||
protected:
|
||||
BOOL mOpen;
|
||||
|
|
@ -912,6 +930,7 @@ public:
|
|||
LLVector2 mTexCoordExtents[2]; //minimum and maximum of texture coordinates of the face.
|
||||
|
||||
S32 mNumVertices;
|
||||
S32 mNumAllocatedVertices;
|
||||
S32 mNumIndices;
|
||||
|
||||
LLVector4a* mPositions;
|
||||
|
|
@ -933,6 +952,9 @@ public:
|
|||
|
||||
LLOctreeNode<LLVolumeTriangle>* mOctree;
|
||||
|
||||
//whether or not face has been cache optimized
|
||||
BOOL mOptimized;
|
||||
|
||||
private:
|
||||
BOOL createUnCutCubeCap(LLVolume* volume, BOOL partial_build = FALSE);
|
||||
BOOL createCap(LLVolume* volume, BOOL partial_build = FALSE);
|
||||
|
|
@ -947,11 +969,7 @@ protected:
|
|||
~LLVolume(); // use unref
|
||||
|
||||
public:
|
||||
struct Point
|
||||
{
|
||||
LLVector3 mPos;
|
||||
};
|
||||
|
||||
|
||||
struct FaceParams
|
||||
{
|
||||
LLFaceID mFaceID;
|
||||
|
|
@ -974,8 +992,8 @@ public:
|
|||
const LLProfile& getProfile() const { return *mProfilep; }
|
||||
LLPath& getPath() const { return *mPathp; }
|
||||
void resizePath(S32 length);
|
||||
const std::vector<Point>& getMesh() const { return mMesh; }
|
||||
const LLVector3& getMeshPt(const U32 i) const { return mMesh[i].mPos; }
|
||||
const LLAlignedArray<LLVector4a,64>& getMesh() const { return mMesh; }
|
||||
const LLVector4a& getMeshPt(const U32 i) const { return mMesh[i]; }
|
||||
|
||||
void setDirty() { mPathp->setDirty(); mProfilep->setDirty(); }
|
||||
|
||||
|
|
@ -990,10 +1008,7 @@ public:
|
|||
S32 getSculptLevel() const { return mSculptLevel; }
|
||||
void setSculptLevel(S32 level) { mSculptLevel = level; }
|
||||
|
||||
S32 *getTriangleIndices(U32 &num_indices) const;
|
||||
|
||||
// returns number of triangle indeces required for path/profile mesh
|
||||
S32 getNumTriangleIndices() const;
|
||||
|
||||
static void getLoDTriangleCounts(const LLVolumeParams& params, S32* counts);
|
||||
|
||||
S32 getNumTriangles(S32* vcount = NULL) const;
|
||||
|
|
@ -1059,7 +1074,8 @@ public:
|
|||
LLVolumeParams mParams;
|
||||
LLPath *mPathp;
|
||||
LLProfile *mProfilep;
|
||||
std::vector<Point> mMesh;
|
||||
LLAlignedArray<LLVector4a,64> mMesh;
|
||||
|
||||
|
||||
BOOL mGenerateSingleFace;
|
||||
typedef std::vector<LLVolumeFace> face_list_t;
|
||||
|
|
|
|||
|
|
@ -92,6 +92,7 @@ S32 LLCurl::sTotalHandles = 0 ;
|
|||
bool LLCurl::sNotQuitting = true;
|
||||
F32 LLCurl::sCurlRequestTimeOut = 120.f; //seonds
|
||||
S32 LLCurl::sMaxHandles = 256; //max number of handles, (multi handles and easy handles combined).
|
||||
CURL* LLCurl::sCurlTemplateStandardHandle = NULL;
|
||||
|
||||
void check_curl_code(CURLcode code)
|
||||
{
|
||||
|
|
@ -1818,10 +1819,10 @@ CURL* LLCurl::newEasyHandle()
|
|||
}
|
||||
sTotalHandles++;
|
||||
|
||||
CURL* ret = curl_easy_init() ;
|
||||
CURL* ret = createStandardCurlHandle();
|
||||
if(!ret)
|
||||
{
|
||||
llwarns << "curl_easy_init failed." << llendl ;
|
||||
llwarns << "failed to create curl handle." << llendl ;
|
||||
}
|
||||
|
||||
return ret ;
|
||||
|
|
@ -1851,3 +1852,47 @@ void LLCurlFF::check_multi_code(CURLMcode code)
|
|||
{
|
||||
check_curl_multi_code(code);
|
||||
}
|
||||
|
||||
|
||||
// Static
|
||||
CURL* LLCurl::createStandardCurlHandle()
|
||||
{
|
||||
if (sCurlTemplateStandardHandle == NULL)
|
||||
{ // Late creation of the template curl handle
|
||||
sCurlTemplateStandardHandle = curl_easy_init();
|
||||
if (sCurlTemplateStandardHandle == NULL)
|
||||
{
|
||||
llwarns << "curl error calling curl_easy_init()" << llendl;
|
||||
}
|
||||
else
|
||||
{
|
||||
CURLcode result = curl_easy_setopt(sCurlTemplateStandardHandle, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4);
|
||||
check_curl_code(result);
|
||||
result = curl_easy_setopt(sCurlTemplateStandardHandle, CURLOPT_NOSIGNAL, 1);
|
||||
check_curl_code(result);
|
||||
result = curl_easy_setopt(sCurlTemplateStandardHandle, CURLOPT_NOPROGRESS, 1);
|
||||
check_curl_code(result);
|
||||
result = curl_easy_setopt(sCurlTemplateStandardHandle, CURLOPT_ENCODING, "");
|
||||
check_curl_code(result);
|
||||
result = curl_easy_setopt(sCurlTemplateStandardHandle, CURLOPT_AUTOREFERER, 1);
|
||||
check_curl_code(result);
|
||||
result = curl_easy_setopt(sCurlTemplateStandardHandle, CURLOPT_FOLLOWLOCATION, 1);
|
||||
check_curl_code(result);
|
||||
result = curl_easy_setopt(sCurlTemplateStandardHandle, CURLOPT_SSL_VERIFYPEER, 1);
|
||||
check_curl_code(result);
|
||||
result = curl_easy_setopt(sCurlTemplateStandardHandle, CURLOPT_SSL_VERIFYHOST, 0);
|
||||
check_curl_code(result);
|
||||
|
||||
// The Linksys WRT54G V5 router has an issue with frequent
|
||||
// DNS lookups from LAN machines. If they happen too often,
|
||||
// like for every HTTP request, the router gets annoyed after
|
||||
// about 700 or so requests and starts issuing TCP RSTs to
|
||||
// new connections. Reuse the DNS lookups for even a few
|
||||
// seconds and no RSTs.
|
||||
result = curl_easy_setopt(sCurlTemplateStandardHandle, CURLOPT_DNS_CACHE_TIMEOUT, 15);
|
||||
check_curl_code(result);
|
||||
}
|
||||
}
|
||||
|
||||
return curl_easy_duphandle(sCurlTemplateStandardHandle);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@
|
|||
#include "llqueuedthread.h"
|
||||
#include "llframetimer.h"
|
||||
#include "llpointer.h"
|
||||
|
||||
#include "llsingleton.h"
|
||||
|
||||
class LLMutex;
|
||||
class LLCurlThread;
|
||||
|
|
@ -188,6 +188,8 @@ public:
|
|||
static CURL* newEasyHandle() ;
|
||||
static void deleteEasyHandle(CURL* handle) ;
|
||||
|
||||
static CURL* createStandardCurlHandle();
|
||||
|
||||
private:
|
||||
static std::string sCAPath;
|
||||
static std::string sCAFile;
|
||||
|
|
@ -197,6 +199,7 @@ private:
|
|||
static LLMutex* sHandleMutexp ;
|
||||
static S32 sTotalHandles ;
|
||||
static S32 sMaxHandles;
|
||||
static CURL* sCurlTemplateStandardHandle;
|
||||
public:
|
||||
static bool sNotQuitting;
|
||||
static F32 sCurlRequestTimeOut;
|
||||
|
|
|
|||
|
|
@ -37,53 +37,46 @@
|
|||
|
||||
|
||||
|
||||
const S32 PS_PART_DATA_BLOCK_SIZE = 4 + 2 + 4 + 4 + 2 + 2; // 18
|
||||
const S32 PS_DATA_BLOCK_SIZE = 68 + PS_PART_DATA_BLOCK_SIZE; // 68 + 18 = 86
|
||||
const S32 PS_PART_DATA_GLOW_SIZE = 2;
|
||||
const S32 PS_PART_DATA_BLEND_SIZE = 2;
|
||||
const S32 PS_LEGACY_PART_DATA_BLOCK_SIZE = 4 + 2 + 4 + 4 + 2 + 2; //18
|
||||
const S32 PS_SYS_DATA_BLOCK_SIZE = 68;
|
||||
const S32 PS_MAX_DATA_BLOCK_SIZE = PS_SYS_DATA_BLOCK_SIZE+
|
||||
PS_LEGACY_PART_DATA_BLOCK_SIZE +
|
||||
PS_PART_DATA_BLEND_SIZE +
|
||||
PS_PART_DATA_GLOW_SIZE+
|
||||
8; //two S32 size fields
|
||||
|
||||
const S32 PS_LEGACY_DATA_BLOCK_SIZE = PS_SYS_DATA_BLOCK_SIZE + PS_LEGACY_PART_DATA_BLOCK_SIZE;
|
||||
|
||||
|
||||
const U32 PART_DATA_MASK = LLPartData::LL_PART_DATA_GLOW | LLPartData::LL_PART_DATA_BLEND;
|
||||
|
||||
|
||||
|
||||
const F32 MAX_PART_SCALE = 4.f;
|
||||
|
||||
BOOL LLPartData::pack(LLDataPacker &dp)
|
||||
bool LLPartData::hasGlow() const
|
||||
{
|
||||
LLColor4U coloru;
|
||||
dp.packU32(mFlags, "pdflags");
|
||||
dp.packFixed(mMaxAge, "pdmaxage", FALSE, 8, 8);
|
||||
coloru.setVec(mStartColor);
|
||||
dp.packColor4U(coloru, "pdstartcolor");
|
||||
coloru.setVec(mEndColor);
|
||||
dp.packColor4U(coloru, "pdendcolor");
|
||||
dp.packFixed(mStartScale.mV[0], "pdstartscalex", FALSE, 3, 5);
|
||||
dp.packFixed(mStartScale.mV[1], "pdstartscaley", FALSE, 3, 5);
|
||||
dp.packFixed(mEndScale.mV[0], "pdendscalex", FALSE, 3, 5);
|
||||
dp.packFixed(mEndScale.mV[1], "pdendscaley", FALSE, 3, 5);
|
||||
return TRUE;
|
||||
return mStartGlow > 0.f || mEndGlow > 0.f;
|
||||
}
|
||||
|
||||
LLSD LLPartData::asLLSD() const
|
||||
bool LLPartData::hasBlendFunc() const
|
||||
{
|
||||
LLSD sd = LLSD();
|
||||
sd["pdflags"] = ll_sd_from_U32(mFlags);
|
||||
sd["pdmaxage"] = mMaxAge;
|
||||
sd["pdstartcolor"] = ll_sd_from_color4(mStartColor);
|
||||
sd["pdendcolor"] = ll_sd_from_color4(mEndColor);
|
||||
sd["pdstartscale"] = ll_sd_from_vector2(mStartScale);
|
||||
sd["pdendscale"] = ll_sd_from_vector2(mEndScale);
|
||||
return sd;
|
||||
return mBlendFuncSource != LLPartData::LL_PART_BF_SOURCE_ALPHA || mBlendFuncDest != LLPartData::LL_PART_BF_ONE_MINUS_SOURCE_ALPHA;
|
||||
}
|
||||
|
||||
bool LLPartData::fromLLSD(LLSD& sd)
|
||||
S32 LLPartData::getSize() const
|
||||
{
|
||||
mFlags = ll_U32_from_sd(sd["pdflags"]);
|
||||
mMaxAge = (F32)sd["pdmaxage"].asReal();
|
||||
mStartColor = ll_color4_from_sd(sd["pdstartcolor"]);
|
||||
mEndColor = ll_color4_from_sd(sd["pdendcolor"]);
|
||||
mStartScale = ll_vector2_from_sd(sd["pdstartscale"]);
|
||||
mEndScale = ll_vector2_from_sd(sd["pdendscale"]);
|
||||
return true;
|
||||
S32 size = PS_LEGACY_PART_DATA_BLOCK_SIZE;
|
||||
if (hasGlow()) size += PS_PART_DATA_GLOW_SIZE;
|
||||
if (hasBlendFunc()) size += PS_PART_DATA_BLEND_SIZE;
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
|
||||
BOOL LLPartData::unpack(LLDataPacker &dp)
|
||||
BOOL LLPartData::unpackLegacy(LLDataPacker &dp)
|
||||
{
|
||||
LLColor4U coloru;
|
||||
|
||||
|
|
@ -98,9 +91,70 @@ BOOL LLPartData::unpack(LLDataPacker &dp)
|
|||
dp.unpackFixed(mStartScale.mV[1], "pdstartscaley", FALSE, 3, 5);
|
||||
dp.unpackFixed(mEndScale.mV[0], "pdendscalex", FALSE, 3, 5);
|
||||
dp.unpackFixed(mEndScale.mV[1], "pdendscaley", FALSE, 3, 5);
|
||||
|
||||
mStartGlow = 0.f;
|
||||
mEndGlow = 0.f;
|
||||
mBlendFuncSource = LLPartData::LL_PART_BF_SOURCE_ALPHA;
|
||||
mBlendFuncDest = LLPartData::LL_PART_BF_ONE_MINUS_SOURCE_ALPHA;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL LLPartData::unpack(LLDataPacker &dp)
|
||||
{
|
||||
S32 size = 0;
|
||||
dp.unpackS32(size, "partsize");
|
||||
|
||||
unpackLegacy(dp);
|
||||
size -= PS_LEGACY_PART_DATA_BLOCK_SIZE;
|
||||
|
||||
if (mFlags & LL_PART_DATA_GLOW)
|
||||
{
|
||||
if (size < PS_PART_DATA_GLOW_SIZE) return FALSE;
|
||||
|
||||
U8 tmp_glow = 0;
|
||||
dp.unpackU8(tmp_glow,"pdstartglow");
|
||||
mStartGlow = tmp_glow / 255.f;
|
||||
dp.unpackU8(tmp_glow,"pdendglow");
|
||||
mEndGlow = tmp_glow / 255.f;
|
||||
|
||||
size -= PS_PART_DATA_GLOW_SIZE;
|
||||
}
|
||||
else
|
||||
{
|
||||
mStartGlow = 0.f;
|
||||
mEndGlow = 0.f;
|
||||
}
|
||||
|
||||
if (mFlags & LL_PART_DATA_BLEND)
|
||||
{
|
||||
if (size < PS_PART_DATA_BLEND_SIZE) return FALSE;
|
||||
dp.unpackU8(mBlendFuncSource,"pdblendsource");
|
||||
dp.unpackU8(mBlendFuncDest,"pdblenddest");
|
||||
size -= PS_PART_DATA_BLEND_SIZE;
|
||||
}
|
||||
else
|
||||
{
|
||||
mBlendFuncSource = LLPartData::LL_PART_BF_SOURCE_ALPHA;
|
||||
mBlendFuncDest = LLPartData::LL_PART_BF_ONE_MINUS_SOURCE_ALPHA;
|
||||
}
|
||||
|
||||
if (size > 0)
|
||||
{ //leftover bytes, unrecognized parameters
|
||||
U8 feh = 0;
|
||||
while (size > 0)
|
||||
{ //read remaining bytes in block
|
||||
dp.unpackU8(feh, "whippang");
|
||||
size--;
|
||||
}
|
||||
|
||||
//this particle system won't display properly, better to not show anything
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void LLPartData::setFlags(const U32 flags)
|
||||
{
|
||||
|
|
@ -148,6 +202,18 @@ void LLPartData::setEndAlpha(const F32 alpha)
|
|||
mEndColor.mV[3] = alpha;
|
||||
}
|
||||
|
||||
// static
|
||||
bool LLPartData::validBlendFunc(S32 func)
|
||||
{
|
||||
if (func >= 0
|
||||
&& func < LL_PART_BF_COUNT
|
||||
&& func != UNSUPPORTED_DEST_ALPHA
|
||||
&& func != UNSUPPORTED_ONE_MINUS_DEST_ALPHA)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
LLPartSysData::LLPartSysData()
|
||||
{
|
||||
|
|
@ -160,6 +226,10 @@ LLPartSysData::LLPartSysData()
|
|||
mPartData.mStartScale = LLVector2(1.f, 1.f);
|
||||
mPartData.mEndScale = LLVector2(1.f, 1.f);
|
||||
mPartData.mMaxAge = 10.0;
|
||||
mPartData.mBlendFuncSource = LLPartData::LL_PART_BF_SOURCE_ALPHA;
|
||||
mPartData.mBlendFuncDest = LLPartData::LL_PART_BF_ONE_MINUS_SOURCE_ALPHA;
|
||||
mPartData.mStartGlow = 0.f;
|
||||
mPartData.mEndGlow = 0.f;
|
||||
|
||||
mMaxAge = 0.0;
|
||||
mStartAge = 0.0;
|
||||
|
|
@ -175,38 +245,7 @@ LLPartSysData::LLPartSysData()
|
|||
mNumParticles = 0;
|
||||
}
|
||||
|
||||
|
||||
BOOL LLPartSysData::pack(LLDataPacker &dp)
|
||||
{
|
||||
dp.packU32(mCRC, "pscrc");
|
||||
dp.packU32(mFlags, "psflags");
|
||||
dp.packU8(mPattern, "pspattern");
|
||||
dp.packFixed(mMaxAge, "psmaxage", FALSE, 8, 8);
|
||||
dp.packFixed(mStartAge, "psstartage", FALSE, 8, 8);
|
||||
dp.packFixed(mInnerAngle, "psinnerangle", FALSE, 3, 5);
|
||||
dp.packFixed(mOuterAngle, "psouterangle", FALSE, 3, 5);
|
||||
dp.packFixed(mBurstRate, "psburstrate", FALSE, 8, 8);
|
||||
dp.packFixed(mBurstRadius, "psburstradius", FALSE, 8, 8);
|
||||
dp.packFixed(mBurstSpeedMin, "psburstspeedmin", FALSE, 8, 8);
|
||||
dp.packFixed(mBurstSpeedMax, "psburstspeedmax", FALSE, 8, 8);
|
||||
dp.packU8(mBurstPartCount, "psburstpartcount");
|
||||
|
||||
dp.packFixed(mAngularVelocity.mV[0], "psangvelx", TRUE, 8, 7);
|
||||
dp.packFixed(mAngularVelocity.mV[1], "psangvely", TRUE, 8, 7);
|
||||
dp.packFixed(mAngularVelocity.mV[2], "psangvelz", TRUE, 8, 7);
|
||||
|
||||
dp.packFixed(mPartAccel.mV[0], "psaccelx", TRUE, 8, 7);
|
||||
dp.packFixed(mPartAccel.mV[1], "psaccely", TRUE, 8, 7);
|
||||
dp.packFixed(mPartAccel.mV[2], "psaccelz", TRUE, 8, 7);
|
||||
|
||||
dp.packUUID(mPartImageID, "psuuid");
|
||||
dp.packUUID(mTargetUUID, "pstargetuuid");
|
||||
mPartData.pack(dp);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
BOOL LLPartSysData::unpack(LLDataPacker &dp)
|
||||
BOOL LLPartSysData::unpackSystem(LLDataPacker &dp)
|
||||
{
|
||||
dp.unpackU32(mCRC, "pscrc");
|
||||
dp.unpackU32(mFlags, "psflags");
|
||||
|
|
@ -232,10 +271,48 @@ BOOL LLPartSysData::unpack(LLDataPacker &dp)
|
|||
|
||||
dp.unpackUUID(mPartImageID, "psuuid");
|
||||
dp.unpackUUID(mTargetUUID, "pstargetuuid");
|
||||
mPartData.unpack(dp);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL LLPartSysData::unpackLegacy(LLDataPacker &dp)
|
||||
{
|
||||
unpackSystem(dp);
|
||||
mPartData.unpackLegacy(dp);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL LLPartSysData::unpack(LLDataPacker &dp)
|
||||
{
|
||||
// syssize is currently unused. Adding now when modifying the 'version to make extensible in the future
|
||||
S32 size = 0;
|
||||
dp.unpackS32(size, "syssize");
|
||||
|
||||
if (size != PS_SYS_DATA_BLOCK_SIZE)
|
||||
{ //unexpected size, this viewer doesn't know how to parse this particle system
|
||||
|
||||
//skip to LLPartData block
|
||||
U8 feh = 0;
|
||||
|
||||
for (U32 i = 0; i < size; ++i)
|
||||
{
|
||||
dp.unpackU8(feh, "whippang");
|
||||
}
|
||||
|
||||
dp.unpackS32(size, "partsize");
|
||||
//skip LLPartData block
|
||||
for (U32 i = 0; i < size; ++i)
|
||||
{
|
||||
dp.unpackU8(feh, "whippang");
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
unpackSystem(dp);
|
||||
|
||||
return mPartData.unpack(dp);
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream& s, const LLPartSysData &data)
|
||||
{
|
||||
s << "Flags: " << std::hex << data.mFlags;
|
||||
|
|
@ -253,7 +330,7 @@ std::ostream& operator<<(std::ostream& s, const LLPartSysData &data)
|
|||
|
||||
BOOL LLPartSysData::isNullPS(const S32 block_num)
|
||||
{
|
||||
U8 ps_data_block[PS_DATA_BLOCK_SIZE];
|
||||
U8 ps_data_block[PS_MAX_DATA_BLOCK_SIZE];
|
||||
U32 crc;
|
||||
|
||||
S32 size;
|
||||
|
|
@ -264,14 +341,28 @@ BOOL LLPartSysData::isNullPS(const S32 block_num)
|
|||
{
|
||||
return TRUE;
|
||||
}
|
||||
else if (size != PS_DATA_BLOCK_SIZE)
|
||||
|
||||
if (size > PS_MAX_DATA_BLOCK_SIZE)
|
||||
{
|
||||
llwarns << "PSBlock is wrong size for particle system data - got " << size << ", expecting " << PS_DATA_BLOCK_SIZE << llendl;
|
||||
//size is too big, newer particle version unsupported
|
||||
return TRUE;
|
||||
}
|
||||
gMessageSystem->getBinaryData("ObjectData", "PSBlock", ps_data_block, PS_DATA_BLOCK_SIZE, block_num, PS_DATA_BLOCK_SIZE);
|
||||
|
||||
LLDataPackerBinaryBuffer dp(ps_data_block, PS_DATA_BLOCK_SIZE);
|
||||
gMessageSystem->getBinaryData("ObjectData", "PSBlock", ps_data_block, size, block_num, PS_MAX_DATA_BLOCK_SIZE);
|
||||
|
||||
LLDataPackerBinaryBuffer dp(ps_data_block, size);
|
||||
if (size > PS_LEGACY_DATA_BLOCK_SIZE)
|
||||
{
|
||||
// non legacy systems pack a size before the CRC
|
||||
S32 tmp = 0;
|
||||
dp.unpackS32(tmp, "syssize");
|
||||
|
||||
if (tmp > PS_SYS_DATA_BLOCK_SIZE)
|
||||
{ //unknown system data block size, don't know how to parse it, treat as NULL
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
dp.unpackU32(crc, "crc");
|
||||
|
||||
if (crc == 0)
|
||||
|
|
@ -281,50 +372,37 @@ BOOL LLPartSysData::isNullPS(const S32 block_num)
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
//static
|
||||
BOOL LLPartSysData::packNull()
|
||||
{
|
||||
U8 ps_data_block[PS_DATA_BLOCK_SIZE];
|
||||
gMessageSystem->addBinaryData("PSBlock", ps_data_block, 0);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
BOOL LLPartSysData::packBlock()
|
||||
{
|
||||
U8 ps_data_block[PS_DATA_BLOCK_SIZE];
|
||||
|
||||
LLDataPackerBinaryBuffer dp(ps_data_block, PS_DATA_BLOCK_SIZE);
|
||||
pack(dp);
|
||||
|
||||
// Add to message
|
||||
gMessageSystem->addBinaryData("PSBlock", ps_data_block, PS_DATA_BLOCK_SIZE);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
BOOL LLPartSysData::unpackBlock(const S32 block_num)
|
||||
{
|
||||
U8 ps_data_block[PS_DATA_BLOCK_SIZE];
|
||||
U8 ps_data_block[PS_MAX_DATA_BLOCK_SIZE];
|
||||
|
||||
// Check size of block
|
||||
S32 size = gMessageSystem->getSize("ObjectData", block_num, "PSBlock");
|
||||
|
||||
if (size != PS_DATA_BLOCK_SIZE)
|
||||
if (size > PS_MAX_DATA_BLOCK_SIZE)
|
||||
{
|
||||
llwarns << "PSBlock is wrong size for particle system data - got " << size << ", expecting " << PS_DATA_BLOCK_SIZE << llendl;
|
||||
// Larger packets are newer and unsupported
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// Get from message
|
||||
gMessageSystem->getBinaryData("ObjectData", "PSBlock", ps_data_block, PS_DATA_BLOCK_SIZE, block_num, PS_DATA_BLOCK_SIZE);
|
||||
gMessageSystem->getBinaryData("ObjectData", "PSBlock", ps_data_block, size, block_num, PS_MAX_DATA_BLOCK_SIZE);
|
||||
|
||||
LLDataPackerBinaryBuffer dp(ps_data_block, PS_DATA_BLOCK_SIZE);
|
||||
unpack(dp);
|
||||
LLDataPackerBinaryBuffer dp(ps_data_block, size);
|
||||
|
||||
return TRUE;
|
||||
if (size == PS_LEGACY_DATA_BLOCK_SIZE)
|
||||
{
|
||||
return unpackLegacy(dp);
|
||||
}
|
||||
else
|
||||
{
|
||||
return unpack(dp);
|
||||
}
|
||||
}
|
||||
|
||||
bool LLPartSysData::isLegacyCompatible() const
|
||||
{
|
||||
return !mPartData.hasGlow() && !mPartData.hasBlendFunc();
|
||||
}
|
||||
|
||||
void LLPartSysData::clampSourceParticleRate()
|
||||
|
|
|
|||
|
|
@ -70,7 +70,12 @@ enum LLPSScriptFlags
|
|||
LLPS_SRC_TARGET_UUID,
|
||||
LLPS_SRC_OMEGA,
|
||||
LLPS_SRC_ANGLE_BEGIN,
|
||||
LLPS_SRC_ANGLE_END
|
||||
LLPS_SRC_ANGLE_END,
|
||||
|
||||
LLPS_PART_BLEND_FUNC_SOURCE,
|
||||
LLPS_PART_BLEND_FUNC_DEST,
|
||||
LLPS_PART_START_GLOW,
|
||||
LLPS_PART_END_GLOW
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -83,11 +88,13 @@ public:
|
|||
mParameter(0.f)
|
||||
{
|
||||
}
|
||||
BOOL unpackLegacy(LLDataPacker &dp);
|
||||
BOOL unpack(LLDataPacker &dp);
|
||||
|
||||
BOOL pack(LLDataPacker &dp);
|
||||
LLSD asLLSD() const;
|
||||
operator LLSD() const {return asLLSD(); }
|
||||
bool fromLLSD(LLSD& sd);
|
||||
|
||||
bool hasGlow() const;
|
||||
bool hasBlendFunc() const;
|
||||
|
||||
// Masks for the different particle flags
|
||||
enum
|
||||
|
|
@ -102,17 +109,39 @@ public:
|
|||
LL_PART_TARGET_LINEAR_MASK = 0x80, // Particle uses a direct linear interpolation
|
||||
LL_PART_EMISSIVE_MASK = 0x100, // Particle is "emissive", instead of being lit
|
||||
LL_PART_BEAM_MASK = 0x200, // Particle is a "beam" connecting source and target
|
||||
LL_PART_RIBBON_MASK = 0x400, // Particles are joined together into one continuous triangle strip
|
||||
|
||||
// Not implemented yet!
|
||||
//LL_PART_RANDOM_ACCEL_MASK = 0x100, // Particles have random acceleration
|
||||
//LL_PART_RANDOM_VEL_MASK = 0x200, // Particles have random velocity shifts"
|
||||
//LL_PART_TRAIL_MASK = 0x400, // Particles have historical "trails"
|
||||
|
||||
//sYSTEM SET FLAGS
|
||||
LL_PART_DATA_GLOW = 0x10000,
|
||||
LL_PART_DATA_BLEND = 0x20000,
|
||||
|
||||
// Viewer side use only!
|
||||
LL_PART_HUD = 0x40000000,
|
||||
LL_PART_DEAD_MASK = 0x80000000,
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
LL_PART_BF_ONE = 0,
|
||||
LL_PART_BF_ZERO = 1,
|
||||
LL_PART_BF_DEST_COLOR = 2,
|
||||
LL_PART_BF_SOURCE_COLOR = 3,
|
||||
LL_PART_BF_ONE_MINUS_DEST_COLOR = 4,
|
||||
LL_PART_BF_ONE_MINUS_SOURCE_COLOR = 5,
|
||||
UNSUPPORTED_DEST_ALPHA = 6,
|
||||
LL_PART_BF_SOURCE_ALPHA = 7,
|
||||
UNSUPPORTED_ONE_MINUS_DEST_ALPHA = 8,
|
||||
LL_PART_BF_ONE_MINUS_SOURCE_ALPHA = 9,
|
||||
LL_PART_BF_COUNT = 10
|
||||
};
|
||||
|
||||
static bool validBlendFunc(S32 func);
|
||||
|
||||
void setFlags(const U32 flags);
|
||||
void setMaxAge(const F32 max_age);
|
||||
void setStartScale(const F32 xs, F32 ys);
|
||||
|
|
@ -126,6 +155,9 @@ public:
|
|||
friend class LLPartSysData;
|
||||
friend class LLViewerPartSourceScript;
|
||||
|
||||
private:
|
||||
S32 getSize() const;
|
||||
|
||||
// These are public because I'm really lazy...
|
||||
public:
|
||||
U32 mFlags; // Particle state/interpolators in effect
|
||||
|
|
@ -137,6 +169,12 @@ public:
|
|||
|
||||
LLVector3 mPosOffset; // Offset from source if using FOLLOW_SOURCE
|
||||
F32 mParameter; // A single floating point parameter
|
||||
|
||||
F32 mStartGlow;
|
||||
F32 mEndGlow;
|
||||
|
||||
U8 mBlendFuncSource;
|
||||
U8 mBlendFuncDest;
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -146,15 +184,13 @@ public:
|
|||
LLPartSysData();
|
||||
|
||||
BOOL unpack(LLDataPacker &dp);
|
||||
BOOL pack(LLDataPacker &dp);
|
||||
|
||||
|
||||
BOOL unpackLegacy(LLDataPacker &dp);
|
||||
BOOL unpackBlock(const S32 block_num);
|
||||
BOOL packBlock();
|
||||
|
||||
static BOOL packNull();
|
||||
|
||||
static BOOL isNullPS(const S32 block_num); // Returns FALSE if this is a "NULL" particle system (i.e. no system)
|
||||
|
||||
bool isLegacyCompatible() const;
|
||||
|
||||
// Different masks for effects on the source
|
||||
enum
|
||||
{
|
||||
|
|
@ -187,7 +223,12 @@ public:
|
|||
void clampSourceParticleRate();
|
||||
|
||||
friend std::ostream& operator<<(std::ostream& s, const LLPartSysData &data); // Stream a
|
||||
|
||||
S32 getdataBlockSize() const;
|
||||
|
||||
private:
|
||||
BOOL unpackSystem(LLDataPacker &dp);
|
||||
|
||||
public:
|
||||
// Public because I'm lazy....
|
||||
|
||||
|
|
|
|||
|
|
@ -606,16 +606,21 @@ void LLTransferManager::processTransferAbort(LLMessageSystem *msgp, void **)
|
|||
void LLTransferManager::reliablePacketCallback(void **user_data, S32 result)
|
||||
{
|
||||
LLUUID *transfer_idp = (LLUUID *)user_data;
|
||||
if (result)
|
||||
if (result &&
|
||||
transfer_idp != NULL)
|
||||
{
|
||||
llwarns << "Aborting reliable transfer " << *transfer_idp << " due to failed reliable resends!" << llendl;
|
||||
LLTransferSource *tsp = gTransferManager.findTransferSource(*transfer_idp);
|
||||
if (tsp)
|
||||
{
|
||||
llwarns << "Aborting reliable transfer " << *transfer_idp << " due to failed reliable resends!" << llendl;
|
||||
LLTransferSourceChannel *tscp = tsp->mChannelp;
|
||||
tsp->abortTransfer();
|
||||
tscp->deleteTransfer(tsp);
|
||||
}
|
||||
else
|
||||
{
|
||||
llwarns << "Aborting reliable transfer " << *transfer_idp << " but can't find the LLTransferSource object" << llendl;
|
||||
}
|
||||
}
|
||||
delete transfer_idp;
|
||||
}
|
||||
|
|
@ -892,22 +897,26 @@ LLTransferSource *LLTransferSourceChannel::findTransferSource(const LLUUID &tran
|
|||
}
|
||||
|
||||
|
||||
BOOL LLTransferSourceChannel::deleteTransfer(LLTransferSource *tsp)
|
||||
void LLTransferSourceChannel::deleteTransfer(LLTransferSource *tsp)
|
||||
{
|
||||
|
||||
LLPriQueueMap<LLTransferSource *>::pqm_iter iter;
|
||||
for (iter = mTransferSources.mMap.begin(); iter != mTransferSources.mMap.end(); iter++)
|
||||
if (tsp)
|
||||
{
|
||||
if (iter->second == tsp)
|
||||
LLPriQueueMap<LLTransferSource *>::pqm_iter iter;
|
||||
for (iter = mTransferSources.mMap.begin(); iter != mTransferSources.mMap.end(); iter++)
|
||||
{
|
||||
delete tsp;
|
||||
mTransferSources.mMap.erase(iter);
|
||||
return TRUE;
|
||||
if (iter->second == tsp)
|
||||
{
|
||||
delete tsp;
|
||||
mTransferSources.mMap.erase(iter);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
llerrs << "Unable to find transfer source to delete!" << llendl;
|
||||
return FALSE;
|
||||
llwarns << "Unable to find transfer source id "
|
||||
<< tsp->getID()
|
||||
<< " to delete!"
|
||||
<< llendl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -1008,21 +1017,26 @@ LLTransferTarget *LLTransferTargetChannel::findTransferTarget(const LLUUID &tran
|
|||
}
|
||||
|
||||
|
||||
BOOL LLTransferTargetChannel::deleteTransfer(LLTransferTarget *ttp)
|
||||
void LLTransferTargetChannel::deleteTransfer(LLTransferTarget *ttp)
|
||||
{
|
||||
tt_iter iter;
|
||||
for (iter = mTransferTargets.begin(); iter != mTransferTargets.end(); iter++)
|
||||
if (ttp)
|
||||
{
|
||||
if (*iter == ttp)
|
||||
tt_iter iter;
|
||||
for (iter = mTransferTargets.begin(); iter != mTransferTargets.end(); iter++)
|
||||
{
|
||||
delete ttp;
|
||||
mTransferTargets.erase(iter);
|
||||
return TRUE;
|
||||
if (*iter == ttp)
|
||||
{
|
||||
delete ttp;
|
||||
mTransferTargets.erase(iter);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
llerrs << "Unable to find transfer target to delete!" << llendl;
|
||||
return FALSE;
|
||||
llwarns << "Unable to find transfer target id "
|
||||
<< ttp->getID()
|
||||
<< " to delete!"
|
||||
<< llendl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -199,7 +199,7 @@ public:
|
|||
|
||||
void addTransferSource(LLTransferSource *sourcep);
|
||||
LLTransferSource *findTransferSource(const LLUUID &transfer_id);
|
||||
BOOL deleteTransfer(LLTransferSource *tsp);
|
||||
void deleteTransfer(LLTransferSource *tsp);
|
||||
|
||||
void setThrottleID(const S32 throttle_id) { mThrottleID = throttle_id; }
|
||||
|
||||
|
|
@ -232,7 +232,7 @@ public:
|
|||
const F32 priority);
|
||||
|
||||
LLTransferTarget *findTransferTarget(const LLUUID &transfer_id);
|
||||
BOOL deleteTransfer(LLTransferTarget *ttp);
|
||||
void deleteTransfer(LLTransferTarget *ttp);
|
||||
|
||||
|
||||
LLTransferChannelType getChannelType() const { return mChannelType; }
|
||||
|
|
|
|||
|
|
@ -38,10 +38,34 @@
|
|||
|
||||
namespace tut
|
||||
{
|
||||
|
||||
//bunch of sniffed data that *should* be a valid particle system
|
||||
static U8 msg[] = {
|
||||
0x44, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x01, 0x00, 0x80, 0x00, 0x80,
|
||||
0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x5e, 0x12, 0x0b, 0xa1, 0x58, 0x05, 0xdc, 0x57, 0x66,
|
||||
0xb7, 0xf5, 0xac, 0x4b, 0xd1, 0x8f, 0x86, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x02, 0x05, 0x02, 0x00, 0x00, 0x0a, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x20, 0x20, 0x00, 0x00, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x7e, 0xc6, 0x81, 0xdc, 0x7e, 0xc6, 0x81, 0xdc, 0x77, 0xcf, 0xef, 0xd4, 0xce, 0x64, 0x1a, 0x7e,
|
||||
0x26, 0x87, 0x55, 0x7f, 0xdd, 0x65, 0x22, 0x7f, 0xdd, 0x65, 0x22, 0x7f, 0x77, 0xcf, 0x98, 0xa3, 0xab,
|
||||
0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd1, 0xf2,
|
||||
0xf1, 0x65, 0x32, 0x1b, 0xef, 0x18, 0x70, 0x66, 0xba, 0x30, 0xa0, 0x11, 0xaa, 0x2f, 0xb0, 0xab, 0xd0,
|
||||
0x30, 0x7d, 0xbd, 0x01, 0x00, 0xf8, 0x0d, 0xb8, 0x30, 0x01, 0x00, 0x00, 0x00, 0xce, 0xc6, 0x81, 0xdc,
|
||||
0xce, 0xc6, 0x81, 0xdc, 0xc7, 0xcf, 0xef, 0xd4, 0x75, 0x65, 0x1a, 0x7f, 0x62, 0x6f, 0x55, 0x7f, 0x6d,
|
||||
0x65, 0x22, 0x7f, 0x6d, 0x65, 0x22, 0x7f, 0xc7, 0xcf, 0x98, 0xa3, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
|
||||
0xab, 0xab, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd6, 0xf2, 0xf1, 0x62, 0x12, 0x1b, 0xef,
|
||||
0x18, 0x7e, 0xbd, 0x01, 0x00, 0x16, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x7c, 0xac, 0x28, 0x03, 0x80, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x48,
|
||||
0xe0, 0xb9, 0x30, 0x03, 0xe1, 0xb9, 0x30, 0xbb, 0x00, 0x00, 0x00, 0x48, 0xe0, 0xb9, 0x30, 0x36, 0xd9,
|
||||
0x81, 0xdc, 0x36, 0xd9, 0x81, 0xdc, 0x3f, 0xd0, 0xef, 0xd4, 0xa5, 0x7a, 0x72, 0x7f, 0x26, 0x30, 0x55,
|
||||
0x7f, 0x95, 0x7a, 0x22, 0x7f, 0x95, 0x7a, 0x22, 0x7f, 0x3f, 0xd0, 0x98, 0xa3, 0xab, 0xab, 0xab, 0xab,
|
||||
0xab, 0xab, 0xab, 0xab, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
||||
|
||||
struct partdata_test
|
||||
{
|
||||
};
|
||||
|
||||
typedef test_group<partdata_test> partdata_test_t;
|
||||
typedef partdata_test_t::object partdata_test_object_t;
|
||||
tut::partdata_test_t tut_partdata_test("LLPartData");
|
||||
|
|
@ -49,168 +73,82 @@ namespace tut
|
|||
template<> template<>
|
||||
void partdata_test_object_t::test<1>()
|
||||
{
|
||||
LLPartData llpdata,llpdata1;
|
||||
U8 pkbuf[128];
|
||||
LLPartSysData llpsysdata;
|
||||
LLDataPackerBinaryBuffer dp1(msg, sizeof(msg));
|
||||
|
||||
llpdata.setFlags(LLPartData::LL_PART_INTERP_COLOR_MASK | LLPartData::LL_PART_INTERP_SCALE_MASK |
|
||||
LLPartData::LL_PART_BOUNCE_MASK | LLPartData::LL_PART_WIND_MASK | LLPartData::LL_PART_FOLLOW_SRC_MASK |
|
||||
LLPartData::LL_PART_FOLLOW_VELOCITY_MASK | LLPartData::LL_PART_TARGET_POS_MASK | LLPartData::LL_PART_TARGET_LINEAR_MASK |
|
||||
LLPartData::LL_PART_EMISSIVE_MASK | LLPartData::LL_PART_BEAM_MASK | LLPartData::LL_PART_DEAD_MASK);
|
||||
ensure("LLPartSysData::unpack failed.", llpsysdata.unpack(dp1));
|
||||
|
||||
llpdata.setMaxAge(29.3f);
|
||||
|
||||
LLVector3 llvec1(1.0f, .5f, .25f);
|
||||
llpdata.setStartColor(llvec1);
|
||||
llpdata.setStartAlpha(.7f);
|
||||
|
||||
LLVector3 llvec2(.2f, .3f, 1.0f);
|
||||
llpdata.setEndColor(llvec2);
|
||||
llpdata.setEndAlpha(1.0f);
|
||||
|
||||
llpdata.setStartScale(3.23f, 4.0f);
|
||||
llpdata.setEndScale(2.4678f, 1.0f);
|
||||
|
||||
LLDataPackerBinaryBuffer dp((U8*)pkbuf, 128);
|
||||
llpdata.pack(dp);
|
||||
|
||||
S32 cur_size = dp.getCurrentSize();
|
||||
//mCRC 1 unsigned int
|
||||
ensure("mCRC different after unpacking", llpsysdata.mCRC == (U32) 1);
|
||||
//mFlags 0 unsigned int
|
||||
ensure ("mFlags different after unpacking", llpsysdata.mFlags == (U32) 0);
|
||||
//mPattern 1 '' unsigned char
|
||||
ensure ("mPattern different after unpacking", llpsysdata.mPattern == (U8) 1);
|
||||
//mInnerAngle 0.00000000 float
|
||||
ensure_approximately_equals("mInnerAngle different after unpacking", llpsysdata.mInnerAngle, 0.f, 8);
|
||||
//mOuterAngle 0.00000000 float
|
||||
ensure_approximately_equals("mOuterAngle different after unpacking", llpsysdata.mOuterAngle, 0.f, 8);
|
||||
//mAngularVelocity 0,0,0
|
||||
ensure_approximately_equals("mAngularVelocity.mV[0] different after unpacking", llpsysdata.mAngularVelocity.mV[0], 0.f, 8);
|
||||
ensure_approximately_equals("mAngularVelocity.mV[0] different after unpacking", llpsysdata.mAngularVelocity.mV[1], 0.f, 8);
|
||||
ensure_approximately_equals("mAngularVelocity.mV[0] different after unpacking", llpsysdata.mAngularVelocity.mV[2], 0.f, 8);
|
||||
//mBurstRate 0.097656250 float
|
||||
ensure_approximately_equals("mBurstRate different after unpacking", llpsysdata.mBurstRate, 0.097656250f, 8);
|
||||
//mBurstPartCount 1 '' unsigned char
|
||||
ensure("mBurstPartCount different after unpacking", llpsysdata.mBurstPartCount == (U8) 1);
|
||||
//mBurstRadius 0.00000000 float
|
||||
ensure_approximately_equals("mBurstRadius different after unpacking", llpsysdata.mBurstRadius, 0.f, 8);
|
||||
//mBurstSpeedMin 1.0000000 float
|
||||
ensure_approximately_equals("mBurstSpeedMin different after unpacking", llpsysdata.mBurstSpeedMin, 1.f, 8);
|
||||
//mBurstSpeedMax 1.0000000 float
|
||||
ensure_approximately_equals("mBurstSpeedMax different after unpacking", llpsysdata.mBurstSpeedMax, 1.f, 8);
|
||||
//mMaxAge 0.00000000 float
|
||||
ensure_approximately_equals("mMaxAge different after unpacking", llpsysdata.mMaxAge, 0.f, 8);
|
||||
//mStartAge 0.00000000 float
|
||||
ensure_approximately_equals("mStartAge different after unpacking", llpsysdata.mStartAge, 0.f, 8);
|
||||
//mPartAccel <0,0,0>
|
||||
ensure_approximately_equals("mPartAccel.mV[0] different after unpacking", llpsysdata.mPartAccel.mV[0], 0.f, 7);
|
||||
ensure_approximately_equals("mPartAccel.mV[1] different after unpacking", llpsysdata.mPartAccel.mV[1], 0.f, 7);
|
||||
ensure_approximately_equals("mPartAccel.mV[2] different after unpacking", llpsysdata.mPartAccel.mV[2], 0.f, 7);
|
||||
|
||||
//mPartData
|
||||
LLPartData& data = llpsysdata.mPartData;
|
||||
|
||||
//mFlags 132354 unsigned int
|
||||
ensure ("mPartData.mFlags different after unpacking", data.mFlags == (U32) 132354);
|
||||
//mMaxAge 10.000000 float
|
||||
ensure_approximately_equals("mPartData.mMaxAge different after unpacking", data.mMaxAge, 10.f, 8);
|
||||
//mStartColor <1,1,1,1>
|
||||
ensure_approximately_equals("mPartData.mStartColor.mV[0] different after unpacking", data.mStartColor.mV[0], 1.f, 8);
|
||||
ensure_approximately_equals("mPartData.mStartColor.mV[1] different after unpacking", data.mStartColor.mV[1], 1.f, 8);
|
||||
ensure_approximately_equals("mPartData.mStartColor.mV[2] different after unpacking", data.mStartColor.mV[2], 1.f, 8);
|
||||
ensure_approximately_equals("mPartData.mStartColor.mV[3] different after unpacking", data.mStartColor.mV[3], 1.f, 8);
|
||||
//mEndColor <1,1,0,0>
|
||||
ensure_approximately_equals("mPartData.mEndColor.mV[0] different after unpacking", data.mEndColor.mV[0], 1.f, 8);
|
||||
ensure_approximately_equals("mPartData.mEndColor.mV[1] different after unpacking", data.mEndColor.mV[1], 1.f, 8);
|
||||
ensure_approximately_equals("mPartData.mEndColor.mV[2] different after unpacking", data.mEndColor.mV[2], 0.f, 8);
|
||||
ensure_approximately_equals("mPartData.mEndColor.mV[3] different after unpacking", data.mEndColor.mV[3], 0.f, 8);
|
||||
//mStartScale <1,1>
|
||||
ensure_approximately_equals("mPartData.mStartScale.mV[0] different after unpacking", data.mStartScale.mV[0], 1.f, 8);
|
||||
ensure_approximately_equals("mPartData.mStartScale.mV[1] different after unpacking", data.mStartScale.mV[1], 1.f, 8);
|
||||
//mEndScale <0,0>
|
||||
ensure_approximately_equals("mPartData.mEndScale.mV[0] different after unpacking", data.mEndScale.mV[0], 0.f, 8);
|
||||
ensure_approximately_equals("mPartData.mEndScale.mV[1] different after unpacking", data.mEndScale.mV[1], 0.f, 8);
|
||||
//mPosOffset <0,0,0>
|
||||
ensure_approximately_equals("mPartData.mPosOffset.mV[0] different after unpacking", data.mPosOffset.mV[0], 0.f, 8);
|
||||
ensure_approximately_equals("mPartData.mPosOffset.mV[1] different after unpacking", data.mPosOffset.mV[1], 0.f, 8);
|
||||
ensure_approximately_equals("mPartData.mPosOffset.mV[2] different after unpacking", data.mPosOffset.mV[2], 0.f, 8);
|
||||
//mParameter 0.00000000 float
|
||||
ensure_approximately_equals("mPartData.mParameter different after unpacking", data.mParameter, 0.f, 8);
|
||||
|
||||
LLDataPackerBinaryBuffer dp1((U8*)pkbuf, cur_size);
|
||||
llpdata1.unpack(dp1);
|
||||
|
||||
ensure("1.mFlags values are different after unpacking", llpdata1.mFlags == llpdata.mFlags);
|
||||
ensure_approximately_equals("2.mMaxAge values are different after unpacking", llpdata1.mMaxAge, llpdata.mMaxAge, 8);
|
||||
|
||||
ensure_approximately_equals("3.mStartColor[0] values are different after unpacking", llpdata1.mStartColor.mV[0], llpdata.mStartColor.mV[0], 8);
|
||||
ensure_approximately_equals("4.mStartColor[1] values are different after unpacking", llpdata1.mStartColor.mV[1], llpdata.mStartColor.mV[1], 8);
|
||||
ensure_approximately_equals("5.mStartColor[2] values are different after unpacking", llpdata1.mStartColor.mV[2], llpdata.mStartColor.mV[2], 8);
|
||||
ensure_approximately_equals("6.mStartColor[3] values are different after unpacking", llpdata1.mStartColor.mV[3], llpdata.mStartColor.mV[3], 8);
|
||||
|
||||
ensure_approximately_equals("7.mEndColor[0] values are different after unpacking", llpdata1.mEndColor.mV[0], llpdata.mEndColor.mV[0], 8);
|
||||
ensure_approximately_equals("8.mEndColor[1] values are different after unpacking", llpdata1.mEndColor.mV[1], llpdata.mEndColor.mV[1], 8);
|
||||
ensure_approximately_equals("9.mEndColor[2] values are different after unpacking", llpdata1.mEndColor.mV[2], llpdata.mEndColor.mV[2], 8);
|
||||
ensure_approximately_equals("10.mEndColor[2] values are different after unpacking", llpdata1.mEndColor.mV[3], llpdata.mEndColor.mV[3], 8);
|
||||
|
||||
ensure_approximately_equals("11.mStartScale[0] values are different after unpacking", llpdata1.mStartScale.mV[0], llpdata.mStartScale.mV[0], 5);
|
||||
ensure_approximately_equals("12.mStartScale[1] values are different after unpacking", llpdata1.mStartScale.mV[1], llpdata.mStartScale.mV[1], 5);
|
||||
|
||||
ensure_approximately_equals("13.mEndScale[0] values are different after unpacking", llpdata1.mEndScale.mV[0], llpdata.mEndScale.mV[0], 5);
|
||||
ensure_approximately_equals("14.mEndScale[1] values are different after unpacking", llpdata1.mEndScale.mV[1], llpdata.mEndScale.mV[1], 5);
|
||||
}
|
||||
|
||||
|
||||
template<> template<>
|
||||
void partdata_test_object_t::test<2>()
|
||||
{
|
||||
LLPartData llpdata,llpdata1;
|
||||
|
||||
llpdata.setFlags(LLPartData::LL_PART_INTERP_COLOR_MASK | LLPartData::LL_PART_INTERP_SCALE_MASK |
|
||||
LLPartData::LL_PART_BOUNCE_MASK | LLPartData::LL_PART_WIND_MASK | LLPartData::LL_PART_FOLLOW_SRC_MASK |
|
||||
LLPartData::LL_PART_FOLLOW_VELOCITY_MASK | LLPartData::LL_PART_TARGET_POS_MASK | LLPartData::LL_PART_TARGET_LINEAR_MASK |
|
||||
LLPartData::LL_PART_EMISSIVE_MASK | LLPartData::LL_PART_BEAM_MASK | LLPartData::LL_PART_DEAD_MASK);
|
||||
|
||||
llpdata.setMaxAge(29.3f);
|
||||
|
||||
LLVector3 llvec1(1.0f, .5f, .25f);
|
||||
llpdata.setStartColor(llvec1);
|
||||
llpdata.setStartAlpha(.7f);
|
||||
|
||||
LLVector3 llvec2(.2f, .3f, 1.0f);
|
||||
llpdata.setEndColor(llvec2);
|
||||
llpdata.setEndAlpha(1.0f);
|
||||
|
||||
llpdata.setStartScale(3.23f, 4.0f);
|
||||
llpdata.setEndScale(2.4678f, 1.0f);
|
||||
|
||||
LLSD llsd = llpdata.asLLSD();
|
||||
|
||||
llpdata1.fromLLSD(llsd);
|
||||
|
||||
ensure("1.mFlags values are different after unpacking", llpdata1.mFlags == llpdata.mFlags);
|
||||
ensure_approximately_equals("2.mMaxAge values are different after unpacking", llpdata1.mMaxAge, llpdata.mMaxAge, 8);
|
||||
|
||||
ensure_approximately_equals("3.mStartColor[0] values are different after unpacking", llpdata1.mStartColor.mV[0], llpdata.mStartColor.mV[0], 8);
|
||||
ensure_approximately_equals("4.mStartColor[1] values are different after unpacking", llpdata1.mStartColor.mV[1], llpdata.mStartColor.mV[1], 8);
|
||||
ensure_approximately_equals("5.mStartColor[2] values are different after unpacking", llpdata1.mStartColor.mV[2], llpdata.mStartColor.mV[2], 8);
|
||||
ensure_approximately_equals("6.mStartColor[3] values are different after unpacking", llpdata1.mStartColor.mV[3], llpdata.mStartColor.mV[3], 8);
|
||||
|
||||
ensure_approximately_equals("7.mEndColor[0] values are different after unpacking", llpdata1.mEndColor.mV[0], llpdata.mEndColor.mV[0], 8);
|
||||
ensure_approximately_equals("8.mEndColor[1] values are different after unpacking", llpdata1.mEndColor.mV[1], llpdata.mEndColor.mV[1], 8);
|
||||
ensure_approximately_equals("9.mEndColor[2] values are different after unpacking", llpdata1.mEndColor.mV[2], llpdata.mEndColor.mV[2], 8);
|
||||
ensure_approximately_equals("10.mEndColor[2] values are different after unpacking", llpdata1.mEndColor.mV[3], llpdata.mEndColor.mV[3], 8);
|
||||
|
||||
ensure_approximately_equals("11.mStartScale[0] values are different after unpacking", llpdata1.mStartScale.mV[0], llpdata.mStartScale.mV[0], 5);
|
||||
ensure_approximately_equals("12.mStartScale[1] values are different after unpacking", llpdata1.mStartScale.mV[1], llpdata.mStartScale.mV[1], 5);
|
||||
|
||||
ensure_approximately_equals("13.mEndScale[0] values are different after unpacking", llpdata1.mEndScale.mV[0], llpdata.mEndScale.mV[0], 5);
|
||||
ensure_approximately_equals("14.mEndScale[1] values are different after unpacking", llpdata1.mEndScale.mV[1], llpdata.mEndScale.mV[1], 5);
|
||||
}
|
||||
|
||||
|
||||
//*********llpartsysdata***********
|
||||
|
||||
template<> template<>
|
||||
void partdata_test_object_t::test<3>()
|
||||
{
|
||||
LLPartSysData llpsysdata, llpsysdata1;
|
||||
U8 pkbuf[256];
|
||||
llpsysdata.setBurstSpeedMin(33.33f);
|
||||
ensure("1.mBurstSpeedMin coudnt be set", 33.33f == llpsysdata.mBurstSpeedMin);
|
||||
|
||||
llpsysdata.setBurstSpeedMax(44.44f);
|
||||
ensure("2.mBurstSpeedMax coudnt be set", 44.44f == llpsysdata.mBurstSpeedMax);
|
||||
|
||||
llpsysdata.setBurstRadius(45.55f);
|
||||
ensure("3.mBurstRadius coudnt be set", 45.55f == llpsysdata.mBurstRadius);
|
||||
|
||||
LLVector3 llvec(44.44f, 111.11f, -40.4f);
|
||||
llpsysdata.setPartAccel(llvec);
|
||||
|
||||
llpsysdata.mCRC = 0xFFFFFFFF;
|
||||
llpsysdata.mFlags = 0x20;
|
||||
|
||||
llpsysdata.mPattern = LLPartSysData::LL_PART_SRC_PATTERN_ANGLE_CONE_EMPTY;
|
||||
|
||||
llpsysdata.mMaxAge = 99.99f;
|
||||
llpsysdata.mStartAge = 18.5f;
|
||||
llpsysdata.mInnerAngle = 4.234f;
|
||||
llpsysdata.mOuterAngle = 7.123f;
|
||||
llpsysdata.mBurstRate = 245.53f;
|
||||
llpsysdata.mBurstPartCount = 0xFF;
|
||||
llpsysdata.mAngularVelocity = llvec;
|
||||
|
||||
llpsysdata.mPartImageID.generate();
|
||||
llpsysdata.mTargetUUID.generate();
|
||||
|
||||
LLDataPackerBinaryBuffer dp((U8*)pkbuf, 256);
|
||||
llpsysdata.pack(dp);
|
||||
S32 cur_size = dp.getCurrentSize();
|
||||
LLDataPackerBinaryBuffer dp1((U8*)pkbuf, cur_size);
|
||||
llpsysdata1.unpack(dp1);
|
||||
|
||||
ensure("1.mCRC's not equal", llpsysdata.mCRC == llpsysdata1.mCRC);
|
||||
ensure("2.mFlags's not equal", llpsysdata.mFlags == llpsysdata1.mFlags);
|
||||
ensure("3.mPattern's not equal", llpsysdata.mPattern == llpsysdata1.mPattern);
|
||||
ensure_approximately_equals("4.mMaxAge's not equal", llpsysdata.mMaxAge , llpsysdata1.mMaxAge, 8);
|
||||
ensure_approximately_equals("5.mStartAge's not equal", llpsysdata.mStartAge, llpsysdata1.mStartAge, 8);
|
||||
ensure_approximately_equals("6.mOuterAngle's not equal", llpsysdata.mOuterAngle, llpsysdata1.mOuterAngle, 5);
|
||||
ensure_approximately_equals("7.mInnerAngles's not equal", llpsysdata.mInnerAngle, llpsysdata1.mInnerAngle, 5);
|
||||
ensure_approximately_equals("8.mBurstRate's not equal", llpsysdata.mBurstRate, llpsysdata1.mBurstRate, 8);
|
||||
ensure("9.mBurstPartCount's not equal", llpsysdata.mBurstPartCount == llpsysdata1.mBurstPartCount);
|
||||
|
||||
ensure_approximately_equals("10.mBurstSpeedMin's not equal", llpsysdata.mBurstSpeedMin, llpsysdata1.mBurstSpeedMin, 8);
|
||||
ensure_approximately_equals("11.mBurstSpeedMax's not equal", llpsysdata.mBurstSpeedMax, llpsysdata1.mBurstSpeedMax, 8);
|
||||
|
||||
ensure_approximately_equals("12.mAngularVelocity's not equal", llpsysdata.mAngularVelocity.mV[0], llpsysdata1.mAngularVelocity.mV[0], 7);
|
||||
ensure_approximately_equals("13.mAngularVelocity's not equal", llpsysdata.mAngularVelocity.mV[1], llpsysdata1.mAngularVelocity.mV[1], 7);
|
||||
ensure_approximately_equals("14.mAngularVelocity's not equal", llpsysdata.mAngularVelocity.mV[2], llpsysdata1.mAngularVelocity.mV[2], 7);
|
||||
|
||||
ensure_approximately_equals("15.mPartAccel's not equal", llpsysdata.mPartAccel.mV[0], llpsysdata1.mPartAccel.mV[0], 7);
|
||||
ensure_approximately_equals("16.mPartAccel's not equal", llpsysdata.mPartAccel.mV[1], llpsysdata1.mPartAccel.mV[1], 7);
|
||||
ensure_approximately_equals("17.mPartAccel's not equal", llpsysdata.mPartAccel.mV[2], llpsysdata1.mPartAccel.mV[2], 7);
|
||||
|
||||
ensure("18.mPartImageID's not equal", llpsysdata.mPartImageID == llpsysdata1.mPartImageID);
|
||||
ensure("19.mTargetUUID's not equal", llpsysdata.mTargetUUID == llpsysdata1.mTargetUUID);
|
||||
ensure_approximately_equals("20.mBurstRadius's not equal", llpsysdata.mBurstRadius, llpsysdata1.mBurstRadius, 8);
|
||||
//mStartGlow 0.00000000 float
|
||||
ensure_approximately_equals("mPartData.mStartGlow different after unpacking", data.mStartGlow, 0.f, 8);
|
||||
//mEndGlow 0.00000000 float
|
||||
ensure_approximately_equals("mPartData.mEndGlow different after unpacking", data.mEndGlow, 0.f, 8);
|
||||
//mBlendFuncSource 2 '' unsigned char
|
||||
ensure("mPartData.mBlendFuncSource different after unpacking", data.mBlendFuncSource == (U8) 2);
|
||||
//mBlendFuncDest 1 '' unsigned char
|
||||
ensure("mPartData.mBlendFuncDest different after unpacking", data.mBlendFuncDest == (U8) 1);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -50,10 +50,17 @@ add_executable(SLPlugin
|
|||
${SLPlugin_SOURCE_FILES}
|
||||
)
|
||||
|
||||
if (WINDOWS)
|
||||
set_target_properties(SLPlugin
|
||||
PROPERTIES
|
||||
LINK_FLAGS_DEBUG "/NODEFAULTLIB:\"LIBCMTD\""
|
||||
)
|
||||
else ()
|
||||
set_target_properties(SLPlugin
|
||||
PROPERTIES
|
||||
MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/slplugin_info.plist
|
||||
)
|
||||
endif ()
|
||||
|
||||
target_link_libraries(SLPlugin
|
||||
${LLPLUGIN_LIBRARIES}
|
||||
|
|
|
|||
|
|
@ -166,6 +166,7 @@ LLModel::EModelStatus load_face_from_dom_triangles(std::vector<LLVolumeFace>& fa
|
|||
|
||||
if ( !get_dom_sources(inputs, pos_offset, tc_offset, norm_offset, idx_stride, pos_source, tc_source, norm_source) || !pos_source )
|
||||
{
|
||||
llwarns << "Could not find dom sources for basic geo data; invalid model." << llendl;
|
||||
return LLModel::BAD_ELEMENT;
|
||||
}
|
||||
|
||||
|
|
@ -186,27 +187,78 @@ LLModel::EModelStatus load_face_from_dom_triangles(std::vector<LLVolumeFace>& fa
|
|||
|
||||
LLVolumeFace::VertexMapData::PointMap point_map;
|
||||
|
||||
for (U32 i = 0; i < idx.getCount(); i += idx_stride)
|
||||
U32 index_count = idx.getCount();
|
||||
U32 vertex_count = pos_source ? v.getCount() : 0;
|
||||
U32 tc_count = tc_source ? tc.getCount() : 0;
|
||||
U32 norm_count = norm_source ? n.getCount() : 0;
|
||||
|
||||
for (U32 i = 0; i < index_count; i += idx_stride)
|
||||
{
|
||||
LLVolumeFace::VertexData cv;
|
||||
if (pos_source)
|
||||
{
|
||||
// guard against model data specifiying out of range indices or verts
|
||||
//
|
||||
if (((i + pos_offset) > index_count)
|
||||
|| ((idx[i+pos_offset]*3+2) > vertex_count))
|
||||
{
|
||||
llwarns << "Out of range index data; invalid model." << llendl;
|
||||
return LLModel::BAD_ELEMENT;
|
||||
}
|
||||
|
||||
cv.setPosition(LLVector4a(v[idx[i+pos_offset]*3+0],
|
||||
v[idx[i+pos_offset]*3+1],
|
||||
v[idx[i+pos_offset]*3+2]));
|
||||
|
||||
if (!cv.getPosition().isFinite3())
|
||||
{
|
||||
llwarns << "Nan positional data, invalid model." << llendl;
|
||||
return LLModel::BAD_ELEMENT;
|
||||
}
|
||||
}
|
||||
|
||||
if (tc_source)
|
||||
{
|
||||
// guard against model data specifiying out of range indices or tcs
|
||||
//
|
||||
|
||||
if (((i + tc_offset) > index_count)
|
||||
|| ((idx[i+tc_offset]*2+1) > tc_count))
|
||||
{
|
||||
llwarns << "Out of range TC indices." << llendl;
|
||||
return LLModel::BAD_ELEMENT;
|
||||
}
|
||||
|
||||
cv.mTexCoord.setVec(tc[idx[i+tc_offset]*2+0],
|
||||
tc[idx[i+tc_offset]*2+1]);
|
||||
|
||||
if (!cv.mTexCoord.isFinite())
|
||||
{
|
||||
llwarns << "Found NaN while loading tex coords from DAE-Model, invalid model." << llendl;
|
||||
return LLModel::BAD_ELEMENT;
|
||||
}
|
||||
}
|
||||
|
||||
if (norm_source)
|
||||
{
|
||||
// guard against model data specifiying out of range indices or norms
|
||||
//
|
||||
if (((i + norm_offset) > index_count)
|
||||
|| ((idx[i+norm_offset]*3+2) > norm_count))
|
||||
{
|
||||
llwarns << "Found out of range norm indices, invalid model." << llendl;
|
||||
return LLModel::BAD_ELEMENT;
|
||||
}
|
||||
|
||||
cv.setNormal(LLVector4a(n[idx[i+norm_offset]*3+0],
|
||||
n[idx[i+norm_offset]*3+1],
|
||||
n[idx[i+norm_offset]*3+2]));
|
||||
|
||||
if (!cv.getNormal().isFinite3())
|
||||
{
|
||||
llwarns << "Found NaN while loading normals from DAE-Model, invalid model." << llendl;
|
||||
return LLModel::BAD_ELEMENT;
|
||||
}
|
||||
}
|
||||
|
||||
BOOL found = FALSE;
|
||||
|
|
@ -261,13 +313,13 @@ LLModel::EModelStatus load_face_from_dom_triangles(std::vector<LLVolumeFace>& fa
|
|||
LLVolumeFace& new_face = *face_list.rbegin();
|
||||
if (!norm_source)
|
||||
{
|
||||
ll_aligned_free_16(new_face.mNormals);
|
||||
//ll_aligned_free_16(new_face.mNormals);
|
||||
new_face.mNormals = NULL;
|
||||
}
|
||||
|
||||
if (!tc_source)
|
||||
{
|
||||
ll_aligned_free_16(new_face.mTexCoords);
|
||||
//ll_aligned_free_16(new_face.mTexCoords);
|
||||
new_face.mTexCoords = NULL;
|
||||
}
|
||||
|
||||
|
|
@ -292,13 +344,13 @@ LLModel::EModelStatus load_face_from_dom_triangles(std::vector<LLVolumeFace>& fa
|
|||
LLVolumeFace& new_face = *face_list.rbegin();
|
||||
if (!norm_source)
|
||||
{
|
||||
ll_aligned_free_16(new_face.mNormals);
|
||||
//ll_aligned_free_16(new_face.mNormals);
|
||||
new_face.mNormals = NULL;
|
||||
}
|
||||
|
||||
if (!tc_source)
|
||||
{
|
||||
ll_aligned_free_16(new_face.mTexCoords);
|
||||
//ll_aligned_free_16(new_face.mTexCoords);
|
||||
new_face.mTexCoords = NULL;
|
||||
}
|
||||
}
|
||||
|
|
@ -333,6 +385,7 @@ LLModel::EModelStatus load_face_from_dom_polylist(std::vector<LLVolumeFace>& fac
|
|||
|
||||
if (!get_dom_sources(inputs, pos_offset, tc_offset, norm_offset, idx_stride, pos_source, tc_source, norm_source))
|
||||
{
|
||||
llwarns << "Could not get DOM sources for basic geo data, invalid model." << llendl;
|
||||
return LLModel::BAD_ELEMENT;
|
||||
}
|
||||
|
||||
|
|
@ -364,6 +417,11 @@ LLModel::EModelStatus load_face_from_dom_polylist(std::vector<LLVolumeFace>& fac
|
|||
|
||||
LLVolumeFace::VertexMapData::PointMap point_map;
|
||||
|
||||
U32 index_count = idx.getCount();
|
||||
U32 vertex_count = pos_source ? v.getCount() : 0;
|
||||
U32 tc_count = tc_source ? tc.getCount() : 0;
|
||||
U32 norm_count = norm_source ? n.getCount() : 0;
|
||||
|
||||
U32 cur_idx = 0;
|
||||
for (U32 i = 0; i < vcount.getCount(); ++i)
|
||||
{ //for each polygon
|
||||
|
|
@ -376,22 +434,68 @@ LLModel::EModelStatus load_face_from_dom_polylist(std::vector<LLVolumeFace>& fac
|
|||
|
||||
if (pos_source)
|
||||
{
|
||||
// guard against model data specifiying out of range indices or verts
|
||||
//
|
||||
if (((cur_idx + pos_offset) > index_count)
|
||||
|| ((idx[cur_idx+pos_offset]*3+2) > vertex_count))
|
||||
{
|
||||
llwarns << "Out of range position indices, invalid model." << llendl;
|
||||
return LLModel::BAD_ELEMENT;
|
||||
}
|
||||
|
||||
cv.getPosition().set(v[idx[cur_idx+pos_offset]*3+0],
|
||||
v[idx[cur_idx+pos_offset]*3+1],
|
||||
v[idx[cur_idx+pos_offset]*3+2]);
|
||||
|
||||
if (!cv.getPosition().isFinite3())
|
||||
{
|
||||
llwarns << "Found NaN while loading positions from DAE-Model, invalid model." << llendl;
|
||||
return LLModel::BAD_ELEMENT;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (tc_source)
|
||||
{
|
||||
// guard against model data specifiying out of range indices or tcs
|
||||
//
|
||||
if (((cur_idx + tc_offset) > index_count)
|
||||
|| ((idx[cur_idx+tc_offset]*2+1) > tc_count))
|
||||
{
|
||||
llwarns << "Out of range TC indices, invalid model." << llendl;
|
||||
return LLModel::BAD_ELEMENT;
|
||||
}
|
||||
|
||||
cv.mTexCoord.setVec(tc[idx[cur_idx+tc_offset]*2+0],
|
||||
tc[idx[cur_idx+tc_offset]*2+1]);
|
||||
|
||||
if (!cv.mTexCoord.isFinite())
|
||||
{
|
||||
llwarns << "Found NaN while loading tex coords from DAE-Model, invalid model." << llendl;
|
||||
return LLModel::BAD_ELEMENT;
|
||||
}
|
||||
}
|
||||
|
||||
if (norm_source)
|
||||
{
|
||||
// guard against model data specifiying out of range indices or norms
|
||||
//
|
||||
if (((cur_idx + norm_offset) > index_count)
|
||||
|| ((idx[cur_idx+norm_offset]*3+2) > norm_count))
|
||||
{
|
||||
llwarns << "Out of range norm indices, invalid model." << llendl;
|
||||
return LLModel::BAD_ELEMENT;
|
||||
}
|
||||
|
||||
cv.getNormal().set(n[idx[cur_idx+norm_offset]*3+0],
|
||||
n[idx[cur_idx+norm_offset]*3+1],
|
||||
n[idx[cur_idx+norm_offset]*3+2]);
|
||||
|
||||
if (!cv.getNormal().isFinite3())
|
||||
{
|
||||
llwarns << "Found NaN while loading normals from DAE-Model, invalid model." << llendl;
|
||||
return LLModel::BAD_ELEMENT;
|
||||
}
|
||||
}
|
||||
|
||||
cur_idx += idx_stride;
|
||||
|
|
@ -480,13 +584,13 @@ LLModel::EModelStatus load_face_from_dom_polylist(std::vector<LLVolumeFace>& fac
|
|||
LLVolumeFace& new_face = *face_list.rbegin();
|
||||
if (!norm_source)
|
||||
{
|
||||
ll_aligned_free_16(new_face.mNormals);
|
||||
//ll_aligned_free_16(new_face.mNormals);
|
||||
new_face.mNormals = NULL;
|
||||
}
|
||||
|
||||
if (!tc_source)
|
||||
{
|
||||
ll_aligned_free_16(new_face.mTexCoords);
|
||||
//ll_aligned_free_16(new_face.mTexCoords);
|
||||
new_face.mTexCoords = NULL;
|
||||
}
|
||||
|
||||
|
|
@ -514,13 +618,13 @@ LLModel::EModelStatus load_face_from_dom_polylist(std::vector<LLVolumeFace>& fac
|
|||
LLVolumeFace& new_face = *face_list.rbegin();
|
||||
if (!norm_source)
|
||||
{
|
||||
ll_aligned_free_16(new_face.mNormals);
|
||||
//ll_aligned_free_16(new_face.mNormals);
|
||||
new_face.mNormals = NULL;
|
||||
}
|
||||
|
||||
if (!tc_source)
|
||||
{
|
||||
ll_aligned_free_16(new_face.mTexCoords);
|
||||
//ll_aligned_free_16(new_face.mTexCoords);
|
||||
new_face.mTexCoords = NULL;
|
||||
}
|
||||
}
|
||||
|
|
@ -558,6 +662,7 @@ LLModel::EModelStatus load_face_from_dom_polygons(std::vector<LLVolumeFace>& fac
|
|||
domVertices* vertices = (domVertices*) elem.cast();
|
||||
if (!vertices)
|
||||
{
|
||||
llwarns << "Could not find vertex source, invalid model." << llendl;
|
||||
return LLModel::BAD_ELEMENT;
|
||||
}
|
||||
domInputLocal_Array& v_inp = vertices->getInput_array();
|
||||
|
|
@ -571,6 +676,7 @@ LLModel::EModelStatus load_face_from_dom_polygons(std::vector<LLVolumeFace>& fac
|
|||
domSource* src = (domSource*) elem.cast();
|
||||
if (!src)
|
||||
{
|
||||
llwarns << "Could not find DOM source, invalid model." << llendl;
|
||||
return LLModel::BAD_ELEMENT;
|
||||
}
|
||||
v = &(src->getFloat_array()->getValue());
|
||||
|
|
@ -586,6 +692,7 @@ LLModel::EModelStatus load_face_from_dom_polygons(std::vector<LLVolumeFace>& fac
|
|||
domSource* src = (domSource*) elem.cast();
|
||||
if (!src)
|
||||
{
|
||||
llwarns << "Could not find DOM source, invalid model." << llendl;
|
||||
return LLModel::BAD_ELEMENT;
|
||||
}
|
||||
n = &(src->getFloat_array()->getValue());
|
||||
|
|
@ -598,6 +705,7 @@ LLModel::EModelStatus load_face_from_dom_polygons(std::vector<LLVolumeFace>& fac
|
|||
domSource* src = (domSource*) elem.cast();
|
||||
if (!src)
|
||||
{
|
||||
llwarns << "Could not find DOM source, invalid model." << llendl;
|
||||
return LLModel::BAD_ELEMENT;
|
||||
}
|
||||
t = &(src->getFloat_array()->getValue());
|
||||
|
|
@ -632,6 +740,12 @@ LLModel::EModelStatus load_face_from_dom_polygons(std::vector<LLVolumeFace>& fac
|
|||
vert.getPosition().set(v->get(v_idx),
|
||||
v->get(v_idx+1),
|
||||
v->get(v_idx+2));
|
||||
|
||||
if (!vert.getPosition().isFinite3())
|
||||
{
|
||||
llwarns << "Found NaN while loading position data from DAE-Model, invalid model." << llendl;
|
||||
return LLModel::BAD_ELEMENT;
|
||||
}
|
||||
}
|
||||
|
||||
//bounds check n and t lookups because some FBX to DAE converters
|
||||
|
|
@ -644,6 +758,12 @@ LLModel::EModelStatus load_face_from_dom_polygons(std::vector<LLVolumeFace>& fac
|
|||
vert.getNormal().set(n->get(n_idx),
|
||||
n->get(n_idx+1),
|
||||
n->get(n_idx+2));
|
||||
|
||||
if (!vert.getNormal().isFinite3())
|
||||
{
|
||||
llwarns << "Found NaN while loading normals from DAE-Model, invalid model." << llendl;
|
||||
return LLModel::BAD_ELEMENT;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -657,6 +777,12 @@ LLModel::EModelStatus load_face_from_dom_polygons(std::vector<LLVolumeFace>& fac
|
|||
t_idx = llclamp(t_idx, (U32) 0, (U32) t->getCount());
|
||||
vert.mTexCoord.setVec(t->get(t_idx),
|
||||
t->get(t_idx+1));
|
||||
|
||||
if (!vert.mTexCoord.isFinite())
|
||||
{
|
||||
llwarns << "Found NaN while loading tex coords from DAE-Model, invalid model." << llendl;
|
||||
return LLModel::BAD_ELEMENT;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -730,13 +856,13 @@ LLModel::EModelStatus load_face_from_dom_polygons(std::vector<LLVolumeFace>& fac
|
|||
LLVolumeFace& new_face = *face_list.rbegin();
|
||||
if (!n)
|
||||
{
|
||||
ll_aligned_free_16(new_face.mNormals);
|
||||
//ll_aligned_free_16(new_face.mNormals);
|
||||
new_face.mNormals = NULL;
|
||||
}
|
||||
|
||||
if (!t)
|
||||
{
|
||||
ll_aligned_free_16(new_face.mTexCoords);
|
||||
//ll_aligned_free_16(new_face.mTexCoords);
|
||||
new_face.mTexCoords = NULL;
|
||||
}
|
||||
}
|
||||
|
|
@ -1010,6 +1136,43 @@ void LLModel::getNormalizedScaleTranslation(LLVector3& scale_out, LLVector3& tra
|
|||
translation_out = mNormalizedTranslation;
|
||||
}
|
||||
|
||||
LLVector3 LLModel::getTransformedCenter(const LLMatrix4& mat)
|
||||
{
|
||||
LLVector3 ret;
|
||||
|
||||
if (!mVolumeFaces.empty())
|
||||
{
|
||||
LLMatrix4a m;
|
||||
m.loadu(mat);
|
||||
|
||||
LLVector4a minv,maxv;
|
||||
|
||||
LLVector4a t;
|
||||
m.affineTransform(mVolumeFaces[0].mPositions[0], t);
|
||||
minv = maxv = t;
|
||||
|
||||
for (S32 i = 0; i < mVolumeFaces.size(); ++i)
|
||||
{
|
||||
LLVolumeFace& face = mVolumeFaces[i];
|
||||
|
||||
for (U32 j = 0; j < face.mNumVertices; ++j)
|
||||
{
|
||||
m.affineTransform(face.mPositions[j],t);
|
||||
update_min_max(minv, maxv, t);
|
||||
}
|
||||
}
|
||||
|
||||
minv.add(maxv);
|
||||
minv.mul(0.5f);
|
||||
|
||||
ret.set(minv.getF32ptr());
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void LLModel::setNumVolumeFaces(S32 count)
|
||||
{
|
||||
mVolumeFaces.resize(count);
|
||||
|
|
@ -1036,7 +1199,7 @@ void LLModel::setVolumeFaceData(
|
|||
}
|
||||
else
|
||||
{
|
||||
ll_aligned_free_16(face.mNormals);
|
||||
//ll_aligned_free_16(face.mNormals);
|
||||
face.mNormals = NULL;
|
||||
}
|
||||
|
||||
|
|
@ -1047,7 +1210,7 @@ void LLModel::setVolumeFaceData(
|
|||
}
|
||||
else
|
||||
{
|
||||
ll_aligned_free_16(face.mTexCoords);
|
||||
//ll_aligned_free_16(face.mTexCoords);
|
||||
face.mTexCoords = NULL;
|
||||
}
|
||||
|
||||
|
|
@ -1246,7 +1409,7 @@ void LLModel::generateNormals(F32 angle_cutoff)
|
|||
}
|
||||
else
|
||||
{
|
||||
ll_aligned_free_16(new_face.mTexCoords);
|
||||
//ll_aligned_free_16(new_face.mTexCoords);
|
||||
new_face.mTexCoords = NULL;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -173,13 +173,15 @@ public:
|
|||
void optimizeVolumeFaces();
|
||||
void offsetMesh( const LLVector3& pivotPoint );
|
||||
void getNormalizedScaleTranslation(LLVector3& scale_out, LLVector3& translation_out);
|
||||
|
||||
LLVector3 getTransformedCenter(const LLMatrix4& mat);
|
||||
|
||||
//reorder face list based on mMaterialList in this and reference so
|
||||
//order matches that of reference (material ordering touchup)
|
||||
bool matchMaterialOrder(LLModel* ref, int& refFaceCnt, int& modelFaceCnt );
|
||||
bool isMaterialListSubset( LLModel* ref );
|
||||
bool needToAddFaces( LLModel* ref, int& refFaceCnt, int& modelFaceCnt );
|
||||
|
||||
|
||||
std::vector<std::string> mMaterialList;
|
||||
|
||||
//data used for skin weights
|
||||
|
|
|
|||
|
|
@ -59,6 +59,7 @@ BOOL gDebugGL = FALSE;
|
|||
BOOL gClothRipple = FALSE;
|
||||
BOOL gHeadlessClient = FALSE;
|
||||
BOOL gGLActive = FALSE;
|
||||
BOOL gGLDebugLoggingEnabled = TRUE;
|
||||
|
||||
static const std::string HEADLESS_VENDOR_STRING("Linden Lab");
|
||||
static const std::string HEADLESS_RENDERER_STRING("Headless");
|
||||
|
|
@ -80,6 +81,8 @@ void APIENTRY gl_debug_callback(GLenum source,
|
|||
const GLchar* message,
|
||||
GLvoid* userParam)
|
||||
{
|
||||
if (gGLDebugLoggingEnabled)
|
||||
{
|
||||
if (severity == GL_DEBUG_SEVERITY_HIGH_ARB)
|
||||
{
|
||||
llwarns << "----- GL ERROR --------" << llendl;
|
||||
|
|
@ -98,6 +101,7 @@ void APIENTRY gl_debug_callback(GLenum source,
|
|||
llerrs << "Halting on GL Error" << llendl;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void parse_glsl_version(S32& major, S32& minor);
|
||||
|
|
@ -258,6 +262,7 @@ PFNGLBEGINTRANSFORMFEEDBACKPROC glBeginTransformFeedback = NULL;
|
|||
PFNGLENDTRANSFORMFEEDBACKPROC glEndTransformFeedback = NULL;
|
||||
PFNGLTRANSFORMFEEDBACKVARYINGSPROC glTransformFeedbackVaryings = NULL;
|
||||
PFNGLBINDBUFFERRANGEPROC glBindBufferRange = NULL;
|
||||
PFNGLBINDBUFFERBASEPROC glBindBufferBase = NULL;
|
||||
|
||||
//GL_ARB_debug_output
|
||||
PFNGLDEBUGMESSAGECONTROLARBPROC glDebugMessageControlARB = NULL;
|
||||
|
|
@ -1156,7 +1161,7 @@ void LLGLManager::initExtensions()
|
|||
glGetIntegerv(GL_MAX_ELEMENTS_VERTICES, (GLint*) &mGLMaxVertexRange);
|
||||
glGetIntegerv(GL_MAX_ELEMENTS_INDICES, (GLint*) &mGLMaxIndexRange);
|
||||
glGetIntegerv(GL_MAX_TEXTURE_SIZE, (GLint*) &mGLMaxTextureSize);
|
||||
|
||||
|
||||
#if (LL_WINDOWS || LL_LINUX || LL_SOLARIS) && !LL_MESA_HEADLESS
|
||||
LL_DEBUGS("RenderInit") << "GL Probe: Getting symbols" << LL_ENDL;
|
||||
if (mHasVertexBufferObject)
|
||||
|
|
@ -1247,6 +1252,7 @@ void LLGLManager::initExtensions()
|
|||
glEndTransformFeedback = (PFNGLENDTRANSFORMFEEDBACKPROC) GLH_EXT_GET_PROC_ADDRESS("glEndTransformFeedback");
|
||||
glTransformFeedbackVaryings = (PFNGLTRANSFORMFEEDBACKVARYINGSPROC) GLH_EXT_GET_PROC_ADDRESS("glTransformFeedbackVaryings");
|
||||
glBindBufferRange = (PFNGLBINDBUFFERRANGEPROC) GLH_EXT_GET_PROC_ADDRESS("glBindBufferRange");
|
||||
glBindBufferBase = (PFNGLBINDBUFFERBASEPROC) GLH_EXT_GET_PROC_ADDRESS("glBindBufferBase");
|
||||
}
|
||||
if (mHasDebugOutput)
|
||||
{
|
||||
|
|
@ -1501,7 +1507,7 @@ void do_assert_glerror()
|
|||
|
||||
void assert_glerror()
|
||||
{
|
||||
if (!gGLActive)
|
||||
/* if (!gGLActive)
|
||||
{
|
||||
//llwarns << "GL used while not active!" << llendl;
|
||||
|
||||
|
|
@ -1510,8 +1516,13 @@ void assert_glerror()
|
|||
//ll_fail("GL used while not active");
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
if (gDebugGL)
|
||||
if (!gDebugGL)
|
||||
{
|
||||
//funny looking if for branch prediction -- gDebugGL is almost always false and assert_glerror is called often
|
||||
}
|
||||
else
|
||||
{
|
||||
do_assert_glerror();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -543,6 +543,7 @@ extern PFNGLBEGINTRANSFORMFEEDBACKPROC glBeginTransformFeedback;
|
|||
extern PFNGLENDTRANSFORMFEEDBACKPROC glEndTransformFeedback;
|
||||
extern PFNGLTRANSFORMFEEDBACKVARYINGSPROC glTransformFeedbackVaryings;
|
||||
extern PFNGLBINDBUFFERRANGEPROC glBindBufferRange;
|
||||
extern PFNGLBINDBUFFERBASEPROC glBindBufferBase;
|
||||
|
||||
|
||||
#elif LL_WINDOWS
|
||||
|
|
@ -787,6 +788,7 @@ extern PFNGLBEGINTRANSFORMFEEDBACKPROC glBeginTransformFeedback;
|
|||
extern PFNGLENDTRANSFORMFEEDBACKPROC glEndTransformFeedback;
|
||||
extern PFNGLTRANSFORMFEEDBACKVARYINGSPROC glTransformFeedbackVaryings;
|
||||
extern PFNGLBINDBUFFERRANGEPROC glBindBufferRange;
|
||||
extern PFNGLBINDBUFFERBASEPROC glBindBufferBase;
|
||||
|
||||
//GL_ARB_debug_output
|
||||
extern PFNGLDEBUGMESSAGECONTROLARBPROC glDebugMessageControlARB;
|
||||
|
|
|
|||
|
|
@ -355,8 +355,8 @@ void LLGLSLShader::unload()
|
|||
stop_glerror();
|
||||
}
|
||||
|
||||
BOOL LLGLSLShader::createShader(vector<string> * attributes,
|
||||
vector<string> * uniforms,
|
||||
BOOL LLGLSLShader::createShader(std::vector<LLStaticHashedString> * attributes,
|
||||
std::vector<LLStaticHashedString> * uniforms,
|
||||
U32 varying_count,
|
||||
const char** varyings)
|
||||
{
|
||||
|
|
@ -374,7 +374,7 @@ BOOL LLGLSLShader::createShader(vector<string> * attributes,
|
|||
|
||||
// Create program
|
||||
mProgramObject = glCreateProgramObjectARB();
|
||||
|
||||
|
||||
#if LL_DARWIN
|
||||
// work-around missing mix(vec3,vec3,bvec3)
|
||||
mDefines["OLD_SELECT"] = "1";
|
||||
|
|
@ -443,7 +443,8 @@ BOOL LLGLSLShader::createShader(vector<string> * attributes,
|
|||
|
||||
for (S32 i = 0; i < channel_count; i++)
|
||||
{
|
||||
uniform1i(llformat("tex%d", i), i);
|
||||
LLStaticHashedString uniName(llformat("tex%d", i));
|
||||
uniform1i(uniName, i);
|
||||
}
|
||||
|
||||
S32 cur_tex = channel_count; //adjust any texture channels that might have been overwritten
|
||||
|
|
@ -500,7 +501,7 @@ void LLGLSLShader::attachObjects(GLhandleARB* objects, S32 count)
|
|||
}
|
||||
}
|
||||
|
||||
BOOL LLGLSLShader::mapAttributes(const vector<string> * attributes)
|
||||
BOOL LLGLSLShader::mapAttributes(const std::vector<LLStaticHashedString> * attributes)
|
||||
{
|
||||
//before linking, make sure reserved attributes always have consistent locations
|
||||
for (U32 i = 0; i < LLShaderMgr::instance()->mReservedAttribs.size(); i++)
|
||||
|
|
@ -537,7 +538,7 @@ BOOL LLGLSLShader::mapAttributes(const vector<string> * attributes)
|
|||
{
|
||||
for (U32 i = 0; i < numAttributes; i++)
|
||||
{
|
||||
const char* name = (*attributes)[i].c_str();
|
||||
const char* name = (*attributes)[i].String().c_str();
|
||||
S32 index = glGetAttribLocationARB(mProgramObject, name);
|
||||
if (index != -1)
|
||||
{
|
||||
|
|
@ -553,7 +554,7 @@ BOOL LLGLSLShader::mapAttributes(const vector<string> * attributes)
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
void LLGLSLShader::mapUniform(GLint index, const vector<string> * uniforms)
|
||||
void LLGLSLShader::mapUniform(GLint index, const vector<LLStaticHashedString> * uniforms)
|
||||
{
|
||||
if (index == -1)
|
||||
{
|
||||
|
|
@ -623,8 +624,10 @@ void LLGLSLShader::mapUniform(GLint index, const vector<string> * uniforms)
|
|||
is_array[0] = 0;
|
||||
}
|
||||
|
||||
mUniformMap[name] = location;
|
||||
LLStaticHashedString hashedName(name);
|
||||
mUniformNameMap[location] = name;
|
||||
mUniformMap[hashedName] = location;
|
||||
|
||||
LL_DEBUGS("ShaderLoading") << "Uniform " << name << " is at location " << location << LL_ENDL;
|
||||
|
||||
//find the index of this uniform
|
||||
|
|
@ -645,7 +648,7 @@ void LLGLSLShader::mapUniform(GLint index, const vector<string> * uniforms)
|
|||
for (U32 i = 0; i < uniforms->size(); i++)
|
||||
{
|
||||
if ( (mUniform[i+LLShaderMgr::instance()->mReservedUniforms.size()] == -1)
|
||||
&& ((*uniforms)[i] == name))
|
||||
&& ((*uniforms)[i].String() == name))
|
||||
{
|
||||
//found it
|
||||
mUniform[i+LLShaderMgr::instance()->mReservedUniforms.size()] = location;
|
||||
|
|
@ -679,7 +682,7 @@ GLint LLGLSLShader::mapUniformTextureChannel(GLint location, GLenum type)
|
|||
return -1;
|
||||
}
|
||||
|
||||
BOOL LLGLSLShader::mapUniforms(const vector<string> * uniforms)
|
||||
BOOL LLGLSLShader::mapUniforms(const vector<LLStaticHashedString> * uniforms)
|
||||
{
|
||||
BOOL res = TRUE;
|
||||
|
||||
|
|
@ -1141,18 +1144,18 @@ void LLGLSLShader::uniformMatrix4fv(U32 index, U32 count, GLboolean transpose, c
|
|||
}
|
||||
}
|
||||
|
||||
GLint LLGLSLShader::getUniformLocation(const string& uniform)
|
||||
GLint LLGLSLShader::getUniformLocation(const LLStaticHashedString& uniform)
|
||||
{
|
||||
GLint ret = -1;
|
||||
if (mProgramObject > 0)
|
||||
{
|
||||
std::map<string, GLint>::iterator iter = mUniformMap.find(uniform);
|
||||
LLStaticStringTable<GLint>::iterator iter = mUniformMap.find(uniform);
|
||||
if (iter != mUniformMap.end())
|
||||
{
|
||||
if (gDebugGL)
|
||||
{
|
||||
stop_glerror();
|
||||
if (iter->second != glGetUniformLocationARB(mProgramObject, uniform.c_str()))
|
||||
if (iter->second != glGetUniformLocationARB(mProgramObject, uniform.String().c_str()))
|
||||
{
|
||||
llerrs << "Uniform does not match." << llendl;
|
||||
}
|
||||
|
|
@ -1189,7 +1192,7 @@ GLint LLGLSLShader::getAttribLocation(U32 attrib)
|
|||
}
|
||||
}
|
||||
|
||||
void LLGLSLShader::uniform1i(const string& uniform, GLint v)
|
||||
void LLGLSLShader::uniform1i(const LLStaticHashedString& uniform, GLint v)
|
||||
{
|
||||
GLint location = getUniformLocation(uniform);
|
||||
|
||||
|
|
@ -1205,7 +1208,7 @@ void LLGLSLShader::uniform1i(const string& uniform, GLint v)
|
|||
}
|
||||
}
|
||||
|
||||
void LLGLSLShader::uniform2i(const string& uniform, GLint i, GLint j)
|
||||
void LLGLSLShader::uniform2i(const LLStaticHashedString& uniform, GLint i, GLint j)
|
||||
{
|
||||
GLint location = getUniformLocation(uniform);
|
||||
|
||||
|
|
@ -1222,7 +1225,7 @@ void LLGLSLShader::uniform2i(const string& uniform, GLint i, GLint j)
|
|||
}
|
||||
|
||||
|
||||
void LLGLSLShader::uniform1f(const string& uniform, GLfloat v)
|
||||
void LLGLSLShader::uniform1f(const LLStaticHashedString& uniform, GLfloat v)
|
||||
{
|
||||
GLint location = getUniformLocation(uniform);
|
||||
|
||||
|
|
@ -1238,7 +1241,7 @@ void LLGLSLShader::uniform1f(const string& uniform, GLfloat v)
|
|||
}
|
||||
}
|
||||
|
||||
void LLGLSLShader::uniform2f(const string& uniform, GLfloat x, GLfloat y)
|
||||
void LLGLSLShader::uniform2f(const LLStaticHashedString& uniform, GLfloat x, GLfloat y)
|
||||
{
|
||||
GLint location = getUniformLocation(uniform);
|
||||
|
||||
|
|
@ -1255,7 +1258,7 @@ void LLGLSLShader::uniform2f(const string& uniform, GLfloat x, GLfloat y)
|
|||
|
||||
}
|
||||
|
||||
void LLGLSLShader::uniform3f(const string& uniform, GLfloat x, GLfloat y, GLfloat z)
|
||||
void LLGLSLShader::uniform3f(const LLStaticHashedString& uniform, GLfloat x, GLfloat y, GLfloat z)
|
||||
{
|
||||
GLint location = getUniformLocation(uniform);
|
||||
|
||||
|
|
@ -1271,23 +1274,7 @@ void LLGLSLShader::uniform3f(const string& uniform, GLfloat x, GLfloat y, GLfloa
|
|||
}
|
||||
}
|
||||
|
||||
void LLGLSLShader::uniform4f(const string& uniform, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
|
||||
{
|
||||
GLint location = getUniformLocation(uniform);
|
||||
|
||||
if (location >= 0)
|
||||
{
|
||||
std::map<GLint, LLVector4>::iterator iter = mValue.find(location);
|
||||
LLVector4 vec(x,y,z,w);
|
||||
if (iter == mValue.end() || shouldChange(iter->second,vec))
|
||||
{
|
||||
glUniform4fARB(location, x,y,z,w);
|
||||
mValue[location] = vec;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LLGLSLShader::uniform1fv(const string& uniform, U32 count, const GLfloat* v)
|
||||
void LLGLSLShader::uniform1fv(const LLStaticHashedString& uniform, U32 count, const GLfloat* v)
|
||||
{
|
||||
GLint location = getUniformLocation(uniform);
|
||||
|
||||
|
|
@ -1303,7 +1290,7 @@ void LLGLSLShader::uniform1fv(const string& uniform, U32 count, const GLfloat* v
|
|||
}
|
||||
}
|
||||
|
||||
void LLGLSLShader::uniform2fv(const string& uniform, U32 count, const GLfloat* v)
|
||||
void LLGLSLShader::uniform2fv(const LLStaticHashedString& uniform, U32 count, const GLfloat* v)
|
||||
{
|
||||
GLint location = getUniformLocation(uniform);
|
||||
|
||||
|
|
@ -1319,7 +1306,7 @@ void LLGLSLShader::uniform2fv(const string& uniform, U32 count, const GLfloat* v
|
|||
}
|
||||
}
|
||||
|
||||
void LLGLSLShader::uniform3fv(const string& uniform, U32 count, const GLfloat* v)
|
||||
void LLGLSLShader::uniform3fv(const LLStaticHashedString& uniform, U32 count, const GLfloat* v)
|
||||
{
|
||||
GLint location = getUniformLocation(uniform);
|
||||
|
||||
|
|
@ -1335,7 +1322,7 @@ void LLGLSLShader::uniform3fv(const string& uniform, U32 count, const GLfloat* v
|
|||
}
|
||||
}
|
||||
|
||||
void LLGLSLShader::uniform4fv(const string& uniform, U32 count, const GLfloat* v)
|
||||
void LLGLSLShader::uniform4fv(const LLStaticHashedString& uniform, U32 count, const GLfloat* v)
|
||||
{
|
||||
GLint location = getUniformLocation(uniform);
|
||||
|
||||
|
|
@ -1353,27 +1340,7 @@ void LLGLSLShader::uniform4fv(const string& uniform, U32 count, const GLfloat* v
|
|||
}
|
||||
}
|
||||
|
||||
void LLGLSLShader::uniformMatrix2fv(const string& uniform, U32 count, GLboolean transpose, const GLfloat* v)
|
||||
{
|
||||
GLint location = getUniformLocation(uniform);
|
||||
|
||||
if (location >= 0)
|
||||
{
|
||||
glUniformMatrix2fvARB(location, count, transpose, v);
|
||||
}
|
||||
}
|
||||
|
||||
void LLGLSLShader::uniformMatrix3fv(const string& uniform, U32 count, GLboolean transpose, const GLfloat* v)
|
||||
{
|
||||
GLint location = getUniformLocation(uniform);
|
||||
|
||||
if (location >= 0)
|
||||
{
|
||||
glUniformMatrix3fvARB(location, count, transpose, v);
|
||||
}
|
||||
}
|
||||
|
||||
void LLGLSLShader::uniformMatrix4fv(const string& uniform, U32 count, GLboolean transpose, const GLfloat* v)
|
||||
void LLGLSLShader::uniformMatrix4fv(const LLStaticHashedString& uniform, U32 count, GLboolean transpose, const GLfloat* v)
|
||||
{
|
||||
GLint location = getUniformLocation(uniform);
|
||||
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@
|
|||
|
||||
#include "llgl.h"
|
||||
#include "llrender.h"
|
||||
#include "llstaticstringtable.h"
|
||||
|
||||
class LLShaderFeatures
|
||||
{
|
||||
|
|
@ -90,16 +91,16 @@ public:
|
|||
void placeProfileQuery();
|
||||
void readProfileQuery(U32 count, U32 mode);
|
||||
|
||||
BOOL createShader(std::vector<std::string> * attributes,
|
||||
std::vector<std::string> * uniforms,
|
||||
BOOL createShader(std::vector<LLStaticHashedString> * attributes,
|
||||
std::vector<LLStaticHashedString> * uniforms,
|
||||
U32 varying_count = 0,
|
||||
const char** varyings = NULL);
|
||||
BOOL attachObject(std::string object);
|
||||
void attachObject(GLhandleARB object);
|
||||
void attachObjects(GLhandleARB* objects = NULL, S32 count = 0);
|
||||
BOOL mapAttributes(const std::vector<std::string> * attributes);
|
||||
BOOL mapUniforms(const std::vector<std::string> * uniforms);
|
||||
void mapUniform(GLint index, const std::vector<std::string> * uniforms);
|
||||
BOOL mapAttributes(const std::vector<LLStaticHashedString> * attributes);
|
||||
BOOL mapUniforms(const std::vector<LLStaticHashedString> *);
|
||||
void mapUniform(GLint index, const std::vector<LLStaticHashedString> *);
|
||||
void uniform1i(U32 index, GLint i);
|
||||
void uniform1f(U32 index, GLfloat v);
|
||||
void uniform2f(U32 index, GLfloat x, GLfloat y);
|
||||
|
|
@ -110,30 +111,27 @@ public:
|
|||
void uniform2fv(U32 index, U32 count, const GLfloat* v);
|
||||
void uniform3fv(U32 index, U32 count, const GLfloat* v);
|
||||
void uniform4fv(U32 index, U32 count, const GLfloat* v);
|
||||
void uniform1i(const std::string& uniform, GLint i);
|
||||
void uniform2i(const std::string& uniform, GLint i, GLint j);
|
||||
void uniform1f(const std::string& uniform, GLfloat v);
|
||||
void uniform2f(const std::string& uniform, GLfloat x, GLfloat y);
|
||||
void uniform3f(const std::string& uniform, GLfloat x, GLfloat y, GLfloat z);
|
||||
void uniform4f(const std::string& uniform, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
|
||||
void uniform1iv(const std::string& uniform, U32 count, const GLint* i);
|
||||
void uniform1fv(const std::string& uniform, U32 count, const GLfloat* v);
|
||||
void uniform2fv(const std::string& uniform, U32 count, const GLfloat* v);
|
||||
void uniform3fv(const std::string& uniform, U32 count, const GLfloat* v);
|
||||
void uniform4fv(const std::string& uniform, U32 count, const GLfloat* v);
|
||||
void uniform2i(const LLStaticHashedString& uniform, GLint i, GLint j);
|
||||
void uniformMatrix2fv(U32 index, U32 count, GLboolean transpose, const GLfloat *v);
|
||||
void uniformMatrix3fv(U32 index, U32 count, GLboolean transpose, const GLfloat *v);
|
||||
void uniformMatrix4fv(U32 index, U32 count, GLboolean transpose, const GLfloat *v);
|
||||
void uniformMatrix2fv(const std::string& uniform, U32 count, GLboolean transpose, const GLfloat *v);
|
||||
void uniformMatrix3fv(const std::string& uniform, U32 count, GLboolean transpose, const GLfloat *v);
|
||||
void uniformMatrix4fv(const std::string& uniform, U32 count, GLboolean transpose, const GLfloat *v);
|
||||
void uniform1i(const LLStaticHashedString& uniform, GLint i);
|
||||
void uniform1f(const LLStaticHashedString& uniform, GLfloat v);
|
||||
void uniform2f(const LLStaticHashedString& uniform, GLfloat x, GLfloat y);
|
||||
void uniform3f(const LLStaticHashedString& uniform, GLfloat x, GLfloat y, GLfloat z);
|
||||
void uniform1fv(const LLStaticHashedString& uniform, U32 count, const GLfloat* v);
|
||||
void uniform2fv(const LLStaticHashedString& uniform, U32 count, const GLfloat* v);
|
||||
void uniform3fv(const LLStaticHashedString& uniform, U32 count, const GLfloat* v);
|
||||
void uniform4fv(const LLStaticHashedString& uniform, U32 count, const GLfloat* v);
|
||||
void uniformMatrix4fv(const LLStaticHashedString& uniform, U32 count, GLboolean transpose, const GLfloat *v);
|
||||
|
||||
void setMinimumAlpha(F32 minimum);
|
||||
|
||||
void vertexAttrib4f(U32 index, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
|
||||
void vertexAttrib4fv(U32 index, GLfloat* v);
|
||||
|
||||
GLint getUniformLocation(const std::string& uniform);
|
||||
//GLint getUniformLocation(const std::string& uniform);
|
||||
GLint getUniformLocation(const LLStaticHashedString& uniform);
|
||||
GLint getUniformLocation(U32 index);
|
||||
|
||||
GLint getAttribLocation(U32 attrib);
|
||||
|
|
@ -170,7 +168,7 @@ public:
|
|||
std::vector<GLint> mAttribute; //lookup table of attribute enum to attribute channel
|
||||
U32 mAttributeMask; //mask of which reserved attributes are set (lines up with LLVertexBuffer::getTypeMask())
|
||||
std::vector<GLint> mUniform; //lookup table of uniform enum to uniform location
|
||||
std::map<std::string, GLint> mUniformMap; //lookup map of uniform name to uniform location
|
||||
LLStaticStringTable<GLint> mUniformMap; //lookup map of uniform name to uniform location
|
||||
std::map<GLint, std::string> mUniformNameMap; //lookup map of uniform location to uniform name
|
||||
std::map<GLint, LLVector4> mValue; //lookup map of uniform location to last known value
|
||||
std::vector<GLint> mTexture;
|
||||
|
|
|
|||
|
|
@ -715,9 +715,9 @@ void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips)
|
|||
|
||||
mMipLevels = wpo2(llmax(w, h));
|
||||
|
||||
//use legacy mipmap generation mode
|
||||
//use legacy mipmap generation mode (note: making this condional can cause rendering issues)
|
||||
glTexParameteri(mTarget, GL_GENERATE_MIPMAP, GL_TRUE);
|
||||
|
||||
|
||||
LLImageGL::setManualImage(mTarget, 0, mFormatInternal,
|
||||
w, h,
|
||||
mFormatPrimary, mFormatType,
|
||||
|
|
@ -1089,6 +1089,16 @@ void LLImageGL::generateTextures(LLTexUnit::eTextureType type, U32 format, S32 n
|
|||
LLFastTimer t(FTM_GENERATE_TEXTURES);
|
||||
bool empty = true;
|
||||
|
||||
if (LLRender::sGLCoreProfile)
|
||||
{
|
||||
switch (format)
|
||||
{
|
||||
case GL_LUMINANCE8: format = GL_RGB8; break;
|
||||
case GL_LUMINANCE8_ALPHA8:
|
||||
case GL_ALPHA8: format = GL_RGBA8; break;
|
||||
}
|
||||
}
|
||||
|
||||
dead_texturelist_t::iterator iter = sDeadTextureList[type].find(format);
|
||||
|
||||
if (iter != sDeadTextureList[type].end())
|
||||
|
|
|
|||
|
|
@ -31,6 +31,21 @@
|
|||
#include "llsdserialize.h"
|
||||
#include "llrender.h"
|
||||
|
||||
static LLStaticHashedString sRenderTexture("RenderTexture");
|
||||
static LLStaticHashedString sBrightness("brightness");
|
||||
static LLStaticHashedString sContrast("contrast");
|
||||
static LLStaticHashedString sContrastBase("contrastBase");
|
||||
static LLStaticHashedString sSaturation("saturation");
|
||||
static LLStaticHashedString sLumWeights("lumWeights");
|
||||
static LLStaticHashedString sNoiseTexture("NoiseTexture");
|
||||
static LLStaticHashedString sBrightMult("brightMult");
|
||||
static LLStaticHashedString sNoiseStrength("noiseStrength");
|
||||
static LLStaticHashedString sExtractLow("extractLow");
|
||||
static LLStaticHashedString sExtractHigh("extractHigh");
|
||||
static LLStaticHashedString sBloomStrength("bloomStrength");
|
||||
static LLStaticHashedString sTexelSize("texelSize");
|
||||
static LLStaticHashedString sBlurDirection("blurDirection");
|
||||
static LLStaticHashedString sBlurWidth("blurWidth");
|
||||
|
||||
LLPostProcess * gPostProcess = NULL;
|
||||
|
||||
|
|
@ -258,12 +273,12 @@ void LLPostProcess::applyColorFilterShader(void)
|
|||
void LLPostProcess::createColorFilterShader(void)
|
||||
{
|
||||
/// Define uniform names
|
||||
colorFilterUniforms["RenderTexture"] = 0;
|
||||
colorFilterUniforms["brightness"] = 0;
|
||||
colorFilterUniforms["contrast"] = 0;
|
||||
colorFilterUniforms["contrastBase"] = 0;
|
||||
colorFilterUniforms["saturation"] = 0;
|
||||
colorFilterUniforms["lumWeights"] = 0;
|
||||
colorFilterUniforms[sRenderTexture] = 0;
|
||||
colorFilterUniforms[sBrightness] = 0;
|
||||
colorFilterUniforms[sContrast] = 0;
|
||||
colorFilterUniforms[sContrastBase] = 0;
|
||||
colorFilterUniforms[sSaturation] = 0;
|
||||
colorFilterUniforms[sLumWeights] = 0;
|
||||
}
|
||||
|
||||
void LLPostProcess::applyNightVisionShader(void)
|
||||
|
|
@ -307,11 +322,11 @@ void LLPostProcess::applyNightVisionShader(void)
|
|||
void LLPostProcess::createNightVisionShader(void)
|
||||
{
|
||||
/// Define uniform names
|
||||
nightVisionUniforms["RenderTexture"] = 0;
|
||||
nightVisionUniforms["NoiseTexture"] = 0;
|
||||
nightVisionUniforms["brightMult"] = 0;
|
||||
nightVisionUniforms["noiseStrength"] = 0;
|
||||
nightVisionUniforms["lumWeights"] = 0;
|
||||
nightVisionUniforms[sRenderTexture] = 0;
|
||||
nightVisionUniforms[sNoiseTexture] = 0;
|
||||
nightVisionUniforms[sBrightMult] = 0;
|
||||
nightVisionUniforms[sNoiseStrength] = 0;
|
||||
nightVisionUniforms[sLumWeights] = 0;
|
||||
|
||||
createNoiseTexture(mNoiseTexture);
|
||||
}
|
||||
|
|
@ -326,25 +341,25 @@ void LLPostProcess::createBloomShader(void)
|
|||
createTexture(mTempBloomTexture, unsigned(screenW * 0.5), unsigned(screenH * 0.5));
|
||||
|
||||
/// Create Bloom Extract Shader
|
||||
bloomExtractUniforms["RenderTexture"] = 0;
|
||||
bloomExtractUniforms["extractLow"] = 0;
|
||||
bloomExtractUniforms["extractHigh"] = 0;
|
||||
bloomExtractUniforms["lumWeights"] = 0;
|
||||
bloomExtractUniforms[sRenderTexture] = 0;
|
||||
bloomExtractUniforms[sExtractLow] = 0;
|
||||
bloomExtractUniforms[sExtractHigh] = 0;
|
||||
bloomExtractUniforms[sLumWeights] = 0;
|
||||
|
||||
/// Create Bloom Blur Shader
|
||||
bloomBlurUniforms["RenderTexture"] = 0;
|
||||
bloomBlurUniforms["bloomStrength"] = 0;
|
||||
bloomBlurUniforms["texelSize"] = 0;
|
||||
bloomBlurUniforms["blurDirection"] = 0;
|
||||
bloomBlurUniforms["blurWidth"] = 0;
|
||||
bloomBlurUniforms[sRenderTexture] = 0;
|
||||
bloomBlurUniforms[sBloomStrength] = 0;
|
||||
bloomBlurUniforms[sTexelSize] = 0;
|
||||
bloomBlurUniforms[sBlurDirection] = 0;
|
||||
bloomBlurUniforms[sBlurWidth] = 0;
|
||||
}
|
||||
|
||||
void LLPostProcess::getShaderUniforms(glslUniforms & uniforms, GLhandleARB & prog)
|
||||
{
|
||||
/// Find uniform locations and insert into map
|
||||
std::map<const char *, GLuint>::iterator i;
|
||||
glslUniforms::iterator i;
|
||||
for (i = uniforms.begin(); i != uniforms.end(); ++i){
|
||||
i->second = glGetUniformLocationARB(prog, i->first);
|
||||
i->second = glGetUniformLocationARB(prog, i->first.String().c_str());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@
|
|||
#include <fstream>
|
||||
#include "llgl.h"
|
||||
#include "llglheaders.h"
|
||||
#include "llstaticstringtable.h"
|
||||
|
||||
class LLPostProcess
|
||||
{
|
||||
|
|
@ -44,7 +45,7 @@ public:
|
|||
} QuadType;
|
||||
|
||||
/// GLSL Shader Encapsulation Struct
|
||||
typedef std::map<const char *, GLuint> glslUniforms;
|
||||
typedef LLStaticStringTable<GLuint> glslUniforms;
|
||||
|
||||
struct PostProcessTweaks : public LLSD {
|
||||
inline PostProcessTweaks() : LLSD(LLSD::emptyMap())
|
||||
|
|
|
|||
|
|
@ -225,26 +225,15 @@ void LLTexUnit::disable(void)
|
|||
bool LLTexUnit::bind(LLTexture* texture, bool for_rendering, bool forceBind)
|
||||
{
|
||||
stop_glerror();
|
||||
if (mIndex < 0) return false;
|
||||
|
||||
if (mIndex >= 0)
|
||||
{
|
||||
gGL.flush();
|
||||
|
||||
LLImageGL* gl_tex = NULL ;
|
||||
if (texture == NULL || !(gl_tex = texture->getGLTexture()))
|
||||
if (texture != NULL && (gl_tex = texture->getGLTexture()))
|
||||
{
|
||||
llwarns << "NULL LLTexUnit::bind texture" << llendl;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!gl_tex->getTexName()) //if texture does not exist
|
||||
if (gl_tex->getTexName()) //if texture exists
|
||||
{
|
||||
//if deleted, will re-generate it immediately
|
||||
texture->forceImmediateUpdate() ;
|
||||
|
||||
gl_tex->forceUpdateBindStats() ;
|
||||
return texture->bindDefaultImage(mIndex);
|
||||
}
|
||||
|
||||
//in audit, replace the selected texture by the default one.
|
||||
if ((mCurrTexture != gl_tex->getTexName()) || forceBind)
|
||||
{
|
||||
|
|
@ -265,6 +254,27 @@ bool LLTexUnit::bind(LLTexture* texture, bool for_rendering, bool forceBind)
|
|||
setTextureFilteringOption(gl_tex->mFilterOption);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//if deleted, will re-generate it immediately
|
||||
texture->forceImmediateUpdate() ;
|
||||
|
||||
gl_tex->forceUpdateBindStats() ;
|
||||
return texture->bindDefaultImage(mIndex);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
llwarns << "NULL LLTexUnit::bind texture" << llendl;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{ // mIndex < 0
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -1058,6 +1068,16 @@ LLRender::~LLRender()
|
|||
|
||||
void LLRender::init()
|
||||
{
|
||||
if (sGLCoreProfile && !LLVertexBuffer::sUseVAO)
|
||||
{ //bind a dummy vertex array object so we're core profile compliant
|
||||
#ifdef GL_ARB_vertex_array_object
|
||||
U32 ret;
|
||||
glGenVertexArrays(1, &ret);
|
||||
glBindVertexArray(ret);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
llassert_always(mBuffer.isNull()) ;
|
||||
stop_glerror();
|
||||
mBuffer = new LLVertexBuffer(immediate_mask, 0);
|
||||
|
|
@ -1852,33 +1872,33 @@ void LLRender::flush()
|
|||
//store mCount in a local variable to avoid re-entrance (drawArrays may call flush)
|
||||
U32 count = mCount;
|
||||
|
||||
if (mMode == LLRender::QUADS && !sGLCoreProfile)
|
||||
{
|
||||
if (mCount%4 != 0)
|
||||
if (mMode == LLRender::QUADS && !sGLCoreProfile)
|
||||
{
|
||||
if (mCount%4 != 0)
|
||||
{
|
||||
count -= (mCount % 4);
|
||||
llwarns << "Incomplete quad requested." << llendl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (mMode == LLRender::TRIANGLES)
|
||||
{
|
||||
if (mCount%3 != 0)
|
||||
|
||||
if (mMode == LLRender::TRIANGLES)
|
||||
{
|
||||
if (mCount%3 != 0)
|
||||
{
|
||||
count -= (mCount % 3);
|
||||
llwarns << "Incomplete triangle requested." << llendl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (mMode == LLRender::LINES)
|
||||
{
|
||||
if (mCount%2 != 0)
|
||||
|
||||
if (mMode == LLRender::LINES)
|
||||
{
|
||||
if (mCount%2 != 0)
|
||||
{
|
||||
count -= (mCount % 2);
|
||||
llwarns << "Incomplete line requested." << llendl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
mCount = 0;
|
||||
|
||||
if (mBuffer->useVBOs() && !mBuffer->isLocked())
|
||||
|
|
@ -2281,6 +2301,22 @@ void LLRender::diffuseColor4ubv(const U8* c)
|
|||
}
|
||||
}
|
||||
|
||||
void LLRender::diffuseColor4ub(U8 r, U8 g, U8 b, U8 a)
|
||||
{
|
||||
LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr;
|
||||
llassert(!LLGLSLShader::sNoFixedFunction || shader != NULL);
|
||||
|
||||
if (shader)
|
||||
{
|
||||
shader->uniform4f(LLShaderMgr::DIFFUSE_COLOR, r/255.f, g/255.f, b/255.f, a/255.f);
|
||||
}
|
||||
else
|
||||
{
|
||||
glColor4ub(r,g,b,a);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void LLRender::debugTexUnits(void)
|
||||
{
|
||||
LL_INFOS("TextureUnit") << "Active TexUnit: " << mCurrTextureUnitIndex << LL_ENDL;
|
||||
|
|
|
|||
|
|
@ -396,6 +396,7 @@ public:
|
|||
void diffuseColor4f(F32 r, F32 g, F32 b, F32 a);
|
||||
void diffuseColor4fv(const F32* c);
|
||||
void diffuseColor4ubv(const U8* c);
|
||||
void diffuseColor4ub(U8 r, U8 g, U8 b, U8 a);
|
||||
|
||||
void vertexBatchPreTransformed(LLVector3* verts, S32 vert_count);
|
||||
void vertexBatchPreTransformed(LLVector3* verts, LLVector2* uvs, S32 vert_count);
|
||||
|
|
|
|||
|
|
@ -262,7 +262,7 @@ bool LLRenderTarget::addColorAttachment(U32 color_fmt)
|
|||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -364,56 +364,36 @@ void LLRenderTarget::release()
|
|||
|
||||
sBytesAllocated -= mResX*mResY*4;
|
||||
}
|
||||
else if (mFBO)
|
||||
{
|
||||
else if (mUseDepth && mFBO)
|
||||
{ //detach shared depth buffer
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
|
||||
|
||||
if (mUseDepth)
|
||||
{ //detach shared depth buffer
|
||||
if (mStencil)
|
||||
{ //attached as a renderbuffer
|
||||
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, 0);
|
||||
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, 0);
|
||||
mStencil = false;
|
||||
}
|
||||
else
|
||||
{ //attached as a texture
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, LLTexUnit::getInternalType(mUsage), 0, 0);
|
||||
}
|
||||
mUseDepth = false;
|
||||
if (mStencil)
|
||||
{ //attached as a renderbuffer
|
||||
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, 0);
|
||||
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, 0);
|
||||
mStencil = false;
|
||||
}
|
||||
}
|
||||
|
||||
// Detach any extra color buffers (e.g. SRGB spec buffers)
|
||||
//
|
||||
if (mFBO && (mTex.size() > 1))
|
||||
{
|
||||
S32 z;
|
||||
for (z = mTex.size() - 1; z >= 1; z--)
|
||||
{
|
||||
sBytesAllocated -= mResX*mResY*4;
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0+z, LLTexUnit::getInternalType(mUsage), 0, 0);
|
||||
stop_glerror();
|
||||
LLImageGL::deleteTextures(mUsage, mInternalFormat[z], 0, 1, &mTex[z], true);
|
||||
else
|
||||
{ //attached as a texture
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, LLTexUnit::getInternalType(mUsage), 0, 0);
|
||||
}
|
||||
mUseDepth = false;
|
||||
}
|
||||
|
||||
if (mFBO)
|
||||
{
|
||||
glDeleteFramebuffers(1, (GLuint *) &mFBO);
|
||||
stop_glerror();
|
||||
mFBO = 0;
|
||||
}
|
||||
|
||||
if (mTex.size() > 0)
|
||||
{
|
||||
sBytesAllocated -= mResX*mResY*4;
|
||||
LLImageGL::deleteTextures(mUsage, mInternalFormat[0], 0, 1, &mTex[0], true);
|
||||
sBytesAllocated -= mResX*mResY*4*mTex.size();
|
||||
LLImageGL::deleteTextures(mUsage, mInternalFormat[0], 0, mTex.size(), &mTex[0], true);
|
||||
mTex.clear();
|
||||
mInternalFormat.clear();
|
||||
}
|
||||
|
||||
mTex.clear();
|
||||
mInternalFormat.clear();
|
||||
|
||||
|
||||
mResX = mResY = 0;
|
||||
|
||||
sBoundTarget = NULL;
|
||||
|
|
@ -495,6 +475,12 @@ U32 LLRenderTarget::getTexture(U32 attachment) const
|
|||
return mTex[attachment];
|
||||
}
|
||||
|
||||
U32 LLRenderTarget::getNumTextures() const
|
||||
{
|
||||
return mTex.size();
|
||||
}
|
||||
|
||||
|
||||
void LLRenderTarget::bindTexture(U32 index, S32 channel)
|
||||
{
|
||||
gGL.getTexUnit(channel)->bindManual(mUsage, getTexture(index));
|
||||
|
|
|
|||
|
|
@ -115,6 +115,7 @@ public:
|
|||
LLTexUnit::eTextureType getUsage(void) const { return mUsage; }
|
||||
|
||||
U32 getTexture(U32 attachment = 0) const;
|
||||
U32 getNumTextures() const;
|
||||
|
||||
U32 getDepth(void) const { return mDepth; }
|
||||
bool hasStencil() const { return mStencil; }
|
||||
|
|
|
|||
|
|
@ -993,7 +993,9 @@ void LLShaderMgr::initAttribsAndUniforms()
|
|||
mReservedUniforms.push_back("texture_matrix1");
|
||||
mReservedUniforms.push_back("texture_matrix2");
|
||||
mReservedUniforms.push_back("texture_matrix3");
|
||||
llassert(mReservedUniforms.size() == LLShaderMgr::TEXTURE_MATRIX3+1);
|
||||
mReservedUniforms.push_back("object_plane_s");
|
||||
mReservedUniforms.push_back("object_plane_t");
|
||||
llassert(mReservedUniforms.size() == LLShaderMgr::OBJECT_PLANE_T+1);
|
||||
|
||||
mReservedUniforms.push_back("viewport");
|
||||
|
||||
|
|
@ -1135,15 +1137,54 @@ void LLShaderMgr::initAttribsAndUniforms()
|
|||
mReservedUniforms.push_back("lightMap");
|
||||
mReservedUniforms.push_back("bloomMap");
|
||||
mReservedUniforms.push_back("projectionMap");
|
||||
|
||||
mReservedUniforms.push_back("global_gamma");
|
||||
mReservedUniforms.push_back("texture_gamma");
|
||||
mReservedUniforms.push_back("norm_mat");
|
||||
|
||||
mReservedUniforms.push_back("global_gamma");
|
||||
mReservedUniforms.push_back("texture_gamma");
|
||||
|
||||
mReservedUniforms.push_back("specular_color");
|
||||
mReservedUniforms.push_back("env_intensity");
|
||||
|
||||
mReservedUniforms.push_back("display_gamma");
|
||||
mReservedUniforms.push_back("matrixPalette");
|
||||
|
||||
mReservedUniforms.push_back("screenTex");
|
||||
mReservedUniforms.push_back("screenDepth");
|
||||
mReservedUniforms.push_back("refTex");
|
||||
mReservedUniforms.push_back("eyeVec");
|
||||
mReservedUniforms.push_back("time");
|
||||
mReservedUniforms.push_back("d1");
|
||||
mReservedUniforms.push_back("d2");
|
||||
mReservedUniforms.push_back("lightDir");
|
||||
mReservedUniforms.push_back("specular");
|
||||
mReservedUniforms.push_back("lightExp");
|
||||
mReservedUniforms.push_back("waterFogColor");
|
||||
mReservedUniforms.push_back("waterFogDensity");
|
||||
mReservedUniforms.push_back("waterFogKS");
|
||||
mReservedUniforms.push_back("refScale");
|
||||
mReservedUniforms.push_back("waterHeight");
|
||||
mReservedUniforms.push_back("waterPlane");
|
||||
mReservedUniforms.push_back("normScale");
|
||||
mReservedUniforms.push_back("fresnelScale");
|
||||
mReservedUniforms.push_back("fresnelOffset");
|
||||
mReservedUniforms.push_back("blurMultiplier");
|
||||
mReservedUniforms.push_back("sunAngle");
|
||||
mReservedUniforms.push_back("scaledAngle");
|
||||
mReservedUniforms.push_back("sunAngle2");
|
||||
|
||||
mReservedUniforms.push_back("camPosLocal");
|
||||
|
||||
mReservedUniforms.push_back("gWindDir");
|
||||
mReservedUniforms.push_back("gSinWaveParams");
|
||||
mReservedUniforms.push_back("gGravity");
|
||||
|
||||
mReservedUniforms.push_back("detail_0");
|
||||
mReservedUniforms.push_back("detail_1");
|
||||
mReservedUniforms.push_back("detail_2");
|
||||
mReservedUniforms.push_back("detail_3");
|
||||
mReservedUniforms.push_back("alpha_ramp");
|
||||
|
||||
mReservedUniforms.push_back("origin");
|
||||
mReservedUniforms.push_back("display_gamma");
|
||||
llassert(mReservedUniforms.size() == END_RESERVED_UNIFORMS);
|
||||
|
||||
std::set<std::string> dupe_check;
|
||||
|
|
|
|||
|
|
@ -47,6 +47,8 @@ public:
|
|||
TEXTURE_MATRIX1,
|
||||
TEXTURE_MATRIX2,
|
||||
TEXTURE_MATRIX3,
|
||||
OBJECT_PLANE_S,
|
||||
OBJECT_PLANE_T,
|
||||
VIEWPORT,
|
||||
LIGHT_POSITION,
|
||||
LIGHT_DIRECTION,
|
||||
|
|
@ -165,15 +167,54 @@ public:
|
|||
DEFERRED_LIGHT,
|
||||
DEFERRED_BLOOM,
|
||||
DEFERRED_PROJECTION,
|
||||
|
||||
GLOBAL_GAMMA,
|
||||
TEXTURE_GAMMA,
|
||||
DEFERRED_NORM_MATRIX,
|
||||
|
||||
GLOBAL_GAMMA,
|
||||
TEXTURE_GAMMA,
|
||||
|
||||
SPECULAR_COLOR,
|
||||
ENVIRONMENT_INTENSITY,
|
||||
|
||||
DISPLAY_GAMMA,
|
||||
AVATAR_MATRIX,
|
||||
|
||||
WATER_SCREENTEX,
|
||||
WATER_SCREENDEPTH,
|
||||
WATER_REFTEX,
|
||||
WATER_EYEVEC,
|
||||
WATER_TIME,
|
||||
WATER_WAVE_DIR1,
|
||||
WATER_WAVE_DIR2,
|
||||
WATER_LIGHT_DIR,
|
||||
WATER_SPECULAR,
|
||||
WATER_SPECULAR_EXP,
|
||||
WATER_FOGCOLOR,
|
||||
WATER_FOGDENSITY,
|
||||
WATER_FOGKS,
|
||||
WATER_REFSCALE,
|
||||
WATER_WATERHEIGHT,
|
||||
WATER_WATERPLANE,
|
||||
WATER_NORM_SCALE,
|
||||
WATER_FRESNEL_SCALE,
|
||||
WATER_FRESNEL_OFFSET,
|
||||
WATER_BLUR_MULTIPLIER,
|
||||
WATER_SUN_ANGLE,
|
||||
WATER_SCALED_ANGLE,
|
||||
WATER_SUN_ANGLE2,
|
||||
|
||||
WL_CAMPOSLOCAL,
|
||||
|
||||
AVATAR_WIND,
|
||||
AVATAR_SINWAVE,
|
||||
AVATAR_GRAVITY,
|
||||
|
||||
TERRAIN_DETAIL0,
|
||||
TERRAIN_DETAIL1,
|
||||
TERRAIN_DETAIL2,
|
||||
TERRAIN_DETAIL3,
|
||||
TERRAIN_ALPHARAMP,
|
||||
|
||||
SHINY_ORIGIN,
|
||||
DISPLAY_GAMMA,
|
||||
END_RESERVED_UNIFORMS
|
||||
} eGLSLReservedUniforms;
|
||||
|
||||
|
|
|
|||
|
|
@ -85,6 +85,7 @@ const U32 LL_VBO_POOL_SEED_COUNT = vbo_block_index(LL_VBO_POOL_MAX_SEED_SIZE);
|
|||
//static
|
||||
LLVBOPool LLVertexBuffer::sStreamVBOPool(GL_STREAM_DRAW_ARB, GL_ARRAY_BUFFER_ARB);
|
||||
LLVBOPool LLVertexBuffer::sDynamicVBOPool(GL_DYNAMIC_DRAW_ARB, GL_ARRAY_BUFFER_ARB);
|
||||
LLVBOPool LLVertexBuffer::sDynamicCopyVBOPool(GL_DYNAMIC_COPY_ARB, GL_ARRAY_BUFFER_ARB);
|
||||
LLVBOPool LLVertexBuffer::sStreamIBOPool(GL_STREAM_DRAW_ARB, GL_ELEMENT_ARRAY_BUFFER_ARB);
|
||||
LLVBOPool LLVertexBuffer::sDynamicIBOPool(GL_DYNAMIC_DRAW_ARB, GL_ELEMENT_ARRAY_BUFFER_ARB);
|
||||
|
||||
|
|
@ -199,7 +200,10 @@ volatile U8* LLVBOPool::allocate(U32& name, U32 size, bool for_seed)
|
|||
if (LLVertexBuffer::sDisableVBOMapping || mUsage != GL_DYNAMIC_DRAW_ARB)
|
||||
{
|
||||
glBufferDataARB(mType, size, 0, mUsage);
|
||||
ret = (U8*) ll_aligned_malloc_16(size);
|
||||
if (mUsage != GL_DYNAMIC_COPY_ARB)
|
||||
{ //data will be provided by application
|
||||
ret = (U8*) ll_aligned_malloc(size, 64);
|
||||
}
|
||||
}
|
||||
else
|
||||
{ //always use a true hint of static draw when allocating non-client-backed buffers
|
||||
|
|
@ -252,7 +256,7 @@ void LLVBOPool::release(U32 name, volatile U8* buffer, U32 size)
|
|||
llassert(vbo_block_size(size) == size);
|
||||
|
||||
deleteBuffer(name);
|
||||
ll_aligned_free_16((U8*) buffer);
|
||||
ll_aligned_free((U8*) buffer);
|
||||
|
||||
if (mType == GL_ARRAY_BUFFER_ARB)
|
||||
{
|
||||
|
|
@ -306,7 +310,7 @@ void LLVBOPool::cleanup()
|
|||
|
||||
if (r.mClientData)
|
||||
{
|
||||
ll_aligned_free_16((void*) r.mClientData);
|
||||
ll_aligned_free((void*) r.mClientData);
|
||||
}
|
||||
|
||||
l.pop_front();
|
||||
|
|
@ -412,6 +416,7 @@ void LLVertexBuffer::seedPools()
|
|||
{
|
||||
sStreamVBOPool.seedPool();
|
||||
sDynamicVBOPool.seedPool();
|
||||
sDynamicCopyVBOPool.seedPool();
|
||||
sStreamIBOPool.seedPool();
|
||||
sDynamicIBOPool.seedPool();
|
||||
}
|
||||
|
|
@ -753,10 +758,10 @@ void LLVertexBuffer::drawRange(U32 mode, U32 start, U32 end, U32 count, U32 indi
|
|||
U16* idx = ((U16*) getIndicesPointer())+indices_offset;
|
||||
|
||||
stop_glerror();
|
||||
LLGLSLShader::startProfile();
|
||||
glDrawRangeElements(sGLMode[mode], start, end, count, GL_UNSIGNED_SHORT,
|
||||
LLGLSLShader::startProfile();
|
||||
glDrawRangeElements(sGLMode[mode], start, end, count, GL_UNSIGNED_SHORT,
|
||||
idx);
|
||||
LLGLSLShader::stopProfile(count, mode);
|
||||
LLGLSLShader::stopProfile(count, mode);
|
||||
stop_glerror();
|
||||
|
||||
|
||||
|
|
@ -910,6 +915,7 @@ void LLVertexBuffer::cleanupClass()
|
|||
sDynamicIBOPool.cleanup();
|
||||
sStreamVBOPool.cleanup();
|
||||
sDynamicVBOPool.cleanup();
|
||||
sDynamicCopyVBOPool.cleanup();
|
||||
|
||||
if(sPrivatePoolp)
|
||||
{
|
||||
|
|
@ -946,6 +952,8 @@ S32 LLVertexBuffer::determineUsage(S32 usage)
|
|||
|
||||
if (ret_usage && ret_usage != GL_STREAM_DRAW_ARB)
|
||||
{ //only stream_draw and dynamic_draw are supported when using VBOs, dynamic draw is the default
|
||||
if (ret_usage != GL_DYNAMIC_COPY_ARB)
|
||||
{
|
||||
if (sDisableVBOMapping)
|
||||
{ //always use stream draw if VBO mapping is disabled
|
||||
ret_usage = GL_STREAM_DRAW_ARB;
|
||||
|
|
@ -955,6 +963,7 @@ S32 LLVertexBuffer::determineUsage(S32 usage)
|
|||
ret_usage = GL_DYNAMIC_DRAW_ARB;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ret_usage;
|
||||
}
|
||||
|
|
@ -1102,10 +1111,15 @@ void LLVertexBuffer::genBuffer(U32 size)
|
|||
{
|
||||
mMappedData = sStreamVBOPool.allocate(mGLBuffer, mSize);
|
||||
}
|
||||
else
|
||||
else if (mUsage == GL_DYNAMIC_DRAW_ARB)
|
||||
{
|
||||
mMappedData = sDynamicVBOPool.allocate(mGLBuffer, mSize);
|
||||
}
|
||||
else
|
||||
{
|
||||
mMappedData = sDynamicCopyVBOPool.allocate(mGLBuffer, mSize);
|
||||
}
|
||||
|
||||
|
||||
sGLCount++;
|
||||
}
|
||||
|
|
@ -2144,21 +2158,14 @@ bool LLVertexBuffer::bindGLBuffer(bool force_bind)
|
|||
|
||||
if (useVBOs() && (force_bind || (mGLBuffer && (mGLBuffer != sGLRenderBuffer || !sVBOActive))))
|
||||
{
|
||||
LLFastTimer t(FTM_BIND_GL_BUFFER);
|
||||
/*if (sMapped)
|
||||
{
|
||||
llerrs << "VBO bound while another VBO mapped!" << llendl;
|
||||
}*/
|
||||
//LLFastTimer t(FTM_BIND_GL_BUFFER); <-- this timer is showing up as a hotspot (irony)
|
||||
|
||||
glBindBufferARB(GL_ARRAY_BUFFER_ARB, mGLBuffer);
|
||||
sGLRenderBuffer = mGLBuffer;
|
||||
sBindCount++;
|
||||
sVBOActive = true;
|
||||
|
||||
if (mGLArray)
|
||||
{
|
||||
llassert(sGLRenderArray == mGLArray);
|
||||
//mCachedRenderBuffer = mGLBuffer;
|
||||
}
|
||||
llassert(!mGLArray || sGLRenderArray == mGLArray);
|
||||
|
||||
ret = true;
|
||||
}
|
||||
|
|
@ -2236,7 +2243,7 @@ void LLVertexBuffer::setBuffer(U32 data_mask)
|
|||
required_mask |= required;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if ((data_mask & required_mask) != required_mask)
|
||||
{
|
||||
|
||||
|
|
@ -2440,7 +2447,8 @@ void LLVertexBuffer::setupVertexBuffer(U32 data_mask)
|
|||
if (data_mask & MAP_COLOR)
|
||||
{
|
||||
S32 loc = TYPE_COLOR;
|
||||
void* ptr = (void*)(base + mOffsets[TYPE_COLOR]);
|
||||
//bind emissive instead of color pointer if emissive is present
|
||||
void* ptr = (data_mask & MAP_EMISSIVE) ? (void*)(base + mOffsets[TYPE_EMISSIVE]) : (void*)(base + mOffsets[TYPE_COLOR]);
|
||||
glVertexAttribPointerARB(loc, 4, GL_UNSIGNED_BYTE, GL_TRUE, LLVertexBuffer::sTypeSize[TYPE_COLOR], ptr);
|
||||
}
|
||||
if (data_mask & MAP_EMISSIVE)
|
||||
|
|
@ -2448,6 +2456,12 @@ void LLVertexBuffer::setupVertexBuffer(U32 data_mask)
|
|||
S32 loc = TYPE_EMISSIVE;
|
||||
void* ptr = (void*)(base + mOffsets[TYPE_EMISSIVE]);
|
||||
glVertexAttribPointerARB(loc, 4, GL_UNSIGNED_BYTE, GL_TRUE, LLVertexBuffer::sTypeSize[TYPE_EMISSIVE], ptr);
|
||||
|
||||
if (!(data_mask & MAP_COLOR))
|
||||
{ //map emissive to color channel when color is not also being bound to avoid unnecessary shader swaps
|
||||
loc = TYPE_COLOR;
|
||||
glVertexAttribPointerARB(loc, 4, GL_UNSIGNED_BYTE, GL_TRUE, LLVertexBuffer::sTypeSize[TYPE_EMISSIVE], ptr);
|
||||
}
|
||||
}
|
||||
if (data_mask & MAP_WEIGHT)
|
||||
{
|
||||
|
|
@ -2533,8 +2547,7 @@ void LLVertexBuffer::setupVertexBuffer(U32 data_mask)
|
|||
LLVertexBuffer::MappedRegion::MappedRegion(S32 type, S32 index, S32 count)
|
||||
: mType(type), mIndex(index), mCount(count)
|
||||
{
|
||||
llassert(mType == LLVertexBuffer::TYPE_INDEX ||
|
||||
mType < LLVertexBuffer::TYPE_TEXTURE_INDEX);
|
||||
mEnd = mIndex+mCount;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -107,6 +107,7 @@ public:
|
|||
S32 mType;
|
||||
S32 mIndex;
|
||||
S32 mCount;
|
||||
S32 mEnd;
|
||||
|
||||
MappedRegion(S32 type, S32 index, S32 count);
|
||||
};
|
||||
|
|
@ -125,9 +126,10 @@ public:
|
|||
|
||||
static LLVBOPool sStreamVBOPool;
|
||||
static LLVBOPool sDynamicVBOPool;
|
||||
static LLVBOPool sDynamicCopyVBOPool;
|
||||
static LLVBOPool sStreamIBOPool;
|
||||
static LLVBOPool sDynamicIBOPool;
|
||||
|
||||
|
||||
static std::list<U32> sAvailableVAOName;
|
||||
static U32 sCurVAOName;
|
||||
|
||||
|
|
|
|||
|
|
@ -243,7 +243,6 @@ void LLConsole::draw()
|
|||
void LLConsole::Paragraph::makeParagraphColorSegments (const LLColor4 &color)
|
||||
{
|
||||
LLSD paragraph_color_segments;
|
||||
|
||||
paragraph_color_segments[0]["text"] =wstring_to_utf8str(mParagraphText);
|
||||
LLSD color_sd = color.getValue();
|
||||
paragraph_color_segments[0]["color"]=color_sd;
|
||||
|
|
|
|||
|
|
@ -37,6 +37,7 @@ class LLSD;
|
|||
class LLConsole : public LLFixedBuffer, public LLUICtrl, public LLInstanceTracker<LLConsole>
|
||||
{
|
||||
public:
|
||||
|
||||
typedef enum e_font_size
|
||||
{
|
||||
MONOSPACE = -1,
|
||||
|
|
|
|||
|
|
@ -112,6 +112,8 @@ struct LLCoordFloater : LLCoord<LL_COORD_FLOATER>
|
|||
bool operator!=(const LLCoordFloater& other) const { return !(*this == other); }
|
||||
|
||||
void setFloater(LLFloater& floater);
|
||||
|
||||
|
||||
};
|
||||
|
||||
class LLFloater : public LLPanel, public LLInstanceTracker<LLFloater>
|
||||
|
|
@ -121,6 +123,7 @@ class LLFloater : public LLPanel, public LLInstanceTracker<LLFloater>
|
|||
friend class LLMultiFloater;
|
||||
|
||||
public:
|
||||
|
||||
struct KeyCompare
|
||||
{
|
||||
// static bool compare(const LLSD& a, const LLSD& b);
|
||||
|
|
|
|||
|
|
@ -367,7 +367,6 @@ void LLKeywords::findSegments(std::vector<LLTextSegmentPtr>* seg_list, const LLW
|
|||
|
||||
const llwchar* base = wtext.c_str();
|
||||
const llwchar* cur = base;
|
||||
|
||||
while( *cur )
|
||||
{
|
||||
if( *cur == '\n' || cur == base )
|
||||
|
|
|
|||
|
|
@ -38,6 +38,7 @@ class LLLayoutPanel;
|
|||
class LLLayoutStack : public LLView, public LLInstanceTracker<LLLayoutStack>
|
||||
{
|
||||
public:
|
||||
|
||||
typedef enum e_layout_orientation
|
||||
{
|
||||
HORIZONTAL,
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ class LLModalDialog : public LLFloater
|
|||
{
|
||||
public:
|
||||
LLModalDialog( const LLSD& key, BOOL modal = true );
|
||||
/*virtual*/ ~LLModalDialog();
|
||||
virtual ~LLModalDialog();
|
||||
|
||||
/*virtual*/ BOOL postBuild();
|
||||
|
||||
|
|
|
|||
|
|
@ -1125,7 +1125,7 @@ LLNotificationChannel::LLNotificationChannel(const Params& p)
|
|||
mName(p.name.isProvided() ? p.name : LLUUID::generateNewID().asString())
|
||||
{
|
||||
BOOST_FOREACH(const std::string& source, p.sources)
|
||||
{
|
||||
{
|
||||
connectToChannel(source);
|
||||
}
|
||||
}
|
||||
|
|
@ -1209,6 +1209,10 @@ LLNotifications::LLNotifications()
|
|||
LLUICtrl::CommitCallbackRegistry::currentRegistrar().add("Notification.Show", boost::bind(&LLNotifications::addFromCallback, this, _2));
|
||||
}
|
||||
|
||||
void LLNotifications::clear()
|
||||
{
|
||||
mDefaultChannels.clear();
|
||||
}
|
||||
|
||||
// The expiration channel gets all notifications that are cancelled
|
||||
bool LLNotifications::expirationFilter(LLNotificationPtr pNotification)
|
||||
|
|
|
|||
|
|
@ -138,6 +138,7 @@ typedef LLFunctorRegistration<LLNotificationResponder> LLNotificationFunctorRegi
|
|||
class LLNotificationContext : public LLInstanceTracker<LLNotificationContext, LLUUID>
|
||||
{
|
||||
public:
|
||||
|
||||
LLNotificationContext() : LLInstanceTracker<LLNotificationContext, LLUUID>(LLUUID::generateNewID())
|
||||
{
|
||||
}
|
||||
|
|
@ -873,6 +874,13 @@ class LLNotifications :
|
|||
|
||||
friend class LLSingleton<LLNotifications>;
|
||||
public:
|
||||
|
||||
// Needed to clear up RefCounted things prior to actual destruction
|
||||
// as the singleton nature of the class makes them do "bad things"
|
||||
// on at least Mac, if not all 3 platforms
|
||||
//
|
||||
void clear();
|
||||
|
||||
// load all notification descriptions from file
|
||||
// calling more than once will overwrite existing templates
|
||||
// but never delete a template
|
||||
|
|
|
|||
|
|
@ -2379,7 +2379,6 @@ S32 LLTextBase::getDocIndexFromLocalCoord( S32 local_x, S32 local_y, BOOL round,
|
|||
{
|
||||
// Figure out which line we're nearest to.
|
||||
LLRect doc_rect = mDocumentView->getRect();
|
||||
|
||||
S32 doc_y = local_y - doc_rect.mBottom;
|
||||
|
||||
// binary search for line that starts before local_y
|
||||
|
|
|
|||
|
|
@ -57,7 +57,7 @@ class LLDragDropWin32
|
|||
#include <windows.h>
|
||||
#include <ole2.h>
|
||||
|
||||
// imposter class that does nothing
|
||||
// impostor class that does nothing
|
||||
class LLDragDropWin32
|
||||
{
|
||||
public:
|
||||
|
|
|
|||
|
|
@ -65,6 +65,7 @@
|
|||
- (unsigned long) getVramSize;
|
||||
|
||||
- (void) allowMarkedTextInput:(bool)allowed;
|
||||
- (void) viewDidEndLiveResize;
|
||||
|
||||
@end
|
||||
|
||||
|
|
|
|||
|
|
@ -91,6 +91,13 @@ attributedStringInfo getSegments(NSAttributedString *str)
|
|||
|
||||
@implementation LLOpenGLView
|
||||
|
||||
// Force a high quality update after live resizing
|
||||
- (void) viewDidEndLiveResize
|
||||
{
|
||||
NSSize size = [self frame].size;
|
||||
callResize(size.width, size.height);
|
||||
}
|
||||
|
||||
- (unsigned long)getVramSize
|
||||
{
|
||||
CGLRendererInfoObj info = 0;
|
||||
|
|
@ -119,9 +126,8 @@ attributedStringInfo getSegments(NSAttributedString *str)
|
|||
|
||||
- (void)windowResized:(NSNotification *)notification;
|
||||
{
|
||||
NSSize size = [self frame].size;
|
||||
|
||||
callResize(size.width, size.height);
|
||||
//NSSize size = [self frame].size;
|
||||
//callResize(size.width, size.height);
|
||||
}
|
||||
|
||||
- (void)dealloc
|
||||
|
|
|
|||
|
|
@ -42,6 +42,7 @@ class LLWindowCallbacks;
|
|||
class LLWindow : public LLInstanceTracker<LLWindow>
|
||||
{
|
||||
public:
|
||||
|
||||
struct LLWindowResolution
|
||||
{
|
||||
S32 mWidth;
|
||||
|
|
|
|||
|
|
@ -49,6 +49,7 @@ void handleQuit();
|
|||
bool runMainLoop();
|
||||
void initMainLoop();
|
||||
void cleanupViewer();
|
||||
void handleUrl(const char* url);
|
||||
|
||||
/* Defined in llwindowmacosx-objc.mm: */
|
||||
int createNSApp(int argc, const char **argv);
|
||||
|
|
|
|||
|
|
@ -57,7 +57,7 @@ void setupCocoa()
|
|||
[[NSUserDefaults standardUserDefaults] setObject:@"NO" forKey:@"NSTreatUnknownArgumentsAsOpen"];
|
||||
|
||||
[pool release];
|
||||
|
||||
|
||||
inited = true;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -79,8 +79,8 @@ void parse_string();
|
|||
#define yyfree indra_free
|
||||
|
||||
|
||||
int yylex( void );
|
||||
int yyparse( void );
|
||||
int yylex( void );
|
||||
int yyerror(const char *fmt, ...);
|
||||
|
||||
%}
|
||||
|
|
@ -161,6 +161,7 @@ int yyerror(const char *fmt, ...);
|
|||
"STATUS_DIE_AT_EDGE" { count(); yylval.ival = 0x80; return(INTEGER_CONSTANT); }
|
||||
"STATUS_RETURN_AT_EDGE" { count(); yylval.ival = 0x100; return(INTEGER_CONSTANT); }
|
||||
"STATUS_CAST_SHADOWS" { count(); yylval.ival = 0x200; return(INTEGER_CONSTANT); }
|
||||
"STATUS_BLOCK_GRAB_OBJECT" { count(); yylval.ival = 0x400; return(INTEGER_CONSTANT); }
|
||||
|
||||
"AGENT_FLYING" { count(); yylval.ival = AGENT_FLYING; return(INTEGER_CONSTANT); }
|
||||
"AGENT_ATTACHMENTS" { count(); yylval.ival = AGENT_ATTACHMENTS; return(INTEGER_CONSTANT); }
|
||||
|
|
@ -235,6 +236,8 @@ int yyerror(const char *fmt, ...);
|
|||
"PERMISSION_TRACK_CAMERA" { count(); yylval.ival = LSCRIPTRunTimePermissionBits[SCRIPT_PERMISSION_TRACK_CAMERA]; return(INTEGER_CONSTANT); }
|
||||
"PERMISSION_CONTROL_CAMERA" { count(); yylval.ival = LSCRIPTRunTimePermissionBits[SCRIPT_PERMISSION_CONTROL_CAMERA]; return(INTEGER_CONSTANT); }
|
||||
"PERMISSION_TELEPORT" { count(); yylval.ival = LSCRIPTRunTimePermissionBits[SCRIPT_PERMISSION_TELEPORT]; return(INTEGER_CONSTANT); }
|
||||
"PERMISSION_SILENT_ESTATE_MANAGEMENT" { count(); yylval.ival = LSCRIPTRunTimePermissionBits[SCRIPT_PERMISSION_SILENT_ESTATE_MANAGEMENT]; return(INTEGER_CONSTANT); }
|
||||
"PERMISSION_OVERRIDE_ANIMATIONS" { count(); yylval.ival = LSCRIPTRunTimePermissionBits[SCRIPT_PERMISSION_OVERRIDE_ANIMATIONS]; return(INTEGER_CONSTANT); }
|
||||
|
||||
"INVENTORY_TEXTURE" { count(); yylval.ival = LLAssetType::AT_TEXTURE; return(INTEGER_CONSTANT); }
|
||||
"INVENTORY_SOUND" { count(); yylval.ival = LLAssetType::AT_SOUND; return(INTEGER_CONSTANT); }
|
||||
|
|
@ -271,6 +274,22 @@ int yyerror(const char *fmt, ...);
|
|||
"OBJECT_OWNER" { count(); yylval.ival = OBJECT_OWNER; return(INTEGER_CONSTANT); }
|
||||
"OBJECT_GROUP" { count(); yylval.ival = OBJECT_GROUP; return(INTEGER_CONSTANT); }
|
||||
"OBJECT_CREATOR" { count(); yylval.ival = OBJECT_CREATOR; return(INTEGER_CONSTANT); }
|
||||
"OBJECT_RUNNING_SCRIPT_COUNT" { count(); yylval.ival = OBJECT_RUNNING_SCRIPT_COUNT; return(INTEGER_CONSTANT); }
|
||||
"OBJECT_TOTAL_SCRIPT_COUNT" { count(); yylval.ival = OBJECT_TOTAL_SCRIPT_COUNT; return(INTEGER_CONSTANT); }
|
||||
"OBJECT_SCRIPT_MEMORY" { count(); yylval.ival = OBJECT_SCRIPT_MEMORY; return(INTEGER_CONSTANT); }
|
||||
"OBJECT_SCRIPT_TIME" { count(); yylval.ival = OBJECT_SCRIPT_TIME; return(INTEGER_CONSTANT); }
|
||||
"OBJECT_PRIM_EQUIVALENCE" { count(); yylval.ival = OBJECT_PRIM_EQUIVALENCE; return(INTEGER_CONSTANT); }
|
||||
"OBJECT_SERVER_COST" { count(); yylval.ival = OBJECT_SERVER_COST; return(INTEGER_CONSTANT); }
|
||||
"OBJECT_STREAMING_COST" { count(); yylval.ival = OBJECT_STREAMING_COST; return(INTEGER_CONSTANT); }
|
||||
"OBJECT_PHYSICS_COST" { count(); yylval.ival = OBJECT_PHYSICS_COST; return(INTEGER_CONSTANT); }
|
||||
"OBJECT_CHARACTER_TIME" { count(); yylval.ival = OBJECT_CHARACTER_TIME; return(INTEGER_CONSTANT); }
|
||||
"OBJECT_ROOT" { count(); yylval.ival = OBJECT_ROOT; return(INTEGER_CONSTANT); }
|
||||
"OBJECT_ATTACHED_POINT" { count(); yylval.ival = OBJECT_ATTACHED_POINT; return(INTEGER_CONSTANT); }
|
||||
"OBJECT_PATHFINDING_TYPE" { count(); yylval.ival = OBJECT_PATHFINDING_TYPE; return(INTEGER_CONSTANT); }
|
||||
"OBJECT_PHYSICS" { count(); yylval.ival = OBJECT_PHYSICS; return(INTEGER_CONSTANT); }
|
||||
"OBJECT_PHANTOM" { count(); yylval.ival = OBJECT_PHANTOM; return(INTEGER_CONSTANT); }
|
||||
"OBJECT_TEMP_ON_REZ" { count(); yylval.ival = OBJECT_TEMP_ON_REZ; return(INTEGER_CONSTANT); }
|
||||
"OBJECT_RENDER_WEIGHT" { count(); yylval.ival = OBJECT_RENDER_WEIGHT; return(INTEGER_CONSTANT); }
|
||||
|
||||
"TYPE_INTEGER" { count(); yylval.ival = LST_INTEGER; return(INTEGER_CONSTANT); }
|
||||
"TYPE_FLOAT" { count(); yylval.ival = LST_FLOATINGPOINT; return(INTEGER_CONSTANT); }
|
||||
|
|
@ -376,6 +395,10 @@ int yyerror(const char *fmt, ...);
|
|||
"PSYS_PART_END_SCALE" { count(); yylval.ival = LLPS_PART_END_SCALE; return (INTEGER_CONSTANT); }
|
||||
"PSYS_PART_MAX_AGE" { count(); yylval.ival = LLPS_PART_MAX_AGE; return (INTEGER_CONSTANT); }
|
||||
|
||||
"PSYS_PART_BLEND_FUNC_SOURCE" { count(); yylval.ival = LLPS_PART_BLEND_FUNC_SOURCE; return (INTEGER_CONSTANT); }
|
||||
"PSYS_PART_BLEND_FUNC_DEST" { count(); yylval.ival = LLPS_PART_BLEND_FUNC_DEST; return (INTEGER_CONSTANT); }
|
||||
"PSYS_PART_START_GLOW" { count(); yylval.ival = LLPS_PART_START_GLOW; return (INTEGER_CONSTANT); }
|
||||
"PSYS_PART_END_GLOW" { count(); yylval.ival = LLPS_PART_END_GLOW; return (INTEGER_CONSTANT); }
|
||||
|
||||
"PSYS_PART_WIND_MASK" { count(); yylval.ival = LLPartData::LL_PART_WIND_MASK; return(INTEGER_CONSTANT); }
|
||||
"PSYS_PART_INTERP_COLOR_MASK" { count(); yylval.ival = LLPartData::LL_PART_INTERP_COLOR_MASK; return(INTEGER_CONSTANT); }
|
||||
|
|
@ -386,6 +409,16 @@ int yyerror(const char *fmt, ...);
|
|||
"PSYS_PART_TARGET_POS_MASK" { count(); yylval.ival = LLPartData::LL_PART_TARGET_POS_MASK; return(INTEGER_CONSTANT); }
|
||||
"PSYS_PART_EMISSIVE_MASK" { count(); yylval.ival = LLPartData::LL_PART_EMISSIVE_MASK; return(INTEGER_CONSTANT); }
|
||||
"PSYS_PART_TARGET_LINEAR_MASK" { count(); yylval.ival = LLPartData::LL_PART_TARGET_LINEAR_MASK; return(INTEGER_CONSTANT); }
|
||||
"PSYS_PART_RIBBON_MASK" { count(); yylval.ival = LLPartData::LL_PART_RIBBON_MASK; return(INTEGER_CONSTANT); }
|
||||
|
||||
"PSYS_PART_BF_ONE" { count(); yylval.ival = LLPartData::LL_PART_BF_ONE; return(INTEGER_CONSTANT); }
|
||||
"PSYS_PART_BF_ZERO" { count(); yylval.ival = LLPartData::LL_PART_BF_ZERO; return(INTEGER_CONSTANT); }
|
||||
"PSYS_PART_BF_DEST_COLOR" { count(); yylval.ival = LLPartData::LL_PART_BF_DEST_COLOR; return(INTEGER_CONSTANT); }
|
||||
"PSYS_PART_BF_SOURCE_COLOR" { count(); yylval.ival = LLPartData::LL_PART_BF_SOURCE_COLOR; return(INTEGER_CONSTANT); }
|
||||
"PSYS_PART_BF_ONE_MINUS_DEST_COLOR" { count(); yylval.ival = LLPartData::LL_PART_BF_ONE_MINUS_DEST_COLOR; return(INTEGER_CONSTANT); }
|
||||
"PSYS_PART_BF_ONE_MINUS_SOURCE_COLOR" { count(); yylval.ival = LLPartData::LL_PART_BF_ONE_MINUS_SOURCE_COLOR; return(INTEGER_CONSTANT); }
|
||||
"PSYS_PART_BF_SOURCE_ALPHA" { count(); yylval.ival = LLPartData::LL_PART_BF_SOURCE_ALPHA; return(INTEGER_CONSTANT); }
|
||||
"PSYS_PART_BF_ONE_MINUS_SOURCE_ALPHA" { count(); yylval.ival = LLPartData::LL_PART_BF_ONE_MINUS_SOURCE_ALPHA; return(INTEGER_CONSTANT); }
|
||||
|
||||
|
||||
"PSYS_SRC_MAX_AGE" { count(); yylval.ival = LLPS_SRC_MAX_AGE; return(INTEGER_CONSTANT); }
|
||||
|
|
@ -481,7 +514,17 @@ int yyerror(const char *fmt, ...);
|
|||
"PRIM_BUMP_SHINY" { count(); yylval.ival = LSL_PRIM_BUMP_SHINY; return(INTEGER_CONSTANT); }
|
||||
"PRIM_FULLBRIGHT" { count(); yylval.ival = LSL_PRIM_FULLBRIGHT; return(INTEGER_CONSTANT); }
|
||||
"PRIM_TEXGEN" { count(); yylval.ival = LSL_PRIM_TEXGEN; return(INTEGER_CONSTANT); }
|
||||
"PRIM_GLOW" { count(); yylval.ival = LSL_PRIM_GLOW; return(INTEGER_CONSTANT); }
|
||||
"PRIM_GLOW" { count(); yylval.ival = LSL_PRIM_GLOW; return(INTEGER_CONSTANT); }
|
||||
"PRIM_TEXT" { count(); yylval.ival = LSL_PRIM_TEXT; return(INTEGER_CONSTANT); }
|
||||
"PRIM_NAME" { count(); yylval.ival = LSL_PRIM_NAME; return(INTEGER_CONSTANT); }
|
||||
"PRIM_DESC" { count(); yylval.ival = LSL_PRIM_DESC; return(INTEGER_CONSTANT); }
|
||||
"PRIM_OMEGA" { count(); yylval.ival = LSL_PRIM_OMEGA; return(INTEGER_CONSTANT); }
|
||||
"PRIM_LINK_TARGET" { count(); yylval.ival = LSL_PRIM_LINK_TARGET; return(INTEGER_CONSTANT); }
|
||||
"PRIM_SLICE" { count(); yylval.ival = LSL_PRIM_SLICE; return(INTEGER_CONSTANT); }
|
||||
|
||||
"PRIM_PHYSICS_SHAPE_PRIM" { count(); yylval.ival = LSL_PRIM_PHYSICS_SHAPE_PRIM; return(INTEGER_CONSTANT); }
|
||||
"PRIM_PHYSICS_SHAPE_NONE" { count(); yylval.ival = LSL_PRIM_PHYSICS_SHAPE_NONE; return(INTEGER_CONSTANT); }
|
||||
"PRIM_PHYSICS_SHAPE_CONVEX" { count(); yylval.ival = LSL_PRIM_PHYSICS_SHAPE_CONVEX; return(INTEGER_CONSTANT); }
|
||||
|
||||
"PRIM_TYPE_BOX" { count(); yylval.ival = LSL_PRIM_TYPE_BOX; return(INTEGER_CONSTANT); }
|
||||
"PRIM_TYPE_CYLINDER" { count(); yylval.ival = LSL_PRIM_TYPE_CYLINDER; return(INTEGER_CONSTANT); }
|
||||
|
|
|
|||
|
|
@ -145,7 +145,6 @@ void LLScriptLSOParse::printGlobals(LLFILE *fp)
|
|||
// get offset to skip past name
|
||||
varoffset = global_v_offset;
|
||||
bytestream2integer(mRawData, global_v_offset);
|
||||
|
||||
// get typeexport
|
||||
type = *(mRawData + global_v_offset++);
|
||||
|
||||
|
|
@ -347,6 +346,7 @@ void LLScriptLSOParse::printStates(LLFILE *fp)
|
|||
S32 temp_end;
|
||||
|
||||
opcode_end = worst_case_opcode_end;
|
||||
(void)opcode_end;
|
||||
|
||||
for (k = LSTT_STATE_BEGIN; k < LSTT_STATE_END; k++)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -124,6 +124,7 @@ set(viewer_SOURCE_FILES
|
|||
llavatariconctrl.cpp
|
||||
llavatarlist.cpp
|
||||
llavatarlistitem.cpp
|
||||
llavatarrenderinfoaccountant.cpp
|
||||
llavatarpropertiesprocessor.cpp
|
||||
llblockedlistitem.cpp
|
||||
llblocklist.cpp
|
||||
|
|
@ -709,6 +710,7 @@ set(viewer_HEADER_FILES
|
|||
llavatarlist.h
|
||||
llavatarlistitem.h
|
||||
llavatarpropertiesprocessor.h
|
||||
llavatarrenderinfoaccountant.h
|
||||
llblockedlistitem.h
|
||||
llblocklist.h
|
||||
llbox.h
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
3.6.7
|
||||
3.6.8
|
||||
|
|
|
|||
|
|
@ -62,10 +62,12 @@ STATUS_ROTATE_X Passed in the llSetStatus library function. If FALSE, object do
|
|||
STATUS_ROTATE_Y Passed in the llSetStatus library function. If FALSE, object doesn't rotate around local Y axis
|
||||
STATUS_ROTATE_Z Passed in the llSetStatus library function. If FALSE, object doesn't rotate around local Z axis
|
||||
STATUS_SANDBOX Passed in the llSetStatus library function. If TRUE, object can't cross region boundaries or move more than 10 meters from its start location
|
||||
STATUS_BLOCK_GRAB Passed in the llSetStatus library function. If TRUE, object can't be grabbed and physically dragged
|
||||
STATUS_BLOCK_GRAB Passed in the llSetStatus library function. If TRUE, root prim of linkset (or unlinked prim) can't be grabbed and physically dragged
|
||||
STATUS_DIE_AT_EDGE Passed in the llSetStatus library function. If TRUE, objects that reach the edge of the world just die:rather than teleporting back to the owner
|
||||
STATUS_RETURN_AT_EDGE Passed in the llSetStatus library function. If TRUE, script rezzed objects that reach the edge of the world:are returned rather than killed:STATUS_RETURN_AT_EDGE trumps STATUS_DIE_AT_EDGE if both are set
|
||||
STATUS_CAST_SHADOWS Passed in the llSetStatus library function. If TRUE, object casts shadows on other objects
|
||||
STATUS_BLOCK_GRAB_OBJECT Passed in the llSetStatus library function. If TRUE, no prims in linkset can be grabbed or physically dragged
|
||||
|
||||
AGENT Passed in llSensor library function to look for other Agents
|
||||
ACTIVE Passed in llSensor library function to look for moving objects
|
||||
PASSIVE Passed in llSensor library function to look for objects that aren't moving
|
||||
|
|
@ -92,7 +94,7 @@ PERMISSION_CHANGE_LINKS Passed to llRequestPermissions library function to req
|
|||
PERMISSION_TRACK_CAMERA Passed to llRequestPermissions library function to request permission to track agent's camera
|
||||
PERMISSION_CONTROL_CAMERA Passed to llRequestPermissions library function to request permission to change agent's camera
|
||||
PERMISSION_TELEPORT Passed to llRequestPermissions library function to request permission to teleport agent
|
||||
SCRIPT_PERMISSION_SILENT_ESTATE_MANAGEMENT Passed to llRequestPermissions library function to request permission to silently modify estate access lists
|
||||
PERMISSION_SILENT_ESTATE_MANAGEMENT Passed to llRequestPermissions library function to request permission to silently modify estate access lists
|
||||
PERMISSION_OVERRIDE_ANIMATIONS Passed to llRequestPermissions library function to request permission to override animations on agent
|
||||
PERMISSION_RETURN_OBJECTS Passed to llRequestPermissions library function to request permission to return objects
|
||||
|
||||
|
|
@ -132,6 +134,7 @@ PSYS_PART_FOLLOW_VELOCITY_MASK
|
|||
PSYS_PART_TARGET_POS_MASK
|
||||
PSYS_PART_EMISSIVE_MASK
|
||||
PSYS_PART_TARGET_LINEAR_MASK
|
||||
PSYS_PART_RIBBON_MASK
|
||||
|
||||
PSYS_SRC_PATTERN
|
||||
PSYS_SRC_INNERANGLE Deprecated -- Use PSYS_SRC_ANGLE_BEGIN
|
||||
|
|
@ -148,12 +151,24 @@ PSYS_SRC_ACCEL
|
|||
PSYS_SRC_TEXTURE
|
||||
PSYS_SRC_TARGET_KEY
|
||||
PSYS_SRC_OMEGA
|
||||
PSYS_PART_BLEND_FUNC_SOURCE
|
||||
PSYS_PART_BLEND_FUNC_DEST
|
||||
PSYS_PART_START_GLOW
|
||||
PSYS_PART_END_GLOW
|
||||
|
||||
PSYS_SRC_PATTERN_DROP
|
||||
PSYS_SRC_PATTERN_EXPLODE
|
||||
PSYS_SRC_PATTERN_ANGLE
|
||||
PSYS_SRC_PATTERN_ANGLE_CONE
|
||||
PSYS_SRC_PATTERN_ANGLE_CONE_EMPTY
|
||||
PSYS_PART_BF_ONE
|
||||
PSYS_PART_BF_ZERO
|
||||
PSYS_PART_BF_DEST_COLOR
|
||||
PSYS_PART_BF_SOURCE_COLOR
|
||||
PSYS_PART_BF_ONE_MINUS_DEST_COLOR
|
||||
PSYS_PART_BF_ONE_MINUS_SOURCE_COLOR
|
||||
PSYS_PART_BF_SOURCE_ALPHA
|
||||
PSYS_PART_BF_ONE_MINUS_SOURCE_ALPHA
|
||||
|
||||
OBJECT_UNKNOWN_DETAIL Returned by llGetObjectDetails when passed an invalid object parameter type
|
||||
OBJECT_NAME Used with llGetObjectDetails to get an object's name
|
||||
|
|
@ -164,6 +179,23 @@ OBJECT_VELOCITY Used with llGetObjectDetails to get an object's velocity
|
|||
OBJECT_OWNER Used with llGetObjectDetails to get an object's owner's key. Will be NULL_KEY if group owned
|
||||
OBJECT_GROUP Used with llGetObjectDetails to get an object's group's key
|
||||
OBJECT_CREATOR Used with llGetObjectDetails to get an object's creator's key
|
||||
OBJECT_RUNNING_SCRIPT_COUNT Used with llGetObjectDetails to get the number of running scripts in an object
|
||||
OBJECT_TOTAL_SCRIPT_COUNT Used with llGetObjectDetails to get the total number of scripts in an object
|
||||
OBJECT_SCRIPT_MEMORY Used with llGetObjectDetails to get the total amount of script memory in an object
|
||||
OBJECT_SCRIPT_TIME Used with llGetObjectDetails to get the average script time used by an object
|
||||
OBJECT_PRIM_EQUIVALENCE Used with llGetObjectDetails to get the prim equivalence of an object
|
||||
OBJECT_SERVER_COST Used with llGetObjectDetails to get the server cost of an object
|
||||
OBJECT_STREAMING_COST Used with llGetObjectDetails to get the streaming (download) cost of an object
|
||||
OBJECT_PHYSICS_COST Used with llGetObjectDetails to get the physics cost of an object
|
||||
OBJECT_CHARACTER_TIME Used with llGetObjectDetails to get the pathfinding time (seconds) for an object
|
||||
OBJECT_ROOT Used with llGetObjectDetails to get root ID of an object
|
||||
OBJECT_ATTACHED_POINT Used with llGetObjectDetails to get attachent point where an object is attached
|
||||
OBJECT_PATHFINDING_TYPE Used with llGetObjectDetails to get the pathfinding setting of an object
|
||||
OBJECT_PHYSICS Used with llGetObjectDetails to determine if the object is physical or not
|
||||
OBJECT_PHANTOM Used with llGetObjectDetails to determine if the object is phantom or not
|
||||
OBJECT_TEMP_ON_REZ Used with llGetObjectDetails to determine if the object is temporary or not
|
||||
OBJECT_RENDER_WEIGHT Used with llGetObjectDetails to return an avatar's rendering weight
|
||||
|
||||
|
||||
# some vehicle params
|
||||
VEHICLE_TYPE_NONE
|
||||
|
|
@ -346,7 +378,7 @@ PRIM_MATERIAL Followed by PRIM_MATERIAL_STONE, PRIM_MATERIAL_METAL, PRIM_MATERI
|
|||
PRIM_PHYSICS Sets physics to TRUE or FALSE
|
||||
PRIM_FLEXIBLE Followed by TRUE or FALSE, integer softness, float gravity, float friction, float wind, float tension, and vector force
|
||||
PRIM_POINT_LIGHT Followed by TRUE or FALSE, vector color, float intensity, float radius, float falloff
|
||||
PRIM_TEMP_ON_REZ Sets temporay on rez to TRUE or FALSE
|
||||
PRIM_TEMP_ON_REZ Sets temporary on rez to TRUE or FALSE
|
||||
PRIM_PHANTOM Sets phantom to TRUE or FALSE
|
||||
PRIM_CAST_SHADOWS DEPRECATED. Takes 1 parameter, an integer, but has no effect when set and always returns 0 if used in llGetPrimitiveParams
|
||||
PRIM_POSITION Sets primitive position to a vector position
|
||||
|
|
@ -358,6 +390,19 @@ PRIM_BUMP_SHINY Followed by an integer face, one of PRIM_SHINY_NONE, PRIM_SHINY
|
|||
PRIM_FULLBRIGHT Followed by an integer face, and TRUE or FALSE
|
||||
PRIM_TEXGEN Followed by an integer face, and one of PRIM_TEXGEN_DEFAULT or PRIM_TEXGEN_PLANAR
|
||||
PRIM_GLOW Followed by an integer face, and a float from 0.0 to 1.0 specifying glow amount
|
||||
PRIM_TEXT Followed by string text, vector color, and float alpha
|
||||
PRIM_NAME Followed by string name
|
||||
PRIM_DESC Followed by string description
|
||||
PRIM_ROT_LOCAL Followed by rotation rot
|
||||
PRIM_PHYSICS_SHAPE_TYPE Followed by PRIM_PHYSICS_SHAPE_PRIM, PRIM_PHYSICS_SHAPE_NONE, or PRIM_PHYSICS_SHAPE_CONVEX
|
||||
PRIM_OMEGA Followed by vector axis, float spinrate, and float gain
|
||||
PRIM_POS_LOCAL Followed by vector position
|
||||
PRIM_LINK_TARGET Followed by integer link_target, then additional prim parameter flags
|
||||
PRIM_SLICE Followed by vector slice
|
||||
|
||||
PRIM_PHYSICS_SHAPE_PRIM Use the default physics shape
|
||||
PRIM_PHYSICS_SHAPE_CONVEX Use the convex hull of the prim shape for physics
|
||||
PRIM_PHYSICS_SHAPE_NONE Ignore this prim in the physics shape
|
||||
|
||||
PRIM_TYPE_BOX Followed by integer hole shape, vector cut, float hollow, vector twist,:vector top size, and vector top shear
|
||||
PRIM_TYPE_CYLINDER Followed by integer hole shape, vector cut, float hollow, vector twist,:vector top size, and vector top shear
|
||||
|
|
|
|||
|
|
@ -2224,6 +2224,17 @@
|
|||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
<key>DebugShowAvatarRenderInfo</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Show avatar render cost information</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
<key>DebugShowColor</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
|
|
@ -3579,13 +3590,13 @@
|
|||
</map>
|
||||
<key>FilterItemsMaxTimePerFrameUnvisible</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<key>Comment</key>
|
||||
<string>Max time devoted to items filtering per frame for non visible inventory listings (in milliseconds)</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>S32</string>
|
||||
<key>Value</key>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>S32</string>
|
||||
<key>Value</key>
|
||||
<integer>1</integer>
|
||||
</map>
|
||||
<key>FindLandArea</key>
|
||||
|
|
@ -9747,10 +9758,22 @@
|
|||
<key>Value</key>
|
||||
<integer>1</integer>
|
||||
</map>
|
||||
|
||||
<key>RenderAutoMuteByteLimit</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Maximum bytes of attachments before an avatar is automatically visually muted (0 for no limit).</string>
|
||||
<string>Maximum bytes of attachments before an avatar is rendered as a simple impostor (0 for no limit).</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>U32</string>
|
||||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
<key>RenderAutoMuteRenderWeightLimit</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Maximum render weight before an avatar is rendered as a simple impostor (0 to not use this limit).</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
|
|
@ -9761,7 +9784,7 @@
|
|||
<key>RenderAutoMuteSurfaceAreaLimit</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Maximum surface area of attachments before an avatar is automatically visually muted (0 for no limit).</string>
|
||||
<string>Maximum surface area of attachments before an avatar is rendered as a simple impostor (0 to not use this limit).</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
|
|
@ -9769,7 +9792,28 @@
|
|||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
|
||||
<key>RenderAutoMuteFunctions</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Developing feature to render some avatars using simple impostors or colored silhouettes. (Set to 7 for all functionality)</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>U32</string>
|
||||
<key>Value</key>
|
||||
<real>0</real>
|
||||
</map>
|
||||
<key>RenderAutoMuteLogging</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Show extra information in viewer logs about avatar rendering costs</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
<key>RenderAutoHideSurfaceAreaLimit</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
|
|
@ -9926,6 +9970,17 @@
|
|||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
<key>RevokePermsOnStopAnimation</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Clear animation permssions when choosing "Stop Animating Me"</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>1</integer>
|
||||
</map>
|
||||
<key>RotateRight</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
|
|
@ -14860,5 +14915,18 @@
|
|||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
|
||||
<key>VersionChannelName</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Version information generated by running the viewer</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>String</string>
|
||||
<key>Value</key>
|
||||
<string />
|
||||
</map>
|
||||
</map>
|
||||
</llsd>
|
||||
|
||||
|
|
|
|||
|
|
@ -185,7 +185,7 @@ vec3 calcPointLightOrSpotLight(vec3 light_col, vec3 diffuse, vec3 v, vec3 n, vec
|
|||
da *= spot*spot; // GL_SPOT_EXPONENT=2
|
||||
|
||||
//angular attenuation
|
||||
da *= max(dot(n, lv), 0.0);
|
||||
da *= max(dot(n, lv), 0.0);
|
||||
|
||||
float lit = max(da * dist_atten,0.0);
|
||||
|
||||
|
|
@ -458,7 +458,7 @@ void main()
|
|||
|
||||
float shadow = 1.0;
|
||||
|
||||
#if HAS_SHADOW
|
||||
#if HAS_SHADOW
|
||||
vec4 spos = pos;
|
||||
|
||||
if (spos.z > -shadow_clip.w)
|
||||
|
|
@ -541,7 +541,7 @@ void main()
|
|||
#else
|
||||
float final_alpha = diff.a;
|
||||
#endif
|
||||
|
||||
|
||||
// Insure we don't pollute depth with invis pixels in impostor rendering
|
||||
//
|
||||
if (final_alpha < 0.01)
|
||||
|
|
@ -549,7 +549,7 @@ void main()
|
|||
discard;
|
||||
}
|
||||
#else
|
||||
|
||||
|
||||
#ifdef USE_VERTEX_COLOR
|
||||
float final_alpha = diff.a * vertex_color.a;
|
||||
diff.rgb *= vertex_color.rgb;
|
||||
|
|
@ -591,16 +591,16 @@ void main()
|
|||
color.rgb *= gamma_diff.rgb;
|
||||
|
||||
//color.rgb = mix(diff.rgb, color.rgb, final_alpha);
|
||||
|
||||
|
||||
color.rgb = atmosLighting(color.rgb);
|
||||
color.rgb = scaleSoftClip(color.rgb);
|
||||
|
||||
vec4 light = vec4(0,0,0,0);
|
||||
|
||||
color.rgb = srgb_to_linear(color.rgb);
|
||||
|
||||
|
||||
#define LIGHT_LOOP(i) light.rgb += calcPointLightOrSpotLight(light_diffuse[i].rgb, diff.rgb, pos.xyz, norm, light_position[i], light_direction[i].xyz, light_attenuation[i].x, light_attenuation[i].y, light_attenuation[i].z);
|
||||
|
||||
|
||||
LIGHT_LOOP(1)
|
||||
LIGHT_LOOP(2)
|
||||
LIGHT_LOOP(3)
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue