summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--indra/llcommon/CMakeLists.txt1
-rw-r--r--indra/llcommon/llapr.cpp4
-rw-r--r--indra/llcommon/llthreadlocalstorage.cpp115
-rw-r--r--indra/llcommon/llthreadlocalstorage.h98
-rw-r--r--indra/llcommon/lltrace.cpp2
-rw-r--r--indra/llcommon/lltraceaccumulators.cpp2
-rw-r--r--indra/llcommon/lltracerecording.cpp14
-rw-r--r--indra/llcommon/lltracethreadrecorder.cpp6
-rw-r--r--indra/llcommon/lltracethreadrecorder.h3
-rw-r--r--indra/llmath/llvolume.cpp22
-rw-r--r--indra/llmessage/message_prehash.cpp3
-rw-r--r--indra/llmessage/message_prehash.h2
-rw-r--r--indra/llprimitive/lldaeloader.cpp5
-rw-r--r--indra/llprimitive/llmodel.h2
-rw-r--r--indra/llrender/llimagegl.cpp2
-rw-r--r--indra/llrender/llrender.cpp77
-rw-r--r--indra/llrender/llrender.h4
-rw-r--r--indra/llrender/llvertexbuffer.cpp2
-rw-r--r--indra/llrender/llvertexbuffer.h1
-rw-r--r--indra/llui/llchat.h3
-rw-r--r--indra/llui/llcheckboxctrl.cpp6
-rw-r--r--indra/llui/llfolderviewmodel.h2
-rw-r--r--indra/llui/llscrolllistctrl.cpp39
-rw-r--r--indra/llui/llscrolllistctrl.h2
-rw-r--r--indra/llui/llspinctrl.cpp7
-rw-r--r--indra/llui/lltextbase.cpp197
-rw-r--r--indra/llui/lltextbase.h2
-rw-r--r--indra/llwindow/llwindowwin32.cpp52
-rw-r--r--indra/newview/CMakeLists.txt4
-rw-r--r--indra/newview/app_settings/settings.xml11
-rw-r--r--indra/newview/llappviewer.cpp4
-rw-r--r--indra/newview/llaudiosourcevo.cpp5
-rw-r--r--indra/newview/llchathistory.cpp7
-rw-r--r--indra/newview/llconversationmodel.h2
-rw-r--r--indra/newview/llfloaterimsession.cpp5
-rw-r--r--indra/newview/llfloateroutfitsnapshot.cpp372
-rw-r--r--indra/newview/llfloateroutfitsnapshot.h123
-rw-r--r--indra/newview/llfloaterpreference.cpp49
-rw-r--r--indra/newview/llfloaterpreference.h6
-rw-r--r--indra/newview/llfloatersimpleoutfitsnapshot.cpp333
-rw-r--r--indra/newview/llfloatersimpleoutfitsnapshot.h129
-rw-r--r--indra/newview/llfloatersnapshot.cpp12
-rw-r--r--indra/newview/llfloatersnapshot.h9
-rw-r--r--indra/newview/llimprocessing.cpp21
-rw-r--r--indra/newview/llimview.cpp24
-rw-r--r--indra/newview/llimview.h10
-rw-r--r--indra/newview/llinventorybridge.cpp72
-rw-r--r--indra/newview/llinventorybridge.h6
-rw-r--r--indra/newview/llinventorymodel.cpp3
-rw-r--r--indra/newview/llmarketplacefunctions.cpp134
-rw-r--r--indra/newview/llmarketplacefunctions.h1
-rw-r--r--indra/newview/lloutfitgallery.cpp6
-rw-r--r--indra/newview/llpanelobjectinventory.cpp6
-rw-r--r--indra/newview/llpanelpresetscamerapulldown.cpp5
-rw-r--r--indra/newview/llpanelpresetspulldown.cpp3
-rw-r--r--indra/newview/llpanelpulldown.cpp2
-rw-r--r--indra/newview/llscripteditor.cpp79
-rw-r--r--indra/newview/llsky.h1
-rw-r--r--indra/newview/llsnapshotlivepreview.cpp3
-rw-r--r--indra/newview/llsnapshotlivepreview.h2
-rw-r--r--indra/newview/llstartup.cpp2
-rw-r--r--indra/newview/lltexturecache.cpp6
-rw-r--r--indra/newview/lltexturefetch.cpp588
-rw-r--r--indra/newview/lltexturefetch.h19
-rw-r--r--indra/newview/lltextureview.cpp1
-rw-r--r--indra/newview/llviewerassetupload.cpp11
-rw-r--r--indra/newview/llvieweraudio.cpp15
-rw-r--r--indra/newview/llviewerfloaterreg.cpp4
-rw-r--r--indra/newview/llviewermedia.cpp15
-rw-r--r--indra/newview/llviewermenu.cpp4
-rw-r--r--indra/newview/llviewermenufile.cpp6
-rw-r--r--indra/newview/llviewerobject.cpp3
-rw-r--r--indra/newview/llviewerobject.h2
-rw-r--r--indra/newview/llviewerparcelmgr.cpp2
-rw-r--r--indra/newview/llviewertexturelist.cpp146
-rw-r--r--indra/newview/llviewertexturelist.h2
-rw-r--r--indra/newview/llviewerwindow.cpp26
-rw-r--r--indra/newview/llvoavatar.cpp20
-rw-r--r--indra/newview/llvoavatar.h2
-rw-r--r--indra/newview/llvoground.h1
-rw-r--r--indra/newview/llvoicevivox.cpp6
-rw-r--r--indra/newview/llvovolume.cpp4
-rw-r--r--indra/newview/llworld.cpp38
-rw-r--r--indra/newview/llworld.h13
-rw-r--r--indra/newview/pipeline.cpp67
-rw-r--r--indra/newview/pipeline.h2
-rw-r--r--indra/newview/skins/default/colors.xml6
-rw-r--r--indra/newview/skins/default/xui/en/floater_how_to.xml1
-rw-r--r--indra/newview/skins/default/xui/en/floater_outfit_snapshot.xml351
-rw-r--r--indra/newview/skins/default/xui/en/floater_simple_outfit_snapshot.xml50
-rw-r--r--indra/newview/skins/default/xui/en/main_view.xml33
-rw-r--r--indra/newview/skins/default/xui/en/notifications.xml18
-rw-r--r--indra/newview/skins/default/xui/en/panel_preferences_sound.xml275
-rw-r--r--indra/newview/skins/default/xui/en/strings.xml4
94 files changed, 1468 insertions, 2399 deletions
diff --git a/indra/llcommon/CMakeLists.txt b/indra/llcommon/CMakeLists.txt
index 59aa731af2..dcef3ec59f 100644
--- a/indra/llcommon/CMakeLists.txt
+++ b/indra/llcommon/CMakeLists.txt
@@ -108,7 +108,6 @@ set(llcommon_SOURCE_FILES
llsys.cpp
lltempredirect.cpp
llthread.cpp
- llthreadlocalstorage.cpp
llthreadsafequeue.cpp
lltimer.cpp
lltrace.cpp
diff --git a/indra/llcommon/llapr.cpp b/indra/llcommon/llapr.cpp
index db94765871..435531f86f 100644
--- a/indra/llcommon/llapr.cpp
+++ b/indra/llcommon/llapr.cpp
@@ -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);
diff --git a/indra/llcommon/llthreadlocalstorage.cpp b/indra/llcommon/llthreadlocalstorage.cpp
deleted file mode 100644
index d8a063e8d5..0000000000
--- a/indra/llcommon/llthreadlocalstorage.cpp
+++ /dev/null
@@ -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;
- }
-}
diff --git a/indra/llcommon/llthreadlocalstorage.h b/indra/llcommon/llthreadlocalstorage.h
index 3b5786023f..bdd28ec865 100644
--- a/indra/llcommon/llthreadlocalstorage.h
+++ b/indra/llcommon/llthreadlocalstorage.h
@@ -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
diff --git a/indra/llcommon/lltrace.cpp b/indra/llcommon/lltrace.cpp
index f59b207ded..acdda5fe1e 100644
--- a/indra/llcommon/lltrace.cpp
+++ b/indra/llcommon/lltrace.cpp
@@ -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;
}
diff --git a/indra/llcommon/lltraceaccumulators.cpp b/indra/llcommon/lltraceaccumulators.cpp
index 34299f5a29..fe447d5319 100644
--- a/indra/llcommon/lltraceaccumulators.cpp
+++ b/indra/llcommon/lltraceaccumulators.cpp
@@ -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++)
diff --git a/indra/llcommon/lltracerecording.cpp b/indra/llcommon/lltracerecording.cpp
index 1613af1dcf..8cbb0db135 100644
--- a/indra/llcommon/lltracerecording.cpp
+++ b/indra/llcommon/lltracerecording.cpp
@@ -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;
}
}
diff --git a/indra/llcommon/lltracethreadrecorder.cpp b/indra/llcommon/lltracethreadrecorder.cpp
index 090d3297a0..26db15eaa0 100644
--- a/indra/llcommon/lltracethreadrecorder.cpp
+++ b/indra/llcommon/lltracethreadrecorder.cpp
@@ -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();
}
diff --git a/indra/llcommon/lltracethreadrecorder.h b/indra/llcommon/lltracethreadrecorder.h
index a797c6687e..8fd1e5ef58 100644
--- a/indra/llcommon/lltracethreadrecorder.h
+++ b/indra/llcommon/lltracethreadrecorder.h
@@ -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*);
diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp
index 4a069b0f63..bb193fc7a5 100644
--- a/indra/llmath/llvolume.cpp
+++ b/indra/llmath/llvolume.cpp
@@ -5012,6 +5012,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);
@@ -5384,6 +5395,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]);
diff --git a/indra/llmessage/message_prehash.cpp b/indra/llmessage/message_prehash.cpp
index 219b1855d2..c7fdb58a98 100644
--- a/indra/llmessage/message_prehash.cpp
+++ b/indra/llmessage/message_prehash.cpp
@@ -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");
diff --git a/indra/llmessage/message_prehash.h b/indra/llmessage/message_prehash.h
index 8f6ee5a327..706ec475d9 100644
--- a/indra/llmessage/message_prehash.h
+++ b/indra/llmessage/message_prehash.h
@@ -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;
diff --git a/indra/llprimitive/lldaeloader.cpp b/indra/llprimitive/lldaeloader.cpp
index 68654486a4..752a850d42 100644
--- a/indra/llprimitive/lldaeloader.cpp
+++ b/indra/llprimitive/lldaeloader.cpp
@@ -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();
}
}
diff --git a/indra/llprimitive/llmodel.h b/indra/llprimitive/llmodel.h
index 354ceb26b7..9a3a8b66a9 100644
--- a/indra/llprimitive/llmodel.h
+++ b/indra/llprimitive/llmodel.h
@@ -56,6 +56,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);
diff --git a/indra/llrender/llimagegl.cpp b/indra/llrender/llimagegl.cpp
index 9bd3a0a6b0..46f0095c92 100644
--- a/indra/llrender/llimagegl.cpp
+++ b/indra/llrender/llimagegl.cpp
@@ -2432,7 +2432,7 @@ void LLImageGLThread::run()
// We must perform setup on this thread before actually servicing our
// WorkQueue, likewise cleanup afterwards.
mWindow->makeContextCurrent(mContext);
- gGL.init();
+ gGL.init(false);
ThreadPool::run();
gGL.shutdown();
mWindow->destroySharedContext(mContext);
diff --git a/indra/llrender/llrender.cpp b/indra/llrender/llrender.cpp
index a03a27cf94..72cca1f2a2 100644
--- a/indra/llrender/llrender.cpp
+++ b/indra/llrender/llrender.cpp
@@ -869,7 +869,7 @@ LLRender::~LLRender()
shutdown();
}
-void LLRender::init()
+void LLRender::init(bool needs_vertex_buffer)
{
#if LL_WINDOWS
if (gGLManager.mHasDebugOutput && gDebugGL)
@@ -897,15 +897,27 @@ void LLRender::init()
#endif
}
+ if (needs_vertex_buffer)
+ {
+ initVertexBuffer();
+ }
+}
- llassert_always(mBuffer.isNull()) ;
- stop_glerror();
- mBuffer = new LLVertexBuffer(immediate_mask, 0);
- mBuffer->allocateBuffer(4096, 0, TRUE);
- mBuffer->getVertexStrider(mVerticesp);
- mBuffer->getTexCoord0Strider(mTexcoordsp);
- mBuffer->getColorStrider(mColorsp);
- stop_glerror();
+void LLRender::initVertexBuffer()
+{
+ llassert_always(mBuffer.isNull());
+ stop_glerror();
+ mBuffer = new LLVertexBuffer(immediate_mask, 0);
+ mBuffer->allocateBuffer(4096, 0, TRUE);
+ mBuffer->getVertexStrider(mVerticesp);
+ mBuffer->getTexCoord0Strider(mTexcoordsp);
+ mBuffer->getColorStrider(mColorsp);
+ stop_glerror();
+}
+
+void LLRender::resetVertexBuffer()
+{
+ mBuffer = NULL;
}
void LLRender::shutdown()
@@ -923,7 +935,7 @@ void LLRender::shutdown()
delete mLightState[i];
}
mLightState.clear();
- mBuffer = NULL ;
+ resetVertexBuffer();
}
void LLRender::refreshState(void)
@@ -1625,25 +1637,34 @@ void LLRender::flush()
mCount = 0;
- if (mBuffer->useVBOs() && !mBuffer->isLocked())
- { //hack to only flush the part of the buffer that was updated (relies on stream draw using buffersubdata)
- mBuffer->getVertexStrider(mVerticesp, 0, count);
- mBuffer->getTexCoord0Strider(mTexcoordsp, 0, count);
- mBuffer->getColorStrider(mColorsp, 0, count);
- }
-
- mBuffer->flush();
- mBuffer->setBuffer(immediate_mask);
+ if (mBuffer)
+ {
+ if (mBuffer->useVBOs() && !mBuffer->isLocked())
+ { //hack to only flush the part of the buffer that was updated (relies on stream draw using buffersubdata)
+ mBuffer->getVertexStrider(mVerticesp, 0, count);
+ mBuffer->getTexCoord0Strider(mTexcoordsp, 0, count);
+ mBuffer->getColorStrider(mColorsp, 0, count);
+ }
+
+ mBuffer->flush();
+ mBuffer->setBuffer(immediate_mask);
+
+ if (mMode == LLRender::QUADS && sGLCoreProfile)
+ {
+ mBuffer->drawArrays(LLRender::TRIANGLES, 0, count);
+ mQuadCycle = 1;
+ }
+ else
+ {
+ mBuffer->drawArrays(mMode, 0, count);
+ }
+ }
+ else
+ {
+ // mBuffer is present in main thread and not present in an image thread
+ LL_ERRS() << "A flush call from outside main rendering thread" << LL_ENDL;
+ }
- if (mMode == LLRender::QUADS && sGLCoreProfile)
- {
- mBuffer->drawArrays(LLRender::TRIANGLES, 0, count);
- mQuadCycle = 1;
- }
- else
- {
- mBuffer->drawArrays(mMode, 0, count);
- }
mVerticesp[0] = mVerticesp[count];
mTexcoordsp[0] = mTexcoordsp[count];
diff --git a/indra/llrender/llrender.h b/indra/llrender/llrender.h
index e2489876e4..9c36c230fb 100644
--- a/indra/llrender/llrender.h
+++ b/indra/llrender/llrender.h
@@ -354,7 +354,9 @@ public:
LLRender();
~LLRender();
- void init() ;
+ void init(bool needs_vertex_buffer);
+ void initVertexBuffer();
+ void resetVertexBuffer();
void shutdown();
// Refreshes renderer state to the cached values
diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp
index 6338cab96a..be3e6ddff0 100644
--- a/indra/llrender/llvertexbuffer.cpp
+++ b/indra/llrender/llvertexbuffer.cpp
@@ -1055,7 +1055,7 @@ void LLVertexBuffer::releaseIndices()
bool LLVertexBuffer::createGLBuffer(U32 size)
{
- if (mGLBuffer)
+ if (mGLBuffer || mMappedData)
{
destroyGLBuffer();
}
diff --git a/indra/llrender/llvertexbuffer.h b/indra/llrender/llvertexbuffer.h
index baf8407fc6..3b3fe44984 100644
--- a/indra/llrender/llvertexbuffer.h
+++ b/indra/llrender/llvertexbuffer.h
@@ -265,7 +265,6 @@ public:
bool getTangentStrider(LLStrider<LLVector3>& strider, S32 index=0, S32 count = -1, bool map_range = false);
bool getTangentStrider(LLStrider<LLVector4a>& strider, S32 index=0, S32 count = -1, bool map_range = false);
bool getColorStrider(LLStrider<LLColor4U>& strider, S32 index=0, S32 count = -1, bool map_range = false);
- bool getTextureIndexStrider(LLStrider<LLColor4U>& strider, S32 index=0, S32 count = -1, bool map_range = false);
bool getEmissiveStrider(LLStrider<LLColor4U>& strider, S32 index=0, S32 count = -1, bool map_range = false);
bool getWeightStrider(LLStrider<F32>& strider, S32 index=0, S32 count = -1, bool map_range = false);
bool getWeight4Strider(LLStrider<LLVector4>& strider, S32 index=0, S32 count = -1, bool map_range = false);
diff --git a/indra/llui/llchat.h b/indra/llui/llchat.h
index c39e44200c..b4fd5f60aa 100644
--- a/indra/llui/llchat.h
+++ b/indra/llui/llchat.h
@@ -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
diff --git a/indra/llui/llcheckboxctrl.cpp b/indra/llui/llcheckboxctrl.cpp
index 08da599ef2..362fe0c19e 100644
--- a/indra/llui/llcheckboxctrl.cpp
+++ b/indra/llui/llcheckboxctrl.cpp
@@ -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);
diff --git a/indra/llui/llfolderviewmodel.h b/indra/llui/llfolderviewmodel.h
index 093e213be3..618169a8fe 100644
--- a/indra/llui/llfolderviewmodel.h
+++ b/indra/llui/llfolderviewmodel.h
@@ -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; };
diff --git a/indra/llui/llscrolllistctrl.cpp b/indra/llui/llscrolllistctrl.cpp
index 11b0eb9f80..f3211b23c9 100644
--- a/indra/llui/llscrolllistctrl.cpp
+++ b/indra/llui/llscrolllistctrl.cpp
@@ -3307,3 +3307,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;
+}
diff --git a/indra/llui/llscrolllistctrl.h b/indra/llui/llscrolllistctrl.h
index 08134bbfc8..af553843bd 100644
--- a/indra/llui/llscrolllistctrl.h
+++ b/indra/llui/llscrolllistctrl.h
@@ -410,6 +410,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();
diff --git a/indra/llui/llspinctrl.cpp b/indra/llui/llspinctrl.cpp
index ef7c8ec012..c411aafb1a 100644
--- a/indra/llui/llspinctrl.cpp
+++ b/indra/llui/llspinctrl.cpp
@@ -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);
diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp
index c4a529e4ad..aced671a39 100644
--- a/indra/llui/lltextbase.cpp
+++ b/indra/llui/lltextbase.cpp
@@ -355,95 +355,113 @@ void LLTextBase::onValueChange(S32 start, S32 end)
{
}
-
-// Draws the black box behind the selected text
-void LLTextBase::drawSelectionBackground()
+std::vector<LLRect> LLTextBase::getSelctionRects()
{
- // Draw selection even if we don't have keyboard focus for search/replace
- if( hasSelection() && !mLineInfoList.empty())
- {
- std::vector<LLRect> selection_rects;
+ // Nor supposed to be called without selection
+ llassert(hasSelection());
+ llassert(!mLineInfoList.empty());
- S32 selection_left = llmin( mSelectionStart, mSelectionEnd );
- S32 selection_right = llmax( mSelectionStart, mSelectionEnd );
+ std::vector<LLRect> selection_rects;
- // Skip through the lines we aren't drawing.
- LLRect content_display_rect = getVisibleDocumentRect();
+ S32 selection_left = llmin(mSelectionStart, mSelectionEnd);
+ S32 selection_right = llmax(mSelectionStart, mSelectionEnd);
- // 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());
+ // Skip through the lines we aren't drawing.
+ LLRect content_display_rect = getVisibleDocumentRect();
- bool done = false;
+ // 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());
- // 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;
+ bool done = false;
- S32 segment_line_start = segmentp->getStart() + segment_offset;
- S32 segment_line_end = llmin(segmentp->getEnd(), line_iter->mDocIndexEnd);
+ // 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);
- if (segment_line_start > segment_line_end) break;
+ // 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;
- S32 segment_width = 0;
- S32 segment_height = 0;
+ for (; segment_iter != mSegments.end(); ++segment_iter, segment_offset = 0)
+ {
+ LLTextSegmentPtr segmentp = *segment_iter;
- // 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;
- }
+ S32 segment_line_start = segmentp->getStart() + segment_offset;
+ S32 segment_line_end = llmin(segmentp->getEnd(), line_iter->mDocIndexEnd);
- // 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;
+ if (segment_line_start > segment_line_end) break;
- break;
- }
- }
- selection_rects.push_back(selection_rect);
- }
- }
+ 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 = 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();
@@ -2550,7 +2568,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;
@@ -2562,8 +2580,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)
{
@@ -2583,8 +2602,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;
@@ -2631,17 +2651,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;
@@ -2649,6 +2663,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;
@@ -2656,18 +2672,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
@@ -2675,6 +2693,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;
diff --git a/indra/llui/lltextbase.h b/indra/llui/lltextbase.h
index 25f8fa1c2b..e3cf56a5ee 100644
--- a/indra/llui/lltextbase.h
+++ b/indra/llui/lltextbase.h
@@ -638,6 +638,8 @@ protected:
return mLabel.getString() + getToolTip();
}
+ std::vector<LLRect> getSelctionRects();
+
protected:
// text segmentation and flow
segment_set_t mSegments;
diff --git a/indra/llwindow/llwindowwin32.cpp b/indra/llwindow/llwindowwin32.cpp
index 4c3aeb4695..6d5b42f2f1 100644
--- a/indra/llwindow/llwindowwin32.cpp
+++ b/indra/llwindow/llwindowwin32.cpp
@@ -3058,18 +3058,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);
+ }
}
}
}
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index 7d78ec9e3c..9eee5338ec 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -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
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index 16d8cd9f06..b156e96d1f 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -14620,6 +14620,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>
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index 60797c87d9..69413577b3 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -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"
@@ -1519,7 +1519,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;
}
}
diff --git a/indra/newview/llaudiosourcevo.cpp b/indra/newview/llaudiosourcevo.cpp
index 1846238d93..43abbb57ee 100644
--- a/indra/newview/llaudiosourcevo.cpp
+++ b/indra/newview/llaudiosourcevo.cpp
@@ -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;
diff --git a/indra/newview/llchathistory.cpp b/indra/newview/llchathistory.cpp
index bdd516e1de..79b7372610 100644
--- a/indra/newview/llchathistory.cpp
+++ b/indra/newview/llchathistory.cpp
@@ -602,7 +602,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)
{
@@ -744,6 +744,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:
@@ -893,7 +894,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();
@@ -1286,7 +1287,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));
diff --git a/indra/newview/llconversationmodel.h b/indra/newview/llconversationmodel.h
index 787deeb594..7c6980a7e6 100644
--- a/indra/newview/llconversationmodel.h
+++ b/indra/newview/llconversationmodel.h
@@ -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; }
diff --git a/indra/newview/llfloaterimsession.cpp b/indra/newview/llfloaterimsession.cpp
index 48e2b8dc14..ee9dc35283 100644
--- a/indra/newview/llfloaterimsession.cpp
+++ b/indra/newview/llfloaterimsession.cpp
@@ -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"))
diff --git a/indra/newview/llfloateroutfitsnapshot.cpp b/indra/newview/llfloateroutfitsnapshot.cpp
deleted file mode 100644
index ad5e97e067..0000000000
--- a/indra/newview/llfloateroutfitsnapshot.cpp
+++ /dev/null
@@ -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()
-{
-}
diff --git a/indra/newview/llfloateroutfitsnapshot.h b/indra/newview/llfloateroutfitsnapshot.h
deleted file mode 100644
index bee386ec63..0000000000
--- a/indra/newview/llfloateroutfitsnapshot.h
+++ /dev/null
@@ -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
diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp
index 26ea029cac..35696ef5ac 100644
--- a/indra/newview/llfloaterpreference.cpp
+++ b/indra/newview/llfloaterpreference.cpp
@@ -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)
@@ -1508,6 +1511,10 @@ void LLFloaterPreference::onClickEnablePopup()
}
buildPopupLists();
+ if (!mFilterEdit->getText().empty())
+ {
+ filterIgnorableNotifications();
+ }
}
void LLFloaterPreference::onClickDisablePopup()
@@ -1523,6 +1530,10 @@ void LLFloaterPreference::onClickDisablePopup()
}
buildPopupLists();
+ if (!mFilterEdit->getText().empty())
+ {
+ filterIgnorableNotifications();
+ }
}
void LLFloaterPreference::resetAllIgnored()
@@ -3543,11 +3554,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 )
@@ -3636,3 +3660,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);
+ }
+}
diff --git a/indra/newview/llfloaterpreference.h b/indra/newview/llfloaterpreference.h
index 542df18ddb..e312c35135 100644
--- a/indra/newview/llfloaterpreference.h
+++ b/indra/newview/llfloaterpreference.h
@@ -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
diff --git a/indra/newview/llfloatersimpleoutfitsnapshot.cpp b/indra/newview/llfloatersimpleoutfitsnapshot.cpp
new file mode 100644
index 0000000000..bab2efbbd5
--- /dev/null
+++ b/indra/newview/llfloatersimpleoutfitsnapshot.cpp
@@ -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()
+{
+}
diff --git a/indra/newview/llfloatersimpleoutfitsnapshot.h b/indra/newview/llfloatersimpleoutfitsnapshot.h
new file mode 100644
index 0000000000..cc9a6c5d1e
--- /dev/null
+++ b/indra/newview/llfloatersimpleoutfitsnapshot.h
@@ -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
diff --git a/indra/newview/llfloatersnapshot.cpp b/indra/newview/llfloatersnapshot.cpp
index 83212230e5..6b9d4580dc 100644
--- a/indra/newview/llfloatersnapshot.cpp
+++ b/indra/newview/llfloatersnapshot.cpp
@@ -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);
}
diff --git a/indra/newview/llfloatersnapshot.h b/indra/newview/llfloatersnapshot.h
index 7ec133ff45..7fc62a2746 100644
--- a/indra/newview/llfloatersnapshot.h
+++ b/indra/newview/llfloatersnapshot.h
@@ -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;
};
diff --git a/indra/newview/llimprocessing.cpp b/indra/newview/llimprocessing.cpp
index 0524313a5c..e6845127e3 100644
--- a/indra/newview/llimprocessing.cpp
+++ b/indra/newview/llimprocessing.cpp
@@ -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;
diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp
index b7e0a6a794..0dea11ce66 100644
--- a/indra/newview/llimview.cpp
+++ b/indra/newview/llimview.cpp
@@ -771,7 +771,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;
@@ -780,6 +780,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;
mMsgs.push_front(message);
@@ -1148,7 +1149,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);
@@ -1158,7 +1159,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;
}
@@ -1196,9 +1197,9 @@ bool LLIMModel::proccessOnlineOfflineNotification(
}
bool LLIMModel::addMessage(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 = addMessageSilently(session_id, from, from_id, utf8_text, log2file);
+ LLIMSession* session = addMessageSilently(session_id, from, from_id, utf8_text, log2file, is_region_msg);
if (!session) return false;
//good place to add some1 to recent list
@@ -1223,7 +1224,7 @@ bool LLIMModel::addMessage(const LLUUID& session_id, const std::string& from, co
}
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);
@@ -1239,7 +1240,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);
@@ -2695,7 +2696,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;
@@ -2767,7 +2768,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
@@ -2797,7 +2798,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
@@ -3724,8 +3725,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))
{
diff --git a/indra/newview/llimview.h b/indra/newview/llimview.h
index 79c831ebb6..707c8ef79f 100644
--- a/indra/newview/llimview.h
+++ b/indra/newview/llimview.h
@@ -82,7 +82,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 */
@@ -212,13 +212,13 @@ public:
* and also saved into a file if log2file is specified.
* It sends new message signal for each added message.
*/
- bool addMessage(const LLUUID& session_id, const std::string& from, const LLUUID& other_participant_id, const std::string& utf8_text, bool log2file = true);
+ bool 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);
/**
* 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
@@ -296,7 +296,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);
};
@@ -338,7 +338,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);
diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp
index 884007d2a6..c18ee0c4a0 100644
--- a/indra/newview/llinventorybridge.cpp
+++ b/indra/newview/llinventorybridge.cpp
@@ -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()))
@@ -882,7 +887,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)
@@ -2056,7 +2062,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())
{
@@ -2099,22 +2106,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
@@ -2318,7 +2327,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.
@@ -2333,22 +2342,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
{
@@ -3765,6 +3778,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())
diff --git a/indra/newview/llinventorybridge.h b/indra/newview/llinventorybridge.h
index 0b0ef273e1..bdffecf1c6 100644
--- a/indra/newview/llinventorybridge.h
+++ b/indra/newview/llinventorybridge.h
@@ -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;
diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp
index 37500176ea..ace4de928e 100644
--- a/indra/newview/llinventorymodel.cpp
+++ b/indra/newview/llinventorymodel.cpp
@@ -1838,7 +1838,8 @@ void LLInventoryModel::addChangedMask(U32 mask, const LLUUID& referent)
}
// Fix me: From DD-81, probably shouldn't be here, instead
- // should be somewhere in an observer
+ // should be somewhere in an observer or in
+ // LLMarketplaceInventoryObserver::onIdleProcessQueue
update_marketplace_category(referent, false);
if (mask & LLInventoryObserver::ADD)
diff --git a/indra/newview/llmarketplacefunctions.cpp b/indra/newview/llmarketplacefunctions.cpp
index 044c76ce2c..a5f1622ab2 100644
--- a/indra/newview/llmarketplacefunctions.cpp
+++ b/indra/newview/llmarketplacefunctions.cpp
@@ -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
diff --git a/indra/newview/llmarketplacefunctions.h b/indra/newview/llmarketplacefunctions.h
index fee9225f77..ec5de88189 100644
--- a/indra/newview/llmarketplacefunctions.h
+++ b/indra/newview/llmarketplacefunctions.h
@@ -240,6 +240,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);
diff --git a/indra/newview/lloutfitgallery.cpp b/indra/newview/lloutfitgallery.cpp
index f419e2e06d..1facbbf37c 100644
--- a/indra/newview/lloutfitgallery.cpp
+++ b/indra/newview/lloutfitgallery.cpp
@@ -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);
diff --git a/indra/newview/llpanelobjectinventory.cpp b/indra/newview/llpanelobjectinventory.cpp
index cfaa9456be..fff25c6c61 100644
--- a/indra/newview/llpanelobjectinventory.cpp
+++ b/indra/newview/llpanelobjectinventory.cpp
@@ -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);
}
diff --git a/indra/newview/llpanelpresetscamerapulldown.cpp b/indra/newview/llpanelpresetscamerapulldown.cpp
index 183123e534..4c9c30160c 100644
--- a/indra/newview/llpanelpresetscamerapulldown.cpp
+++ b/indra/newview/llpanelpresetscamerapulldown.cpp
@@ -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
{
diff --git a/indra/newview/llpanelpresetspulldown.cpp b/indra/newview/llpanelpresetspulldown.cpp
index d52ad8056f..23e4fa8887 100644
--- a/indra/newview/llpanelpresetspulldown.cpp
+++ b/indra/newview/llpanelpresetspulldown.cpp
@@ -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
diff --git a/indra/newview/llpanelpulldown.cpp b/indra/newview/llpanelpulldown.cpp
index 4de6ee8182..075278f44c 100644
--- a/indra/newview/llpanelpulldown.cpp
+++ b/indra/newview/llpanelpulldown.cpp
@@ -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);
}
}
diff --git a/indra/newview/llscripteditor.cpp b/indra/newview/llscripteditor.cpp
index c6bb2f19dd..140cbbedbe 100644
--- a/indra/newview/llscripteditor.cpp
+++ b/indra/newview/llscripteditor.cpp
@@ -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();
diff --git a/indra/newview/llsky.h b/indra/newview/llsky.h
index 8c0d70c16c..ec0de1fbfd 100644
--- a/indra/newview/llsky.h
+++ b/indra/newview/llsky.h
@@ -39,7 +39,6 @@
class LLViewerCamera;
class LLVOWLSky;
-class LLVOWLClouds;
class LLSky
diff --git a/indra/newview/llsnapshotlivepreview.cpp b/indra/newview/llsnapshotlivepreview.cpp
index 8134187c21..ed7e18fadc 100644
--- a/indra/newview/llsnapshotlivepreview.cpp
+++ b/indra/newview/llsnapshotlivepreview.cpp
@@ -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())
{
diff --git a/indra/newview/llsnapshotlivepreview.h b/indra/newview/llsnapshotlivepreview.h
index 683cd016d8..1f81307976 100644
--- a/indra/newview/llsnapshotlivepreview.h
+++ b/indra/newview/llsnapshotlivepreview.h
@@ -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();
diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp
index 142dc4c46e..c6c32630a1 100644
--- a/indra/newview/llstartup.cpp
+++ b/indra/newview/llstartup.cpp
@@ -2503,8 +2503,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 );
diff --git a/indra/newview/lltexturecache.cpp b/indra/newview/lltexturecache.cpp
index d4fc6f3de2..882378d7e5 100644
--- a/indra/newview/lltexturecache.cpp
+++ b/indra/newview/lltexturecache.cpp
@@ -1645,6 +1645,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)
diff --git a/indra/newview/lltexturefetch.cpp b/indra/newview/lltexturefetch.cpp
index 0edaf40c66..3099092abb 100644
--- a/indra/newview/lltexturefetch.cpp
+++ b/indra/newview/lltexturefetch.cpp
@@ -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();
@@ -507,10 +503,6 @@ private:
void removeFromCache();
// Threads: Ttf
- // Locks: Mw
- bool processSimulatorPackets();
-
- // Threads: Ttf
bool writeToCacheComplete();
// Threads: Ttf
@@ -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;
@@ -1408,14 +1363,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 +1389,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 +1436,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 +1582,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)
{
@@ -2284,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
-// Locks: Mw
S32 LLTextureFetchWorker::callbackHttpGet(LLCore::HttpResponse * response,
bool partial, bool success)
{
@@ -2813,40 +2620,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 +2653,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 +2680,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 +2968,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 +3058,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 +3120,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 +3158,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;
}
diff --git a/indra/newview/lltexturefetch.h b/indra/newview/lltexturefetch.h
index bf6732963f..d087db275b 100644
--- a/indra/newview/lltexturefetch.h
+++ b/indra/newview/lltexturefetch.h
@@ -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;
diff --git a/indra/newview/lltextureview.cpp b/indra/newview/lltextureview.cpp
index b74577315e..cf9211767e 100644
--- a/indra/newview/lltextureview.cpp
+++ b/indra/newview/lltextureview.cpp
@@ -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
diff --git a/indra/newview/llviewerassetupload.cpp b/indra/newview/llviewerassetupload.cpp
index 3f7e8531fb..fc83b109ba 100644
--- a/indra/newview/llviewerassetupload.cpp
+++ b/indra/newview/llviewerassetupload.cpp
@@ -811,11 +811,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")));
- }
}
//=========================================================================
@@ -893,11 +888,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")));
- }
}
diff --git a/indra/newview/llvieweraudio.cpp b/indra/newview/llvieweraudio.cpp
index f810e5f4ef..cc73f7ca80 100644
--- a/indra/newview/llvieweraudio.cpp
+++ b/indra/newview/llvieweraudio.cpp
@@ -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);
diff --git a/indra/newview/llviewerfloaterreg.cpp b/indra/newview/llviewerfloaterreg.cpp
index 06a6c5e373..75f68517de 100644
--- a/indra/newview/llviewerfloaterreg.cpp
+++ b/indra/newview/llviewerfloaterreg.cpp
@@ -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"
@@ -368,7 +368,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>);
diff --git a/indra/newview/llviewermedia.cpp b/indra/newview/llviewermedia.cpp
index 661f70972d..2739d3c594 100644
--- a/indra/newview/llviewermedia.cpp
+++ b/indra/newview/llviewermedia.cpp
@@ -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();
}
}
diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp
index ac516b8460..734c04c322 100644
--- a/indra/newview/llviewermenu.cpp
+++ b/indra/newview/llviewermenu.cpp
@@ -4284,6 +4284,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;
diff --git a/indra/newview/llviewermenufile.cpp b/indra/newview/llviewermenufile.cpp
index f1e2c06e0c..fdf1d04c09 100644
--- a/indra/newview/llviewermenufile.cpp
+++ b/indra/newview/llviewermenufile.cpp
@@ -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();
diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp
index a95636ff23..6e1d5c76f8 100644
--- a/indra/newview/llviewerobject.cpp
+++ b/indra/newview/llviewerobject.cpp
@@ -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)
{
diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h
index bef8e3e7e3..0005cdf14e 100644
--- a/indra/newview/llviewerobject.h
+++ b/indra/newview/llviewerobject.h
@@ -702,6 +702,8 @@ public:
// Replace textures with web pages on this object while drawing
BOOL mRenderMedia;
+ bool mRiggedAttachedWarned;
+
// In bits
S32 mBestUpdatePrecision;
diff --git a/indra/newview/llviewerparcelmgr.cpp b/indra/newview/llviewerparcelmgr.cpp
index e69b0347f8..9095a6b5b7 100644
--- a/indra/newview/llviewerparcelmgr.cpp
+++ b/indra/newview/llviewerparcelmgr.cpp
@@ -1959,7 +1959,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
diff --git a/indra/newview/llviewertexturelist.cpp b/indra/newview/llviewertexturelist.cpp
index d603f584ff..546a03def2 100644
--- a/indra/newview/llviewertexturelist.cpp
+++ b/indra/newview/llviewertexturelist.cpp
@@ -1502,152 +1502,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)
diff --git a/indra/newview/llviewertexturelist.h b/indra/newview/llviewertexturelist.h
index 6fb0d3552e..41b3568570 100644
--- a/indra/newview/llviewertexturelist.h
+++ b/indra/newview/llviewertexturelist.h
@@ -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();
diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp
index 119859a4ac..ae9da97642 100644
--- a/indra/newview/llviewerwindow.cpp
+++ b/indra/newview/llviewerwindow.cpp
@@ -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", ""));
@@ -1997,7 +1999,7 @@ LLViewerWindow::LLViewerWindow(const Params& p)
}
LLVertexBuffer::initClass(gSavedSettings.getBOOL("RenderVBOEnable"), gSavedSettings.getBOOL("RenderVBOMappingDisable"));
LL_INFOS("RenderInit") << "LLVertexBuffer initialization done." << LL_ENDL ;
- gGL.init() ;
+ gGL.init(true);
if (LLFeatureManager::getInstance()->isSafe()
|| (gSavedSettings.getS32("LastFeatureVersion") != LLFeatureManager::getInstance()->getVersion())
@@ -2224,26 +2226,31 @@ 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);
+
+ // Navigation bar is outside visible area, expand status_bar_container to show it
+ S32 new_height = nav_bar_container->getRect().getHeight() + status_bar_container->getRect().getHeight();
+ S32 new_width = status_bar_container->getRect().getWidth();
+ status_bar_container->reshape(new_width, new_height, TRUE);
+
if (!gSavedSettings.getBOOL("ShowNavbarNavigationPanel"))
{
@@ -2874,6 +2881,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())
{
diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp
index 5c76f7b392..1f7596807b 100644
--- a/indra/newview/llvoavatar.cpp
+++ b/indra/newview/llvoavatar.cpp
@@ -2810,6 +2810,7 @@ void LLVOAvatar::idleUpdateMisc(bool detailed_update)
if (detailed_update)
{
U32 draw_order = 0;
+ S32 attachment_selected = LLSelectMgr::getInstance()->getSelection()->getObjectCount() && LLSelectMgr::getInstance()->getSelection()->isAttachment();
for (attachment_map_t::iterator iter = mAttachmentPoints.begin();
iter != mAttachmentPoints.end();
++iter)
@@ -2849,7 +2850,7 @@ void LLVOAvatar::idleUpdateMisc(bool detailed_update)
}
// if selecting any attachments, update all of them as non-damped
- if (LLSelectMgr::getInstance()->getSelection()->getObjectCount() && LLSelectMgr::getInstance()->getSelection()->isAttachment())
+ if (attachment_selected)
{
gPipeline.updateMoveNormalAsync(attached_object->mDrawable);
}
@@ -10664,7 +10665,7 @@ void LLVOAvatar::updateVisualComplexity()
// with an avatar. This will be either an attached object or an animated
// object.
void LLVOAvatar::accountRenderComplexityForObject(
- const LLViewerObject *attached_object,
+ LLViewerObject *attached_object,
const F32 max_attachment_complexity,
LLVOVolume::texture_cost_t& textures,
U32& cost,
@@ -10736,7 +10737,7 @@ void LLVOAvatar::accountRenderComplexityForObject(
&& attached_object->mDrawable)
{
textures.clear();
-
+ BOOL is_rigged_mesh = attached_object->isRiggedMesh();
mAttachmentSurfaceArea += attached_object->recursiveGetScaledSurfaceArea();
const LLVOVolume* volume = attached_object->mDrawable->getVOVolume();
@@ -10757,6 +10758,7 @@ void LLVOAvatar::accountRenderComplexityForObject(
iter != child_list.end(); ++iter)
{
LLViewerObject* childp = *iter;
+ is_rigged_mesh |= childp->isRiggedMesh();
const LLVOVolume* chld_volume = dynamic_cast<LLVOVolume*>(childp);
if (chld_volume)
{
@@ -10765,6 +10767,16 @@ void LLVOAvatar::accountRenderComplexityForObject(
hud_object_complexity.objectsCount++;
}
}
+ if (is_rigged_mesh && !attached_object->mRiggedAttachedWarned)
+ {
+ LLSD args;
+ LLViewerInventoryItem* itemp = gInventory.getItem(attached_object->getAttachmentItemID());
+ args["NAME"] = itemp ? itemp->getName() : LLTrans::getString("Unknown");
+ args["POINT"] = LLTrans::getString(getTargetAttachmentPoint(attached_object)->getName());
+ LLNotificationsUtil::add("RiggedMeshAttachedToHUD", args);
+
+ attached_object->mRiggedAttachedWarned = true;
+ }
hud_object_complexity.texturesCount += textures.size();
@@ -10869,7 +10881,7 @@ void LLVOAvatar::calculateUpdateRenderComplexity()
attachment_iter != attachment->mAttachedObjects.end();
++attachment_iter)
{
- const LLViewerObject* attached_object = attachment_iter->get();
+ LLViewerObject* attached_object = attachment_iter->get();
accountRenderComplexityForObject(attached_object, max_attachment_complexity,
textures, cost, hud_complexity_list);
}
diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h
index 3c3decaad6..c06f60b26c 100644
--- a/indra/newview/llvoavatar.h
+++ b/indra/newview/llvoavatar.h
@@ -293,7 +293,7 @@ public:
void addNameTagLine(const std::string& line, const LLColor4& color, S32 style, const LLFontGL* font, const bool use_ellipses = false);
void idleUpdateRenderComplexity();
void idleUpdateDebugInfo();
- void accountRenderComplexityForObject(const LLViewerObject *attached_object,
+ void accountRenderComplexityForObject(LLViewerObject *attached_object,
const F32 max_attachment_complexity,
LLVOVolume::texture_cost_t& textures,
U32& cost,
diff --git a/indra/newview/llvoground.h b/indra/newview/llvoground.h
index a53f309e46..e7033290c7 100644
--- a/indra/newview/llvoground.h
+++ b/indra/newview/llvoground.h
@@ -49,7 +49,6 @@ public:
/*virtual*/ LLDrawable* createDrawable(LLPipeline *pipeline);
/*virtual*/ BOOL updateGeometry(LLDrawable *drawable);
- void cleanupGL();
};
#endif // LL_LLVOGROUND_H
diff --git a/indra/newview/llvoicevivox.cpp b/indra/newview/llvoicevivox.cpp
index 19036a3f77..c3115e2b45 100644
--- a/indra/newview/llvoicevivox.cpp
+++ b/indra/newview/llvoicevivox.cpp
@@ -4527,9 +4527,7 @@ void LLVivoxVoiceClient::messageEvent(
IM_NOTHING_SPECIAL, // default arg
0, // default arg
LLUUID::null, // default arg
- LLVector3::zero, // default arg
- true); // prepend name and make it a link to the user's profile
-
+ LLVector3::zero); // default arg
}
}
}
@@ -6188,7 +6186,7 @@ void LLVivoxVoiceClient::clearSessionHandle(const sessionStatePtr_t &session)
{
if (session)
{
- if (session->mHandle.empty())
+ if (!session->mHandle.empty())
{
sessionMap::iterator iter = mSessionsByHandle.find(session->mHandle);
if (iter != mSessionsByHandle.end())
diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp
index f4a938e57d..cf633d2146 100644
--- a/indra/newview/llvovolume.cpp
+++ b/indra/newview/llvovolume.cpp
@@ -6014,7 +6014,7 @@ void LLVolumeGeometryManager::rebuildMesh(LLSpatialGroup* group)
{
LLDrawable* drawablep = (LLDrawable*)(*drawable_iter)->getDrawable();
- if (drawablep && !drawablep->isDead() && drawablep->isState(LLDrawable::REBUILD_ALL) && !drawablep->isState(LLDrawable::RIGGED) )
+ if (drawablep && !drawablep->isDead() && drawablep->isState(LLDrawable::REBUILD_ALL))
{
LLVOVolume* vobj = drawablep->getVOVolume();
@@ -6048,8 +6048,6 @@ void LLVolumeGeometryManager::rebuildMesh(LLSpatialGroup* group)
LLVertexBuffer* buff = face->getVertexBuffer();
if (buff)
{
- llassert(!face->isState(LLFace::RIGGED));
-
if (!face->getGeometryVolume(*volume, face->getTEOffset(),
vobj->getRelativeXform(), vobj->getRelativeXformInvTrans(), face->getGeomIndex()))
{ //something's gone wrong with the vertex buffer accounting, rebuild this group
diff --git a/indra/newview/llworld.cpp b/indra/newview/llworld.cpp
index 8abb49fba8..5d6e8611a7 100644
--- a/indra/newview/llworld.cpp
+++ b/indra/newview/llworld.cpp
@@ -93,7 +93,7 @@ LLWorld::LLWorld() :
mLastPacketsLost(0),
mSpaceTimeUSec(0)
{
- for (S32 i = 0; i < 8; i++)
+ for (S32 i = 0; i < EDGE_WATER_OBJECTS_COUNT; i++)
{
mEdgeWaterObjects[i] = NULL;
}
@@ -126,7 +126,7 @@ void LLWorld::resetClass()
LLViewerPartSim::getInstance()->destroyClass();
mDefaultWaterTexturep = NULL ;
- for (S32 i = 0; i < 8; i++)
+ for (S32 i = 0; i < EDGE_WATER_OBJECTS_COUNT; i++)
{
mEdgeWaterObjects[i] = NULL;
}
@@ -753,6 +753,8 @@ void LLWorld::clearAllVisibleObjects()
//clear all cached visible objects.
(*iter)->clearCachedVisibleObjects();
}
+ clearHoleWaterObjects();
+ clearEdgeWaterObjects();
}
void LLWorld::updateParticles()
@@ -923,7 +925,7 @@ void LLWorld::precullWaterObjects(LLCamera& camera, LLCullResult* cull, bool inc
}
S32 dir;
- for (dir = 0; dir < 8; dir++)
+ for (dir = 0; dir < EDGE_WATER_OBJECTS_COUNT; dir++)
{
LLVOWater* waterp = mEdgeWaterObjects[dir];
if (waterp && waterp->mDrawable)
@@ -934,6 +936,26 @@ void LLWorld::precullWaterObjects(LLCamera& camera, LLCullResult* cull, bool inc
}
}
+void LLWorld::clearHoleWaterObjects()
+{
+ for (std::list<LLPointer<LLVOWater> >::iterator iter = mHoleWaterObjects.begin();
+ iter != mHoleWaterObjects.end(); ++iter)
+ {
+ LLVOWater* waterp = (*iter).get();
+ gObjectList.killObject(waterp);
+ }
+ mHoleWaterObjects.clear();
+}
+
+void LLWorld::clearEdgeWaterObjects()
+{
+ for (S32 i = 0; i < EDGE_WATER_OBJECTS_COUNT; i++)
+ {
+ gObjectList.killObject(mEdgeWaterObjects[i]);
+ mEdgeWaterObjects[i] = NULL;
+ }
+}
+
void LLWorld::updateWaterObjects()
{
if (!gAgent.getRegion())
@@ -977,13 +999,7 @@ void LLWorld::updateWaterObjects()
}
}
- for (std::list<LLPointer<LLVOWater> >::iterator iter = mHoleWaterObjects.begin();
- iter != mHoleWaterObjects.end(); ++ iter)
- {
- LLVOWater* waterp = (*iter).get();
- gObjectList.killObject(waterp);
- }
- mHoleWaterObjects.clear();
+ clearHoleWaterObjects();
// Use the water height of the region we're on for areas where there is no region
F32 water_height = gAgent.getRegion()->getWaterHeight();
@@ -1024,7 +1040,7 @@ void LLWorld::updateWaterObjects()
(S32)(512 - (region_y - min_y)) };
S32 dir;
- for (dir = 0; dir < 8; dir++)
+ for (dir = 0; dir < EDGE_WATER_OBJECTS_COUNT; dir++)
{
S32 dim[2] = { 0 };
switch (gDirAxes[dir][0])
diff --git a/indra/newview/llworld.h b/indra/newview/llworld.h
index 5c43cdf4e2..5dee8eea0f 100644
--- a/indra/newview/llworld.h
+++ b/indra/newview/llworld.h
@@ -122,12 +122,9 @@ public:
void updateRegions(F32 max_update_time);
void updateVisibilities();
void updateParticles();
- void updateClouds(const F32 dt);
- LLCloudGroup * findCloudGroup(const LLCloudPuff &puff);
void renderPropertyLines();
- void resetStats();
void updateNetStats(); // Update network statistics for all the regions...
void printPacketsLost();
@@ -140,7 +137,7 @@ public:
void setLandFarClip(const F32 far_clip);
LLViewerTexture *getDefaultWaterTexture();
- void updateWaterObjects();
+ void updateWaterObjects();
void precullWaterObjects(LLCamera& camera, LLCullResult* cull, bool include_void_water);
@@ -175,6 +172,9 @@ public:
bool isRegionListed(const LLViewerRegion* region) const;
private:
+ void clearHoleWaterObjects();
+ void clearEdgeWaterObjects();
+
region_list_t mActiveRegionList;
region_list_t mRegionList;
region_list_t mVisibleRegionList;
@@ -198,15 +198,14 @@ private:
U32 mNumOfActiveCachedObjects;
U64MicrosecondsImplicit mSpaceTimeUSec;
- BOOL mClassicCloudsEnabled;
-
////////////////////////////
//
// Data for "Fake" objects
//
std::list<LLPointer<LLVOWater> > mHoleWaterObjects;
- LLPointer<LLVOWater> mEdgeWaterObjects[8];
+ static const S32 EDGE_WATER_OBJECTS_COUNT = 8;
+ LLPointer<LLVOWater> mEdgeWaterObjects[EDGE_WATER_OBJECTS_COUNT];
LLPointer<LLViewerTexture> mDefaultWaterTexturep;
};
diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index 54e6c6fc6e..13d6966723 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -685,7 +685,9 @@ void LLPipeline::cleanup()
mFaceSelectImagep = NULL;
- mMovedBridge.clear();
+ mMovedList.clear();
+ mMovedBridge.clear();
+ mShiftList.clear();
mInitialized = false;
@@ -1773,15 +1775,20 @@ void LLPipeline::unlinkDrawable(LLDrawable *drawable)
void LLPipeline::removeMutedAVsLights(LLVOAvatar* muted_avatar)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE;
- for (light_set_t::iterator iter = gPipeline.mNearbyLights.begin();
- iter != gPipeline.mNearbyLights.end(); iter++)
- {
- if (iter->drawable->getVObj()->isAttachment() && iter->drawable->getVObj()->getAvatar() == muted_avatar)
- {
- gPipeline.mLights.erase(iter->drawable);
- gPipeline.mNearbyLights.erase(iter);
- }
- }
+ light_set_t::iterator iter = gPipeline.mNearbyLights.begin();
+
+ while (iter != gPipeline.mNearbyLights.end())
+ {
+ if (iter->drawable->getVObj()->isAttachment() && iter->drawable->getVObj()->getAvatar() == muted_avatar)
+ {
+ gPipeline.mLights.erase(iter->drawable);
+ iter = gPipeline.mNearbyLights.erase(iter);
+ }
+ else
+ {
+ iter++;
+ }
+ }
}
U32 LLPipeline::addObject(LLViewerObject *vobj)
@@ -2817,6 +2824,14 @@ void LLPipeline::clearRebuildDrawables()
drawablep->clearState(LLDrawable::EARLY_MOVE | LLDrawable::MOVE_UNDAMPED | LLDrawable::ON_MOVE_LIST | LLDrawable::ANIMATED_CHILD);
}
mMovedList.clear();
+
+ for (LLDrawable::drawable_vector_t::iterator iter = mShiftList.begin();
+ iter != mShiftList.end(); ++iter)
+ {
+ LLDrawable *drawablep = *iter;
+ drawablep->clearState(LLDrawable::EARLY_MOVE | LLDrawable::MOVE_UNDAMPED | LLDrawable::ON_MOVE_LIST | LLDrawable::ANIMATED_CHILD | LLDrawable::ON_SHIFT_LIST);
+ }
+ mShiftList.clear();
}
void LLPipeline::rebuildPriorityGroups()
@@ -7238,6 +7253,7 @@ void LLPipeline::doResetVertexBuffers(bool forced)
mResetVertexBuffers = false;
mCubeVB = NULL;
+ mDeferredVB = NULL;
for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin();
iter != LLWorld::getInstance()->getRegionList().end(); ++iter)
@@ -7271,10 +7287,11 @@ void LLPipeline::doResetVertexBuffers(bool forced)
LLPathingLib::getInstance()->cleanupVBOManager();
}
LLVOPartGroup::destroyGL();
+ gGL.resetVertexBuffer();
SUBSYSTEM_CLEANUP(LLVertexBuffer);
- if (LLVertexBuffer::sGLCount > 0)
+ if (LLVertexBuffer::sGLCount != 0)
{
LL_WARNS() << "VBO wipe failed -- " << LLVertexBuffer::sGLCount << " buffers remaining." << LL_ENDL;
}
@@ -7295,6 +7312,10 @@ void LLPipeline::doResetVertexBuffers(bool forced)
LLPipeline::sTextureBindTest = gSavedSettings.getBOOL("RenderDebugTextureBind");
LLVertexBuffer::initClass(LLVertexBuffer::sEnableVBOs, LLVertexBuffer::sDisableVBOMapping);
+ gGL.initVertexBuffer();
+
+ mDeferredVB = new LLVertexBuffer(DEFERRED_VB_MASK, 0);
+ mDeferredVB->allocateBuffer(8, 0, true);
LLVOPartGroup::restoreGL();
}
@@ -10900,6 +10921,8 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar, bool preview_avatar)
if (preview_avatar)
{
// Only show rigged attachments for preview
+ // For the sake of performance and so that static
+ // objects won't obstruct previewing changes
LLVOAvatar::attachment_map_t::iterator iter;
for (iter = avatar->mAttachmentPoints.begin();
iter != avatar->mAttachmentPoints.end();
@@ -10911,9 +10934,27 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar, bool preview_avatar)
++attachment_iter)
{
LLViewerObject* attached_object = attachment_iter->get();
- if (attached_object && attached_object->isRiggedMesh())
+ if (attached_object)
{
- markVisible(attached_object->mDrawable->getSpatialBridge(), *viewer_camera);
+ if (attached_object->isRiggedMesh())
+ {
+ markVisible(attached_object->mDrawable->getSpatialBridge(), *viewer_camera);
+ }
+ else
+ {
+ // sometimes object is a linkset and rigged mesh is a child
+ LLViewerObject::const_child_list_t& child_list = attached_object->getChildren();
+ for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin();
+ iter != child_list.end(); iter++)
+ {
+ LLViewerObject* child = *iter;
+ if (child->isRiggedMesh())
+ {
+ markVisible(attached_object->mDrawable->getSpatialBridge(), *viewer_camera);
+ break;
+ }
+ }
+ }
}
}
}
diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h
index 62d3ae7a39..0830d4a2ea 100644
--- a/indra/newview/pipeline.h
+++ b/indra/newview/pipeline.h
@@ -465,7 +465,7 @@ public:
RENDER_TYPE_PASS_SIMPLE_RIGGED = LLRenderPass::PASS_SIMPLE_RIGGED,
RENDER_TYPE_PASS_GRASS = LLRenderPass::PASS_GRASS,
RENDER_TYPE_PASS_FULLBRIGHT = LLRenderPass::PASS_FULLBRIGHT,
- RENDER_TYPE_PASS_FULLBRIGHT_RIGGED = LLRenderPass::PASS_FULLBRIGHT,
+ RENDER_TYPE_PASS_FULLBRIGHT_RIGGED = LLRenderPass::PASS_FULLBRIGHT_RIGGED,
RENDER_TYPE_PASS_INVISIBLE = LLRenderPass::PASS_INVISIBLE,
RENDER_TYPE_PASS_INVISIBLE_RIGGED = LLRenderPass::PASS_INVISIBLE_RIGGED,
RENDER_TYPE_PASS_INVISI_SHINY = LLRenderPass::PASS_INVISI_SHINY,
diff --git a/indra/newview/skins/default/colors.xml b/indra/newview/skins/default/colors.xml
index 1085972d9e..cfe7ab5f7c 100644
--- a/indra/newview/skins/default/colors.xml
+++ b/indra/newview/skins/default/colors.xml
@@ -985,4 +985,10 @@
<color
name="AddPaymentPanel"
value="0.27 0.27 0.27 1" />
+ <color
+ name="OutfitSnapshotMacMask"
+ value="0.115 0.115 0.115 1"/>
+ <color
+ name="OutfitSnapshotMacMask2"
+ value="0.1 0.1 0.1 1"/>
</colors>
diff --git a/indra/newview/skins/default/xui/en/floater_how_to.xml b/indra/newview/skins/default/xui/en/floater_how_to.xml
index baff8e1bc0..19e42798af 100644
--- a/indra/newview/skins/default/xui/en/floater_how_to.xml
+++ b/indra/newview/skins/default/xui/en/floater_how_to.xml
@@ -3,7 +3,6 @@
legacy_header_height="18"
can_resize="false"
can_minimize="false"
- can_close="false"
height="525"
layout="topleft"
name="floater_how_to"
diff --git a/indra/newview/skins/default/xui/en/floater_outfit_snapshot.xml b/indra/newview/skins/default/xui/en/floater_outfit_snapshot.xml
deleted file mode 100644
index 15c480f144..0000000000
--- a/indra/newview/skins/default/xui/en/floater_outfit_snapshot.xml
+++ /dev/null
@@ -1,351 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
-<floater
- positioning="cascading"
- legacy_header_height="18"
- can_minimize="true"
- can_resize="false"
- can_close="true"
- height="455"
- layout="topleft"
- name="outfit_snapshot"
- single_instance="true"
- help_topic="snapshot"
- save_rect="true"
- save_visibility="false"
- title="OUTFIT SNAPSHOT"
- width="624"
- min_height="455">
- <floater.string
- name="unknown">
- unknown
- </floater.string>
- <string
- name="inventory_progress_str">
- Saving to Inventory
- </string>
- <string
- name="inventory_succeeded_str">
- Saved to Inventory!
- </string>
- <string
- name="inventory_failed_str">
- Failed to save to inventory.
- </string>
- <button
- follows="left|top"
- height="25"
- image_overlay="Refresh_Off"
- image_hover_unselected="Toolbar_Middle_Over"
- image_selected="Toolbar_Middle_Selected"
- image_unselected="Toolbar_Middle_Off"
- image_overlay_alignment="left"
- imgoverlay_label_space="5"
- pad_bottom="0"
- halign="left"
- layout="topleft"
- left="10"
- label="REFRESH"
- name="new_snapshot_btn"
- top_pad="26"
- width="167" />
- <button
- follows="left|top"
- control_name="AdvanceOutfitSnapshot"
- invisibility_control="AdvanceOutfitSnapshot"
- height="25"
- is_toggle="true"
- layout="topleft"
- image_hover_unselected="Toolbar_Middle_Over"
- image_selected="Toolbar_Middle_Off"
- image_unselected="Toolbar_Middle_Off"
- image_overlay="Conv_toolbar_expand"
- name="retract_btn"
- left_pad="1"
- top_delta="0"
- width="31" />
- <button
- follows="left|top"
- control_name="AdvanceOutfitSnapshot"
- visibility_control="AdvanceOutfitSnapshot"
- height="25"
- is_toggle="true"
- layout="topleft"
- image_overlay="Conv_toolbar_collapse"
- image_hover_unselected="Toolbar_Middle_Over"
- image_selected="Toolbar_Middle_Off"
- image_unselected="Toolbar_Middle_Off"
- name="extend_btn"
- left_delta="0"
- top_delta="0"
- width="31" />
- <panel
- height="154"
- layout="topleft"
- follows="top|left"
- left="0"
- name="advanced_options_panel"
- top_pad="-6"
- width="210">
- <view_border
- bevel_style="in"
- follows="left|top|right"
- height="1"
- left="10"
- layout="topleft"
- name="advanced_options_hr"
- right="-1"
- top_pad="5"
- />
- <text
- type="string"
- length="1"
- follows="left|top"
- height="13"
- layout="topleft"
- left="10"
- name="layer_type_label"
- top_pad="10"
- width="100">
- Capture:
- </text>
- <check_box
- label="Interface"
- layout="topleft"
- left="30"
- height="16"
- top_pad="8"
- width="180"
- name="ui_check" />
- <check_box
- label="HUDs"
- layout="topleft"
- height="16"
- left="30"
- top_pad="1"
- width="180"
- name="hud_check" />
- <check_box
- label="Freeze frame (fullscreen)"
- layout="topleft"
- height="16"
- left="10"
- top_pad="1"
- width="180"
- name="freeze_frame_check" />
- <check_box
- label="Auto-refresh"
- layout="topleft"
- height="16"
- left="10"
- top_pad="1"
- width="180"
- name="auto_snapshot_check" />
- <text
- type="string"
- length="1"
- follows="left|top"
- height="13"
- layout="topleft"
- left="10"
- name="filter_list_label"
- top_pad="10"
- width="50">
- Filter:
- </text>
- <combo_box
- control_name="PhotoFilters"
- follows="left|right|top"
- name="filters_combobox"
- tool_tip="Image filters"
- top_delta="-3"
- left="50"
- right="-1"
- height="21"
- width="135">
- <combo_box.item
- label="No Filter"
- name="NoFilter"
- value="NoFilter" />
- </combo_box>
- <view_border
- bevel_style="in"
- follows="left|top|right"
- height="1"
- left="10"
- layout="topleft"
- name="advanced_options_hr"
- right="-1"
- top_pad="7"
- />
- </panel>
- <panel
- class="llpaneloutfitsnapshotinventory"
- follows="left|top"
- height="230"
- layout="topleft"
- left="0"
- name="panel_outfit_snapshot_inventory"
- filename="panel_outfit_snapshot_inventory.xml"
- top_pad="10"
- width="215"
- />
- <view_border
- bevel_style="in"
- follows="left|top"
- height="1"
- left="10"
- layout="topleft"
- name="status_hr"
- width="199"
- top_pad="-16"/>
- <panel
- background_visible="false"
- follows="left|top"
- font="SansSerifLarge"
- halign="center"
- height="20"
- layout="topleft"
- left="10"
- length="1"
- name="succeeded_panel"
- width="198"
- top_pad="1"
- type="string"
- visible="false">
- <text
- follows="all"
- font="SansSerif"
- halign="center"
- height="18"
- layout="topleft"
- left="1"
- length="1"
- name="succeeded_lbl"
- right="-1"
- text_color="0.2 0.85 0.2 1"
- top="4"
- translate="false"
- type="string">
- Succeeded
- </text>
- </panel>
- <panel
- background_visible="false"
- follows="left|top"
- font="SansSerifLarge"
- halign="center"
- height="20"
- layout="topleft"
- left="10"
- length="1"
- name="failed_panel"
- width="198"
- top_delta="0"
- type="string"
- visible="false">
- <text
- follows="all"
- font="SansSerif"
- halign="center"
- height="18"
- layout="topleft"
- left="1"
- length="1"
- name="failed_lbl"
- right="-1"
- text_color="0.95 0.4 0.4 1"
- top="4"
- translate="false"
- type="string">
- Failed
- </text>
- </panel>
- <loading_indicator
- follows="left|top"
- height="24"
- layout="topleft"
- name="working_indicator"
- left="10"
- top_delta="0"
- visible="false"
- width="24" />
- <text
- follows="left|top"
- font="SansSerifBold"
- height="14"
- layout="topleft"
- left_pad="3"
- length="1"
- halign="left"
- name="working_lbl"
- top_delta="5"
- translate="false"
- type="string"
- visible="false"
- width="162">
- Working
- </text>
- <text
- follows="left|top"
- font="SansSerifBold"
- halign="left"
- height="18"
- layout="topleft"
- left="10"
- length="1"
- name="refresh_lbl"
- text_color="0.95 0.4 0.4 1"
- top_delta="0"
- translate="false"
- type="string"
- visible="false"
- width="130">
- Refresh to save.
- </text>
- <ui_ctrl
- layout="topleft"
- name="thumbnail_placeholder"
- top="23"
- left="215"
- width="400"
- height="400"
- follows="top|left"/>
- <view_border
- bevel_style="in"
- height="21"
- layout="topleft"
- name="img_info_border"
- top_pad="0"
- right="-10"
- follows="left|top|right"
- left_delta="0"/>
- <text
- type="string"
- font="SansSerifSmall"
- length="1"
- follows="left|top|right"
- height="14"
- layout="topleft"
- left="220"
- right="-20"
- halign="left"
- name="image_res_text"
- top_delta="5"
- width="200">
- [WIDTH]px (width) x [HEIGHT]px (height)
- </text>
- <text
- follows="right|top"
- font="SansSerifSmall"
- height="14"
- layout="topleft"
- left="-65"
- length="1"
- halign="right"
- name="file_size_label"
- top_delta="0"
- type="string"
- width="50">
- [SIZE] KB
- </text>
-</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_simple_outfit_snapshot.xml b/indra/newview/skins/default/xui/en/floater_simple_outfit_snapshot.xml
new file mode 100644
index 0000000000..5ece7b85d5
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_simple_outfit_snapshot.xml
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<floater
+ positioning="cascading"
+ legacy_header_height="18"
+ can_minimize="true"
+ can_resize="false"
+ can_close="true"
+ height="305"
+ layout="topleft"
+ name="simple_outfit_snapshot"
+ single_instance="true"
+ help_topic="snapshot"
+ save_rect="true"
+ save_visibility="false"
+ title="OUTFIT SNAPSHOT"
+ width="351">
+ <ui_ctrl
+ layout="topleft"
+ name="thumbnail_placeholder"
+ top="18"
+ left="22"
+ width="335"
+ height="200"
+ follows="top|left"/>
+ <button
+ follows="left|bottom"
+ height="22"
+ layout="topleft"
+ left="29"
+ label="Take photo"
+ name="new_snapshot_btn"
+ bottom="-15"
+ width="90" />
+ <button
+ follows="left|bottom"
+ height="22"
+ layout="topleft"
+ left_pad="10"
+ label="Save (L$[UPLOAD_COST])"
+ name="save_btn"
+ width="90" />
+ <button
+ follows="left|bottom"
+ height="22"
+ layout="topleft"
+ left_pad="10"
+ label="Cancel"
+ name="cancel_btn"
+ width="90" />
+</floater>
diff --git a/indra/newview/skins/default/xui/en/main_view.xml b/indra/newview/skins/default/xui/en/main_view.xml
index 842184de88..bab37c6258 100644
--- a/indra/newview/skins/default/xui/en/main_view.xml
+++ b/indra/newview/skins/default/xui/en/main_view.xml
@@ -8,16 +8,6 @@
tab_stop="false"
name="main_view"
width="1024">
-
- <!-- At the moment layout_stack is not an LLUICtrl,
- but Tab requires focus_root to function and focus_root
- functionality is implemented in LLUICtrl -->
- <panel follows="all"
- height="768"
- name="menu_tab_wrapper"
- mouse_opaque="false"
- focus_root="true"
- top="0">
<layout_stack border_size="0"
follows="all"
mouse_opaque="false"
@@ -25,31 +15,35 @@
name="menu_stack"
orientation="vertical"
top="0">
+ <!-- Menu, nav bar and status bar need common focus_root-->
<layout_panel mouse_opaque="true"
follows="left|right|top"
name="status_bar_container"
+ focus_root="true"
height="19"
left="0"
top="0"
width="1024"
auto_resize="false"
- default_tab_group="1"
visible="true">
<view mouse_opaque="false"
- follows="all"
+ follows="top|left|right"
name="menu_bar_holder"
+ tab_group="1"
left="0"
top="0"
width="1024"
- tab_group="1"
height="19"/>
+ <view mouse_opaque="false"
+ follows="top|left|right"
+ name="nav_bar_container"
+ tab_group="3"
+ left="0"
+ top="19"
+ width="1024"
+ height="34"
+ visible="false"/>
</layout_panel>
- <layout_panel auto_resize="false"
- height="34"
- mouse_opaque="false"
- name="nav_bar_container"
- width="1024"
- visible="false"/>
<layout_panel auto_resize="true"
follows="all"
height="500"
@@ -109,7 +103,6 @@
tab_stop="false"/>
</layout_panel>
</layout_stack>
- </panel> <!--menu_tab_wrapper-->
<panel top="0"
follows="all"
diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml
index 998c7a08d1..4369119bc9 100644
--- a/indra/newview/skins/default/xui/en/notifications.xml
+++ b/indra/newview/skins/default/xui/en/notifications.xml
@@ -9689,7 +9689,7 @@ Do you wish to continue?
The selected object affects the navmesh. Changing it to a Flexible Path will remove it from the navmesh.
<tag>confirm</tag>
<usetemplate
- ignoretext="The selected object affects the navmesh. Changing it to a Flexible Path will remove it from the navmesh."
+ ignoretext="The selected object affects the navmesh. Changing it to a Flexible Path will remove it from the navmesh."
name="okcancelignore"
notext="Cancel"
yestext="OK"/>
@@ -11914,4 +11914,20 @@ Unpacking: [UNPACK_TIME]s [USIZE]KB
yestext="OK"/>
</notification>
+ <notification
+ icon="alertmodal.tga"
+ name="RiggedMeshAttachedToHUD"
+ type="alertmodal">
+ An object "[NAME]" attached to HUD point "[POINT]" contains rigged mesh.
+
+Rigged mesh objects are designed for attachment to the avatar. You will see this object but no one else will.
+
+If you want others to see this object, remove it and re-attach it to an avatar attachment point.
+ <tag>confirm</tag>
+ <usetemplate
+ ignoretext="Warn me when rigged mesh is attached to HUD point."
+ name="okignore"
+ yestext="OK"/>
+ </notification>
+
</notifications>
diff --git a/indra/newview/skins/default/xui/en/panel_preferences_sound.xml b/indra/newview/skins/default/xui/en/panel_preferences_sound.xml
index 42a34d171a..ab2e9c72f3 100644
--- a/indra/newview/skins/default/xui/en/panel_preferences_sound.xml
+++ b/indra/newview/skins/default/xui/en/panel_preferences_sound.xml
@@ -322,154 +322,161 @@
name="enable_voice_check"
width="110"/>
<!-- -->
- <text
- follows="left|top"
- layout="topleft"
- height="15"
- left="0"
- top_pad="3"
- width="120"
- halign="right"
- name="media_autoplay_label">
- Media auto-play
- </text>
- <combo_box
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ layout="topleft"
+ left="23"
+ top_delta="22"
+ name="Listen media from"
+ height="15"
+ word_wrap="true"
+ width="112">
+ Hear media and sounds from:
+ </text>
+ <radio_group
+ control_name="MediaSoundsEarLocation"
+ follows="left|top"
+ top_delta="-6"
+ layout="topleft"
+ left_pad="20"
+ width="360"
+ height="40"
+ name="media_ear_location">
+ <radio_item
+ height="19"
+ label="Camera position"
+ follows="left|top"
+ layout="topleft"
+ name="0"
+ width="200"/>
+ <radio_item
+ height="19"
+ follows="left|top"
+ label="Avatar position"
+ layout="topleft"
+ left_delta="0"
+ name="1"
+ top_delta ="18"
+ width="200" />
+ </radio_group>
+ <check_box
+ name="media_show_on_others_btn"
+ control_name="MediaShowOnOthers"
+ value="true"
+ follows="left|top"
+ layout="topleft"
+ height="15"
+ top_pad="8"
+ tool_tip="Uncheck this to hide media attached to other avatars nearby"
+ label="Play media attached to other avatars"
+ left="20"
+ width="230"/>
+ <text
+ follows="left|top"
+ layout="topleft"
+ height="15"
+ left="23"
+ top_pad="8"
+ width="120"
+ name="media_autoplay_label">
+ Auto-play media
+ </text>
+ <combo_box
control_name="ParcelMediaAutoPlayEnable"
enabled_control="AudioStreamingMedia"
follows="left|top"
layout="topleft"
height="23"
- left_pad="7"
+ left_pad="-15"
top_delta="-4"
name="media_auto_play_combo"
- width="100">
- <item
- label="No"
- name="autoplay_disabled"
- value="0"/>
- <item
- label="Yes"
- name="autoplay_enabled"
- value="1"/>
- <item
- label="Ask"
- name="autoplay_ask"
- value="2"/>
- </combo_box>
- <check_box
- name="media_show_on_others_btn"
- control_name="MediaShowOnOthers"
- value="true"
- follows="left|bottom|right"
- height="15"
- tool_tip="Uncheck this to hide media attached to other avatars nearby"
- label="Play media attached to other avatars"
- left="25"
- width="230"/>
- <check_box
- name="gesture_audio_play_btn"
- control_name="EnableGestureSounds"
- disabled_control="MuteAudio"
- value="true"
- follows="left|bottom|right"
- height="15"
- tool_tip="Check this to hear sounds from gestures"
- label="Play sounds from gestures"
- top_pad="1"
- left="25"/>
- <text
- type="string"
- length="1"
- follows="left|top"
- height="20"
- layout="topleft"
- left="25"
- name="voice_chat_settings"
- width="200"
- top_pad="16">
- Voice Chat Settings
- </text>
- <text
- type="string"
- length="1"
- follows="left|top"
- layout="topleft"
- left="46"
- top_delta="16"
- name="Listen from"
- width="112">
- Listen from:
- </text>
- <icon
- follows="left|top"
- height="18"
- image_name="Cam_FreeCam_Off"
- layout="topleft"
- name="camera_icon"
- mouse_opaque="false"
- visible="true"
- width="18"
- left_pad="-4"
- top_delta="-5"/>
- <icon
- follows="left|top"
- height="18"
- image_name="Move_Walk_Off"
- layout="topleft"
- left_pad="170"
- name="avatar_icon"
- mouse_opaque="false"
- visible="true"
- width="18"
- top_delta="0" />
- <radio_group
- enabled_control="EnableVoiceChat"
- control_name="VoiceEarLocation"
- follows="left|top"
- layout="topleft"
- left_delta="-168"
- width="360"
- height="20"
- name="ear_location">
- <radio_item
- height="19"
- label="Camera position"
- follows="left|top"
- layout="topleft"
- name="0"
- width="200"/>
- <radio_item
- height="19"
- follows="left|top"
- label="Avatar position"
- layout="topleft"
- left_pad="-16"
- name="1"
- top_delta ="0"
- width="200" />
- </radio_group>
+ width="115">
+ <item
+ label="Never"
+ name="autoplay_disabled"
+ value="0"/>
+ <item
+ label="Always"
+ name="autoplay_enabled"
+ value="1"/>
+ <item
+ label="Ask"
+ name="autoplay_ask"
+ value="2"/>
+ </combo_box>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ layout="topleft"
+ left="23"
+ top_delta="30"
+ name="Listen from"
+ width="112">
+ Hear voice from:
+ </text>
+ <radio_group
+ enabled_control="EnableVoiceChat"
+ control_name="VoiceEarLocation"
+ follows="left|top"
+ layout="topleft"
+ left_pad="20"
+ top_delta="-6"
+ width="360"
+ height="40"
+ name="ear_location">
+ <radio_item
+ height="19"
+ label="Camera position"
+ follows="left|top"
+ layout="topleft"
+ name="0"
+ width="200"/>
+ <radio_item
+ height="19"
+ follows="left|top"
+ label="Avatar position"
+ layout="topleft"
+ left_delta="0"
+ name="1"
+ top_delta ="18"
+ width="200" />
+ </radio_group>
<check_box
control_name="LipSyncEnabled"
follows="left|top"
height="15"
label="Move avatar lips when speaking"
layout="topleft"
- left="44"
+ left="20"
name="enable_lip_sync"
- top_pad="5"
+ top_pad="10"
width="237"/>
- <check_box
- follows="top|left"
- enabled_control="EnableVoiceChat"
- control_name="PushToTalkToggle"
- height="15"
- label="Toggle speak on/off when I press button in toolbar"
- layout="topleft"
- left="44"
- name="push_to_talk_toggle_check"
- width="237"
- tool_tip="When in toggle mode, press and release the trigger key ONCE to switch your microphone on or off. When not in toggle mode, the microphone broadcasts your voice only while the trigger is being held down."
- top_pad="3"/>
+ <check_box
+ follows="top|left"
+ enabled_control="EnableVoiceChat"
+ control_name="PushToTalkToggle"
+ height="15"
+ label="Toggle speak on/off when I press button in toolbar"
+ layout="topleft"
+ left="20"
+ name="push_to_talk_toggle_check"
+ width="237"
+ tool_tip="When in toggle mode, press and release the trigger key ONCE to switch your microphone on or off. When not in toggle mode, the microphone broadcasts your voice only while the trigger is being held down."
+ top_pad="5"/>
+ <check_box
+ name="gesture_audio_play_btn"
+ control_name="EnableGestureSounds"
+ disabled_control="MuteAudio"
+ value="true"
+ follows="left|bottom|right"
+ height="15"
+ tool_tip="Check this to hear sounds from gestures"
+ label="Play sounds from gestures"
+ top_pad="5"
+ left="20"/>
<button
control_name="ShowDeviceSettings"
follows="left|top"
@@ -478,7 +485,7 @@
label="Voice Input/Output devices"
layout="topleft"
left="20"
- top_pad="6"
+ top_pad="9"
name="device_settings_btn"
width="230">
</button>
diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml
index 8c2db9bde3..46fcc1d8b9 100644
--- a/indra/newview/skins/default/xui/en/strings.xml
+++ b/indra/newview/skins/default/xui/en/strings.xml
@@ -4294,6 +4294,10 @@ name="Command_360_Capture_Tooltip">Capture a 360 equirectangular image</string>
<string name="Mav_Details_MAV_CONFIRMATION_DATA_MISMATCH">
The physics shape contains bad confirmation data. Try to correct the physics model.
</string>
+ <!-- MAV_BLOCK_MISSING means server didn't get and couldn't substitute physics_convex, high_lod or BoundingVerts-->
+ <string name="Mav_Details_MAV_BLOCK_MISSING">
+ Missing data. Make sure high lod is present and valid. Set the physics model if not set.
+ </string>
<string name="Mav_Details_MAV_UNKNOWN_VERSION">
The physics shape does not have correct version. Set the correct version for the physics model.
</string>