Merge branch 'master' of https://github.com/FirestormViewer/phoenix-firestorm
commit
096aef2a72
|
|
@ -0,0 +1,11 @@
|
|||
# To get started with Dependabot version updates, you'll need to specify which
|
||||
# package ecosystems to update and where the package manifests are located.
|
||||
# Please see the documentation for all configuration options:
|
||||
# https://docs.github.com/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file
|
||||
|
||||
version: 2
|
||||
updates:
|
||||
- package-ecosystem: "github-actions" # See documentation for possible values
|
||||
directory: "/" # Location of package manifests
|
||||
schedule:
|
||||
interval: "monthly"
|
||||
|
|
@ -73,7 +73,7 @@ jobs:
|
|||
uses: actions/checkout@v4
|
||||
with:
|
||||
repository: secondlife/build-variables
|
||||
ref: viewer
|
||||
ref: master
|
||||
path: .build-variables
|
||||
|
||||
- name: Checkout master-message-template
|
||||
|
|
@ -224,7 +224,7 @@ jobs:
|
|||
|
||||
- name: Upload executable
|
||||
if: matrix.configuration != 'ReleaseOS' && steps.build.outputs.viewer_app
|
||||
uses: actions/upload-artifact@v3
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: "${{ steps.build.outputs.artifact }}-app"
|
||||
path: |
|
||||
|
|
@ -234,7 +234,7 @@ jobs:
|
|||
# artifact for that too.
|
||||
- name: Upload symbol file
|
||||
if: matrix.configuration != 'ReleaseOS'
|
||||
uses: actions/upload-artifact@v3
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: "${{ steps.build.outputs.artifact }}-symbols"
|
||||
path: |
|
||||
|
|
@ -242,7 +242,7 @@ jobs:
|
|||
|
||||
- name: Upload metadata
|
||||
if: matrix.configuration != 'ReleaseOS'
|
||||
uses: actions/upload-artifact@v3
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: "${{ steps.build.outputs.artifact }}-metadata"
|
||||
# emitted by build.sh, possibly multiple lines
|
||||
|
|
@ -250,7 +250,7 @@ jobs:
|
|||
${{ steps.build.outputs.metadata }}
|
||||
|
||||
- name: Upload physics package
|
||||
uses: actions/upload-artifact@v3
|
||||
uses: actions/upload-artifact@v4
|
||||
# should only be set for viewer-private
|
||||
if: matrix.configuration != 'ReleaseOS' && steps.build.outputs.physicstpv
|
||||
with:
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ jobs:
|
|||
pull-requests: write
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/labeler@v4
|
||||
- uses: actions/labeler@v5
|
||||
with:
|
||||
configuration-path: .github/labeler.yaml
|
||||
repo-token: "${{ secrets.GITHUB_TOKEN }}"
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ jobs:
|
|||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-python@v4
|
||||
- uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: 3.x
|
||||
- uses: pre-commit/action@v3.0.0
|
||||
- uses: pre-commit/action@v3.0.1
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ jobs:
|
|||
stale:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/stale@v6
|
||||
- uses: actions/stale@v9
|
||||
id: stale
|
||||
with:
|
||||
stale-pr-message: This pull request is stale because it has been open 30 days with no activity. Remove stale label or comment or it will be closed in 7 days
|
||||
|
|
|
|||
|
|
@ -142,9 +142,11 @@
|
|||
<key>archive</key>
|
||||
<map>
|
||||
<key>hash</key>
|
||||
<string>81fe1e927e4fe3c5e5f15ce6219ca883</string>
|
||||
<string>691fef2ddd57d7b6c26e87fc82d9ace3f54e078c</string>
|
||||
<key>hash_algorithm</key>
|
||||
<string>sha1</string>
|
||||
<key>url</key>
|
||||
<string>https://3p.firestormviewer.org/fltk-1.3.5.202282121-linux64-202282121.tar.bz2</string>
|
||||
<string>https://github.com/secondlife/3p-fltk/releases/download/v1.3.9-r1/fltk-1.3.9.8556992788-linux64-8556992788.tar.zst</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>linux</string>
|
||||
|
|
@ -1177,34 +1179,6 @@
|
|||
<key>description</key>
|
||||
<string>a library for writing and using C++ mock classes</string>
|
||||
</map>
|
||||
<key>gstreamer</key>
|
||||
<map>
|
||||
<key>platforms</key>
|
||||
<map>
|
||||
<key>linux64</key>
|
||||
<map>
|
||||
<key>archive</key>
|
||||
<map>
|
||||
<key>hash</key>
|
||||
<string>86a358f1b5a2c2baf68444b2bfc5bb32</string>
|
||||
<key>url</key>
|
||||
<string>https://3p.firestormviewer.org/gstreamer-0.10.6.180841551-linux64-180841551.tar.bz2</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>linux64</string>
|
||||
</map>
|
||||
</map>
|
||||
<key>license</key>
|
||||
<string>LGPL</string>
|
||||
<key>license_file</key>
|
||||
<string>LICENSES/gstreamer.txt</string>
|
||||
<key>copyright</key>
|
||||
<string>Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/></string>
|
||||
<key>version</key>
|
||||
<string>0.10.6.314267</string>
|
||||
<key>name</key>
|
||||
<string>gstreamer</string>
|
||||
</map>
|
||||
<key>havok-source</key>
|
||||
<map>
|
||||
<key>platforms</key>
|
||||
|
|
@ -1302,11 +1276,11 @@
|
|||
<key>archive</key>
|
||||
<map>
|
||||
<key>hash</key>
|
||||
<string>f5e5be3af96f1eb0842219a94765c04aa9c561c5</string>
|
||||
<string>bdd74e2a02c7b78fded9222140d197da4af9904e</string>
|
||||
<key>hash_algorithm</key>
|
||||
<string>sha1</string>
|
||||
<key>url</key>
|
||||
<string>https://3p.firestormviewer.org/icu4c-4.8.1-linux64-240621048.tar.zst</string>
|
||||
<string>https://github.com/secondlife/3p-icu4c/releases/download/v4.8.1-8bff176/icu4c-4.8.1-linux64-8512575562.tar.zst</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>linux64</string>
|
||||
|
|
@ -1856,11 +1830,11 @@
|
|||
<key>archive</key>
|
||||
<map>
|
||||
<key>hash</key>
|
||||
<string>e50ea94bbaa4ff41bf53b84b7192df1a694c5337</string>
|
||||
<string>3a3e14563cd5fc019c3f139b82aa46ec79847709</string>
|
||||
<key>hash_algorithm</key>
|
||||
<string>sha1</string>
|
||||
<key>url</key>
|
||||
<string>https://github.com/secondlife/llca/releases/download/v202310121525.0-d22bd98/llca-202310121530.0-common-d22bd98.tar.zst</string>
|
||||
<string>https://github.com/secondlife/llca/releases/download/v202312051403.17-0f5d9c3/llca-202312051404.0-common-0f5d9c3.tar.zst</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>common</string>
|
||||
|
|
@ -1874,7 +1848,7 @@
|
|||
<string>Copyright (c) 2016, Linden Research, Inc.; data provided by the Mozilla NSS Project.
|
||||
</string>
|
||||
<key>version</key>
|
||||
<string>202310121530.0</string>
|
||||
<string>202312051404.0</string>
|
||||
<key>name</key>
|
||||
<string>llca</string>
|
||||
</map>
|
||||
|
|
|
|||
3
build.sh
3
build.sh
|
|
@ -112,7 +112,8 @@ installer_CYGWIN()
|
|||
fi
|
||||
}
|
||||
|
||||
[[ -n "$GITHUB_OUTPUT" ]] || fatal "Need to export GITHUB_OUTPUT"
|
||||
# if someone wants to run build.sh outside the GitHub environment
|
||||
[[ -n "$GITHUB_OUTPUT" ]] || export GITHUB_OUTPUT='/dev/null'
|
||||
# The following is based on the Warning for GitHub multiline output strings:
|
||||
# https://docs.github.com/en/actions/using-workflows/workflow-commands-for-github-actions#multiline-strings
|
||||
EOF=$(dd if=/dev/urandom bs=15 count=1 status=none | base64)
|
||||
|
|
|
|||
|
|
@ -297,6 +297,7 @@ Beq Janus
|
|||
SL-18637
|
||||
SL-19317
|
||||
SL-19660
|
||||
SL-20610
|
||||
Beth Walcher
|
||||
Bezilon Kasei
|
||||
Biancaluce Robbiani
|
||||
|
|
|
|||
|
|
@ -119,11 +119,11 @@ public:
|
|||
* ClassicCallback must not itself be copied or moved! Once you've passed
|
||||
* get_userdata() to some API, this object MUST remain at that address.
|
||||
*/
|
||||
// However, we can't yet count on C++17 Class Template Argument Deduction,
|
||||
// which means makeClassicCallback() is still useful, which means we MUST
|
||||
// be able to return one to construct into caller's instance (move ctor).
|
||||
// Possible defense: bool 'referenced' data member set by get_userdata(),
|
||||
// with an llassert_always(! referenced) check in the move constructor.
|
||||
// However, makeClassicCallback() is useful for deducing the CALLABLE
|
||||
// type, which means we MUST be able to return one to construct into
|
||||
// caller's instance (move ctor). Possible defense: bool 'referenced' data
|
||||
// member set by get_userdata(), with an llassert_always(! referenced)
|
||||
// check in the move constructor.
|
||||
ClassicCallback(ClassicCallback const&) = delete;
|
||||
ClassicCallback(ClassicCallback&&) = default; // delete;
|
||||
ClassicCallback& operator=(ClassicCallback const&) = delete;
|
||||
|
|
|
|||
|
|
@ -104,7 +104,6 @@ BOOL LLApp::sLogInSignal = FALSE;
|
|||
// Keeps track of application status
|
||||
LLScalarCond<LLApp::EAppStatus> LLApp::sStatus{LLApp::APP_STATUS_STOPPED};
|
||||
LLAppErrorHandler LLApp::sErrorHandler = NULL;
|
||||
BOOL LLApp::sErrorThreadRunning = FALSE;
|
||||
|
||||
|
||||
LLApp::LLApp()
|
||||
|
|
@ -793,13 +792,8 @@ void default_unix_signal_handler(int signum, siginfo_t *info, void *)
|
|||
return;
|
||||
}
|
||||
|
||||
// Flag status to ERROR, so thread_error does its work.
|
||||
// Flag status to ERROR
|
||||
LLApp::setError();
|
||||
// Block in the signal handler until somebody says that we're done.
|
||||
while (LLApp::sErrorThreadRunning && !LLApp::isStopped())
|
||||
{
|
||||
ms_sleep(10);
|
||||
}
|
||||
|
||||
if (LLApp::sLogInSignal)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -291,7 +291,6 @@ protected:
|
|||
|
||||
static void setStatus(EAppStatus status); // Use this to change the application status.
|
||||
static LLScalarCond<EAppStatus> sStatus; // Reflects current application status
|
||||
static BOOL sErrorThreadRunning; // Set while the error thread is running
|
||||
static BOOL sDisableCrashlogger; // Let the OS handle crashes for us.
|
||||
std::wstring mCrashReportPipeStr; //Name of pipe to use for crash reporting.
|
||||
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@ std::string LLBase64::encode(const U8* input, size_t input_size)
|
|||
&& input_size > 0)
|
||||
{
|
||||
// Yes, it returns int.
|
||||
int b64_buffer_length = apr_base64_encode_len(narrow(input_size));
|
||||
int b64_buffer_length = apr_base64_encode_len(narrow<size_t>(input_size));
|
||||
char* b64_buffer = new char[b64_buffer_length];
|
||||
|
||||
// This is faster than apr_base64_encode() if you know
|
||||
|
|
@ -52,7 +52,7 @@ std::string LLBase64::encode(const U8* input, size_t input_size)
|
|||
b64_buffer_length = apr_base64_encode_binary(
|
||||
b64_buffer,
|
||||
input,
|
||||
narrow(input_size));
|
||||
narrow<size_t>(input_size));
|
||||
output.assign(b64_buffer);
|
||||
delete[] b64_buffer;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -123,7 +123,7 @@ LLCoros::LLCoros():
|
|||
// Previously we used
|
||||
// boost::context::guarded_stack_allocator::default_stacksize();
|
||||
// empirically this is insufficient.
|
||||
mStackSize(768*1024),
|
||||
mStackSize(900*1024),
|
||||
// mCurrent does NOT own the current CoroData instance -- it simply
|
||||
// points to it. So initialize it with a no-op deleter.
|
||||
mCurrent{ [](CoroData*){} }
|
||||
|
|
|
|||
|
|
@ -87,11 +87,10 @@ protected:
|
|||
}
|
||||
void addEntry(Index index, Entry *entry)
|
||||
{
|
||||
if (lookup(index))
|
||||
if (!this->emplace(index, entry).second)
|
||||
{
|
||||
LL_ERRS() << "Dictionary entry already added (attempted to add duplicate entry)" << LL_ENDL;
|
||||
}
|
||||
(*this)[index] = entry;
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -46,33 +46,32 @@
|
|||
template <class Type> class LLPointer
|
||||
{
|
||||
public:
|
||||
|
||||
LLPointer() :
|
||||
LLPointer() :
|
||||
mPointer(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
LLPointer(Type* ptr) :
|
||||
LLPointer(Type* ptr) :
|
||||
mPointer(ptr)
|
||||
{
|
||||
ref();
|
||||
}
|
||||
|
||||
LLPointer(const LLPointer<Type>& ptr) :
|
||||
LLPointer(const LLPointer<Type>& ptr) :
|
||||
mPointer(ptr.mPointer)
|
||||
{
|
||||
ref();
|
||||
}
|
||||
|
||||
// support conversion up the type hierarchy. See Item 45 in Effective C++, 3rd Ed.
|
||||
// Support conversion up the type hierarchy. See Item 45 in Effective C++, 3rd Ed.
|
||||
template<typename Subclass>
|
||||
LLPointer(const LLPointer<Subclass>& ptr) :
|
||||
LLPointer(const LLPointer<Subclass>& ptr) :
|
||||
mPointer(ptr.get())
|
||||
{
|
||||
ref();
|
||||
}
|
||||
|
||||
~LLPointer()
|
||||
~LLPointer()
|
||||
{
|
||||
unref();
|
||||
}
|
||||
|
|
@ -83,39 +82,39 @@ public:
|
|||
const Type& operator*() const { return *mPointer; }
|
||||
Type& operator*() { return *mPointer; }
|
||||
|
||||
operator BOOL() const { return (mPointer != NULL); }
|
||||
operator bool() const { return (mPointer != NULL); }
|
||||
operator BOOL() const { return (mPointer != NULL); }
|
||||
operator bool() const { return (mPointer != NULL); }
|
||||
bool operator!() const { return (mPointer == NULL); }
|
||||
bool isNull() const { return (mPointer == NULL); }
|
||||
bool notNull() const { return (mPointer != NULL); }
|
||||
|
||||
operator Type*() const { return mPointer; }
|
||||
bool operator !=(Type* ptr) const { return (mPointer != ptr); }
|
||||
bool operator ==(Type* ptr) const { return (mPointer == ptr); }
|
||||
bool operator ==(const LLPointer<Type>& ptr) const { return (mPointer == ptr.mPointer); }
|
||||
bool operator < (const LLPointer<Type>& ptr) const { return (mPointer < ptr.mPointer); }
|
||||
bool operator > (const LLPointer<Type>& ptr) const { return (mPointer > ptr.mPointer); }
|
||||
operator Type*() const { return mPointer; }
|
||||
bool operator !=(Type* ptr) const { return (mPointer != ptr); }
|
||||
bool operator ==(Type* ptr) const { return (mPointer == ptr); }
|
||||
bool operator ==(const LLPointer<Type>& ptr) const { return (mPointer == ptr.mPointer); }
|
||||
bool operator < (const LLPointer<Type>& ptr) const { return (mPointer < ptr.mPointer); }
|
||||
bool operator > (const LLPointer<Type>& ptr) const { return (mPointer > ptr.mPointer); }
|
||||
|
||||
LLPointer<Type>& operator =(Type* ptr)
|
||||
{
|
||||
LLPointer<Type>& operator =(Type* ptr)
|
||||
{
|
||||
assign(ptr);
|
||||
return *this;
|
||||
return *this;
|
||||
}
|
||||
|
||||
LLPointer<Type>& operator =(const LLPointer<Type>& ptr)
|
||||
{
|
||||
LLPointer<Type>& operator =(const LLPointer<Type>& ptr)
|
||||
{
|
||||
assign(ptr);
|
||||
return *this;
|
||||
return *this;
|
||||
}
|
||||
|
||||
// support assignment up the type hierarchy. See Item 45 in Effective C++, 3rd Ed.
|
||||
template<typename Subclass>
|
||||
LLPointer<Type>& operator =(const LLPointer<Subclass>& ptr)
|
||||
{
|
||||
LLPointer<Type>& operator =(const LLPointer<Subclass>& ptr)
|
||||
{
|
||||
assign(ptr.get());
|
||||
return *this;
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
// Just exchange the pointers, which will not change the reference counts.
|
||||
static void swap(LLPointer<Type>& a, LLPointer<Type>& b)
|
||||
{
|
||||
|
|
@ -129,16 +128,6 @@ protected:
|
|||
void ref();
|
||||
void unref();
|
||||
#else
|
||||
|
||||
void assign(const LLPointer<Type>& ptr)
|
||||
{
|
||||
if( mPointer != ptr.mPointer )
|
||||
{
|
||||
unref();
|
||||
mPointer = ptr.mPointer;
|
||||
ref();
|
||||
}
|
||||
}
|
||||
void ref()
|
||||
{
|
||||
if (mPointer)
|
||||
|
|
@ -161,7 +150,18 @@ protected:
|
|||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif // LL_LIBRARY_INCLUDE
|
||||
|
||||
void assign(const LLPointer<Type>& ptr)
|
||||
{
|
||||
if (mPointer != ptr.mPointer)
|
||||
{
|
||||
unref();
|
||||
mPointer = ptr.mPointer;
|
||||
ref();
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
Type* mPointer;
|
||||
};
|
||||
|
|
@ -169,18 +169,18 @@ protected:
|
|||
template <class Type> class LLConstPointer
|
||||
{
|
||||
public:
|
||||
LLConstPointer() :
|
||||
LLConstPointer() :
|
||||
mPointer(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
LLConstPointer(const Type* ptr) :
|
||||
LLConstPointer(const Type* ptr) :
|
||||
mPointer(ptr)
|
||||
{
|
||||
ref();
|
||||
}
|
||||
|
||||
LLConstPointer(const LLConstPointer<Type>& ptr) :
|
||||
LLConstPointer(const LLConstPointer<Type>& ptr) :
|
||||
mPointer(ptr.mPointer)
|
||||
{
|
||||
ref();
|
||||
|
|
@ -188,7 +188,7 @@ public:
|
|||
|
||||
// support conversion up the type hierarchy. See Item 45 in Effective C++, 3rd Ed.
|
||||
template<typename Subclass>
|
||||
LLConstPointer(const LLConstPointer<Subclass>& ptr) :
|
||||
LLConstPointer(const LLConstPointer<Subclass>& ptr) :
|
||||
mPointer(ptr.get())
|
||||
{
|
||||
ref();
|
||||
|
|
@ -203,55 +203,55 @@ public:
|
|||
const Type* operator->() const { return mPointer; }
|
||||
const Type& operator*() const { return *mPointer; }
|
||||
|
||||
operator BOOL() const { return (mPointer != NULL); }
|
||||
operator bool() const { return (mPointer != NULL); }
|
||||
operator BOOL() const { return (mPointer != NULL); }
|
||||
operator bool() const { return (mPointer != NULL); }
|
||||
bool operator!() const { return (mPointer == NULL); }
|
||||
bool isNull() const { return (mPointer == NULL); }
|
||||
bool notNull() const { return (mPointer != NULL); }
|
||||
|
||||
operator const Type*() const { return mPointer; }
|
||||
bool operator !=(const Type* ptr) const { return (mPointer != ptr); }
|
||||
bool operator ==(const Type* ptr) const { return (mPointer == ptr); }
|
||||
bool operator ==(const LLConstPointer<Type>& ptr) const { return (mPointer == ptr.mPointer); }
|
||||
bool operator < (const LLConstPointer<Type>& ptr) const { return (mPointer < ptr.mPointer); }
|
||||
bool operator > (const LLConstPointer<Type>& ptr) const { return (mPointer > ptr.mPointer); }
|
||||
operator const Type*() const { return mPointer; }
|
||||
bool operator !=(const Type* ptr) const { return (mPointer != ptr); }
|
||||
bool operator ==(const Type* ptr) const { return (mPointer == ptr); }
|
||||
bool operator ==(const LLConstPointer<Type>& ptr) const { return (mPointer == ptr.mPointer); }
|
||||
bool operator < (const LLConstPointer<Type>& ptr) const { return (mPointer < ptr.mPointer); }
|
||||
bool operator > (const LLConstPointer<Type>& ptr) const { return (mPointer > ptr.mPointer); }
|
||||
|
||||
LLConstPointer<Type>& operator =(const Type* ptr)
|
||||
LLConstPointer<Type>& operator =(const Type* ptr)
|
||||
{
|
||||
if( mPointer != ptr )
|
||||
{
|
||||
unref();
|
||||
mPointer = ptr;
|
||||
unref();
|
||||
mPointer = ptr;
|
||||
ref();
|
||||
}
|
||||
|
||||
return *this;
|
||||
return *this;
|
||||
}
|
||||
|
||||
LLConstPointer<Type>& operator =(const LLConstPointer<Type>& ptr)
|
||||
{
|
||||
LLConstPointer<Type>& operator =(const LLConstPointer<Type>& ptr)
|
||||
{
|
||||
if( mPointer != ptr.mPointer )
|
||||
{
|
||||
unref();
|
||||
unref();
|
||||
mPointer = ptr.mPointer;
|
||||
ref();
|
||||
}
|
||||
return *this;
|
||||
return *this;
|
||||
}
|
||||
|
||||
// support assignment up the type hierarchy. See Item 45 in Effective C++, 3rd Ed.
|
||||
template<typename Subclass>
|
||||
LLConstPointer<Type>& operator =(const LLConstPointer<Subclass>& ptr)
|
||||
{
|
||||
LLConstPointer<Type>& operator =(const LLConstPointer<Subclass>& ptr)
|
||||
{
|
||||
if( mPointer != ptr.get() )
|
||||
{
|
||||
unref();
|
||||
unref();
|
||||
mPointer = ptr.get();
|
||||
ref();
|
||||
}
|
||||
return *this;
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
// Just exchange the pointers, which will not change the reference counts.
|
||||
static void swap(LLConstPointer<Type>& a, LLConstPointer<Type>& b)
|
||||
{
|
||||
|
|
@ -262,11 +262,11 @@ public:
|
|||
|
||||
protected:
|
||||
#ifdef LL_LIBRARY_INCLUDE
|
||||
void ref();
|
||||
void ref();
|
||||
void unref();
|
||||
#else
|
||||
void ref()
|
||||
{
|
||||
#else // LL_LIBRARY_INCLUDE
|
||||
void ref()
|
||||
{
|
||||
if (mPointer)
|
||||
{
|
||||
mPointer->ref();
|
||||
|
|
@ -277,9 +277,9 @@ protected:
|
|||
{
|
||||
if (mPointer)
|
||||
{
|
||||
const Type *tempp = mPointer;
|
||||
const Type *temp = mPointer;
|
||||
mPointer = NULL;
|
||||
tempp->unref();
|
||||
temp->unref();
|
||||
if (mPointer != NULL)
|
||||
{
|
||||
LL_WARNS() << "Unreference did assignment to non-NULL because of destructor" << LL_ENDL;
|
||||
|
|
@ -287,7 +287,8 @@ protected:
|
|||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif // LL_LIBRARY_INCLUDE
|
||||
|
||||
protected:
|
||||
const Type* mPointer;
|
||||
};
|
||||
|
|
@ -297,13 +298,13 @@ class LLCopyOnWritePointer : public LLPointer<Type>
|
|||
{
|
||||
public:
|
||||
typedef LLCopyOnWritePointer<Type> self_t;
|
||||
typedef LLPointer<Type> pointer_t;
|
||||
|
||||
LLCopyOnWritePointer()
|
||||
typedef LLPointer<Type> pointer_t;
|
||||
|
||||
LLCopyOnWritePointer()
|
||||
: mStayUnique(false)
|
||||
{}
|
||||
|
||||
LLCopyOnWritePointer(Type* ptr)
|
||||
LLCopyOnWritePointer(Type* ptr)
|
||||
: LLPointer<Type>(ptr),
|
||||
mStayUnique(false)
|
||||
{}
|
||||
|
|
|
|||
|
|
@ -58,7 +58,9 @@
|
|||
* to restore uniform distribution.
|
||||
*/
|
||||
|
||||
static LLRandLagFib2281 gRandomGenerator(LLUUID::getRandomSeed());
|
||||
// gRandomGenerator is a stateful static object, which is therefore not
|
||||
// inherently thread-safe.
|
||||
static thread_local LLRandLagFib2281 gRandomGenerator(LLUUID::getRandomSeed());
|
||||
|
||||
// no default implementation, only specific F64 and F32 specializations
|
||||
template <typename REAL>
|
||||
|
|
@ -71,7 +73,7 @@ inline F64 ll_internal_random<F64>()
|
|||
// CPUs (or at least multi-threaded processes) seem to
|
||||
// occasionally give an obviously incorrect random number -- like
|
||||
// 5^15 or something. Sooooo, clamp it as described above.
|
||||
F64 rv = gRandomGenerator();
|
||||
F64 rv{ gRandomGenerator() };
|
||||
if(!((rv >= 0.0) && (rv < 1.0))) return fmod(rv, 1.0);
|
||||
return rv;
|
||||
}
|
||||
|
|
@ -79,7 +81,13 @@ inline F64 ll_internal_random<F64>()
|
|||
template <>
|
||||
inline F32 ll_internal_random<F32>()
|
||||
{
|
||||
return F32(ll_internal_random<F64>());
|
||||
// *HACK: clamp the result as described above.
|
||||
// Per Monty, it's important to clamp using the correct fmodf() rather
|
||||
// than expanding to F64 for fmod() and then truncating back to F32. Prior
|
||||
// to this change, we were getting sporadic ll_frand() == 1.0 results.
|
||||
F32 rv{ narrow<F32>(gRandomGenerator()) };
|
||||
if(!((rv >= 0.0f) && (rv < 1.0f))) return fmodf(rv, 1.0f);
|
||||
return rv;
|
||||
}
|
||||
|
||||
/*------------------------------ F64 aliases -------------------------------*/
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@
|
|||
#include "llerror.h"
|
||||
|
||||
// maximum reference count before sounding memory leak alarm
|
||||
const S32 gMaxRefCount = S32_MAX;
|
||||
const S32 gMaxRefCount = LL_REFCOUNT_FREE;
|
||||
|
||||
LLRefCount::LLRefCount(const LLRefCount& other)
|
||||
: mRef(0)
|
||||
|
|
@ -49,7 +49,7 @@ LLRefCount::LLRefCount() :
|
|||
}
|
||||
|
||||
LLRefCount::~LLRefCount()
|
||||
{
|
||||
{
|
||||
if (mRef != LL_REFCOUNT_FREE && mRef != 0)
|
||||
{
|
||||
LL_ERRS() << "deleting non-zero reference" << LL_ENDL;
|
||||
|
|
|
|||
|
|
@ -51,24 +51,20 @@ protected:
|
|||
public:
|
||||
LLRefCount();
|
||||
|
||||
inline void validateRefCount() const
|
||||
{
|
||||
llassert(mRef > 0); // ref count below 0, likely corrupted
|
||||
llassert(mRef < gMaxRefCount); // ref count excessive, likely memory leak
|
||||
}
|
||||
|
||||
inline void ref() const
|
||||
{
|
||||
mRef++;
|
||||
validateRefCount();
|
||||
}
|
||||
{
|
||||
llassert(mRef != LL_REFCOUNT_FREE); // object is deleted
|
||||
mRef++;
|
||||
llassert(mRef < gMaxRefCount); // ref count excessive, likely memory leak
|
||||
}
|
||||
|
||||
inline S32 unref() const
|
||||
{
|
||||
validateRefCount();
|
||||
llassert(mRef != LL_REFCOUNT_FREE); // object is deleted
|
||||
llassert(mRef > 0); // ref count below 1, likely corrupted
|
||||
if (0 == --mRef)
|
||||
{
|
||||
mRef = LL_REFCOUNT_FREE; // set to nonsense yet recognizable value to aid in debugging
|
||||
mRef = LL_REFCOUNT_FREE; // set to nonsense yet recognizable value to aid in debugging
|
||||
delete this;
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -82,8 +78,8 @@ public:
|
|||
return mRef;
|
||||
}
|
||||
|
||||
private:
|
||||
mutable S32 mRef;
|
||||
private:
|
||||
mutable S32 mRef;
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -106,7 +102,7 @@ protected:
|
|||
public:
|
||||
LLThreadSafeRefCount();
|
||||
LLThreadSafeRefCount(const LLThreadSafeRefCount&);
|
||||
LLThreadSafeRefCount& operator=(const LLThreadSafeRefCount& ref)
|
||||
LLThreadSafeRefCount& operator=(const LLThreadSafeRefCount& ref)
|
||||
{
|
||||
mRef = 0;
|
||||
return *this;
|
||||
|
|
@ -114,8 +110,8 @@ public:
|
|||
|
||||
void ref()
|
||||
{
|
||||
mRef++;
|
||||
}
|
||||
mRef++;
|
||||
}
|
||||
|
||||
void unref()
|
||||
{
|
||||
|
|
@ -136,36 +132,36 @@ public:
|
|||
return currentVal;
|
||||
}
|
||||
|
||||
private:
|
||||
LLAtomicS32 mRef;
|
||||
private:
|
||||
LLAtomicS32 mRef;
|
||||
};
|
||||
|
||||
/**
|
||||
* intrusive pointer support for LLThreadSafeRefCount
|
||||
* this allows you to use boost::intrusive_ptr with any LLThreadSafeRefCount-derived type
|
||||
*/
|
||||
inline void intrusive_ptr_add_ref(LLThreadSafeRefCount* p)
|
||||
inline void intrusive_ptr_add_ref(LLThreadSafeRefCount* p)
|
||||
{
|
||||
p->ref();
|
||||
}
|
||||
|
||||
inline void intrusive_ptr_release(LLThreadSafeRefCount* p)
|
||||
inline void intrusive_ptr_release(LLThreadSafeRefCount* p)
|
||||
{
|
||||
p->unref();
|
||||
p->unref();
|
||||
}
|
||||
|
||||
/**
|
||||
* intrusive pointer support
|
||||
* this allows you to use boost::intrusive_ptr with any LLRefCount-derived type
|
||||
*/
|
||||
inline void intrusive_ptr_add_ref(LLRefCount* p)
|
||||
inline void intrusive_ptr_add_ref(LLRefCount* p)
|
||||
{
|
||||
p->ref();
|
||||
}
|
||||
|
||||
inline void intrusive_ptr_release(LLRefCount* p)
|
||||
inline void intrusive_ptr_release(LLRefCount* p)
|
||||
{
|
||||
p->unref();
|
||||
p->unref();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -197,12 +197,12 @@ public:
|
|||
typename std::enable_if<std::is_integral<VALUE>::value &&
|
||||
! std::is_same<VALUE, Boolean>::value,
|
||||
bool>::type = true>
|
||||
LLSD(VALUE v): LLSD(Integer(narrow(v))) {}
|
||||
LLSD(VALUE v): LLSD(Integer(narrow<VALUE>(v))) {}
|
||||
// support construction from F32 et al.
|
||||
template <typename VALUE,
|
||||
typename std::enable_if<std::is_floating_point<VALUE>::value,
|
||||
bool>::type = true>
|
||||
LLSD(VALUE v): LLSD(Real(narrow(v))) {}
|
||||
LLSD(VALUE v): LLSD(Real(narrow<VALUE>(v))) {}
|
||||
//@}
|
||||
|
||||
/** @name Scalar Assignment */
|
||||
|
|
|
|||
|
|
@ -2174,7 +2174,7 @@ std::string zip_llsd(LLSD& data)
|
|||
|
||||
U8 out[CHUNK];
|
||||
|
||||
strm.avail_in = narrow(source.size());
|
||||
strm.avail_in = narrow<size_t>(source.size());
|
||||
strm.next_in = (U8*) source.data();
|
||||
U8* output = NULL;
|
||||
|
||||
|
|
|
|||
|
|
@ -197,12 +197,12 @@ S32 LLSDXMLFormatter::format_impl(const LLSD& data, std::ostream& ostr,
|
|||
// *FIX: memory inefficient.
|
||||
// *TODO: convert to use LLBase64
|
||||
ostr << pre << "<binary encoding=\"base64\">";
|
||||
int b64_buffer_length = apr_base64_encode_len(narrow(buffer.size()));
|
||||
int b64_buffer_length = apr_base64_encode_len(narrow<size_t>(buffer.size()));
|
||||
char* b64_buffer = new char[b64_buffer_length];
|
||||
b64_buffer_length = apr_base64_encode_binary(
|
||||
b64_buffer,
|
||||
&buffer[0],
|
||||
narrow(buffer.size()));
|
||||
narrow<size_t>(buffer.size()));
|
||||
ostr.write(b64_buffer, b64_buffer_length - 1);
|
||||
delete[] b64_buffer;
|
||||
ostr << "</binary>" << post;
|
||||
|
|
@ -415,11 +415,18 @@ S32 LLSDXMLParser::Impl::parse(std::istream& input, LLSD& data)
|
|||
if (buffer)
|
||||
{
|
||||
((char*) buffer)[count ? count - 1 : 0] = '\0';
|
||||
if (mEmitErrors)
|
||||
{
|
||||
LL_INFOS() << "LLSDXMLParser::Impl::parse: XML_STATUS_ERROR parsing:" << (char*)buffer << LL_ENDL;
|
||||
}
|
||||
}
|
||||
if (mEmitErrors)
|
||||
{
|
||||
LL_INFOS() << "LLSDXMLParser::Impl::parse: XML_STATUS_ERROR parsing:" << (char*) buffer << LL_ENDL;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (mEmitErrors)
|
||||
{
|
||||
LL_INFOS() << "LLSDXMLParser::Impl::parse: XML_STATUS_ERROR, null buffer" << LL_ENDL;
|
||||
}
|
||||
}
|
||||
data = LLSD();
|
||||
return LLSDParser::PARSE_FAILURE;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1533,9 +1533,17 @@ bool LLStringUtil::formatDatetime(std::string& replacement, std::string token,
|
|||
}
|
||||
else
|
||||
{
|
||||
#if 0
|
||||
// EXT-1565 : Zai Lynch, James Linden : 15/Oct/09
|
||||
// [BSI] Feedback: Viewer clock mentions SLT, but would prefer it to show PST/PDT
|
||||
// "slt" = Second Life Time, which is deprecated.
|
||||
// If not utc or user local time, fallback to Pacific time
|
||||
replacement = LLStringOps::getPacificDaylightTime() ? "PDT" : "PST";
|
||||
#else
|
||||
// SL-20370 : Steeltoe Linden : 29/Sep/23
|
||||
// Change "PDT" to "SLT" on menu bar
|
||||
replacement = "SLT";
|
||||
#endif
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -929,7 +929,7 @@ void LLMemoryInfo::stream(std::ostream& s) const
|
|||
// Now stream stats
|
||||
BOOST_FOREACH(const MapEntry& pair, inMap(mStatsMap))
|
||||
{
|
||||
s << pfx << std::setw(narrow(key_width+1)) << (pair.first + ':') << ' ';
|
||||
s << pfx << std::setw(narrow<size_t>(key_width+1)) << (pair.first + ':') << ' ';
|
||||
LLSD value(pair.second);
|
||||
if (value.isInteger())
|
||||
s << std::setw(12) << value.asInteger();
|
||||
|
|
|
|||
|
|
@ -113,15 +113,16 @@ LL_COMMON_API bool on_main_thread()
|
|||
return (LLThread::currentID() == main_thread());
|
||||
}
|
||||
|
||||
LL_COMMON_API void assert_main_thread()
|
||||
LL_COMMON_API bool assert_main_thread()
|
||||
{
|
||||
auto curr = LLThread::currentID();
|
||||
auto main = main_thread();
|
||||
if (curr != main)
|
||||
{
|
||||
LL_WARNS() << "Illegal execution from thread id " << curr
|
||||
<< " outside main thread " << main << LL_ENDL;
|
||||
}
|
||||
if (curr == main)
|
||||
return true;
|
||||
|
||||
LL_WARNS() << "Illegal execution from thread id " << curr
|
||||
<< " outside main thread " << main << LL_ENDL;
|
||||
return false;
|
||||
}
|
||||
|
||||
// this function has become moot
|
||||
|
|
|
|||
|
|
@ -152,7 +152,7 @@ public:
|
|||
|
||||
//============================================================================
|
||||
|
||||
extern LL_COMMON_API void assert_main_thread();
|
||||
extern LL_COMMON_API bool assert_main_thread();
|
||||
extern LL_COMMON_API bool on_main_thread();
|
||||
|
||||
#endif // LL_LLTHREAD_H
|
||||
|
|
|
|||
|
|
@ -342,13 +342,7 @@ bool LLThreadSafeQueue<ElementT, QueueT>::pushIfOpen(T&& element)
|
|||
return true;
|
||||
|
||||
// Storage Full. Wait for signal.
|
||||
// <FS:Beq> [FIRE-32453][BUG-232971] Improve shutdown behaviour. Time bound the sleep
|
||||
// mCapacityCond.wait(lock1);
|
||||
// When the queue is full and the consuming thread has exited we would never wake up.
|
||||
// For safety, we now wait max half a second then recheck close.
|
||||
const auto timeout = std::chrono::milliseconds(500);
|
||||
mCapacityCond.wait_for(lock1, timeout);
|
||||
// </FS:Beq>
|
||||
mCapacityCond.wait(lock1);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -33,8 +33,6 @@
|
|||
namespace LLTrace
|
||||
{
|
||||
|
||||
MemStatHandle gTraceMemStat("LLTrace");
|
||||
|
||||
StatBase::StatBase( const char* name, const char* description )
|
||||
: mName(name),
|
||||
mDescription(description ? description : "")
|
||||
|
|
@ -65,7 +63,7 @@ void TimeBlockTreeNode::setParent( BlockTimerStatHandle* parent )
|
|||
llassert_always(parent != mBlock);
|
||||
llassert_always(parent != NULL);
|
||||
|
||||
TimeBlockTreeNode* parent_tree_node = get_thread_recorder()->getTimeBlockTreeNode(narrow(parent->getIndex()));
|
||||
TimeBlockTreeNode* parent_tree_node = get_thread_recorder()->getTimeBlockTreeNode(narrow<size_t>(parent->getIndex()));
|
||||
if (!parent_tree_node) return;
|
||||
|
||||
if (mParent)
|
||||
|
|
|
|||
|
|
@ -211,61 +211,6 @@ void add(CountStatHandle<T>& count, VALUE_T value)
|
|||
#endif
|
||||
}
|
||||
|
||||
template<>
|
||||
class StatType<MemAccumulator::AllocationFacet>
|
||||
: public StatType<MemAccumulator>
|
||||
{
|
||||
public:
|
||||
|
||||
StatType(const char* name, const char* description = "")
|
||||
: StatType<MemAccumulator>(name, description)
|
||||
{}
|
||||
};
|
||||
|
||||
template<>
|
||||
class StatType<MemAccumulator::DeallocationFacet>
|
||||
: public StatType<MemAccumulator>
|
||||
{
|
||||
public:
|
||||
|
||||
StatType(const char* name, const char* description = "")
|
||||
: StatType<MemAccumulator>(name, description)
|
||||
{}
|
||||
};
|
||||
|
||||
class MemStatHandle : public StatType<MemAccumulator>
|
||||
{
|
||||
public:
|
||||
typedef StatType<MemAccumulator> stat_t;
|
||||
MemStatHandle(const char* name, const char* description = "")
|
||||
: stat_t(name, description)
|
||||
{
|
||||
mName = name;
|
||||
}
|
||||
|
||||
void setName(const char* name)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
mName = name;
|
||||
setKey(name);
|
||||
}
|
||||
|
||||
/*virtual*/ const char* getUnitLabel() const { return "KB"; }
|
||||
|
||||
StatType<MemAccumulator::AllocationFacet>& allocations()
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
return static_cast<StatType<MemAccumulator::AllocationFacet>&>(*(StatType<MemAccumulator>*)this);
|
||||
}
|
||||
|
||||
StatType<MemAccumulator::DeallocationFacet>& deallocations()
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
return static_cast<StatType<MemAccumulator::DeallocationFacet>&>(*(StatType<MemAccumulator>*)this);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// measures effective memory footprint of specified type
|
||||
// specialize to cover different types
|
||||
template<typename T, typename IS_MEM_TRACKABLE = void, typename IS_UNITS = void>
|
||||
|
|
@ -352,33 +297,6 @@ struct MeasureMem<std::basic_string<T>, IS_MEM_TRACKABLE, IS_BYTES>
|
|||
}
|
||||
};
|
||||
|
||||
|
||||
template<typename T>
|
||||
inline void claim_alloc(MemStatHandle& measurement, const T& value)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
#if LL_TRACE_ENABLED
|
||||
auto size = MeasureMem<T>::measureFootprint(value);
|
||||
if(size == 0) return;
|
||||
MemAccumulator& accumulator = measurement.getCurrentAccumulator();
|
||||
accumulator.mSize.sample(accumulator.mSize.hasValue() ? accumulator.mSize.getLastValue() + (F64)size : (F64)size);
|
||||
accumulator.mAllocations.record(size);
|
||||
#endif
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline void disclaim_alloc(MemStatHandle& measurement, const T& value)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
#if LL_TRACE_ENABLED
|
||||
auto size = MeasureMem<T>::measureFootprint(value);
|
||||
if(size == 0) return;
|
||||
MemAccumulator& accumulator = measurement.getCurrentAccumulator();
|
||||
accumulator.mSize.sample(accumulator.mSize.hasValue() ? accumulator.mSize.getLastValue() - (F64)size : -(F64)size);
|
||||
accumulator.mDeallocations.add(size);
|
||||
#endif
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif // LL_LLTRACE_H
|
||||
|
|
|
|||
|
|
@ -1,24 +1,24 @@
|
|||
/**
|
||||
/**
|
||||
* @file lltracesampler.cpp
|
||||
*
|
||||
* $LicenseInfo:firstyear=2001&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2012, 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$
|
||||
*/
|
||||
|
|
@ -32,73 +32,52 @@
|
|||
namespace LLTrace
|
||||
{
|
||||
|
||||
extern MemStatHandle gTraceMemStat;
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
// AccumulatorBufferGroup
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
|
||||
AccumulatorBufferGroup::AccumulatorBufferGroup()
|
||||
AccumulatorBufferGroup::AccumulatorBufferGroup()
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
claim_alloc(gTraceMemStat, mCounts.capacity() * sizeof(CountAccumulator));
|
||||
claim_alloc(gTraceMemStat, mSamples.capacity() * sizeof(SampleAccumulator));
|
||||
claim_alloc(gTraceMemStat, mEvents.capacity() * sizeof(EventAccumulator));
|
||||
claim_alloc(gTraceMemStat, mStackTimers.capacity() * sizeof(TimeBlockAccumulator));
|
||||
claim_alloc(gTraceMemStat, mMemStats.capacity() * sizeof(MemAccumulator));
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
}
|
||||
|
||||
AccumulatorBufferGroup::AccumulatorBufferGroup(const AccumulatorBufferGroup& other)
|
||||
: mCounts(other.mCounts),
|
||||
mSamples(other.mSamples),
|
||||
mEvents(other.mEvents),
|
||||
mStackTimers(other.mStackTimers),
|
||||
mMemStats(other.mMemStats)
|
||||
mStackTimers(other.mStackTimers)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
claim_alloc(gTraceMemStat, mCounts.capacity() * sizeof(CountAccumulator));
|
||||
claim_alloc(gTraceMemStat, mSamples.capacity() * sizeof(SampleAccumulator));
|
||||
claim_alloc(gTraceMemStat, mEvents.capacity() * sizeof(EventAccumulator));
|
||||
claim_alloc(gTraceMemStat, mStackTimers.capacity() * sizeof(TimeBlockAccumulator));
|
||||
claim_alloc(gTraceMemStat, mMemStats.capacity() * sizeof(MemAccumulator));
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
}
|
||||
|
||||
AccumulatorBufferGroup::~AccumulatorBufferGroup()
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
disclaim_alloc(gTraceMemStat, mCounts.capacity() * sizeof(CountAccumulator));
|
||||
disclaim_alloc(gTraceMemStat, mSamples.capacity() * sizeof(SampleAccumulator));
|
||||
disclaim_alloc(gTraceMemStat, mEvents.capacity() * sizeof(EventAccumulator));
|
||||
disclaim_alloc(gTraceMemStat, mStackTimers.capacity() * sizeof(TimeBlockAccumulator));
|
||||
disclaim_alloc(gTraceMemStat, mMemStats.capacity() * sizeof(MemAccumulator));
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
}
|
||||
|
||||
void AccumulatorBufferGroup::handOffTo(AccumulatorBufferGroup& other)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
other.mCounts.reset(&mCounts);
|
||||
other.mSamples.reset(&mSamples);
|
||||
other.mEvents.reset(&mEvents);
|
||||
other.mStackTimers.reset(&mStackTimers);
|
||||
other.mMemStats.reset(&mMemStats);
|
||||
}
|
||||
|
||||
void AccumulatorBufferGroup::makeCurrent()
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
mCounts.makeCurrent();
|
||||
mSamples.makeCurrent();
|
||||
mEvents.makeCurrent();
|
||||
mStackTimers.makeCurrent();
|
||||
mMemStats.makeCurrent();
|
||||
|
||||
ThreadRecorder* thread_recorder = get_thread_recorder();
|
||||
AccumulatorBuffer<TimeBlockAccumulator>& timer_accumulator_buffer = mStackTimers;
|
||||
// update stacktimer parent pointers
|
||||
for (size_t i = 0, end_i = mStackTimers.size(); i < end_i; i++)
|
||||
{
|
||||
TimeBlockTreeNode* tree_node = thread_recorder->getTimeBlockTreeNode(narrow(i));
|
||||
TimeBlockTreeNode* tree_node = thread_recorder->getTimeBlockTreeNode(narrow<size_t>(i));
|
||||
if (tree_node)
|
||||
{
|
||||
timer_accumulator_buffer[i].mParent = tree_node->mParent;
|
||||
|
|
@ -109,12 +88,11 @@ void AccumulatorBufferGroup::makeCurrent()
|
|||
//static
|
||||
void AccumulatorBufferGroup::clearCurrent()
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
AccumulatorBuffer<CountAccumulator>::clearCurrent();
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
AccumulatorBuffer<CountAccumulator>::clearCurrent();
|
||||
AccumulatorBuffer<SampleAccumulator>::clearCurrent();
|
||||
AccumulatorBuffer<EventAccumulator>::clearCurrent();
|
||||
AccumulatorBuffer<TimeBlockAccumulator>::clearCurrent();
|
||||
AccumulatorBuffer<MemAccumulator>::clearCurrent();
|
||||
}
|
||||
|
||||
bool AccumulatorBufferGroup::isCurrent() const
|
||||
|
|
@ -124,44 +102,39 @@ bool AccumulatorBufferGroup::isCurrent() const
|
|||
|
||||
void AccumulatorBufferGroup::append( const AccumulatorBufferGroup& other )
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
mCounts.addSamples(other.mCounts, SEQUENTIAL);
|
||||
mSamples.addSamples(other.mSamples, SEQUENTIAL);
|
||||
mEvents.addSamples(other.mEvents, SEQUENTIAL);
|
||||
mMemStats.addSamples(other.mMemStats, SEQUENTIAL);
|
||||
mStackTimers.addSamples(other.mStackTimers, SEQUENTIAL);
|
||||
}
|
||||
|
||||
void AccumulatorBufferGroup::merge( const AccumulatorBufferGroup& other)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
mCounts.addSamples(other.mCounts, NON_SEQUENTIAL);
|
||||
mSamples.addSamples(other.mSamples, NON_SEQUENTIAL);
|
||||
mEvents.addSamples(other.mEvents, NON_SEQUENTIAL);
|
||||
mMemStats.addSamples(other.mMemStats, NON_SEQUENTIAL);
|
||||
// for now, hold out timers from merge, need to be displayed per thread
|
||||
//mStackTimers.addSamples(other.mStackTimers, NON_SEQUENTIAL);
|
||||
}
|
||||
|
||||
void AccumulatorBufferGroup::reset(AccumulatorBufferGroup* other)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
mCounts.reset(other ? &other->mCounts : NULL);
|
||||
mSamples.reset(other ? &other->mSamples : NULL);
|
||||
mEvents.reset(other ? &other->mEvents : NULL);
|
||||
mStackTimers.reset(other ? &other->mStackTimers : NULL);
|
||||
mMemStats.reset(other ? &other->mMemStats : NULL);
|
||||
}
|
||||
|
||||
void AccumulatorBufferGroup::sync()
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
if (isCurrent())
|
||||
{
|
||||
F64SecondsImplicit time_stamp = LLTimer::getTotalSeconds();
|
||||
|
||||
mSamples.sync(time_stamp);
|
||||
mMemStats.sync(time_stamp);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -197,10 +170,9 @@ F64 SampleAccumulator::mergeSumsOfSquares(const SampleAccumulator& a, const Samp
|
|||
return a.getSumOfSquares();
|
||||
}
|
||||
|
||||
|
||||
void SampleAccumulator::addSamples( const SampleAccumulator& other, EBufferAppendType append_type )
|
||||
{
|
||||
if (append_type == NON_SEQUENTIAL)
|
||||
if (append_type == NON_SEQUENTIAL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
|
@ -299,7 +271,7 @@ void EventAccumulator::addSamples( const EventAccumulator& other, EBufferAppendT
|
|||
|
||||
void EventAccumulator::reset( const EventAccumulator* other )
|
||||
{
|
||||
mNumSamples = 0;
|
||||
mNumSamples = 0;
|
||||
mSum = 0;
|
||||
mMin = F32(NaN);
|
||||
mMax = F32(NaN);
|
||||
|
|
@ -308,5 +280,4 @@ void EventAccumulator::reset( const EventAccumulator* other )
|
|||
mLastValue = other ? other->mLastValue : NaN;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,26 +1,26 @@
|
|||
|
||||
/**
|
||||
/**
|
||||
* @file lltraceaccumulators.h
|
||||
* @brief Storage for accumulating statistics
|
||||
*
|
||||
* $LicenseInfo:firstyear=2001&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2012, 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$
|
||||
*/
|
||||
|
|
@ -28,7 +28,6 @@
|
|||
#ifndef LL_LLTRACEACCUMULATORS_H
|
||||
#define LL_LLTRACEACCUMULATORS_H
|
||||
|
||||
|
||||
#include "stdtypes.h"
|
||||
#include "llpreprocessor.h"
|
||||
#include "llunits.h"
|
||||
|
|
@ -66,7 +65,7 @@ namespace LLTrace
|
|||
: mStorageSize(0),
|
||||
mStorage(NULL)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
const AccumulatorBuffer& other = *getDefaultBuffer();
|
||||
resize(sNextStorageSlot);
|
||||
for (S32 i = 0; i < sNextStorageSlot; i++)
|
||||
|
|
@ -77,7 +76,7 @@ namespace LLTrace
|
|||
|
||||
~AccumulatorBuffer()
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
if (isCurrent())
|
||||
{
|
||||
LLThreadLocalSingletonPointer<ACCUMULATOR>::setInstance(NULL);
|
||||
|
|
@ -85,14 +84,14 @@ namespace LLTrace
|
|||
delete[] mStorage;
|
||||
}
|
||||
|
||||
LL_FORCE_INLINE ACCUMULATOR& operator[](size_t index)
|
||||
{
|
||||
return mStorage[index];
|
||||
LL_FORCE_INLINE ACCUMULATOR& operator[](size_t index)
|
||||
{
|
||||
return mStorage[index];
|
||||
}
|
||||
|
||||
LL_FORCE_INLINE const ACCUMULATOR& operator[](size_t index) const
|
||||
{
|
||||
return mStorage[index];
|
||||
{
|
||||
return mStorage[index];
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -100,7 +99,7 @@ namespace LLTrace
|
|||
: mStorageSize(0),
|
||||
mStorage(NULL)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
resize(sNextStorageSlot);
|
||||
for (S32 i = 0; i < sNextStorageSlot; i++)
|
||||
{
|
||||
|
|
@ -110,7 +109,7 @@ namespace LLTrace
|
|||
|
||||
void addSamples(const AccumulatorBuffer<ACCUMULATOR>& other, EBufferAppendType append_type)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
llassert(mStorageSize >= sNextStorageSlot && other.mStorageSize >= sNextStorageSlot);
|
||||
for (size_t i = 0; i < sNextStorageSlot; i++)
|
||||
{
|
||||
|
|
@ -120,7 +119,7 @@ namespace LLTrace
|
|||
|
||||
void copyFrom(const AccumulatorBuffer<ACCUMULATOR>& other)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
llassert(mStorageSize >= sNextStorageSlot && other.mStorageSize >= sNextStorageSlot);
|
||||
for (size_t i = 0; i < sNextStorageSlot; i++)
|
||||
{
|
||||
|
|
@ -130,7 +129,7 @@ namespace LLTrace
|
|||
|
||||
void reset(const AccumulatorBuffer<ACCUMULATOR>* other = NULL)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
llassert(mStorageSize >= sNextStorageSlot);
|
||||
for (size_t i = 0; i < sNextStorageSlot; i++)
|
||||
{
|
||||
|
|
@ -140,7 +139,7 @@ namespace LLTrace
|
|||
|
||||
void sync(F64SecondsImplicit time_stamp)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
llassert(mStorageSize >= sNextStorageSlot);
|
||||
for (size_t i = 0; i < sNextStorageSlot; i++)
|
||||
{
|
||||
|
|
@ -160,13 +159,13 @@ namespace LLTrace
|
|||
|
||||
static void clearCurrent()
|
||||
{
|
||||
LLThreadLocalSingletonPointer<ACCUMULATOR>::setInstance(NULL);
|
||||
LLThreadLocalSingletonPointer<ACCUMULATOR>::setInstance(NULL);
|
||||
}
|
||||
|
||||
// NOTE: this is not thread-safe. We assume that slots are reserved in the main thread before any child threads are spawned
|
||||
size_t reserveSlot()
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
size_t next_slot = sNextStorageSlot++;
|
||||
if (next_slot >= mStorageSize)
|
||||
{
|
||||
|
|
@ -180,7 +179,7 @@ namespace LLTrace
|
|||
|
||||
void resize(size_t new_size)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
if (new_size <= mStorageSize) return;
|
||||
|
||||
ACCUMULATOR* old_storage = mStorage;
|
||||
|
|
@ -214,14 +213,14 @@ namespace LLTrace
|
|||
return mStorageSize;
|
||||
}
|
||||
|
||||
static size_t getNumIndices()
|
||||
static size_t getNumIndices()
|
||||
{
|
||||
return sNextStorageSlot;
|
||||
}
|
||||
|
||||
static self_t* getDefaultBuffer()
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
static bool sInitialized = false;
|
||||
if (!sInitialized)
|
||||
{
|
||||
|
|
@ -336,7 +335,7 @@ namespace LLTrace
|
|||
|
||||
void sample(F64 value)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
F64SecondsImplicit time_stamp = LLTimer::getTotalSeconds();
|
||||
|
||||
// store effect of last value
|
||||
|
|
@ -399,7 +398,7 @@ namespace LLTrace
|
|||
F64 mMean,
|
||||
mSumOfSquares;
|
||||
|
||||
F64SecondsImplicit
|
||||
F64SecondsImplicit
|
||||
mLastSampleTimeStamp,
|
||||
mTotalSamplingTime;
|
||||
|
||||
|
|
@ -409,7 +408,7 @@ namespace LLTrace
|
|||
S32 mNumSamples;
|
||||
// distinct from mNumSamples, since we might have inherited a last value from
|
||||
// a previous sampling period
|
||||
bool mHasValue;
|
||||
bool mHasValue;
|
||||
};
|
||||
|
||||
class CountAccumulator
|
||||
|
|
@ -457,14 +456,14 @@ namespace LLTrace
|
|||
|
||||
class alignas(32) TimeBlockAccumulator
|
||||
{
|
||||
public:
|
||||
public:
|
||||
typedef F64Seconds value_t;
|
||||
static F64Seconds getDefaultValue() { return F64Seconds(0); }
|
||||
|
||||
typedef TimeBlockAccumulator self_t;
|
||||
|
||||
// fake classes that allows us to view different facets of underlying statistic
|
||||
struct CallCountFacet
|
||||
struct CallCountFacet
|
||||
{
|
||||
typedef S32 value_t;
|
||||
};
|
||||
|
|
@ -515,12 +514,12 @@ namespace LLTrace
|
|||
BlockTimerStatHandle* getParent() { return mParent; }
|
||||
|
||||
BlockTimerStatHandle* mBlock;
|
||||
BlockTimerStatHandle* mParent;
|
||||
BlockTimerStatHandle* mParent;
|
||||
std::vector<BlockTimerStatHandle*> mChildren;
|
||||
bool mCollapsed;
|
||||
bool mNeedsSorting;
|
||||
};
|
||||
|
||||
|
||||
struct BlockTimerStackRecord
|
||||
{
|
||||
class BlockTimer* mActiveTimer;
|
||||
|
|
@ -528,65 +527,6 @@ namespace LLTrace
|
|||
U64 mChildTime;
|
||||
};
|
||||
|
||||
struct MemAccumulator
|
||||
{
|
||||
typedef F64Bytes value_t;
|
||||
static F64Bytes getDefaultValue() { return F64Bytes(0); }
|
||||
|
||||
typedef MemAccumulator self_t;
|
||||
|
||||
// fake classes that allows us to view different facets of underlying statistic
|
||||
struct AllocationFacet
|
||||
{
|
||||
typedef F64Bytes value_t;
|
||||
static F64Bytes getDefaultValue() { return F64Bytes(0); }
|
||||
};
|
||||
|
||||
struct DeallocationFacet
|
||||
{
|
||||
typedef F64Bytes value_t;
|
||||
static F64Bytes getDefaultValue() { return F64Bytes(0); }
|
||||
};
|
||||
|
||||
void addSamples(const MemAccumulator& other, EBufferAppendType append_type)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
mAllocations.addSamples(other.mAllocations, append_type);
|
||||
mDeallocations.addSamples(other.mDeallocations, append_type);
|
||||
|
||||
if (append_type == SEQUENTIAL)
|
||||
{
|
||||
mSize.addSamples(other.mSize, SEQUENTIAL);
|
||||
}
|
||||
else
|
||||
{
|
||||
F64 allocation_delta(other.mAllocations.getSum() - other.mDeallocations.getSum());
|
||||
mSize.sample(mSize.hasValue()
|
||||
? mSize.getLastValue() + allocation_delta
|
||||
: allocation_delta);
|
||||
}
|
||||
}
|
||||
|
||||
void reset(const MemAccumulator* other)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
mSize.reset(other ? &other->mSize : NULL);
|
||||
mAllocations.reset(other ? &other->mAllocations : NULL);
|
||||
mDeallocations.reset(other ? &other->mDeallocations : NULL);
|
||||
}
|
||||
|
||||
void sync(F64SecondsImplicit time_stamp)
|
||||
{
|
||||
mSize.sync(time_stamp);
|
||||
}
|
||||
|
||||
bool hasValue() const { return mSize.hasValue(); }
|
||||
|
||||
SampleAccumulator mSize;
|
||||
EventAccumulator mAllocations;
|
||||
CountAccumulator mDeallocations;
|
||||
};
|
||||
|
||||
struct AccumulatorBufferGroup : public LLRefCount
|
||||
{
|
||||
AccumulatorBufferGroup();
|
||||
|
|
@ -607,9 +547,7 @@ namespace LLTrace
|
|||
AccumulatorBuffer<SampleAccumulator> mSamples;
|
||||
AccumulatorBuffer<EventAccumulator> mEvents;
|
||||
AccumulatorBuffer<TimeBlockAccumulator> mStackTimers;
|
||||
AccumulatorBuffer<MemAccumulator> mMemStats;
|
||||
};
|
||||
}
|
||||
|
||||
#endif // LL_LLTRACEACCUMULATORS_H
|
||||
|
||||
|
|
|
|||
|
|
@ -1,24 +1,24 @@
|
|||
/**
|
||||
/**
|
||||
* @file lltracesampler.cpp
|
||||
*
|
||||
* $LicenseInfo:firstyear=2001&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2012, 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$
|
||||
*/
|
||||
|
|
@ -32,7 +32,7 @@
|
|||
#include "lltracethreadrecorder.h"
|
||||
#include "llthread.h"
|
||||
|
||||
inline F64 lerp(F64 a, F64 b, F64 u)
|
||||
inline F64 lerp(F64 a, F64 b, F64 u)
|
||||
{
|
||||
return a + ((b - a) * u);
|
||||
}
|
||||
|
|
@ -40,34 +40,29 @@ inline F64 lerp(F64 a, F64 b, F64 u)
|
|||
namespace LLTrace
|
||||
{
|
||||
|
||||
extern MemStatHandle gTraceMemStat;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
// Recording
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
|
||||
Recording::Recording(EPlayState state)
|
||||
Recording::Recording(EPlayState state)
|
||||
: mElapsedSeconds(0),
|
||||
mActiveBuffers(NULL)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
claim_alloc(gTraceMemStat, this);
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
mBuffers = new AccumulatorBufferGroup();
|
||||
claim_alloc(gTraceMemStat, mBuffers);
|
||||
setPlayState(state);
|
||||
}
|
||||
|
||||
Recording::Recording( const Recording& other )
|
||||
: mActiveBuffers(NULL)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
claim_alloc(gTraceMemStat, this);
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
*this = other;
|
||||
}
|
||||
|
||||
Recording& Recording::operator = (const Recording& other)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
// this will allow us to seamlessly start without affecting any data we've acquired from other
|
||||
setPlayState(PAUSED);
|
||||
|
||||
|
|
@ -85,14 +80,11 @@ Recording& Recording::operator = (const Recording& other)
|
|||
return *this;
|
||||
}
|
||||
|
||||
|
||||
Recording::~Recording()
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
disclaim_alloc(gTraceMemStat, this);
|
||||
disclaim_alloc(gTraceMemStat, mBuffers);
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
|
||||
// allow recording destruction without thread recorder running,
|
||||
// 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() != NULL)
|
||||
|
|
@ -107,14 +99,14 @@ void Recording::update()
|
|||
#if LL_TRACE_ENABLED
|
||||
if (isStarted())
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
mElapsedSeconds += mSamplingTimer.getElapsedTimeF64();
|
||||
|
||||
// must have
|
||||
llassert(mActiveBuffers != NULL
|
||||
// must have
|
||||
llassert(mActiveBuffers != NULL
|
||||
&& LLTrace::get_thread_recorder() != NULL);
|
||||
|
||||
if(!mActiveBuffers->isCurrent() && LLTrace::get_thread_recorder() != NULL)
|
||||
if (!mActiveBuffers->isCurrent() && LLTrace::get_thread_recorder() != NULL)
|
||||
{
|
||||
AccumulatorBufferGroup* buffers = mBuffers.write();
|
||||
LLTrace::get_thread_recorder()->deactivate(buffers);
|
||||
|
|
@ -128,7 +120,7 @@ void Recording::update()
|
|||
|
||||
void Recording::handleReset()
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
#if LL_TRACE_ENABLED
|
||||
mBuffers.write()->reset();
|
||||
|
||||
|
|
@ -139,7 +131,7 @@ void Recording::handleReset()
|
|||
|
||||
void Recording::handleStart()
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
#if LL_TRACE_ENABLED
|
||||
mSamplingTimer.reset();
|
||||
mBuffers.setStayUnique(true);
|
||||
|
|
@ -151,7 +143,7 @@ void Recording::handleStart()
|
|||
|
||||
void Recording::handleStop()
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
#if LL_TRACE_ENABLED
|
||||
mElapsedSeconds += mSamplingTimer.getElapsedTimeF64();
|
||||
// must have thread recorder running on this thread
|
||||
|
|
@ -204,7 +196,6 @@ F64Seconds Recording::getSum(const StatType<TimeBlockAccumulator::SelfTimeFacet>
|
|||
return F64Seconds(((F64)(accumulator.mSelfTimeCounter) + (F64)(active_accumulator ? active_accumulator->mSelfTimeCounter : 0)) / (F64)LLTrace::BlockTimer::countsPerSecond());
|
||||
}
|
||||
|
||||
|
||||
S32 Recording::getSum(const StatType<TimeBlockAccumulator::CallCountFacet>& stat)
|
||||
{
|
||||
update();
|
||||
|
|
@ -219,7 +210,7 @@ F64Seconds Recording::getPerSec(const StatType<TimeBlockAccumulator>& stat)
|
|||
const TimeBlockAccumulator& accumulator = mBuffers->mStackTimers[stat.getIndex()];
|
||||
const TimeBlockAccumulator* active_accumulator = mActiveBuffers ? &mActiveBuffers->mStackTimers[stat.getIndex()] : NULL;
|
||||
|
||||
return F64Seconds((F64)(accumulator.mTotalTimeCounter + (active_accumulator ? active_accumulator->mTotalTimeCounter : 0))
|
||||
return F64Seconds((F64)(accumulator.mTotalTimeCounter + (active_accumulator ? active_accumulator->mTotalTimeCounter : 0))
|
||||
/ ((F64)LLTrace::BlockTimer::countsPerSecond() * mElapsedSeconds.value()));
|
||||
}
|
||||
|
||||
|
|
@ -241,144 +232,9 @@ F32 Recording::getPerSec(const StatType<TimeBlockAccumulator::CallCountFacet>& s
|
|||
return (F32)(accumulator.mCalls + (active_accumulator ? active_accumulator->mCalls : 0)) / mElapsedSeconds.value();
|
||||
}
|
||||
|
||||
bool Recording::hasValue(const StatType<MemAccumulator>& stat)
|
||||
{
|
||||
update();
|
||||
const MemAccumulator& accumulator = mBuffers->mMemStats[stat.getIndex()];
|
||||
const MemAccumulator* active_accumulator = mActiveBuffers ? &mActiveBuffers->mMemStats[stat.getIndex()] : NULL;
|
||||
return accumulator.mSize.hasValue() || (active_accumulator && active_accumulator->mSize.hasValue() ? active_accumulator->mSize.hasValue() : false);
|
||||
}
|
||||
|
||||
F64Kilobytes Recording::getMin(const StatType<MemAccumulator>& stat)
|
||||
{
|
||||
update();
|
||||
const MemAccumulator& accumulator = mBuffers->mMemStats[stat.getIndex()];
|
||||
const MemAccumulator* active_accumulator = mActiveBuffers ? &mActiveBuffers->mMemStats[stat.getIndex()] : NULL;
|
||||
return F64Bytes(llmin(accumulator.mSize.getMin(), (active_accumulator && active_accumulator->mSize.hasValue() ? active_accumulator->mSize.getMin() : F32_MAX)));
|
||||
}
|
||||
|
||||
F64Kilobytes Recording::getMean(const StatType<MemAccumulator>& stat)
|
||||
{
|
||||
update();
|
||||
const MemAccumulator& accumulator = mBuffers->mMemStats[stat.getIndex()];
|
||||
const MemAccumulator* active_accumulator = mActiveBuffers ? &mActiveBuffers->mMemStats[stat.getIndex()] : NULL;
|
||||
|
||||
if (active_accumulator && active_accumulator->mSize.hasValue())
|
||||
{
|
||||
F32 t = 0.0f;
|
||||
S32 div = accumulator.mSize.getSampleCount() + active_accumulator->mSize.getSampleCount();
|
||||
if (div > 0)
|
||||
{
|
||||
t = active_accumulator->mSize.getSampleCount() / div;
|
||||
}
|
||||
return F64Bytes(lerp(accumulator.mSize.getMean(), active_accumulator->mSize.getMean(), t));
|
||||
}
|
||||
else
|
||||
{
|
||||
return F64Bytes(accumulator.mSize.getMean());
|
||||
}
|
||||
}
|
||||
|
||||
F64Kilobytes Recording::getMax(const StatType<MemAccumulator>& stat)
|
||||
{
|
||||
update();
|
||||
const MemAccumulator& accumulator = mBuffers->mMemStats[stat.getIndex()];
|
||||
const MemAccumulator* active_accumulator = mActiveBuffers ? &mActiveBuffers->mMemStats[stat.getIndex()] : NULL;
|
||||
return F64Bytes(llmax(accumulator.mSize.getMax(), active_accumulator && active_accumulator->mSize.hasValue() ? active_accumulator->mSize.getMax() : F32_MIN));
|
||||
}
|
||||
|
||||
F64Kilobytes Recording::getStandardDeviation(const StatType<MemAccumulator>& stat)
|
||||
{
|
||||
update();
|
||||
const MemAccumulator& accumulator = mBuffers->mMemStats[stat.getIndex()];
|
||||
const MemAccumulator* active_accumulator = mActiveBuffers ? &mActiveBuffers->mMemStats[stat.getIndex()] : NULL;
|
||||
if (active_accumulator && active_accumulator->hasValue())
|
||||
{
|
||||
F64 sum_of_squares = SampleAccumulator::mergeSumsOfSquares(accumulator.mSize, active_accumulator->mSize);
|
||||
return F64Bytes(sqrtf(sum_of_squares / (accumulator.mSize.getSamplingTime().value() + active_accumulator->mSize.getSamplingTime().value())));
|
||||
}
|
||||
else
|
||||
{
|
||||
return F64Bytes(accumulator.mSize.getStandardDeviation());
|
||||
}
|
||||
}
|
||||
|
||||
F64Kilobytes Recording::getLastValue(const StatType<MemAccumulator>& stat)
|
||||
{
|
||||
update();
|
||||
const MemAccumulator& accumulator = mBuffers->mMemStats[stat.getIndex()];
|
||||
const MemAccumulator* active_accumulator = mActiveBuffers ? &mActiveBuffers->mMemStats[stat.getIndex()] : NULL;
|
||||
return F64Bytes(active_accumulator ? active_accumulator->mSize.getLastValue() : accumulator.mSize.getLastValue());
|
||||
}
|
||||
|
||||
bool Recording::hasValue(const StatType<MemAccumulator::AllocationFacet>& stat)
|
||||
{
|
||||
update();
|
||||
const MemAccumulator& accumulator = mBuffers->mMemStats[stat.getIndex()];
|
||||
const MemAccumulator* active_accumulator = mActiveBuffers ? &mActiveBuffers->mMemStats[stat.getIndex()] : NULL;
|
||||
return accumulator.mAllocations.hasValue() || (active_accumulator ? active_accumulator->mAllocations.hasValue() : false);
|
||||
}
|
||||
|
||||
F64Kilobytes Recording::getSum(const StatType<MemAccumulator::AllocationFacet>& stat)
|
||||
{
|
||||
update();
|
||||
const MemAccumulator& accumulator = mBuffers->mMemStats[stat.getIndex()];
|
||||
const MemAccumulator* active_accumulator = mActiveBuffers ? &mActiveBuffers->mMemStats[stat.getIndex()] : NULL;
|
||||
return F64Bytes(accumulator.mAllocations.getSum() + (active_accumulator ? active_accumulator->mAllocations.getSum() : 0));
|
||||
}
|
||||
|
||||
F64Kilobytes Recording::getPerSec(const StatType<MemAccumulator::AllocationFacet>& stat)
|
||||
{
|
||||
update();
|
||||
const MemAccumulator& accumulator = mBuffers->mMemStats[stat.getIndex()];
|
||||
const MemAccumulator* active_accumulator = mActiveBuffers ? &mActiveBuffers->mMemStats[stat.getIndex()] : NULL;
|
||||
return F64Bytes((accumulator.mAllocations.getSum() + (active_accumulator ? active_accumulator->mAllocations.getSum() : 0)) / mElapsedSeconds.value());
|
||||
}
|
||||
|
||||
S32 Recording::getSampleCount(const StatType<MemAccumulator::AllocationFacet>& stat)
|
||||
{
|
||||
update();
|
||||
const MemAccumulator& accumulator = mBuffers->mMemStats[stat.getIndex()];
|
||||
const MemAccumulator* active_accumulator = mActiveBuffers ? &mActiveBuffers->mMemStats[stat.getIndex()] : NULL;
|
||||
return accumulator.mAllocations.getSampleCount() + (active_accumulator ? active_accumulator->mAllocations.getSampleCount() : 0);
|
||||
}
|
||||
|
||||
bool Recording::hasValue(const StatType<MemAccumulator::DeallocationFacet>& stat)
|
||||
{
|
||||
update();
|
||||
const MemAccumulator& accumulator = mBuffers->mMemStats[stat.getIndex()];
|
||||
const MemAccumulator* active_accumulator = mActiveBuffers ? &mActiveBuffers->mMemStats[stat.getIndex()] : NULL;
|
||||
return accumulator.mDeallocations.hasValue() || (active_accumulator ? active_accumulator->mDeallocations.hasValue() : false);
|
||||
}
|
||||
|
||||
|
||||
F64Kilobytes Recording::getSum(const StatType<MemAccumulator::DeallocationFacet>& stat)
|
||||
{
|
||||
update();
|
||||
const MemAccumulator& accumulator = mBuffers->mMemStats[stat.getIndex()];
|
||||
const MemAccumulator* active_accumulator = mActiveBuffers ? &mActiveBuffers->mMemStats[stat.getIndex()] : NULL;
|
||||
return F64Bytes(accumulator.mDeallocations.getSum() + (active_accumulator ? active_accumulator->mDeallocations.getSum() : 0));
|
||||
}
|
||||
|
||||
F64Kilobytes Recording::getPerSec(const StatType<MemAccumulator::DeallocationFacet>& stat)
|
||||
{
|
||||
update();
|
||||
const MemAccumulator& accumulator = mBuffers->mMemStats[stat.getIndex()];
|
||||
const MemAccumulator* active_accumulator = mActiveBuffers ? &mActiveBuffers->mMemStats[stat.getIndex()] : NULL;
|
||||
return F64Bytes((accumulator.mDeallocations.getSum() + (active_accumulator ? active_accumulator->mDeallocations.getSum() : 0)) / mElapsedSeconds.value());
|
||||
}
|
||||
|
||||
S32 Recording::getSampleCount(const StatType<MemAccumulator::DeallocationFacet>& stat)
|
||||
{
|
||||
update();
|
||||
const MemAccumulator& accumulator = mBuffers->mMemStats[stat.getIndex()];
|
||||
const MemAccumulator* active_accumulator = mActiveBuffers ? &mActiveBuffers->mMemStats[stat.getIndex()] : NULL;
|
||||
return accumulator.mDeallocations.getSampleCount() + (active_accumulator ? active_accumulator->mDeallocations.getSampleCount() : 0);
|
||||
}
|
||||
|
||||
bool Recording::hasValue(const StatType<CountAccumulator>& stat)
|
||||
{
|
||||
update();
|
||||
update();
|
||||
const CountAccumulator& accumulator = mBuffers->mCounts[stat.getIndex()];
|
||||
const CountAccumulator* active_accumulator = mActiveBuffers ? &mActiveBuffers->mCounts[stat.getIndex()] : NULL;
|
||||
return accumulator.hasValue() || (active_accumulator ? active_accumulator->hasValue() : false);
|
||||
|
|
@ -386,7 +242,7 @@ bool Recording::hasValue(const StatType<CountAccumulator>& stat)
|
|||
|
||||
F64 Recording::getSum(const StatType<CountAccumulator>& stat)
|
||||
{
|
||||
update();
|
||||
update();
|
||||
const CountAccumulator& accumulator = mBuffers->mCounts[stat.getIndex()];
|
||||
const CountAccumulator* active_accumulator = mActiveBuffers ? &mActiveBuffers->mCounts[stat.getIndex()] : NULL;
|
||||
return accumulator.getSum() + (active_accumulator ? active_accumulator->getSum() : 0);
|
||||
|
|
@ -394,7 +250,7 @@ F64 Recording::getSum(const StatType<CountAccumulator>& stat)
|
|||
|
||||
F64 Recording::getPerSec( const StatType<CountAccumulator>& stat )
|
||||
{
|
||||
update();
|
||||
update();
|
||||
const CountAccumulator& accumulator = mBuffers->mCounts[stat.getIndex()];
|
||||
const CountAccumulator* active_accumulator = mActiveBuffers ? &mActiveBuffers->mCounts[stat.getIndex()] : NULL;
|
||||
F64 sum = accumulator.getSum() + (active_accumulator ? active_accumulator->getSum() : 0);
|
||||
|
|
@ -403,7 +259,7 @@ F64 Recording::getPerSec( const StatType<CountAccumulator>& stat )
|
|||
|
||||
S32 Recording::getSampleCount( const StatType<CountAccumulator>& stat )
|
||||
{
|
||||
update();
|
||||
update();
|
||||
const CountAccumulator& accumulator = mBuffers->mCounts[stat.getIndex()];
|
||||
const CountAccumulator* active_accumulator = mActiveBuffers ? &mActiveBuffers->mCounts[stat.getIndex()] : NULL;
|
||||
return accumulator.getSampleCount() + (active_accumulator ? active_accumulator->getSampleCount() : 0);
|
||||
|
|
@ -411,7 +267,7 @@ S32 Recording::getSampleCount( const StatType<CountAccumulator>& stat )
|
|||
|
||||
bool Recording::hasValue(const StatType<SampleAccumulator>& stat)
|
||||
{
|
||||
update();
|
||||
update();
|
||||
const SampleAccumulator& accumulator = mBuffers->mSamples[stat.getIndex()];
|
||||
const SampleAccumulator* active_accumulator = mActiveBuffers ? &mActiveBuffers->mSamples[stat.getIndex()] : NULL;
|
||||
return accumulator.hasValue() || (active_accumulator && active_accumulator->hasValue());
|
||||
|
|
@ -419,7 +275,7 @@ bool Recording::hasValue(const StatType<SampleAccumulator>& stat)
|
|||
|
||||
F64 Recording::getMin( const StatType<SampleAccumulator>& stat )
|
||||
{
|
||||
update();
|
||||
update();
|
||||
const SampleAccumulator& accumulator = mBuffers->mSamples[stat.getIndex()];
|
||||
const SampleAccumulator* active_accumulator = mActiveBuffers ? &mActiveBuffers->mSamples[stat.getIndex()] : NULL;
|
||||
return llmin(accumulator.getMin(), active_accumulator && active_accumulator->hasValue() ? active_accumulator->getMin() : F32_MAX);
|
||||
|
|
@ -427,7 +283,7 @@ F64 Recording::getMin( const StatType<SampleAccumulator>& stat )
|
|||
|
||||
F64 Recording::getMax( const StatType<SampleAccumulator>& stat )
|
||||
{
|
||||
update();
|
||||
update();
|
||||
const SampleAccumulator& accumulator = mBuffers->mSamples[stat.getIndex()];
|
||||
const SampleAccumulator* active_accumulator = mActiveBuffers ? &mActiveBuffers->mSamples[stat.getIndex()] : NULL;
|
||||
return llmax(accumulator.getMax(), active_accumulator && active_accumulator->hasValue() ? active_accumulator->getMax() : F32_MIN);
|
||||
|
|
@ -435,17 +291,17 @@ F64 Recording::getMax( const StatType<SampleAccumulator>& stat )
|
|||
|
||||
F64 Recording::getMean( const StatType<SampleAccumulator>& stat )
|
||||
{
|
||||
update();
|
||||
update();
|
||||
const SampleAccumulator& accumulator = mBuffers->mSamples[stat.getIndex()];
|
||||
const SampleAccumulator* active_accumulator = mActiveBuffers ? &mActiveBuffers->mSamples[stat.getIndex()] : NULL;
|
||||
if (active_accumulator && active_accumulator->hasValue())
|
||||
{
|
||||
F32 t = 0.0f;
|
||||
S32 div = accumulator.getSampleCount() + active_accumulator->getSampleCount();
|
||||
if (div > 0)
|
||||
{
|
||||
t = active_accumulator->getSampleCount() / div;
|
||||
}
|
||||
F32 t = 0.0f;
|
||||
S32 div = accumulator.getSampleCount() + active_accumulator->getSampleCount();
|
||||
if (div > 0)
|
||||
{
|
||||
t = active_accumulator->getSampleCount() / div;
|
||||
}
|
||||
return lerp(accumulator.getMean(), active_accumulator->getMean(), t);
|
||||
}
|
||||
else
|
||||
|
|
@ -456,7 +312,7 @@ F64 Recording::getMean( const StatType<SampleAccumulator>& stat )
|
|||
|
||||
F64 Recording::getStandardDeviation( const StatType<SampleAccumulator>& stat )
|
||||
{
|
||||
update();
|
||||
update();
|
||||
const SampleAccumulator& accumulator = mBuffers->mSamples[stat.getIndex()];
|
||||
const SampleAccumulator* active_accumulator = mActiveBuffers ? &mActiveBuffers->mSamples[stat.getIndex()] : NULL;
|
||||
|
||||
|
|
@ -473,7 +329,7 @@ F64 Recording::getStandardDeviation( const StatType<SampleAccumulator>& stat )
|
|||
|
||||
F64 Recording::getLastValue( const StatType<SampleAccumulator>& stat )
|
||||
{
|
||||
update();
|
||||
update();
|
||||
const SampleAccumulator& accumulator = mBuffers->mSamples[stat.getIndex()];
|
||||
const SampleAccumulator* active_accumulator = mActiveBuffers ? &mActiveBuffers->mSamples[stat.getIndex()] : NULL;
|
||||
return (active_accumulator && active_accumulator->hasValue() ? active_accumulator->getLastValue() : accumulator.getLastValue());
|
||||
|
|
@ -481,7 +337,7 @@ F64 Recording::getLastValue( const StatType<SampleAccumulator>& stat )
|
|||
|
||||
S32 Recording::getSampleCount( const StatType<SampleAccumulator>& stat )
|
||||
{
|
||||
update();
|
||||
update();
|
||||
const SampleAccumulator& accumulator = mBuffers->mSamples[stat.getIndex()];
|
||||
const SampleAccumulator* active_accumulator = mActiveBuffers ? &mActiveBuffers->mSamples[stat.getIndex()] : NULL;
|
||||
return accumulator.getSampleCount() + (active_accumulator && active_accumulator->hasValue() ? active_accumulator->getSampleCount() : 0);
|
||||
|
|
@ -489,7 +345,7 @@ S32 Recording::getSampleCount( const StatType<SampleAccumulator>& stat )
|
|||
|
||||
bool Recording::hasValue(const StatType<EventAccumulator>& stat)
|
||||
{
|
||||
update();
|
||||
update();
|
||||
const EventAccumulator& accumulator = mBuffers->mEvents[stat.getIndex()];
|
||||
const EventAccumulator* active_accumulator = mActiveBuffers ? &mActiveBuffers->mEvents[stat.getIndex()] : NULL;
|
||||
return accumulator.hasValue() || (active_accumulator && active_accumulator->hasValue());
|
||||
|
|
@ -497,7 +353,7 @@ bool Recording::hasValue(const StatType<EventAccumulator>& stat)
|
|||
|
||||
F64 Recording::getSum( const StatType<EventAccumulator>& stat)
|
||||
{
|
||||
update();
|
||||
update();
|
||||
const EventAccumulator& accumulator = mBuffers->mEvents[stat.getIndex()];
|
||||
const EventAccumulator* active_accumulator = mActiveBuffers ? &mActiveBuffers->mEvents[stat.getIndex()] : NULL;
|
||||
return (F64)(accumulator.getSum() + (active_accumulator && active_accumulator->hasValue() ? active_accumulator->getSum() : 0));
|
||||
|
|
@ -505,7 +361,7 @@ F64 Recording::getSum( const StatType<EventAccumulator>& stat)
|
|||
|
||||
F64 Recording::getMin( const StatType<EventAccumulator>& stat )
|
||||
{
|
||||
update();
|
||||
update();
|
||||
const EventAccumulator& accumulator = mBuffers->mEvents[stat.getIndex()];
|
||||
const EventAccumulator* active_accumulator = mActiveBuffers ? &mActiveBuffers->mEvents[stat.getIndex()] : NULL;
|
||||
return llmin(accumulator.getMin(), active_accumulator && active_accumulator->hasValue() ? active_accumulator->getMin() : F32_MAX);
|
||||
|
|
@ -513,7 +369,7 @@ F64 Recording::getMin( const StatType<EventAccumulator>& stat )
|
|||
|
||||
F64 Recording::getMax( const StatType<EventAccumulator>& stat )
|
||||
{
|
||||
update();
|
||||
update();
|
||||
const EventAccumulator& accumulator = mBuffers->mEvents[stat.getIndex()];
|
||||
const EventAccumulator* active_accumulator = mActiveBuffers ? &mActiveBuffers->mEvents[stat.getIndex()] : NULL;
|
||||
return llmax(accumulator.getMax(), active_accumulator && active_accumulator->hasValue() ? active_accumulator->getMax() : F32_MIN);
|
||||
|
|
@ -521,17 +377,17 @@ F64 Recording::getMax( const StatType<EventAccumulator>& stat )
|
|||
|
||||
F64 Recording::getMean( const StatType<EventAccumulator>& stat )
|
||||
{
|
||||
update();
|
||||
update();
|
||||
const EventAccumulator& accumulator = mBuffers->mEvents[stat.getIndex()];
|
||||
const EventAccumulator* active_accumulator = mActiveBuffers ? &mActiveBuffers->mEvents[stat.getIndex()] : NULL;
|
||||
if (active_accumulator && active_accumulator->hasValue())
|
||||
{
|
||||
F32 t = 0.0f;
|
||||
S32 div = accumulator.getSampleCount() + active_accumulator->getSampleCount();
|
||||
if (div > 0)
|
||||
{
|
||||
t = active_accumulator->getSampleCount() / div;
|
||||
}
|
||||
S32 div = accumulator.getSampleCount() + active_accumulator->getSampleCount();
|
||||
if (div > 0)
|
||||
{
|
||||
t = active_accumulator->getSampleCount() / div;
|
||||
}
|
||||
return lerp(accumulator.getMean(), active_accumulator->getMean(), t);
|
||||
}
|
||||
else
|
||||
|
|
@ -542,7 +398,7 @@ F64 Recording::getMean( const StatType<EventAccumulator>& stat )
|
|||
|
||||
F64 Recording::getStandardDeviation( const StatType<EventAccumulator>& stat )
|
||||
{
|
||||
update();
|
||||
update();
|
||||
const EventAccumulator& accumulator = mBuffers->mEvents[stat.getIndex()];
|
||||
const EventAccumulator* active_accumulator = mActiveBuffers ? &mActiveBuffers->mEvents[stat.getIndex()] : NULL;
|
||||
|
||||
|
|
@ -559,7 +415,7 @@ F64 Recording::getStandardDeviation( const StatType<EventAccumulator>& stat )
|
|||
|
||||
F64 Recording::getLastValue( const StatType<EventAccumulator>& stat )
|
||||
{
|
||||
update();
|
||||
update();
|
||||
const EventAccumulator& accumulator = mBuffers->mEvents[stat.getIndex()];
|
||||
const EventAccumulator* active_accumulator = mActiveBuffers ? &mActiveBuffers->mEvents[stat.getIndex()] : NULL;
|
||||
return active_accumulator ? active_accumulator->getLastValue() : accumulator.getLastValue();
|
||||
|
|
@ -567,7 +423,7 @@ F64 Recording::getLastValue( const StatType<EventAccumulator>& stat )
|
|||
|
||||
S32 Recording::getSampleCount( const StatType<EventAccumulator>& stat )
|
||||
{
|
||||
update();
|
||||
update();
|
||||
const EventAccumulator& accumulator = mBuffers->mEvents[stat.getIndex()];
|
||||
const EventAccumulator* active_accumulator = mActiveBuffers ? &mActiveBuffers->mEvents[stat.getIndex()] : NULL;
|
||||
return accumulator.getSampleCount() + (active_accumulator ? active_accumulator->getSampleCount() : 0);
|
||||
|
|
@ -577,7 +433,7 @@ S32 Recording::getSampleCount( const StatType<EventAccumulator>& stat )
|
|||
// PeriodicRecording
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
|
||||
PeriodicRecording::PeriodicRecording( size_t num_periods, EPlayState state)
|
||||
PeriodicRecording::PeriodicRecording( size_t num_periods, EPlayState state)
|
||||
: mAutoResize(num_periods == 0),
|
||||
mCurPeriod(0),
|
||||
mNumRecordedPeriods(0),
|
||||
|
|
@ -585,15 +441,13 @@ PeriodicRecording::PeriodicRecording( size_t num_periods, EPlayState state)
|
|||
// code in several methods.
|
||||
mRecordingPeriods(num_periods ? num_periods : 1)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
setPlayState(state);
|
||||
claim_alloc(gTraceMemStat, this);
|
||||
}
|
||||
|
||||
PeriodicRecording::~PeriodicRecording()
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
disclaim_alloc(gTraceMemStat, this);
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
}
|
||||
|
||||
void PeriodicRecording::nextPeriod()
|
||||
|
|
@ -615,12 +469,11 @@ void PeriodicRecording::nextPeriod()
|
|||
|
||||
void PeriodicRecording::appendRecording(Recording& recording)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
getCurRecording().appendRecording(recording);
|
||||
nextPeriod();
|
||||
}
|
||||
|
||||
|
||||
void PeriodicRecording::appendPeriodicRecording( PeriodicRecording& other )
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
|
|
@ -693,16 +546,14 @@ F64Seconds PeriodicRecording::getDuration() const
|
|||
return duration;
|
||||
}
|
||||
|
||||
|
||||
LLTrace::Recording PeriodicRecording::snapshotCurRecording() const
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
Recording recording_copy(getCurRecording());
|
||||
recording_copy.stop();
|
||||
return recording_copy;
|
||||
}
|
||||
|
||||
|
||||
Recording& PeriodicRecording::getLastRecording()
|
||||
{
|
||||
return getPrevRecording(1);
|
||||
|
|
@ -737,19 +588,19 @@ const Recording& PeriodicRecording::getPrevRecording( size_t offset ) const
|
|||
|
||||
void PeriodicRecording::handleStart()
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
getCurRecording().start();
|
||||
}
|
||||
|
||||
void PeriodicRecording::handleStop()
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
getCurRecording().pause();
|
||||
}
|
||||
|
||||
void PeriodicRecording::handleReset()
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
getCurRecording().stop();
|
||||
|
||||
if (mAutoResize)
|
||||
|
|
@ -771,13 +622,13 @@ void PeriodicRecording::handleReset()
|
|||
|
||||
void PeriodicRecording::handleSplitTo(PeriodicRecording& other)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
getCurRecording().splitTo(other.getCurRecording());
|
||||
}
|
||||
|
||||
F64 PeriodicRecording::getPeriodMin( const StatType<EventAccumulator>& stat, size_t num_periods /*= std::numeric_limits<size_t>::max()*/ )
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
num_periods = llmin(num_periods, getNumRecordedPeriods());
|
||||
|
||||
bool has_value = false;
|
||||
|
|
@ -792,14 +643,14 @@ F64 PeriodicRecording::getPeriodMin( const StatType<EventAccumulator>& stat, siz
|
|||
}
|
||||
}
|
||||
|
||||
return has_value
|
||||
? min_val
|
||||
return has_value
|
||||
? min_val
|
||||
: NaN;
|
||||
}
|
||||
|
||||
F64 PeriodicRecording::getPeriodMax( const StatType<EventAccumulator>& stat, size_t num_periods /*= std::numeric_limits<size_t>::max()*/ )
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
num_periods = llmin(num_periods, getNumRecordedPeriods());
|
||||
|
||||
bool has_value = false;
|
||||
|
|
@ -814,15 +665,15 @@ F64 PeriodicRecording::getPeriodMax( const StatType<EventAccumulator>& stat, siz
|
|||
}
|
||||
}
|
||||
|
||||
return has_value
|
||||
? max_val
|
||||
return has_value
|
||||
? max_val
|
||||
: NaN;
|
||||
}
|
||||
|
||||
// calculates means using aggregates per period
|
||||
F64 PeriodicRecording::getPeriodMean( const StatType<EventAccumulator>& stat, size_t num_periods /*= std::numeric_limits<size_t>::max()*/ )
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
num_periods = llmin(num_periods, getNumRecordedPeriods());
|
||||
|
||||
F64 mean = 0;
|
||||
|
|
@ -838,14 +689,14 @@ F64 PeriodicRecording::getPeriodMean( const StatType<EventAccumulator>& stat, si
|
|||
}
|
||||
}
|
||||
|
||||
return valid_period_count
|
||||
return valid_period_count
|
||||
? mean / (F64)valid_period_count
|
||||
: NaN;
|
||||
}
|
||||
|
||||
F64 PeriodicRecording::getPeriodStandardDeviation( const StatType<EventAccumulator>& stat, size_t num_periods /*= std::numeric_limits<size_t>::max()*/ )
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
num_periods = llmin(num_periods, getNumRecordedPeriods());
|
||||
|
||||
F64 period_mean = getPeriodMean(stat, num_periods);
|
||||
|
|
@ -870,7 +721,7 @@ F64 PeriodicRecording::getPeriodStandardDeviation( const StatType<EventAccumulat
|
|||
|
||||
F64 PeriodicRecording::getPeriodMin( const StatType<SampleAccumulator>& stat, size_t num_periods /*= std::numeric_limits<size_t>::max()*/ )
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
num_periods = llmin(num_periods, getNumRecordedPeriods());
|
||||
|
||||
bool has_value = false;
|
||||
|
|
@ -885,14 +736,14 @@ F64 PeriodicRecording::getPeriodMin( const StatType<SampleAccumulator>& stat, si
|
|||
}
|
||||
}
|
||||
|
||||
return has_value
|
||||
? min_val
|
||||
return has_value
|
||||
? min_val
|
||||
: NaN;
|
||||
}
|
||||
|
||||
F64 PeriodicRecording::getPeriodMax(const StatType<SampleAccumulator>& stat, size_t num_periods /*= std::numeric_limits<size_t>::max()*/)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
num_periods = llmin(num_periods, getNumRecordedPeriods());
|
||||
|
||||
bool has_value = false;
|
||||
|
|
@ -907,15 +758,15 @@ F64 PeriodicRecording::getPeriodMax(const StatType<SampleAccumulator>& stat, siz
|
|||
}
|
||||
}
|
||||
|
||||
return has_value
|
||||
? max_val
|
||||
return has_value
|
||||
? max_val
|
||||
: NaN;
|
||||
}
|
||||
|
||||
|
||||
F64 PeriodicRecording::getPeriodMean( const StatType<SampleAccumulator>& stat, size_t num_periods /*= std::numeric_limits<size_t>::max()*/ )
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
num_periods = llmin(num_periods, getNumRecordedPeriods());
|
||||
|
||||
S32 valid_period_count = 0;
|
||||
|
|
@ -938,7 +789,7 @@ F64 PeriodicRecording::getPeriodMean( const StatType<SampleAccumulator>& stat, s
|
|||
|
||||
F64 PeriodicRecording::getPeriodMedian( const StatType<SampleAccumulator>& stat, size_t num_periods /*= std::numeric_limits<size_t>::max()*/ )
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
num_periods = llmin(num_periods, getNumRecordedPeriods());
|
||||
|
||||
std::vector<F64> buf;
|
||||
|
|
@ -964,7 +815,7 @@ F64 PeriodicRecording::getPeriodMedian( const StatType<SampleAccumulator>& stat,
|
|||
|
||||
F64 PeriodicRecording::getPeriodStandardDeviation( const StatType<SampleAccumulator>& stat, size_t num_periods /*= std::numeric_limits<size_t>::max()*/ )
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
num_periods = llmin(num_periods, getNumRecordedPeriods());
|
||||
|
||||
F64 period_mean = getPeriodMean(stat, num_periods);
|
||||
|
|
@ -987,105 +838,13 @@ F64 PeriodicRecording::getPeriodStandardDeviation( const StatType<SampleAccumula
|
|||
: NaN;
|
||||
}
|
||||
|
||||
|
||||
F64Kilobytes PeriodicRecording::getPeriodMin( const StatType<MemAccumulator>& stat, size_t num_periods /*= std::numeric_limits<size_t>::max()*/ )
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
num_periods = llmin(num_periods, getNumRecordedPeriods());
|
||||
|
||||
F64Kilobytes min_val(std::numeric_limits<F64>::max());
|
||||
for (size_t i = 1; i <= num_periods; i++)
|
||||
{
|
||||
Recording& recording = getPrevRecording(i);
|
||||
min_val = llmin(min_val, recording.getMin(stat));
|
||||
}
|
||||
|
||||
return min_val;
|
||||
}
|
||||
|
||||
F64Kilobytes PeriodicRecording::getPeriodMin(const MemStatHandle& stat, size_t num_periods)
|
||||
{
|
||||
return getPeriodMin(static_cast<const StatType<MemAccumulator>&>(stat), num_periods);
|
||||
}
|
||||
|
||||
F64Kilobytes PeriodicRecording::getPeriodMax(const StatType<MemAccumulator>& stat, size_t num_periods /*= std::numeric_limits<size_t>::max()*/)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
num_periods = llmin(num_periods, getNumRecordedPeriods());
|
||||
|
||||
F64Kilobytes max_val(0.0);
|
||||
for (size_t i = 1; i <= num_periods; i++)
|
||||
{
|
||||
Recording& recording = getPrevRecording(i);
|
||||
max_val = llmax(max_val, recording.getMax(stat));
|
||||
}
|
||||
|
||||
return max_val;
|
||||
}
|
||||
|
||||
F64Kilobytes PeriodicRecording::getPeriodMax(const MemStatHandle& stat, size_t num_periods)
|
||||
{
|
||||
return getPeriodMax(static_cast<const StatType<MemAccumulator>&>(stat), num_periods);
|
||||
}
|
||||
|
||||
F64Kilobytes PeriodicRecording::getPeriodMean( const StatType<MemAccumulator>& stat, size_t num_periods /*= std::numeric_limits<size_t>::max()*/ )
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
num_periods = llmin(num_periods, getNumRecordedPeriods());
|
||||
|
||||
F64Kilobytes mean(0);
|
||||
|
||||
for (size_t i = 1; i <= num_periods; i++)
|
||||
{
|
||||
Recording& recording = getPrevRecording(i);
|
||||
mean += recording.getMean(stat);
|
||||
}
|
||||
|
||||
return mean / F64(num_periods);
|
||||
}
|
||||
|
||||
F64Kilobytes PeriodicRecording::getPeriodMean(const MemStatHandle& stat, size_t num_periods)
|
||||
{
|
||||
return getPeriodMean(static_cast<const StatType<MemAccumulator>&>(stat), num_periods);
|
||||
}
|
||||
|
||||
F64Kilobytes PeriodicRecording::getPeriodStandardDeviation( const StatType<MemAccumulator>& stat, size_t num_periods /*= std::numeric_limits<size_t>::max()*/ )
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
num_periods = llmin(num_periods, getNumRecordedPeriods());
|
||||
|
||||
F64Kilobytes period_mean = getPeriodMean(stat, num_periods);
|
||||
S32 valid_period_count = 0;
|
||||
F64 sum_of_squares = 0;
|
||||
|
||||
for (size_t i = 1; i <= num_periods; i++)
|
||||
{
|
||||
Recording& recording = getPrevRecording(i);
|
||||
if (recording.hasValue(stat))
|
||||
{
|
||||
F64Kilobytes delta = recording.getMean(stat) - period_mean;
|
||||
sum_of_squares += delta.value() * delta.value();
|
||||
valid_period_count++;
|
||||
}
|
||||
}
|
||||
|
||||
return F64Kilobytes(valid_period_count
|
||||
? sqrt(sum_of_squares / (F64)valid_period_count)
|
||||
: NaN);
|
||||
}
|
||||
|
||||
F64Kilobytes PeriodicRecording::getPeriodStandardDeviation(const MemStatHandle& stat, size_t num_periods)
|
||||
{
|
||||
return getPeriodStandardDeviation(static_cast<const StatType<MemAccumulator>&>(stat), num_periods);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
// ExtendableRecording
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
|
||||
void ExtendableRecording::extend()
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
// push the data back to accepted recording
|
||||
mAcceptedRecording.appendRecording(mPotentialRecording);
|
||||
// flush data, so we can start from scratch
|
||||
|
|
@ -1094,76 +853,72 @@ void ExtendableRecording::extend()
|
|||
|
||||
void ExtendableRecording::handleStart()
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
mPotentialRecording.start();
|
||||
}
|
||||
|
||||
void ExtendableRecording::handleStop()
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
mPotentialRecording.pause();
|
||||
}
|
||||
|
||||
void ExtendableRecording::handleReset()
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
mAcceptedRecording.reset();
|
||||
mPotentialRecording.reset();
|
||||
}
|
||||
|
||||
void ExtendableRecording::handleSplitTo(ExtendableRecording& other)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
mPotentialRecording.splitTo(other.mPotentialRecording);
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
// ExtendablePeriodicRecording
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
ExtendablePeriodicRecording::ExtendablePeriodicRecording()
|
||||
: mAcceptedRecording(0),
|
||||
ExtendablePeriodicRecording::ExtendablePeriodicRecording()
|
||||
: mAcceptedRecording(0),
|
||||
mPotentialRecording(0)
|
||||
{}
|
||||
|
||||
void ExtendablePeriodicRecording::extend()
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
// push the data back to accepted recording
|
||||
mAcceptedRecording.appendPeriodicRecording(mPotentialRecording);
|
||||
// flush data, so we can start from scratch
|
||||
mPotentialRecording.reset();
|
||||
}
|
||||
|
||||
|
||||
void ExtendablePeriodicRecording::handleStart()
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
mPotentialRecording.start();
|
||||
}
|
||||
|
||||
void ExtendablePeriodicRecording::handleStop()
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
mPotentialRecording.pause();
|
||||
}
|
||||
|
||||
void ExtendablePeriodicRecording::handleReset()
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
mAcceptedRecording.reset();
|
||||
mPotentialRecording.reset();
|
||||
}
|
||||
|
||||
void ExtendablePeriodicRecording::handleSplitTo(ExtendablePeriodicRecording& other)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
mPotentialRecording.splitTo(other.mPotentialRecording);
|
||||
}
|
||||
|
||||
|
||||
PeriodicRecording& get_frame_recording()
|
||||
{
|
||||
static thread_local PeriodicRecording sRecording(200, PeriodicRecording::STARTED);
|
||||
|
|
@ -1174,7 +929,7 @@ PeriodicRecording& get_frame_recording()
|
|||
|
||||
void LLStopWatchControlsMixinCommon::start()
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
switch (mPlayState)
|
||||
{
|
||||
case STOPPED:
|
||||
|
|
@ -1196,7 +951,7 @@ void LLStopWatchControlsMixinCommon::start()
|
|||
|
||||
void LLStopWatchControlsMixinCommon::stop()
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
switch (mPlayState)
|
||||
{
|
||||
case STOPPED:
|
||||
|
|
@ -1216,7 +971,7 @@ void LLStopWatchControlsMixinCommon::stop()
|
|||
|
||||
void LLStopWatchControlsMixinCommon::pause()
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
switch (mPlayState)
|
||||
{
|
||||
case STOPPED:
|
||||
|
|
@ -1236,7 +991,7 @@ void LLStopWatchControlsMixinCommon::pause()
|
|||
|
||||
void LLStopWatchControlsMixinCommon::unpause()
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
switch (mPlayState)
|
||||
{
|
||||
case STOPPED:
|
||||
|
|
@ -1256,7 +1011,7 @@ void LLStopWatchControlsMixinCommon::unpause()
|
|||
|
||||
void LLStopWatchControlsMixinCommon::resume()
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
switch (mPlayState)
|
||||
{
|
||||
case STOPPED:
|
||||
|
|
@ -1277,7 +1032,7 @@ void LLStopWatchControlsMixinCommon::resume()
|
|||
|
||||
void LLStopWatchControlsMixinCommon::restart()
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
switch (mPlayState)
|
||||
{
|
||||
case STOPPED:
|
||||
|
|
@ -1301,13 +1056,13 @@ void LLStopWatchControlsMixinCommon::restart()
|
|||
|
||||
void LLStopWatchControlsMixinCommon::reset()
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
handleReset();
|
||||
}
|
||||
|
||||
void LLStopWatchControlsMixinCommon::setPlayState( EPlayState state )
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
switch(state)
|
||||
{
|
||||
case STOPPED:
|
||||
|
|
|
|||
|
|
@ -1,25 +1,25 @@
|
|||
/**
|
||||
/**
|
||||
* @file lltracerecording.h
|
||||
* @brief Sampling object for collecting runtime statistics originating from lltrace.
|
||||
*
|
||||
* $LicenseInfo:firstyear=2001&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2012, 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$
|
||||
*/
|
||||
|
|
@ -112,7 +112,6 @@ private:
|
|||
// atomically stop this object while starting the other
|
||||
// no data can be missed in between stop and start
|
||||
virtual void handleSplitTo(DERIVED& other) {};
|
||||
|
||||
};
|
||||
|
||||
namespace LLTrace
|
||||
|
|
@ -129,8 +128,6 @@ namespace LLTrace
|
|||
template<typename T>
|
||||
class EventStatHandle;
|
||||
|
||||
class MemStatHandle;
|
||||
|
||||
template<typename T>
|
||||
struct RelatedTypes
|
||||
{
|
||||
|
|
@ -152,7 +149,7 @@ namespace LLTrace
|
|||
typedef S32 sum_t;
|
||||
};
|
||||
|
||||
class Recording
|
||||
class Recording
|
||||
: public LLStopWatchControlsMixin<Recording>
|
||||
{
|
||||
public:
|
||||
|
|
@ -182,24 +179,6 @@ namespace LLTrace
|
|||
F64Seconds getPerSec(const StatType<TimeBlockAccumulator::SelfTimeFacet>& stat);
|
||||
F32 getPerSec(const StatType<TimeBlockAccumulator::CallCountFacet>& stat);
|
||||
|
||||
// Memory accessors
|
||||
bool hasValue(const StatType<MemAccumulator>& stat);
|
||||
F64Kilobytes getMin(const StatType<MemAccumulator>& stat);
|
||||
F64Kilobytes getMean(const StatType<MemAccumulator>& stat);
|
||||
F64Kilobytes getMax(const StatType<MemAccumulator>& stat);
|
||||
F64Kilobytes getStandardDeviation(const StatType<MemAccumulator>& stat);
|
||||
F64Kilobytes getLastValue(const StatType<MemAccumulator>& stat);
|
||||
|
||||
bool hasValue(const StatType<MemAccumulator::AllocationFacet>& stat);
|
||||
F64Kilobytes getSum(const StatType<MemAccumulator::AllocationFacet>& stat);
|
||||
F64Kilobytes getPerSec(const StatType<MemAccumulator::AllocationFacet>& stat);
|
||||
S32 getSampleCount(const StatType<MemAccumulator::AllocationFacet>& stat);
|
||||
|
||||
bool hasValue(const StatType<MemAccumulator::DeallocationFacet>& stat);
|
||||
F64Kilobytes getSum(const StatType<MemAccumulator::DeallocationFacet>& stat);
|
||||
F64Kilobytes getPerSec(const StatType<MemAccumulator::DeallocationFacet>& stat);
|
||||
S32 getSampleCount(const StatType<MemAccumulator::DeallocationFacet>& stat);
|
||||
|
||||
// CountStatHandle accessors
|
||||
bool hasValue(const StatType<CountAccumulator>& stat);
|
||||
F64 getSum(const StatType<CountAccumulator>& stat);
|
||||
|
|
@ -318,7 +297,7 @@ namespace LLTrace
|
|||
/*virtual*/ void handleSplitTo(Recording& other);
|
||||
|
||||
// returns data for current thread
|
||||
class ThreadRecorder* getThreadRecorder();
|
||||
class ThreadRecorder* getThreadRecorder();
|
||||
|
||||
LLTimer mSamplingTimer;
|
||||
F64Seconds mElapsedSeconds;
|
||||
|
|
@ -335,10 +314,10 @@ namespace LLTrace
|
|||
~PeriodicRecording();
|
||||
|
||||
void nextPeriod();
|
||||
auto getNumRecordedPeriods()
|
||||
{
|
||||
auto getNumRecordedPeriods()
|
||||
{
|
||||
// current period counts if not active
|
||||
return mNumRecordedPeriods + (isStarted() ? 0 : 1);
|
||||
return mNumRecordedPeriods + (isStarted() ? 0 : 1);
|
||||
}
|
||||
|
||||
F64Seconds getDuration() const;
|
||||
|
|
@ -367,7 +346,7 @@ namespace LLTrace
|
|||
}
|
||||
return num_samples;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// PERIODIC MIN
|
||||
//
|
||||
|
|
@ -376,7 +355,7 @@ namespace LLTrace
|
|||
template <typename T>
|
||||
typename T::value_t getPeriodMin(const StatType<T>& stat, size_t num_periods = std::numeric_limits<size_t>::max())
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
num_periods = llmin(num_periods, getNumRecordedPeriods());
|
||||
|
||||
bool has_value = false;
|
||||
|
|
@ -391,15 +370,15 @@ namespace LLTrace
|
|||
}
|
||||
}
|
||||
|
||||
return has_value
|
||||
? min_val
|
||||
return has_value
|
||||
? min_val
|
||||
: T::getDefaultValue();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T getPeriodMin(const CountStatHandle<T>& stat, size_t num_periods = std::numeric_limits<size_t>::max())
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
return T(getPeriodMin(static_cast<const StatType<CountAccumulator>&>(stat), num_periods));
|
||||
}
|
||||
|
||||
|
|
@ -407,7 +386,7 @@ namespace LLTrace
|
|||
template<typename T>
|
||||
T getPeriodMin(const SampleStatHandle<T>& stat, size_t num_periods = std::numeric_limits<size_t>::max())
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
return T(getPeriodMin(static_cast<const StatType<SampleAccumulator>&>(stat), num_periods));
|
||||
}
|
||||
|
||||
|
|
@ -415,17 +394,14 @@ namespace LLTrace
|
|||
template<typename T>
|
||||
T getPeriodMin(const EventStatHandle<T>& stat, size_t num_periods = std::numeric_limits<size_t>::max())
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
return T(getPeriodMin(static_cast<const StatType<EventAccumulator>&>(stat), num_periods));
|
||||
}
|
||||
|
||||
F64Kilobytes getPeriodMin(const StatType<MemAccumulator>& stat, size_t num_periods = std::numeric_limits<size_t>::max());
|
||||
F64Kilobytes getPeriodMin(const MemStatHandle& stat, size_t num_periods = std::numeric_limits<size_t>::max());
|
||||
|
||||
template <typename T>
|
||||
typename RelatedTypes<typename T::value_t>::fractional_t getPeriodMinPerSec(const StatType<T>& stat, size_t num_periods = std::numeric_limits<size_t>::max())
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
num_periods = llmin(num_periods, getNumRecordedPeriods());
|
||||
|
||||
typename RelatedTypes<typename T::value_t>::fractional_t min_val(std::numeric_limits<F64>::max());
|
||||
|
|
@ -440,7 +416,7 @@ namespace LLTrace
|
|||
template<typename T>
|
||||
typename RelatedTypes<T>::fractional_t getPeriodMinPerSec(const CountStatHandle<T>& stat, size_t num_periods = std::numeric_limits<size_t>::max())
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
return typename RelatedTypes<T>::fractional_t(getPeriodMinPerSec(static_cast<const StatType<CountAccumulator>&>(stat), num_periods));
|
||||
}
|
||||
|
||||
|
|
@ -452,7 +428,7 @@ namespace LLTrace
|
|||
template <typename T>
|
||||
typename T::value_t getPeriodMax(const StatType<T>& stat, size_t num_periods = std::numeric_limits<size_t>::max())
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
num_periods = llmin(num_periods, getNumRecordedPeriods());
|
||||
|
||||
bool has_value = false;
|
||||
|
|
@ -467,15 +443,15 @@ namespace LLTrace
|
|||
}
|
||||
}
|
||||
|
||||
return has_value
|
||||
? max_val
|
||||
return has_value
|
||||
? max_val
|
||||
: T::getDefaultValue();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T getPeriodMax(const CountStatHandle<T>& stat, size_t num_periods = std::numeric_limits<size_t>::max())
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
return T(getPeriodMax(static_cast<const StatType<CountAccumulator>&>(stat), num_periods));
|
||||
}
|
||||
|
||||
|
|
@ -483,7 +459,7 @@ namespace LLTrace
|
|||
template<typename T>
|
||||
T getPeriodMax(const SampleStatHandle<T>& stat, size_t num_periods = std::numeric_limits<size_t>::max())
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
return T(getPeriodMax(static_cast<const StatType<SampleAccumulator>&>(stat), num_periods));
|
||||
}
|
||||
|
||||
|
|
@ -491,17 +467,14 @@ namespace LLTrace
|
|||
template<typename T>
|
||||
T getPeriodMax(const EventStatHandle<T>& stat, size_t num_periods = std::numeric_limits<size_t>::max())
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
return T(getPeriodMax(static_cast<const StatType<EventAccumulator>&>(stat), num_periods));
|
||||
}
|
||||
|
||||
F64Kilobytes getPeriodMax(const StatType<MemAccumulator>& stat, size_t num_periods = std::numeric_limits<size_t>::max());
|
||||
F64Kilobytes getPeriodMax(const MemStatHandle& stat, size_t num_periods = std::numeric_limits<size_t>::max());
|
||||
|
||||
template <typename T>
|
||||
typename RelatedTypes<typename T::value_t>::fractional_t getPeriodMaxPerSec(const StatType<T>& stat, size_t num_periods = std::numeric_limits<size_t>::max())
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
num_periods = llmin(num_periods, getNumRecordedPeriods());
|
||||
|
||||
F64 max_val = std::numeric_limits<F64>::min();
|
||||
|
|
@ -516,7 +489,7 @@ namespace LLTrace
|
|||
template<typename T>
|
||||
typename RelatedTypes<T>::fractional_t getPeriodMaxPerSec(const CountStatHandle<T>& stat, size_t num_periods = std::numeric_limits<size_t>::max())
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
return typename RelatedTypes<T>::fractional_t(getPeriodMaxPerSec(static_cast<const StatType<CountAccumulator>&>(stat), num_periods));
|
||||
}
|
||||
|
||||
|
|
@ -528,7 +501,7 @@ namespace LLTrace
|
|||
template <typename T>
|
||||
typename RelatedTypes<typename T::value_t>::fractional_t getPeriodMean(const StatType<T >& stat, size_t num_periods = std::numeric_limits<size_t>::max())
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
num_periods = llmin(num_periods, getNumRecordedPeriods());
|
||||
|
||||
typename RelatedTypes<typename T::value_t>::fractional_t mean(0);
|
||||
|
|
@ -549,14 +522,14 @@ namespace LLTrace
|
|||
template<typename T>
|
||||
typename RelatedTypes<T>::fractional_t getPeriodMean(const CountStatHandle<T>& stat, size_t num_periods = std::numeric_limits<size_t>::max())
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
return typename RelatedTypes<T>::fractional_t(getPeriodMean(static_cast<const StatType<CountAccumulator>&>(stat), num_periods));
|
||||
}
|
||||
F64 getPeriodMean(const StatType<SampleAccumulator>& stat, size_t num_periods = std::numeric_limits<size_t>::max());
|
||||
template<typename T>
|
||||
template<typename T>
|
||||
typename RelatedTypes<T>::fractional_t getPeriodMean(const SampleStatHandle<T>& stat, size_t num_periods = std::numeric_limits<size_t>::max())
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
return typename RelatedTypes<T>::fractional_t(getPeriodMean(static_cast<const StatType<SampleAccumulator>&>(stat), num_periods));
|
||||
}
|
||||
|
||||
|
|
@ -564,17 +537,14 @@ namespace LLTrace
|
|||
template<typename T>
|
||||
typename RelatedTypes<T>::fractional_t getPeriodMean(const EventStatHandle<T>& stat, size_t num_periods = std::numeric_limits<size_t>::max())
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
return typename RelatedTypes<T>::fractional_t(getPeriodMean(static_cast<const StatType<EventAccumulator>&>(stat), num_periods));
|
||||
}
|
||||
|
||||
F64Kilobytes getPeriodMean(const StatType<MemAccumulator>& stat, size_t num_periods = std::numeric_limits<size_t>::max());
|
||||
F64Kilobytes getPeriodMean(const MemStatHandle& stat, size_t num_periods = std::numeric_limits<size_t>::max());
|
||||
|
||||
template <typename T>
|
||||
typename RelatedTypes<typename T::value_t>::fractional_t getPeriodMeanPerSec(const StatType<T>& stat, size_t num_periods = std::numeric_limits<size_t>::max())
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
num_periods = llmin(num_periods, getNumRecordedPeriods());
|
||||
|
||||
typename RelatedTypes<typename T::value_t>::fractional_t mean = 0;
|
||||
|
|
@ -596,7 +566,7 @@ namespace LLTrace
|
|||
template<typename T>
|
||||
typename RelatedTypes<T>::fractional_t getPeriodMeanPerSec(const CountStatHandle<T>& stat, size_t num_periods = std::numeric_limits<size_t>::max())
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
return typename RelatedTypes<T>::fractional_t(getPeriodMeanPerSec(static_cast<const StatType<CountAccumulator>&>(stat), num_periods));
|
||||
}
|
||||
|
||||
|
|
@ -635,10 +605,10 @@ namespace LLTrace
|
|||
|
||||
F64 getPeriodStandardDeviation(const StatType<SampleAccumulator>& stat, size_t num_periods = std::numeric_limits<size_t>::max());
|
||||
|
||||
template<typename T>
|
||||
template<typename T>
|
||||
typename RelatedTypes<T>::fractional_t getPeriodStandardDeviation(const SampleStatHandle<T>& stat, size_t num_periods = std::numeric_limits<size_t>::max())
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
return typename RelatedTypes<T>::fractional_t(getPeriodStandardDeviation(static_cast<const StatType<SampleAccumulator>&>(stat), num_periods));
|
||||
}
|
||||
|
||||
|
|
@ -646,13 +616,10 @@ namespace LLTrace
|
|||
template<typename T>
|
||||
typename RelatedTypes<T>::fractional_t getPeriodStandardDeviation(const EventStatHandle<T>& stat, size_t num_periods = std::numeric_limits<size_t>::max())
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
return typename RelatedTypes<T>::fractional_t(getPeriodStandardDeviation(static_cast<const StatType<EventAccumulator>&>(stat), num_periods));
|
||||
}
|
||||
|
||||
F64Kilobytes getPeriodStandardDeviation(const StatType<MemAccumulator>& stat, size_t num_periods = std::numeric_limits<size_t>::max());
|
||||
F64Kilobytes getPeriodStandardDeviation(const MemStatHandle& stat, size_t num_periods = std::numeric_limits<size_t>::max());
|
||||
|
||||
private:
|
||||
// implementation for LLStopWatchControlsMixin
|
||||
/*virtual*/ void handleStart();
|
||||
|
|
@ -731,7 +698,7 @@ namespace LLTrace
|
|||
|
||||
PeriodicRecording& getResults() { return mAcceptedRecording; }
|
||||
const PeriodicRecording& getResults() const {return mAcceptedRecording;}
|
||||
|
||||
|
||||
void nextPeriod() { mPotentialRecording.nextPeriod(); }
|
||||
|
||||
private:
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@
|
|||
|
||||
namespace LLTrace
|
||||
{
|
||||
extern MemStatHandle gTraceMemStat;
|
||||
//extern MemStatHandle gTraceMemStat;
|
||||
|
||||
static ThreadRecorder* sMasterThreadRecorder = NULL;
|
||||
|
||||
|
|
@ -81,9 +81,9 @@ void ThreadRecorder::init()
|
|||
|
||||
BlockTimer::getRootTimeBlock().getCurrentAccumulator().mActiveCount = 1;
|
||||
|
||||
claim_alloc(gTraceMemStat, this);
|
||||
claim_alloc(gTraceMemStat, mRootTimer);
|
||||
claim_alloc(gTraceMemStat, sizeof(TimeBlockTreeNode) * mNumTimeBlockTreeNodes);
|
||||
//claim_alloc(gTraceMemStat, this);
|
||||
//claim_alloc(gTraceMemStat, mRootTimer);
|
||||
//claim_alloc(gTraceMemStat, sizeof(TimeBlockTreeNode) * mNumTimeBlockTreeNodes);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
@ -101,9 +101,9 @@ ThreadRecorder::~ThreadRecorder()
|
|||
#if LL_TRACE_ENABLED
|
||||
LLThreadLocalSingletonPointer<BlockTimerStackRecord>::setInstance(NULL);
|
||||
|
||||
disclaim_alloc(gTraceMemStat, this);
|
||||
disclaim_alloc(gTraceMemStat, sizeof(BlockTimer));
|
||||
disclaim_alloc(gTraceMemStat, sizeof(TimeBlockTreeNode) * mNumTimeBlockTreeNodes);
|
||||
//disclaim_alloc(gTraceMemStat, this);
|
||||
//disclaim_alloc(gTraceMemStat, sizeof(BlockTimer));
|
||||
//disclaim_alloc(gTraceMemStat, sizeof(TimeBlockTreeNode) * mNumTimeBlockTreeNodes);
|
||||
|
||||
deactivate(&mThreadRecordingBuffers);
|
||||
|
||||
|
|
|
|||
|
|
@ -164,8 +164,10 @@ void LLUriParser::extractParts()
|
|||
#if LL_DARWIN
|
||||
typedef void(*sighandler_t)(int);
|
||||
jmp_buf return_to_normalize;
|
||||
static int sLastSignal = 0;
|
||||
void uri_signal_handler(int signal)
|
||||
{
|
||||
sLastSignal = signal;
|
||||
// Apparently signal handler throwing an exception doesn't work.
|
||||
// This is ugly and unsafe due to not unwinding content of uriparser library,
|
||||
// but unless we have a way to catch this as NSexception, jump appears to be the only option.
|
||||
|
|
@ -179,8 +181,10 @@ S32 LLUriParser::normalize()
|
|||
if (!mRes)
|
||||
{
|
||||
#if LL_DARWIN
|
||||
sighandler_t last_handler;
|
||||
last_handler = signal(SIGILL, &uri_signal_handler); // illegal instruction
|
||||
sighandler_t last_sigill_handler, last_sigbus_handler;
|
||||
last_sigill_handler = signal(SIGILL, &uri_signal_handler); // illegal instruction
|
||||
last_sigbus_handler = signal(SIGBUS, &uri_signal_handler);
|
||||
|
||||
if (setjmp(return_to_normalize))
|
||||
{
|
||||
// Issue: external library crashed via signal
|
||||
|
|
@ -194,8 +198,9 @@ S32 LLUriParser::normalize()
|
|||
// if this can be handled by NSexception, it needs to be remade
|
||||
llassert(0);
|
||||
|
||||
LL_WARNS() << "Uriparser crashed with SIGILL, while processing: " << mNormalizedUri << LL_ENDL;
|
||||
signal(SIGILL, last_handler);
|
||||
LL_WARNS() << "Uriparser crashed with " << sLastSignal << " , while processing: " << mNormalizedUri << LL_ENDL;
|
||||
signal(SIGILL, last_sigill_handler);
|
||||
signal(SIGBUS, last_sigbus_handler);
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
|
@ -203,7 +208,8 @@ S32 LLUriParser::normalize()
|
|||
mRes = uriNormalizeSyntaxExA(&mUri, URI_NORMALIZE_SCHEME | URI_NORMALIZE_HOST);
|
||||
|
||||
#if LL_DARWIN
|
||||
signal(SIGILL, last_handler);
|
||||
signal(SIGILL, last_sigill_handler);
|
||||
signal(SIGBUS, last_sigbus_handler);
|
||||
#endif
|
||||
|
||||
if (!mRes)
|
||||
|
|
@ -226,7 +232,7 @@ S32 LLUriParser::normalize()
|
|||
}
|
||||
}
|
||||
|
||||
if(mTmpScheme)
|
||||
if(mTmpScheme && mNormalizedUri.size() > 7)
|
||||
{
|
||||
mNormalizedUri = mNormalizedUri.substr(7);
|
||||
mTmpScheme = false;
|
||||
|
|
|
|||
|
|
@ -156,18 +156,15 @@ typedef int intptr_t;
|
|||
* type.
|
||||
*/
|
||||
// narrow_holder is a struct that accepts the passed value as its original
|
||||
// type and provides templated conversion functions to other types. Once we're
|
||||
// building with compilers that support Class Template Argument Deduction, we
|
||||
// can rename this class template 'narrow' and eliminate the narrow() factory
|
||||
// function below.
|
||||
// type and provides templated conversion functions to other types.
|
||||
template <typename FROM>
|
||||
class narrow_holder
|
||||
class narrow
|
||||
{
|
||||
private:
|
||||
FROM mValue;
|
||||
|
||||
public:
|
||||
narrow_holder(FROM value): mValue(value) {}
|
||||
narrow(FROM value): mValue(value) {}
|
||||
|
||||
/*---------------------- Narrowing unsigned to signed ----------------------*/
|
||||
template <typename TO,
|
||||
|
|
@ -207,13 +204,4 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
/// narrow() factory function returns a narrow_holder<FROM>(), which can be
|
||||
/// implicitly converted to the target type.
|
||||
template <typename FROM>
|
||||
inline
|
||||
narrow_holder<FROM> narrow(FROM value)
|
||||
{
|
||||
return { value };
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -46,11 +46,12 @@ namespace tut
|
|||
// the real time required for each push() call. Explicitly increment
|
||||
// the timestamp for each one -- but since we're passing explicit
|
||||
// timestamps, make the queue reorder them.
|
||||
queue.push(Queue::TimeTuple(Queue::Clock::now() + 200ms, "ghi"));
|
||||
auto now{ Queue::Clock::now() };
|
||||
queue.push(Queue::TimeTuple(now + 200ms, "ghi"));
|
||||
// Given the various push() overloads, you have to match the type
|
||||
// exactly: conversions are ambiguous.
|
||||
queue.push("abc"s);
|
||||
queue.push(Queue::Clock::now() + 100ms, "def");
|
||||
queue.push(now + 100ms, "def");
|
||||
queue.close();
|
||||
auto entry = queue.pop();
|
||||
ensure_equals("failed to pop first", std::get<0>(entry), "abc"s);
|
||||
|
|
|
|||
|
|
@ -60,12 +60,15 @@ struct sleepy_robin: public boost::fibers::algo::round_robin
|
|||
/*****************************************************************************
|
||||
* ThreadPoolBase
|
||||
*****************************************************************************/
|
||||
LL::ThreadPoolBase::ThreadPoolBase(const std::string& name, size_t threads,
|
||||
WorkQueueBase* queue):
|
||||
LL::ThreadPoolBase::ThreadPoolBase(const std::string& name,
|
||||
size_t threads,
|
||||
WorkQueueBase* queue,
|
||||
bool auto_shutdown):
|
||||
super(name),
|
||||
mName("ThreadPool:" + name),
|
||||
mThreadCount(getConfiguredWidth(name, threads)),
|
||||
mQueue(queue)
|
||||
mQueue(queue),
|
||||
mAutomaticShutdown(auto_shutdown)
|
||||
{}
|
||||
|
||||
void LL::ThreadPoolBase::start()
|
||||
|
|
@ -80,6 +83,14 @@ void LL::ThreadPoolBase::start()
|
|||
run(tname);
|
||||
});
|
||||
}
|
||||
|
||||
if (!mAutomaticShutdown)
|
||||
{
|
||||
// Some threads, like main window's might need to run a bit longer
|
||||
// to wait for a proper shutdown message
|
||||
return;
|
||||
}
|
||||
|
||||
// Listen on "LLApp", and when the app is shutting down, close the queue
|
||||
// and join the workers.
|
||||
LLEventPumps::instance().obtain("LLApp").listen(
|
||||
|
|
@ -110,8 +121,11 @@ void LL::ThreadPoolBase::close()
|
|||
mQueue->close();
|
||||
for (auto& pair: mThreads)
|
||||
{
|
||||
LL_DEBUGS("ThreadPool") << mName << " waiting on thread " << pair.first << LL_ENDL;
|
||||
pair.second.join();
|
||||
if (pair.second.joinable())
|
||||
{
|
||||
LL_DEBUGS("ThreadPool") << mName << " waiting on thread " << pair.first << LL_ENDL;
|
||||
pair.second.join();
|
||||
}
|
||||
}
|
||||
LL_DEBUGS("ThreadPool") << mName << " shutdown complete" << LL_ENDL;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ namespace LL
|
|||
* overrides this parameter.
|
||||
*/
|
||||
ThreadPoolBase(const std::string& name, size_t threads,
|
||||
WorkQueueBase* queue);
|
||||
WorkQueueBase* queue, bool auto_shutdown = true);
|
||||
virtual ~ThreadPoolBase();
|
||||
|
||||
/**
|
||||
|
|
@ -55,10 +55,7 @@ namespace LL
|
|||
* ThreadPool listens for application shutdown messages on the "LLApp"
|
||||
* LLEventPump. Call close() to shut down this ThreadPool early.
|
||||
*/
|
||||
// <FS:Beq> [FIRE-32453][BUG-232971] Improve shutdown behaviour.
|
||||
// void close();
|
||||
virtual void close();
|
||||
// </FS:Beq>
|
||||
|
||||
std::string getName() const { return mName; }
|
||||
size_t getWidth() const { return mThreads.size(); }
|
||||
|
|
@ -90,14 +87,14 @@ namespace LL
|
|||
|
||||
protected:
|
||||
std::unique_ptr<WorkQueueBase> mQueue;
|
||||
std::vector<std::pair<std::string, std::thread>> mThreads;
|
||||
bool mAutomaticShutdown;
|
||||
|
||||
private:
|
||||
void run(const std::string& name);
|
||||
|
||||
protected: // <FS:Beq/> [FIRE-32453][BUG-232971] Improve shutdown behaviour.
|
||||
|
||||
std::string mName;
|
||||
size_t mThreadCount;
|
||||
std::vector<std::pair<std::string, std::thread>> mThreads;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -121,8 +118,11 @@ namespace LL
|
|||
* Constraining the queue can cause a submitter to block. Do not
|
||||
* constrain any ThreadPool accepting work from the main thread.
|
||||
*/
|
||||
ThreadPoolUsing(const std::string& name, size_t threads=1, size_t capacity=1024*1024):
|
||||
ThreadPoolBase(name, threads, new queue_t(name, capacity))
|
||||
ThreadPoolUsing(const std::string& name,
|
||||
size_t threads=1,
|
||||
size_t capacity=1024*1024,
|
||||
bool auto_shutdown = true):
|
||||
ThreadPoolBase(name, threads, new queue_t(name, capacity), auto_shutdown)
|
||||
{}
|
||||
~ThreadPoolUsing() override {}
|
||||
|
||||
|
|
|
|||
|
|
@ -288,7 +288,7 @@ int BufferArray::findBlock(size_t pos, size_t * ret_offset)
|
|||
if (pos >= mLen)
|
||||
return -1; // Doesn't exist
|
||||
|
||||
const int block_limit(narrow(mBlocks.size()));
|
||||
const int block_limit(narrow<size_t>(mBlocks.size()));
|
||||
for (int i(0); i < block_limit; ++i)
|
||||
{
|
||||
if (pos < mBlocks[i]->mUsed)
|
||||
|
|
|
|||
|
|
@ -50,6 +50,7 @@ bool LLImageDimensionsInfo::load(const std::string& src_filename,U32 codec)
|
|||
|
||||
if (file_size == 0)
|
||||
{
|
||||
mWarning = "texture_load_empty_file";
|
||||
setLastError("File is empty",src_filename);
|
||||
return false;
|
||||
}
|
||||
|
|
@ -90,6 +91,7 @@ bool LLImageDimensionsInfo::getImageDimensionsBmp()
|
|||
if (signature[0] != 'B' || signature[1] != 'M')
|
||||
{
|
||||
LL_WARNS() << "Not a BMP" << LL_ENDL;
|
||||
mWarning = "texture_load_format_error";
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -140,6 +142,7 @@ bool LLImageDimensionsInfo::getImageDimensionsPng()
|
|||
if (memcmp(signature, png_magic, PNG_MAGIC_SIZE) != 0)
|
||||
{
|
||||
LL_WARNS() << "Not a PNG" << LL_ENDL;
|
||||
mWarning = "texture_load_format_error";
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -184,6 +187,7 @@ bool LLImageDimensionsInfo::getImageDimensionsJpeg()
|
|||
if (memcmp(signature, jpeg_magic, JPEG_MAGIC_SIZE) != 0)
|
||||
{
|
||||
LL_WARNS() << "Not a JPEG" << LL_ENDL;
|
||||
mWarning = "texture_load_format_error";
|
||||
fclose(fp); // <FS:ND/> Don't leak the file handle
|
||||
return false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -55,6 +55,12 @@ public:
|
|||
{
|
||||
return mLastError;
|
||||
}
|
||||
|
||||
const std::string& getWarningName()
|
||||
{
|
||||
return mWarning;
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
void clean()
|
||||
|
|
@ -129,6 +135,7 @@ protected:
|
|||
std::string mSrcFilename;
|
||||
|
||||
std::string mLastError;
|
||||
std::string mWarning;
|
||||
|
||||
U8* mData;
|
||||
|
||||
|
|
|
|||
|
|
@ -35,8 +35,10 @@ class ImageRequest
|
|||
{
|
||||
public:
|
||||
ImageRequest(const LLPointer<LLImageFormatted>& image,
|
||||
S32 discard, BOOL needs_aux,
|
||||
const LLPointer<LLImageDecodeThread::Responder>& responder);
|
||||
S32 discard,
|
||||
BOOL needs_aux,
|
||||
const LLPointer<LLImageDecodeThread::Responder>& responder,
|
||||
U32 request_id);
|
||||
virtual ~ImageRequest();
|
||||
|
||||
/*virtual*/ bool processRequest();
|
||||
|
|
@ -48,6 +50,7 @@ private:
|
|||
// input
|
||||
LLPointer<LLImageFormatted> mFormattedImage;
|
||||
S32 mDiscardLevel;
|
||||
U32 mRequestId;
|
||||
BOOL mNeedsAux;
|
||||
// output
|
||||
LLPointer<LLImageRaw> mDecodedImageRaw;
|
||||
|
|
@ -62,6 +65,7 @@ private:
|
|||
|
||||
// MAIN THREAD
|
||||
LLImageDecodeThread::LLImageDecodeThread(bool /*threaded*/)
|
||||
: mDecodeCount(0)
|
||||
{
|
||||
mThreadPool.reset(new LL::ThreadPool("ImageDecode", 8));
|
||||
mThreadPool->start();
|
||||
|
|
@ -92,9 +96,10 @@ LLImageDecodeThread::handle_t LLImageDecodeThread::decodeImage(
|
|||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
|
||||
|
||||
U32 decode_id = ++mDecodeCount;
|
||||
// Instantiate the ImageRequest right in the lambda, why not?
|
||||
bool posted = mThreadPool->getQueue().post(
|
||||
[req = ImageRequest(image, discard, needs_aux, responder)]
|
||||
[req = ImageRequest(image, discard, needs_aux, responder, decode_id)]
|
||||
() mutable
|
||||
{
|
||||
auto done = req.processRequest();
|
||||
|
|
@ -103,13 +108,10 @@ LLImageDecodeThread::handle_t LLImageDecodeThread::decodeImage(
|
|||
if (! posted)
|
||||
{
|
||||
LL_DEBUGS() << "Tried to start decoding on shutdown" << LL_ENDL;
|
||||
// should this return 0?
|
||||
return 0;
|
||||
}
|
||||
|
||||
// It's important to our consumer (LLTextureFetchWorker) that we return a
|
||||
// nonzero handle. It is NOT important that the nonzero handle be unique:
|
||||
// nothing is ever done with it except to compare it to zero, or zero it.
|
||||
return 17;
|
||||
return decode_id;
|
||||
}
|
||||
|
||||
void LLImageDecodeThread::shutdown()
|
||||
|
|
@ -123,15 +125,18 @@ LLImageDecodeThread::Responder::~Responder()
|
|||
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
ImageRequest::ImageRequest(const LLPointer<LLImageFormatted>& image,
|
||||
S32 discard, BOOL needs_aux,
|
||||
const LLPointer<LLImageDecodeThread::Responder>& responder)
|
||||
ImageRequest::ImageRequest(const LLPointer<LLImageFormatted>& image,
|
||||
S32 discard,
|
||||
BOOL needs_aux,
|
||||
const LLPointer<LLImageDecodeThread::Responder>& responder,
|
||||
U32 request_id)
|
||||
: mFormattedImage(image),
|
||||
mDiscardLevel(discard),
|
||||
mNeedsAux(needs_aux),
|
||||
mDecodedRaw(FALSE),
|
||||
mDecodedAux(FALSE),
|
||||
mResponder(responder)
|
||||
mResponder(responder),
|
||||
mRequestId(request_id)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
@ -211,7 +216,7 @@ void ImageRequest::finishRequest(bool completed)
|
|||
if (mResponder.notNull())
|
||||
{
|
||||
bool success = completed && mDecodedRaw && (!mNeedsAux || mDecodedAux);
|
||||
mResponder->completed(success, mDecodedImageRaw, mDecodedImageAux);
|
||||
mResponder->completed(success, mDecodedImageRaw, mDecodedImageAux, mRequestId);
|
||||
}
|
||||
// Will automatically be deleted
|
||||
}
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ public:
|
|||
protected:
|
||||
virtual ~Responder();
|
||||
public:
|
||||
virtual void completed(bool success, LLImageRaw* raw, LLImageRaw* aux) = 0;
|
||||
virtual void completed(bool success, LLImageRaw* raw, LLImageRaw* aux, U32 request_id) = 0;
|
||||
};
|
||||
|
||||
public:
|
||||
|
|
@ -53,6 +53,7 @@ public:
|
|||
const LLPointer<Responder>& responder);
|
||||
size_t getPending();
|
||||
size_t update(F32 max_time_ms);
|
||||
S32 getTotalDecodeCount() { return mDecodeCount; }
|
||||
void shutdown();
|
||||
|
||||
private:
|
||||
|
|
@ -60,6 +61,7 @@ private:
|
|||
// LLQueuedThread - instead this is the API by which we submit work to the
|
||||
// "ImageDecode" ThreadPool.
|
||||
std::unique_ptr<LL::ThreadPool> mThreadPool;
|
||||
LLAtomicU32 mDecodeCount;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -5630,9 +5630,9 @@ bool LLVolumeFace::cacheOptimize(bool gen_tangents)
|
|||
|
||||
U32 stream_count = data.w.empty() ? 4 : 5;
|
||||
|
||||
U32 vert_count = meshopt_generateVertexRemapMulti(&remap[0], nullptr, data.p.size(), data.p.size(), mos, stream_count);
|
||||
size_t vert_count = meshopt_generateVertexRemapMulti(&remap[0], nullptr, data.p.size(), data.p.size(), mos, stream_count);
|
||||
|
||||
if (vert_count < 65535)
|
||||
if (vert_count < 65535 && vert_count != 0)
|
||||
{
|
||||
std::vector<U32> indices;
|
||||
indices.resize(mNumIndices);
|
||||
|
|
@ -5651,6 +5651,13 @@ bool LLVolumeFace::cacheOptimize(bool gen_tangents)
|
|||
{
|
||||
U32 src_idx = i;
|
||||
U32 dst_idx = remap[i];
|
||||
if (dst_idx >= mNumVertices)
|
||||
{
|
||||
dst_idx = mNumVertices - 1;
|
||||
// Shouldn't happen, figure out what gets returned in remap and why.
|
||||
llassert(false);
|
||||
LL_DEBUGS_ONCE("LLVOLUME") << "Invalid destination index, substituting" << LL_ENDL;
|
||||
}
|
||||
mIndices[i] = dst_idx;
|
||||
|
||||
mPositions[dst_idx].load3(data.p[src_idx].mV);
|
||||
|
|
@ -5684,6 +5691,10 @@ bool LLVolumeFace::cacheOptimize(bool gen_tangents)
|
|||
}
|
||||
else
|
||||
{
|
||||
if (vert_count == 0)
|
||||
{
|
||||
LL_WARNS_ONCE("LLVOLUME") << "meshopt_generateVertexRemapMulti failed to process a model or model was invalid" << LL_ENDL;
|
||||
}
|
||||
// blew past the max vertex size limit, use legacy tangent generation which never adds verts
|
||||
createTangents();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -386,12 +386,3 @@ std::ostream& operator<< (std::ostream& os, LLXfer &hh)
|
|||
os << hh.getFileName() ;
|
||||
return os;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1056,7 +1056,12 @@ LLModel::weight_list& LLModel::getJointInfluences(const LLVector3& pos)
|
|||
weight_map::iterator iterPos = mSkinWeights.begin();
|
||||
weight_map::iterator iterEnd = mSkinWeights.end();
|
||||
|
||||
llassert(!mSkinWeights.empty());
|
||||
if (mSkinWeights.empty())
|
||||
{
|
||||
// function calls iter->second on all return paths
|
||||
// everything that calls this function should precheck that there is data.
|
||||
LL_ERRS() << "called getJointInfluences with empty weights list" << LL_ENDL;
|
||||
}
|
||||
|
||||
for ( ; iterPos!=iterEnd; ++iterPos )
|
||||
{
|
||||
|
|
@ -1083,11 +1088,16 @@ LLModel::weight_list& LLModel::getJointInfluences(const LLVector3& pos)
|
|||
const F32 epsilon = 1e-5f;
|
||||
weight_map::iterator iter_up = mSkinWeights.lower_bound(pos);
|
||||
weight_map::iterator iter_down = iter_up;
|
||||
if (iter_up != mSkinWeights.end())
|
||||
{
|
||||
iter_down = ++iter_up;
|
||||
}
|
||||
weight_map::iterator best = iter_up;
|
||||
weight_map::iterator best = iter_up;
|
||||
if (iter_up != mSkinWeights.end())
|
||||
{
|
||||
iter_down = ++iter_up;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Assumes that there is at least one element
|
||||
--best;
|
||||
}
|
||||
|
||||
// <FS:ND> FIRE-9251; There is no way iter can be valid here, otherwise we had hit the if branch and not the else branch.
|
||||
// F32 min_dist = (iter->first - pos).magVec();
|
||||
|
|
|
|||
|
|
@ -101,6 +101,17 @@ void APIENTRY gl_debug_callback(GLenum source,
|
|||
return;
|
||||
}*/
|
||||
|
||||
if (gGLManager.mIsDisabled &&
|
||||
severity == GL_DEBUG_SEVERITY_HIGH_ARB &&
|
||||
source == GL_DEBUG_SOURCE_API_ARB &&
|
||||
type == GL_DEBUG_TYPE_ERROR_ARB &&
|
||||
id == GL_INVALID_VALUE)
|
||||
{
|
||||
// Suppress messages about deleting already deleted objects called from LLViewerWindow::stopGL()
|
||||
// "GL_INVALID_VALUE error generated. Handle does not refer to an object generated by OpenGL."
|
||||
return;
|
||||
}
|
||||
|
||||
// list of messages to suppress
|
||||
const char* suppress[] =
|
||||
{
|
||||
|
|
@ -155,8 +166,9 @@ void APIENTRY gl_debug_callback(GLenum source,
|
|||
glGetBufferParameteriv(GL_UNIFORM_BUFFER, GL_BUFFER_SIZE, &ubo_size);
|
||||
glGetBufferParameteriv(GL_UNIFORM_BUFFER, GL_BUFFER_IMMUTABLE_STORAGE, &ubo_immutable);
|
||||
}
|
||||
|
||||
if (severity == GL_DEBUG_SEVERITY_HIGH)
|
||||
|
||||
// No needs to halt when is called from LLViewerWindow::stopGL()
|
||||
if (severity == GL_DEBUG_SEVERITY_HIGH && !gGLManager.mIsDisabled)
|
||||
{
|
||||
LL_ERRS() << "Halting on GL Error" << LL_ENDL;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -126,12 +126,12 @@ public:
|
|||
|
||||
void setSelected(bool is_selected);
|
||||
|
||||
bool getCollapsible() {return mCollapsible;};
|
||||
bool getCollapsible() { return mCollapsible; };
|
||||
|
||||
void setCollapsible(bool collapsible) {mCollapsible = collapsible;};
|
||||
void setCollapsible(bool collapsible) { mCollapsible = collapsible; };
|
||||
void changeOpenClose(bool is_open);
|
||||
|
||||
void canOpenClose(bool can_open_close) { mCanOpenClose = can_open_close;};
|
||||
void canOpenClose(bool can_open_close) { mCanOpenClose = can_open_close; };
|
||||
bool canOpenClose() const { return mCanOpenClose; };
|
||||
|
||||
virtual BOOL postBuild();
|
||||
|
|
@ -142,8 +142,8 @@ public:
|
|||
|
||||
void draw();
|
||||
|
||||
void storeOpenCloseState ();
|
||||
void restoreOpenCloseState ();
|
||||
void storeOpenCloseState();
|
||||
void restoreOpenCloseState();
|
||||
|
||||
protected:
|
||||
LLAccordionCtrlTab(const LLAccordionCtrlTab::Params&);
|
||||
|
|
|
|||
|
|
@ -296,7 +296,7 @@ void LLContainerView::setLabel(const std::string& label)
|
|||
mLabel = label;
|
||||
}
|
||||
|
||||
void LLContainerView::setDisplayChildren(const BOOL displayChildren)
|
||||
void LLContainerView::setDisplayChildren(BOOL displayChildren)
|
||||
{
|
||||
mDisplayChildren = displayChildren;
|
||||
for (child_list_const_iter_t child_iter = getChildList()->begin();
|
||||
|
|
|
|||
|
|
@ -86,7 +86,7 @@ public:
|
|||
|
||||
void setLabel(const std::string& label);
|
||||
void showLabel(BOOL show) { mShowLabel = show; }
|
||||
void setDisplayChildren(const BOOL displayChildren);
|
||||
void setDisplayChildren(BOOL displayChildren);
|
||||
BOOL getDisplayChildren() { return mDisplayChildren; }
|
||||
void setScrollContainer(LLScrollContainer* scroll) {mScrollContainer = scroll;}
|
||||
|
||||
|
|
|
|||
|
|
@ -1373,26 +1373,28 @@ void LLFlatListViewEx::setForceShowingUnmatchedItems(bool show)
|
|||
mForceShowingUnmatchedItems = show;
|
||||
}
|
||||
|
||||
void LLFlatListViewEx::setFilterSubString(const std::string& filter_str)
|
||||
void LLFlatListViewEx::setFilterSubString(const std::string& filter_str, bool notify_parent)
|
||||
{
|
||||
if (0 != LLStringUtil::compareInsensitive(filter_str, mFilterSubString))
|
||||
{
|
||||
mFilterSubString = filter_str;
|
||||
updateNoItemsMessage(mFilterSubString);
|
||||
filterItems();
|
||||
filterItems(false, notify_parent);
|
||||
}
|
||||
}
|
||||
|
||||
void LLFlatListViewEx::updateItemVisibility(LLPanel* item, const LLSD &action)
|
||||
bool LLFlatListViewEx::updateItemVisibility(LLPanel* item, const LLSD &action)
|
||||
{
|
||||
if (!item) return;
|
||||
if (!item)
|
||||
return false;
|
||||
|
||||
BOOL visible = TRUE;
|
||||
|
||||
// 0 signifies that filter is matched,
|
||||
// i.e. we don't hide items that don't support 'match_filter' action, separators etc.
|
||||
if (0 == item->notify(action))
|
||||
{
|
||||
mHasMatchedItems = true;
|
||||
item->setVisible(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -1400,34 +1402,45 @@ void LLFlatListViewEx::updateItemVisibility(LLPanel* item, const LLSD &action)
|
|||
if (!mForceShowingUnmatchedItems)
|
||||
{
|
||||
selectItem(item, false);
|
||||
visible = FALSE;
|
||||
}
|
||||
item->setVisible(mForceShowingUnmatchedItems);
|
||||
}
|
||||
|
||||
if (item->getVisible() != visible)
|
||||
{
|
||||
item->setVisible(visible);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void LLFlatListViewEx::filterItems()
|
||||
void LLFlatListViewEx::filterItems(bool re_sort, bool notify_parent)
|
||||
{
|
||||
typedef std::vector <LLPanel*> item_panel_list_t;
|
||||
|
||||
std::string cur_filter = mFilterSubString;
|
||||
LLStringUtil::toUpper(cur_filter);
|
||||
|
||||
LLSD action;
|
||||
action.with("match_filter", cur_filter);
|
||||
|
||||
item_panel_list_t items;
|
||||
getItems(items);
|
||||
|
||||
mHasMatchedItems = false;
|
||||
item_panel_list_t::iterator iter = items.begin(), iter_end = items.end();
|
||||
while (iter < iter_end)
|
||||
bool visibility_changed = false;
|
||||
pairs_const_iterator_t iter = getItemPairs().begin(), iter_end = getItemPairs().end();
|
||||
while (iter != iter_end)
|
||||
{
|
||||
LLPanel* pItem = *(iter++);
|
||||
updateItemVisibility(pItem, action);
|
||||
LLPanel* pItem = (*(iter++))->first;
|
||||
visibility_changed |= updateItemVisibility(pItem, action);
|
||||
}
|
||||
|
||||
sort();
|
||||
notifyParentItemsRectChanged();
|
||||
if (re_sort)
|
||||
{
|
||||
sort();
|
||||
}
|
||||
|
||||
if (visibility_changed && notify_parent)
|
||||
{
|
||||
notifyParentItemsRectChanged();
|
||||
}
|
||||
}
|
||||
|
||||
bool LLFlatListViewEx::hasMatchedItems()
|
||||
|
|
|
|||
|
|
@ -308,6 +308,7 @@ public:
|
|||
virtual S32 notify(const LLSD& info) ;
|
||||
|
||||
virtual ~LLFlatListView();
|
||||
|
||||
protected:
|
||||
|
||||
/** Pairs LLpanel representing a single item LLPanel and LLSD associated with it */
|
||||
|
|
@ -383,7 +384,9 @@ protected:
|
|||
|
||||
LLRect getLastSelectedItemRect();
|
||||
|
||||
void ensureSelectedVisible();
|
||||
void ensureSelectedVisible();
|
||||
|
||||
const pairs_list_t& getItemPairs() { return mItemPairs; }
|
||||
|
||||
private:
|
||||
|
||||
|
|
@ -496,14 +499,14 @@ public:
|
|||
/**
|
||||
* Sets up new filter string and filters the list.
|
||||
*/
|
||||
void setFilterSubString(const std::string& filter_str);
|
||||
void setFilterSubString(const std::string& filter_str, bool notify_parent);
|
||||
std::string getFilterSubString() { return mFilterSubString; }
|
||||
|
||||
/**
|
||||
* Filters the list, rearranges and notifies parent about shape changes.
|
||||
* Derived classes may want to overload rearrangeItems() to exclude repeated separators after filtration.
|
||||
*/
|
||||
void filterItems();
|
||||
void filterItems(bool re_sort, bool notify_parent);
|
||||
|
||||
/**
|
||||
* Returns true if last call of filterItems() found at least one matching item
|
||||
|
|
@ -527,7 +530,7 @@ protected:
|
|||
* @param item - item we are changing
|
||||
* @param item - action - parameters to determin visibility from
|
||||
*/
|
||||
void updateItemVisibility(LLPanel* item, const LLSD &action);
|
||||
bool updateItemVisibility(LLPanel* item, const LLSD &action);
|
||||
|
||||
private:
|
||||
std::string mNoFilteredItemsMsg;
|
||||
|
|
|
|||
|
|
@ -541,7 +541,6 @@ void LLFloater::enableResizeCtrls(bool enable, bool width, bool height)
|
|||
|
||||
void LLFloater::destroy()
|
||||
{
|
||||
gFloaterView->onDestroyFloater(this);
|
||||
// LLFloaterReg should be synchronized with "dead" floater to avoid returning dead instance before
|
||||
// it was deleted via LLMortician::updateClass(). See EXT-8458.
|
||||
LLFloaterReg::removeInstance(mInstanceName, mKey);
|
||||
|
|
@ -2631,8 +2630,7 @@ LLFloaterView::LLFloaterView (const Params& p)
|
|||
mSnapOffsetBottom(0),
|
||||
mSnapOffsetChatBar(0),
|
||||
mSnapOffsetLeft(0),
|
||||
mSnapOffsetRight(0),
|
||||
mFrontChild(NULL)
|
||||
mSnapOffsetRight(0)
|
||||
{
|
||||
mSnapView = getHandle();
|
||||
}
|
||||
|
|
@ -2788,7 +2786,8 @@ void LLFloaterView::bringToFront(LLFloater* child, BOOL give_focus, BOOL restore
|
|||
if (!child)
|
||||
return;
|
||||
|
||||
if (mFrontChild == child)
|
||||
LLFloater* front_child = mFrontChildHandle.get();
|
||||
if (front_child == child)
|
||||
{
|
||||
if (give_focus && child->canFocusStealFrontmost() && !gFocusMgr.childHasKeyboardFocus(child))
|
||||
{
|
||||
|
|
@ -2797,12 +2796,12 @@ void LLFloaterView::bringToFront(LLFloater* child, BOOL give_focus, BOOL restore
|
|||
return;
|
||||
}
|
||||
|
||||
if (mFrontChild && !mFrontChild->isDead())
|
||||
if (front_child && !front_child->isDead() && front_child->getVisible())
|
||||
{
|
||||
mFrontChild->goneFromFront();
|
||||
front_child->goneFromFront();
|
||||
}
|
||||
|
||||
mFrontChild = child;
|
||||
mFrontChildHandle = child->getHandle();
|
||||
|
||||
// *TODO: make this respect floater's mAutoFocus value, instead of
|
||||
// using parameter
|
||||
|
|
@ -3389,7 +3388,8 @@ LLFloater *LLFloaterView::getBackmost() const
|
|||
|
||||
void LLFloaterView::syncFloaterTabOrder()
|
||||
{
|
||||
if (mFrontChild && !mFrontChild->isDead() && mFrontChild->getIsChrome())
|
||||
LLFloater* front_child = mFrontChildHandle.get();
|
||||
if (front_child && front_child->getIsChrome())
|
||||
return;
|
||||
|
||||
// look for a visible modal dialog, starting from first
|
||||
|
|
@ -3427,11 +3427,12 @@ void LLFloaterView::syncFloaterTabOrder()
|
|||
LLFloater* floaterp = dynamic_cast<LLFloater*>(*child_it);
|
||||
if (gFocusMgr.childHasKeyboardFocus(floaterp))
|
||||
{
|
||||
if (mFrontChild != floaterp)
|
||||
LLFloater* front_child = mFrontChildHandle.get();
|
||||
if (front_child != floaterp)
|
||||
{
|
||||
// Grab a list of the top floaters that want to stay on top of the focused floater
|
||||
std::list<LLFloater*> listTop;
|
||||
if (mFrontChild && !mFrontChild->canFocusStealFrontmost())
|
||||
if (front_child && !front_child->canFocusStealFrontmost())
|
||||
{
|
||||
for (LLView* childp : *getChildList())
|
||||
{
|
||||
|
|
@ -3451,7 +3452,7 @@ void LLFloaterView::syncFloaterTabOrder()
|
|||
{
|
||||
sendChildToFront(childp);
|
||||
}
|
||||
mFrontChild = listTop.back();
|
||||
mFrontChildHandle = listTop.back()->getHandle();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -3547,14 +3548,6 @@ void LLFloaterView::setToolbarRect(LLToolBarEnums::EToolBarLocation tb, const LL
|
|||
}
|
||||
}
|
||||
|
||||
void LLFloaterView::onDestroyFloater(LLFloater* floater)
|
||||
{
|
||||
if (mFrontChild == floater)
|
||||
{
|
||||
mFrontChild = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
// <FS:Ansariel> Prevent floaters being dragged under main chat bar
|
||||
void LLFloaterView::setMainChatbarRect(LLLayoutPanel* panel, const LLRect& chatbar_rect)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -645,7 +645,6 @@ public:
|
|||
// </FS:KC> Fix for bad edge snapping
|
||||
|
||||
void setToolbarRect(LLToolBarEnums::EToolBarLocation tb, const LLRect& toolbar_rect);
|
||||
void onDestroyFloater(LLFloater* floater);
|
||||
|
||||
// <FS:Ansariel> Prevent floaters being dragged under main chat bar
|
||||
void setMainChatbarRect(LLLayoutPanel* panel, const LLRect& chatbar_rect);
|
||||
|
|
@ -670,7 +669,7 @@ private:
|
|||
S32 mMinimizePositionVOffset;
|
||||
typedef std::vector<std::pair<LLHandle<LLFloater>, boost::signals2::connection> > hidden_floaters_t;
|
||||
hidden_floaters_t mHiddenFloaters;
|
||||
LLFloater * mFrontChild;
|
||||
LLHandle<LLFloater> mFrontChildHandle;
|
||||
|
||||
// <FS:Ansariel> Prevent floaters being dragged under main chat bar
|
||||
LLRect mMainChatbarRect;
|
||||
|
|
|
|||
|
|
@ -206,14 +206,18 @@ LLFolderViewItem::~LLFolderViewItem()
|
|||
|
||||
BOOL LLFolderViewItem::postBuild()
|
||||
{
|
||||
LLFolderViewModelItem& vmi = *getViewModelItem();
|
||||
// getDisplayName() is expensive (due to internal getLabelSuffix() and name building)
|
||||
// it also sets search strings so it requires a filter reset
|
||||
mLabel = vmi.getDisplayName();
|
||||
setToolTip(vmi.getName());
|
||||
LLFolderViewModelItem* vmi = getViewModelItem();
|
||||
llassert(vmi); // not supposed to happen, if happens, find out why and fix
|
||||
if (vmi)
|
||||
{
|
||||
// getDisplayName() is expensive (due to internal getLabelSuffix() and name building)
|
||||
// it also sets search strings so it requires a filter reset
|
||||
mLabel = vmi->getDisplayName();
|
||||
setToolTip(vmi->getName());
|
||||
|
||||
// Dirty the filter flag of the model from the view (CHUI-849)
|
||||
vmi.dirtyFilter();
|
||||
// Dirty the filter flag of the model from the view (CHUI-849)
|
||||
vmi->dirtyFilter();
|
||||
}
|
||||
|
||||
// Don't do full refresh on constructor if it is possible to avoid
|
||||
// it significantly slows down bulk view creation.
|
||||
|
|
|
|||
|
|
@ -502,7 +502,7 @@ LLTrace::BlockTimerStatHandle FTM_SYNTAX_COLORING("Syntax Coloring");
|
|||
|
||||
// Walk through a string, applying the rules specified by the keyword token list and
|
||||
// create a list of color segments.
|
||||
void LLKeywords::findSegments(std::vector<LLTextSegmentPtr>* seg_list, const LLWString& wtext, const LLColor4 &defaultColor, LLTextEditor& editor)
|
||||
void LLKeywords::findSegments(std::vector<LLTextSegmentPtr>* seg_list, const LLWString& wtext, LLTextEditor& editor, LLStyleConstSP style)
|
||||
{
|
||||
LL_RECORD_BLOCK_TIME(FTM_SYNTAX_COLORING);
|
||||
seg_list->clear();
|
||||
|
|
@ -515,10 +515,10 @@ void LLKeywords::findSegments(std::vector<LLTextSegmentPtr>* seg_list, const LLW
|
|||
S32 text_len = wtext.size() + 1;
|
||||
|
||||
// <FS:Ansariel> Script editor ignoring font selection
|
||||
//seg_list->push_back( new LLNormalTextSegment( defaultColor, 0, text_len, editor ) );
|
||||
LLStyleSP style = getDefaultStyle(editor);
|
||||
style->setColor(defaultColor);
|
||||
seg_list->push_back( new LLNormalTextSegment( style, 0, text_len, editor ) );
|
||||
//seg_list->push_back( new LLNormalTextSegment( style, 0, text_len, editor ) );
|
||||
LLStyleSP actual_style = getDefaultStyle(editor);
|
||||
actual_style->setColor(style->getColor());
|
||||
seg_list->push_back( new LLNormalTextSegment( actual_style, 0, text_len, editor ) );
|
||||
// </FS:Ansariel>
|
||||
|
||||
const llwchar* base = wtext.c_str();
|
||||
|
|
@ -530,11 +530,11 @@ void LLKeywords::findSegments(std::vector<LLTextSegmentPtr>* seg_list, const LLW
|
|||
if( *cur == '\n' )
|
||||
{
|
||||
// <FS:Ansariel> Script editor ignoring font selection
|
||||
//LLTextSegmentPtr text_segment = new LLLineBreakTextSegment(cur-base);
|
||||
//LLTextSegmentPtr text_segment = new LLLineBreakTextSegment(style, cur-base);
|
||||
LLTextSegmentPtr text_segment = new LLLineBreakTextSegment(getDefaultStyle(editor), cur-base);
|
||||
// </FS:Ansariel>
|
||||
text_segment->setToken( 0 );
|
||||
insertSegment( *seg_list, text_segment, text_len, defaultColor, editor);
|
||||
insertSegment( *seg_list, text_segment, text_len, style, editor);
|
||||
cur++;
|
||||
if( !*cur || *cur == '\n' )
|
||||
{
|
||||
|
|
@ -572,7 +572,7 @@ void LLKeywords::findSegments(std::vector<LLTextSegmentPtr>* seg_list, const LLW
|
|||
S32 seg_end = cur - base;
|
||||
|
||||
//create segments from seg_start to seg_end
|
||||
insertSegments(wtext, *seg_list,cur_token, text_len, seg_start, seg_end, defaultColor, editor);
|
||||
insertSegments(wtext, *seg_list,cur_token, text_len, seg_start, seg_end, style, editor);
|
||||
line_done = TRUE; // to break out of second loop.
|
||||
break;
|
||||
}
|
||||
|
|
@ -679,7 +679,7 @@ void LLKeywords::findSegments(std::vector<LLTextSegmentPtr>* seg_list, const LLW
|
|||
seg_end = seg_start + between_delimiters + cur_delimiter->getLengthHead();
|
||||
}
|
||||
|
||||
insertSegments(wtext, *seg_list,cur_delimiter, text_len, seg_start, seg_end, defaultColor, editor);
|
||||
insertSegments(wtext, *seg_list,cur_delimiter, text_len, seg_start, seg_end, style, editor);
|
||||
/*
|
||||
// <FS:Ansariel> Script editor ignoring font selection
|
||||
//LLTextSegmentPtr text_segment = new LLNormalTextSegment( cur_delimiter->getColor(), seg_start, seg_end, editor );
|
||||
|
|
@ -723,7 +723,7 @@ void LLKeywords::findSegments(std::vector<LLTextSegmentPtr>* seg_list, const LLW
|
|||
|
||||
// LL_INFOS("SyntaxLSL") << "Seg: [" << word.c_str() << "]" << LL_ENDL;
|
||||
|
||||
insertSegments(wtext, *seg_list,cur_token, text_len, seg_start, seg_end, defaultColor, editor);
|
||||
insertSegments(wtext, *seg_list,cur_token, text_len, seg_start, seg_end, style, editor);
|
||||
}
|
||||
cur += seg_len;
|
||||
continue;
|
||||
|
|
@ -738,9 +738,12 @@ void LLKeywords::findSegments(std::vector<LLTextSegmentPtr>* seg_list, const LLW
|
|||
}
|
||||
}
|
||||
|
||||
void LLKeywords::insertSegments(const LLWString& wtext, std::vector<LLTextSegmentPtr>& seg_list, LLKeywordToken* cur_token, S32 text_len, S32 seg_start, S32 seg_end, const LLColor4 &defaultColor, LLTextEditor& editor )
|
||||
void LLKeywords::insertSegments(const LLWString& wtext, std::vector<LLTextSegmentPtr>& seg_list, LLKeywordToken* cur_token, S32 text_len, S32 seg_start, S32 seg_end, LLStyleConstSP style, LLTextEditor& editor )
|
||||
{
|
||||
std::string::size_type pos = wtext.find('\n',seg_start);
|
||||
|
||||
// <FS:Ansariel> Script editor ignoring font selection
|
||||
//LLStyleConstSP cur_token_style = new LLStyle(LLStyle::Params().font(style->getFont()).color(cur_token->getColor()));
|
||||
|
||||
while (pos!=-1 && pos < (std::string::size_type)seg_end)
|
||||
{
|
||||
|
|
@ -753,28 +756,28 @@ void LLKeywords::insertSegments(const LLWString& wtext, std::vector<LLTextSegmen
|
|||
LLTextSegmentPtr text_segment = new LLNormalTextSegment( style, seg_start, pos, editor );
|
||||
// </FS:Ansariel>
|
||||
text_segment->setToken( cur_token );
|
||||
insertSegment( seg_list, text_segment, text_len, defaultColor, editor);
|
||||
insertSegment( seg_list, text_segment, text_len, style, editor);
|
||||
}
|
||||
|
||||
// <FS:Ansariel> Script editor ignoring font selection
|
||||
//LLTextSegmentPtr text_segment = new LLLineBreakTextSegment(pos);
|
||||
//LLTextSegmentPtr text_segment = new LLLineBreakTextSegment(style, pos);
|
||||
LLTextSegmentPtr text_segment = new LLLineBreakTextSegment(getDefaultStyle(editor), pos);
|
||||
// </FS:Ansariel>
|
||||
text_segment->setToken( cur_token );
|
||||
insertSegment( seg_list, text_segment, text_len, defaultColor, editor);
|
||||
insertSegment( seg_list, text_segment, text_len, style, editor);
|
||||
|
||||
seg_start = pos+1;
|
||||
pos = wtext.find('\n',seg_start);
|
||||
}
|
||||
|
||||
// <FS:Ansariel> Script editor ignoring font selection
|
||||
//LLTextSegmentPtr text_segment = new LLNormalTextSegment( cur_token->getColor(), seg_start, seg_end, editor );
|
||||
LLStyleSP style = getDefaultStyle(editor);
|
||||
style->setColor(cur_token->getColor());
|
||||
LLTextSegmentPtr text_segment = new LLNormalTextSegment( style, seg_start, seg_end, editor );
|
||||
//LLTextSegmentPtr text_segment = new LLNormalTextSegment(cur_token_style, seg_start, seg_end, editor);
|
||||
LLStyleSP actual_style = getDefaultStyle(editor);
|
||||
actual_style->setColor(cur_token->getColor());
|
||||
LLTextSegmentPtr text_segment = new LLNormalTextSegment(actual_style, seg_start, seg_end, editor);
|
||||
// </FS:Ansariel>
|
||||
text_segment->setToken( cur_token );
|
||||
insertSegment( seg_list, text_segment, text_len, defaultColor, editor);
|
||||
insertSegment( seg_list, text_segment, text_len, style, editor);
|
||||
}
|
||||
|
||||
void LLKeywords::insertSegment(std::vector<LLTextSegmentPtr>& seg_list, LLTextSegmentPtr new_segment, S32 text_len, const LLColor4 &defaultColor, LLTextEditor& editor )
|
||||
|
|
@ -803,6 +806,32 @@ void LLKeywords::insertSegment(std::vector<LLTextSegmentPtr>& seg_list, LLTextSe
|
|||
}
|
||||
}
|
||||
|
||||
void LLKeywords::insertSegment(std::vector<LLTextSegmentPtr>& seg_list, LLTextSegmentPtr new_segment, S32 text_len, LLStyleConstSP style, LLTextEditor& editor )
|
||||
{
|
||||
LLTextSegmentPtr last = seg_list.back();
|
||||
S32 new_seg_end = new_segment->getEnd();
|
||||
|
||||
if( new_segment->getStart() == last->getStart() )
|
||||
{
|
||||
seg_list.pop_back();
|
||||
}
|
||||
else
|
||||
{
|
||||
last->setEnd( new_segment->getStart() );
|
||||
}
|
||||
seg_list.push_back( new_segment );
|
||||
|
||||
if( new_seg_end < text_len )
|
||||
{
|
||||
// <FS:Ansariel> Script editor ignoring font selection
|
||||
//seg_list.push_back( new LLNormalTextSegment( style, new_seg_end, text_len, editor ) );
|
||||
LLStyleSP actual_style = getDefaultStyle(editor);
|
||||
actual_style->setColor(style->getColor());
|
||||
seg_list.push_back(new LLNormalTextSegment(actual_style, new_seg_end, text_len, editor));
|
||||
// </FS:Ansariel>
|
||||
}
|
||||
}
|
||||
|
||||
// <FS:Ansariel> Re-add support for Cinder's legacy file format
|
||||
bool LLKeywords::loadFromLegacyFile(const std::string& filename)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@
|
|||
|
||||
|
||||
#include "lldir.h"
|
||||
#include "llstyle.h"
|
||||
#include "llstring.h"
|
||||
#include "v3color.h"
|
||||
#include "v4color.h"
|
||||
|
|
@ -121,8 +122,8 @@ public:
|
|||
|
||||
void findSegments(std::vector<LLTextSegmentPtr> *seg_list,
|
||||
const LLWString& text,
|
||||
const LLColor4 &defaultColor,
|
||||
class LLTextEditor& editor);
|
||||
class LLTextEditor& editor,
|
||||
LLStyleConstSP style);
|
||||
void initialize(LLSD SyntaxXML);
|
||||
void processTokens();
|
||||
|
||||
|
|
@ -187,9 +188,11 @@ protected:
|
|||
S32 text_len,
|
||||
S32 seg_start,
|
||||
S32 seg_end,
|
||||
const LLColor4 &defaultColor,
|
||||
LLStyleConstSP style,
|
||||
LLTextEditor& editor);
|
||||
|
||||
void insertSegment(std::vector<LLTextSegmentPtr>& seg_list, LLTextSegmentPtr new_segment, S32 text_len, LLStyleConstSP style, LLTextEditor& editor );
|
||||
|
||||
bool mLoaded;
|
||||
LLSD mSyntax;
|
||||
word_token_map_t mWordTokenMap;
|
||||
|
|
|
|||
|
|
@ -1811,7 +1811,8 @@ LLMenuGL::LLMenuGL(const LLMenuGL::Params& p)
|
|||
mNeedsArrange(FALSE),
|
||||
mAlwaysShowMenu(FALSE),
|
||||
mResetScrollPositionOnShow(true),
|
||||
mShortcutPad(p.shortcut_pad)
|
||||
mShortcutPad(p.shortcut_pad),
|
||||
mFont(p.font)
|
||||
{
|
||||
typedef boost::tokenizer<boost::char_separator<char> > tokenizer;
|
||||
boost::char_separator<char> sep("_");
|
||||
|
|
@ -3682,6 +3683,7 @@ BOOL LLMenuBarGL::appendMenu( LLMenuGL* menu )
|
|||
p.disabled_color=LLUIColorTable::instance().getColor("MenuItemDisabledColor");
|
||||
p.highlight_bg_color=LLUIColorTable::instance().getColor("MenuItemHighlightBgColor");
|
||||
p.highlight_fg_color=LLUIColorTable::instance().getColor("MenuItemHighlightFgColor");
|
||||
p.font = menu->getFont();
|
||||
|
||||
LLMenuItemBranchDownGL* branch = LLUICtrlFactory::create<LLMenuItemBranchDownGL>(p);
|
||||
success &= branch->addToAcceleratorList(&mAccelerators);
|
||||
|
|
|
|||
|
|
@ -563,6 +563,8 @@ public:
|
|||
// add a context menu branch
|
||||
BOOL appendContextSubMenu(LLMenuGL *menu);
|
||||
|
||||
const LLFontGL *getFont() const { return mFont; }
|
||||
|
||||
// <FS:Ansariel> Items-accessor
|
||||
typedef std::list< LLMenuItemGL* > item_list_t;
|
||||
item_list_t* getItems() { return &mItems; }
|
||||
|
|
@ -599,6 +601,9 @@ protected:
|
|||
BOOL mKeepFixedSize;
|
||||
BOOL mNeedsArrange;
|
||||
|
||||
// Font for top menu items only
|
||||
const LLFontGL* mFont;
|
||||
|
||||
private:
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -184,7 +184,7 @@ LLStatBar::LLStatBar(const Params& p)
|
|||
mTargetMinBar(llmin(p.bar_min, p.bar_max)),
|
||||
mTargetMaxBar(llmax(p.bar_max, p.bar_min)),
|
||||
mCurMaxBar(p.bar_max),
|
||||
mCurMinBar(0),
|
||||
mCurMinBar(0),
|
||||
mDecimalDigits(p.decimal_digits),
|
||||
mNumHistoryFrames(p.num_frames),
|
||||
mNumShortHistoryFrames(p.num_frames_short),
|
||||
|
|
@ -279,9 +279,6 @@ BOOL LLStatBar::handleHover(S32 x, S32 y, MASK mask)
|
|||
case STAT_SAMPLE:
|
||||
LLToolTipMgr::instance().show(LLToolTip::Params().message(mStat.sampleStatp->getDescription()).sticky_rect(calcScreenRect()));
|
||||
break;
|
||||
case STAT_MEM:
|
||||
LLToolTipMgr::instance().show(LLToolTip::Params().message(mStat.memStatp->getDescription()).sticky_rect(calcScreenRect()));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
@ -430,18 +427,6 @@ void LLStatBar::draw()
|
|||
}
|
||||
}
|
||||
break;
|
||||
case STAT_MEM:
|
||||
{
|
||||
const LLTrace::StatType<LLTrace::MemAccumulator>& mem_stat = *mStat.memStatp;
|
||||
|
||||
unit_label = mUnitLabel.empty() ? mem_stat.getUnitLabel() : mUnitLabel;
|
||||
current = last_frame_recording.getLastValue(mem_stat).value();
|
||||
min = frame_recording.getPeriodMin(mem_stat, num_frames).value();
|
||||
max = frame_recording.getPeriodMax(mem_stat, num_frames).value();
|
||||
mean = frame_recording.getPeriodMean(mem_stat, num_frames).value();
|
||||
display_value = current;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
@ -560,11 +545,6 @@ void LLStatBar::draw()
|
|||
max_value = recording.getMax(*mStat.sampleStatp);
|
||||
num_samples = recording.getSampleCount(*mStat.sampleStatp);
|
||||
break;
|
||||
case STAT_MEM:
|
||||
min_value = recording.getMin(*mStat.memStatp).value();
|
||||
max_value = recording.getMax(*mStat.memStatp).value();
|
||||
num_samples = 1;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
@ -661,14 +641,8 @@ void LLStatBar::setStat(const std::string& stat_name)
|
|||
mStat.sampleStatp = sample_stat.get();
|
||||
mStatType = STAT_SAMPLE;
|
||||
}
|
||||
else if (auto mem_stat = StatType<MemAccumulator>::getInstance(stat_name))
|
||||
{
|
||||
mStat.memStatp = mem_stat.get();
|
||||
mStatType = STAT_MEM;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void LLStatBar::setRange(F32 bar_min, F32 bar_max)
|
||||
{
|
||||
mTargetMinBar = llmin(bar_min, bar_max);
|
||||
|
|
|
|||
|
|
@ -100,17 +100,15 @@ private:
|
|||
STAT_NONE,
|
||||
STAT_COUNT,
|
||||
STAT_EVENT,
|
||||
STAT_SAMPLE,
|
||||
STAT_MEM
|
||||
STAT_SAMPLE
|
||||
} mStatType;
|
||||
|
||||
union
|
||||
{
|
||||
void* valid;
|
||||
void* valid;
|
||||
const LLTrace::StatType<LLTrace::CountAccumulator>* countStatp;
|
||||
const LLTrace::StatType<LLTrace::EventAccumulator>* eventStatp;
|
||||
const LLTrace::StatType<LLTrace::SampleAccumulator>* sampleStatp;
|
||||
const LLTrace::StatType<LLTrace::MemAccumulator>* memStatp;
|
||||
const LLTrace::StatType<LLTrace::SampleAccumulator>* sampleStatp;
|
||||
} mStat;
|
||||
|
||||
LLUIString mLabel;
|
||||
|
|
|
|||
|
|
@ -58,10 +58,7 @@ LLStatView::~LLStatView()
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
static StatViewRegistry::Register<LLStatBar> r1("stat_bar");
|
||||
static StatViewRegistry::Register<LLStatView> r2("stat_view");
|
||||
// stat_view can be a child of panels/etc.
|
||||
static LLDefaultChildRegistry::Register<LLStatView> r3("stat_view");
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -63,7 +63,7 @@ protected:
|
|||
friend class LLUICtrlFactory;
|
||||
|
||||
protected:
|
||||
std::string mSetting;
|
||||
|
||||
const std::string mSetting;
|
||||
};
|
||||
|
||||
#endif // LL_STATVIEW_
|
||||
|
|
|
|||
|
|
@ -1657,25 +1657,23 @@ BOOL LLTabContainer::selectTab(S32 which)
|
|||
|
||||
LLTabTuple* selected_tuple = getTab(which);
|
||||
if (!selected_tuple)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
LLSD cbdata;
|
||||
if (selected_tuple->mTabPanel)
|
||||
cbdata = selected_tuple->mTabPanel->getName();
|
||||
|
||||
BOOL res = FALSE;
|
||||
if( !mValidateSignal || (*mValidateSignal)( this, cbdata ) )
|
||||
BOOL result = FALSE;
|
||||
if (!mValidateSignal || (*mValidateSignal)(this, cbdata))
|
||||
{
|
||||
res = setTab(which);
|
||||
if (res && mCommitSignal)
|
||||
result = setTab(which);
|
||||
if (result && mCommitSignal)
|
||||
{
|
||||
(*mCommitSignal)(this, cbdata);
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// private
|
||||
|
|
|
|||
|
|
@ -3829,7 +3829,7 @@ BOOL LLNormalTextSegment::handleToolTip(S32 x, S32 y, MASK mask)
|
|||
if (mToken && !mToken->getToolTip().empty())
|
||||
{
|
||||
const LLWString& wmsg = mToken->getToolTip();
|
||||
LLToolTipMgr::instance().show(wstring_to_utf8str(wmsg));
|
||||
LLToolTipMgr::instance().show(wstring_to_utf8str(wmsg), (mToken->getType() == LLKeywordToken::TT_FUNCTION));
|
||||
return TRUE;
|
||||
}
|
||||
// or do we have an explicitly set tooltip (e.g., for Urls)
|
||||
|
|
|
|||
|
|
@ -2048,7 +2048,8 @@ BOOL LLTextEditor::handleKeyHere(KEY key, MASK mask )
|
|||
}
|
||||
|
||||
if (mEnableTooltipPaste &&
|
||||
LLToolTipMgr::instance().toolTipVisible() &&
|
||||
LLToolTipMgr::instance().toolTipVisible() &&
|
||||
LLToolTipMgr::instance().isTooltipPastable() &&
|
||||
KEY_TAB == key)
|
||||
{ // Paste the first line of a tooltip into the editor
|
||||
std::string message;
|
||||
|
|
|
|||
|
|
@ -154,7 +154,8 @@ LLToolTip::Params::Params()
|
|||
text_color("text_color"),
|
||||
time_based_media("time_based_media", false),
|
||||
web_based_media("web_based_media", false),
|
||||
media_playing("media_playing", false)
|
||||
media_playing("media_playing", false),
|
||||
allow_paste_tooltip("allow_paste_tooltip", false)
|
||||
{
|
||||
changeDefault(chrome, true);
|
||||
}
|
||||
|
|
@ -167,7 +168,8 @@ LLToolTip::LLToolTip(const LLToolTip::Params& p)
|
|||
mTextBox(NULL),
|
||||
mInfoButton(NULL),
|
||||
mPlayMediaButton(NULL),
|
||||
mHomePageButton(NULL)
|
||||
mHomePageButton(NULL),
|
||||
mIsTooltipPastable(p.allow_paste_tooltip)
|
||||
{
|
||||
LLTextBox::Params params;
|
||||
params.name = params.initial_value().asString();
|
||||
|
|
@ -289,6 +291,8 @@ void LLToolTip::initFromParams(const LLToolTip::Params& p)
|
|||
mTextBox->setText(p.message());
|
||||
}
|
||||
|
||||
mIsTooltipPastable = p.allow_paste_tooltip;
|
||||
|
||||
updateTextBox();
|
||||
snapToChildren();
|
||||
}
|
||||
|
|
@ -483,9 +487,9 @@ void LLToolTipMgr::createToolTip(const LLToolTip::Params& params)
|
|||
}
|
||||
|
||||
|
||||
void LLToolTipMgr::show(const std::string& msg)
|
||||
void LLToolTipMgr::show(const std::string& msg, bool allow_paste_tooltip)
|
||||
{
|
||||
show(LLToolTip::Params().message(msg));
|
||||
show(LLToolTip::Params().message(msg).allow_paste_tooltip(allow_paste_tooltip));
|
||||
}
|
||||
|
||||
void LLToolTipMgr::show(const LLToolTip::Params& params)
|
||||
|
|
@ -625,5 +629,13 @@ void LLToolTipMgr::getToolTipMessage(std::string & message)
|
|||
}
|
||||
}
|
||||
|
||||
bool LLToolTipMgr::isTooltipPastable()
|
||||
{
|
||||
if (toolTipVisible())
|
||||
{
|
||||
return mToolTip->isTooltipPastable();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// EOF
|
||||
|
|
|
|||
|
|
@ -94,6 +94,8 @@ public:
|
|||
padding;
|
||||
Optional<bool> wrap;
|
||||
|
||||
Optional<bool> allow_paste_tooltip;
|
||||
|
||||
Params();
|
||||
};
|
||||
/*virtual*/ void draw();
|
||||
|
|
@ -109,6 +111,7 @@ public:
|
|||
virtual void initFromParams(const LLToolTip::Params& params);
|
||||
|
||||
void getToolTipMessage(std::string & message);
|
||||
bool isTooltipPastable() { return mIsTooltipPastable; }
|
||||
|
||||
protected:
|
||||
void updateTextBox();
|
||||
|
|
@ -125,6 +128,8 @@ protected:
|
|||
bool mHasClickCallback;
|
||||
S32 mPadding; // pixels
|
||||
S32 mMaxWidth;
|
||||
|
||||
bool mIsTooltipPastable;
|
||||
};
|
||||
|
||||
// used for the inspector tooltips which need different background images etc.
|
||||
|
|
@ -142,7 +147,7 @@ class LLToolTipMgr : public LLSingleton<LLToolTipMgr>
|
|||
|
||||
public:
|
||||
void show(const LLToolTip::Params& params);
|
||||
void show(const std::string& message);
|
||||
void show(const std::string& message, bool allow_paste_tooltip = false);
|
||||
|
||||
void unblockToolTips();
|
||||
void blockToolTips();
|
||||
|
|
@ -154,6 +159,7 @@ public:
|
|||
void updateToolTipVisibility();
|
||||
|
||||
void getToolTipMessage(std::string & message);
|
||||
bool isTooltipPastable();
|
||||
|
||||
private:
|
||||
void createToolTip(const LLToolTip::Params& params);
|
||||
|
|
|
|||
|
|
@ -237,14 +237,20 @@ bool LLUrlEntryBase::isWikiLinkCorrect(const std::string &labeled_url) const
|
|||
|
||||
std::string LLUrlEntryBase::urlToLabelWithGreyQuery(const std::string &url) const
|
||||
{
|
||||
if (url.empty())
|
||||
{
|
||||
return url;
|
||||
}
|
||||
LLUriParser up(escapeUrl(url));
|
||||
up.normalize();
|
||||
if (up.normalize() == 0)
|
||||
{
|
||||
std::string label;
|
||||
up.extractParts();
|
||||
up.glueFirst(label);
|
||||
|
||||
std::string label;
|
||||
up.extractParts();
|
||||
up.glueFirst(label);
|
||||
|
||||
return unescapeUrl(label);
|
||||
return unescapeUrl(label);
|
||||
}
|
||||
return std::string();
|
||||
}
|
||||
|
||||
std::string LLUrlEntryBase::urlToGreyQuery(const std::string &url) const
|
||||
|
|
|
|||
|
|
@ -293,16 +293,18 @@ bool LLUrlRegistry::findUrl(const std::string &text, LLUrlMatch &match, const LL
|
|||
//if (match_entry == mUrlEntryTrusted)
|
||||
//{
|
||||
// LLUriParser up(url);
|
||||
// up.normalize();
|
||||
// url = up.normalizedUri();
|
||||
// if (up.normalize() == 0)
|
||||
// {
|
||||
// url = up.normalizedUri();
|
||||
// }
|
||||
//}
|
||||
if (match_entry != mUrlEntryNoLink && match_entry == mUrlEntryTrustedUrl)
|
||||
{
|
||||
LLUriParser up(url);
|
||||
if (!up.normalize())
|
||||
{
|
||||
url = up.normalizedUri();
|
||||
}
|
||||
if (up.normalize() == 0)
|
||||
{
|
||||
url = up.normalizedUri();
|
||||
}
|
||||
}
|
||||
// </FS:Ansariel>
|
||||
|
||||
|
|
|
|||
|
|
@ -37,7 +37,6 @@
|
|||
#include "llwindowcallbacks.h"
|
||||
|
||||
// Linden library includes
|
||||
#include "llapp.h" // <FS:Beq/> [FIRE-32453][BUG-232971] Improve shutdown behaviour.
|
||||
#include "llerror.h"
|
||||
#include "llexception.h"
|
||||
#include "llfasttimer.h"
|
||||
|
|
@ -94,7 +93,6 @@ const UINT WM_DUMMY_(WM_USER + 0x0017);
|
|||
const UINT WM_POST_FUNCTION_(WM_USER + 0x0018);
|
||||
|
||||
extern BOOL gDebugWindowProc;
|
||||
extern BOOL gDisconnected; // <FS:Beq/> [FIRE-32453][BUG-232971] Improve shutdown behaviour.
|
||||
|
||||
static std::thread::id sWindowThreadId;
|
||||
static std::thread::id sMainThreadId;
|
||||
|
|
@ -353,7 +351,10 @@ struct LLWindowWin32::LLWindowWin32Thread : public LL::ThreadPool
|
|||
LLWindowWin32Thread();
|
||||
|
||||
void run() override;
|
||||
void close() override; // <FS:Beq/> [FIRE-32453][BUG-232971] Improve shutdown behaviour.
|
||||
void close() override;
|
||||
|
||||
// closes queue, wakes thread, waits until thread closes
|
||||
void wakeAndDestroy();
|
||||
|
||||
void glReady()
|
||||
{
|
||||
|
|
@ -366,6 +367,9 @@ struct LLWindowWin32::LLWindowWin32Thread : public LL::ThreadPool
|
|||
// initialize D3D (if DXGI cannot be used)
|
||||
void initD3D();
|
||||
|
||||
//clean up DXGI/D3D resources
|
||||
void cleanupDX();
|
||||
|
||||
// call periodically to update available VRAM
|
||||
void updateVRAMUsage();
|
||||
|
||||
|
|
@ -415,8 +419,8 @@ struct LLWindowWin32::LLWindowWin32Thread : public LL::ThreadPool
|
|||
using FuncType = std::function<void()>;
|
||||
// call GetMessage() and pull enqueue messages for later processing
|
||||
void gatherInput();
|
||||
HWND mWindowHandle = NULL;
|
||||
HDC mhDC = 0;
|
||||
HWND mWindowHandleThrd = NULL;
|
||||
HDC mhDCThrd = 0;
|
||||
|
||||
// *HACK: Attempt to prevent startup crashes by deferring memory accounting
|
||||
// until after some graphics setup. See SL-20177. -Cosmic,2023-09-18
|
||||
|
|
@ -992,53 +996,10 @@ void LLWindowWin32::close()
|
|||
|
||||
LL_DEBUGS("Window") << "Destroying Window" << LL_ENDL;
|
||||
|
||||
mWindowThread->post([=]()
|
||||
{
|
||||
if (IsWindow(mWindowHandle))
|
||||
{
|
||||
if (mhDC)
|
||||
{
|
||||
if (!ReleaseDC(mWindowHandle, mhDC))
|
||||
{
|
||||
LL_WARNS("Window") << "Release of ghDC failed!" << LL_ENDL;
|
||||
}
|
||||
}
|
||||
|
||||
// Make sure we don't leave a blank toolbar button.
|
||||
ShowWindow(mWindowHandle, SW_HIDE);
|
||||
|
||||
// This causes WM_DESTROY to be sent *immediately*
|
||||
if (!destroy_window_handler(mWindowHandle))
|
||||
{
|
||||
// <FS:Beq> Can't use a message box here because we're about to stop servicing the events.
|
||||
// OSMessageBox(mCallbacks->translateString("MBDestroyWinFailed"),
|
||||
// mCallbacks->translateString("MBShutdownErr"),
|
||||
// OSMB_OK);
|
||||
LL_INFOS("Window") << "Destroying Window failed" << LL_ENDL;
|
||||
// </FS:Beq>
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Something killed the window while we were busy destroying gl or handle somehow got broken
|
||||
LL_WARNS("Window") << "Failed to destroy Window, invalid handle!" << LL_ENDL;
|
||||
}
|
||||
|
||||
});
|
||||
// Window thread might be waiting for a getMessage(), give it
|
||||
// a push to enshure it will process destroy_window_handler
|
||||
kickWindowThread();
|
||||
|
||||
// Even though the above lambda might not yet have run, we've already
|
||||
// bound mWindowHandle into it by value, which should suffice for the
|
||||
// operations we're asking. That's the last time WE should touch it.
|
||||
mhDC = NULL;
|
||||
mWindowHandle = NULL;
|
||||
// <FS:Beq> [FIRE-32453][BUG-232971] close the related queues first to prevent spinning.
|
||||
mFunctionQueue.close();
|
||||
mMouseQueue.close();
|
||||
// </FS:Beq>
|
||||
mWindowThread->close();
|
||||
|
||||
mWindowThread->wakeAndDestroy();
|
||||
}
|
||||
|
||||
BOOL LLWindowWin32::isValid()
|
||||
|
|
@ -1791,8 +1752,8 @@ void LLWindowWin32::recreateWindow(RECT window_rect, DWORD dw_ex_style, DWORD dw
|
|||
()
|
||||
{
|
||||
LL_DEBUGS("Window") << "recreateWindow(): window_work entry" << LL_ENDL;
|
||||
self->mWindowHandle = 0;
|
||||
self->mhDC = 0;
|
||||
self->mWindowHandleThrd = 0;
|
||||
self->mhDCThrd = 0;
|
||||
|
||||
if (oldWindowHandle)
|
||||
{
|
||||
|
|
@ -1826,20 +1787,20 @@ void LLWindowWin32::recreateWindow(RECT window_rect, DWORD dw_ex_style, DWORD dw
|
|||
{
|
||||
// Failed to create window: clear the variables. This
|
||||
// assignment is valid because we're running on mWindowThread.
|
||||
self->mWindowHandle = NULL;
|
||||
self->mhDC = 0;
|
||||
self->mWindowHandleThrd = NULL;
|
||||
self->mhDCThrd = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Update mWindowThread's own mWindowHandle and mhDC.
|
||||
self->mWindowHandle = handle;
|
||||
self->mhDC = GetDC(handle);
|
||||
self->mWindowHandleThrd = handle;
|
||||
self->mhDCThrd = GetDC(handle);
|
||||
}
|
||||
|
||||
updateWindowRect();
|
||||
|
||||
// It's important to wake up the future either way.
|
||||
promise.set_value(std::make_pair(self->mWindowHandle, self->mhDC));
|
||||
promise.set_value(std::make_pair(self->mWindowHandleThrd, self->mhDCThrd));
|
||||
LL_DEBUGS("Window") << "recreateWindow(): window_work done" << LL_ENDL;
|
||||
};
|
||||
// But how we pass window_work to the window thread depends on whether we
|
||||
|
|
@ -3723,6 +3684,7 @@ void LLWindowWin32::swapBuffers()
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// LLSplashScreenImp
|
||||
//
|
||||
|
|
@ -3745,6 +3707,9 @@ void LLSplashScreenWin32::showImpl()
|
|||
NULL, // no parent
|
||||
(DLGPROC) LLSplashScreenWin32::windowProc);
|
||||
ShowWindow(mWindow, SW_SHOW);
|
||||
|
||||
// Should set taskbar text without creating a header for the window (caption)
|
||||
SetWindowTextA(mWindow, APP_NAME.c_str());
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -4708,11 +4673,25 @@ void LLWindowWin32::getWindowChrome( U32 &aChromeW, U32 &aChromeH )
|
|||
#endif // LL_WINDOWS
|
||||
|
||||
inline LLWindowWin32::LLWindowWin32Thread::LLWindowWin32Thread()
|
||||
: LL::ThreadPool("Window Thread", 1, MAX_QUEUE_SIZE)
|
||||
: LL::ThreadPool("Window Thread", 1, MAX_QUEUE_SIZE, true /*should be false, temporary workaround for SL-18721*/)
|
||||
{
|
||||
LL::ThreadPool::start();
|
||||
}
|
||||
|
||||
void LLWindowWin32::LLWindowWin32Thread::close()
|
||||
{
|
||||
if (!mQueue->isClosed())
|
||||
{
|
||||
LL_WARNS() << "Closing window thread without using destroy_window_handler" << LL_ENDL;
|
||||
LL::ThreadPool::close();
|
||||
|
||||
// Workaround for SL-18721 in case window closes too early and abruptly
|
||||
LLSplashScreen::show();
|
||||
LLSplashScreen::update("..."); // will be updated later
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* LogChange is to log changes in status while trying to avoid spamming the
|
||||
* log with repeated messages, especially in a tight loop. It refuses to log
|
||||
|
|
@ -4864,7 +4843,7 @@ void LLWindowWin32::LLWindowWin32Thread::initD3D()
|
|||
{
|
||||
if (!mGLReady) { return; }
|
||||
|
||||
if (mDXGIAdapter == NULL && mD3DDevice == NULL && mWindowHandle != 0)
|
||||
if (mDXGIAdapter == NULL && mD3DDevice == NULL && mWindowHandleThrd != 0)
|
||||
{
|
||||
mD3D = Direct3DCreate9(D3D_SDK_VERSION);
|
||||
|
||||
|
|
@ -4874,7 +4853,7 @@ void LLWindowWin32::LLWindowWin32Thread::initD3D()
|
|||
d3dpp.Windowed = TRUE;
|
||||
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
|
||||
|
||||
HRESULT res = mD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, mWindowHandle, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &mD3DDevice);
|
||||
HRESULT res = mD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, mWindowHandleThrd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &mD3DDevice);
|
||||
|
||||
if (FAILED(res))
|
||||
{
|
||||
|
|
@ -4887,6 +4866,28 @@ void LLWindowWin32::LLWindowWin32Thread::initD3D()
|
|||
}
|
||||
}
|
||||
|
||||
void LLWindowWin32::LLWindowWin32Thread::cleanupDX()
|
||||
{
|
||||
//clean up DXGI/D3D resources
|
||||
if (mDXGIAdapter)
|
||||
{
|
||||
mDXGIAdapter->Release();
|
||||
mDXGIAdapter = nullptr;
|
||||
}
|
||||
|
||||
if (mD3DDevice)
|
||||
{
|
||||
mD3DDevice->Release();
|
||||
mD3DDevice = nullptr;
|
||||
}
|
||||
|
||||
if (mD3D)
|
||||
{
|
||||
mD3D->Release();
|
||||
mD3D = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void LLWindowWin32::LLWindowWin32Thread::updateVRAMUsage()
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED;
|
||||
|
|
@ -4960,45 +4961,10 @@ void LLWindowWin32::LLWindowWin32Thread::updateVRAMUsage()
|
|||
}
|
||||
}
|
||||
|
||||
// <FS:Beq> [FIRE-32453][BUG-232971] Improve shutdown behaviour.
|
||||
// Provide a close() override that ignores the initial close triggered by the threadpool detecting "quit"
|
||||
// but waits for the viewer to be disconected and the second close call triggered by the app window destructor
|
||||
void LLWindowWin32::LLWindowWin32Thread::close()
|
||||
{
|
||||
assert_main_thread();
|
||||
if (!mQueue->isClosed() && gDisconnected)
|
||||
{
|
||||
LL_DEBUGS("ThreadPool") << mName << " closing queue and joining threads" << LL_ENDL;
|
||||
mQueue->close();
|
||||
for (auto& pair: mThreads)
|
||||
{
|
||||
LL_DEBUGS("ThreadPool") << mName << " waiting on thread " << pair.first << LL_ENDL;
|
||||
// As we cannot seem to rely on the clean and timely exit of the windows thread in ALL situations we apply a timeout.
|
||||
std::future<void> f = std::async(std::launch::async, [&] { pair.second.join(); });
|
||||
if (f.wait_until(std::chrono::steady_clock::now() + std::chrono::seconds(5)) == std::future_status::ready) {
|
||||
LL_DEBUGS("ThreadPool") << mName << " joined normally." << LL_ENDL;
|
||||
} else {
|
||||
LL_WARNS("ThreadPool") << mName << " join timed out." << LL_ENDL;
|
||||
// the specified time point was reached before the thread finished execution and could be joined
|
||||
}
|
||||
}
|
||||
LL_DEBUGS("ThreadPool") << mName << " shutdown complete" << LL_ENDL;
|
||||
}
|
||||
else
|
||||
{
|
||||
LL_DEBUGS("ThreadPool") << mName << " shutdown request ignored - not yet disconneced." << LL_ENDL;
|
||||
}
|
||||
}
|
||||
// </FS:Beq>
|
||||
|
||||
void LLWindowWin32::LLWindowWin32Thread::run()
|
||||
{
|
||||
sWindowThreadId = std::this_thread::get_id();
|
||||
LogChange logger("Window");
|
||||
// <FS:Beq> [FIRE-32453][BUG-232971] Improve shutdown behaviour.
|
||||
try
|
||||
{
|
||||
// </FS:Beq>
|
||||
//as good a place as any to up the MM timer resolution (see ms_sleep)
|
||||
//attempt to set timer resolution to 1ms
|
||||
TIMECAPS tc;
|
||||
|
|
@ -5014,7 +4980,7 @@ void LLWindowWin32::LLWindowWin32Thread::run()
|
|||
// lazily call initD3D inside this loop to catch when mGLReady has been set to true
|
||||
initDX();
|
||||
|
||||
if (mWindowHandle != 0)
|
||||
if (mWindowHandleThrd != 0)
|
||||
{
|
||||
// lazily call initD3D inside this loop to catch when mWindowHandle has been set, and mGLReady has been set to true
|
||||
// *TODO: Shutdown if this fails when mWindowHandle exists
|
||||
|
|
@ -5022,16 +4988,16 @@ void LLWindowWin32::LLWindowWin32Thread::run()
|
|||
|
||||
MSG msg;
|
||||
BOOL status;
|
||||
if (mhDC == 0)
|
||||
if (mhDCThrd == 0)
|
||||
{
|
||||
LL_PROFILE_ZONE_NAMED_CATEGORY_WIN32("w32t - PeekMessage");
|
||||
logger.onChange("PeekMessage(", std::hex, mWindowHandle, ")");
|
||||
status = PeekMessage(&msg, mWindowHandle, 0, 0, PM_REMOVE);
|
||||
logger.onChange("PeekMessage(", std::hex, mWindowHandleThrd, ")");
|
||||
status = PeekMessage(&msg, mWindowHandleThrd, 0, 0, PM_REMOVE);
|
||||
}
|
||||
else
|
||||
{
|
||||
LL_PROFILE_ZONE_NAMED_CATEGORY_WIN32("w32t - GetMessage");
|
||||
logger.always("GetMessage(", std::hex, mWindowHandle, ")");
|
||||
logger.always("GetMessage(", std::hex, mWindowHandleThrd, ")");
|
||||
status = GetMessage(&msg, NULL, 0, 0);
|
||||
}
|
||||
if (status > 0)
|
||||
|
|
@ -5040,21 +5006,7 @@ void LLWindowWin32::LLWindowWin32Thread::run()
|
|||
", ", msg.wParam, ")");
|
||||
TranslateMessage(&msg);
|
||||
DispatchMessage(&msg);
|
||||
// <FS:Beq> [FIRE-32453][BUG-232971] Improve shutdown behaviour.
|
||||
// mMessageQueue.pushFront(msg);
|
||||
try
|
||||
{
|
||||
// <FS:Beq> Nobody is reading this queue once we are quitting. Writing to it causes a hang.
|
||||
if(!LLApp::isQuitting())
|
||||
mMessageQueue.pushFront(msg);
|
||||
}
|
||||
catch (const LLThreadSafeQueueInterrupt&)
|
||||
{
|
||||
// Shutdown timing is tricky. The main thread can end up trying
|
||||
// to post a cursor position after having closed the WorkQueue.
|
||||
logger.always("Message procesing tried to push() to closed MessageQueue - caught");
|
||||
}
|
||||
// </FS:Beq>
|
||||
mMessageQueue.pushFront(msg);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -5080,38 +5032,111 @@ void LLWindowWin32::LLWindowWin32Thread::run()
|
|||
}
|
||||
#endif
|
||||
}
|
||||
// <FS:Beq> [FIRE-32453][BUG-232971] Improve shutdown behaviour.
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
logger.always("Windows thread exiting - Exception: ", e.what());
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
logger.always("Windows thread exiting - Exception: Unknown");
|
||||
}
|
||||
logger.always("done - queue closed on windows thread.");
|
||||
// </FS:Beq>
|
||||
|
||||
//clean up DXGI/D3D resources
|
||||
if (mDXGIAdapter)
|
||||
cleanupDX();
|
||||
}
|
||||
|
||||
void LLWindowWin32::LLWindowWin32Thread::wakeAndDestroy()
|
||||
{
|
||||
if (mQueue->isClosed())
|
||||
{
|
||||
mDXGIAdapter->Release();
|
||||
mDXGIAdapter = nullptr;
|
||||
LL_WARNS() << "Tried to close Queue. Win32 thread Queue already closed." << LL_ENDL;
|
||||
return;
|
||||
}
|
||||
|
||||
if (mD3DDevice)
|
||||
// Make sure we don't leave a blank toolbar button.
|
||||
// Also hiding window now prevents user from suspending it
|
||||
// via some action (like dragging it around)
|
||||
ShowWindow(mWindowHandleThrd, SW_HIDE);
|
||||
|
||||
// Schedule destruction
|
||||
HWND old_handle = mWindowHandleThrd;
|
||||
post([this]()
|
||||
{
|
||||
if (IsWindow(mWindowHandleThrd))
|
||||
{
|
||||
if (mhDCThrd)
|
||||
{
|
||||
if (!ReleaseDC(mWindowHandleThrd, mhDCThrd))
|
||||
{
|
||||
LL_WARNS("Window") << "Release of ghDC failed!" << LL_ENDL;
|
||||
}
|
||||
mhDCThrd = NULL;
|
||||
}
|
||||
|
||||
// This causes WM_DESTROY to be sent *immediately*
|
||||
if (!destroy_window_handler(mWindowHandleThrd))
|
||||
{
|
||||
LL_WARNS("Window") << "Failed to destroy Window! " << std::hex << GetLastError() << LL_ENDL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Something killed the window while we were busy destroying gl or handle somehow got broken
|
||||
LL_WARNS("Window") << "Failed to destroy Window, invalid handle!" << LL_ENDL;
|
||||
}
|
||||
mWindowHandleThrd = NULL;
|
||||
mhDCThrd = NULL;
|
||||
mGLReady = false;
|
||||
});
|
||||
|
||||
LL_DEBUGS("Window") << "Closing window's pool queue" << LL_ENDL;
|
||||
mQueue->close();
|
||||
|
||||
// Post a nonsense user message to wake up the thread in
|
||||
// case it is waiting for a getMessage()
|
||||
if (old_handle)
|
||||
{
|
||||
mD3DDevice->Release();
|
||||
mD3DDevice = nullptr;
|
||||
WPARAM wparam{ 0xB0B0 };
|
||||
LL_DEBUGS("Window") << "PostMessage(" << std::hex << old_handle
|
||||
<< ", " << WM_DUMMY_
|
||||
<< ", " << wparam << ")" << std::dec << LL_ENDL;
|
||||
PostMessage(old_handle, WM_DUMMY_, wparam, 0x1337);
|
||||
}
|
||||
|
||||
if (mD3D)
|
||||
// There are cases where window will refuse to close,
|
||||
// can't wait forever on join, check state instead
|
||||
LLTimer timeout;
|
||||
timeout.setTimerExpirySec(2.0);
|
||||
while (!getQueue().done() && !timeout.hasExpired() && mWindowHandleThrd)
|
||||
{
|
||||
mD3D->Release();
|
||||
mD3D = nullptr;
|
||||
ms_sleep(100);
|
||||
}
|
||||
|
||||
if (getQueue().done() || mWindowHandleThrd == NULL)
|
||||
{
|
||||
// Window is closed, started closing or is cleaning up
|
||||
// now wait for our single thread to die.
|
||||
if (mWindowHandleThrd)
|
||||
{
|
||||
LL_INFOS("Window") << "Window is closing, waiting on pool's thread to join, time since post: " << timeout.getElapsedSeconds() << "s" << LL_ENDL;
|
||||
}
|
||||
else
|
||||
{
|
||||
LL_DEBUGS("Window") << "Waiting on pool's thread, time since post: " << timeout.getElapsedSeconds() << "s" << LL_ENDL;
|
||||
}
|
||||
for (auto& pair : mThreads)
|
||||
{
|
||||
pair.second.join();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Something suspended window thread, can't afford to wait forever
|
||||
// so kill thread instead
|
||||
// Ex: This can happen if user starts dragging window arround (if it
|
||||
// was visible) or a modal notification pops up
|
||||
LL_WARNS("Window") << "Window is frozen, couldn't perform clean exit" << LL_ENDL;
|
||||
|
||||
for (auto& pair : mThreads)
|
||||
{
|
||||
// very unsafe
|
||||
TerminateThread(pair.second.native_handle(), 0);
|
||||
pair.second.detach();
|
||||
cleanupDX();
|
||||
}
|
||||
}
|
||||
LL_DEBUGS("Window") << "thread pool shutdown complete" << LL_ENDL;
|
||||
}
|
||||
|
||||
void LLWindowWin32::post(const std::function<void()>& func)
|
||||
|
|
|
|||
|
|
@ -286,7 +286,11 @@ void VolumeCatcherImpl::setVolume(F32 volume)
|
|||
|
||||
void VolumeCatcherImpl::pump()
|
||||
{
|
||||
return;
|
||||
// <FS:Beq> PR#17 makidoll: Fix Linux volume catcher
|
||||
if (mGotSyms && mMainloop) {
|
||||
llpa_mainloop_iterate(mMainloop, 0, NULL);
|
||||
}
|
||||
// </FS:Beq>
|
||||
}
|
||||
|
||||
void VolumeCatcherImpl::connected_okay()
|
||||
|
|
|
|||
|
|
@ -21,5 +21,6 @@ LL_PA_SYM(true, pa_sw_volume_from_linear, pa_volume_t, double v);
|
|||
LL_PA_SYM(true, pa_mainloop_free, void, pa_mainloop* m);
|
||||
LL_PA_SYM(true, pa_mainloop_get_api, pa_mainloop_api*, pa_mainloop* m);
|
||||
LL_PA_SYM(true, pa_mainloop_new, pa_mainloop*, void);
|
||||
LL_PA_SYM(true, pa_mainloop_iterate, int, pa_mainloop*, int, int*);
|
||||
|
||||
// optional symbols to grab
|
||||
|
|
|
|||
|
|
@ -28,6 +28,8 @@
|
|||
<string>${VIEWER_VERSION_MAJOR}.${VIEWER_VERSION_MINOR}.${VIEWER_VERSION_PATCH}.${VIEWER_VERSION_REVISION}</string>
|
||||
<key>CSResourcesFileMapped</key>
|
||||
<true/>
|
||||
<key>LSApplicationCategoryType</key>
|
||||
<string>public.app-category.games</string>
|
||||
<key>LSRequiresCarbon</key>
|
||||
<true/>
|
||||
<key>NSAppSleepDisabled</key>
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
7.1.5
|
||||
7.1.6
|
||||
|
|
|
|||
|
|
@ -5152,171 +5152,6 @@
|
|||
<key>Value</key>
|
||||
<integer>-1</integer>
|
||||
</map>
|
||||
<key>DebugStatModeMemTrace</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Mode of stat in Statistics floater</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>S32</string>
|
||||
<key>Value</key>
|
||||
<integer>-1</integer>
|
||||
</map>
|
||||
<key>DebugStatModeMemUI</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Mode of stat in Statistics floater</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>S32</string>
|
||||
<key>Value</key>
|
||||
<integer>-1</integer>
|
||||
</map>
|
||||
<key>DebugStatModeMemFonts</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Mode of stat in Statistics floater</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>S32</string>
|
||||
<key>Value</key>
|
||||
<integer>-1</integer>
|
||||
</map>
|
||||
<key>DebugStatModeMemInventory</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Mode of stat in Statistics floater</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>S32</string>
|
||||
<key>Value</key>
|
||||
<integer>-1</integer>
|
||||
</map>
|
||||
<key>DebugStatModeMemObjects</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Mode of stat in Statistics floater</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>S32</string>
|
||||
<key>Value</key>
|
||||
<integer>-1</integer>
|
||||
</map>
|
||||
<key>DebugStatModeMemOctreeGroupData</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Mode of stat in Statistics floater</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>S32</string>
|
||||
<key>Value</key>
|
||||
<integer>-1</integer>
|
||||
</map>
|
||||
<key>DebugStatModeMemOctreeData</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Mode of stat in Statistics floater</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>S32</string>
|
||||
<key>Value</key>
|
||||
<integer>-1</integer>
|
||||
</map>
|
||||
<key>DebugStatModeMemObjectCache</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Mode of stat in Statistics floater</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>S32</string>
|
||||
<key>Value</key>
|
||||
<integer>-1</integer>
|
||||
</map>
|
||||
<key>DebugStatModeMemDrawable</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Mode of stat in Statistics floater</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>S32</string>
|
||||
<key>Value</key>
|
||||
<integer>-1</integer>
|
||||
</map>
|
||||
<key>DebugStatModeMemFaceData</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Mode of stat in Statistics floater</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>S32</string>
|
||||
<key>Value</key>
|
||||
<integer>-1</integer>
|
||||
</map>
|
||||
<key>DebugStatModeMemDrawInfo</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Mode of stat in Statistics floater</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>S32</string>
|
||||
<key>Value</key>
|
||||
<integer>-1</integer>
|
||||
</map>
|
||||
<key>DebugStatModeMemTextureData</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Mode of stat in Statistics floater</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>S32</string>
|
||||
<key>Value</key>
|
||||
<integer>-1</integer>
|
||||
</map>
|
||||
<key>DebugStatModeMemImageData</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Mode of stat in Statistics floater</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>S32</string>
|
||||
<key>Value</key>
|
||||
<integer>-1</integer>
|
||||
</map>
|
||||
<key>DebugStatModeMemGLImageData</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Mode of stat in Statistics floater</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>S32</string>
|
||||
<key>Value</key>
|
||||
<integer>-1</integer>
|
||||
</map>
|
||||
<key>DebugStatModeMemVertexBuffer</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Mode of stat in Statistics floater</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>S32</string>
|
||||
<key>Value</key>
|
||||
<integer>-1</integer>
|
||||
</map>
|
||||
<key>DebugStatModeMaterials</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
|
|
@ -7732,6 +7567,17 @@
|
|||
<key>Backup</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
<key>LSLFontSizeName</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>UNUSED - Text font size in LSL editor</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>String</string>
|
||||
<key>Value</key>
|
||||
<string>Monospace</string>
|
||||
</map>
|
||||
<key>GridStatusRSS</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
|
|
@ -10342,21 +10188,10 @@ Change of this parameter will affect the layout of buttons in notification toast
|
|||
<key>Value</key>
|
||||
<integer>1</integer>
|
||||
</map>
|
||||
<key>OpenDebugStatAdvanced</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Expand advanced performance stats display</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>1</integer>
|
||||
</map>
|
||||
<key>OpenDebugStatBasic</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Expand basic performance stats display</string>
|
||||
<string>Expand Basic performance stats display</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
|
|
@ -10364,10 +10199,10 @@ Change of this parameter will affect the layout of buttons in notification toast
|
|||
<key>Value</key>
|
||||
<integer>1</integer>
|
||||
</map>
|
||||
<key>OpenDebugStatNet</key>
|
||||
<key>OpenDebugStatAdvanced</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Expand network stats display</string>
|
||||
<string>Expand Advanced performance stats display</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
|
|
@ -10378,18 +10213,7 @@ Change of this parameter will affect the layout of buttons in notification toast
|
|||
<key>OpenDebugStatRender</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Expand render stats display</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>1</integer>
|
||||
</map>
|
||||
<key>OpenDebugStatSim</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Expand simulator performance stats display</string>
|
||||
<string>Expand Render performance stats display</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
|
|
@ -10408,10 +10232,32 @@ Change of this parameter will affect the layout of buttons in notification toast
|
|||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
<key>OpenDebugStatSimPathfinding</key>
|
||||
<key>OpenDebugStatNet</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Expand Pathfinding performance stats display</string>
|
||||
<string>Expand Network performance stats display</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>1</integer>
|
||||
</map>
|
||||
<key>OpenDebugStatSim</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Expand Simulator performance stats display</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>1</integer>
|
||||
</map>
|
||||
<key>OpenDebugStatPhysicsDetails</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Expand Physics Details performance stats display</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
|
|
@ -10419,10 +10265,10 @@ Change of this parameter will affect the layout of buttons in notification toast
|
|||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
<key>OpenDebugStatPhysicsDetails</key>
|
||||
<key>OpenDebugStatPathfinding</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Expand Physics Details performance stats display</string>
|
||||
<string>Expand Pathfinding performance stats display</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
|
|
@ -10452,17 +10298,6 @@ Change of this parameter will affect the layout of buttons in notification toast
|
|||
<key>Value</key>
|
||||
<integer>1</integer>
|
||||
</map>
|
||||
<key>OpenDebugStatMemory</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Expand Memory performance stats display</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>1</integer>
|
||||
</map>
|
||||
<key>OutBandwidth</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
|
|
@ -21989,17 +21824,6 @@ Change of this parameter will affect the layout of buttons in notification toast
|
|||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
<key>FSDisplaySavedOutfitsCap</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Display only so many saved outfits in edit appearance. 0 to disable.</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>U32</string>
|
||||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
<key>FSAdvancedWorldmapRegionInfo</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
|
|
@ -25198,17 +25022,6 @@ Change of this parameter will affect the layout of buttons in notification toast
|
|||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
<key>VoiceMultiInstance</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Enables using voice in multiple simultaneous viewer instances</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>1</integer>
|
||||
</map>
|
||||
<key>FSSoundCacheLocation</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
|
|
|
|||
|
|
@ -2023,7 +2023,7 @@
|
|||
value_min="-1"
|
||||
value_max="1">
|
||||
<param_skeleton>
|
||||
|
||||
|
||||
<bone
|
||||
name="mEyeLeft"
|
||||
scale="0 0 0"
|
||||
|
|
@ -2033,9 +2033,8 @@
|
|||
name="mEyeRight"
|
||||
scale="0 0 0"
|
||||
offset="-.005 0 0" />
|
||||
|
||||
|
||||
<bone
|
||||
|
||||
<bone
|
||||
name="mFaceEyeAltLeft"
|
||||
scale="0 0 0"
|
||||
offset="-.005 0 0" />
|
||||
|
|
@ -2044,7 +2043,7 @@
|
|||
name="mFaceEyeAltRight"
|
||||
scale="0 0 0"
|
||||
offset="-.005 0 0" />
|
||||
|
||||
|
||||
<bone
|
||||
name="mFaceEyeLidLowerRight"
|
||||
scale="0 0.3 0.7"
|
||||
|
|
@ -2055,7 +2054,7 @@
|
|||
scale="0 0.3 0.7"
|
||||
offset="0 0 0" />
|
||||
|
||||
<bone
|
||||
<bone
|
||||
name="mFaceEyeLidUpperRight"
|
||||
scale="0 0.3 0.7"
|
||||
offset=" 0 0 0" />
|
||||
|
|
@ -2064,17 +2063,17 @@
|
|||
name="mFaceEyeLidUpperLeft"
|
||||
scale="0 0.3 0.7"
|
||||
offset=" 0 0 0" />
|
||||
|
||||
|
||||
<bone
|
||||
name="mFaceEyecornerInnerLeft"
|
||||
scale="0 0 0"
|
||||
offset="-0.005 -0.008 0.0" />
|
||||
|
||||
|
||||
<bone
|
||||
name="mFaceEyecornerInnerRight"
|
||||
scale="0 0 0"
|
||||
offset="-0.005 0.008 0.0" />
|
||||
|
||||
|
||||
</param_skeleton>
|
||||
</param>
|
||||
|
||||
|
|
|
|||
|
|
@ -311,7 +311,7 @@ void FSFloaterWearableFavorites::handleRemove()
|
|||
|
||||
void FSFloaterWearableFavorites::onFilterEdit(const std::string& search_string)
|
||||
{
|
||||
mItemsList->setFilterSubString(search_string);
|
||||
mItemsList->setFilterSubString(search_string, true);
|
||||
mItemsList->setNoItemsCommentText(getString("empty_list"));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -66,14 +66,14 @@ LLSLURL::LLSLURL(const std::string& slurl)
|
|||
// by default we go to agni.
|
||||
mType = INVALID;
|
||||
LL_DEBUGS("AppInit", "SLURL") << "SLURL: " << slurl << LL_ENDL;
|
||||
if(slurl == SIM_LOCATION_HOME)
|
||||
{
|
||||
mType = HOME_LOCATION;
|
||||
}
|
||||
else if(slurl.empty() || (slurl == SIM_LOCATION_LAST))
|
||||
if (slurl.empty() || (slurl == SIM_LOCATION_LAST))
|
||||
{
|
||||
mType = LAST_LOCATION;
|
||||
}
|
||||
else if (slurl == SIM_LOCATION_HOME)
|
||||
{
|
||||
mType = HOME_LOCATION;
|
||||
}
|
||||
else
|
||||
{
|
||||
LLURI slurl_uri;
|
||||
|
|
@ -154,6 +154,15 @@ LLSLURL::LLSLURL(const std::string& slurl)
|
|||
if(slurl_uri.scheme() == LLSLURL::SLURL_SECONDLIFE_SCHEME)
|
||||
{
|
||||
LL_DEBUGS("SLURL") << "secondlife scheme" << LL_ENDL;
|
||||
if (path_array.size() == 0
|
||||
&& slurl_uri.authority().empty()
|
||||
&& slurl_uri.escapedQuery().empty())
|
||||
{
|
||||
mType = EMPTY;
|
||||
// um, we need a path...
|
||||
return;
|
||||
}
|
||||
|
||||
// parse a maingrid style slurl. We know the grid is maingrid
|
||||
// so grab it.
|
||||
// A location slurl for maingrid (with the special schemes) can be in the form
|
||||
|
|
@ -676,28 +685,24 @@ std::string LLSLURL::asString() const
|
|||
// <AW: opensim>
|
||||
std::string LLSLURL::getTypeHumanReadable(SLURL_TYPE type)
|
||||
{
|
||||
std::string ret;
|
||||
switch(type)
|
||||
{
|
||||
case INVALID:
|
||||
ret = "INVALID";
|
||||
break;
|
||||
return "INVALID";
|
||||
case LOCATION:
|
||||
ret = "LOCATION";
|
||||
break;
|
||||
return "LOCATION";
|
||||
case HOME_LOCATION:
|
||||
ret = "HOME_LOCATION";
|
||||
break;
|
||||
return "HOME_LOCATION";
|
||||
case LAST_LOCATION:
|
||||
ret = "LAST_LOCATION";
|
||||
break;
|
||||
return "LAST_LOCATION";
|
||||
case APP:
|
||||
ret = "APP";
|
||||
break;
|
||||
return "APP";
|
||||
case HELP:
|
||||
ret = "HELP";
|
||||
return "HELP";
|
||||
case EMPTY:
|
||||
return "EMPTY";
|
||||
default:
|
||||
return{};
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
// </AW: opensim>
|
||||
|
|
|
|||
|
|
@ -60,7 +60,8 @@ public:
|
|||
HOME_LOCATION,
|
||||
LAST_LOCATION,
|
||||
APP,
|
||||
HELP
|
||||
HELP,
|
||||
EMPTY
|
||||
};
|
||||
|
||||
LLSLURL(): mType(INVALID) { }
|
||||
|
|
|
|||
|
|
@ -18,22 +18,23 @@ if [[ -f "$CONFIG_FILE" ]]; then
|
|||
res=$(xcrun notarytool submit "$zip_file" \
|
||||
--apple-id $USERNAME \
|
||||
--password $PASSWORD \
|
||||
--verbose \
|
||||
--team-id $ASC_PROVIDER \
|
||||
--wait 2>&1)
|
||||
echo "Notarytool submit:"
|
||||
echo $res
|
||||
|
||||
[[ "$res" =~ 'id: '([^[:space:]]+) ]]
|
||||
match=$?
|
||||
echo "Notarized with id: [$match]"
|
||||
|
||||
if [[ ! $match -eq 0 ]]; then
|
||||
echo "Running Stapler"
|
||||
xcrun stapler staple "$app_file"
|
||||
exit 0
|
||||
else
|
||||
echo "Notarization error"
|
||||
exit 1
|
||||
fi
|
||||
# if [[ ! $match -eq 0 ]]; then
|
||||
echo "Running Stapler"
|
||||
xcrun stapler staple "$app_file"
|
||||
exit 0
|
||||
# else
|
||||
# echo "Notarization error"
|
||||
# exit 1
|
||||
# fi
|
||||
else
|
||||
echo "Notarization error: ditto failed"
|
||||
exit 1
|
||||
|
|
|
|||
|
|
@ -2214,6 +2214,9 @@ bool LLAppViewer::cleanup()
|
|||
LL_INFOS() << "ViewerWindow deleted" << LL_ENDL;
|
||||
}
|
||||
|
||||
LLSplashScreen::show();
|
||||
LLSplashScreen::update(LLTrans::getString("ShuttingDown"));
|
||||
|
||||
LL_INFOS() << "Cleaning up Keyboard & Joystick" << LL_ENDL;
|
||||
|
||||
// viewer UI relies on keyboard so keep it aound until viewer UI isa gone
|
||||
|
|
@ -2530,6 +2533,8 @@ bool LLAppViewer::cleanup()
|
|||
// deleteSingleton() methods.
|
||||
LLSingletonBase::deleteAll();
|
||||
|
||||
LLSplashScreen::hide();
|
||||
|
||||
LL_INFOS() << "Goodbye!" << LL_ENDL;
|
||||
|
||||
removeDumpDir();
|
||||
|
|
@ -3478,20 +3483,19 @@ bool LLAppViewer::initConfiguration()
|
|||
return false;
|
||||
}
|
||||
|
||||
if (mSecondInstance)
|
||||
{
|
||||
// This is the second instance of SL. Turn off voice support,
|
||||
// but make sure the setting is *not* persisted.
|
||||
LLControlVariable* disable_voice = gSavedSettings.getControl("CmdLineDisableVoice");
|
||||
// <FS:Ansariel> Voice in multiple instances; by Latif Khalifa
|
||||
//if(disable_voice)
|
||||
if(disable_voice && !gSavedSettings.getBOOL("VoiceMultiInstance"))
|
||||
// </FS:Ansariel>
|
||||
{
|
||||
const BOOL DO_NOT_PERSIST = FALSE;
|
||||
disable_voice->setValue(LLSD(TRUE), DO_NOT_PERSIST);
|
||||
}
|
||||
}
|
||||
// <FS:Ansariel> Voice in multiple instances
|
||||
//if (mSecondInstance)
|
||||
//{
|
||||
// // This is the second instance of SL. Mute voice,
|
||||
// // but make sure the setting is *not* persisted.
|
||||
// LLControlVariable* enable_voice = gSavedSettings.getControl("EnableVoiceChat");
|
||||
// if(enable_voice)
|
||||
// {
|
||||
// const BOOL DO_NOT_PERSIST = FALSE;
|
||||
// enable_voice->setValue(LLSD(FALSE), DO_NOT_PERSIST);
|
||||
// }
|
||||
//}
|
||||
// </FS:Ansariel>
|
||||
|
||||
gLastRunVersion = gSavedSettings.getString("LastRunVersion");
|
||||
|
||||
|
|
@ -5932,6 +5936,9 @@ void LLAppViewer::idleShutdown()
|
|||
&& gLogoutTimer.getElapsedTimeF32() < SHUTDOWN_UPLOAD_SAVE_TIME
|
||||
&& !logoutRequestSent())
|
||||
{
|
||||
gViewerWindow->setShowProgress(TRUE, !gSavedSettings.getBOOL("FSDisableLogoutScreens"));
|
||||
gViewerWindow->setProgressPercent(100.f);
|
||||
gViewerWindow->setProgressString(LLTrans::getString("LoggingOut"));
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -6336,9 +6343,18 @@ void LLAppViewer::forceErrorBadMemoryAccess()
|
|||
void LLAppViewer::forceErrorInfiniteLoop()
|
||||
{
|
||||
LL_WARNS() << "Forcing a deliberate infinite loop" << LL_ENDL;
|
||||
// Loop is intentionally complicated to fool basic loop detection
|
||||
LLTimer timer_total;
|
||||
LLTimer timer_expiry;
|
||||
const S32 report_frequency = 10;
|
||||
timer_expiry.setTimerExpirySec(report_frequency);
|
||||
while(true)
|
||||
{
|
||||
;
|
||||
if (timer_expiry.hasExpired())
|
||||
{
|
||||
LL_INFOS() << "Infinite loop time : " << timer_total.getElapsedSeconds() << LL_ENDL;
|
||||
timer_expiry.setTimerExpirySec(report_frequency);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
|
@ -6349,6 +6365,13 @@ void LLAppViewer::forceErrorSoftwareException()
|
|||
LLTHROW(LLException("User selected Force Software Exception"));
|
||||
}
|
||||
|
||||
void LLAppViewer::forceErrorOSSpecificException()
|
||||
{
|
||||
// Virtual, MacOS only
|
||||
const std::string exception_text = "User selected Force OS Exception, Not implemented on this OS";
|
||||
throw std::runtime_error(exception_text);
|
||||
}
|
||||
|
||||
void LLAppViewer::forceErrorDriverCrash()
|
||||
{
|
||||
LL_WARNS() << "Forcing a deliberate driver crash" << LL_ENDL;
|
||||
|
|
|
|||
|
|
@ -154,6 +154,7 @@ public:
|
|||
virtual void forceErrorBadMemoryAccess();
|
||||
virtual void forceErrorInfiniteLoop();
|
||||
virtual void forceErrorSoftwareException();
|
||||
virtual void forceErrorOSSpecificException();
|
||||
virtual void forceErrorDriverCrash();
|
||||
// <FS:Ansariel> Wrongly merged back in by LL
|
||||
//virtual void forceErrorCoroutineCrash();
|
||||
|
|
|
|||
|
|
@ -33,4 +33,6 @@
|
|||
//Why? Because BOOL
|
||||
void launchApplication(const std::string* app_name, const std::vector<std::string>* args);
|
||||
|
||||
void force_ns_sxeption();
|
||||
|
||||
#endif // LL_LLAPPVIEWERMACOSX_OBJC_H
|
||||
|
|
|
|||
|
|
@ -71,3 +71,9 @@ void launchApplication(const std::string* app_name, const std::vector<std::strin
|
|||
[pool release];
|
||||
return;
|
||||
}
|
||||
|
||||
void force_ns_sxeption()
|
||||
{
|
||||
NSException *exception = [NSException exceptionWithName:@"Forced NSException" reason:nullptr userInfo:nullptr];
|
||||
@throw exception;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -250,6 +250,11 @@ bool LLAppViewerMacOSX::init()
|
|||
return LLAppViewer::init();
|
||||
}
|
||||
|
||||
void LLAppViewerMacOSX::forceErrorOSSpecificException()
|
||||
{
|
||||
force_ns_sxeption();
|
||||
}
|
||||
|
||||
// MacOSX may add and addition command line arguement for the process serial number.
|
||||
// The option takes a form like '-psn_0_12345'. The following method should be able to recognize
|
||||
// and either ignore or return a pair of values for the option.
|
||||
|
|
|
|||
|
|
@ -42,6 +42,8 @@ public:
|
|||
//
|
||||
virtual bool init(); // Override to do application initialization
|
||||
|
||||
virtual void forceErrorOSSpecificException();
|
||||
|
||||
protected:
|
||||
virtual bool restoreErrorTrap();
|
||||
|
||||
|
|
|
|||
|
|
@ -101,7 +101,6 @@ LLVOAvatar *LLControlAvatar::getAttachedAvatar()
|
|||
|
||||
void LLControlAvatar::getNewConstraintFixups(LLVector3& new_pos_fixup, F32& new_scale_fixup) const
|
||||
{
|
||||
|
||||
F32 max_legal_offset = MAX_LEGAL_OFFSET;
|
||||
if (gSavedSettings.getControl("AnimatedObjectsMaxLegalOffset"))
|
||||
{
|
||||
|
|
@ -364,6 +363,9 @@ LLControlAvatar *LLControlAvatar::createControlAvatar(LLVOVolume *obj)
|
|||
void LLControlAvatar::markForDeath()
|
||||
{
|
||||
mMarkedForDeath = true;
|
||||
// object unlinked cav and might be dead already
|
||||
// might need to clean mControlAVBridge here as well
|
||||
mRootVolp = NULL;
|
||||
mVolumep = nullptr;
|
||||
}
|
||||
|
||||
|
|
@ -382,6 +384,7 @@ void LLControlAvatar::idleUpdate(LLAgent &agent, const F64 &time)
|
|||
|
||||
void LLControlAvatar::markDead()
|
||||
{
|
||||
mRootVolp = NULL;
|
||||
super::markDead();
|
||||
mControlAVBridge = NULL;
|
||||
}
|
||||
|
|
@ -442,7 +445,7 @@ void LLControlAvatar::updateDebugText()
|
|||
F32 streaming_cost = 0.f;
|
||||
std::string cam_dist_string = "";
|
||||
S32 cam_dist_count = 0;
|
||||
F32 lod_radius = mRootVolp->mLODRadius;
|
||||
F32 lod_radius = mRootVolp ? mRootVolp->mLODRadius : 0.f;
|
||||
|
||||
for (std::vector<LLVOVolume*>::iterator it = volumes.begin();
|
||||
it != volumes.end(); ++it)
|
||||
|
|
|
|||
|
|
@ -92,6 +92,8 @@ LLConversationItem::~LLConversationItem()
|
|||
{
|
||||
mAvatarNameCacheConnection.disconnect();
|
||||
}
|
||||
|
||||
clearChildren();
|
||||
}
|
||||
|
||||
//virtual
|
||||
|
|
@ -256,6 +258,11 @@ LLConversationItemSession::LLConversationItemSession(const LLUUID& uuid, LLFolde
|
|||
mConvType = CONV_SESSION_UNKNOWN;
|
||||
}
|
||||
|
||||
LLConversationItemSession::~LLConversationItemSession()
|
||||
{
|
||||
clearAndDeparentModels();
|
||||
}
|
||||
|
||||
bool LLConversationItemSession::hasChildren() const
|
||||
{
|
||||
return getChildrenCount() > 0;
|
||||
|
|
|
|||
|
|
@ -160,6 +160,7 @@ class LLConversationItemSession : public LLConversationItem
|
|||
public:
|
||||
LLConversationItemSession(std::string display_name, const LLUUID& uuid, LLFolderViewModelInterface& root_view_model);
|
||||
LLConversationItemSession(const LLUUID& uuid, LLFolderViewModelInterface& root_view_model);
|
||||
~LLConversationItemSession();
|
||||
|
||||
/*virtual*/ bool hasChildren() const;
|
||||
LLPointer<LLUIImage> getIcon() const { return NULL; }
|
||||
|
|
|
|||
|
|
@ -971,7 +971,7 @@ void LLFastTimerView::printLineStats()
|
|||
{
|
||||
std::string legend_stat;
|
||||
bool first = true;
|
||||
for(block_timer_tree_df_iterator_t it = LLTrace::begin_block_timer_tree_df(FTM_FRAME);
|
||||
for(LLTrace::block_timer_tree_df_iterator_t it = LLTrace::begin_block_timer_tree_df(FTM_FRAME);
|
||||
it != LLTrace::end_block_timer_tree_df();
|
||||
++it)
|
||||
{
|
||||
|
|
@ -993,7 +993,7 @@ void LLFastTimerView::printLineStats()
|
|||
|
||||
std::string timer_stat;
|
||||
first = true;
|
||||
for(block_timer_tree_df_iterator_t it = LLTrace::begin_block_timer_tree_df(FTM_FRAME);
|
||||
for(LLTrace::block_timer_tree_df_iterator_t it = LLTrace::begin_block_timer_tree_df(FTM_FRAME);
|
||||
it != LLTrace::end_block_timer_tree_df();
|
||||
++it)
|
||||
{
|
||||
|
|
@ -1070,7 +1070,7 @@ void LLFastTimerView::drawLineGraph()
|
|||
F32Seconds cur_max(0);
|
||||
U32 cur_max_calls = 0;
|
||||
|
||||
for(block_timer_tree_df_iterator_t it = LLTrace::begin_block_timer_tree_df(FTM_FRAME);
|
||||
for(LLTrace::block_timer_tree_df_iterator_t it = LLTrace::begin_block_timer_tree_df(FTM_FRAME);
|
||||
it != LLTrace::end_block_timer_tree_df();
|
||||
++it)
|
||||
{
|
||||
|
|
@ -1229,8 +1229,8 @@ void LLFastTimerView::drawLegend()
|
|||
#pragma GCC diagnostic ignored "-Wnonnull"
|
||||
#endif
|
||||
// </FS:Zi>
|
||||
for (block_timer_tree_df_iterator_t it = LLTrace::begin_block_timer_tree_df(FTM_FRAME);
|
||||
it != block_timer_tree_df_iterator_t();
|
||||
for (LLTrace::block_timer_tree_df_iterator_t it = LLTrace::begin_block_timer_tree_df(FTM_FRAME);
|
||||
it != LLTrace::end_block_timer_tree_df();
|
||||
++it)
|
||||
// <FS:Zi> GCC12 warning: nonnull - probably bogus
|
||||
#if defined(__GNUC__) && (__GNUC__ >= 12)
|
||||
|
|
@ -1355,8 +1355,8 @@ void LLFastTimerView::generateUniqueColors()
|
|||
#pragma GCC diagnostic ignored "-Wnonnull"
|
||||
#endif
|
||||
// </FS:Zi>
|
||||
for (block_timer_tree_df_iterator_t it = LLTrace::begin_block_timer_tree_df(FTM_FRAME);
|
||||
it != block_timer_tree_df_iterator_t();
|
||||
for (LLTrace::block_timer_tree_df_iterator_t it = LLTrace::begin_block_timer_tree_df(FTM_FRAME);
|
||||
it != LLTrace::end_block_timer_tree_df();
|
||||
++it)
|
||||
// <FS:Zi> GCC12 warning: nonnull - probably bogus
|
||||
#if defined(__GNUC__) && (__GNUC__ >= 12)
|
||||
|
|
|
|||
|
|
@ -446,6 +446,7 @@ public:
|
|||
|
||||
if (item)
|
||||
{
|
||||
LLFavoritesBarCtrl::sWaitingForCallabck = 0.f;
|
||||
LLFavoritesOrderStorage::instance().setSortIndex(item, mSortField);
|
||||
|
||||
item->setComplete(TRUE);
|
||||
|
|
@ -491,6 +492,9 @@ struct LLFavoritesSort
|
|||
}
|
||||
};
|
||||
|
||||
|
||||
F64 LLFavoritesBarCtrl::sWaitingForCallabck = 0.f;
|
||||
|
||||
LLFavoritesBarCtrl::Params::Params()
|
||||
: image_drag_indication("image_drag_indication"),
|
||||
more_button("more_button"),
|
||||
|
|
@ -510,7 +514,7 @@ LLFavoritesBarCtrl::LLFavoritesBarCtrl(const LLFavoritesBarCtrl::Params& p)
|
|||
mShowDragMarker(FALSE),
|
||||
mLandingTab(NULL),
|
||||
mLastTab(NULL),
|
||||
mTabsHighlightEnabled(TRUE),
|
||||
mItemsListDirty(false),
|
||||
mUpdateDropDownItems(true),
|
||||
mRestoreOverflowMenu(false),
|
||||
mGetPrevItems(true),
|
||||
|
|
@ -765,6 +769,9 @@ void LLFavoritesBarCtrl::handleNewFavoriteDragAndDrop(LLInventoryItem *item, con
|
|||
int sortField = 0;
|
||||
LLPointer<LLItemCopiedCallback> cb;
|
||||
|
||||
const F64 CALLBACK_WAIT_TIME = 30.f;
|
||||
sWaitingForCallabck = LLTimer::getTotalSeconds() + CALLBACK_WAIT_TIME;
|
||||
|
||||
// current order is saved by setting incremental values (1, 2, 3, ...) for the sort field
|
||||
for (LLInventoryModel::item_array_t::iterator i = mItems.begin(); i != mItems.end(); ++i)
|
||||
{
|
||||
|
|
@ -838,16 +845,22 @@ void LLFavoritesBarCtrl::changed(U32 mask)
|
|||
LLFavoritesOrderStorage::instance().getSLURL((*i)->getAssetUUID());
|
||||
}
|
||||
|
||||
updateButtons();
|
||||
if (!mItemsChangedTimer.getStarted())
|
||||
{
|
||||
mItemsChangedTimer.start();
|
||||
}
|
||||
else
|
||||
{
|
||||
mItemsChangedTimer.reset();
|
||||
}
|
||||
|
||||
if (sWaitingForCallabck < LLTimer::getTotalSeconds())
|
||||
{
|
||||
updateButtons();
|
||||
if (!mItemsChangedTimer.getStarted())
|
||||
{
|
||||
mItemsChangedTimer.start();
|
||||
}
|
||||
else
|
||||
{
|
||||
mItemsChangedTimer.reset();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
mItemsListDirty = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -901,6 +914,18 @@ void LLFavoritesBarCtrl::draw()
|
|||
mItemsChangedTimer.start();
|
||||
}
|
||||
|
||||
if (mItemsListDirty && sWaitingForCallabck < LLTimer::getTotalSeconds())
|
||||
{
|
||||
updateButtons();
|
||||
if (!mItemsChangedTimer.getStarted())
|
||||
{
|
||||
mItemsChangedTimer.start();
|
||||
}
|
||||
else
|
||||
{
|
||||
mItemsChangedTimer.reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const LLButton::Params& LLFavoritesBarCtrl::getButtonParams()
|
||||
|
|
@ -929,6 +954,7 @@ void LLFavoritesBarCtrl::updateButtons(bool force_update)
|
|||
return;
|
||||
}
|
||||
|
||||
mItemsListDirty = false;
|
||||
mItems.clear();
|
||||
|
||||
if (!collectFavoriteItems(mItems))
|
||||
|
|
|
|||
|
|
@ -56,6 +56,7 @@ public:
|
|||
protected:
|
||||
LLFavoritesBarCtrl(const Params&);
|
||||
friend class LLUICtrlFactory;
|
||||
friend class LLItemCopiedCallback;
|
||||
public:
|
||||
virtual ~LLFavoritesBarCtrl();
|
||||
|
||||
|
|
@ -87,7 +88,6 @@ protected:
|
|||
void onButtonRightClick(LLUUID id,LLView* button,S32 x,S32 y,MASK mask);
|
||||
|
||||
void onButtonMouseDown(LLUUID id, LLUICtrl* button, S32 x, S32 y, MASK mask);
|
||||
void onOverflowMenuItemMouseDown(LLUUID id, LLUICtrl* item, S32 x, S32 y, MASK mask);
|
||||
void onButtonMouseUp(LLUUID id, LLUICtrl* button, S32 x, S32 y, MASK mask);
|
||||
|
||||
void onEndDrag();
|
||||
|
|
@ -171,7 +171,8 @@ private:
|
|||
BOOL mStartDrag;
|
||||
LLInventoryModel::item_array_t mItems;
|
||||
|
||||
BOOL mTabsHighlightEnabled;
|
||||
static F64 sWaitingForCallabck;
|
||||
bool mItemsListDirty;
|
||||
|
||||
S32 mMouseX;
|
||||
S32 mMouseY;
|
||||
|
|
|
|||
|
|
@ -1782,6 +1782,7 @@ void LLFloaterIMContainer::setTimeNow(const LLUUID& session_id, const LLUUID& pa
|
|||
LLConversationItemSession* item = dynamic_cast<LLConversationItemSession*>(getSessionModel(session_id));
|
||||
if (item)
|
||||
{
|
||||
item->setTimeNow(participant_id);
|
||||
mConversationViewModel.requestSortAll();
|
||||
mConversationsRoot->arrangeAll();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -619,6 +619,8 @@ void LLFloaterIMNearbyChatHandler::processChat(const LLChat& chat_msg,
|
|||
static LLCachedControl<bool> FSllOwnerSayToScriptDebugWindow(gSavedPerAccountSettings, "FSllOwnerSayToScriptDebugWindow");
|
||||
if (chat_msg.mChatType == CHAT_TYPE_DEBUG_MSG || (chat_msg.mChatType == CHAT_TYPE_OWNER && FSllOwnerSayToScriptDebugWindow))
|
||||
{
|
||||
if (LLFloater::isQuitRequested()) return;
|
||||
|
||||
// <FS:Kadah> [FSllOwnerSayToScriptDebugWindow] Show llOwnerSays in the script debug window instead of local chat
|
||||
// if(gSavedSettings.getBOOL("ShowScriptErrors") == FALSE)
|
||||
if(gSavedSettings.getBOOL("ShowScriptErrors") == FALSE && chat_msg.mChatType == CHAT_TYPE_DEBUG_MSG)
|
||||
|
|
|
|||
|
|
@ -126,6 +126,7 @@
|
|||
#include "llpresetsmanager.h"
|
||||
#include "llviewercontrol.h"
|
||||
#include "llpresetsmanager.h"
|
||||
#include "llinventoryfunctions.h"
|
||||
|
||||
#include "llsearchableui.h"
|
||||
#include "llperfstats.h"
|
||||
|
|
@ -2839,25 +2840,6 @@ void LLFloaterPreference::onChangeMaturity()
|
|||
getChild<LLIconCtrl>("rating_icon_adult")->setVisible(sim_access == SIM_ACCESS_ADULT);
|
||||
}
|
||||
|
||||
std::string get_category_path(LLUUID cat_id)
|
||||
{
|
||||
LLViewerInventoryCategory* cat = gInventory.getCategory(cat_id);
|
||||
std::string localized_cat_name;
|
||||
if (!LLTrans::findString(localized_cat_name, "InvFolder " + cat->getName()))
|
||||
{
|
||||
localized_cat_name = cat->getName();
|
||||
}
|
||||
|
||||
if (cat->getParentUUID().notNull())
|
||||
{
|
||||
return get_category_path(cat->getParentUUID()) + " > " + localized_cat_name;
|
||||
}
|
||||
else
|
||||
{
|
||||
return localized_cat_name;
|
||||
}
|
||||
}
|
||||
|
||||
std::string get_category_path(LLFolderType::EType cat_type)
|
||||
{
|
||||
LLUUID cat_id = gInventory.findUserDefinedCategoryUUIDForType(cat_type);
|
||||
|
|
|
|||
|
|
@ -60,6 +60,8 @@ LLFloaterProfileTexture::~LLFloaterProfileTexture()
|
|||
mImage->forceActive(); // <FS:Ansariel> Make sure it can get discarded
|
||||
mImage = NULL;
|
||||
}
|
||||
|
||||
LLLoadedCallbackEntry::cleanUpCallbackList(&mCallbackTextureList);
|
||||
}
|
||||
|
||||
// virtual
|
||||
|
|
|
|||
|
|
@ -150,7 +150,7 @@ public:
|
|||
const LLUUID& invoice,
|
||||
const sparam_t& strings);
|
||||
|
||||
LLSD getIDs( sparam_t::const_iterator it, sparam_t::const_iterator end, S32 count );
|
||||
static LLSD getIDs( sparam_t::const_iterator it, sparam_t::const_iterator end, S32 count );
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -2987,11 +2987,12 @@ bool LLDispatchSetEstateAccess::operator()(
|
|||
return true;
|
||||
}
|
||||
|
||||
// static
|
||||
LLSD LLDispatchSetEstateExperience::getIDs( sparam_t::const_iterator it, sparam_t::const_iterator end, S32 count )
|
||||
{
|
||||
LLSD idList = LLSD::emptyArray();
|
||||
LLUUID id;
|
||||
while(count--> 0)
|
||||
while (count-- > 0 && it < end)
|
||||
{
|
||||
memcpy(id.mData, (*(it++)).data(), UUID_BYTES);
|
||||
idList.append(id);
|
||||
|
|
@ -3005,7 +3006,7 @@ LLSD LLDispatchSetEstateExperience::getIDs( sparam_t::const_iterator it, sparam_
|
|||
// strings[2] = str(num blocked)
|
||||
// strings[3] = str(num trusted)
|
||||
// strings[4] = str(num allowed)
|
||||
// strings[8] = bin(uuid) ...
|
||||
// strings[5] = bin(uuid) ...
|
||||
// ...
|
||||
bool LLDispatchSetEstateExperience::operator()(
|
||||
const LLDispatcher* dispatcher,
|
||||
|
|
@ -3014,23 +3015,30 @@ bool LLDispatchSetEstateExperience::operator()(
|
|||
const sparam_t& strings)
|
||||
{
|
||||
LLPanelRegionExperiences* panel = LLFloaterRegionInfo::getPanelExperiences();
|
||||
if (!panel) return true;
|
||||
if (!panel)
|
||||
return true;
|
||||
|
||||
const sparam_t::size_type MIN_SIZE = 5;
|
||||
if (strings.size() < MIN_SIZE)
|
||||
return true;
|
||||
|
||||
// Skip 2 parameters
|
||||
sparam_t::const_iterator it = strings.begin();
|
||||
++it; // U32 estate_id = strtol((*it).c_str(), NULL, 10);
|
||||
++it; // U32 send_to_agent_only = strtoul((*(++it)).c_str(), NULL, 10);
|
||||
|
||||
// Read 3 parameters
|
||||
LLUUID id;
|
||||
S32 num_blocked = strtol((*(it++)).c_str(), NULL, 10);
|
||||
S32 num_trusted = strtol((*(it++)).c_str(), NULL, 10);
|
||||
S32 num_allowed = strtol((*(it++)).c_str(), NULL, 10);
|
||||
|
||||
LLSD ids = LLSD::emptyMap()
|
||||
.with("blocked", getIDs(it, strings.end(), num_blocked))
|
||||
.with("trusted", getIDs(it + (num_blocked), strings.end(), num_trusted))
|
||||
.with("allowed", getIDs(it + (num_blocked+num_trusted), strings.end(), num_allowed));
|
||||
.with("blocked", getIDs(it, strings.end(), num_blocked))
|
||||
.with("trusted", getIDs(it + num_blocked, strings.end(), num_trusted))
|
||||
.with("allowed", getIDs(it + num_blocked + num_trusted, strings.end(), num_allowed));
|
||||
|
||||
panel->processResponse(ids);
|
||||
panel->processResponse(ids);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -71,14 +71,14 @@ void LLFloaterSidePanelContainer::closeFloater(bool app_quitting)
|
|||
if (parent == this )
|
||||
{
|
||||
LLSidepanelAppearance* panel_appearance = dynamic_cast<LLSidepanelAppearance*>(getPanel("appearance"));
|
||||
if ( panel_appearance )
|
||||
if (panel_appearance)
|
||||
{
|
||||
LLPanelEditWearable *edit_wearable_ptr = panel_appearance->getWearable();
|
||||
if (edit_wearable_ptr)
|
||||
{
|
||||
edit_wearable_ptr->onClose();
|
||||
}
|
||||
if(!app_quitting)
|
||||
if (!app_quitting)
|
||||
{
|
||||
panel_appearance->showOutfitsInventoryPanel();
|
||||
}
|
||||
|
|
@ -133,11 +133,16 @@ LLFloater* LLFloaterSidePanelContainer::getTopmostInventoryFloater()
|
|||
LLPanel* LLFloaterSidePanelContainer::openChildPanel(const std::string& panel_name, const LLSD& params)
|
||||
{
|
||||
LLView* view = findChildView(panel_name, true);
|
||||
if (!view) return NULL;
|
||||
if (!view)
|
||||
return NULL;
|
||||
|
||||
if (!getVisible())
|
||||
{
|
||||
openFloater();
|
||||
openFloater();
|
||||
}
|
||||
else if (!hasFocus())
|
||||
{
|
||||
setFocus(TRUE);
|
||||
}
|
||||
|
||||
LLPanel* panel = NULL;
|
||||
|
|
|
|||
|
|
@ -243,8 +243,13 @@ void LLGLTFMaterialList::applyOverrideMessage(LLMessageSystem* msg, const std::s
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
region->cacheFullUpdateGLTFOverride(cache);
|
||||
// <FS:Beq> FIRE-33808 - Material Override Cache causes long delays
|
||||
if(cache.mSides.size() > 0)
|
||||
{
|
||||
region->cacheFullUpdateGLTFOverride(cache);
|
||||
LL_DEBUGS("GLTF") << "GLTF Material Override: " << cache.mObjectId << " " << cache.mLocalId << " " << cache.mRegionHandle << " (sides:" << (cache.mSides.size()) << ")" << LL_ENDL;
|
||||
}
|
||||
// </FS:Beq>
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue