Merge branch 'main' into DRTVWR-573-maint-R

# Conflicts:
#	autobuild.xml
#	indra/newview/llagent.cpp
#	indra/newview/llimview.cpp
#	indra/newview/llimview.h
#	indra/newview/llinventoryfunctions.cpp
#	indra/newview/llpanelmediasettingsgeneral.cpp
#	indra/newview/pipeline.cpp
master
Andrey Lihatskiy 2023-01-12 04:37:42 +02:00
commit f9866a3543
120 changed files with 1717 additions and 2518 deletions

View File

@ -184,9 +184,9 @@
<key>archive</key>
<map>
<key>hash</key>
<string>ae90d19cdcddf539f6d0b41cab12f918</string>
<string>7b4aceaed511d44c4d1354b2162b59c7</string>
<key>url</key>
<string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/72773/702861/bugsplat-1.0.7.552580-darwin64-552580.tar.bz2</string>
<string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/107398/936936/bugsplat-1.0.7.576560-darwin64-576560.tar.bz2</string>
</map>
<key>name</key>
<string>darwin64</string>
@ -196,9 +196,9 @@
<key>archive</key>
<map>
<key>hash</key>
<string>f5936eceb6a33ff0f1cc31996a40f29c</string>
<string>53918c7c74b943cdc0bb90caf9657a84</string>
<key>url</key>
<string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/72774/702905/bugsplat-3.6.0.8.552580-windows-552580.tar.bz2</string>
<string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/107400/936949/bugsplat-4.0.3.0.576560-windows-576560.tar.bz2</string>
</map>
<key>name</key>
<string>windows</string>
@ -208,16 +208,16 @@
<key>archive</key>
<map>
<key>hash</key>
<string>9cd940754e53e0670030b3da5ba8f373</string>
<string>19d6a55db101f02e7eb531daf3e8cfd1</string>
<key>url</key>
<string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/72775/702906/bugsplat-3.6.0.8.552580-windows64-552580.tar.bz2</string>
<string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/107401/936948/bugsplat-.576560-windows64-576560.tar.bz2</string>
</map>
<key>name</key>
<string>windows64</string>
</map>
</map>
<key>version</key>
<string>3.6.0.8.552580</string>
<string>4.0.3.0.576560</string>
</map>
<key>colladadom</key>
<map>
@ -602,9 +602,9 @@
<key>archive</key>
<map>
<key>hash</key>
<string>2c619c1bef969dc42b4f44a4651b314e</string>
<string>8de71c518c248d77f70f87ab5e9de732</string>
<key>url</key>
<string>https://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/98369/869141/fmodstudio-2.02.06.570913-darwin64-570913.tar.bz2</string>
<string>https://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/105828/925920/fmodstudio-2.02.06.575716-darwin64-575716.tar.bz2</string>
</map>
<key>name</key>
<string>darwin64</string>
@ -626,9 +626,9 @@
<key>archive</key>
<map>
<key>hash</key>
<string>875ccd8c1feec8ff03438d453371044b</string>
<string>2eea946ee7a572b748cec0c623ade3ef</string>
<key>url</key>
<string>https://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/98371/869153/fmodstudio-2.02.06.570913-windows-570913.tar.bz2</string>
<string>https://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/105830/925932/fmodstudio-2.02.06.575716-windows-575716.tar.bz2</string>
</map>
<key>name</key>
<string>windows</string>
@ -638,16 +638,16 @@
<key>archive</key>
<map>
<key>hash</key>
<string>5e402f4828741bce942e2ced318cd02a</string>
<string>483d6fd5d057b0a681bffef9b8b9d927</string>
<key>url</key>
<string>https://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/98372/869154/fmodstudio-2.02.06.570913-windows64-570913.tar.bz2</string>
<string>https://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/105829/925931/fmodstudio-2.02.06.575716-windows64-575716.tar.bz2</string>
</map>
<key>name</key>
<string>windows64</string>
</map>
</map>
<key>version</key>
<string>2.02.06.570913</string>
<string>2.02.06.575716</string>
</map>
<key>fontconfig</key>
<map>

View File

@ -282,6 +282,7 @@ Beq Janus
SL-11300
SL-15709
SL-16021
SL-18637
Beth Walcher
Bezilon Kasei
Biancaluce Robbiani

View File

@ -108,7 +108,6 @@ set(llcommon_SOURCE_FILES
llsys.cpp
lltempredirect.cpp
llthread.cpp
llthreadlocalstorage.cpp
llthreadsafequeue.cpp
lltimer.cpp
lltrace.cpp

View File

@ -30,7 +30,6 @@
#include "llapr.h"
#include "llmutex.h"
#include "apr_dso.h"
#include "llthreadlocalstorage.h"
apr_pool_t *gAPRPoolp = NULL; // Global APR memory pool
LLVolatileAPRPool *LLAPRFile::sAPRFilePoolp = NULL ; //global volatile APR memory pool.
@ -54,7 +53,6 @@ void ll_init_apr()
LLAPRFile::sAPRFilePoolp = new LLVolatileAPRPool(FALSE) ;
}
LLThreadLocalPointerBase::initAllThreadLocalStorage();
gAPRInitialized = true;
}
@ -70,8 +68,6 @@ void ll_cleanup_apr()
LL_DEBUGS("APR") << "Cleaning up APR" << LL_ENDL;
LLThreadLocalPointerBase::destroyAllThreadLocalStorage();
if (gAPRPoolp)
{
apr_pool_destroy(gAPRPoolp);

View File

@ -1,115 +0,0 @@
/**
* @file llthreadlocalstorage.cpp
* @author Richard
* @date 2013-1-11
* @brief implementation of thread local storage utility classes
*
* $LicenseInfo:firstyear=2013&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$
*/
#include "linden_common.h"
#include "llthreadlocalstorage.h"
#include "llapr.h"
//
//LLThreadLocalPointerBase
//
bool LLThreadLocalPointerBase::sInitialized = false;
void LLThreadLocalPointerBase::set( void* value )
{
llassert(sInitialized && mThreadKey);
apr_status_t result = apr_threadkey_private_set((void*)value, mThreadKey);
if (result != APR_SUCCESS)
{
ll_apr_warn_status(result);
LL_ERRS() << "Failed to set thread local data" << LL_ENDL;
}
}
void* LLThreadLocalPointerBase::get() const
{
// llassert(sInitialized);
void* ptr;
apr_status_t result =
apr_threadkey_private_get(&ptr, mThreadKey);
if (result != APR_SUCCESS)
{
ll_apr_warn_status(result);
LL_ERRS() << "Failed to get thread local data" << LL_ENDL;
}
return ptr;
}
void LLThreadLocalPointerBase::initStorage( )
{
apr_status_t result = apr_threadkey_private_create(&mThreadKey, NULL, gAPRPoolp);
if (result != APR_SUCCESS)
{
ll_apr_warn_status(result);
LL_ERRS() << "Failed to allocate thread local data" << LL_ENDL;
}
}
void LLThreadLocalPointerBase::destroyStorage()
{
if (sInitialized)
{
if (mThreadKey)
{
apr_status_t result = apr_threadkey_private_delete(mThreadKey);
if (result != APR_SUCCESS)
{
ll_apr_warn_status(result);
LL_ERRS() << "Failed to delete thread local data" << LL_ENDL;
}
}
}
}
//static
void LLThreadLocalPointerBase::initAllThreadLocalStorage()
{
if (!sInitialized)
{
for (auto& base : instance_snapshot())
{
base.initStorage();
}
sInitialized = true;
}
}
//static
void LLThreadLocalPointerBase::destroyAllThreadLocalStorage()
{
if (sInitialized)
{
//for (auto& base : instance_snapshot())
//{
// base.destroyStorage();
//}
sInitialized = false;
}
}

View File

@ -30,100 +30,6 @@
#include "llinstancetracker.h"
class LLThreadLocalPointerBase : public LLInstanceTracker<LLThreadLocalPointerBase>
{
public:
LLThreadLocalPointerBase()
: mThreadKey(NULL)
{
if (sInitialized)
{
initStorage();
}
}
LLThreadLocalPointerBase( const LLThreadLocalPointerBase& other)
: mThreadKey(NULL)
{
if (sInitialized)
{
initStorage();
}
}
~LLThreadLocalPointerBase()
{
destroyStorage();
}
static void initAllThreadLocalStorage();
static void destroyAllThreadLocalStorage();
protected:
void set(void* value);
void* get() const;
void initStorage();
void destroyStorage();
protected:
struct apr_threadkey_t* mThreadKey;
static bool sInitialized;
};
template <typename T>
class LLThreadLocalPointer : public LLThreadLocalPointerBase
{
public:
LLThreadLocalPointer()
{}
explicit LLThreadLocalPointer(T* value)
{
set(value);
}
LLThreadLocalPointer(const LLThreadLocalPointer<T>& other)
: LLThreadLocalPointerBase(other)
{
set(other.get());
}
LL_FORCE_INLINE T* get() const
{
return (T*)LLThreadLocalPointerBase::get();
}
T* operator -> () const
{
return (T*)get();
}
T& operator*() const
{
return *(T*)get();
}
LLThreadLocalPointer<T>& operator = (T* value)
{
set((void*)value);
return *this;
}
bool operator ==(const T* other) const
{
if (!sInitialized) return false;
return get() == other;
}
bool isNull() const { return !sInitialized || get() == NULL; }
bool notNull() const { return sInitialized && get() != NULL; }
};
template<typename DERIVED_TYPE>
class LLThreadLocalSingletonPointer
{
@ -139,10 +45,10 @@ public:
}
private:
static LL_THREAD_LOCAL DERIVED_TYPE* sInstance;
static thread_local DERIVED_TYPE* sInstance;
};
template<typename DERIVED_TYPE>
LL_THREAD_LOCAL DERIVED_TYPE* LLThreadLocalSingletonPointer<DERIVED_TYPE>::sInstance = NULL;
thread_local DERIVED_TYPE* LLThreadLocalSingletonPointer<DERIVED_TYPE>::sInstance = NULL;
#endif // LL_LLTHREADLOCALSTORAGE_H

View File

@ -40,7 +40,7 @@ StatBase::StatBase( const char* name, const char* description )
mDescription(description ? description : "")
{
#ifndef LL_RELEASE_FOR_DOWNLOAD
if (LLTrace::get_thread_recorder().notNull())
if (LLTrace::get_thread_recorder() != NULL)
{
LL_ERRS() << "Attempting to declare trace object after program initialization. Trace objects should be statically initialized." << LL_ENDL;
}

View File

@ -93,7 +93,7 @@ void AccumulatorBufferGroup::makeCurrent()
mStackTimers.makeCurrent();
mMemStats.makeCurrent();
ThreadRecorder* thread_recorder = get_thread_recorder().get();
ThreadRecorder* thread_recorder = get_thread_recorder();
AccumulatorBuffer<TimeBlockAccumulator>& timer_accumulator_buffer = mStackTimers;
// update stacktimer parent pointers
for (S32 i = 0, end_i = mStackTimers.size(); i < end_i; i++)

View File

@ -95,7 +95,7 @@ Recording::~Recording()
// allow recording destruction without thread recorder running,
// otherwise thread shutdown could crash if a recording outlives the thread recorder
// besides, recording construction and destruction is fine without a recorder...just don't attempt to start one
if (isStarted() && LLTrace::get_thread_recorder().notNull())
if (isStarted() && LLTrace::get_thread_recorder() != NULL)
{
LLTrace::get_thread_recorder()->deactivate(mBuffers.write());
}
@ -112,9 +112,9 @@ void Recording::update()
// must have
llassert(mActiveBuffers != NULL
&& LLTrace::get_thread_recorder().notNull());
&& LLTrace::get_thread_recorder() != NULL);
if(!mActiveBuffers->isCurrent())
if(!mActiveBuffers->isCurrent() && LLTrace::get_thread_recorder() != NULL)
{
AccumulatorBufferGroup* buffers = mBuffers.write();
LLTrace::get_thread_recorder()->deactivate(buffers);
@ -144,7 +144,7 @@ void Recording::handleStart()
mSamplingTimer.reset();
mBuffers.setStayUnique(true);
// must have thread recorder running on this thread
llassert(LLTrace::get_thread_recorder().notNull());
llassert(LLTrace::get_thread_recorder() != NULL);
mActiveBuffers = LLTrace::get_thread_recorder()->activate(mBuffers.write());
#endif
}
@ -155,7 +155,7 @@ void Recording::handleStop()
#if LL_TRACE_ENABLED
mElapsedSeconds += mSamplingTimer.getElapsedTimeF64();
// must have thread recorder running on this thread
llassert(LLTrace::get_thread_recorder().notNull());
llassert(LLTrace::get_thread_recorder() != NULL);
LLTrace::get_thread_recorder()->deactivate(mBuffers.write());
mActiveBuffers = NULL;
mBuffers.setStayUnique(false);
@ -1181,8 +1181,8 @@ void ExtendablePeriodicRecording::handleSplitTo(ExtendablePeriodicRecording& oth
PeriodicRecording& get_frame_recording()
{
static LLThreadLocalPointer<PeriodicRecording> sRecording(new PeriodicRecording(200, PeriodicRecording::STARTED));
return *sRecording;
static thread_local PeriodicRecording sRecording(200, PeriodicRecording::STARTED);
return sRecording;
}
}

View File

@ -308,13 +308,13 @@ ThreadRecorder* get_master_thread_recorder()
return sMasterThreadRecorder;
}
LLThreadLocalPointer<ThreadRecorder>& get_thread_recorder_ptr()
ThreadRecorder*& get_thread_recorder_ptr()
{
static LLThreadLocalPointer<ThreadRecorder> s_thread_recorder;
static thread_local ThreadRecorder* s_thread_recorder;
return s_thread_recorder;
}
const LLThreadLocalPointer<ThreadRecorder>& get_thread_recorder()
ThreadRecorder* get_thread_recorder()
{
return get_thread_recorder_ptr();
}

View File

@ -32,7 +32,6 @@
#include "llmutex.h"
#include "lltraceaccumulators.h"
#include "llthreadlocalstorage.h"
namespace LLTrace
{
@ -92,7 +91,7 @@ namespace LLTrace
};
const LLThreadLocalPointer<ThreadRecorder>& get_thread_recorder();
ThreadRecorder* get_thread_recorder();
void set_thread_recorder(ThreadRecorder*);
void set_master_thread_recorder(ThreadRecorder*);

View File

@ -5013,6 +5013,17 @@ void LLVolumeFace::optimize(F32 angle_cutoff)
{
U16 index = mIndices[i];
if (index >= mNumVertices)
{
// invalid index
// replace with a valid index to avoid crashes
index = mNumVertices - 1;
mIndices[i] = index;
// Needs better logging
LL_DEBUGS_ONCE("LLVOLUME") << "Invalid index, substituting" << LL_ENDL;
}
LLVolumeFace::VertexData cv;
getVertexData(index, cv);
@ -5385,6 +5396,17 @@ bool LLVolumeFace::cacheOptimize()
U16 idx = mIndices[i];
U32 tri_idx = i / 3;
if (idx >= mNumVertices)
{
// invalid index
// replace with a valid index to avoid crashes
idx = mNumVertices - 1;
mIndices[i] = idx;
// Needs better logging
LL_DEBUGS_ONCE("LLVOLUME") << "Invalid index, substituting" << LL_ENDL;
}
vertex_data[idx].mTriangles.push_back(&(triangle_data[tri_idx]));
vertex_data[idx].mIdx = idx;
triangle_data[tri_idx].mVertex[i % 3] = &(vertex_data[idx]);

View File

@ -666,7 +666,6 @@ char const* const _PREHASH_GroupRolesCount = LLMessageStringTable::getInstance()
char const* const _PREHASH_SimulatorBlock = LLMessageStringTable::getInstance()->getString("SimulatorBlock");
char const* const _PREHASH_GroupID = LLMessageStringTable::getInstance()->getString("GroupID");
char const* const _PREHASH_AgentVel = LLMessageStringTable::getInstance()->getString("AgentVel");
char const* const _PREHASH_RequestImage = LLMessageStringTable::getInstance()->getString("RequestImage");
char const* const _PREHASH_NetStats = LLMessageStringTable::getInstance()->getString("NetStats");
char const* const _PREHASH_AgentPos = LLMessageStringTable::getInstance()->getString("AgentPos");
char const* const _PREHASH_AgentSit = LLMessageStringTable::getInstance()->getString("AgentSit");
@ -1047,7 +1046,6 @@ char const* const _PREHASH_SortOrder = LLMessageStringTable::getInstance()->getS
char const* const _PREHASH_Hunter = LLMessageStringTable::getInstance()->getString("Hunter");
char const* const _PREHASH_SunAngVelocity = LLMessageStringTable::getInstance()->getString("SunAngVelocity");
char const* const _PREHASH_BinaryBucket = LLMessageStringTable::getInstance()->getString("BinaryBucket");
char const* const _PREHASH_ImagePacket = LLMessageStringTable::getInstance()->getString("ImagePacket");
char const* const _PREHASH_StartGroupProposal = LLMessageStringTable::getInstance()->getString("StartGroupProposal");
char const* const _PREHASH_EnergyLevel = LLMessageStringTable::getInstance()->getString("EnergyLevel");
char const* const _PREHASH_PriceForListing = LLMessageStringTable::getInstance()->getString("PriceForListing");
@ -1236,7 +1234,6 @@ char const* const _PREHASH_ForceScriptControlRelease = LLMessageStringTable::get
char const* const _PREHASH_ParcelRelease = LLMessageStringTable::getInstance()->getString("ParcelRelease");
char const* const _PREHASH_VFileType = LLMessageStringTable::getInstance()->getString("VFileType");
char const* const _PREHASH_EjectGroupMemberReply = LLMessageStringTable::getInstance()->getString("EjectGroupMemberReply");
char const* const _PREHASH_ImageData = LLMessageStringTable::getInstance()->getString("ImageData");
char const* const _PREHASH_SimulatorViewerTimeMessage = LLMessageStringTable::getInstance()->getString("SimulatorViewerTimeMessage");
char const* const _PREHASH_Rotation = LLMessageStringTable::getInstance()->getString("Rotation");
char const* const _PREHASH_Selection = LLMessageStringTable::getInstance()->getString("Selection");

View File

@ -666,7 +666,6 @@ extern char const* const _PREHASH_GroupRolesCount;
extern char const* const _PREHASH_SimulatorBlock;
extern char const* const _PREHASH_GroupID;
extern char const* const _PREHASH_AgentVel;
extern char const* const _PREHASH_RequestImage;
extern char const* const _PREHASH_NetStats;
extern char const* const _PREHASH_AgentPos;
extern char const* const _PREHASH_AgentSit;
@ -1047,7 +1046,6 @@ extern char const* const _PREHASH_SortOrder;
extern char const* const _PREHASH_Hunter;
extern char const* const _PREHASH_SunAngVelocity;
extern char const* const _PREHASH_BinaryBucket;
extern char const* const _PREHASH_ImagePacket;
extern char const* const _PREHASH_StartGroupProposal;
extern char const* const _PREHASH_EnergyLevel;
extern char const* const _PREHASH_PriceForListing;

View File

@ -330,7 +330,10 @@ LLModel::EModelStatus load_face_from_dom_triangles(
// VFExtents change
face.mExtents[0].set(v[0], v[1], v[2]);
face.mExtents[1].set(v[0], v[1], v[2]);
point_map.clear();
verts.clear();
indices.clear();
point_map.clear();
}
}

View File

@ -57,6 +57,8 @@ public:
mutable std::vector<S32> mJointNums;
typedef std::vector<LLMatrix4a, boost::alignment::aligned_allocator<LLMatrix4a, 16>> matrix_list_t;
matrix_list_t mInvBindMatrix;
// bones/joints position overrides
matrix_list_t mAlternateBindMatrix;
LL_ALIGN_16(LLMatrix4a mBindShapeMatrix);

View File

@ -38,7 +38,8 @@ typedef enum e_chat_source_type
CHAT_SOURCE_AGENT = 1,
CHAT_SOURCE_OBJECT = 2,
CHAT_SOURCE_TELEPORT = 3,
CHAT_SOURCE_UNKNOWN = 4
CHAT_SOURCE_UNKNOWN = 4,
CHAT_SOURCE_REGION = 5,
} EChatSourceType;
typedef enum e_chat_type

View File

@ -203,11 +203,9 @@ void LLCheckBoxCtrl::reshape(S32 width, S32 height, BOOL called_from_parent)
// it will work fine in case of decrease of space, but if we get more space or text
// becomes longer, label will fail to grow so reinit label's dimentions.
static LLUICachedControl<S32> llcheckboxctrl_hpad("UICheckboxctrlHPad", 0);
LLRect label_rect = mLabel->getRect();
S32 new_width = getRect().getWidth() - label_rect.mLeft - llcheckboxctrl_hpad;
label_rect.mRight = label_rect.mLeft + new_width;
mLabel->setRect(label_rect);
S32 new_width = rect.getWidth() - label_rect.mLeft;
mLabel->reshape(new_width, label_rect.getHeight(), TRUE);
S32 label_top = label_rect.mTop;
mLabel->reshapeToFitText(TRUE);

View File

@ -172,7 +172,7 @@ public:
virtual BOOL removeItem() = 0;
virtual void removeBatch(std::vector<LLFolderViewModelItem*>& batch) = 0;
virtual BOOL isItemCopyable() const = 0;
virtual bool isItemCopyable(bool can_copy_as_link = true) const = 0;
virtual BOOL copyToClipboard() const = 0;
virtual BOOL cutToClipboard() = 0;
virtual bool isCutToClipboard() { return false; };

View File

@ -3395,3 +3395,42 @@ boost::signals2::connection LLScrollListCtrl::setIsFriendCallback(const is_frien
}
return mIsFriendSignal->connect(cb);
}
bool LLScrollListCtrl::highlightMatchingItems(const std::string& filter_str)
{
if (filter_str == "" || filter_str == " ")
{
clearHighlightedItems();
return false;
}
bool res = false;
setHighlightedColor(LLUIColorTable::instance().getColor("SearchableControlHighlightColor", LLColor4::red));
std::string filter_str_lc(filter_str);
LLStringUtil::toLower(filter_str_lc);
std::vector<LLScrollListItem*> data = getAllData();
std::vector<LLScrollListItem*>::iterator iter = data.begin();
while (iter != data.end())
{
LLScrollListCell* cell = (*iter)->getColumn(0);
if (cell)
{
std::string value = cell->getValue().asString();
LLStringUtil::toLower(value);
if (value.find(filter_str_lc) == std::string::npos)
{
(*iter)->setHighlighted(false);
}
else
{
(*iter)->setHighlighted(true);
res = true;
}
}
iter++;
}
return res;
}

View File

@ -419,6 +419,8 @@ public:
void setNeedsSort(bool val = true) { mSorted = !val; }
void dirtyColumns(); // some operation has potentially affected column layout or ordering
bool highlightMatchingItems(const std::string& filter_str);
boost::signals2::connection setSortCallback(sort_signal_t::slot_type cb )
{
if (!mSortCallback) mSortCallback = new sort_signal_t();

View File

@ -101,7 +101,10 @@ LLSpinCtrl::LLSpinCtrl(const LLSpinCtrl::Params& p)
// Spin buttons
LLButton::Params up_button_params(p.up_button);
up_button_params.rect = LLRect(btn_left, getRect().getHeight(), btn_right, getRect().getHeight() - spinctrl_btn_height);
up_button_params.click_callback.function(boost::bind(&LLSpinCtrl::onUpBtn, this, _2));
// Click callback starts within the button and ends within the button,
// but LLSpinCtrl handles the action continuosly so subsribers needs to
// be informed about click ending even if outside view, use 'up' instead
up_button_params.mouse_up_callback.function(boost::bind(&LLSpinCtrl::onUpBtn, this, _2));
up_button_params.mouse_held_callback.function(boost::bind(&LLSpinCtrl::onUpBtn, this, _2));
up_button_params.commit_on_capture_lost = true;
@ -110,7 +113,7 @@ LLSpinCtrl::LLSpinCtrl(const LLSpinCtrl::Params& p)
LLButton::Params down_button_params(p.down_button);
down_button_params.rect = LLRect(btn_left, getRect().getHeight() - spinctrl_btn_height, btn_right, getRect().getHeight() - 2 * spinctrl_btn_height);
down_button_params.click_callback.function(boost::bind(&LLSpinCtrl::onDownBtn, this, _2));
down_button_params.mouse_up_callback.function(boost::bind(&LLSpinCtrl::onDownBtn, this, _2));
down_button_params.mouse_held_callback.function(boost::bind(&LLSpinCtrl::onDownBtn, this, _2));
down_button_params.commit_on_capture_lost = true;
mDownBtn = LLUICtrlFactory::create<LLButton>(down_button_params);

View File

@ -355,95 +355,113 @@ void LLTextBase::onValueChange(S32 start, S32 end)
{
}
std::vector<LLRect> LLTextBase::getSelctionRects()
{
// Nor supposed to be called without selection
llassert(hasSelection());
llassert(!mLineInfoList.empty());
std::vector<LLRect> selection_rects;
S32 selection_left = llmin(mSelectionStart, mSelectionEnd);
S32 selection_right = llmax(mSelectionStart, mSelectionEnd);
// Skip through the lines we aren't drawing.
LLRect content_display_rect = getVisibleDocumentRect();
// binary search for line that starts before top of visible buffer
line_list_t::const_iterator line_iter = std::lower_bound(mLineInfoList.begin(), mLineInfoList.end(), content_display_rect.mTop, compare_bottom());
line_list_t::const_iterator end_iter = std::upper_bound(mLineInfoList.begin(), mLineInfoList.end(), content_display_rect.mBottom, compare_top());
bool done = false;
// Find the coordinates of the selected area
for (; line_iter != end_iter && !done; ++line_iter)
{
// is selection visible on this line?
if (line_iter->mDocIndexEnd > selection_left && line_iter->mDocIndexStart < selection_right)
{
segment_set_t::iterator segment_iter;
S32 segment_offset;
getSegmentAndOffset(line_iter->mDocIndexStart, &segment_iter, &segment_offset);
// Use F32 otherwise a string of multiple segments
// will accumulate a large error
F32 left_precise = line_iter->mRect.mLeft;
F32 right_precise = line_iter->mRect.mLeft;
for (; segment_iter != mSegments.end(); ++segment_iter, segment_offset = 0)
{
LLTextSegmentPtr segmentp = *segment_iter;
S32 segment_line_start = segmentp->getStart() + segment_offset;
S32 segment_line_end = llmin(segmentp->getEnd(), line_iter->mDocIndexEnd);
if (segment_line_start > segment_line_end) break;
F32 segment_width = 0;
S32 segment_height = 0;
// if selection after beginning of segment
if (selection_left >= segment_line_start)
{
S32 num_chars = llmin(selection_left, segment_line_end) - segment_line_start;
segmentp->getDimensionsF32(segment_offset, num_chars, segment_width, segment_height);
left_precise += segment_width;
}
// if selection_right == segment_line_end then that means we are the first character of the next segment
// or first character of the next line, in either case we want to add the length of the current segment
// to the selection rectangle and continue.
// if selection right > segment_line_end then selection spans end of current segment...
if (selection_right >= segment_line_end)
{
// extend selection slightly beyond end of line
// to indicate selection of newline character (use "n" character to determine width)
S32 num_chars = segment_line_end - segment_line_start;
segmentp->getDimensionsF32(segment_offset, num_chars, segment_width, segment_height);
right_precise += segment_width;
}
// else if selection ends on current segment...
else
{
S32 num_chars = selection_right - segment_line_start;
segmentp->getDimensionsF32(segment_offset, num_chars, segment_width, segment_height);
right_precise += segment_width;
break;
}
}
LLRect selection_rect;
selection_rect.mLeft = left_precise;
selection_rect.mRight = right_precise;
selection_rect.mBottom = line_iter->mRect.mBottom;
selection_rect.mTop = line_iter->mRect.mTop;
selection_rects.push_back(selection_rect);
}
}
return selection_rects;
}
// Draws the black box behind the selected text
void LLTextBase::drawSelectionBackground()
{
// Draw selection even if we don't have keyboard focus for search/replace
if( hasSelection() && !mLineInfoList.empty())
{
std::vector<LLRect> selection_rects;
S32 selection_left = llmin( mSelectionStart, mSelectionEnd );
S32 selection_right = llmax( mSelectionStart, mSelectionEnd );
// Skip through the lines we aren't drawing.
LLRect content_display_rect = getVisibleDocumentRect();
// binary search for line that starts before top of visible buffer
line_list_t::const_iterator line_iter = std::lower_bound(mLineInfoList.begin(), mLineInfoList.end(), content_display_rect.mTop, compare_bottom());
line_list_t::const_iterator end_iter = std::upper_bound(mLineInfoList.begin(), mLineInfoList.end(), content_display_rect.mBottom, compare_top());
bool done = false;
// Find the coordinates of the selected area
for (;line_iter != end_iter && !done; ++line_iter)
{
// is selection visible on this line?
if (line_iter->mDocIndexEnd > selection_left && line_iter->mDocIndexStart < selection_right)
{
segment_set_t::iterator segment_iter;
S32 segment_offset;
getSegmentAndOffset(line_iter->mDocIndexStart, &segment_iter, &segment_offset);
LLRect selection_rect;
selection_rect.mLeft = line_iter->mRect.mLeft;
selection_rect.mRight = line_iter->mRect.mLeft;
selection_rect.mBottom = line_iter->mRect.mBottom;
selection_rect.mTop = line_iter->mRect.mTop;
for(;segment_iter != mSegments.end(); ++segment_iter, segment_offset = 0)
{
LLTextSegmentPtr segmentp = *segment_iter;
S32 segment_line_start = segmentp->getStart() + segment_offset;
S32 segment_line_end = llmin(segmentp->getEnd(), line_iter->mDocIndexEnd);
if (segment_line_start > segment_line_end) break;
S32 segment_width = 0;
S32 segment_height = 0;
// if selection after beginning of segment
if(selection_left >= segment_line_start)
{
S32 num_chars = llmin(selection_left, segment_line_end) - segment_line_start;
segmentp->getDimensions(segment_offset, num_chars, segment_width, segment_height);
selection_rect.mLeft += segment_width;
}
// if selection_right == segment_line_end then that means we are the first character of the next segment
// or first character of the next line, in either case we want to add the length of the current segment
// to the selection rectangle and continue.
// if selection right > segment_line_end then selection spans end of current segment...
if (selection_right >= segment_line_end)
{
// extend selection slightly beyond end of line
// to indicate selection of newline character (use "n" character to determine width)
S32 num_chars = segment_line_end - segment_line_start;
segmentp->getDimensions(segment_offset, num_chars, segment_width, segment_height);
selection_rect.mRight += segment_width;
}
// else if selection ends on current segment...
else
{
S32 num_chars = selection_right - segment_line_start;
segmentp->getDimensions(segment_offset, num_chars, segment_width, segment_height);
selection_rect.mRight += segment_width;
break;
}
}
selection_rects.push_back(selection_rect);
}
}
// Draw selection even if we don't have keyboard focus for search/replace
if (hasSelection() && !mLineInfoList.empty())
{
std::vector<LLRect> selection_rects = getSelctionRects();
// Draw the selection box (we're using a box instead of reversing the colors on the selected text).
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
const LLColor4& color = mSelectedBGColor;
F32 alpha = hasFocus() ? 0.7f : 0.3f;
alpha *= getDrawContext().mAlpha;
LLColor4 selection_color(color.mV[VRED], color.mV[VGREEN], color.mV[VBLUE], alpha);
LLRect content_display_rect = getVisibleDocumentRect();
for (std::vector<LLRect>::iterator rect_it = selection_rects.begin();
rect_it != selection_rects.end();
@ -2551,7 +2569,7 @@ S32 LLTextBase::getDocIndexFromLocalCoord( S32 local_x, S32 local_y, BOOL round,
}
S32 pos = getLength();
S32 start_x = line_iter->mRect.mLeft + doc_rect.mLeft;
F32 start_x = line_iter->mRect.mLeft + doc_rect.mLeft;
segment_set_t::iterator line_seg_iter;
S32 line_seg_offset;
@ -2563,8 +2581,9 @@ S32 LLTextBase::getDocIndexFromLocalCoord( S32 local_x, S32 local_y, BOOL round,
S32 segment_line_start = segmentp->getStart() + line_seg_offset;
S32 segment_line_length = llmin(segmentp->getEnd(), line_iter->mDocIndexEnd) - segment_line_start;
S32 text_width, text_height;
bool newline = segmentp->getDimensions(line_seg_offset, segment_line_length, text_width, text_height);
F32 text_width;
S32 text_height;
bool newline = segmentp->getDimensionsF32(line_seg_offset, segment_line_length, text_width, text_height);
if(newline)
{
@ -2584,8 +2603,9 @@ S32 LLTextBase::getDocIndexFromLocalCoord( S32 local_x, S32 local_y, BOOL round,
S32 offset;
if (!segmentp->canEdit())
{
S32 segment_width, segment_height;
segmentp->getDimensions(0, segmentp->getEnd() - segmentp->getStart(), segment_width, segment_height);
F32 segment_width;
S32 segment_height;
segmentp->getDimensionsF32(0, segmentp->getEnd() - segmentp->getStart(), segment_width, segment_height);
if (round && local_x - start_x > segment_width / 2)
{
offset = segment_line_length;
@ -2632,17 +2652,11 @@ LLRect LLTextBase::getDocRectFromDocIndex(S32 pos) const
return LLRect();
}
LLRect doc_rect;
// clamp pos to valid values
pos = llclamp(pos, 0, mLineInfoList.back().mDocIndexEnd - 1);
line_list_t::const_iterator line_iter = std::upper_bound(mLineInfoList.begin(), mLineInfoList.end(), pos, line_end_compare());
doc_rect.mLeft = line_iter->mRect.mLeft;
doc_rect.mBottom = line_iter->mRect.mBottom;
doc_rect.mTop = line_iter->mRect.mTop;
segment_set_t::iterator line_seg_iter;
S32 line_seg_offset;
segment_set_t::iterator cursor_seg_iter;
@ -2650,6 +2664,8 @@ LLRect LLTextBase::getDocRectFromDocIndex(S32 pos) const
getSegmentAndOffset(line_iter->mDocIndexStart, &line_seg_iter, &line_seg_offset);
getSegmentAndOffset(pos, &cursor_seg_iter, &cursor_seg_offset);
F32 doc_left_precise = line_iter->mRect.mLeft;
while(line_seg_iter != mSegments.end())
{
const LLTextSegmentPtr segmentp = *line_seg_iter;
@ -2657,18 +2673,20 @@ LLRect LLTextBase::getDocRectFromDocIndex(S32 pos) const
if (line_seg_iter == cursor_seg_iter)
{
// cursor advanced to right based on difference in offset of cursor to start of line
S32 segment_width, segment_height;
segmentp->getDimensions(line_seg_offset, cursor_seg_offset - line_seg_offset, segment_width, segment_height);
doc_rect.mLeft += segment_width;
F32 segment_width;
S32 segment_height;
segmentp->getDimensionsF32(line_seg_offset, cursor_seg_offset - line_seg_offset, segment_width, segment_height);
doc_left_precise += segment_width;
break;
}
else
{
// add remainder of current text segment to cursor position
S32 segment_width, segment_height;
segmentp->getDimensions(line_seg_offset, (segmentp->getEnd() - segmentp->getStart()) - line_seg_offset, segment_width, segment_height);
doc_rect.mLeft += segment_width;
F32 segment_width;
S32 segment_height;
segmentp->getDimensionsF32(line_seg_offset, (segmentp->getEnd() - segmentp->getStart()) - line_seg_offset, segment_width, segment_height);
doc_left_precise += segment_width;
// offset will be 0 for all segments after the first
line_seg_offset = 0;
// go to next text segment on this line
@ -2676,6 +2694,11 @@ LLRect LLTextBase::getDocRectFromDocIndex(S32 pos) const
}
}
LLRect doc_rect;
doc_rect.mLeft = doc_left_precise;
doc_rect.mBottom = line_iter->mRect.mBottom;
doc_rect.mTop = line_iter->mRect.mTop;
// set rect to 0 width
doc_rect.mRight = doc_rect.mLeft;

View File

@ -638,6 +638,8 @@ protected:
return mLabel.getString() + getToolTip();
}
std::vector<LLRect> getSelctionRects();
protected:
// text segmentation and flow
segment_set_t mSegments;

View File

@ -3067,18 +3067,54 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_
{
LLMutexLock lock(&window_imp->mRawMouseMutex);
S32 speed;
const S32 DEFAULT_SPEED(10);
SystemParametersInfo(SPI_GETMOUSESPEED, 0, &speed, 0);
if (speed == DEFAULT_SPEED)
bool absolute_coordinates = (raw->data.mouse.usFlags & MOUSE_MOVE_ABSOLUTE);
if (absolute_coordinates)
{
window_imp->mRawMouseDelta.mX += raw->data.mouse.lLastX;
window_imp->mRawMouseDelta.mY -= raw->data.mouse.lLastY;
static S32 prev_absolute_x = 0;
static S32 prev_absolute_y = 0;
S32 absolute_x;
S32 absolute_y;
if ((raw->data.mouse.usFlags & 0x10) == 0x10) // touch screen? touch? Not defined in header
{
// touch screen spams (0,0) coordinates in a number of situations
// (0,0) might need to be filtered
absolute_x = raw->data.mouse.lLastX;
absolute_y = raw->data.mouse.lLastY;
}
else
{
bool v_desktop = (raw->data.mouse.usFlags & MOUSE_VIRTUAL_DESKTOP) == MOUSE_VIRTUAL_DESKTOP;
S32 width = GetSystemMetrics(v_desktop ? SM_CXVIRTUALSCREEN : SM_CXSCREEN);
S32 height = GetSystemMetrics(v_desktop ? SM_CYVIRTUALSCREEN : SM_CYSCREEN);
absolute_x = (raw->data.mouse.lLastX / 65535.0f) * width;
absolute_y = (raw->data.mouse.lLastY / 65535.0f) * height;
}
window_imp->mRawMouseDelta.mX += absolute_x - prev_absolute_x;
window_imp->mRawMouseDelta.mY -= absolute_y - prev_absolute_y;
prev_absolute_x = absolute_x;
prev_absolute_y = absolute_y;
}
else
{
window_imp->mRawMouseDelta.mX += round((F32)raw->data.mouse.lLastX * (F32)speed / DEFAULT_SPEED);
window_imp->mRawMouseDelta.mY -= round((F32)raw->data.mouse.lLastY * (F32)speed / DEFAULT_SPEED);
S32 speed;
const S32 DEFAULT_SPEED(10);
SystemParametersInfo(SPI_GETMOUSESPEED, 0, &speed, 0);
if (speed == DEFAULT_SPEED)
{
window_imp->mRawMouseDelta.mX += raw->data.mouse.lLastX;
window_imp->mRawMouseDelta.mY -= raw->data.mouse.lLastY;
}
else
{
window_imp->mRawMouseDelta.mX += round((F32)raw->data.mouse.lLastX * (F32)speed / DEFAULT_SPEED);
window_imp->mRawMouseDelta.mY -= round((F32)raw->data.mouse.lLastY * (F32)speed / DEFAULT_SPEED);
}
}
}
}
@ -4219,7 +4255,10 @@ void LLWindowWin32::handleCompositionMessage(const U32 indexes)
if (needs_update)
{
mPreeditor->resetPreedit();
if (preedit_string.length() != 0 || result_string.length() != 0)
{
mPreeditor->resetPreedit();
}
if (result_string.length() > 0)
{

View File

@ -287,9 +287,9 @@ set(viewer_SOURCE_FILES
llfloaternotificationsconsole.cpp
llfloaternotificationstabbed.cpp
llfloateroutfitphotopreview.cpp
llfloateroutfitsnapshot.cpp
llfloaterobjectweights.cpp
llfloateropenobject.cpp
llfloatersimpleoutfitsnapshot.cpp
llfloaterpathfindingcharacters.cpp
llfloaterpathfindingconsole.cpp
llfloaterpathfindinglinksets.cpp
@ -929,9 +929,9 @@ set(viewer_HEADER_FILES
llfloaternotificationsconsole.h
llfloaternotificationstabbed.h
llfloateroutfitphotopreview.h
llfloateroutfitsnapshot.h
llfloaterobjectweights.h
llfloateropenobject.h
llfloatersimpleoutfitsnapshot.h
llfloaterpathfindingcharacters.h
llfloaterpathfindingconsole.h
llfloaterpathfindinglinksets.h

View File

@ -1 +1 @@
6.6.8
6.6.9

View File

@ -4747,7 +4747,7 @@
<key>Type</key>
<string>String</string>
<key>Value</key>
<string>https://search.[GRID]/?query_term=[QUERY]&amp;search_type=[TYPE][COLLECTION]&amp;maturity=[MATURITY]&amp;lang=[LANGUAGE]&amp;g=[GODLIKE]&amp;sid=[SESSION_ID]&amp;rid=[REGION_ID]&amp;pid=[PARCEL_ID]&amp;channel=[CHANNEL]&amp;version=[VERSION]&amp;major=[VERSION_MAJOR]&amp;minor=[VERSION_MINOR]&amp;patch=[VERSION_PATCH]&amp;build=[VERSION_BUILD]</string>
<string>https://search.[GRID]/viewer/?query_term=[QUERY]&amp;search_type=[TYPE][COLLECTION]&amp;maturity=[MATURITY]&amp;lang=[LANGUAGE]&amp;g=[GODLIKE]&amp;sid=[SESSION_ID]&amp;rid=[REGION_ID]&amp;pid=[PARCEL_ID]&amp;channel=[CHANNEL]&amp;version=[VERSION]&amp;major=[VERSION_MAJOR]&amp;minor=[VERSION_MINOR]&amp;patch=[VERSION_PATCH]&amp;build=[VERSION_BUILD]</string>
</map>
<key>GuidebookURL</key>
<map>
@ -14634,6 +14634,17 @@
<key>Value</key>
<integer>0</integer>
</map>
<key>MediaSoundsEarLocation</key>
<map>
<key>Comment</key>
<string>Location of the virtual ear for media and sounds</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>S32</string>
<key>Value</key>
<integer>0</integer>
</map>
<key>VoiceHost</key>
<map>
<key>Comment</key>

View File

@ -202,7 +202,7 @@ VARYING vec2 vary_texcoord2;
uniform float env_intensity;
uniform vec4 specular_color; // specular color RGB and specular exponent (glossiness) in alpha
#ifdef HAS_ALPHA_MASK
#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_MASK)
uniform float minimum_alpha;
#endif
@ -227,12 +227,11 @@ void main()
vec4 diffcol = texture2D(diffuseMap, vary_texcoord0.xy);
diffcol.rgb *= vertex_color.rgb;
#ifdef HAS_ALPHA_MASK
#if DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_BLEND
if (diffcol.a*vertex_color.a < minimum_alpha)
#else
if (diffcol.a < minimum_alpha)
#endif
#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_MASK)
// Comparing floats cast from 8-bit values, produces acne right at the 8-bit transition points
float bias = 0.001953125; // 1/512, or half an 8-bit quantization (SL-18637)
if (diffcol.a < minimum_alpha-bias)
{
discard;
}

View File

@ -33,7 +33,6 @@ RenderAvatarLODFactor 1 1.0
RenderAvatarPhysicsLODFactor 1 1.0
RenderAvatarMaxNonImpostors 1 16
RenderAvatarMaxComplexity 1 350000
RenderAvatarVP 1 1
RenderAutoMuteSurfaceAreaLimit 1 1000.0
RenderCubeMap 1 1
RenderDelayVBUpdate 1 0

View File

@ -33,7 +33,6 @@ RenderAvatarLODFactor 1 1.0
RenderAvatarPhysicsLODFactor 1 1.0
RenderAvatarMaxNonImpostors 1 16
RenderAvatarMaxComplexity 1 350000
RenderAvatarVP 1 1
RenderAutoMuteSurfaceAreaLimit 1 1000.0
RenderCubeMap 1 1
RenderDelayVBUpdate 1 0
@ -80,7 +79,6 @@ RenderAvatarLODFactor 1 0
RenderAvatarPhysicsLODFactor 1 0
RenderAvatarMaxNonImpostors 1 3
RenderAvatarMaxComplexity 1 25000
RenderAvatarVP 1 0
RenderFarClip 1 64
RenderFlexTimeFactor 1 0
RenderGlowResolutionPow 1 8
@ -111,7 +109,6 @@ RenderAvatarLODFactor 1 0
RenderAvatarPhysicsLODFactor 1 0
RenderAvatarMaxNonImpostors 1 3
RenderAvatarMaxComplexity 1 35000
RenderAvatarVP 1 0
RenderFarClip 1 64
RenderFlexTimeFactor 1 0
RenderGlowResolutionPow 1 8
@ -141,7 +138,6 @@ RenderAvatarCloth 1 0
RenderAvatarLODFactor 1 0.5
RenderAvatarMaxComplexity 1 100000
RenderAvatarPhysicsLODFactor 1 0.75
RenderAvatarVP 1 1
RenderFarClip 1 96
RenderFlexTimeFactor 1 1.0
RenderGlowResolutionPow 1 8
@ -171,7 +167,6 @@ RenderAvatarCloth 1 0
RenderAvatarLODFactor 1 1.0
RenderAvatarMaxComplexity 1 200000
RenderAvatarPhysicsLODFactor 1 1.0
RenderAvatarVP 1 1
RenderFarClip 1 128
RenderFlexTimeFactor 1 1.0
RenderGlowResolutionPow 1 9
@ -201,7 +196,6 @@ RenderAvatarCloth 1 0
RenderAvatarLODFactor 1 1.0
RenderAvatarMaxComplexity 1 250000
RenderAvatarPhysicsLODFactor 1 1.0
RenderAvatarVP 1 1
RenderFarClip 1 128
RenderFlexTimeFactor 1 1.0
RenderGlowResolutionPow 1 9
@ -231,7 +225,6 @@ RenderAvatarCloth 1 0
RenderAvatarLODFactor 1 1.0
RenderAvatarMaxComplexity 1 300000
RenderAvatarPhysicsLODFactor 1 1.0
RenderAvatarVP 1 1
RenderFarClip 1 128
RenderFlexTimeFactor 1 1.0
RenderGlowResolutionPow 1 9
@ -261,7 +254,6 @@ RenderAvatarCloth 1 0
RenderAvatarLODFactor 1 1.0
RenderAvatarMaxComplexity 1 350000
RenderAvatarPhysicsLODFactor 1 1.0
RenderAvatarVP 1 1
RenderFarClip 1 128
RenderFlexTimeFactor 1 1.0
RenderGlowResolutionPow 1 9
@ -290,7 +282,6 @@ RenderAnisotropic 1 1
RenderAvatarCloth 1 1
RenderAvatarLODFactor 1 1.0
RenderAvatarPhysicsLODFactor 1 1.0
RenderAvatarVP 1 1
RenderFarClip 1 256
RenderFlexTimeFactor 1 1.0
RenderGlowResolutionPow 1 9
@ -367,7 +358,6 @@ RenderCompressTextures 1 0
// No Pixel Shaders available
//
list NoPixelShaders
RenderAvatarVP 0 0
RenderAvatarCloth 0 0
RenderReflectionDetail 0 0
WindLightUseAtmosShaders 0 0
@ -380,7 +370,6 @@ RenderShadowDetail 0 0
// No Vertex Shaders available
//
list NoVertexShaders
RenderAvatarVP 0 0
RenderAvatarCloth 0 0
RenderReflectionDetail 0 0
WindLightUseAtmosShaders 0 0
@ -402,7 +391,6 @@ RenderVBOMappingDisable 1 1
list safe
RenderAnisotropic 1 0
RenderAvatarCloth 0 0
RenderAvatarVP 0 0
RenderAvatarMaxNonImpostors 1 16
RenderAvatarMaxComplexity 1 80000
RenderObjectBump 0 0
@ -597,7 +585,6 @@ Disregard128DefaultDrawDistance 1 0
// on various ATI chipsets on drivers before 8.2
list ATIOldDriver
RenderAvatarVP 0 0
RenderAvatarCloth 0 0
// Avoid driver crashes with some features on Linux with old ATI drivers
UseOcclusion 0 0

View File

@ -33,7 +33,6 @@ RenderAvatarLODFactor 1 1.0
RenderAvatarPhysicsLODFactor 1 1.0
RenderAvatarMaxNonImpostors 1 16
RenderAvatarMaxComplexity 1 350000
RenderAvatarVP 1 1
RenderAutoMuteSurfaceAreaLimit 1 1000.0
RenderCubeMap 1 1
RenderDelayVBUpdate 1 0

View File

@ -2912,9 +2912,11 @@ void LLAgent::processMaturityPreferenceFromServer(const LLSD &result, U8 perferr
bool LLAgent::requestPostCapability(const std::string &capName, LLSD &postData, httpCallback_t cbSuccess, httpCallback_t cbFailure)
{
std::string url;
url = getRegionCapability(capName);
if (!getRegion())
{
return false;
}
std::string url = getRegion()->getCapability(capName);
if (url.empty())
{

View File

@ -209,7 +209,7 @@
#include "llcommandlineparser.h"
#include "llfloatermemleak.h"
#include "llfloaterreg.h"
#include "llfloateroutfitsnapshot.h"
#include "llfloatersimpleoutfitsnapshot.h"
#include "llfloatersnapshot.h"
#include "llsidepanelinventory.h"
#include "llatmosphere.h"
@ -1275,7 +1275,6 @@ bool LLAppViewer::init()
//LLSimpleton creations
LLEnvironment::createInstance();
LLEnvironment::getInstance()->initSingleton();
LLWorld::createInstance();
LLSelectMgr::createInstance();
LLViewerCamera::createInstance();
@ -1521,7 +1520,7 @@ bool LLAppViewer::doFrame()
LL_PROFILE_ZONE_NAMED_CATEGORY_APP( "df Snapshot" )
pingMainloopTimeout("Main:Snapshot");
LLFloaterSnapshot::update(); // take snapshots
LLFloaterOutfitSnapshot::update();
LLFloaterSimpleOutfitSnapshot::update();
gGLActive = FALSE;
}
}

View File

@ -102,7 +102,7 @@ LLVector3d LLAudioSourceVO::getPosGlobal() const
bool LLAudioSourceVO::isInCutOffRadius(const LLVector3d pos_global, const F32 cutoff) const
{
static LLCachedControl<S32> ear_mode(gSavedSettings, "VoiceEarLocation", 0);
static LLCachedControl<S32> ear_mode(gSavedSettings, "MediaSoundsEarLocation", 0);
LLVector3d pos_ear;
@ -113,9 +113,6 @@ bool LLAudioSourceVO::isInCutOffRadius(const LLVector3d pos_global, const F32 cu
break;
case 1: // avatar
case 2:
// voice support 'mixed' in '2' case with agent's position and camera's rotations
// but it is not defined in settings and uses camera as default
pos_ear = gAgent.getPositionGlobal();
break;

View File

@ -650,7 +650,7 @@ public:
void showInspector()
{
if (mAvatarID.isNull() && CHAT_SOURCE_SYSTEM != mSourceType) return;
if (mAvatarID.isNull() && CHAT_SOURCE_SYSTEM != mSourceType && CHAT_SOURCE_REGION != mSourceType) return;
if (mSourceType == CHAT_SOURCE_OBJECT)
{
@ -798,6 +798,7 @@ public:
icon->setValue(LLSD("OBJECT_Icon"));
break;
case CHAT_SOURCE_SYSTEM:
case CHAT_SOURCE_REGION:
icon->setValue(LLSD("SL_Logo"));
break;
case CHAT_SOURCE_TELEPORT:
@ -947,7 +948,7 @@ protected:
void showInfoCtrl()
{
const bool isVisible = !mAvatarID.isNull() && !mFrom.empty() && CHAT_SOURCE_SYSTEM != mSourceType;
const bool isVisible = !mAvatarID.isNull() && !mFrom.empty() && CHAT_SOURCE_SYSTEM != mSourceType && CHAT_SOURCE_REGION != mSourceType;
if (isVisible)
{
const LLRect sticky_rect = mUserNameTextBox->getRect();
@ -1343,7 +1344,7 @@ void LLChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LL
mEditor->appendText(chat.mFromName + delimiter, prependNewLineState, link_params);
prependNewLineState = false;
}
else if ( chat.mFromName != SYSTEM_FROM && chat.mFromID.notNull() && !message_from_log)
else if ( chat.mFromName != SYSTEM_FROM && chat.mFromID.notNull() && !message_from_log && chat.mSourceType != CHAT_SOURCE_REGION)
{
LLStyle::Params link_params(body_message_params);
link_params.overwriteFrom(LLStyleMap::instance().lookupAgent(chat.mFromID));

View File

@ -87,7 +87,7 @@ public:
virtual BOOL removeItem() { return FALSE; }
virtual void removeBatch(std::vector<LLFolderViewModelItem*>& batch) { }
virtual void move( LLFolderViewModelItem* parent_listener ) { }
virtual BOOL isItemCopyable() const { return FALSE; }
virtual bool isItemCopyable(bool can_copy_as_link = true) const { return false; }
virtual BOOL copyToClipboard() const { return FALSE; }
virtual BOOL cutToClipboard() { return FALSE; }
virtual BOOL isClipboardPasteable() const { return FALSE; }

View File

@ -41,6 +41,7 @@
#include "lldrawable.h"
#include "llface.h"
#include "llsky.h"
#include "llstartup.h"
#include "lltextureentry.h"
#include "llviewercamera.h"
#include "llviewertexturelist.h"
@ -81,11 +82,6 @@ static S32 bump_channel = -1;
// LLAtomicBool; this should work just fine, now. HB
#define LL_BUMPLIST_MULTITHREADED 1
// static
void LLStandardBumpmap::init()
{
LLStandardBumpmap::restoreGL();
}
// static
void LLStandardBumpmap::shutdown()
@ -96,7 +92,7 @@ void LLStandardBumpmap::shutdown()
// static
void LLStandardBumpmap::restoreGL()
{
addstandard();
addstandard();
}
// static
@ -109,6 +105,12 @@ void LLStandardBumpmap::addstandard()
return ;
}
if (LLStartUp::getStartupState() < STATE_SEED_CAP_GRANTED)
{
// Not ready, need caps for images
return;
}
// can't assert; we destroyGL and restoreGL a lot during *first* startup, which populates this list already, THEN we explicitly init the list as part of *normal* startup. Sigh. So clear the list every time before we (re-)add the standard bumpmaps.
//llassert( LLStandardBumpmap::sStandardBumpmapCount == 0 );
clear();
@ -771,8 +773,6 @@ void LLBumpImageList::init()
llassert( mBrightnessEntries.size() == 0 );
llassert( mDarknessEntries.size() == 0 );
LLStandardBumpmap::init();
LLStandardBumpmap::restoreGL();
sMainQueue = LL::WorkQueue::getInstance("mainloop");
sTexUpdateQueue = LL::WorkQueue::getInstance("LLImageGL"); // Share work queue with tex loader.

View File

@ -118,7 +118,6 @@ public:
static void clear();
static void addstandard();
static void init();
static void shutdown();
static void restoreGL();
static void destroyGL();

View File

@ -874,26 +874,37 @@ void LLEnvironment::initSingleton()
requestRegion();
gAgent.addParcelChangedCallback([this]() { onParcelChange(); });
if (!mParcelCallbackConnection.connected())
{
mParcelCallbackConnection = gAgent.addParcelChangedCallback([this]() { onParcelChange(); });
//TODO: This frequently results in one more request than we need. It isn't breaking, but should be nicer.
// We need to know new env version to fix this, without it we can only do full re-request
// Happens: on updates, on opening LLFloaterRegionInfo, on region crossing if info floater is open
LLRegionInfoModel::instance().setUpdateCallback([this]() { requestRegion(); });
gAgent.addRegionChangedCallback([this]() { onRegionChange(); });
//TODO: This frequently results in one more request than we need. It isn't breaking, but should be nicer.
// We need to know new env version to fix this, without it we can only do full re-request
// Happens: on updates, on opening LLFloaterRegionInfo, on region crossing if info floater is open
mRegionUpdateCallbackConnection = LLRegionInfoModel::instance().setUpdateCallback([this]() { requestRegion(); });
mRegionChangeCallbackConnection = gAgent.addRegionChangedCallback([this]() { onRegionChange(); });
gAgent.whenPositionChanged([this](const LLVector3 &localpos, const LLVector3d &) { onAgentPositionHasChanged(localpos); });
mPositionCallbackConnection = gAgent.whenPositionChanged([this](const LLVector3 &localpos, const LLVector3d &) { onAgentPositionHasChanged(localpos); });
}
if (!gGenericDispatcher.isHandlerPresent(MESSAGE_PUSHENVIRONMENT))
{
gGenericDispatcher.addHandler(MESSAGE_PUSHENVIRONMENT, &environment_push_dispatch_handler);
}
LLEventPumps::instance().obtain(PUMP_EXPERIENCE).stopListening(LISTENER_NAME);
LLEventPumps::instance().obtain(PUMP_EXPERIENCE).listen(LISTENER_NAME, [this](LLSD message) { listenExperiencePump(message); return false; });
}
void LLEnvironment::cleanupSingleton()
{
if (mParcelCallbackConnection.connected())
{
mParcelCallbackConnection.disconnect();
mRegionUpdateCallbackConnection.disconnect();
mRegionChangeCallbackConnection.disconnect();
mPositionCallbackConnection.disconnect();
}
LLEventPumps::instance().obtain(PUMP_EXPERIENCE).stopListening(LISTENER_NAME);
}

View File

@ -402,6 +402,11 @@ private:
bool mShowMoonBeacon;
S32 mEditorCounter;
connection_t mParcelCallbackConnection;
connection_t mRegionUpdateCallbackConnection;
connection_t mRegionChangeCallbackConnection;
connection_t mPositionCallbackConnection;
struct UpdateInfo
{
typedef std::shared_ptr<UpdateInfo> ptr_t;

View File

@ -84,7 +84,7 @@ LLFloater360Capture::~LLFloater360Capture()
// Tell the Simulator not to send us everything anymore
// and revert to the regular "keyhole" frustum of interest
// list updates.
if (gSavedSettings.getBOOL("360CaptureUseInterestListCap"))
if (!LLApp::isExiting() && gSavedSettings.getBOOL("360CaptureUseInterestListCap"))
{
const bool send_everything = false;
changeInterestListMode(send_everything);

View File

@ -307,7 +307,6 @@ void LLFloaterIMNearbyChat::onOpen(const LLSD& key)
restoreFloater();
onCollapseToLine(this);
}
showTranslationCheckbox(LLTranslate::isTranslationConfigured());
}
// virtual

View File

@ -842,6 +842,7 @@ void LLFloaterIMSession::updateMessages()
std::string from = msg["from"].asString();
std::string message = msg["message"].asString();
bool is_history = msg["is_history"].asBoolean();
bool is_region_msg = msg["is_region_msg"].asBoolean();
LLChat chat;
chat.mFromID = from_id;
@ -849,6 +850,10 @@ void LLFloaterIMSession::updateMessages()
chat.mFromName = from;
chat.mTimeStr = time;
chat.mChatStyle = is_history ? CHAT_STYLE_HISTORY : chat.mChatStyle;
if (is_region_msg)
{
chat.mSourceType = CHAT_SOURCE_REGION;
}
// process offer notification
if (msg.has("notification_id"))

View File

@ -253,7 +253,6 @@ BOOL LLFloaterIMSessionTab::postBuild()
mGearBtn = getChild<LLButton>("gear_btn");
mAddBtn = getChild<LLButton>("add_btn");
mVoiceButton = getChild<LLButton>("voice_call_btn");
mTranslationCheckBox = getChild<LLUICtrl>("translate_chat_checkbox_lp");
mParticipantListPanel = getChild<LLLayoutPanel>("speakers_list_panel");
mRightPartPanel = getChild<LLLayoutPanel>("right_part_holder");
@ -811,8 +810,6 @@ void LLFloaterIMSessionTab::updateHeaderAndToolbar()
mCloseBtn->setVisible(is_not_torn_off && !mIsNearbyChat);
enableDisableCallBtn();
showTranslationCheckbox();
}
void LLFloaterIMSessionTab::forceReshape()
@ -829,11 +826,6 @@ void LLFloaterIMSessionTab::reshapeChatLayoutPanel()
mChatLayoutPanel->reshape(mChatLayoutPanel->getRect().getWidth(), mInputEditor->getRect().getHeight() + mInputEditorPad, FALSE);
}
void LLFloaterIMSessionTab::showTranslationCheckbox(BOOL show)
{
mTranslationCheckBox->setVisible(mIsNearbyChat && show);
}
// static
void LLFloaterIMSessionTab::processChatHistoryStyleUpdate(bool clean_messages/* = false*/)
{

View File

@ -71,8 +71,6 @@ public:
static LLFloaterIMSessionTab* findConversation(const LLUUID& uuid);
static LLFloaterIMSessionTab* getConversation(const LLUUID& uuid);
// show/hide the translation check box
void showTranslationCheckbox(const BOOL visible = FALSE);
bool isNearbyChat() {return mIsNearbyChat;}
@ -187,7 +185,6 @@ protected:
LLButton* mGearBtn;
LLButton* mAddBtn;
LLButton* mVoiceButton;
LLUICtrl* mTranslationCheckBox;
private:
// Handling selection and contextual menu

View File

@ -1,372 +0,0 @@
/**
* @file llfloateroutfitsnapshot.cpp
* @brief Snapshot preview window for saving as an outfit thumbnail in visual outfit gallery
*
* $LicenseInfo:firstyear=2004&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2016, 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$
*/
#include "llviewerprecompiledheaders.h"
#include "llfloatersnapshot.h"
#include "llfloateroutfitsnapshot.h"
#include "llagent.h"
#include "llfloaterreg.h"
#include "llimagefiltersmanager.h"
#include "llcheckboxctrl.h"
#include "llcombobox.h"
#include "llpostcard.h"
#include "llresmgr.h" // LLLocale
#include "llsdserialize.h"
#include "llsidetraypanelcontainer.h"
#include "llspinctrl.h"
#include "llviewercontrol.h"
#include "lltoolfocus.h"
#include "lltoolmgr.h"
///----------------------------------------------------------------------------
/// Local function declarations, constants, enums, and typedefs
///----------------------------------------------------------------------------
LLOutfitSnapshotFloaterView* gOutfitSnapshotFloaterView = NULL;
const S32 OUTFIT_SNAPSHOT_WIDTH = 256;
const S32 OUTFIT_SNAPSHOT_HEIGHT = 256;
static LLDefaultChildRegistry::Register<LLOutfitSnapshotFloaterView> r("snapshot_outfit_floater_view");
///----------------------------------------------------------------------------
/// Class LLFloaterOutfitSnapshot::Impl
///----------------------------------------------------------------------------
// virtual
LLPanelSnapshot* LLFloaterOutfitSnapshot::Impl::getActivePanel(LLFloaterSnapshotBase* floater, bool ok_if_not_found)
{
LLPanel* panel = floater->getChild<LLPanel>("panel_outfit_snapshot_inventory");
LLPanelSnapshot* active_panel = dynamic_cast<LLPanelSnapshot*>(panel);
if (!ok_if_not_found)
{
llassert_always(active_panel != NULL);
}
return active_panel;
}
// virtual
LLSnapshotModel::ESnapshotFormat LLFloaterOutfitSnapshot::Impl::getImageFormat(LLFloaterSnapshotBase* floater)
{
return LLSnapshotModel::SNAPSHOT_FORMAT_PNG;
}
// virtual
LLSnapshotModel::ESnapshotLayerType LLFloaterOutfitSnapshot::Impl::getLayerType(LLFloaterSnapshotBase* floater)
{
return LLSnapshotModel::SNAPSHOT_TYPE_COLOR;
}
// This is the main function that keeps all the GUI controls in sync with the saved settings.
// It should be called anytime a setting is changed that could affect the controls.
// No other methods should be changing any of the controls directly except for helpers called by this method.
// The basic pattern for programmatically changing the GUI settings is to first set the
// appropriate saved settings and then call this method to sync the GUI with them.
// FIXME: The above comment seems obsolete now.
// virtual
void LLFloaterOutfitSnapshot::Impl::updateControls(LLFloaterSnapshotBase* floater)
{
LLSnapshotModel::ESnapshotType shot_type = getActiveSnapshotType(floater);
LLSnapshotModel::ESnapshotFormat shot_format = (LLSnapshotModel::ESnapshotFormat)gSavedSettings.getS32("SnapshotFormat");
LLSnapshotModel::ESnapshotLayerType layer_type = getLayerType(floater);
LLSnapshotLivePreview* previewp = getPreviewView();
BOOL got_snap = previewp && previewp->getSnapshotUpToDate();
// *TODO: Separate maximum size for Web images from postcards
LL_DEBUGS() << "Is snapshot up-to-date? " << got_snap << LL_ENDL;
LLLocale locale(LLLocale::USER_LOCALE);
std::string bytes_string;
if (got_snap)
{
LLResMgr::getInstance()->getIntegerString(bytes_string, (previewp->getDataSize()) >> 10);
}
// Update displayed image resolution.
LLTextBox* image_res_tb = floater->getChild<LLTextBox>("image_res_text");
image_res_tb->setVisible(got_snap);
if (got_snap)
{
image_res_tb->setTextArg("[WIDTH]", llformat("%d", previewp->getEncodedImageWidth()));
image_res_tb->setTextArg("[HEIGHT]", llformat("%d", previewp->getEncodedImageHeight()));
}
floater->getChild<LLUICtrl>("file_size_label")->setTextArg("[SIZE]", got_snap ? bytes_string : floater->getString("unknown"));
floater->getChild<LLUICtrl>("file_size_label")->setColor(LLUIColorTable::instance().getColor("LabelTextColor"));
updateResolution(floater);
if (previewp)
{
previewp->setSnapshotType(shot_type);
previewp->setSnapshotFormat(shot_format);
previewp->setSnapshotBufferType(layer_type);
}
LLPanelSnapshot* current_panel = Impl::getActivePanel(floater);
if (current_panel)
{
LLSD info;
info["have-snapshot"] = got_snap;
current_panel->updateControls(info);
}
LL_DEBUGS() << "finished updating controls" << LL_ENDL;
}
// virtual
std::string LLFloaterOutfitSnapshot::Impl::getSnapshotPanelPrefix()
{
return "panel_outfit_snapshot_";
}
// Show/hide upload status message.
// virtual
void LLFloaterOutfitSnapshot::Impl::setFinished(bool finished, bool ok, const std::string& msg)
{
mFloater->setSuccessLabelPanelVisible(finished && ok);
mFloater->setFailureLabelPanelVisible(finished && !ok);
if (finished)
{
LLUICtrl* finished_lbl = mFloater->getChild<LLUICtrl>(ok ? "succeeded_lbl" : "failed_lbl");
std::string result_text = mFloater->getString(msg + "_" + (ok ? "succeeded_str" : "failed_str"));
finished_lbl->setValue(result_text);
LLPanel* snapshot_panel = mFloater->getChild<LLPanel>("panel_outfit_snapshot_inventory");
snapshot_panel->onOpen(LLSD());
}
}
void LLFloaterOutfitSnapshot::Impl::updateResolution(void* data)
{
LLFloaterOutfitSnapshot *view = (LLFloaterOutfitSnapshot *)data;
if (!view)
{
llassert(view);
return;
}
S32 width = OUTFIT_SNAPSHOT_WIDTH;
S32 height = OUTFIT_SNAPSHOT_HEIGHT;
LLSnapshotLivePreview* previewp = getPreviewView();
if (previewp)
{
S32 original_width = 0, original_height = 0;
previewp->getSize(original_width, original_height);
if (gSavedSettings.getBOOL("RenderUIInSnapshot") || gSavedSettings.getBOOL("RenderHUDInSnapshot"))
{ //clamp snapshot resolution to window size when showing UI or HUD in snapshot
width = llmin(width, gViewerWindow->getWindowWidthRaw());
height = llmin(height, gViewerWindow->getWindowHeightRaw());
}
llassert(width > 0 && height > 0);
// use the resolution from the selected pre-canned drop-down choice
LL_DEBUGS() << "Setting preview res selected from combo: " << width << "x" << height << LL_ENDL;
previewp->setSize(width, height);
if (original_width != width || original_height != height)
{
// hide old preview as the aspect ratio could be wrong
checkAutoSnapshot(previewp, FALSE);
LL_DEBUGS() << "updating thumbnail" << LL_ENDL;
previewp->updateSnapshot(TRUE);
}
}
}
///----------------------------------------------------------------------------
/// Class LLFloaterOutfitSnapshot
///----------------------------------------------------------------------------
// Default constructor
LLFloaterOutfitSnapshot::LLFloaterOutfitSnapshot(const LLSD& key)
: LLFloaterSnapshotBase(key),
mOutfitGallery(NULL)
{
impl = new Impl(this);
}
LLFloaterOutfitSnapshot::~LLFloaterOutfitSnapshot()
{
}
// virtual
BOOL LLFloaterOutfitSnapshot::postBuild()
{
mRefreshBtn = getChild<LLUICtrl>("new_snapshot_btn");
childSetAction("new_snapshot_btn", ImplBase::onClickNewSnapshot, this);
mRefreshLabel = getChild<LLUICtrl>("refresh_lbl");
mSucceessLblPanel = getChild<LLUICtrl>("succeeded_panel");
mFailureLblPanel = getChild<LLUICtrl>("failed_panel");
childSetCommitCallback("ui_check", ImplBase::onClickUICheck, this);
getChild<LLUICtrl>("ui_check")->setValue(gSavedSettings.getBOOL("RenderUIInSnapshot"));
childSetCommitCallback("hud_check", ImplBase::onClickHUDCheck, this);
getChild<LLUICtrl>("hud_check")->setValue(gSavedSettings.getBOOL("RenderHUDInSnapshot"));
getChild<LLUICtrl>("freeze_frame_check")->setValue(gSavedSettings.getBOOL("UseFreezeFrame"));
childSetCommitCallback("freeze_frame_check", ImplBase::onCommitFreezeFrame, this);
getChild<LLUICtrl>("auto_snapshot_check")->setValue(gSavedSettings.getBOOL("AutoSnapshot"));
childSetCommitCallback("auto_snapshot_check", ImplBase::onClickAutoSnap, this);
getChild<LLButton>("retract_btn")->setCommitCallback(boost::bind(&LLFloaterOutfitSnapshot::onExtendFloater, this));
getChild<LLButton>("extend_btn")->setCommitCallback(boost::bind(&LLFloaterOutfitSnapshot::onExtendFloater, this));
// Filters
LLComboBox* filterbox = getChild<LLComboBox>("filters_combobox");
std::vector<std::string> filter_list = LLImageFiltersManager::getInstance()->getFiltersList();
for (U32 i = 0; i < filter_list.size(); i++)
{
filterbox->add(filter_list[i]);
}
childSetCommitCallback("filters_combobox", ImplBase::onClickFilter, this);
mThumbnailPlaceholder = getChild<LLUICtrl>("thumbnail_placeholder");
// create preview window
LLRect full_screen_rect = getRootView()->getRect();
LLSnapshotLivePreview::Params p;
p.rect(full_screen_rect);
LLSnapshotLivePreview* previewp = new LLSnapshotLivePreview(p);
LLView* parent_view = gSnapshotFloaterView->getParent();
parent_view->removeChild(gSnapshotFloaterView);
// make sure preview is below snapshot floater
parent_view->addChild(previewp);
parent_view->addChild(gSnapshotFloaterView);
//move snapshot floater to special purpose snapshotfloaterview
gFloaterView->removeChild(this);
gSnapshotFloaterView->addChild(this);
impl->mPreviewHandle = previewp->getHandle();
previewp->setContainer(this);
impl->updateControls(this);
impl->setAdvanced(gSavedSettings.getBOOL("AdvanceOutfitSnapshot"));
impl->updateLayout(this);
previewp->mKeepAspectRatio = FALSE;
previewp->setThumbnailPlaceholderRect(getThumbnailPlaceholderRect());
return TRUE;
}
// virtual
void LLFloaterOutfitSnapshot::onOpen(const LLSD& key)
{
LLSnapshotLivePreview* preview = getPreviewView();
if (preview)
{
LL_DEBUGS() << "opened, updating snapshot" << LL_ENDL;
preview->updateSnapshot(TRUE);
}
focusFirstItem(FALSE);
gSnapshotFloaterView->setEnabled(TRUE);
gSnapshotFloaterView->setVisible(TRUE);
gSnapshotFloaterView->adjustToFitScreen(this, FALSE);
impl->updateControls(this);
impl->setAdvanced(gSavedSettings.getBOOL("AdvanceOutfitSnapshot"));
impl->updateLayout(this);
LLPanel* snapshot_panel = getChild<LLPanel>("panel_outfit_snapshot_inventory");
snapshot_panel->onOpen(LLSD());
postPanelSwitch();
}
void LLFloaterOutfitSnapshot::onExtendFloater()
{
impl->setAdvanced(gSavedSettings.getBOOL("AdvanceOutfitSnapshot"));
}
// static
void LLFloaterOutfitSnapshot::update()
{
LLFloaterOutfitSnapshot* inst = findInstance();
if (inst != NULL)
{
inst->impl->updateLivePreview();
}
}
// static
LLFloaterOutfitSnapshot* LLFloaterOutfitSnapshot::findInstance()
{
return LLFloaterReg::findTypedInstance<LLFloaterOutfitSnapshot>("outfit_snapshot");
}
// static
LLFloaterOutfitSnapshot* LLFloaterOutfitSnapshot::getInstance()
{
return LLFloaterReg::getTypedInstance<LLFloaterOutfitSnapshot>("outfit_snapshot");
}
// virtual
void LLFloaterOutfitSnapshot::saveTexture()
{
LL_DEBUGS() << "saveTexture" << LL_ENDL;
LLSnapshotLivePreview* previewp = getPreviewView();
if (!previewp)
{
llassert(previewp != NULL);
return;
}
if (mOutfitGallery)
{
mOutfitGallery->onBeforeOutfitSnapshotSave();
}
previewp->saveTexture(TRUE, getOutfitID().asString());
if (mOutfitGallery)
{
mOutfitGallery->onAfterOutfitSnapshotSave();
}
closeFloater();
}
///----------------------------------------------------------------------------
/// Class LLOutfitSnapshotFloaterView
///----------------------------------------------------------------------------
LLOutfitSnapshotFloaterView::LLOutfitSnapshotFloaterView(const Params& p) : LLFloaterView(p)
{
}
LLOutfitSnapshotFloaterView::~LLOutfitSnapshotFloaterView()
{
}

View File

@ -1,123 +0,0 @@
/**
* @file llfloateroutfitsnapshot.h
* @brief Snapshot preview window for saving as an outfit thumbnail in visual outfit gallery
*
* $LicenseInfo:firstyear=2004&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2016, 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_LLFLOATEROUTFITSNAPSHOT_H
#define LL_LLFLOATEROUTFITSNAPSHOT_H
#include "llfloater.h"
#include "llfloatersnapshot.h"
#include "lloutfitgallery.h"
#include "llsnapshotlivepreview.h"
///----------------------------------------------------------------------------
/// Class LLFloaterOutfitSnapshot
///----------------------------------------------------------------------------
class LLFloaterOutfitSnapshot : public LLFloaterSnapshotBase
{
LOG_CLASS(LLFloaterOutfitSnapshot);
public:
LLFloaterOutfitSnapshot(const LLSD& key);
/*virtual*/ ~LLFloaterOutfitSnapshot();
/*virtual*/ BOOL postBuild();
/*virtual*/ void onOpen(const LLSD& key);
static void update();
void onExtendFloater();
static LLFloaterOutfitSnapshot* getInstance();
static LLFloaterOutfitSnapshot* findInstance();
/*virtual*/ void saveTexture();
const LLRect& getThumbnailPlaceholderRect() { return mThumbnailPlaceholder->getRect(); }
void setOutfitID(LLUUID id) { mOutfitID = id; }
LLUUID getOutfitID() { return mOutfitID; }
void setGallery(LLOutfitGallery* gallery) { mOutfitGallery = gallery; }
class Impl;
friend class Impl;
private:
LLUUID mOutfitID;
LLOutfitGallery* mOutfitGallery;
};
///----------------------------------------------------------------------------
/// Class LLFloaterOutfitSnapshot::Impl
///----------------------------------------------------------------------------
class LLFloaterOutfitSnapshot::Impl : public LLFloaterSnapshotBase::ImplBase
{
LOG_CLASS(LLFloaterOutfitSnapshot::Impl);
public:
Impl(LLFloaterSnapshotBase* floater)
: LLFloaterSnapshotBase::ImplBase(floater)
{}
~Impl()
{}
void updateResolution(void* data);
static void onSnapshotUploadFinished(LLFloaterSnapshotBase* floater, bool status);
/*virtual*/ LLPanelSnapshot* getActivePanel(LLFloaterSnapshotBase* floater, bool ok_if_not_found = true);
/*virtual*/ LLSnapshotModel::ESnapshotFormat getImageFormat(LLFloaterSnapshotBase* floater);
/*virtual*/ std::string getSnapshotPanelPrefix();
/*virtual*/ void updateControls(LLFloaterSnapshotBase* floater);
private:
/*virtual*/ LLSnapshotModel::ESnapshotLayerType getLayerType(LLFloaterSnapshotBase* floater);
/*virtual*/ void setFinished(bool finished, bool ok = true, const std::string& msg = LLStringUtil::null);
};
///----------------------------------------------------------------------------
/// Class LLOutfitSnapshotFloaterView
///----------------------------------------------------------------------------
class LLOutfitSnapshotFloaterView : public LLFloaterView
{
public:
struct Params
: public LLInitParam::Block<Params, LLFloaterView::Params>
{
};
protected:
LLOutfitSnapshotFloaterView(const Params& p);
friend class LLUICtrlFactory;
public:
virtual ~LLOutfitSnapshotFloaterView();
};
extern LLOutfitSnapshotFloaterView* gOutfitSnapshotFloaterView;
#endif // LL_LLFLOATEROUTFITSNAPSHOT_H

View File

@ -512,6 +512,7 @@ void LLFloaterPreference::saveSettings()
if (panel)
panel->saveSettings();
}
saveIgnoredNotifications();
}
void LLFloaterPreference::apply()
@ -628,6 +629,8 @@ void LLFloaterPreference::cancel()
gSavedSettings.setString("PresetGraphicActive", mSavedGraphicsPreset);
LLPresetsManager::getInstance()->triggerChangeSignal();
}
restoreIgnoredNotifications();
}
void LLFloaterPreference::onOpen(const LLSD& key)
@ -1505,6 +1508,10 @@ void LLFloaterPreference::onClickEnablePopup()
}
buildPopupLists();
if (!mFilterEdit->getText().empty())
{
filterIgnorableNotifications();
}
}
void LLFloaterPreference::onClickDisablePopup()
@ -1520,6 +1527,10 @@ void LLFloaterPreference::onClickDisablePopup()
}
buildPopupLists();
if (!mFilterEdit->getText().empty())
{
filterIgnorableNotifications();
}
}
void LLFloaterPreference::resetAllIgnored()
@ -3545,11 +3556,24 @@ void LLFloaterPreference::onUpdateFilterTerm(bool force)
return;
mSearchData->mRootTab->hightlightAndHide( seachValue );
filterIgnorableNotifications();
LLTabContainer *pRoot = getChild< LLTabContainer >( "pref core" );
if( pRoot )
pRoot->selectFirstTab();
}
void LLFloaterPreference::filterIgnorableNotifications()
{
bool visible = getChildRef<LLScrollListCtrl>("enabled_popups").highlightMatchingItems(mFilterEdit->getValue());
visible |= getChildRef<LLScrollListCtrl>("disabled_popups").highlightMatchingItems(mFilterEdit->getValue());
if (visible)
{
getChildRef<LLTabContainer>("pref core").setTabVisibility( getChild<LLPanel>("msgs"), true );
}
}
void collectChildren( LLView const *aView, ll::prefs::PanelDataPtr aParentPanel, ll::prefs::TabContainerDataPtr aParentTabContainer )
{
if( !aView )
@ -3638,3 +3662,28 @@ void LLFloaterPreference::collectSearchableItems()
}
mSearchDataDirty = false;
}
void LLFloaterPreference::saveIgnoredNotifications()
{
for (LLNotifications::TemplateMap::const_iterator iter = LLNotifications::instance().templatesBegin();
iter != LLNotifications::instance().templatesEnd();
++iter)
{
LLNotificationTemplatePtr templatep = iter->second;
LLNotificationFormPtr formp = templatep->mForm;
LLNotificationForm::EIgnoreType ignore = formp->getIgnoreType();
if (ignore <= LLNotificationForm::IGNORE_NO)
continue;
mIgnorableNotifs[templatep->mName] = !formp->getIgnored();
}
}
void LLFloaterPreference::restoreIgnoredNotifications()
{
for (std::map<std::string, bool>::iterator it = mIgnorableNotifs.begin(); it != mIgnorableNotifs.end(); ++it)
{
LLUI::getInstance()->mSettingGroups["ignores"]->setBOOL(it->first, it->second);
}
}

View File

@ -143,6 +143,9 @@ public:
// cancel() can restore them.
void saveSettings();
void saveIgnoredNotifications();
void restoreIgnoredNotifications();
void setCacheLocation(const LLStringExplicit& location);
void onClickSetCache();
@ -223,6 +226,9 @@ private:
void onUpdateFilterTerm( bool force = false );
void collectSearchableItems();
void filterIgnorableNotifications();
std::map<std::string, bool> mIgnorableNotifs;
};
class LLPanelPreference : public LLPanel

View File

@ -0,0 +1,333 @@
/**
* @file llfloatersimpleoutfitsnapshot.cpp
* @brief Snapshot preview window for saving as an outfit thumbnail in visual outfit gallery
*
* $LicenseInfo:firstyear=2022&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2022, 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$
*/
#include "llviewerprecompiledheaders.h"
#include "llfloatersimpleoutfitsnapshot.h"
#include "llfloaterreg.h"
#include "llimagefiltersmanager.h"
#include "llstatusbar.h" // can_afford_transaction()
#include "llnotificationsutil.h"
#include "llagentbenefits.h"
#include "llviewercontrol.h"
LLSimpleOutfitSnapshotFloaterView* gSimpleOutfitSnapshotFloaterView = NULL;
const S32 OUTFIT_SNAPSHOT_WIDTH = 256;
const S32 OUTFIT_SNAPSHOT_HEIGHT = 256;
static LLDefaultChildRegistry::Register<LLSimpleOutfitSnapshotFloaterView> r("simple_snapshot_outfit_floater_view");
///----------------------------------------------------------------------------
/// Class LLFloaterSimpleOutfitSnapshot::Impl
///----------------------------------------------------------------------------
LLSnapshotModel::ESnapshotFormat LLFloaterSimpleOutfitSnapshot::Impl::getImageFormat(LLFloaterSnapshotBase* floater)
{
return LLSnapshotModel::SNAPSHOT_FORMAT_PNG;
}
LLSnapshotModel::ESnapshotLayerType LLFloaterSimpleOutfitSnapshot::Impl::getLayerType(LLFloaterSnapshotBase* floater)
{
return LLSnapshotModel::SNAPSHOT_TYPE_COLOR;
}
void LLFloaterSimpleOutfitSnapshot::Impl::updateControls(LLFloaterSnapshotBase* floater)
{
LLSnapshotLivePreview* previewp = getPreviewView();
updateResolution(floater);
if (previewp)
{
previewp->setSnapshotType(LLSnapshotModel::ESnapshotType::SNAPSHOT_TEXTURE);
previewp->setSnapshotFormat(LLSnapshotModel::ESnapshotFormat::SNAPSHOT_FORMAT_PNG);
previewp->setSnapshotBufferType(LLSnapshotModel::ESnapshotLayerType::SNAPSHOT_TYPE_COLOR);
}
}
std::string LLFloaterSimpleOutfitSnapshot::Impl::getSnapshotPanelPrefix()
{
return "panel_outfit_snapshot_";
}
void LLFloaterSimpleOutfitSnapshot::Impl::updateResolution(void* data)
{
LLFloaterSimpleOutfitSnapshot *view = (LLFloaterSimpleOutfitSnapshot *)data;
if (!view)
{
llassert(view);
return;
}
S32 width = OUTFIT_SNAPSHOT_WIDTH;
S32 height = OUTFIT_SNAPSHOT_HEIGHT;
LLSnapshotLivePreview* previewp = getPreviewView();
if (previewp)
{
S32 original_width = 0, original_height = 0;
previewp->getSize(original_width, original_height);
if (gSavedSettings.getBOOL("RenderHUDInSnapshot"))
{ //clamp snapshot resolution to window size when showing UI HUD in snapshot
width = llmin(width, gViewerWindow->getWindowWidthRaw());
height = llmin(height, gViewerWindow->getWindowHeightRaw());
}
llassert(width > 0 && height > 0);
previewp->setSize(width, height);
if (original_width != width || original_height != height)
{
// hide old preview as the aspect ratio could be wrong
checkAutoSnapshot(previewp, FALSE);
previewp->updateSnapshot(TRUE);
}
}
}
void LLFloaterSimpleOutfitSnapshot::Impl::setStatus(EStatus status, bool ok, const std::string& msg)
{
switch (status)
{
case STATUS_READY:
mFloater->setCtrlsEnabled(true);
break;
case STATUS_WORKING:
mFloater->setCtrlsEnabled(false);
break;
case STATUS_FINISHED:
mFloater->setCtrlsEnabled(true);
break;
}
mStatus = status;
}
///----------------------------------------------------------------re------------
/// Class LLFloaterSimpleOutfitSnapshot
///----------------------------------------------------------------------------
LLFloaterSimpleOutfitSnapshot::LLFloaterSimpleOutfitSnapshot(const LLSD& key)
: LLFloaterSnapshotBase(key),
mOutfitGallery(NULL)
{
impl = new Impl(this);
}
LLFloaterSimpleOutfitSnapshot::~LLFloaterSimpleOutfitSnapshot()
{
}
BOOL LLFloaterSimpleOutfitSnapshot::postBuild()
{
getChild<LLUICtrl>("save_btn")->setLabelArg("[UPLOAD_COST]", std::to_string(LLAgentBenefitsMgr::current().getTextureUploadCost()));
childSetAction("new_snapshot_btn", ImplBase::onClickNewSnapshot, this);
childSetAction("save_btn", boost::bind(&LLFloaterSimpleOutfitSnapshot::onSend, this));
childSetAction("cancel_btn", boost::bind(&LLFloaterSimpleOutfitSnapshot::onCancel, this));
mThumbnailPlaceholder = getChild<LLUICtrl>("thumbnail_placeholder");
// create preview window
LLRect full_screen_rect = getRootView()->getRect();
LLSnapshotLivePreview::Params p;
p.rect(full_screen_rect);
LLSnapshotLivePreview* previewp = new LLSnapshotLivePreview(p);
LLView* parent_view = gSnapshotFloaterView->getParent();
parent_view->removeChild(gSnapshotFloaterView);
// make sure preview is below snapshot floater
parent_view->addChild(previewp);
parent_view->addChild(gSnapshotFloaterView);
//move snapshot floater to special purpose snapshotfloaterview
gFloaterView->removeChild(this);
gSnapshotFloaterView->addChild(this);
impl->mPreviewHandle = previewp->getHandle();
previewp->setContainer(this);
impl->updateControls(this);
impl->setAdvanced(true);
impl->setSkipReshaping(true);
previewp->mKeepAspectRatio = FALSE;
previewp->setThumbnailPlaceholderRect(getThumbnailPlaceholderRect());
previewp->setAllowRenderUI(false);
return TRUE;
}
const S32 PREVIEW_OFFSET_X = 12;
const S32 PREVIEW_OFFSET_Y = 70;
void LLFloaterSimpleOutfitSnapshot::draw()
{
LLSnapshotLivePreview* previewp = getPreviewView();
if (previewp && (previewp->isSnapshotActive() || previewp->getThumbnailLock()))
{
// don't render snapshot window in snapshot, even if "show ui" is turned on
return;
}
LLFloater::draw();
if (previewp && !isMinimized() && mThumbnailPlaceholder->getVisible())
{
if(previewp->getThumbnailImage())
{
bool working = impl->getStatus() == ImplBase::STATUS_WORKING;
const LLRect& thumbnail_rect = getThumbnailPlaceholderRect();
const S32 thumbnail_w = previewp->getThumbnailWidth();
const S32 thumbnail_h = previewp->getThumbnailHeight();
S32 offset_x = PREVIEW_OFFSET_X;
S32 offset_y = PREVIEW_OFFSET_Y;
gGL.matrixMode(LLRender::MM_MODELVIEW);
// Apply floater transparency to the texture unless the floater is focused.
F32 alpha = getTransparencyType() == TT_ACTIVE ? 1.0f : getCurrentTransparency();
LLColor4 color = working ? LLColor4::grey4 : LLColor4::white;
gl_draw_scaled_image(offset_x, offset_y,
thumbnail_w, thumbnail_h,
previewp->getThumbnailImage(), color % alpha);
#if LL_DARWIN
std::string alpha_color = getTransparencyType() == TT_ACTIVE ? "OutfitSnapshotMacMask" : "OutfitSnapshotMacMask2";
#else
std::string alpha_color = getTransparencyType() == TT_ACTIVE ? "FloaterFocusBackgroundColor" : "DkGray";
#endif
previewp->drawPreviewRect(offset_x, offset_y, LLUIColorTable::instance().getColor(alpha_color));
gGL.pushUIMatrix();
LLUI::translate((F32) thumbnail_rect.mLeft, (F32) thumbnail_rect.mBottom);
mThumbnailPlaceholder->draw();
gGL.popUIMatrix();
}
}
impl->updateLayout(this);
}
void LLFloaterSimpleOutfitSnapshot::onOpen(const LLSD& key)
{
LLSnapshotLivePreview* preview = getPreviewView();
if (preview)
{
preview->updateSnapshot(TRUE);
}
focusFirstItem(FALSE);
gSnapshotFloaterView->setEnabled(TRUE);
gSnapshotFloaterView->setVisible(TRUE);
gSnapshotFloaterView->adjustToFitScreen(this, FALSE);
impl->updateControls(this);
impl->setStatus(ImplBase::STATUS_READY);
}
void LLFloaterSimpleOutfitSnapshot::onCancel()
{
closeFloater();
}
void LLFloaterSimpleOutfitSnapshot::onSend()
{
S32 expected_upload_cost = LLAgentBenefitsMgr::current().getTextureUploadCost();
if (can_afford_transaction(expected_upload_cost))
{
saveTexture();
postSave();
}
else
{
LLSD args;
args["COST"] = llformat("%d", expected_upload_cost);
LLNotificationsUtil::add("ErrorPhotoCannotAfford", args);
inventorySaveFailed();
}
}
void LLFloaterSimpleOutfitSnapshot::postSave()
{
impl->setStatus(ImplBase::STATUS_WORKING);
}
// static
void LLFloaterSimpleOutfitSnapshot::update()
{
LLFloaterSimpleOutfitSnapshot* inst = findInstance();
if (inst != NULL)
{
inst->impl->updateLivePreview();
}
}
// static
LLFloaterSimpleOutfitSnapshot* LLFloaterSimpleOutfitSnapshot::findInstance()
{
return LLFloaterReg::findTypedInstance<LLFloaterSimpleOutfitSnapshot>("simple_outfit_snapshot");
}
// static
LLFloaterSimpleOutfitSnapshot* LLFloaterSimpleOutfitSnapshot::getInstance()
{
return LLFloaterReg::getTypedInstance<LLFloaterSimpleOutfitSnapshot>("simple_outfit_snapshot");
}
void LLFloaterSimpleOutfitSnapshot::saveTexture()
{
LLSnapshotLivePreview* previewp = getPreviewView();
if (!previewp)
{
llassert(previewp != NULL);
return;
}
if (mOutfitGallery)
{
mOutfitGallery->onBeforeOutfitSnapshotSave();
}
previewp->saveTexture(TRUE, getOutfitID().asString());
if (mOutfitGallery)
{
mOutfitGallery->onAfterOutfitSnapshotSave();
}
closeFloater();
}
///----------------------------------------------------------------------------
/// Class LLSimpleOutfitSnapshotFloaterView
///----------------------------------------------------------------------------
LLSimpleOutfitSnapshotFloaterView::LLSimpleOutfitSnapshotFloaterView(const Params& p) : LLFloaterView(p)
{
}
LLSimpleOutfitSnapshotFloaterView::~LLSimpleOutfitSnapshotFloaterView()
{
}

View File

@ -0,0 +1,129 @@
/**
* @file llfloatersimpleoutfitsnapshot.h
* @brief Snapshot preview window for saving as an outfit thumbnail in visual outfit gallery
*
* $LicenseInfo:firstyear=2022&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2022, 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_LLFLOATERSIMPLEOUTFITSNAPSHOT_H
#define LL_LLFLOATERSIMPLEOUTFITSNAPSHOT_H
#include "llfloater.h"
#include "llfloatersnapshot.h"
#include "lloutfitgallery.h"
#include "llsnapshotlivepreview.h"
///----------------------------------------------------------------------------
/// Class LLFloaterSimpleOutfitSnapshot
///----------------------------------------------------------------------------
class LLFloaterSimpleOutfitSnapshot : public LLFloaterSnapshotBase
{
LOG_CLASS(LLFloaterSimpleOutfitSnapshot);
public:
LLFloaterSimpleOutfitSnapshot(const LLSD& key);
~LLFloaterSimpleOutfitSnapshot();
BOOL postBuild();
void onOpen(const LLSD& key);
void draw();
static void update();
static LLFloaterSimpleOutfitSnapshot* getInstance();
static LLFloaterSimpleOutfitSnapshot* findInstance();
void saveTexture();
const LLRect& getThumbnailPlaceholderRect() { return mThumbnailPlaceholder->getRect(); }
void setOutfitID(LLUUID id) { mOutfitID = id; }
LLUUID getOutfitID() { return mOutfitID; }
void setGallery(LLOutfitGallery* gallery) { mOutfitGallery = gallery; }
void postSave();
class Impl;
friend class Impl;
private:
void onSend();
void onCancel();
LLUUID mOutfitID;
LLOutfitGallery* mOutfitGallery;
};
///----------------------------------------------------------------------------
/// Class LLFloaterSimpleOutfitSnapshot::Impl
///----------------------------------------------------------------------------
class LLFloaterSimpleOutfitSnapshot::Impl : public LLFloaterSnapshotBase::ImplBase
{
LOG_CLASS(LLFloaterSimpleOutfitSnapshot::Impl);
public:
Impl(LLFloaterSnapshotBase* floater)
: LLFloaterSnapshotBase::ImplBase(floater)
{}
~Impl()
{}
void updateResolution(void* data);
static void onSnapshotUploadFinished(LLFloaterSnapshotBase* floater, bool status);
LLPanelSnapshot* getActivePanel(LLFloaterSnapshotBase* floater, bool ok_if_not_found = true) { return NULL; }
LLSnapshotModel::ESnapshotFormat getImageFormat(LLFloaterSnapshotBase* floater);
std::string getSnapshotPanelPrefix();
void updateControls(LLFloaterSnapshotBase* floater);
void setStatus(EStatus status, bool ok = true, const std::string& msg = LLStringUtil::null);
private:
LLSnapshotModel::ESnapshotLayerType getLayerType(LLFloaterSnapshotBase* floater);
void setFinished(bool finished, bool ok = true, const std::string& msg = LLStringUtil::null) {};
};
///----------------------------------------------------------------------------
/// Class LLSimpleOutfitSnapshotFloaterView
///----------------------------------------------------------------------------
class LLSimpleOutfitSnapshotFloaterView : public LLFloaterView
{
public:
struct Params
: public LLInitParam::Block<Params, LLFloaterView::Params>
{
};
protected:
LLSimpleOutfitSnapshotFloaterView(const Params& p);
friend class LLUICtrlFactory;
public:
virtual ~LLSimpleOutfitSnapshotFloaterView();
};
extern LLSimpleOutfitSnapshotFloaterView* gSimpleOutfitSnapshotFloaterView;
#endif // LL_LLFLOATERSIMPLEOUTFITSNAPSHOT_H

View File

@ -176,16 +176,20 @@ void LLFloaterSnapshotBase::ImplBase::updateLayout(LLFloaterSnapshotBase* floate
LLUICtrl* thumbnail_placeholder = floaterp->getChild<LLUICtrl>("thumbnail_placeholder");
thumbnail_placeholder->setVisible(mAdvanced);
thumbnail_placeholder->reshape(panel_width, thumbnail_placeholder->getRect().getHeight());
floaterp->getChild<LLUICtrl>("image_res_text")->setVisible(mAdvanced);
floaterp->getChild<LLUICtrl>("file_size_label")->setVisible(mAdvanced);
if (floaterp->hasChild("360_label", TRUE))
{
floaterp->getChild<LLUICtrl>("360_label")->setVisible(mAdvanced);
}
if(!floaterp->isMinimized())
if (!mSkipReshaping)
{
floaterp->reshape(floater_width, floaterp->getRect().getHeight());
thumbnail_placeholder->reshape(panel_width, thumbnail_placeholder->getRect().getHeight());
if (!floaterp->isMinimized())
{
floaterp->reshape(floater_width, floaterp->getRect().getHeight());
}
}
bool use_freeze_frame = floaterp->getChild<LLUICtrl>("freeze_frame_check")->getValue().asBoolean();
@ -1193,7 +1197,7 @@ S32 LLFloaterSnapshotBase::notify(const LLSD& info)
// The refresh button is initially hidden. We show it after the first update,
// i.e. when preview appears.
if (!mRefreshBtn->getVisible())
if (mRefreshBtn && !mRefreshBtn->getVisible())
{
mRefreshBtn->setVisible(true);
}

View File

@ -59,9 +59,9 @@ public:
const LLRect& getThumbnailPlaceholderRect() { return mThumbnailPlaceholder->getRect(); }
void setRefreshLabelVisible(bool value) { mRefreshLabel->setVisible(value); }
void setSuccessLabelPanelVisible(bool value) { mSucceessLblPanel->setVisible(value); }
void setFailureLabelPanelVisible(bool value) { mFailureLblPanel->setVisible(value); }
void setRefreshLabelVisible(bool value) { if (mRefreshLabel) mRefreshLabel->setVisible(value); }
void setSuccessLabelPanelVisible(bool value) { if (mSucceessLblPanel) mSucceessLblPanel->setVisible(value); }
void setFailureLabelPanelVisible(bool value) { if (mFailureLblPanel) mFailureLblPanel->setVisible(value); }
void inventorySaveFailed();
class ImplBase;
@ -88,6 +88,7 @@ public:
mLastToolset(NULL),
mAspectRatioCheckOff(false),
mNeedRefresh(false),
mSkipReshaping(false),
mStatus(STATUS_READY),
mFloater(floater)
{}
@ -120,6 +121,7 @@ public:
static BOOL updatePreviewList(bool initialized);
void setAdvanced(bool advanced) { mAdvanced = advanced; }
void setSkipReshaping(bool skip) { mSkipReshaping = skip; }
virtual LLSnapshotModel::ESnapshotLayerType getLayerType(LLFloaterSnapshotBase* floater) = 0;
virtual void checkAutoSnapshot(LLSnapshotLivePreview* floater, BOOL update_thumbnail = FALSE);
@ -135,6 +137,7 @@ public:
bool mAspectRatioCheckOff;
bool mNeedRefresh;
bool mAdvanced;
bool mSkipReshaping;
EStatus mStatus;
};

View File

@ -289,7 +289,6 @@ void LLFloaterTranslationSettings::onBtnOK()
gSavedSettings.setString("TranslationService", getSelectedService());
gSavedSettings.setString("BingTranslateAPIKey", getEnteredBingKey());
gSavedSettings.setString("GoogleTranslateAPIKey", getEnteredGoogleKey());
(LLFloaterReg::getTypedInstance<LLFloaterIMNearbyChat>("nearby_chat"))->
showTranslationCheckbox(LLTranslate::isTranslationConfigured());
closeFloater(false);
}

View File

@ -175,8 +175,7 @@ public:
virtual void processGroupData() = 0;
protected:
LLUUID mGroupId;
private:
bool mRequestProcessed;
bool mRequestProcessed;
};
class LLFetchLeaveGroupData: public LLFetchGroupMemberData
@ -189,6 +188,22 @@ public:
{
LLGroupActions::processLeaveGroupDataResponse(mGroupId);
}
void changed(LLGroupChange gc)
{
if (gc == GC_PROPERTIES && !mRequestProcessed)
{
LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(mGroupId);
if (!gdatap)
{
LL_WARNS() << "GroupData was NULL" << LL_ENDL;
}
else
{
processGroupData();
mRequestProcessed = true;
}
}
}
};
LLFetchLeaveGroupData* gFetchLeaveGroupData = NULL;

View File

@ -55,6 +55,7 @@
#include "llviewerwindow.h"
#include "llviewerregion.h"
#include "llvoavatarself.h"
#include "llworld.h"
#include "boost/lexical_cast.hpp"
#if LL_MSVC
@ -520,8 +521,7 @@ void LLIMProcessing::processNewMessage(LLUUID from_id,
dialog,
parent_estate_id,
region_id,
position,
true);
position);
if (!gIMMgr->isDNDMessageSend(session_id))
{
@ -572,6 +572,15 @@ void LLIMProcessing::processNewMessage(LLUUID from_id,
}
if (!mute_im)
{
bool region_message = false;
if (region_id.isNull())
{
LLViewerRegion* regionp = LLWorld::instance().getRegionFromID(from_id);
if (regionp)
{
region_message = true;
}
}
gIMMgr->addMessage(
session_id,
from_id,
@ -583,7 +592,7 @@ void LLIMProcessing::processNewMessage(LLUUID from_id,
parent_estate_id,
region_id,
position,
true);
region_message);
}
else
{
@ -1102,8 +1111,7 @@ void LLIMProcessing::processNewMessage(LLUUID from_id,
IM_SESSION_INVITE,
parent_estate_id,
region_id,
position,
true);
position);
}
else
{
@ -1128,8 +1136,7 @@ void LLIMProcessing::processNewMessage(LLUUID from_id,
IM_SESSION_INVITE,
parent_estate_id,
region_id,
position,
true);
position);
}
break;

View File

@ -786,7 +786,7 @@ void LLIMModel::LLIMSession::sessionInitReplyReceived(const LLUUID& new_session_
}
}
void LLIMModel::LLIMSession::addMessage(const std::string& from, const LLUUID& from_id, const std::string& utf8_text, const std::string& time, const bool is_history)
void LLIMModel::LLIMSession::addMessage(const std::string& from, const LLUUID& from_id, const std::string& utf8_text, const std::string& time, const bool is_history, bool is_region_msg)
{
LLSD message;
message["from"] = from;
@ -795,6 +795,7 @@ void LLIMModel::LLIMSession::addMessage(const std::string& from, const LLUUID& f
message["time"] = time;
message["index"] = (LLSD::Integer)mMsgs.size();
message["is_history"] = is_history;
message["is_region_msg"] = is_region_msg;
LL_DEBUGS("UIUsage") << "addMessage " << " from " << from << " from_id " << from_id << " utf8_text " << utf8_text << " time " << time << " is_history " << is_history << " session mType " << mType << LL_ENDL;
if (from_id == gAgent.getID())
@ -1175,7 +1176,7 @@ void LLIMModel::sendNoUnreadMessages(const LLUUID& session_id)
mNoUnreadMsgsSignal(arg);
}
bool LLIMModel::addToHistory(const LLUUID& session_id, const std::string& from, const LLUUID& from_id, const std::string& utf8_text) {
bool LLIMModel::addToHistory(const LLUUID& session_id, const std::string& from, const LLUUID& from_id, const std::string& utf8_text, bool is_region_msg) {
LLIMSession* session = findIMSession(session_id);
@ -1185,7 +1186,7 @@ bool LLIMModel::addToHistory(const LLUUID& session_id, const std::string& from,
return false;
}
session->addMessage(from, from_id, utf8_text, LLLogChat::timestamp(false)); //might want to add date separately
session->addMessage(from, from_id, utf8_text, LLLogChat::timestamp(false), false, is_region_msg); //might want to add date separately
return true;
}
@ -1267,7 +1268,7 @@ void LLIMModel::processAddingMessage(const LLUUID& session_id, const std::string
}
LLIMModel::LLIMSession* LLIMModel::addMessageSilently(const LLUUID& session_id, const std::string& from, const LLUUID& from_id,
const std::string& utf8_text, bool log2file /* = true */)
const std::string& utf8_text, bool log2file, bool is_region_msg)
{
LLIMSession* session = findIMSession(session_id);
@ -1283,7 +1284,7 @@ LLIMModel::LLIMSession* LLIMModel::addMessageSilently(const LLUUID& session_id,
from_name = SYSTEM_FROM;
}
addToHistory(session_id, from_name, from_id, utf8_text);
addToHistory(session_id, from_name, from_id, utf8_text, is_region_msg);
if (log2file)
{
logToFile(getHistoryFileName(session_id), from_name, from_id, utf8_text);
@ -2706,7 +2707,7 @@ void LLIMMgr::addMessage(
U32 parent_estate_id,
const LLUUID& region_id,
const LLVector3& position,
bool link_name) // If this is true, then we insert the name and link it to a profile
bool is_region_msg)
{
LLUUID other_participant_id = target_id;
@ -2778,7 +2779,7 @@ void LLIMMgr::addMessage(
//<< "*** region_id: " << region_id << std::endl
//<< "*** position: " << position << std::endl;
LLIMModel::instance().addMessage(new_session_id, from, other_participant_id, bonus_info.str());
LLIMModel::instance().addMessage(new_session_id, from, other_participant_id, bonus_info.str(), true, is_region_msg);
}
// Logically it would make more sense to reject the session sooner, in another area of the
@ -2808,7 +2809,7 @@ void LLIMMgr::addMessage(
if (!LLMuteList::getInstance()->isMuted(other_participant_id, LLMute::flagTextChat) && !skip_message)
{
LLIMModel::instance().addMessage(new_session_id, from, other_participant_id, msg);
LLIMModel::instance().addMessage(new_session_id, from, other_participant_id, msg, true, is_region_msg);
}
// Open conversation floater if offline messages are present
@ -3735,8 +3736,7 @@ public:
IM_SESSION_INVITE,
message_params["parent_estate_id"].asInteger(),
message_params["region_id"].asUUID(),
ll_vector3_from_sd(message_params["position"]),
true);
ll_vector3_from_sd(message_params["position"]));
if (LLMuteList::getInstance()->isMuted(from_id, name, LLMute::flagTextChat))
{

View File

@ -81,7 +81,7 @@ public:
void sessionInitReplyReceived(const LLUUID& new_session_id);
void addMessagesFromHistory(const std::list<LLSD>& history);
void addMessage(const std::string& from, const LLUUID& from_id, const std::string& utf8_text, const std::string& time, const bool is_history = false);
void addMessage(const std::string& from, const LLUUID& from_id, const std::string& utf8_text, const std::string& time, const bool is_history = false, bool is_region_msg = false);
void onVoiceChannelStateChanged(const LLVoiceChannel::EState& old_state, const LLVoiceChannel::EState& new_state, const LLVoiceChannel::EDirection& direction);
/** @deprecated */
@ -208,14 +208,14 @@ public:
* and also saved into a file if log2file is specified.
* It sends new message signal for each added message.
*/
void addMessage(const LLUUID& session_id, const std::string& from, const LLUUID& other_participant_id, const std::string& utf8_text, bool log2file = true);
void addMessage(const LLUUID& session_id, const std::string& from, const LLUUID& other_participant_id, const std::string& utf8_text, bool log2file = true, bool is_region_msg = false);
void processAddingMessage(const LLUUID& session_id, const std::string& from, const LLUUID& other_participant_id, const std::string& utf8_text, bool log2file = true);
/**
* Similar to addMessage(...) above but won't send a signal about a new message added
*/
LLIMModel::LLIMSession* addMessageSilently(const LLUUID& session_id, const std::string& from, const LLUUID& from_id,
const std::string& utf8_text, bool log2file = true);
const std::string& utf8_text, bool log2file = true, bool is_region_msg = false);
/**
* Add a system message to an IM Model
@ -293,7 +293,7 @@ private:
/**
* Add message to a list of message associated with session specified by session_id
*/
bool addToHistory(const LLUUID& session_id, const std::string& from, const LLUUID& from_id, const std::string& utf8_text);
bool addToHistory(const LLUUID& session_id, const std::string& from, const LLUUID& from_id, const std::string& utf8_text, bool is_region_msg = false);
};
@ -335,7 +335,7 @@ public:
U32 parent_estate_id = 0,
const LLUUID& region_id = LLUUID::null,
const LLVector3& position = LLVector3::zero,
bool link_name = false);
bool is_region_msg = false);
void addSystemMessage(const LLUUID& session_id, const std::string& message_name, const LLSD& args);

View File

@ -614,7 +614,7 @@ BOOL LLInvFVBridge::isClipboardPasteable() const
if (cat)
{
LLFolderBridge cat_br(mInventoryPanel.get(), mRoot, item_id);
if (!cat_br.isItemCopyable())
if (!cat_br.isItemCopyable(false))
return FALSE;
// Skip to the next item in the clipboard
continue;
@ -622,7 +622,7 @@ BOOL LLInvFVBridge::isClipboardPasteable() const
// Each item must be copyable to be pastable
LLItemBridge item_br(mInventoryPanel.get(), mRoot, item_id);
if (!item_br.isItemCopyable())
if (!item_br.isItemCopyable(false))
{
return FALSE;
}
@ -654,6 +654,11 @@ BOOL LLInvFVBridge::isClipboardPasteableAsLink() const
{
return FALSE;
}
if (gInventory.isObjectDescendentOf(item->getUUID(), gInventory.getLibraryRootFolderID()))
{
return FALSE;
}
}
const LLViewerInventoryCategory *cat = model->getCategory(objects.at(i));
if (cat && LLFolderType::lookupIsProtectedType(cat->getPreferredType()))
@ -729,15 +734,15 @@ void hide_context_entries(LLMenuGL& menu,
}
bool found = false;
menuentry_vec_t::const_iterator itor2;
for (itor2 = entries_to_show.begin(); itor2 != entries_to_show.end(); ++itor2)
{
if (*itor2 == name)
{
found = true;
break;
}
}
std::string myinput;
std::vector<std::string> mylist{ "a", "b", "c" };
menuentry_vec_t::const_iterator itor2 = std::find(entries_to_show.begin(), entries_to_show.end(), name);
if (itor2 != entries_to_show.end())
{
found = true;
}
// Don't allow multiple separators in a row (e.g. such as if there are no items
// between two separators).
@ -755,7 +760,21 @@ void hide_context_entries(LLMenuGL& menu,
menu_item->setVisible(FALSE);
}
menu_item->setEnabled(FALSE);
if (menu_item->getEnabled())
{
// These should stay enabled unless specifically disabled
const menuentry_vec_t exceptions = {
"Detach From Yourself",
"Wearable And Object Wear",
"Wearable Add",
};
menuentry_vec_t::const_iterator itor2 = std::find(exceptions.begin(), exceptions.end(), name);
if (itor2 == exceptions.end())
{
menu_item->setEnabled(FALSE);
}
}
}
else
{
@ -882,7 +901,8 @@ void LLInvFVBridge::getClipboardEntries(bool show_asset_id,
disabled_items.push_back(std::string("Paste"));
}
if (gSavedSettings.getBOOL("InventoryLinking"))
static LLCachedControl<bool> inventory_linking(gSavedSettings, "InventoryLinking", true);
if (inventory_linking)
{
items.push_back(std::string("Paste As Link"));
if (!isClipboardPasteableAsLink() || (flags & FIRST_SELECTED_ITEM) == 0)
@ -2059,7 +2079,8 @@ BOOL LLItemBridge::removeItem()
// we can't do this check because we may have items in a folder somewhere that is
// not yet in memory, so we don't want false negatives. (If disabled, then we
// know we only have links in the Outfits folder which we explicitly fetch.)
if (!gSavedSettings.getBOOL("InventoryLinking"))
static LLCachedControl<bool> inventory_linking(gSavedSettings, "InventoryLinking", true);
if (!inventory_linking)
{
if (!item->getIsLinkType())
{
@ -2102,22 +2123,24 @@ BOOL LLItemBridge::confirmRemoveItem(const LLSD& notification, const LLSD& respo
return FALSE;
}
BOOL LLItemBridge::isItemCopyable() const
bool LLItemBridge::isItemCopyable(bool can_copy_as_link) const
{
LLViewerInventoryItem* item = getItem();
if (item)
{
// Can't copy worn objects.
// Worn objects are tied to their inworld conterparts
// Copy of modified worn object will return object with obsolete asset and inventory
if(get_is_item_worn(mUUID))
{
return FALSE;
}
LLViewerInventoryItem* item = getItem();
if (!item)
{
return false;
}
// Can't copy worn objects.
// Worn objects are tied to their inworld conterparts
// Copy of modified worn object will return object with obsolete asset and inventory
if (get_is_item_worn(mUUID))
{
return false;
}
return item->getPermissions().allowCopyBy(gAgent.getID()) || gSavedSettings.getBOOL("InventoryLinking");
}
return FALSE;
static LLCachedControl<bool> inventory_linking(gSavedSettings, "InventoryLinking", true);
return (can_copy_as_link && inventory_linking)
|| item->getPermissions().allowCopyBy(gAgent.getID());
}
LLViewerInventoryItem* LLItemBridge::getItem() const
@ -2321,7 +2344,7 @@ BOOL LLFolderBridge::isUpToDate() const
return category->getVersion() != LLViewerInventoryCategory::VERSION_UNKNOWN;
}
BOOL LLFolderBridge::isItemCopyable() const
bool LLFolderBridge::isItemCopyable(bool can_copy_as_link) const
{
// Folders are copyable if items in them are, recursively, copyable.
@ -2336,22 +2359,26 @@ BOOL LLFolderBridge::isItemCopyable() const
{
LLInventoryItem* item = *iter;
LLItemBridge item_br(mInventoryPanel.get(), mRoot, item->getUUID());
if (!item_br.isItemCopyable())
return FALSE;
}
if (!item_br.isItemCopyable(false))
{
return false;
}
}
// Check the folders
LLInventoryModel::cat_array_t cat_array_copy = *cat_array;
for (LLInventoryModel::cat_array_t::iterator iter = cat_array_copy.begin(); iter != cat_array_copy.end(); iter++)
{
{
LLViewerInventoryCategory* category = *iter;
LLFolderBridge cat_br(mInventoryPanel.get(), mRoot, category->getUUID());
if (!cat_br.isItemCopyable())
return FALSE;
}
return TRUE;
}
if (!cat_br.isItemCopyable(false))
{
return false;
}
}
return true;
}
BOOL LLFolderBridge::isClipboardPasteable() const
{
@ -3768,6 +3795,7 @@ void LLFolderBridge::perform_pasteFromClipboard()
LLInventoryObject *obj = model->getObject(item_id);
if (obj)
{
if (move_is_into_lost_and_found)
{
if (LLAssetType::AT_CATEGORY == obj->getType())
@ -4296,7 +4324,7 @@ void LLFolderBridge::buildContextMenuFolderOptions(U32 flags, menuentry_vec_t&
items.push_back(std::string("IM All Contacts In Folder"));
}
if (((flags & ITEM_IN_MULTI_SELECTION) == 0) && hasChildren())
if (((flags & ITEM_IN_MULTI_SELECTION) == 0) && hasChildren() && (type != LLFolderType::FT_OUTFIT))
{
items.push_back(std::string("Ungroup folder items"));
}

View File

@ -119,7 +119,7 @@ public:
//virtual BOOL removeItem() = 0;
virtual void removeBatch(std::vector<LLFolderViewModelItem*>& batch);
virtual void move(LLFolderViewModelItem* new_parent_bridge) {}
virtual BOOL isItemCopyable() const { return FALSE; }
virtual bool isItemCopyable(bool can_copy_as_link = true) const { return false; }
virtual BOOL copyToClipboard() const;
virtual BOOL cutToClipboard();
virtual bool isCutToClipboard();
@ -245,7 +245,7 @@ public:
virtual BOOL isItemRenameable() const;
virtual BOOL renameItem(const std::string& new_name);
virtual BOOL removeItem();
virtual BOOL isItemCopyable() const;
virtual bool isItemCopyable(bool can_copy_as_link = true) const;
virtual bool hasChildren() const { return FALSE; }
virtual BOOL isUpToDate() const { return TRUE; }
virtual LLUIImagePtr getIconOverlay() const;
@ -318,7 +318,7 @@ public:
virtual BOOL isItemRemovable() const;
virtual BOOL isItemMovable() const ;
virtual BOOL isUpToDate() const;
virtual BOOL isItemCopyable() const;
virtual bool isItemCopyable(bool can_copy_as_link = true) const;
virtual BOOL isClipboardPasteable() const;
virtual BOOL isClipboardPasteableAsLink() const;

View File

@ -867,6 +867,9 @@ LLUUID create_folder_for_item(LLInventoryItem* item, const LLUUID& destFolderId)
S32 depth_nesting_in_marketplace(LLUUID cur_uuid)
{
// Get the marketplace listings root, exit with -1 (i.e. not under the marketplace listings root) if none
// Todo: findCategoryUUIDForType is somewhat expensive with large
// flat root folders yet we use depth_nesting_in_marketplace at
// every turn, find a way to correctly cache this id.
const LLUUID marketplace_listings_uuid = gInventory.findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS, false);
if (marketplace_listings_uuid.isNull())
{
@ -1509,7 +1512,12 @@ void dump_trace(std::string& message, S32 depth, LLError::ELevel log_level)
// This function does no deletion of listings but a mere audit and raises issues to the user (through the
// optional callback cb). It also returns a boolean, true if things validate, false if issues are raised.
// The only inventory changes that are done is to move and sort folders containing no-copy items to stock folders.
bool validate_marketplacelistings(LLInventoryCategory* cat, validation_callback_t cb, bool fix_hierarchy, S32 depth)
bool validate_marketplacelistings(
LLInventoryCategory* cat,
validation_callback_t cb,
bool fix_hierarchy,
S32 depth,
bool notify_observers)
{
#if 0
// Used only for debug
@ -1575,7 +1583,7 @@ bool validate_marketplacelistings(LLInventoryCategory* cat, validation_callback_
LLUUID folder_uuid = gInventory.createNewCategory(parent_uuid, LLFolderType::FT_NONE, cat->getName());
LLInventoryCategory* new_cat = gInventory.getCategory(folder_uuid);
gInventory.changeCategoryParent(viewer_cat, folder_uuid, false);
result &= validate_marketplacelistings(new_cat, cb, fix_hierarchy, depth + 1);
result &= validate_marketplacelistings(new_cat, cb, fix_hierarchy, depth + 1, notify_observers);
return result;
}
else
@ -1745,7 +1753,10 @@ bool validate_marketplacelistings(LLInventoryCategory* cat, validation_callback_
// Next type
update_marketplace_category(parent_uuid);
update_marketplace_category(folder_uuid);
gInventory.notifyObservers();
if (notify_observers)
{
gInventory.notifyObservers();
}
items_vector_it++;
}
}
@ -1759,7 +1770,7 @@ bool validate_marketplacelistings(LLInventoryCategory* cat, validation_callback_
{
LLViewerInventoryCategory * viewer_cat = (LLViewerInventoryCategory *) (*iter);
gInventory.changeCategoryParent(viewer_cat, parent_uuid, false);
result &= validate_marketplacelistings(viewer_cat, cb, fix_hierarchy, depth);
result &= validate_marketplacelistings(viewer_cat, cb, fix_hierarchy, depth, false);
}
}
}
@ -1831,7 +1842,10 @@ bool validate_marketplacelistings(LLInventoryCategory* cat, validation_callback_
cb(message,depth,LLError::LEVEL_WARN);
}
gInventory.removeCategory(cat->getUUID());
gInventory.notifyObservers();
if (notify_observers)
{
gInventory.notifyObservers();
}
return result && !has_bad_items;
}
}
@ -1845,11 +1859,14 @@ bool validate_marketplacelistings(LLInventoryCategory* cat, validation_callback_
for (LLInventoryModel::cat_array_t::iterator iter = cat_array_copy.begin(); iter != cat_array_copy.end(); iter++)
{
LLInventoryCategory* category = *iter;
result &= validate_marketplacelistings(category, cb, fix_hierarchy, depth + 1);
result &= validate_marketplacelistings(category, cb, fix_hierarchy, depth + 1, false);
}
update_marketplace_category(cat->getUUID(), true, true);
gInventory.notifyObservers();
if (notify_observers)
{
gInventory.notifyObservers();
}
return result && !has_bad_items;
}
@ -2587,13 +2604,63 @@ void LLInventoryAction::doToSelected(LLInventoryModel* model, LLFolderView* root
LLFloater::setFloaterHost(multi_propertiesp);
}
std::set<LLUUID> selected_uuid_set = LLAvatarActions::getInventorySelectedUUIDs();
// copy list of applicable items into a vector for bulk handling
uuid_vec_t ids;
for (std::set<LLFolderViewItem*>::iterator it = selected_items.begin(), end_it = selected_items.end();
it != end_it;
++it)
if (action == "wear" || action == "wear_add")
{
ids.push_back(static_cast<LLFolderViewModelItemInventory*>((*it)->getViewModelItem())->getUUID());
const LLUUID trash_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_TRASH);
const LLUUID mp_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS, false);
std::copy_if(selected_uuid_set.begin(),
selected_uuid_set.end(),
std::back_inserter(ids),
[trash_id, mp_id](LLUUID id)
{
if (get_is_item_worn(id)
|| LLAppearanceMgr::instance().getIsInCOF(id)
|| gInventory.isObjectDescendentOf(id, trash_id))
{
return false;
}
if (mp_id.notNull() && gInventory.isObjectDescendentOf(id, mp_id))
{
return false;
}
LLInventoryObject* obj = (LLInventoryObject*)gInventory.getObject(id);
if (!obj)
{
return false;
}
if (obj->getIsLinkType() && gInventory.isObjectDescendentOf(obj->getLinkedUUID(), trash_id))
{
return false;
}
if (obj->getIsLinkType() && LLAssetType::lookupIsLinkType(obj->getType()))
{
// missing
return false;
}
return true;
}
);
}
else if (isRemoveAction(action))
{
std::copy_if(selected_uuid_set.begin(),
selected_uuid_set.end(),
std::back_inserter(ids),
[](LLUUID id)
{
return get_is_item_worn(id);
}
);
}
else
{
std::copy(selected_uuid_set.begin(), selected_uuid_set.end(), std::back_inserter(ids));
}
// Check for actions that get handled in bulk
if (action == "wear")
{

View File

@ -87,7 +87,7 @@ bool can_move_item_to_marketplace(const LLInventoryCategory* root_folder, LLInve
bool can_move_folder_to_marketplace(const LLInventoryCategory* root_folder, LLInventoryCategory* dest_folder, LLInventoryCategory* inv_cat, std::string& tooltip_msg, S32 bundle_size = 1, bool check_items = true, bool from_paste = false);
bool move_item_to_marketplacelistings(LLInventoryItem* inv_item, LLUUID dest_folder, bool copy = false);
bool move_folder_to_marketplacelistings(LLInventoryCategory* inv_cat, const LLUUID& dest_folder, bool copy = false, bool move_no_copy_items = false);
bool validate_marketplacelistings(LLInventoryCategory* inv_cat, validation_callback_t cb = NULL, bool fix_hierarchy = true, S32 depth = -1);
bool validate_marketplacelistings(LLInventoryCategory* inv_cat, validation_callback_t cb = NULL, bool fix_hierarchy = true, S32 depth = -1, bool notify_observers = true);
S32 depth_nesting_in_marketplace(LLUUID cur_uuid);
LLUUID nested_parent_id(LLUUID cur_uuid, S32 depth);
S32 compute_stock_count(LLUUID cat_uuid, bool force_count = false);

View File

@ -1853,9 +1853,13 @@ void LLInventoryModel::addChangedMask(U32 mask, const LLUUID& referent)
mChangedItemIDs.insert(referent);
}
// Fix me: From DD-81, probably shouldn't be here, instead
// should be somewhere in an observer
update_marketplace_category(referent, false);
if (mask != LLInventoryObserver::LABEL)
{
// Fix me: From DD-81, probably shouldn't be here, instead
// should be somewhere in an observer or in
// LLMarketplaceInventoryObserver::onIdleProcessQueue
update_marketplace_category(referent, false);
}
if (mask & LLInventoryObserver::ADD)
{

View File

@ -30,6 +30,7 @@
#include "llagent.h"
#include "llbufferstream.h"
#include "llcallbacklist.h"
#include "llinventoryfunctions.h"
#include "llinventoryobserver.h"
#include "llnotificationsutil.h"
@ -605,20 +606,67 @@ public:
LLMarketplaceInventoryObserver() {}
virtual ~LLMarketplaceInventoryObserver() {}
virtual void changed(U32 mask);
private:
static void onIdleProcessQueue(void *userdata);
// doesn't hold just marketplace related ids
static std::set<LLUUID> sAddQueue;
static std::set<LLUUID> sStructureQueue;
static bool sProcessingQueue;
};
std::set<LLUUID> LLMarketplaceInventoryObserver::sAddQueue;
std::set<LLUUID> LLMarketplaceInventoryObserver::sStructureQueue;
bool LLMarketplaceInventoryObserver::sProcessingQueue = false;
void LLMarketplaceInventoryObserver::changed(U32 mask)
{
// When things are added to the marketplace, we might need to re-validate and fix the containing listings
if (mask & LLInventoryObserver::ADD)
if (mask & LLInventoryObserver::ADD && LLMarketplaceData::instance().hasValidationWaiting())
{
// When things are added to the marketplace, we might need to re-validate and fix the containing listings
// just add whole list even if it contains items and non-marketplace folders
const std::set<LLUUID>& changed_items = gInventory.getChangedIDs();
std::set<LLUUID>::const_iterator id_it = changed_items.begin();
std::set<LLUUID>::const_iterator id_end = changed_items.end();
sAddQueue.insert(changed_items.begin(), changed_items.end());
}
if (mask & (LLInventoryObserver::INTERNAL | LLInventoryObserver::STRUCTURE))
{
// When things are changed in the inventory, this can trigger a host of changes in the marketplace listings folder:
// * stock counts changing : no copy items coming in and out will change the stock count on folders
// * version and listing folders : moving those might invalidate the marketplace data itself
// Since we should cannot raise inventory change while the observer is called (the list will be cleared
// once observers are called) we need to raise a flag in the inventory to signal that things have been dirtied.
const std::set<LLUUID>& changed_items = gInventory.getChangedIDs();
sStructureQueue.insert(changed_items.begin(), changed_items.end());
}
if (!sProcessingQueue && (!sAddQueue.empty() || !sStructureQueue.empty()))
{
gIdleCallbacks.addFunction(onIdleProcessQueue, NULL);
// can do without sProcessingQueue, but it's usufull for simplicity and reliability
sProcessingQueue = true;
}
}
void LLMarketplaceInventoryObserver::onIdleProcessQueue(void *userdata)
{
U64 start_time = LLTimer::getTotalTime(); // microseconds
const U64 MAX_PROCESSING_TIME = 1000;
U64 stop_time = start_time + MAX_PROCESSING_TIME;
if (!sAddQueue.empty())
{
// Make a copy of sAddQueue since decrementValidationWaiting
// can theoretically add more items
std::set<LLUUID> add_queue(sAddQueue);
sAddQueue.clear();
std::set<LLUUID>::const_iterator id_it = add_queue.begin();
std::set<LLUUID>::const_iterator id_end = add_queue.end();
// First, count the number of items in this list...
S32 count = 0;
for (;id_it != id_end; ++id_it)
for (; id_it != id_end; ++id_it)
{
LLInventoryObject* obj = gInventory.getObject(*id_it);
if (obj && (LLAssetType::AT_CATEGORY != obj->getType()))
@ -629,56 +677,58 @@ void LLMarketplaceInventoryObserver::changed(U32 mask)
// Then, decrement the folders of that amount
// Note that of all of those, only one folder will be a listing folder (if at all).
// The other will be ignored by the decrement method.
id_it = changed_items.begin();
for (;id_it != id_end; ++id_it)
id_it = add_queue.begin();
for (; id_it != id_end; ++id_it)
{
LLInventoryObject* obj = gInventory.getObject(*id_it);
if (obj && (LLAssetType::AT_CATEGORY == obj->getType()))
{
LLMarketplaceData::instance().decrementValidationWaiting(obj->getUUID(),count);
// can trigger notifyObservers
LLMarketplaceData::instance().decrementValidationWaiting(obj->getUUID(), count);
}
}
}
// When things are changed in the inventory, this can trigger a host of changes in the marketplace listings folder:
// * stock counts changing : no copy items coming in and out will change the stock count on folders
// * version and listing folders : moving those might invalidate the marketplace data itself
// Since we should cannot raise inventory change while the observer is called (the list will be cleared
// once observers are called) we need to raise a flag in the inventory to signal that things have been dirtied.
if (mask & (LLInventoryObserver::INTERNAL | LLInventoryObserver::STRUCTURE))
{
const std::set<LLUUID>& changed_items = gInventory.getChangedIDs();
std::set<LLUUID>::const_iterator id_it = changed_items.begin();
std::set<LLUUID>::const_iterator id_end = changed_items.end();
for (;id_it != id_end; ++id_it)
}
while (!sStructureQueue.empty() && LLTimer::getTotalTime() < stop_time)
{
std::set<LLUUID>::const_iterator id_it = sStructureQueue.begin();
LLInventoryObject* obj = gInventory.getObject(*id_it);
if (obj)
{
LLInventoryObject* obj = gInventory.getObject(*id_it);
if (obj)
if (LLAssetType::AT_CATEGORY == obj->getType())
{
if (LLAssetType::AT_CATEGORY == obj->getType())
// If it's a folder known to the marketplace, let's check it's in proper shape
if (LLMarketplaceData::instance().isListed(*id_it) || LLMarketplaceData::instance().isVersionFolder(*id_it))
{
// If it's a folder known to the marketplace, let's check it's in proper shape
if (LLMarketplaceData::instance().isListed(*id_it) || LLMarketplaceData::instance().isVersionFolder(*id_it))
{
LLInventoryCategory* cat = (LLInventoryCategory*)(obj);
validate_marketplacelistings(cat);
}
LLInventoryCategory* cat = (LLInventoryCategory*)(obj);
// can trigger notifyObservers
// can cause more structural changes
validate_marketplacelistings(cat);
}
else
}
else
{
// If it's not a category, it's an item...
LLInventoryItem* item = (LLInventoryItem*)(obj);
// If it's a no copy item, we may need to update the label count of marketplace listings
if (!item->getPermissions().allowOperationBy(PERM_COPY, gAgent.getID(), gAgent.getGroupID()))
{
// If it's not a category, it's an item...
LLInventoryItem* item = (LLInventoryItem*)(obj);
// If it's a no copy item, we may need to update the label count of marketplace listings
if (!item->getPermissions().allowOperationBy(PERM_COPY, gAgent.getID(), gAgent.getGroupID()))
{
LLMarketplaceData::instance().setDirtyCount();
}
LLMarketplaceData::instance().setDirtyCount();
}
}
}
}
// sStructureQueue could have been modified in validate_marketplacelistings
// adding items does not invalidate existing iterator
sStructureQueue.erase(id_it);
}
if (LLApp::isExiting() || (sAddQueue.empty() && sStructureQueue.empty()))
{
// Nothing to do anymore
gIdleCallbacks.deleteFunction(onIdleProcessQueue, NULL);
sProcessingQueue = false;
}
}
// Tuple == Item

View File

@ -242,6 +242,7 @@ public:
void setUpdating(const LLUUID& folder_id, bool isUpdating);
// Used to decide when to run a validation on listing folders
bool hasValidationWaiting() { return mValidationWaitingList.size() > 0; }
void setValidationWaiting(const LLUUID& folder_id, S32 count);
void decrementValidationWaiting(const LLUUID& folder_id, S32 count = 1);

View File

@ -41,7 +41,7 @@
#include "llfilepicker.h"
#include "llfloaterperms.h"
#include "llfloaterreg.h"
#include "llfloateroutfitsnapshot.h"
#include "llfloatersimpleoutfitsnapshot.h"
#include "llimagedimensionsinfo.h"
#include "llinventoryfunctions.h"
#include "llinventorymodel.h"
@ -1386,8 +1386,8 @@ void LLOutfitGallery::onSelectPhoto(LLUUID selected_outfit_id)
void LLOutfitGallery::onTakeSnapshot(LLUUID selected_outfit_id)
{
LLFloaterReg::toggleInstanceOrBringToFront("outfit_snapshot");
LLFloaterOutfitSnapshot* snapshot_floater = LLFloaterOutfitSnapshot::getInstance();
LLFloaterReg::toggleInstanceOrBringToFront("simple_outfit_snapshot");
LLFloaterSimpleOutfitSnapshot* snapshot_floater = LLFloaterSimpleOutfitSnapshot::getInstance();
if (snapshot_floater)
{
snapshot_floater->setOutfitID(selected_outfit_id);

View File

@ -455,6 +455,7 @@ bool LLPanelMediaSettingsGeneral::navigateHomeSelectedFace(bool only_if_current_
LLViewerMedia::getInstance()->getMediaImplFromTextureID(object->getTE(face)->getMediaData()->getMediaID());
if (media_impl)
{
media_impl->setPriority(LLPluginClassMedia::PRIORITY_NORMAL);
media_impl->navigateHome();
if (!only_if_current_is_empty)

View File

@ -93,6 +93,8 @@ enum {
MI_HOLE_COUNT
};
const F32 MAX_ATTACHMENT_DIST = 3.5f; // meters
//static const std::string LEGACY_FULLBRIGHT_DESC =LLTrans::getString("Fullbright");
BOOL LLPanelObject::postBuild()
@ -1685,6 +1687,16 @@ void LLPanelObject::sendPosition(BOOL btn_down)
mCtrlPosZ->set(LLWorld::getInstance()->resolveLandHeightAgent(newpos) + 1.f);
}
}
else
{
if (newpos.length() > MAX_ATTACHMENT_DIST)
{
newpos.clampLength(MAX_ATTACHMENT_DIST);
mCtrlPosX->set(newpos.mV[VX]);
mCtrlPosY->set(newpos.mV[VY]);
mCtrlPosZ->set(newpos.mV[VZ]);
}
}
// Make sure new position is in a valid region, so the object
// won't get dumped by the simulator.
@ -2191,6 +2203,10 @@ void LLPanelObject::onPastePos()
mClipboardPos.mV[VY] = llclamp(mClipboardPos.mV[VY], 0.f, max_width);
//height will get properly clamped by sendPosition
}
else
{
mClipboardPos.clampLength(MAX_ATTACHMENT_DIST);
}
mCtrlPosX->set( mClipboardPos.mV[VX] );
mCtrlPosY->set( mClipboardPos.mV[VY] );

View File

@ -131,7 +131,7 @@ public:
virtual BOOL removeItem();
virtual void removeBatch(std::vector<LLFolderViewModelItem*>& batch);
virtual void move(LLFolderViewModelItem* parent_listener);
virtual BOOL isItemCopyable() const;
virtual bool isItemCopyable(bool can_copy_as_link = true) const;
virtual BOOL copyToClipboard() const;
virtual BOOL cutToClipboard();
virtual BOOL isClipboardPasteable() const;
@ -439,10 +439,10 @@ void LLTaskInvFVBridge::move(LLFolderViewModelItem* parent_listener)
{
}
BOOL LLTaskInvFVBridge::isItemCopyable() const
bool LLTaskInvFVBridge::isItemCopyable(bool can_link) const
{
LLInventoryItem* item = findItem();
if(!item) return FALSE;
if(!item) return false;
return gAgent.allowOperation(PERM_COPY, item->getPermissions(),
GP_OBJECT_MANIPULATE);
}

View File

@ -127,7 +127,10 @@ void LLPanelPresetsCameraPulldown::onRowClick(const LLSD& user_data)
LL_DEBUGS() << "selected '" << name << "'" << LL_ENDL;
LLFloaterCamera::switchToPreset(name);
setVisible(FALSE);
// Scroll grabbed focus, drop it to prevent selection of parent menu
setFocus(FALSE);
setVisible(FALSE);
}
else
{

View File

@ -122,6 +122,9 @@ void LLPanelPresetsPulldown::onRowClick(const LLSD& user_data)
LL_DEBUGS() << "selected '" << name << "'" << LL_ENDL;
LLPresetsManager::getInstance()->loadPreset(PRESETS_GRAPHIC, name);
// Scroll grabbed focus, drop it to prevent selection of parent menu
setFocus(FALSE);
setVisible(FALSE);
}
else

View File

@ -51,6 +51,7 @@ void LLPanelPulldown::onMouseEnter(S32 x, S32 y, MASK mask)
/*virtual*/
void LLPanelPulldown::onTopLost()
{
setFocus(FALSE); // drop focus to prevent transfer to parent
setVisible(FALSE);
}
@ -113,6 +114,7 @@ void LLPanelPulldown::draw()
if (alpha == 0.f)
{
setFocus(FALSE); // drop focus to prevent transfer to parent
setVisible(FALSE);
}
}

View File

@ -187,82 +187,8 @@ void LLScriptEditor::drawSelectionBackground()
// Draw selection even if we don't have keyboard focus for search/replace
if( hasSelection() && !mLineInfoList.empty())
{
std::vector<LLRect> selection_rects;
S32 selection_left = llmin( mSelectionStart, mSelectionEnd );
S32 selection_right = llmax( mSelectionStart, mSelectionEnd );
// Skip through the lines we aren't drawing.
LLRect content_display_rect = getVisibleDocumentRect();
// binary search for line that starts before top of visible buffer
line_list_t::const_iterator line_iter = std::lower_bound(mLineInfoList.begin(), mLineInfoList.end(), content_display_rect.mTop, LLTextBase::compare_bottom());
line_list_t::const_iterator end_iter = std::upper_bound(mLineInfoList.begin(), mLineInfoList.end(), content_display_rect.mBottom, LLTextBase::compare_top());
bool done = false;
// Find the coordinates of the selected area
for (;line_iter != end_iter && !done; ++line_iter)
{
// is selection visible on this line?
if (line_iter->mDocIndexEnd > selection_left && line_iter->mDocIndexStart < selection_right)
{
segment_set_t::iterator segment_iter;
S32 segment_offset;
getSegmentAndOffset(line_iter->mDocIndexStart, &segment_iter, &segment_offset);
LLRect selection_rect;
selection_rect.mLeft = line_iter->mRect.mLeft;
selection_rect.mRight = line_iter->mRect.mLeft;
selection_rect.mBottom = line_iter->mRect.mBottom;
selection_rect.mTop = line_iter->mRect.mTop;
for(;segment_iter != mSegments.end(); ++segment_iter, segment_offset = 0)
{
LLTextSegmentPtr segmentp = *segment_iter;
S32 segment_line_start = segmentp->getStart() + segment_offset;
S32 segment_line_end = llmin(segmentp->getEnd(), line_iter->mDocIndexEnd);
if (segment_line_start > segment_line_end) break;
S32 segment_width = 0;
S32 segment_height = 0;
// if selection after beginning of segment
if(selection_left >= segment_line_start)
{
S32 num_chars = llmin(selection_left, segment_line_end) - segment_line_start;
segmentp->getDimensions(segment_offset, num_chars, segment_width, segment_height);
selection_rect.mLeft += segment_width;
}
// if selection_right == segment_line_end then that means we are the first character of the next segment
// or first character of the next line, in either case we want to add the length of the current segment
// to the selection rectangle and continue.
// if selection right > segment_line_end then selection spans end of current segment...
if (selection_right >= segment_line_end)
{
// extend selection slightly beyond end of line
// to indicate selection of newline character (use "n" character to determine width)
S32 num_chars = segment_line_end - segment_line_start;
segmentp->getDimensions(segment_offset, num_chars, segment_width, segment_height);
selection_rect.mRight += segment_width;
}
// else if selection ends on current segment...
else
{
S32 num_chars = selection_right - segment_line_start;
segmentp->getDimensions(segment_offset, num_chars, segment_width, segment_height);
selection_rect.mRight += segment_width;
break;
}
}
selection_rects.push_back(selection_rect);
}
}
std::vector<LLRect> selection_rects = getSelctionRects();
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
const LLColor4& color = mReadOnly ? mReadOnlyFgColor : mFgColor;
F32 alpha = hasFocus() ? 0.7f : 0.3f;
@ -272,6 +198,7 @@ void LLScriptEditor::drawSelectionBackground()
(1.f + color.mV[VGREEN]) * 0.5f,
(1.f + color.mV[VBLUE]) * 0.5f,
alpha);
LLRect content_display_rect = getVisibleDocumentRect();
for (std::vector<LLRect>::iterator rect_it = selection_rects.begin();
rect_it != selection_rects.end();

View File

@ -39,7 +39,6 @@
class LLViewerCamera;
class LLVOWLSky;
class LLVOWLClouds;
class LLSky

View File

@ -233,7 +233,7 @@ bool LLSnapshotLivePreview::setSnapshotQuality(S32 quality, bool set_by_user)
return false;
}
void LLSnapshotLivePreview::drawPreviewRect(S32 offset_x, S32 offset_y)
void LLSnapshotLivePreview::drawPreviewRect(S32 offset_x, S32 offset_y, LLColor4 alpha_color)
{
F32 line_width ;
glGetFloatv(GL_LINE_WIDTH, &line_width) ;
@ -246,7 +246,6 @@ void LLSnapshotLivePreview::drawPreviewRect(S32 offset_x, S32 offset_y)
//draw four alpha rectangles to cover areas outside of the snapshot image
if(!mKeepAspectRatio)
{
LLColor4 alpha_color(0.5f, 0.5f, 0.5f, 0.8f) ;
S32 dwl = 0, dwr = 0 ;
if(mThumbnailWidth > mPreviewRect.getWidth())
{

View File

@ -112,7 +112,7 @@ public:
BOOL setThumbnailImageSize() ;
void generateThumbnailImage(BOOL force_update = FALSE) ;
void resetThumbnailImage() { mThumbnailImage = NULL ; }
void drawPreviewRect(S32 offset_x, S32 offset_y) ;
void drawPreviewRect(S32 offset_x, S32 offset_y, LLColor4 alpha_color = LLColor4(0.5f, 0.5f, 0.5f, 0.8f));
void prepareFreezeFrame();
LLViewerTexture* getBigThumbnailImage();

View File

@ -1285,9 +1285,6 @@ bool idle_startup()
// Initialize classes w/graphics stuff.
//
LLViewerStatsRecorder::instance(); // Since textures work in threads
gTextureList.doPrefetchImages();
display_startup();
LLSurface::initClasses();
display_startup();
@ -1432,6 +1429,15 @@ bool idle_startup()
if (STATE_SEED_CAP_GRANTED == LLStartUp::getStartupState())
{
display_startup();
// These textures are not warrantied to be cached, so needs
// to hapen with caps granted
gTextureList.doPrefetchImages();
// will init images, should be done with caps, but before gSky.init()
LLEnvironment::getInstance()->initSingleton();
display_startup();
update_texture_fetch();
display_startup();
@ -2526,8 +2532,6 @@ void use_circuit_callback(void**, S32 result)
void register_viewer_callbacks(LLMessageSystem* msg)
{
msg->setHandlerFuncFast(_PREHASH_LayerData, process_layer_data );
msg->setHandlerFuncFast(_PREHASH_ImageData, LLViewerTextureList::receiveImageHeader );
msg->setHandlerFuncFast(_PREHASH_ImagePacket, LLViewerTextureList::receiveImagePacket );
msg->setHandlerFuncFast(_PREHASH_ObjectUpdate, process_object_update );
msg->setHandlerFunc("ObjectUpdateCompressed", process_compressed_object_update );
msg->setHandlerFunc("ObjectUpdateCached", process_cached_object_update );
@ -2913,6 +2917,7 @@ void reset_login()
gAgentWearables.cleanup();
gAgentCamera.cleanup();
gAgent.cleanup();
gSky.cleanup(); // mVOSkyp is an inworld object.
LLWorld::getInstance()->resetClass();
if ( gViewerWindow )

View File

@ -714,7 +714,7 @@ BOOL LLSurfacePatch::updateTexture()
{
mVObjp->dirtyGeom();
gPipeline.markGLRebuild(mVObjp);
return TRUE;
return !mSTexUpdate;
}
}
}

View File

@ -1646,6 +1646,12 @@ void LLTextureCache::purgeAllTextures(bool purge_directories)
{
gDirUtilp->deleteFilesInDir(dirname, mask);
}
#if LL_WINDOWS
// Texture cache can be large and can take a while to remove
// assure OS that processes is alive and not hanging
MSG msg;
PeekMessage(&msg, 0, 0, 0, PM_NOREMOVE | PM_NOYIELD);
#endif
}
gDirUtilp->deleteFilesInDir(mTexturesDirName, mask); // headers, fast cache
if (purge_directories)

View File

@ -282,7 +282,6 @@ static const char* e_state_name[] =
"LOAD_FROM_TEXTURE_CACHE",
"CACHE_POST",
"LOAD_FROM_NETWORK",
"LOAD_FROM_SIMULATOR",
"WAIT_HTTP_RESOURCE",
"WAIT_HTTP_RESOURCE2",
"SEND_HTTP_REQ",
@ -456,7 +455,6 @@ public:
LOAD_FROM_TEXTURE_CACHE,
CACHE_POST,
LOAD_FROM_NETWORK,
LOAD_FROM_SIMULATOR,
WAIT_HTTP_RESOURCE, // Waiting for HTTP resources
WAIT_HTTP_RESOURCE2, // Waiting for HTTP resources
SEND_HTTP_REQ, // Commit to sending as HTTP
@ -497,8 +495,6 @@ private:
// Locks: Mw
void clearPackets();
// Locks: Mw
void setupPacketData();
// Locks: Mw (ctor invokes without lock)
U32 calcWorkPriority();
@ -506,10 +502,6 @@ private:
// Locks: Mw
void removeFromCache();
// Threads: Ttf
// Locks: Mw
bool processSimulatorPackets();
// Threads: Ttf
bool writeToCacheComplete();
@ -612,8 +604,7 @@ private:
BOOL mHaveAllData;
BOOL mInLocalCache;
BOOL mInCache;
bool mCanUseHTTP,
mCanUseNET ; //can get from asset server.
bool mCanUseHTTP;
S32 mRetryAttempt;
S32 mActiveCount;
LLCore::HttpStatus mGetStatus;
@ -885,7 +876,6 @@ const char* sStateDescs[] = {
"LOAD_FROM_TEXTURE_CACHE",
"CACHE_POST",
"LOAD_FROM_NETWORK",
"LOAD_FROM_SIMULATOR",
"WAIT_HTTP_RESOURCE",
"WAIT_HTTP_RESOURCE2",
"SEND_HTTP_REQ",
@ -897,7 +887,7 @@ const char* sStateDescs[] = {
"DONE"
};
const std::set<S32> LOGGED_STATES = { LLTextureFetchWorker::LOAD_FROM_TEXTURE_CACHE, LLTextureFetchWorker::LOAD_FROM_NETWORK, LLTextureFetchWorker::LOAD_FROM_SIMULATOR,
const std::set<S32> LOGGED_STATES = { LLTextureFetchWorker::LOAD_FROM_TEXTURE_CACHE, LLTextureFetchWorker::LOAD_FROM_NETWORK,
LLTextureFetchWorker::WAIT_HTTP_REQ, LLTextureFetchWorker::DECODE_IMAGE_UPDATE, LLTextureFetchWorker::WAIT_ON_WRITE };
// static
@ -972,8 +962,6 @@ LLTextureFetchWorker::LLTextureFetchWorker(LLTextureFetch* fetcher,
mResourceWaitCount(0U),
mFetchRetryPolicy(10.0,3600.0,2.0,10)
{
mCanUseNET = mUrl.empty() ;
calcWorkPriority();
mType = host.isOk() ? LLImageBase::TYPE_AVATAR_BAKE : LLImageBase::TYPE_NORMAL;
// LL_INFOS(LOG_TXT) << "Create: " << mID << " mHost:" << host << " Discard=" << discard << LL_ENDL;
@ -1037,39 +1025,6 @@ void LLTextureFetchWorker::clearPackets()
mFirstPacket = 0;
}
// Locks: Mw
void LLTextureFetchWorker::setupPacketData()
{
S32 data_size = 0;
if (mFormattedImage.notNull())
{
data_size = mFormattedImage->getDataSize();
}
if (data_size > 0)
{
// Only used for simulator requests
mFirstPacket = (data_size - FIRST_PACKET_SIZE) / MAX_IMG_PACKET_SIZE + 1;
if (FIRST_PACKET_SIZE + (mFirstPacket-1) * MAX_IMG_PACKET_SIZE != data_size)
{
LL_WARNS(LOG_TXT) << "Bad CACHED TEXTURE size: " << data_size << " removing." << LL_ENDL;
removeFromCache();
resetFormattedData();
clearPackets();
}
else if (mFileSize > 0)
{
mLastPacket = mFirstPacket-1;
mTotalPackets = (mFileSize - FIRST_PACKET_SIZE + MAX_IMG_PACKET_SIZE-1) / MAX_IMG_PACKET_SIZE + 1;
}
else
{
// This file was cached using HTTP so we have to refetch the first packet
resetFormattedData();
clearPackets();
}
}
}
// Locks: Mw (ctor invokes without lock)
U32 LLTextureFetchWorker::calcWorkPriority()
{
@ -1177,13 +1132,13 @@ bool LLTextureFetchWorker::doWork(S32 param)
if(mImagePriority < F_ALMOST_ZERO)
{
if (mState == INIT || mState == LOAD_FROM_NETWORK || mState == LOAD_FROM_SIMULATOR)
if (mState == INIT || mState == LOAD_FROM_NETWORK)
{
LL_DEBUGS(LOG_TXT) << mID << " abort: mImagePriority < F_ALMOST_ZERO" << LL_ENDL;
return true; // abort
}
}
if(mState > CACHE_POST && !mCanUseNET && !mCanUseHTTP)
if(mState > CACHE_POST && !mCanUseHTTP)
{
//nowhere to get data, abort.
LL_WARNS(LOG_TXT) << mID << " abort, nowhere to get data" << LL_ENDL;
@ -1387,10 +1342,14 @@ bool LLTextureFetchWorker::doWork(S32 param)
if ( use_http && mCanUseHTTP && mUrl.empty())//get http url.
{
LLViewerRegion* region = NULL;
if (mHost.isInvalid())
region = gAgent.getRegion();
else
region = LLWorld::getInstance()->getRegion(mHost);
if (mHost.isInvalid())
{
region = gAgent.getRegion();
}
else if (LLWorld::instanceExists())
{
region = LLWorld::getInstance()->getRegion(mHost);
}
if (region)
{
@ -1408,14 +1367,14 @@ bool LLTextureFetchWorker::doWork(S32 param)
else
{
mCanUseHTTP = false ;
LL_DEBUGS(LOG_TXT) << "Texture not available via HTTP: empty URL." << LL_ENDL;
LL_WARNS(LOG_TXT) << "Texture not available via HTTP: empty URL." << LL_ENDL;
}
}
else
{
// This will happen if not logged in or if a region deoes not have HTTP Texture enabled
//LL_WARNS(LOG_TXT) << "Region not found for host: " << mHost << LL_ENDL;
LL_DEBUGS(LOG_TXT) << "Texture not available via HTTP: no region " << mUrl << LL_ENDL;
LL_WARNS(LOG_TXT) << "Texture not available via HTTP: no region " << mUrl << LL_ENDL;
mCanUseHTTP = false;
}
}
@ -1434,84 +1393,12 @@ bool LLTextureFetchWorker::doWork(S32 param)
}
// don't return, fall through to next state
}
else if (mSentRequest == UNSENT && mCanUseNET)
{
// Add this to the network queue and sit here.
// LLTextureFetch::update() will send off a request which will change our state
mWriteToCacheState = CAN_WRITE ;
mRequestedSize = mDesiredSize;
mRequestedDiscard = mDesiredDiscard;
mSentRequest = QUEUED;
mFetcher->addToNetworkQueue(this);
recordTextureStart(false);
setPriority(LLWorkerThread::PRIORITY_LOW | mWorkPriority);
return false;
}
else
{
// Shouldn't need to do anything here
//llassert_always(mFetcher->mNetworkQueue.find(mID) != mFetcher->mNetworkQueue.end());
// Make certain this is in the network queue
//mFetcher->addToNetworkQueue(this);
//recordTextureStart(false);
//setPriority(LLWorkerThread::PRIORITY_LOW | mWorkPriority);
return false;
}
}
if (mState == LOAD_FROM_SIMULATOR)
{
if (mFormattedImage.isNull())
{
mFormattedImage = new LLImageJ2C;
}
if (processSimulatorPackets())
{
// Capture some measure of total size for metrics
F64 byte_count = 0;
if (mLastPacket >= mFirstPacket)
{
for (S32 i=mFirstPacket; i<=mLastPacket; i++)
{
llassert_always((i>=0) && (i<mPackets.size()));
if (mPackets[i])
{
byte_count += mPackets[i]->mSize;
}
}
}
LL_DEBUGS(LOG_TXT) << mID << ": Loaded from Sim. Bytes: " << mFormattedImage->getDataSize() << LL_ENDL;
mFetcher->removeFromNetworkQueue(this, false);
if (mFormattedImage.isNull() || !mFormattedImage->getDataSize())
{
// processSimulatorPackets() failed
// LL_WARNS(LOG_TXT) << "processSimulatorPackets() failed to load buffer" << LL_ENDL;
LL_WARNS(LOG_TXT) << mID << " processSimulatorPackets() failed to load buffer" << LL_ENDL;
return true; // failed
}
setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority);
if (mLoadedDiscard < 0)
{
LL_WARNS(LOG_TXT) << mID << " mLoadedDiscard is " << mLoadedDiscard
<< ", should be >=0" << LL_ENDL;
}
setState(DECODE_IMAGE);
mWriteToCacheState = SHOULD_WRITE;
recordTextureDone(false, byte_count);
}
else
{
mFetcher->addToNetworkQueue(this); // failsafe
setPriority(LLWorkerThread::PRIORITY_LOW | mWorkPriority);
recordTextureStart(false);
}
return false;
}
if (mState == WAIT_HTTP_RESOURCE)
{
// NOTE:
@ -1553,8 +1440,6 @@ bool LLTextureFetchWorker::doWork(S32 param)
LL_WARNS(LOG_TXT) << mID << " abort: SEND_HTTP_REQ but !mCanUseHTTP" << LL_ENDL;
return true; // abort
}
mFetcher->removeFromNetworkQueue(this, false);
S32 cur_size = 0;
if (mFormattedImage.notNull())
@ -1701,17 +1586,6 @@ bool LLTextureFetchWorker::doWork(S32 param)
}
return true;
}
// roll back to try UDP
if (mCanUseNET)
{
setState(INIT);
mCanUseHTTP = false;
mUrl.clear();
setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority);
releaseHttpSemaphore();
return false;
}
}
else if (http_service_unavail == mGetStatus)
{
@ -2280,69 +2154,6 @@ void LLTextureFetchWorker::removeFromCache()
}
//////////////////////////////////////////////////////////////////////////////
// Threads: Ttf
// Locks: Mw
bool LLTextureFetchWorker::processSimulatorPackets()
{
if (mFormattedImage.isNull() || mRequestedSize < 0)
{
// not sure how we got here, but not a valid state, abort!
llassert_always(mDecodeHandle == 0);
mFormattedImage = NULL;
return true;
}
if (mLastPacket >= mFirstPacket)
{
S32 buffer_size = mFormattedImage->getDataSize();
for (S32 i = mFirstPacket; i<=mLastPacket; i++)
{
llassert_always((i>=0) && (i<mPackets.size()));
llassert_always(mPackets[i]);
buffer_size += mPackets[i]->mSize;
}
bool have_all_data = mLastPacket >= mTotalPackets-1;
if (mRequestedSize <= 0)
{
// We received a packed but haven't requested anything yet (edge case)
// Return true (we're "done") since we didn't request anything
return true;
}
if (buffer_size >= mRequestedSize || have_all_data)
{
/// We have enough (or all) data
if (have_all_data)
{
mHaveAllData = TRUE;
}
S32 cur_size = mFormattedImage->getDataSize();
if (buffer_size > cur_size)
{
/// We have new data
U8* buffer = (U8*)ll_aligned_malloc_16(buffer_size);
S32 offset = 0;
if (cur_size > 0 && mFirstPacket > 0)
{
memcpy(buffer, mFormattedImage->getData(), cur_size);
offset = cur_size;
}
for (S32 i=mFirstPacket; i<=mLastPacket; i++)
{
memcpy(buffer + offset, mPackets[i]->mData, mPackets[i]->mSize);
offset += mPackets[i]->mSize;
}
// NOTE: setData releases current data
mFormattedImage->setData(buffer, buffer_size);
}
mLoadedDiscard = mRequestedDiscard;
return true;
}
}
return false;
}
//////////////////////////////////////////////////////////////////////////////
// Threads: Ttf
@ -2813,40 +2624,6 @@ bool LLTextureFetch::createRequest(FTType f_type, const std::string& url, const
}
// Threads: T* (but Ttf in practice)
// protected
void LLTextureFetch::addToNetworkQueue(LLTextureFetchWorker* worker)
{
lockQueue(); // +Mfq
bool in_request_map = (mRequestMap.find(worker->mID) != mRequestMap.end()) ;
unlockQueue(); // -Mfq
LLMutexLock lock(&mNetworkQueueMutex); // +Mfnq
if (in_request_map)
{
// only add to the queue if in the request map
// i.e. a delete has not been requested
mNetworkQueue.insert(worker->mID);
}
for (cancel_queue_t::iterator iter1 = mCancelQueue.begin();
iter1 != mCancelQueue.end(); ++iter1)
{
iter1->second.erase(worker->mID);
}
} // -Mfnq
// Threads: T*
void LLTextureFetch::removeFromNetworkQueue(LLTextureFetchWorker* worker, bool cancel)
{
LLMutexLock lock(&mNetworkQueueMutex); // +Mfnq
size_t erased = mNetworkQueue.erase(worker->mID);
if (cancel && erased > 0)
{
mCancelQueue[worker->mHost].insert(worker->mID);
}
} // -Mfnq
// Threads: T*
//
// protected
@ -2880,7 +2657,6 @@ void LLTextureFetch::deleteRequest(const LLUUID& id, bool cancel)
unlockQueue(); // -Mfq
llassert_always(erased_1 > 0) ;
removeFromNetworkQueue(worker, cancel);
llassert_always(!(worker->getFlags(LLWorkerClass::WCF_DELETE_REQUESTED))) ;
worker->scheduleDelete();
@ -2908,7 +2684,6 @@ void LLTextureFetch::removeRequest(LLTextureFetchWorker* worker, bool cancel)
unlockQueue(); // -Mfq
llassert_always(erased_1 > 0) ;
removeFromNetworkQueue(worker, cancel);
llassert_always(!(worker->getFlags(LLWorkerClass::WCF_DELETE_REQUESTED))) ;
worker->scheduleDelete();
@ -3197,17 +2972,6 @@ S32 LLTextureFetch::update(F32 max_time_ms)
S32 res = LLWorkerThread::update(max_time_ms);
if (!mDebugPause)
{
// this is the startup state when send_complete_agent_movement() message is sent.
// Before this, the RequestImages message sent by sendRequestListToSimulators
// won't work so don't bother trying
if (LLStartUp::getStartupState() > STATE_AGENT_SEND)
{
sendRequestListToSimulators();
}
}
if (!mThreaded)
{
commonUpdate();
@ -3298,202 +3062,6 @@ void LLTextureFetch::threadedUpdate()
//////////////////////////////////////////////////////////////////////////////
// Threads: Tmain
void LLTextureFetch::sendRequestListToSimulators()
{
// All requests
const F32 REQUEST_DELTA_TIME = 0.10f; // 10 fps
// Sim requests
const S32 IMAGES_PER_REQUEST = 50;
const F32 SIM_LAZY_FLUSH_TIMEOUT = 10.0f; // temp
const F32 MIN_REQUEST_TIME = 1.0f;
const F32 MIN_DELTA_PRIORITY = 1000.f;
// Periodically, gather the list of textures that need data from the network
// And send the requests out to the simulators
static LLFrameTimer timer;
if (timer.getElapsedTimeF32() < REQUEST_DELTA_TIME)
{
return;
}
timer.reset();
// Send requests
typedef std::set<LLTextureFetchWorker*,LLTextureFetchWorker::Compare> request_list_t;
typedef std::map< LLHost, request_list_t > work_request_map_t;
work_request_map_t requests;
{
LLMutexLock lock2(&mNetworkQueueMutex); // +Mfnq
for (queue_t::iterator iter = mNetworkQueue.begin(); iter != mNetworkQueue.end(); )
{
queue_t::iterator curiter = iter++;
LLTextureFetchWorker* req = getWorker(*curiter);
if (!req)
{
mNetworkQueue.erase(curiter);
continue; // paranoia
}
if ((req->mState != LLTextureFetchWorker::LOAD_FROM_NETWORK) &&
(req->mState != LLTextureFetchWorker::LOAD_FROM_SIMULATOR))
{
// We already received our URL, remove from the queue
LL_WARNS(LOG_TXT) << "Worker: " << req->mID << " in mNetworkQueue but in wrong state: " << req->mState << LL_ENDL;
mNetworkQueue.erase(curiter);
continue;
}
if (req->mID == mDebugID)
{
mDebugCount++; // for setting breakpoints
}
if (req->mSentRequest == LLTextureFetchWorker::SENT_SIM &&
req->mTotalPackets > 0 &&
req->mLastPacket >= req->mTotalPackets-1)
{
// We have all the packets... make sure this is high priority
// req->setPriority(LLWorkerThread::PRIORITY_HIGH | req->mWorkPriority);
continue;
}
F32 elapsed = req->mRequestedDeltaTimer.getElapsedTimeF32();
{
F32 delta_priority = llabs(req->mRequestedPriority - req->mImagePriority);
if ((req->mSimRequestedDiscard != req->mDesiredDiscard) ||
(delta_priority > MIN_DELTA_PRIORITY && elapsed >= MIN_REQUEST_TIME) ||
(elapsed >= SIM_LAZY_FLUSH_TIMEOUT))
{
requests[req->mHost].insert(req);
}
}
}
} // -Mfnq
for (work_request_map_t::iterator iter1 = requests.begin();
iter1 != requests.end(); ++iter1)
{
LLHost host = iter1->first;
// invalid host = use agent host
if (host.isInvalid())
{
host = gAgent.getRegionHost();
}
S32 sim_request_count = 0;
for (request_list_t::iterator iter2 = iter1->second.begin();
iter2 != iter1->second.end(); ++iter2)
{
LLTextureFetchWorker* req = *iter2;
if (gMessageSystem)
{
if (req->mSentRequest != LLTextureFetchWorker::SENT_SIM)
{
// Initialize packet data based on data read from cache
req->lockWorkMutex(); // +Mw
req->setupPacketData();
req->unlockWorkMutex(); // -Mw
}
if (0 == sim_request_count)
{
gMessageSystem->newMessageFast(_PREHASH_RequestImage);
gMessageSystem->nextBlockFast(_PREHASH_AgentData);
gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
}
S32 packet = req->mLastPacket + 1;
gMessageSystem->nextBlockFast(_PREHASH_RequestImage);
gMessageSystem->addUUIDFast(_PREHASH_Image, req->mID);
gMessageSystem->addS8Fast(_PREHASH_DiscardLevel, (S8)req->mDesiredDiscard);
gMessageSystem->addF32Fast(_PREHASH_DownloadPriority, req->mImagePriority);
gMessageSystem->addU32Fast(_PREHASH_Packet, packet);
gMessageSystem->addU8Fast(_PREHASH_Type, req->mType);
// LL_INFOS(LOG_TXT) << "IMAGE REQUEST: " << req->mID << " Discard: " << req->mDesiredDiscard
// << " Packet: " << packet << " Priority: " << req->mImagePriority << LL_ENDL;
static LLCachedControl<bool> log_to_viewer_log(gSavedSettings,"LogTextureDownloadsToViewerLog", false);
static LLCachedControl<bool> log_to_sim(gSavedSettings,"LogTextureDownloadsToSimulator", false);
if (log_to_viewer_log || log_to_sim)
{
mTextureInfo.setRequestStartTime(req->mID, LLTimer::getTotalTime());
mTextureInfo.setRequestOffset(req->mID, 0);
mTextureInfo.setRequestSize(req->mID, 0);
mTextureInfo.setRequestType(req->mID, LLTextureInfoDetails::REQUEST_TYPE_UDP);
}
req->lockWorkMutex(); // +Mw
req->mSentRequest = LLTextureFetchWorker::SENT_SIM;
req->mSimRequestedDiscard = req->mDesiredDiscard;
req->mRequestedPriority = req->mImagePriority;
req->mRequestedDeltaTimer.reset();
req->unlockWorkMutex(); // -Mw
sim_request_count++;
if (sim_request_count >= IMAGES_PER_REQUEST)
{
// LL_INFOS(LOG_TXT) << "REQUESTING " << sim_request_count << " IMAGES FROM HOST: " << host.getIPString() << LL_ENDL;
gMessageSystem->sendSemiReliable(host, NULL, NULL);
sim_request_count = 0;
}
}
}
if (gMessageSystem && sim_request_count > 0 && sim_request_count < IMAGES_PER_REQUEST)
{
// LL_INFOS(LOG_TXT) << "REQUESTING " << sim_request_count << " IMAGES FROM HOST: " << host.getIPString() << LL_ENDL;
gMessageSystem->sendSemiReliable(host, NULL, NULL);
sim_request_count = 0;
}
}
// Send cancelations
{
LLMutexLock lock2(&mNetworkQueueMutex); // +Mfnq
if (gMessageSystem && !mCancelQueue.empty())
{
for (cancel_queue_t::iterator iter1 = mCancelQueue.begin();
iter1 != mCancelQueue.end(); ++iter1)
{
LLHost host = iter1->first;
if (host.isInvalid())
{
host = gAgent.getRegionHost();
}
S32 request_count = 0;
for (queue_t::iterator iter2 = iter1->second.begin();
iter2 != iter1->second.end(); ++iter2)
{
if (0 == request_count)
{
gMessageSystem->newMessageFast(_PREHASH_RequestImage);
gMessageSystem->nextBlockFast(_PREHASH_AgentData);
gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
}
gMessageSystem->nextBlockFast(_PREHASH_RequestImage);
gMessageSystem->addUUIDFast(_PREHASH_Image, *iter2);
gMessageSystem->addS8Fast(_PREHASH_DiscardLevel, -1);
gMessageSystem->addF32Fast(_PREHASH_DownloadPriority, 0);
gMessageSystem->addU32Fast(_PREHASH_Packet, 0);
gMessageSystem->addU8Fast(_PREHASH_Type, 0);
// LL_INFOS(LOG_TXT) << "CANCELING IMAGE REQUEST: " << (*iter2) << LL_ENDL;
request_count++;
if (request_count >= IMAGES_PER_REQUEST)
{
gMessageSystem->sendSemiReliable(host, NULL, NULL);
request_count = 0;
}
}
if (request_count > 0 && request_count < IMAGES_PER_REQUEST)
{
gMessageSystem->sendSemiReliable(host, NULL, NULL);
}
}
mCancelQueue.clear();
}
} // -Mfnq
}
//////////////////////////////////////////////////////////////////////////////
// Threads: T*
// Locks: Mw
bool LLTextureFetchWorker::insertPacket(S32 index, U8* data, S32 size)
@ -3556,138 +3124,6 @@ void LLTextureFetchWorker::setState(e_state new_state)
mState = new_state;
}
// Threads: T*
bool LLTextureFetch::receiveImageHeader(const LLHost& host, const LLUUID& id, U8 codec, U16 packets, U32 totalbytes,
U16 data_size, U8* data)
{
LLTextureFetchWorker* worker = getWorker(id);
bool res = true;
++mPacketCount;
if (!worker)
{
// LL_WARNS(LOG_TXT) << "Received header for non active worker: " << id << LL_ENDL;
res = false;
}
else if (worker->mState != LLTextureFetchWorker::LOAD_FROM_NETWORK ||
worker->mSentRequest != LLTextureFetchWorker::SENT_SIM)
{
// LL_WARNS(LOG_TXT) << "receiveImageHeader for worker: " << id
// << " in state: " << LLTextureFetchWorker::sStateDescs[worker->mState]
// << " sent: " << worker->mSentRequest << LL_ENDL;
res = false;
}
else if (worker->mLastPacket != -1)
{
// check to see if we've gotten this packet before
// LL_WARNS(LOG_TXT) << "Received duplicate header for: " << id << LL_ENDL;
res = false;
}
else if (!data_size)
{
// LL_WARNS(LOG_TXT) << "Img: " << id << ":" << " Empty Image Header" << LL_ENDL;
res = false;
}
if (!res)
{
mNetworkQueueMutex.lock(); // +Mfnq
++mBadPacketCount;
mCancelQueue[host].insert(id);
mNetworkQueueMutex.unlock(); // -Mfnq
return false;
}
LLViewerStatsRecorder::instance().textureFetch(data_size);
LLViewerStatsRecorder::instance().log(0.1f);
worker->lockWorkMutex();
// Copy header data into image object
worker->mImageCodec = codec;
worker->mTotalPackets = packets;
worker->mFileSize = (S32)totalbytes;
llassert_always(totalbytes > 0);
llassert_always(data_size == FIRST_PACKET_SIZE || data_size == worker->mFileSize);
res = worker->insertPacket(0, data, data_size);
worker->setPriority(LLWorkerThread::PRIORITY_HIGH | worker->mWorkPriority);
worker->setState(LLTextureFetchWorker::LOAD_FROM_SIMULATOR);
worker->unlockWorkMutex(); // -Mw
return res;
}
// Threads: T*
bool LLTextureFetch::receiveImagePacket(const LLHost& host, const LLUUID& id, U16 packet_num, U16 data_size, U8* data)
{
LLTextureFetchWorker* worker = getWorker(id);
bool res = true;
++mPacketCount;
if (!worker)
{
// LL_WARNS(LOG_TXT) << "Received packet " << packet_num << " for non active worker: " << id << LL_ENDL;
res = false;
}
else if (worker->mLastPacket == -1)
{
// LL_WARNS(LOG_TXT) << "Received packet " << packet_num << " before header for: " << id << LL_ENDL;
res = false;
}
else if (!data_size)
{
// LL_WARNS(LOG_TXT) << "Img: " << id << ":" << " Empty Image Header" << LL_ENDL;
res = false;
}
if (!res)
{
mNetworkQueueMutex.lock(); // +Mfnq
++mBadPacketCount;
mCancelQueue[host].insert(id);
mNetworkQueueMutex.unlock(); // -Mfnq
return false;
}
LLViewerStatsRecorder::instance().textureFetch(data_size);
LLViewerStatsRecorder::instance().log(0.1f);
worker->lockWorkMutex();
res = worker->insertPacket(packet_num, data, data_size);
if ((worker->mState == LLTextureFetchWorker::LOAD_FROM_SIMULATOR) ||
(worker->mState == LLTextureFetchWorker::LOAD_FROM_NETWORK))
{
worker->setPriority(LLWorkerThread::PRIORITY_HIGH | worker->mWorkPriority);
worker->setState(LLTextureFetchWorker::LOAD_FROM_SIMULATOR);
}
else
{
// LL_WARNS(LOG_TXT) << "receiveImagePacket " << packet_num << "/" << worker->mLastPacket << " for worker: " << id
// << " in state: " << LLTextureFetchWorker::sStateDescs[worker->mState] << LL_ENDL;
removeFromNetworkQueue(worker, true); // failsafe
}
if (packet_num >= (worker->mTotalPackets - 1))
{
static LLCachedControl<bool> log_to_viewer_log(gSavedSettings,"LogTextureDownloadsToViewerLog", false);
static LLCachedControl<bool> log_to_sim(gSavedSettings,"LogTextureDownloadsToSimulator", false);
if (log_to_viewer_log || log_to_sim)
{
U64Microseconds timeNow = LLTimer::getTotalTime();
mTextureInfoMainThread.setRequestSize(id, worker->mFileSize);
mTextureInfoMainThread.setRequestCompleteTimeAndLog(id, timeNow);
}
}
worker->unlockWorkMutex(); // -Mw
return res;
}
//////////////////////////////////////////////////////////////////////////////
// Threads: T*
@ -3726,13 +3162,7 @@ S32 LLTextureFetch::getFetchState(const LLUUID& id, F32& data_progress_p, F32& r
request_dtime = worker->mRequestedDeltaTimer.getElapsedTimeF32();
if (worker->mFileSize > 0)
{
if (state == LLTextureFetchWorker::LOAD_FROM_SIMULATOR)
{
S32 data_size = FIRST_PACKET_SIZE + (worker->mLastPacket-1) * MAX_IMG_PACKET_SIZE;
data_size = llmax(data_size, 0);
data_progress = (F32)data_size / (F32)worker->mFileSize;
}
else if (worker->mFormattedImage.notNull())
if (worker->mFormattedImage.notNull())
{
data_progress = (F32)worker->mFormattedImage->getDataSize() / (F32)worker->mFileSize;
}

View File

@ -101,12 +101,6 @@ public:
// Threads: T*
bool updateRequestPriority(const LLUUID& id, F32 priority);
// Threads: T*
bool receiveImageHeader(const LLHost& host, const LLUUID& id, U8 codec, U16 packets, U32 totalbytes, U16 data_size, U8* data);
// Threads: T*
bool receiveImagePacket(const LLHost& host, const LLUUID& id, U16 packet_num, U16 data_size, U8* data);
// Threads: T* (but not safe)
void setTextureBandwidth(F32 bandwidth) { mTextureBandwidth = bandwidth; }
@ -227,12 +221,6 @@ public:
// ----------------------------------
protected:
// Threads: T* (but Ttf in practice)
void addToNetworkQueue(LLTextureFetchWorker* worker);
// Threads: T*
void removeFromNetworkQueue(LLTextureFetchWorker* worker, bool cancel);
// Threads: T*
void addToHTTPQueue(const LLUUID& id);
@ -251,9 +239,6 @@ protected:
bool runCondition();
private:
// Threads: Tmain
void sendRequestListToSimulators();
// Threads: Ttf
/*virtual*/ void startThread(void);
@ -319,7 +304,7 @@ public:
private:
LLMutex mQueueMutex; //to protect mRequestMap and mCommands only
LLMutex mNetworkQueueMutex; //to protect mNetworkQueue, mHTTPTextureQueue and mCancelQueue.
LLMutex mNetworkQueueMutex; //to protect mHTTPTextureQueue
LLTextureCache* mTextureCache;
LLImageDecodeThread* mImageDecodeThread;
@ -330,10 +315,8 @@ private:
// Set of requests that require network data
typedef std::set<LLUUID> queue_t;
queue_t mNetworkQueue; // Mfnq
queue_t mHTTPTextureQueue; // Mfnq
typedef std::map<LLHost,std::set<LLUUID> > cancel_queue_t;
cancel_queue_t mCancelQueue; // Mfnq
F32 mTextureBandwidth; // <none>
F32 mMaxBandwidth; // Mfnq
LLTextureInfo mTextureInfo;

View File

@ -234,7 +234,6 @@ void LLTextureBar::draw()
{ "DSK", LLColor4::cyan }, // LOAD_FROM_TEXTURE_CACHE
{ "DSK", LLColor4::blue }, // CACHE_POST
{ "NET", LLColor4::green }, // LOAD_FROM_NETWORK
{ "SIM", LLColor4::green }, // LOAD_FROM_SIMULATOR
{ "HTW", LLColor4::green }, // WAIT_HTTP_RESOURCE
{ "HTW", LLColor4::green }, // WAIT_HTTP_RESOURCE2
{ "REQ", LLColor4::yellow },// SEND_HTTP_REQ

View File

@ -44,6 +44,7 @@
#include "llagent.h" // HACK for destinations guide on startup
#include "llfloaterreg.h" // HACK for destinations guide on startup
#include "llviewercontrol.h" // HACK for destinations guide on startup
#include "llinventorymodel.h" // HACK to disable starter avatars button for NUX
#include <boost/foreach.hpp>
@ -319,6 +320,22 @@ bool LLToolBarView::loadToolbars(bool force_default)
}
}
}
// SL-18581: Don't show the starter avatar toolbar button for NUX users
LLViewerInventoryCategory* my_outfits_cat = gInventory.getCategory(gInventory.findCategoryUUIDForType(LLFolderType::FT_MY_OUTFITS));
if (gAgent.isFirstLogin()
&& my_outfits_cat != NULL
&& my_outfits_cat->getDescendentCount() > 0)
{
for (S32 i = LLToolBarEnums::TOOLBAR_FIRST; i <= LLToolBarEnums::TOOLBAR_LAST; i++)
{
if (mToolbars[i])
{
mToolbars[i]->removeCommand(LLCommandId("avatar"));
}
}
}
mToolbarsLoaded = true;
return true;
}

View File

@ -868,11 +868,6 @@ void LLViewerAssetUpload::AssetInventoryUploadCoproc(LLCoreHttpUtil::HttpCorouti
{
floater_snapshot->notify(LLSD().with("set-finished", LLSD().with("ok", success).with("msg", "inventory")));
}
LLFloater* floater_outfit_snapshot = LLFloaterReg::findInstance("outfit_snapshot");
if (uploadInfo->getAssetType() == LLAssetType::AT_TEXTURE && floater_outfit_snapshot && floater_outfit_snapshot->isShown())
{
floater_outfit_snapshot->notify(LLSD().with("set-finished", LLSD().with("ok", success).with("msg", "inventory")));
}
}
//=========================================================================
@ -951,11 +946,5 @@ void LLViewerAssetUpload::HandleUploadError(LLCore::HttpStatus status, LLSD &res
floater_snapshot->notify(LLSD().with("set-finished", LLSD().with("ok", false).with("msg", "inventory")));
}
}
LLFloater* floater_outfit_snapshot = LLFloaterReg::findInstance("outfit_snapshot");
if (uploadInfo->getAssetType() == LLAssetType::AT_TEXTURE && floater_outfit_snapshot && floater_outfit_snapshot->isShown())
{
floater_outfit_snapshot->notify(LLSD().with("set-finished", LLSD().with("ok", false).with("msg", "inventory")));
}
}

View File

@ -496,7 +496,20 @@ void audio_update_listener()
if (gAudiop)
{
// update listener position because agent has moved
LLVector3d lpos_global = gAgentCamera.getCameraPositionGlobal();
static LLUICachedControl<S32> mEarLocation("MediaSoundsEarLocation", 0);
LLVector3d ear_position;
switch(mEarLocation)
{
case 0:
default:
ear_position = gAgentCamera.getCameraPositionGlobal();
break;
case 1:
ear_position = gAgent.getPositionGlobal();
break;
}
LLVector3d lpos_global = ear_position;
LLVector3 lpos_global_f;
lpos_global_f.setVec(lpos_global);

View File

@ -616,7 +616,7 @@ bool toggle_show_navigation_panel(const LLSD& newvalue)
LLNavigationBar::getInstance()->setVisible(value);
gSavedSettings.setBOOL("ShowMiniLocationPanel", !value);
gViewerWindow->reshapeStatusBarContainer();
return true;
}

View File

@ -103,7 +103,7 @@
#include "llfloaterobjectweights.h"
#include "llfloateropenobject.h"
#include "llfloateroutfitphotopreview.h"
#include "llfloateroutfitsnapshot.h"
#include "llfloatersimpleoutfitsnapshot.h"
#include "llfloaterpathfindingcharacters.h"
#include "llfloaterpathfindingconsole.h"
#include "llfloaterpathfindinglinksets.h"
@ -170,6 +170,7 @@
// *NOTE: Please add files in alphabetical order to keep merges easy.
// handle secondlife:///app/openfloater/{NAME} URLs
const std::string FLOATER_PROFILE("profile");
class LLFloaterOpenHandler : public LLCommandHandler
{
public:
@ -185,7 +186,12 @@ public:
}
const std::string floater_name = LLURI::unescape(params[0].asString());
LLFloaterReg::showInstance(floater_name);
LLSD key;
if (floater_name == FLOATER_PROFILE)
{
key["id"] = gAgentID;
}
LLFloaterReg::showInstance(floater_name, key);
return true;
}
@ -368,7 +374,7 @@ void LLViewerFloaterReg::registerFloaters()
LLFloaterReg::add("scene_load_stats", "floater_scene_load_stats.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSceneLoadStats>);
LLFloaterReg::add("stop_queue", "floater_script_queue.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterNotRunQueue>);
LLFloaterReg::add("snapshot", "floater_snapshot.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSnapshot>);
LLFloaterReg::add("outfit_snapshot", "floater_outfit_snapshot.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterOutfitSnapshot>);
LLFloaterReg::add("simple_outfit_snapshot", "floater_simple_outfit_snapshot.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSimpleOutfitSnapshot>);
LLFloaterReg::add("search", "floater_search.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSearch>);
LLFloaterReg::add("profile", "floater_profile.xml",(LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterProfile>);
LLFloaterReg::add("guidebook", "floater_how_to.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterHowTo>);

View File

@ -45,7 +45,7 @@
#include "llglheaders.h"
extern LLPipeline gPipeline;
const F32 MAX_ATTACHMENT_DIST = 3.5f; // meters?
const F32 MAX_ATTACHMENT_DIST = 3.5f; // meters
//-----------------------------------------------------------------------------
// LLViewerJointAttachment()

View File

@ -3581,7 +3581,20 @@ void LLViewerMediaImpl::calculateInterest()
LLVector3d global_delta = agent_global - obj_global ;
mProximityDistance = global_delta.magVecSquared(); // use distance-squared because it's cheaper and sorts the same.
LLVector3d camera_delta = gAgentCamera.getCameraPositionGlobal() - obj_global;
static LLUICachedControl<S32> mEarLocation("MediaSoundsEarLocation", 0);
LLVector3d ear_position;
switch(mEarLocation)
{
case 0:
default:
ear_position = gAgentCamera.getCameraPositionGlobal();
break;
case 1:
ear_position = agent_global;
break;
}
LLVector3d camera_delta = ear_position - obj_global;
mProximityCamera = camera_delta.magVec();
}
}

View File

@ -4334,6 +4334,10 @@ class LLLandSit : public view_listener_t
{
bool handleEvent(const LLSD& userdata)
{
if (gAgent.isSitting())
{
gAgent.standUp();
}
LLVector3d posGlobal = LLToolPie::getInstance()->getPick().mPosGlobal;
LLQuaternion target_rot;

View File

@ -38,7 +38,7 @@
#include "llfloatermap.h"
#include "llfloatermodelpreview.h"
#include "llfloatersnapshot.h"
#include "llfloateroutfitsnapshot.h"
#include "llfloatersimpleoutfitsnapshot.h"
#include "llimage.h"
#include "llimagebmp.h"
#include "llimagepng.h"
@ -664,7 +664,7 @@ class LLFileEnableCloseAllWindows : public view_listener_t
bool handleEvent(const LLSD& userdata)
{
LLFloaterSnapshot* floater_snapshot = LLFloaterSnapshot::findInstance();
LLFloaterOutfitSnapshot* floater_outfit_snapshot = LLFloaterOutfitSnapshot::findInstance();
LLFloaterSimpleOutfitSnapshot* floater_outfit_snapshot = LLFloaterSimpleOutfitSnapshot::findInstance();
bool is_floaters_snapshot_opened = (floater_snapshot && floater_snapshot->isInVisibleChain())
|| (floater_outfit_snapshot && floater_outfit_snapshot->isInVisibleChain());
bool open_children = gFloaterView->allChildrenClosed() && !is_floaters_snapshot_opened;
@ -681,7 +681,7 @@ class LLFileCloseAllWindows : public view_listener_t
LLFloaterSnapshot* floater_snapshot = LLFloaterSnapshot::findInstance();
if (floater_snapshot)
floater_snapshot->closeFloater(app_quitting);
LLFloaterOutfitSnapshot* floater_outfit_snapshot = LLFloaterOutfitSnapshot::findInstance();
LLFloaterSimpleOutfitSnapshot* floater_outfit_snapshot = LLFloaterSimpleOutfitSnapshot::findInstance();
if (floater_outfit_snapshot)
floater_outfit_snapshot->closeFloater(app_quitting);
if (gMenuHolder) gMenuHolder->hideMenus();

View File

@ -316,7 +316,8 @@ LLViewerObject::LLViewerObject(const LLUUID &id, const LLPCode pcode, LLViewerRe
mLastUpdateType(OUT_UNKNOWN),
mLastUpdateCached(FALSE),
mCachedMuteListUpdateTime(0),
mCachedOwnerInMuteList(false)
mCachedOwnerInMuteList(false),
mRiggedAttachedWarned(false)
{
if (!is_global)
{

View File

@ -702,6 +702,8 @@ public:
// Replace textures with web pages on this object while drawing
BOOL mRenderMedia;
bool mRiggedAttachedWarned;
// In bits
S32 mBestUpdatePrecision;

View File

@ -1974,7 +1974,7 @@ void LLViewerParcelMgr::optionallyStartMusic(const std::string &music_url, const
static LLCachedControl<bool> tentative_autoplay(gSavedSettings, "MediaTentativeAutoPlay", true);
// only play music when you enter a new parcel if the UI control for this
// was not *explicitly* stopped by the user. (part of SL-4878)
LLPanelNearByMedia* nearby_media_panel = gStatusBar->getNearbyMediaPanel();
LLPanelNearByMedia* nearby_media_panel = gStatusBar ? gStatusBar->getNearbyMediaPanel() : NULL;
LLViewerAudio* viewer_audio = LLViewerAudio::getInstance();
// ask mode //todo constants

View File

@ -45,11 +45,13 @@
#include "llxmltree.h"
#include "message.h"
#include "lldrawpoolbump.h" // to init bumpmap images
#include "lltexturecache.h"
#include "lltexturefetch.h"
#include "llviewercontrol.h"
#include "llviewertexture.h"
#include "llviewermedia.h"
#include "llviewernetwork.h"
#include "llviewerregion.h"
#include "llviewerstats.h"
#include "pipeline.h"
@ -139,9 +141,6 @@ void LLViewerTextureList::doPreloadImages()
//uv_test->setClamp(FALSE, FALSE);
//uv_test->setMipFilterNearest(TRUE, TRUE);
// prefetch specific UUIDs
LLViewerTextureManager::getFetchedTexture(IMG_SHOT);
LLViewerTextureManager::getFetchedTexture(IMG_SMOKE_POOF);
LLViewerFetchedTexture* image = LLViewerTextureManager::getFetchedTextureFromFile("silhouette.j2c", FTT_LOCAL_FILE, MIPMAP_YES, LLViewerFetchedTexture::BOOST_UI);
if (image)
{
@ -160,12 +159,6 @@ void LLViewerTextureList::doPreloadImages()
image->setAddressMode(LLTexUnit::TAM_WRAP);
mImagePreloads.insert(image);
}
image = LLViewerTextureManager::getFetchedTexture(DEFAULT_WATER_NORMAL, FTT_DEFAULT, MIPMAP_YES, LLViewerFetchedTexture::BOOST_UI);
if (image)
{
image->setAddressMode(LLTexUnit::TAM_WRAP);
mImagePreloads.insert(image);
}
image = LLViewerTextureManager::getFetchedTextureFromFile("transparent.j2c", FTT_LOCAL_FILE, MIPMAP_YES, LLViewerFetchedTexture::BOOST_UI, LLViewerTexture::FETCHED_TEXTURE,
0, 0, IMG_TRANSPARENT);
if (image)
@ -198,7 +191,18 @@ void LLViewerTextureList::doPreloadImages()
static std::string get_texture_list_name()
{
return gDirUtilp->getExpandedFilename(LL_PATH_CACHE, "texture_list_" + gSavedSettings.getString("LoginLocation") + "." + gDirUtilp->getUserName() + ".xml");
if (LLGridManager::getInstance()->isInProductionGrid())
{
return gDirUtilp->getExpandedFilename(LL_PATH_CACHE,
"texture_list_" + gSavedSettings.getString("LoginLocation") + "." + gDirUtilp->getUserName() + ".xml");
}
else
{
const std::string& grid_id_str = LLGridManager::getInstance()->getGridId();
const std::string& grid_id_lower = utf8str_tolower(grid_id_str);
return gDirUtilp->getExpandedFilename(LL_PATH_CACHE,
"texture_list_" + gSavedSettings.getString("LoginLocation") + "." + gDirUtilp->getUserName() + "." + grid_id_lower + ".xml");
}
}
void LLViewerTextureList::doPrefetchImages()
@ -207,6 +211,26 @@ void LLViewerTextureList::doPrefetchImages()
gTextureTimer.start();
gTextureTimer.pause();
// todo: do not load without getViewerAssetUrl()
// either fail login without caps or provide this
// in some other way, textures won't load otherwise
LLViewerFetchedTexture *imagep = findImage(DEFAULT_WATER_NORMAL, TEX_LIST_STANDARD);
if (!imagep)
{
// add it to mImagePreloads only once
imagep = LLViewerTextureManager::getFetchedTexture(DEFAULT_WATER_NORMAL, FTT_DEFAULT, MIPMAP_YES, LLViewerFetchedTexture::BOOST_UI);
if (imagep)
{
imagep->setAddressMode(LLTexUnit::TAM_WRAP);
mImagePreloads.insert(imagep);
}
}
LLViewerTextureManager::getFetchedTexture(IMG_SHOT);
LLViewerTextureManager::getFetchedTexture(IMG_SMOKE_POOF);
LLStandardBumpmap::addstandard();
if (LLAppViewer::instance()->getPurgeCache())
{
// cache was purged, no point
@ -1501,152 +1525,6 @@ void LLViewerTextureList::updateMaxResidentTexMem(S32Megabytes mem)
///////////////////////////////////////////////////////////////////////////////
// static
void LLViewerTextureList::receiveImageHeader(LLMessageSystem *msg, void **user_data)
{
static LLCachedControl<bool> log_texture_traffic(gSavedSettings,"LogTextureNetworkTraffic", false) ;
LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
// Receive image header, copy into image object and decompresses
// if this is a one-packet image.
LLUUID id;
char ip_string[256];
u32_to_ip_string(msg->getSenderIP(),ip_string);
U32Bytes received_size ;
if (msg->getReceiveCompressedSize())
{
received_size = (U32Bytes)msg->getReceiveCompressedSize() ;
}
else
{
received_size = (U32Bytes)msg->getReceiveSize() ;
}
add(LLStatViewer::TEXTURE_NETWORK_DATA_RECEIVED, received_size);
add(LLStatViewer::TEXTURE_PACKETS, 1);
U8 codec;
U16 packets;
U32 totalbytes;
msg->getUUIDFast(_PREHASH_ImageID, _PREHASH_ID, id);
msg->getU8Fast(_PREHASH_ImageID, _PREHASH_Codec, codec);
msg->getU16Fast(_PREHASH_ImageID, _PREHASH_Packets, packets);
msg->getU32Fast(_PREHASH_ImageID, _PREHASH_Size, totalbytes);
S32 data_size = msg->getSizeFast(_PREHASH_ImageData, _PREHASH_Data);
if (!data_size)
{
return;
}
if (data_size < 0)
{
// msg->getSizeFast() is probably trying to tell us there
// was an error.
LL_ERRS() << "image header chunk size was negative: "
<< data_size << LL_ENDL;
return;
}
// this buffer gets saved off in the packet list
U8 *data = new U8[data_size];
msg->getBinaryDataFast(_PREHASH_ImageData, _PREHASH_Data, data, data_size);
LLViewerFetchedTexture *image = LLViewerTextureManager::getFetchedTexture(id, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE);
if (!image)
{
delete [] data;
return;
}
if(log_texture_traffic)
{
gTotalTextureBytesPerBoostLevel[image->getBoostLevel()] += received_size ;
}
//image->getLastPacketTimer()->reset();
bool res = LLAppViewer::getTextureFetch()->receiveImageHeader(msg->getSender(), id, codec, packets, totalbytes, data_size, data);
if (!res)
{
delete[] data;
}
}
// static
void LLViewerTextureList::receiveImagePacket(LLMessageSystem *msg, void **user_data)
{
static LLCachedControl<bool> log_texture_traffic(gSavedSettings,"LogTextureNetworkTraffic", false) ;
LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
// Receives image packet, copy into image object,
// checks if all packets received, decompresses if so.
LLUUID id;
U16 packet_num;
char ip_string[256];
u32_to_ip_string(msg->getSenderIP(),ip_string);
U32Bytes received_size ;
if (msg->getReceiveCompressedSize())
{
received_size = (U32Bytes)msg->getReceiveCompressedSize() ;
}
else
{
received_size = (U32Bytes)msg->getReceiveSize() ;
}
add(LLStatViewer::TEXTURE_NETWORK_DATA_RECEIVED, F64Bytes(received_size));
add(LLStatViewer::TEXTURE_PACKETS, 1);
//llprintline("Start decode, image header...");
msg->getUUIDFast(_PREHASH_ImageID, _PREHASH_ID, id);
msg->getU16Fast(_PREHASH_ImageID, _PREHASH_Packet, packet_num);
S32 data_size = msg->getSizeFast(_PREHASH_ImageData, _PREHASH_Data);
if (!data_size)
{
return;
}
if (data_size < 0)
{
// msg->getSizeFast() is probably trying to tell us there
// was an error.
LL_ERRS() << "image data chunk size was negative: "
<< data_size << LL_ENDL;
return;
}
if (data_size > MTUBYTES)
{
LL_ERRS() << "image data chunk too large: " << data_size << " bytes" << LL_ENDL;
return;
}
U8 *data = new U8[data_size];
msg->getBinaryDataFast(_PREHASH_ImageData, _PREHASH_Data, data, data_size);
LLViewerFetchedTexture *image = LLViewerTextureManager::getFetchedTexture(id, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE);
if (!image)
{
delete [] data;
return;
}
if(log_texture_traffic)
{
gTotalTextureBytesPerBoostLevel[image->getBoostLevel()] += received_size ;
}
//image->getLastPacketTimer()->reset();
bool res = LLAppViewer::getTextureFetch()->receiveImagePacket(msg->getSender(), id, packet_num, data_size, data);
if (!res)
{
delete[] data;
}
}
// We've been that the asset server does not contain the requested image id.
// static
void LLViewerTextureList::processImageNotInDatabase(LLMessageSystem *msg,void **user_data)

View File

@ -98,8 +98,6 @@ public:
const S32 max_image_dimentions = LLViewerFetchedTexture::MAX_IMAGE_SIZE_DEFAULT);
static LLPointer<LLImageJ2C> convertToUploadFile(LLPointer<LLImageRaw> raw_image, const S32 max_image_dimentions = LLViewerFetchedTexture::MAX_IMAGE_SIZE_DEFAULT);
static void processImageNotInDatabase( LLMessageSystem *msg, void **user_data );
static void receiveImageHeader(LLMessageSystem *msg, void **user_data);
static void receiveImagePacket(LLMessageSystem *msg, void **user_data);
public:
LLViewerTextureList();
@ -133,7 +131,9 @@ public:
void updateMaxResidentTexMem(S32Megabytes mem);
// Local UI images
void doPreloadImages();
// Network images. Needs caps and cache to work
void doPrefetchImages();
void clearFetchingRequests();

View File

@ -262,6 +262,8 @@ static const F32 MIN_UI_SCALE = 0.75f;
static const F32 MAX_UI_SCALE = 7.0f;
static const F32 MIN_DISPLAY_SCALE = 0.75f;
static const char KEY_MOUSELOOK = 'M';
static LLCachedControl<std::string> sSnapshotBaseName(LLCachedControl<std::string>(gSavedPerAccountSettings, "SnapshotBaseName", "Snapshot"));
static LLCachedControl<std::string> sSnapshotDir(LLCachedControl<std::string>(gSavedPerAccountSettings, "SnapshotBaseDir", ""));
@ -2232,31 +2234,36 @@ void LLViewerWindow::initWorldUI()
// Force gFloaterTools to initialize
LLFloaterReg::getInstance("build");
// Status bar
LLPanel* status_bar_container = getRootView()->getChild<LLPanel>("status_bar_container");
gStatusBar = new LLStatusBar(status_bar_container->getLocalRect());
gStatusBar->setFollowsAll();
gStatusBar->setFollows(FOLLOWS_LEFT | FOLLOWS_TOP | FOLLOWS_RIGHT);
gStatusBar->setShape(status_bar_container->getLocalRect());
// sync bg color with menu bar
gStatusBar->setBackgroundColor( gMenuBarView->getBackgroundColor().get() );
// add InBack so that gStatusBar won't be drawn over menu
status_bar_container->addChildInBack(gStatusBar);
status_bar_container->setVisible(TRUE);
status_bar_container->addChildInBack(gStatusBar, 2/*tab order, after menu*/);
status_bar_container->setVisible(TRUE);
// Navigation bar
LLPanel* nav_bar_container = getRootView()->getChild<LLPanel>("nav_bar_container");
LLView* nav_bar_container = getRootView()->getChild<LLView>("nav_bar_container");
LLNavigationBar* navbar = LLNavigationBar::getInstance();
navbar->setShape(nav_bar_container->getLocalRect());
navbar->setBackgroundColor(gMenuBarView->getBackgroundColor().get());
nav_bar_container->addChild(navbar);
nav_bar_container->setVisible(TRUE);
if (!gSavedSettings.getBOOL("ShowNavbarNavigationPanel"))
{
navbar->setVisible(FALSE);
}
else
{
reshapeStatusBarContainer();
}
// Top Info bar
LLPanel* topinfo_bar_container = getRootView()->getChild<LLPanel>("topinfo_bar_container");
@ -2883,6 +2890,13 @@ BOOL LLViewerWindow::handleKey(KEY key, MASK mask)
if (keyboard_focus
&& !gFocusMgr.getKeystrokesOnly())
{
//Most things should fall through, but mouselook is an exception,
//don't switch to mouselook if any floater has focus
if ((key == KEY_MOUSELOOK) && !(mask & (MASK_CONTROL | MASK_ALT)))
{
return TRUE;
}
LLUICtrl* cur_focus = dynamic_cast<LLUICtrl*>(keyboard_focus);
if (cur_focus && cur_focus->acceptsTextInput())
{
@ -5842,6 +5856,27 @@ LLRect LLViewerWindow::getChatConsoleRect()
return console_rect;
}
void LLViewerWindow::reshapeStatusBarContainer()
{
LLPanel* status_bar_container = getRootView()->getChild<LLPanel>("status_bar_container");
LLView* nav_bar_container = getRootView()->getChild<LLView>("nav_bar_container");
S32 new_height = status_bar_container->getRect().getHeight();
S32 new_width = status_bar_container->getRect().getWidth();
if (gSavedSettings.getBOOL("ShowNavbarNavigationPanel"))
{
// Navigation bar is outside visible area, expand status_bar_container to show it
new_height += nav_bar_container->getRect().getHeight();
}
else
{
// collapse status_bar_container
new_height -= nav_bar_container->getRect().getHeight();
}
status_bar_container->reshape(new_width, new_height, TRUE);
}
//----------------------------------------------------------------------------

View File

@ -177,6 +177,8 @@ public:
bool getUIVisibility();
void handlePieMenu(S32 x, S32 y, MASK mask);
void reshapeStatusBarContainer();
BOOL handleAnyMouseClick(LLWindow *window, LLCoordGL pos, MASK mask, EMouseClickType clicktype, BOOL down);
//

View File

@ -287,6 +287,12 @@ BOOL LLVLComposition::generateTexture(const F32 x, const F32 y,
BOOL delete_raw = (mDetailTextures[i]->reloadRawImage(ddiscard) != NULL) ;
if(mDetailTextures[i]->getRawImageLevel() != ddiscard)//raw iamge is not ready, will enter here again later.
{
if (mDetailTextures[i]->getDecodePriority() <= 0.0f && !mDetailTextures[i]->hasSavedRawImage())
{
mDetailTextures[i]->setBoostLevel(LLGLTexture::BOOST_MAP);
mDetailTextures[i]->forceToRefetchTexture(ddiscard);
}
if(delete_raw)
{
mDetailTextures[i]->destroyRawImage() ;

Some files were not shown because too many files have changed in this diff Show More