Merge branch 'master' of https://vcs.firestormviewer.org/phoenix-firestorm
commit
d06c357bab
|
|
@ -3476,9 +3476,9 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
|
|||
<key>archive</key>
|
||||
<map>
|
||||
<key>hash</key>
|
||||
<string>b639d0035f4a8c9b4973be428a1b7e61</string>
|
||||
<string>5e553a4358203f283c74744aed2fcd8c</string>
|
||||
<key>url</key>
|
||||
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/69569/671323/vlc_bin-3.0.9.549888-darwin64-549888.tar.bz2</string>
|
||||
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/54836/510036/vlc_bin-2.2.8.538966-darwin64-538966.tar.bz2</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>darwin64</string>
|
||||
|
|
@ -3512,9 +3512,9 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
|
|||
<key>archive</key>
|
||||
<map>
|
||||
<key>hash</key>
|
||||
<string>4f50b0c47daa081dd4fcb83763d5b0b2</string>
|
||||
<string>ca84b7c5f86e702fb35727eed8f0c8c4</string>
|
||||
<key>url</key>
|
||||
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/69567/671314/vlc_bin-3.0.9.549888-windows-549888.tar.bz2</string>
|
||||
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/54958/511725/vlc_bin-2.2.8.538966-windows-538966.tar.bz2</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>windows</string>
|
||||
|
|
@ -3524,16 +3524,16 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
|
|||
<key>archive</key>
|
||||
<map>
|
||||
<key>hash</key>
|
||||
<string>c2f8c01fb6c261b72beb07f0c4cd423f</string>
|
||||
<string>93cd88d90cb8aedbed5cd90ff9262409</string>
|
||||
<key>url</key>
|
||||
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/69568/671315/vlc_bin-3.0.9.549888-windows64-549888.tar.bz2</string>
|
||||
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/54954/511718/vlc_bin-2.2.8.538966-windows64-538966.tar.bz2</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>windows64</string>
|
||||
</map>
|
||||
</map>
|
||||
<key>version</key>
|
||||
<string>3.0.9.549888</string>
|
||||
<string>2.2.8.538966</string>
|
||||
</map>
|
||||
<key>xmlrpc-epi</key>
|
||||
<map>
|
||||
|
|
|
|||
|
|
@ -72,7 +72,8 @@ mSystem(system),
|
|||
mCurrentInternetStreamp(NULL),
|
||||
mStreamGroup(NULL),
|
||||
mFMODInternetStreamChannelp(NULL),
|
||||
mGain(1.0f)
|
||||
mGain(1.0f),
|
||||
mWasAlreadyPlaying(false)
|
||||
{
|
||||
// Number of milliseconds of audio to buffer for the audio card.
|
||||
// Must be larger than the usual Second Life frame stutter time.
|
||||
|
|
@ -158,18 +159,14 @@ void LLStreamingAudio_FMODSTUDIO::update()
|
|||
if (Check_FMOD_Error(mCurrentInternetStreamp->getOpenState(open_state, &progress, &starving, &diskbusy), "FMOD::Sound::getOpenState"))
|
||||
{
|
||||
LL_WARNS() << "Internet stream openstate error: open_state = " << open_state << " - progress = " << progress << " - starving = " << starving << " - diskbusy = " << diskbusy << LL_ENDL;
|
||||
bool was_playing = mWasAlreadyPlaying;
|
||||
stop();
|
||||
return;
|
||||
}
|
||||
else if (open_state == FMOD_OPENSTATE_ERROR)
|
||||
{
|
||||
// Actually we might not get into this case at all since according to the
|
||||
// FMOD API doc, one should check the result of getOpenState for further
|
||||
// details, which most likely means if open_state is FMOD_OPENSTATE_ERROR,
|
||||
// calling getOpenState will return anything but FMOD_OK and we end up in
|
||||
// the if-case above.
|
||||
LL_WARNS() << "Internet stream openstate error: progress = " << progress << " - starving = " << starving << " - diskbusy = " << diskbusy << LL_ENDL;
|
||||
stop();
|
||||
// Try to restart previously playing stream on socket error
|
||||
if (open_state == FMOD_OPENSTATE_ERROR && was_playing)
|
||||
{
|
||||
LL_WARNS() << "Stream was playing before - trying to restart" << LL_ENDL;
|
||||
start(mURL);
|
||||
}
|
||||
return;
|
||||
}
|
||||
else if (open_state == FMOD_OPENSTATE_READY)
|
||||
|
|
@ -183,6 +180,14 @@ void LLStreamingAudio_FMODSTUDIO::update()
|
|||
// Reset volume to previously set volume
|
||||
setGain(getGain());
|
||||
Check_FMOD_Error(mFMODInternetStreamChannelp->setPaused(false), "FMOD::Channel::setPaused");
|
||||
mWasAlreadyPlaying = true;
|
||||
}
|
||||
}
|
||||
else if (open_state == FMOD_OPENSTATE_PLAYING)
|
||||
{
|
||||
if (!mWasAlreadyPlaying)
|
||||
{
|
||||
mWasAlreadyPlaying = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -317,6 +322,7 @@ void LLStreamingAudio_FMODSTUDIO::update()
|
|||
void LLStreamingAudio_FMODSTUDIO::stop()
|
||||
{
|
||||
mPendingURL.clear();
|
||||
mWasAlreadyPlaying = false;
|
||||
|
||||
if (mFMODInternetStreamChannelp)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -80,6 +80,8 @@ private:
|
|||
bool mNewMetadata;
|
||||
LLSD mMetadata;
|
||||
// </DKO> Streamtitle display
|
||||
|
||||
bool mWasAlreadyPlaying;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,582 @@
|
|||
// Provides an efficient blocking version of moodycamel::ConcurrentQueue.
|
||||
// ©2015-2020 Cameron Desrochers. Distributed under the terms of the simplified
|
||||
// BSD license, available at the top of concurrentqueue.h.
|
||||
// Also dual-licensed under the Boost Software License (see LICENSE.md)
|
||||
// Uses Jeff Preshing's semaphore implementation (under the terms of its
|
||||
// separate zlib license, see lightweightsemaphore.h).
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "concurrentqueue.h"
|
||||
#include "lightweightsemaphore.h"
|
||||
|
||||
#include <type_traits>
|
||||
#include <cerrno>
|
||||
#include <memory>
|
||||
#include <chrono>
|
||||
#include <ctime>
|
||||
|
||||
namespace moodycamel
|
||||
{
|
||||
// This is a blocking version of the queue. It has an almost identical interface to
|
||||
// the normal non-blocking version, with the addition of various wait_dequeue() methods
|
||||
// and the removal of producer-specific dequeue methods.
|
||||
template<typename T, typename Traits = ConcurrentQueueDefaultTraits>
|
||||
class BlockingConcurrentQueue
|
||||
{
|
||||
private:
|
||||
typedef ::moodycamel::ConcurrentQueue<T, Traits> ConcurrentQueue;
|
||||
typedef ::moodycamel::LightweightSemaphore LightweightSemaphore;
|
||||
|
||||
public:
|
||||
typedef typename ConcurrentQueue::producer_token_t producer_token_t;
|
||||
typedef typename ConcurrentQueue::consumer_token_t consumer_token_t;
|
||||
|
||||
typedef typename ConcurrentQueue::index_t index_t;
|
||||
typedef typename ConcurrentQueue::size_t size_t;
|
||||
typedef typename std::make_signed<size_t>::type ssize_t;
|
||||
|
||||
static const size_t BLOCK_SIZE = ConcurrentQueue::BLOCK_SIZE;
|
||||
static const size_t EXPLICIT_BLOCK_EMPTY_COUNTER_THRESHOLD = ConcurrentQueue::EXPLICIT_BLOCK_EMPTY_COUNTER_THRESHOLD;
|
||||
static const size_t EXPLICIT_INITIAL_INDEX_SIZE = ConcurrentQueue::EXPLICIT_INITIAL_INDEX_SIZE;
|
||||
static const size_t IMPLICIT_INITIAL_INDEX_SIZE = ConcurrentQueue::IMPLICIT_INITIAL_INDEX_SIZE;
|
||||
static const size_t INITIAL_IMPLICIT_PRODUCER_HASH_SIZE = ConcurrentQueue::INITIAL_IMPLICIT_PRODUCER_HASH_SIZE;
|
||||
static const std::uint32_t EXPLICIT_CONSUMER_CONSUMPTION_QUOTA_BEFORE_ROTATE = ConcurrentQueue::EXPLICIT_CONSUMER_CONSUMPTION_QUOTA_BEFORE_ROTATE;
|
||||
static const size_t MAX_SUBQUEUE_SIZE = ConcurrentQueue::MAX_SUBQUEUE_SIZE;
|
||||
|
||||
public:
|
||||
// Creates a queue with at least `capacity` element slots; note that the
|
||||
// actual number of elements that can be inserted without additional memory
|
||||
// allocation depends on the number of producers and the block size (e.g. if
|
||||
// the block size is equal to `capacity`, only a single block will be allocated
|
||||
// up-front, which means only a single producer will be able to enqueue elements
|
||||
// without an extra allocation -- blocks aren't shared between producers).
|
||||
// This method is not thread safe -- it is up to the user to ensure that the
|
||||
// queue is fully constructed before it starts being used by other threads (this
|
||||
// includes making the memory effects of construction visible, possibly with a
|
||||
// memory barrier).
|
||||
explicit BlockingConcurrentQueue(size_t capacity = 6 * BLOCK_SIZE)
|
||||
: inner(capacity), sema(create<LightweightSemaphore, ssize_t, int>(0, (int)Traits::MAX_SEMA_SPINS), &BlockingConcurrentQueue::template destroy<LightweightSemaphore>)
|
||||
{
|
||||
assert(reinterpret_cast<ConcurrentQueue*>((BlockingConcurrentQueue*)1) == &((BlockingConcurrentQueue*)1)->inner && "BlockingConcurrentQueue must have ConcurrentQueue as its first member");
|
||||
if (!sema) {
|
||||
MOODYCAMEL_THROW(std::bad_alloc());
|
||||
}
|
||||
}
|
||||
|
||||
BlockingConcurrentQueue(size_t minCapacity, size_t maxExplicitProducers, size_t maxImplicitProducers)
|
||||
: inner(minCapacity, maxExplicitProducers, maxImplicitProducers), sema(create<LightweightSemaphore, ssize_t, int>(0, (int)Traits::MAX_SEMA_SPINS), &BlockingConcurrentQueue::template destroy<LightweightSemaphore>)
|
||||
{
|
||||
assert(reinterpret_cast<ConcurrentQueue*>((BlockingConcurrentQueue*)1) == &((BlockingConcurrentQueue*)1)->inner && "BlockingConcurrentQueue must have ConcurrentQueue as its first member");
|
||||
if (!sema) {
|
||||
MOODYCAMEL_THROW(std::bad_alloc());
|
||||
}
|
||||
}
|
||||
|
||||
// Disable copying and copy assignment
|
||||
BlockingConcurrentQueue(BlockingConcurrentQueue const&) MOODYCAMEL_DELETE_FUNCTION;
|
||||
BlockingConcurrentQueue& operator=(BlockingConcurrentQueue const&) MOODYCAMEL_DELETE_FUNCTION;
|
||||
|
||||
// Moving is supported, but note that it is *not* a thread-safe operation.
|
||||
// Nobody can use the queue while it's being moved, and the memory effects
|
||||
// of that move must be propagated to other threads before they can use it.
|
||||
// Note: When a queue is moved, its tokens are still valid but can only be
|
||||
// used with the destination queue (i.e. semantically they are moved along
|
||||
// with the queue itself).
|
||||
BlockingConcurrentQueue(BlockingConcurrentQueue&& other) MOODYCAMEL_NOEXCEPT
|
||||
: inner(std::move(other.inner)), sema(std::move(other.sema))
|
||||
{ }
|
||||
|
||||
inline BlockingConcurrentQueue& operator=(BlockingConcurrentQueue&& other) MOODYCAMEL_NOEXCEPT
|
||||
{
|
||||
return swap_internal(other);
|
||||
}
|
||||
|
||||
// Swaps this queue's state with the other's. Not thread-safe.
|
||||
// Swapping two queues does not invalidate their tokens, however
|
||||
// the tokens that were created for one queue must be used with
|
||||
// only the swapped queue (i.e. the tokens are tied to the
|
||||
// queue's movable state, not the object itself).
|
||||
inline void swap(BlockingConcurrentQueue& other) MOODYCAMEL_NOEXCEPT
|
||||
{
|
||||
swap_internal(other);
|
||||
}
|
||||
|
||||
private:
|
||||
BlockingConcurrentQueue& swap_internal(BlockingConcurrentQueue& other)
|
||||
{
|
||||
if (this == &other) {
|
||||
return *this;
|
||||
}
|
||||
|
||||
inner.swap(other.inner);
|
||||
sema.swap(other.sema);
|
||||
return *this;
|
||||
}
|
||||
|
||||
public:
|
||||
// Enqueues a single item (by copying it).
|
||||
// Allocates memory if required. Only fails if memory allocation fails (or implicit
|
||||
// production is disabled because Traits::INITIAL_IMPLICIT_PRODUCER_HASH_SIZE is 0,
|
||||
// or Traits::MAX_SUBQUEUE_SIZE has been defined and would be surpassed).
|
||||
// Thread-safe.
|
||||
inline bool enqueue(T const& item)
|
||||
{
|
||||
if ((details::likely)(inner.enqueue(item))) {
|
||||
sema->signal();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Enqueues a single item (by moving it, if possible).
|
||||
// Allocates memory if required. Only fails if memory allocation fails (or implicit
|
||||
// production is disabled because Traits::INITIAL_IMPLICIT_PRODUCER_HASH_SIZE is 0,
|
||||
// or Traits::MAX_SUBQUEUE_SIZE has been defined and would be surpassed).
|
||||
// Thread-safe.
|
||||
inline bool enqueue(T&& item)
|
||||
{
|
||||
if ((details::likely)(inner.enqueue(std::move(item)))) {
|
||||
sema->signal();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Enqueues a single item (by copying it) using an explicit producer token.
|
||||
// Allocates memory if required. Only fails if memory allocation fails (or
|
||||
// Traits::MAX_SUBQUEUE_SIZE has been defined and would be surpassed).
|
||||
// Thread-safe.
|
||||
inline bool enqueue(producer_token_t const& token, T const& item)
|
||||
{
|
||||
if ((details::likely)(inner.enqueue(token, item))) {
|
||||
sema->signal();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Enqueues a single item (by moving it, if possible) using an explicit producer token.
|
||||
// Allocates memory if required. Only fails if memory allocation fails (or
|
||||
// Traits::MAX_SUBQUEUE_SIZE has been defined and would be surpassed).
|
||||
// Thread-safe.
|
||||
inline bool enqueue(producer_token_t const& token, T&& item)
|
||||
{
|
||||
if ((details::likely)(inner.enqueue(token, std::move(item)))) {
|
||||
sema->signal();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Enqueues several items.
|
||||
// Allocates memory if required. Only fails if memory allocation fails (or
|
||||
// implicit production is disabled because Traits::INITIAL_IMPLICIT_PRODUCER_HASH_SIZE
|
||||
// is 0, or Traits::MAX_SUBQUEUE_SIZE has been defined and would be surpassed).
|
||||
// Note: Use std::make_move_iterator if the elements should be moved instead of copied.
|
||||
// Thread-safe.
|
||||
template<typename It>
|
||||
inline bool enqueue_bulk(It itemFirst, size_t count)
|
||||
{
|
||||
if ((details::likely)(inner.enqueue_bulk(std::forward<It>(itemFirst), count))) {
|
||||
sema->signal((LightweightSemaphore::ssize_t)(ssize_t)count);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Enqueues several items using an explicit producer token.
|
||||
// Allocates memory if required. Only fails if memory allocation fails
|
||||
// (or Traits::MAX_SUBQUEUE_SIZE has been defined and would be surpassed).
|
||||
// Note: Use std::make_move_iterator if the elements should be moved
|
||||
// instead of copied.
|
||||
// Thread-safe.
|
||||
template<typename It>
|
||||
inline bool enqueue_bulk(producer_token_t const& token, It itemFirst, size_t count)
|
||||
{
|
||||
if ((details::likely)(inner.enqueue_bulk(token, std::forward<It>(itemFirst), count))) {
|
||||
sema->signal((LightweightSemaphore::ssize_t)(ssize_t)count);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Enqueues a single item (by copying it).
|
||||
// Does not allocate memory. Fails if not enough room to enqueue (or implicit
|
||||
// production is disabled because Traits::INITIAL_IMPLICIT_PRODUCER_HASH_SIZE
|
||||
// is 0).
|
||||
// Thread-safe.
|
||||
inline bool try_enqueue(T const& item)
|
||||
{
|
||||
if (inner.try_enqueue(item)) {
|
||||
sema->signal();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Enqueues a single item (by moving it, if possible).
|
||||
// Does not allocate memory (except for one-time implicit producer).
|
||||
// Fails if not enough room to enqueue (or implicit production is
|
||||
// disabled because Traits::INITIAL_IMPLICIT_PRODUCER_HASH_SIZE is 0).
|
||||
// Thread-safe.
|
||||
inline bool try_enqueue(T&& item)
|
||||
{
|
||||
if (inner.try_enqueue(std::move(item))) {
|
||||
sema->signal();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Enqueues a single item (by copying it) using an explicit producer token.
|
||||
// Does not allocate memory. Fails if not enough room to enqueue.
|
||||
// Thread-safe.
|
||||
inline bool try_enqueue(producer_token_t const& token, T const& item)
|
||||
{
|
||||
if (inner.try_enqueue(token, item)) {
|
||||
sema->signal();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Enqueues a single item (by moving it, if possible) using an explicit producer token.
|
||||
// Does not allocate memory. Fails if not enough room to enqueue.
|
||||
// Thread-safe.
|
||||
inline bool try_enqueue(producer_token_t const& token, T&& item)
|
||||
{
|
||||
if (inner.try_enqueue(token, std::move(item))) {
|
||||
sema->signal();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Enqueues several items.
|
||||
// Does not allocate memory (except for one-time implicit producer).
|
||||
// Fails if not enough room to enqueue (or implicit production is
|
||||
// disabled because Traits::INITIAL_IMPLICIT_PRODUCER_HASH_SIZE is 0).
|
||||
// Note: Use std::make_move_iterator if the elements should be moved
|
||||
// instead of copied.
|
||||
// Thread-safe.
|
||||
template<typename It>
|
||||
inline bool try_enqueue_bulk(It itemFirst, size_t count)
|
||||
{
|
||||
if (inner.try_enqueue_bulk(std::forward<It>(itemFirst), count)) {
|
||||
sema->signal((LightweightSemaphore::ssize_t)(ssize_t)count);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Enqueues several items using an explicit producer token.
|
||||
// Does not allocate memory. Fails if not enough room to enqueue.
|
||||
// Note: Use std::make_move_iterator if the elements should be moved
|
||||
// instead of copied.
|
||||
// Thread-safe.
|
||||
template<typename It>
|
||||
inline bool try_enqueue_bulk(producer_token_t const& token, It itemFirst, size_t count)
|
||||
{
|
||||
if (inner.try_enqueue_bulk(token, std::forward<It>(itemFirst), count)) {
|
||||
sema->signal((LightweightSemaphore::ssize_t)(ssize_t)count);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// Attempts to dequeue from the queue.
|
||||
// Returns false if all producer streams appeared empty at the time they
|
||||
// were checked (so, the queue is likely but not guaranteed to be empty).
|
||||
// Never allocates. Thread-safe.
|
||||
template<typename U>
|
||||
inline bool try_dequeue(U& item)
|
||||
{
|
||||
if (sema->tryWait()) {
|
||||
while (!inner.try_dequeue(item)) {
|
||||
continue;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Attempts to dequeue from the queue using an explicit consumer token.
|
||||
// Returns false if all producer streams appeared empty at the time they
|
||||
// were checked (so, the queue is likely but not guaranteed to be empty).
|
||||
// Never allocates. Thread-safe.
|
||||
template<typename U>
|
||||
inline bool try_dequeue(consumer_token_t& token, U& item)
|
||||
{
|
||||
if (sema->tryWait()) {
|
||||
while (!inner.try_dequeue(token, item)) {
|
||||
continue;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Attempts to dequeue several elements from the queue.
|
||||
// Returns the number of items actually dequeued.
|
||||
// Returns 0 if all producer streams appeared empty at the time they
|
||||
// were checked (so, the queue is likely but not guaranteed to be empty).
|
||||
// Never allocates. Thread-safe.
|
||||
template<typename It>
|
||||
inline size_t try_dequeue_bulk(It itemFirst, size_t max)
|
||||
{
|
||||
size_t count = 0;
|
||||
max = (size_t)sema->tryWaitMany((LightweightSemaphore::ssize_t)(ssize_t)max);
|
||||
while (count != max) {
|
||||
count += inner.template try_dequeue_bulk<It&>(itemFirst, max - count);
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
// Attempts to dequeue several elements from the queue using an explicit consumer token.
|
||||
// Returns the number of items actually dequeued.
|
||||
// Returns 0 if all producer streams appeared empty at the time they
|
||||
// were checked (so, the queue is likely but not guaranteed to be empty).
|
||||
// Never allocates. Thread-safe.
|
||||
template<typename It>
|
||||
inline size_t try_dequeue_bulk(consumer_token_t& token, It itemFirst, size_t max)
|
||||
{
|
||||
size_t count = 0;
|
||||
max = (size_t)sema->tryWaitMany((LightweightSemaphore::ssize_t)(ssize_t)max);
|
||||
while (count != max) {
|
||||
count += inner.template try_dequeue_bulk<It&>(token, itemFirst, max - count);
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Blocks the current thread until there's something to dequeue, then
|
||||
// dequeues it.
|
||||
// Never allocates. Thread-safe.
|
||||
template<typename U>
|
||||
inline void wait_dequeue(U& item)
|
||||
{
|
||||
while (!sema->wait()) {
|
||||
continue;
|
||||
}
|
||||
while (!inner.try_dequeue(item)) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// Blocks the current thread until either there's something to dequeue
|
||||
// or the timeout (specified in microseconds) expires. Returns false
|
||||
// without setting `item` if the timeout expires, otherwise assigns
|
||||
// to `item` and returns true.
|
||||
// Using a negative timeout indicates an indefinite timeout,
|
||||
// and is thus functionally equivalent to calling wait_dequeue.
|
||||
// Never allocates. Thread-safe.
|
||||
template<typename U>
|
||||
inline bool wait_dequeue_timed(U& item, std::int64_t timeout_usecs)
|
||||
{
|
||||
if (!sema->wait(timeout_usecs)) {
|
||||
return false;
|
||||
}
|
||||
while (!inner.try_dequeue(item)) {
|
||||
continue;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// Blocks the current thread until either there's something to dequeue
|
||||
// or the timeout expires. Returns false without setting `item` if the
|
||||
// timeout expires, otherwise assigns to `item` and returns true.
|
||||
// Never allocates. Thread-safe.
|
||||
template<typename U, typename Rep, typename Period>
|
||||
inline bool wait_dequeue_timed(U& item, std::chrono::duration<Rep, Period> const& timeout)
|
||||
{
|
||||
return wait_dequeue_timed(item, std::chrono::duration_cast<std::chrono::microseconds>(timeout).count());
|
||||
}
|
||||
|
||||
// Blocks the current thread until there's something to dequeue, then
|
||||
// dequeues it using an explicit consumer token.
|
||||
// Never allocates. Thread-safe.
|
||||
template<typename U>
|
||||
inline void wait_dequeue(consumer_token_t& token, U& item)
|
||||
{
|
||||
while (!sema->wait()) {
|
||||
continue;
|
||||
}
|
||||
while (!inner.try_dequeue(token, item)) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// Blocks the current thread until either there's something to dequeue
|
||||
// or the timeout (specified in microseconds) expires. Returns false
|
||||
// without setting `item` if the timeout expires, otherwise assigns
|
||||
// to `item` and returns true.
|
||||
// Using a negative timeout indicates an indefinite timeout,
|
||||
// and is thus functionally equivalent to calling wait_dequeue.
|
||||
// Never allocates. Thread-safe.
|
||||
template<typename U>
|
||||
inline bool wait_dequeue_timed(consumer_token_t& token, U& item, std::int64_t timeout_usecs)
|
||||
{
|
||||
if (!sema->wait(timeout_usecs)) {
|
||||
return false;
|
||||
}
|
||||
while (!inner.try_dequeue(token, item)) {
|
||||
continue;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// Blocks the current thread until either there's something to dequeue
|
||||
// or the timeout expires. Returns false without setting `item` if the
|
||||
// timeout expires, otherwise assigns to `item` and returns true.
|
||||
// Never allocates. Thread-safe.
|
||||
template<typename U, typename Rep, typename Period>
|
||||
inline bool wait_dequeue_timed(consumer_token_t& token, U& item, std::chrono::duration<Rep, Period> const& timeout)
|
||||
{
|
||||
return wait_dequeue_timed(token, item, std::chrono::duration_cast<std::chrono::microseconds>(timeout).count());
|
||||
}
|
||||
|
||||
// Attempts to dequeue several elements from the queue.
|
||||
// Returns the number of items actually dequeued, which will
|
||||
// always be at least one (this method blocks until the queue
|
||||
// is non-empty) and at most max.
|
||||
// Never allocates. Thread-safe.
|
||||
template<typename It>
|
||||
inline size_t wait_dequeue_bulk(It itemFirst, size_t max)
|
||||
{
|
||||
size_t count = 0;
|
||||
max = (size_t)sema->waitMany((LightweightSemaphore::ssize_t)(ssize_t)max);
|
||||
while (count != max) {
|
||||
count += inner.template try_dequeue_bulk<It&>(itemFirst, max - count);
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
// Attempts to dequeue several elements from the queue.
|
||||
// Returns the number of items actually dequeued, which can
|
||||
// be 0 if the timeout expires while waiting for elements,
|
||||
// and at most max.
|
||||
// Using a negative timeout indicates an indefinite timeout,
|
||||
// and is thus functionally equivalent to calling wait_dequeue_bulk.
|
||||
// Never allocates. Thread-safe.
|
||||
template<typename It>
|
||||
inline size_t wait_dequeue_bulk_timed(It itemFirst, size_t max, std::int64_t timeout_usecs)
|
||||
{
|
||||
size_t count = 0;
|
||||
max = (size_t)sema->waitMany((LightweightSemaphore::ssize_t)(ssize_t)max, timeout_usecs);
|
||||
while (count != max) {
|
||||
count += inner.template try_dequeue_bulk<It&>(itemFirst, max - count);
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
// Attempts to dequeue several elements from the queue.
|
||||
// Returns the number of items actually dequeued, which can
|
||||
// be 0 if the timeout expires while waiting for elements,
|
||||
// and at most max.
|
||||
// Never allocates. Thread-safe.
|
||||
template<typename It, typename Rep, typename Period>
|
||||
inline size_t wait_dequeue_bulk_timed(It itemFirst, size_t max, std::chrono::duration<Rep, Period> const& timeout)
|
||||
{
|
||||
return wait_dequeue_bulk_timed<It&>(itemFirst, max, std::chrono::duration_cast<std::chrono::microseconds>(timeout).count());
|
||||
}
|
||||
|
||||
// Attempts to dequeue several elements from the queue using an explicit consumer token.
|
||||
// Returns the number of items actually dequeued, which will
|
||||
// always be at least one (this method blocks until the queue
|
||||
// is non-empty) and at most max.
|
||||
// Never allocates. Thread-safe.
|
||||
template<typename It>
|
||||
inline size_t wait_dequeue_bulk(consumer_token_t& token, It itemFirst, size_t max)
|
||||
{
|
||||
size_t count = 0;
|
||||
max = (size_t)sema->waitMany((LightweightSemaphore::ssize_t)(ssize_t)max);
|
||||
while (count != max) {
|
||||
count += inner.template try_dequeue_bulk<It&>(token, itemFirst, max - count);
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
// Attempts to dequeue several elements from the queue using an explicit consumer token.
|
||||
// Returns the number of items actually dequeued, which can
|
||||
// be 0 if the timeout expires while waiting for elements,
|
||||
// and at most max.
|
||||
// Using a negative timeout indicates an indefinite timeout,
|
||||
// and is thus functionally equivalent to calling wait_dequeue_bulk.
|
||||
// Never allocates. Thread-safe.
|
||||
template<typename It>
|
||||
inline size_t wait_dequeue_bulk_timed(consumer_token_t& token, It itemFirst, size_t max, std::int64_t timeout_usecs)
|
||||
{
|
||||
size_t count = 0;
|
||||
max = (size_t)sema->waitMany((LightweightSemaphore::ssize_t)(ssize_t)max, timeout_usecs);
|
||||
while (count != max) {
|
||||
count += inner.template try_dequeue_bulk<It&>(token, itemFirst, max - count);
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
// Attempts to dequeue several elements from the queue using an explicit consumer token.
|
||||
// Returns the number of items actually dequeued, which can
|
||||
// be 0 if the timeout expires while waiting for elements,
|
||||
// and at most max.
|
||||
// Never allocates. Thread-safe.
|
||||
template<typename It, typename Rep, typename Period>
|
||||
inline size_t wait_dequeue_bulk_timed(consumer_token_t& token, It itemFirst, size_t max, std::chrono::duration<Rep, Period> const& timeout)
|
||||
{
|
||||
return wait_dequeue_bulk_timed<It&>(token, itemFirst, max, std::chrono::duration_cast<std::chrono::microseconds>(timeout).count());
|
||||
}
|
||||
|
||||
|
||||
// Returns an estimate of the total number of elements currently in the queue. This
|
||||
// estimate is only accurate if the queue has completely stabilized before it is called
|
||||
// (i.e. all enqueue and dequeue operations have completed and their memory effects are
|
||||
// visible on the calling thread, and no further operations start while this method is
|
||||
// being called).
|
||||
// Thread-safe.
|
||||
inline size_t size_approx() const
|
||||
{
|
||||
return (size_t)sema->availableApprox();
|
||||
}
|
||||
|
||||
|
||||
// Returns true if the underlying atomic variables used by
|
||||
// the queue are lock-free (they should be on most platforms).
|
||||
// Thread-safe.
|
||||
static bool is_lock_free()
|
||||
{
|
||||
return ConcurrentQueue::is_lock_free();
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
template<typename U, typename A1, typename A2>
|
||||
static inline U* create(A1&& a1, A2&& a2)
|
||||
{
|
||||
void* p = (Traits::malloc)(sizeof(U));
|
||||
return p != nullptr ? new (p) U(std::forward<A1>(a1), std::forward<A2>(a2)) : nullptr;
|
||||
}
|
||||
|
||||
template<typename U>
|
||||
static inline void destroy(U* p)
|
||||
{
|
||||
if (p != nullptr) {
|
||||
p->~U();
|
||||
}
|
||||
(Traits::free)(p);
|
||||
}
|
||||
|
||||
private:
|
||||
ConcurrentQueue inner;
|
||||
std::unique_ptr<LightweightSemaphore, void (*)(LightweightSemaphore*)> sema;
|
||||
};
|
||||
|
||||
|
||||
template<typename T, typename Traits>
|
||||
inline void swap(BlockingConcurrentQueue<T, Traits>& a, BlockingConcurrentQueue<T, Traits>& b) MOODYCAMEL_NOEXCEPT
|
||||
{
|
||||
a.swap(b);
|
||||
}
|
||||
|
||||
} // end namespace moodycamel
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,411 @@
|
|||
// Provides an efficient implementation of a semaphore (LightweightSemaphore).
|
||||
// This is an extension of Jeff Preshing's sempahore implementation (licensed
|
||||
// under the terms of its separate zlib license) that has been adapted and
|
||||
// extended by Cameron Desrochers.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <cstddef> // For std::size_t
|
||||
#include <atomic>
|
||||
#include <type_traits> // For std::make_signed<T>
|
||||
|
||||
#if defined(_WIN32)
|
||||
// Avoid including windows.h in a header; we only need a handful of
|
||||
// items, so we'll redeclare them here (this is relatively safe since
|
||||
// the API generally has to remain stable between Windows versions).
|
||||
// I know this is an ugly hack but it still beats polluting the global
|
||||
// namespace with thousands of generic names or adding a .cpp for nothing.
|
||||
extern "C" {
|
||||
struct _SECURITY_ATTRIBUTES;
|
||||
__declspec(dllimport) void* __stdcall CreateSemaphoreW(_SECURITY_ATTRIBUTES* lpSemaphoreAttributes, long lInitialCount, long lMaximumCount, const wchar_t* lpName);
|
||||
__declspec(dllimport) int __stdcall CloseHandle(void* hObject);
|
||||
__declspec(dllimport) unsigned long __stdcall WaitForSingleObject(void* hHandle, unsigned long dwMilliseconds);
|
||||
__declspec(dllimport) int __stdcall ReleaseSemaphore(void* hSemaphore, long lReleaseCount, long* lpPreviousCount);
|
||||
}
|
||||
#elif defined(__MACH__)
|
||||
#include <mach/mach.h>
|
||||
#elif defined(__unix__)
|
||||
#include <semaphore.h>
|
||||
#endif
|
||||
|
||||
namespace moodycamel
|
||||
{
|
||||
namespace details
|
||||
{
|
||||
|
||||
// Code in the mpmc_sema namespace below is an adaptation of Jeff Preshing's
|
||||
// portable + lightweight semaphore implementations, originally from
|
||||
// https://github.com/preshing/cpp11-on-multicore/blob/master/common/sema.h
|
||||
// LICENSE:
|
||||
// Copyright (c) 2015 Jeff Preshing
|
||||
//
|
||||
// This software is provided 'as-is', without any express or implied
|
||||
// warranty. In no event will the authors be held liable for any damages
|
||||
// arising from the use of this software.
|
||||
//
|
||||
// Permission is granted to anyone to use this software for any purpose,
|
||||
// including commercial applications, and to alter it and redistribute it
|
||||
// freely, subject to the following restrictions:
|
||||
//
|
||||
// 1. The origin of this software must not be misrepresented; you must not
|
||||
// claim that you wrote the original software. If you use this software
|
||||
// in a product, an acknowledgement in the product documentation would be
|
||||
// appreciated but is not required.
|
||||
// 2. Altered source versions must be plainly marked as such, and must not be
|
||||
// misrepresented as being the original software.
|
||||
// 3. This notice may not be removed or altered from any source distribution.
|
||||
#if defined(_WIN32)
|
||||
class Semaphore
|
||||
{
|
||||
private:
|
||||
void* m_hSema;
|
||||
|
||||
Semaphore(const Semaphore& other) MOODYCAMEL_DELETE_FUNCTION;
|
||||
Semaphore& operator=(const Semaphore& other) MOODYCAMEL_DELETE_FUNCTION;
|
||||
|
||||
public:
|
||||
Semaphore(int initialCount = 0)
|
||||
{
|
||||
assert(initialCount >= 0);
|
||||
const long maxLong = 0x7fffffff;
|
||||
m_hSema = CreateSemaphoreW(nullptr, initialCount, maxLong, nullptr);
|
||||
assert(m_hSema);
|
||||
}
|
||||
|
||||
~Semaphore()
|
||||
{
|
||||
CloseHandle(m_hSema);
|
||||
}
|
||||
|
||||
bool wait()
|
||||
{
|
||||
const unsigned long infinite = 0xffffffff;
|
||||
return WaitForSingleObject(m_hSema, infinite) == 0;
|
||||
}
|
||||
|
||||
bool try_wait()
|
||||
{
|
||||
return WaitForSingleObject(m_hSema, 0) == 0;
|
||||
}
|
||||
|
||||
bool timed_wait(std::uint64_t usecs)
|
||||
{
|
||||
return WaitForSingleObject(m_hSema, (unsigned long)(usecs / 1000)) == 0;
|
||||
}
|
||||
|
||||
void signal(int count = 1)
|
||||
{
|
||||
while (!ReleaseSemaphore(m_hSema, count, nullptr));
|
||||
}
|
||||
};
|
||||
#elif defined(__MACH__)
|
||||
//---------------------------------------------------------
|
||||
// Semaphore (Apple iOS and OSX)
|
||||
// Can't use POSIX semaphores due to http://lists.apple.com/archives/darwin-kernel/2009/Apr/msg00010.html
|
||||
//---------------------------------------------------------
|
||||
class Semaphore
|
||||
{
|
||||
private:
|
||||
semaphore_t m_sema;
|
||||
|
||||
Semaphore(const Semaphore& other) MOODYCAMEL_DELETE_FUNCTION;
|
||||
Semaphore& operator=(const Semaphore& other) MOODYCAMEL_DELETE_FUNCTION;
|
||||
|
||||
public:
|
||||
Semaphore(int initialCount = 0)
|
||||
{
|
||||
assert(initialCount >= 0);
|
||||
kern_return_t rc = semaphore_create(mach_task_self(), &m_sema, SYNC_POLICY_FIFO, initialCount);
|
||||
assert(rc == KERN_SUCCESS);
|
||||
(void)rc;
|
||||
}
|
||||
|
||||
~Semaphore()
|
||||
{
|
||||
semaphore_destroy(mach_task_self(), m_sema);
|
||||
}
|
||||
|
||||
bool wait()
|
||||
{
|
||||
return semaphore_wait(m_sema) == KERN_SUCCESS;
|
||||
}
|
||||
|
||||
bool try_wait()
|
||||
{
|
||||
return timed_wait(0);
|
||||
}
|
||||
|
||||
bool timed_wait(std::uint64_t timeout_usecs)
|
||||
{
|
||||
mach_timespec_t ts;
|
||||
ts.tv_sec = static_cast<unsigned int>(timeout_usecs / 1000000);
|
||||
ts.tv_nsec = static_cast<int>((timeout_usecs % 1000000) * 1000);
|
||||
|
||||
// added in OSX 10.10: https://developer.apple.com/library/prerelease/mac/documentation/General/Reference/APIDiffsMacOSX10_10SeedDiff/modules/Darwin.html
|
||||
kern_return_t rc = semaphore_timedwait(m_sema, ts);
|
||||
return rc == KERN_SUCCESS;
|
||||
}
|
||||
|
||||
void signal()
|
||||
{
|
||||
while (semaphore_signal(m_sema) != KERN_SUCCESS);
|
||||
}
|
||||
|
||||
void signal(int count)
|
||||
{
|
||||
while (count-- > 0)
|
||||
{
|
||||
while (semaphore_signal(m_sema) != KERN_SUCCESS);
|
||||
}
|
||||
}
|
||||
};
|
||||
#elif defined(__unix__)
|
||||
//---------------------------------------------------------
|
||||
// Semaphore (POSIX, Linux)
|
||||
//---------------------------------------------------------
|
||||
class Semaphore
|
||||
{
|
||||
private:
|
||||
sem_t m_sema;
|
||||
|
||||
Semaphore(const Semaphore& other) MOODYCAMEL_DELETE_FUNCTION;
|
||||
Semaphore& operator=(const Semaphore& other) MOODYCAMEL_DELETE_FUNCTION;
|
||||
|
||||
public:
|
||||
Semaphore(int initialCount = 0)
|
||||
{
|
||||
assert(initialCount >= 0);
|
||||
int rc = sem_init(&m_sema, 0, static_cast<unsigned int>(initialCount));
|
||||
assert(rc == 0);
|
||||
(void)rc;
|
||||
}
|
||||
|
||||
~Semaphore()
|
||||
{
|
||||
sem_destroy(&m_sema);
|
||||
}
|
||||
|
||||
bool wait()
|
||||
{
|
||||
// http://stackoverflow.com/questions/2013181/gdb-causes-sem-wait-to-fail-with-eintr-error
|
||||
int rc;
|
||||
do {
|
||||
rc = sem_wait(&m_sema);
|
||||
} while (rc == -1 && errno == EINTR);
|
||||
return rc == 0;
|
||||
}
|
||||
|
||||
bool try_wait()
|
||||
{
|
||||
int rc;
|
||||
do {
|
||||
rc = sem_trywait(&m_sema);
|
||||
} while (rc == -1 && errno == EINTR);
|
||||
return rc == 0;
|
||||
}
|
||||
|
||||
bool timed_wait(std::uint64_t usecs)
|
||||
{
|
||||
struct timespec ts;
|
||||
const int usecs_in_1_sec = 1000000;
|
||||
const int nsecs_in_1_sec = 1000000000;
|
||||
clock_gettime(CLOCK_REALTIME, &ts);
|
||||
ts.tv_sec += (time_t)(usecs / usecs_in_1_sec);
|
||||
ts.tv_nsec += (long)(usecs % usecs_in_1_sec) * 1000;
|
||||
// sem_timedwait bombs if you have more than 1e9 in tv_nsec
|
||||
// so we have to clean things up before passing it in
|
||||
if (ts.tv_nsec >= nsecs_in_1_sec) {
|
||||
ts.tv_nsec -= nsecs_in_1_sec;
|
||||
++ts.tv_sec;
|
||||
}
|
||||
|
||||
int rc;
|
||||
do {
|
||||
rc = sem_timedwait(&m_sema, &ts);
|
||||
} while (rc == -1 && errno == EINTR);
|
||||
return rc == 0;
|
||||
}
|
||||
|
||||
void signal()
|
||||
{
|
||||
while (sem_post(&m_sema) == -1);
|
||||
}
|
||||
|
||||
void signal(int count)
|
||||
{
|
||||
while (count-- > 0)
|
||||
{
|
||||
while (sem_post(&m_sema) == -1);
|
||||
}
|
||||
}
|
||||
};
|
||||
#else
|
||||
#error Unsupported platform! (No semaphore wrapper available)
|
||||
#endif
|
||||
|
||||
} // end namespace details
|
||||
|
||||
|
||||
//---------------------------------------------------------
|
||||
// LightweightSemaphore
|
||||
//---------------------------------------------------------
|
||||
class LightweightSemaphore
|
||||
{
|
||||
public:
|
||||
typedef std::make_signed<std::size_t>::type ssize_t;
|
||||
|
||||
private:
|
||||
std::atomic<ssize_t> m_count;
|
||||
details::Semaphore m_sema;
|
||||
int m_maxSpins;
|
||||
|
||||
bool waitWithPartialSpinning(std::int64_t timeout_usecs = -1)
|
||||
{
|
||||
ssize_t oldCount;
|
||||
int spin = m_maxSpins;
|
||||
while (--spin >= 0)
|
||||
{
|
||||
oldCount = m_count.load(std::memory_order_relaxed);
|
||||
if ((oldCount > 0) && m_count.compare_exchange_strong(oldCount, oldCount - 1, std::memory_order_acquire, std::memory_order_relaxed))
|
||||
return true;
|
||||
std::atomic_signal_fence(std::memory_order_acquire); // Prevent the compiler from collapsing the loop.
|
||||
}
|
||||
oldCount = m_count.fetch_sub(1, std::memory_order_acquire);
|
||||
if (oldCount > 0)
|
||||
return true;
|
||||
if (timeout_usecs < 0)
|
||||
{
|
||||
if (m_sema.wait())
|
||||
return true;
|
||||
}
|
||||
if (timeout_usecs > 0 && m_sema.timed_wait((std::uint64_t)timeout_usecs))
|
||||
return true;
|
||||
// At this point, we've timed out waiting for the semaphore, but the
|
||||
// count is still decremented indicating we may still be waiting on
|
||||
// it. So we have to re-adjust the count, but only if the semaphore
|
||||
// wasn't signaled enough times for us too since then. If it was, we
|
||||
// need to release the semaphore too.
|
||||
while (true)
|
||||
{
|
||||
oldCount = m_count.load(std::memory_order_acquire);
|
||||
if (oldCount >= 0 && m_sema.try_wait())
|
||||
return true;
|
||||
if (oldCount < 0 && m_count.compare_exchange_strong(oldCount, oldCount + 1, std::memory_order_relaxed, std::memory_order_relaxed))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
ssize_t waitManyWithPartialSpinning(ssize_t max, std::int64_t timeout_usecs = -1)
|
||||
{
|
||||
assert(max > 0);
|
||||
ssize_t oldCount;
|
||||
int spin = m_maxSpins;
|
||||
while (--spin >= 0)
|
||||
{
|
||||
oldCount = m_count.load(std::memory_order_relaxed);
|
||||
if (oldCount > 0)
|
||||
{
|
||||
ssize_t newCount = oldCount > max ? oldCount - max : 0;
|
||||
if (m_count.compare_exchange_strong(oldCount, newCount, std::memory_order_acquire, std::memory_order_relaxed))
|
||||
return oldCount - newCount;
|
||||
}
|
||||
std::atomic_signal_fence(std::memory_order_acquire);
|
||||
}
|
||||
oldCount = m_count.fetch_sub(1, std::memory_order_acquire);
|
||||
if (oldCount <= 0)
|
||||
{
|
||||
if ((timeout_usecs == 0) || (timeout_usecs < 0 && !m_sema.wait()) || (timeout_usecs > 0 && !m_sema.timed_wait((std::uint64_t)timeout_usecs)))
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
oldCount = m_count.load(std::memory_order_acquire);
|
||||
if (oldCount >= 0 && m_sema.try_wait())
|
||||
break;
|
||||
if (oldCount < 0 && m_count.compare_exchange_strong(oldCount, oldCount + 1, std::memory_order_relaxed, std::memory_order_relaxed))
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (max > 1)
|
||||
return 1 + tryWaitMany(max - 1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
public:
|
||||
LightweightSemaphore(ssize_t initialCount = 0, int maxSpins = 10000) : m_count(initialCount), m_maxSpins(maxSpins)
|
||||
{
|
||||
assert(initialCount >= 0);
|
||||
assert(maxSpins >= 0);
|
||||
}
|
||||
|
||||
bool tryWait()
|
||||
{
|
||||
ssize_t oldCount = m_count.load(std::memory_order_relaxed);
|
||||
while (oldCount > 0)
|
||||
{
|
||||
if (m_count.compare_exchange_weak(oldCount, oldCount - 1, std::memory_order_acquire, std::memory_order_relaxed))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool wait()
|
||||
{
|
||||
return tryWait() || waitWithPartialSpinning();
|
||||
}
|
||||
|
||||
bool wait(std::int64_t timeout_usecs)
|
||||
{
|
||||
return tryWait() || waitWithPartialSpinning(timeout_usecs);
|
||||
}
|
||||
|
||||
// Acquires between 0 and (greedily) max, inclusive
|
||||
ssize_t tryWaitMany(ssize_t max)
|
||||
{
|
||||
assert(max >= 0);
|
||||
ssize_t oldCount = m_count.load(std::memory_order_relaxed);
|
||||
while (oldCount > 0)
|
||||
{
|
||||
ssize_t newCount = oldCount > max ? oldCount - max : 0;
|
||||
if (m_count.compare_exchange_weak(oldCount, newCount, std::memory_order_acquire, std::memory_order_relaxed))
|
||||
return oldCount - newCount;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Acquires at least one, and (greedily) at most max
|
||||
ssize_t waitMany(ssize_t max, std::int64_t timeout_usecs)
|
||||
{
|
||||
assert(max >= 0);
|
||||
ssize_t result = tryWaitMany(max);
|
||||
if (result == 0 && max > 0)
|
||||
result = waitManyWithPartialSpinning(max, timeout_usecs);
|
||||
return result;
|
||||
}
|
||||
|
||||
ssize_t waitMany(ssize_t max)
|
||||
{
|
||||
ssize_t result = waitMany(max, -1);
|
||||
assert(result > 0);
|
||||
return result;
|
||||
}
|
||||
|
||||
void signal(ssize_t count = 1)
|
||||
{
|
||||
assert(count >= 0);
|
||||
ssize_t oldCount = m_count.fetch_add(count, std::memory_order_release);
|
||||
ssize_t toRelease = -oldCount < count ? -oldCount : count;
|
||||
if (toRelease > 0)
|
||||
{
|
||||
m_sema.signal((int)toRelease);
|
||||
}
|
||||
}
|
||||
|
||||
std::size_t availableApprox() const
|
||||
{
|
||||
ssize_t count = m_count.load(std::memory_order_relaxed);
|
||||
return count > 0 ? static_cast<std::size_t>(count) : 0;
|
||||
}
|
||||
};
|
||||
|
||||
} // end namespace moodycamel
|
||||
|
|
@ -28,4 +28,5 @@
|
|||
namespace LLProfiler
|
||||
{
|
||||
bool active{false};
|
||||
|
||||
}
|
||||
|
|
@ -580,6 +580,31 @@ namespace LLTrace
|
|||
return typename RelatedTypes<T>::fractional_t(getPeriodMeanPerSec(static_cast<const StatType<CountAccumulator>&>(stat), num_periods));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
typename RelatedTypes<typename T::value_t>::fractional_t getPeriodMedianPerSec(const StatType<T>& stat, S32 num_periods = S32_MAX)
|
||||
{
|
||||
num_periods = llmin(num_periods, getNumRecordedPeriods());
|
||||
|
||||
std::vector <typename RelatedTypes<typename T::value_t>::fractional_t> buf;
|
||||
for (S32 i = 1; i <= num_periods; i++)
|
||||
{
|
||||
Recording& recording = getPrevRecording(i);
|
||||
if (recording.getDuration() > (F32Seconds)0.f)
|
||||
{
|
||||
buf.push_back(recording.getPerSec(stat));
|
||||
}
|
||||
}
|
||||
std::sort(buf.begin(), buf.end());
|
||||
|
||||
return typename RelatedTypes<T>::fractional_t((buf.size() % 2 == 0) ? (buf[buf.size() / 2 - 1] + buf[buf.size() / 2]) / 2 : buf[buf.size() / 2]);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
typename RelatedTypes<T>::fractional_t getPeriodMedianPerSec(const CountStatHandle<T>& stat, S32 num_periods = S32_MAX)
|
||||
{
|
||||
return typename RelatedTypes<T>::fractional_t(getPeriodMedianPerSec(static_cast<const StatType<CountAccumulator>&>(stat), num_periods));
|
||||
}
|
||||
|
||||
//
|
||||
// PERIODIC STANDARD DEVIATION
|
||||
//
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@
|
|||
#include "lltimer.h"
|
||||
#include "llthread.h"
|
||||
#include "llmutex.h"
|
||||
|
||||
#include "llprofiler.h"
|
||||
const LLUUID LLUUID::null;
|
||||
const LLTransactionID LLTransactionID::tnull;
|
||||
|
||||
|
|
@ -155,6 +155,7 @@ U32 janky_fast_random_seeded_bytes(U32 seed, U32 val)
|
|||
// Common to all UUID implementations
|
||||
void LLUUID::toString(std::string& out) const
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED;
|
||||
out = llformat(
|
||||
"%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x",
|
||||
(U8)(mData[0]),
|
||||
|
|
@ -217,6 +218,7 @@ BOOL LLUUID::set(const char* in_string, BOOL emit)
|
|||
|
||||
BOOL LLUUID::set(const std::string& in_string, BOOL emit)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED;
|
||||
BOOL broken_format = FALSE;
|
||||
|
||||
// empty strings should make NULL uuid
|
||||
|
|
@ -1027,6 +1029,7 @@ LLUUID::LLUUID()
|
|||
// Copy constructor
|
||||
LLUUID::LLUUID(const LLUUID& rhs)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED;
|
||||
// <FS> Fix for misaligned unsigned ints in LLUUID; by Sovereign Engineer / Shyotl Kuhr
|
||||
//U32 *tmp = (U32 *)mData;
|
||||
//U32 *rhstmp = (U32 *)rhs.mData;
|
||||
|
|
@ -1045,6 +1048,7 @@ LLUUID::LLUUID()
|
|||
// Assignment
|
||||
LLUUID& LLUUID::operator=(const LLUUID& rhs)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED;
|
||||
// <FS> Fix for misaligned unsigned ints in LLUUID; by Sovereign Engineer / Shyotl Kuhr
|
||||
//// No need to check the case where this==&rhs. The branch is slower than the write.
|
||||
//U32 *tmp = (U32 *)mData;
|
||||
|
|
|
|||
|
|
@ -29,10 +29,11 @@
|
|||
#include <iostream>
|
||||
#include <set>
|
||||
#include <vector>
|
||||
#include <cstring> // <FS:Beq> for std::memmove
|
||||
#include "stdtypes.h"
|
||||
#include "llpreprocessor.h"
|
||||
#include <boost/functional/hash.hpp>
|
||||
|
||||
#include "llprofiler.h"
|
||||
class LLMutex;
|
||||
|
||||
const S32 UUID_BYTES = 16;
|
||||
|
|
@ -56,7 +57,9 @@ public:
|
|||
explicit LLUUID(const char *in_string); // Convert from string.
|
||||
explicit LLUUID(const std::string& in_string); // Convert from string.
|
||||
LLUUID(const LLUUID &in);
|
||||
LLUUID(LLUUID&& rhs) noexcept { LL_PROFILE_ZONE_SCOPED; std::memmove(mData, rhs.mData, sizeof(mData));};
|
||||
LLUUID &operator=(const LLUUID &rhs);
|
||||
LLUUID &operator=(LLUUID &&rhs) noexcept { LL_PROFILE_ZONE_SCOPED; std::memmove(mData, rhs.mData, sizeof(mData));return *this;};
|
||||
|
||||
~LLUUID();
|
||||
|
||||
|
|
@ -112,6 +115,61 @@ public:
|
|||
void toString(std::string& out) const;
|
||||
void toCompressedString(char *out) const; // Does not allocate memory, needs 17 characters (including \0)
|
||||
void toCompressedString(std::string& out) const;
|
||||
|
||||
// last 4 chars for quick ref - Very lightweight, no nul-term added - provide your own, ensure min 4 bytes.
|
||||
# define hexnybl(N) (N)>9?((N)-10)+'a':(N)+'0'
|
||||
inline char * toShortString(char *out) const
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED;
|
||||
out[0] = hexnybl(mData[14]>>4);
|
||||
out[1] = hexnybl(mData[14]&15);
|
||||
out[2] = hexnybl(mData[15]>>4);
|
||||
out[3] = hexnybl(mData[15]&15);
|
||||
return out;
|
||||
}
|
||||
// full uuid - Much lighterweight than default, no allocation, or nul-term added - provide your own, ensure min 36 bytes.
|
||||
inline char * toStringFast(char *out) const
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED;
|
||||
out[0] = hexnybl(mData[0]>>4);
|
||||
out[1] = hexnybl(mData[0]&15);
|
||||
out[2] = hexnybl(mData[1]>>4);
|
||||
out[3] = hexnybl(mData[1]&15);
|
||||
out[4] = hexnybl(mData[2]>>4);
|
||||
out[5] = hexnybl(mData[2]&15);
|
||||
out[6] = hexnybl(mData[3]>>4);
|
||||
out[7] = hexnybl(mData[3]&15);
|
||||
out[8] = '-';
|
||||
out[9] = hexnybl(mData[4]>>4);
|
||||
out[10] = hexnybl(mData[4]&15);
|
||||
out[11] = hexnybl(mData[5]>>4);
|
||||
out[12] = hexnybl(mData[5]&15);
|
||||
out[13] = '-';
|
||||
out[14] = hexnybl(mData[6]>>4);
|
||||
out[15] = hexnybl(mData[6]&15);
|
||||
out[16] = hexnybl(mData[7]>>4);
|
||||
out[17] = hexnybl(mData[7]&15);
|
||||
out[18] = '-';
|
||||
out[19] = hexnybl(mData[8]>>4);
|
||||
out[20] = hexnybl(mData[8]&15);
|
||||
out[21] = hexnybl(mData[9]>>4);
|
||||
out[22] = hexnybl(mData[9]&15);
|
||||
out[23] = '-';
|
||||
out[24] = hexnybl(mData[10]>>4);
|
||||
out[25] = hexnybl(mData[10]&15);
|
||||
out[26] = hexnybl(mData[11]>>4);
|
||||
out[27] = hexnybl(mData[11]&15);
|
||||
out[28] = hexnybl(mData[12]>>4);
|
||||
out[29] = hexnybl(mData[12]&15);
|
||||
out[30] = hexnybl(mData[13]>>4);
|
||||
out[31] = hexnybl(mData[13]&15);
|
||||
out[32] = hexnybl(mData[14]>>4);
|
||||
out[33] = hexnybl(mData[14]&15);
|
||||
out[34] = hexnybl(mData[15]>>4);
|
||||
out[35] = hexnybl(mData[15]&15);
|
||||
return out;
|
||||
}
|
||||
|
||||
|
||||
std::string asString() const;
|
||||
std::string getString() const;
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@
|
|||
|
||||
#include "apr.h" // thread-related functions
|
||||
#include "_refcounted.h"
|
||||
#include "llprofiler.h"
|
||||
|
||||
namespace LLCoreInt
|
||||
{
|
||||
|
|
@ -54,6 +55,10 @@ private:
|
|||
|
||||
void run()
|
||||
{ // THREAD CONTEXT
|
||||
// <FS:Beq> - Add threadnames
|
||||
LL_INFOS("THREAD") << "Started unnamed HTTP thread " << LL_ENDL;
|
||||
LL_PROFILER_THREAD_BEGIN("HTTP");
|
||||
// </FS:Beq>
|
||||
|
||||
// Take out additional reference for the at_exit handler
|
||||
addRef();
|
||||
|
|
@ -62,7 +67,10 @@ private:
|
|||
// run the thread function
|
||||
mThreadFunc(this);
|
||||
|
||||
} // THREAD CONTEXT
|
||||
// <FS:Beq> - Add threadnames
|
||||
LL_PROFILER_THREAD_END("HTTP");
|
||||
// </FS:Beq>
|
||||
} // THREAD CONTEXT
|
||||
|
||||
protected:
|
||||
virtual ~HttpThread()
|
||||
|
|
|
|||
|
|
@ -54,6 +54,10 @@ LLScrollListCell* LLScrollListCell::create(const LLScrollListCell::Params& cell_
|
|||
{
|
||||
cell = new LLScrollListIconText(cell_p);
|
||||
}
|
||||
else if (cell_p.type() == "bar")
|
||||
{
|
||||
cell = new LLScrollListBar(cell_p);
|
||||
}
|
||||
else // default is "text"
|
||||
{
|
||||
cell = new LLScrollListText(cell_p);
|
||||
|
|
@ -165,6 +169,74 @@ void LLScrollListIcon::draw(const LLColor4& color, const LLColor4& highlight_col
|
|||
}
|
||||
}
|
||||
|
||||
//
|
||||
// LLScrollListBar
|
||||
//
|
||||
LLScrollListBar::LLScrollListBar(const LLScrollListCell::Params& p)
|
||||
: LLScrollListCell(p),
|
||||
mRatio(0),
|
||||
mColor(p.color),
|
||||
mBottom(1),
|
||||
mLeftPad(1),
|
||||
mRightPad(1)
|
||||
{}
|
||||
|
||||
LLScrollListBar::~LLScrollListBar()
|
||||
{
|
||||
}
|
||||
|
||||
/*virtual*/
|
||||
S32 LLScrollListBar::getHeight() const
|
||||
{
|
||||
return LLScrollListCell::getHeight();
|
||||
}
|
||||
|
||||
/*virtual*/
|
||||
const LLSD LLScrollListBar::getValue() const
|
||||
{
|
||||
return LLStringUtil::null;
|
||||
}
|
||||
|
||||
void LLScrollListBar::setValue(const LLSD& value)
|
||||
{
|
||||
if (value.has("ratio"))
|
||||
{
|
||||
mRatio = value["ratio"].asReal();
|
||||
}
|
||||
if (value.has("bottom"))
|
||||
{
|
||||
mBottom = value["bottom"].asInteger();
|
||||
}
|
||||
if (value.has("left_pad"))
|
||||
{
|
||||
mLeftPad = value["left_pad"].asInteger();
|
||||
}
|
||||
if (value.has("right_pad"))
|
||||
{
|
||||
mRightPad = value["right_pad"].asInteger();
|
||||
}
|
||||
}
|
||||
|
||||
void LLScrollListBar::setColor(const LLColor4& color)
|
||||
{
|
||||
mColor = color;
|
||||
}
|
||||
|
||||
S32 LLScrollListBar::getWidth() const
|
||||
{
|
||||
return LLScrollListCell::getWidth();
|
||||
}
|
||||
|
||||
|
||||
void LLScrollListBar::draw(const LLColor4& color, const LLColor4& highlight_color) const
|
||||
{
|
||||
S32 bar_width = getWidth() - mLeftPad - mRightPad;
|
||||
S32 left = bar_width - bar_width * mRatio;
|
||||
left = llclamp(left, mLeftPad, getWidth() - mRightPad - 1);
|
||||
|
||||
gl_rect_2d(left, mBottom, getWidth() - mRightPad, mBottom - 1, mColor);
|
||||
}
|
||||
|
||||
//
|
||||
// LLScrollListText
|
||||
//
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@
|
|||
#include "lluistring.h"
|
||||
#include "v4color.h"
|
||||
#include "llui.h"
|
||||
#include "llgltexture.h"
|
||||
|
||||
class LLCheckBoxCtrl;
|
||||
class LLSD;
|
||||
|
|
@ -153,6 +154,7 @@ public:
|
|||
|
||||
void setText(const LLStringExplicit& text);
|
||||
void setFontStyle(const U8 font_style);
|
||||
void setAlignment(LLFontGL::HAlign align) { mFontAlignment = align; }
|
||||
|
||||
protected:
|
||||
LLUIString mText;
|
||||
|
|
@ -192,6 +194,26 @@ private:
|
|||
LLFontGL::HAlign mAlignment;
|
||||
};
|
||||
|
||||
|
||||
class LLScrollListBar : public LLScrollListCell
|
||||
{
|
||||
public:
|
||||
LLScrollListBar(const LLScrollListCell::Params& p);
|
||||
/*virtual*/ ~LLScrollListBar();
|
||||
/*virtual*/ void draw(const LLColor4& color, const LLColor4& highlight_color) const;
|
||||
/*virtual*/ S32 getWidth() const;
|
||||
/*virtual*/ S32 getHeight() const;
|
||||
/*virtual*/ const LLSD getValue() const;
|
||||
/*virtual*/ void setColor(const LLColor4&);
|
||||
/*virtual*/ void setValue(const LLSD& value);
|
||||
|
||||
private:
|
||||
LLColor4 mColor;
|
||||
F32 mRatio;
|
||||
S32 mBottom;
|
||||
S32 mRightPad;
|
||||
S32 mLeftPad;
|
||||
};
|
||||
/*
|
||||
* An interactive cell containing a check box.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -399,9 +399,12 @@ set(viewer_SOURCE_FILES
|
|||
llfloaterpathfindinglinksets.cpp
|
||||
llfloaterpathfindingobjects.cpp
|
||||
llfloaterpay.cpp
|
||||
# llfloaterperformance.cpp <FS:Beq/> replaced with fs version due to large changes and likelihood that LL version will not release.
|
||||
fsfloaterperformance.cpp
|
||||
llfloaterperms.cpp
|
||||
llfloaterpostprocess.cpp
|
||||
llfloaterpreference.cpp
|
||||
# llfloaterpreferencesgraphicsadvanced.cpp
|
||||
llfloaterpreferenceviewadvanced.cpp
|
||||
llfloaterpreviewtrash.cpp
|
||||
llfloaterproperties.cpp
|
||||
|
|
@ -1177,9 +1180,12 @@ set(viewer_HEADER_FILES
|
|||
llfloaterpathfindinglinksets.h
|
||||
llfloaterpathfindingobjects.h
|
||||
llfloaterpay.h
|
||||
# llfloaterperformance.h <FS:Beq/> replaced with fs version due to large changes and likelihood that LL version will not release.
|
||||
fsfloaterperformance.h
|
||||
llfloaterperms.h
|
||||
llfloaterpostprocess.h
|
||||
llfloaterpreference.h
|
||||
# llfloaterpreferencesgraphicsadvanced.h
|
||||
llfloaterpreferenceviewadvanced.h
|
||||
llfloaterpreviewtrash.h
|
||||
llfloaterproperties.h
|
||||
|
|
@ -1679,6 +1685,10 @@ configure_file(
|
|||
list(APPEND viewer_HEADER_FILES ${CMAKE_CURRENT_BINARY_DIR}/fsversionvalues.h)
|
||||
# </FS:TS>
|
||||
|
||||
# <FS:Beq> Performance stast support
|
||||
list(APPEND viewer_SOURCE_FILES fsperfstats.cpp)
|
||||
list(APPEND viewer_HEADER_FILES fsperfstats.h)
|
||||
# </FS:Beq>
|
||||
source_group("CMake Rules" FILES ViewerInstall.cmake)
|
||||
|
||||
#build_data.json creation moved to viewer_manifest.py MAINT-6413
|
||||
|
|
|
|||
|
|
@ -638,4 +638,14 @@
|
|||
is_running_function="Floater.IsOpen"
|
||||
is_running_parameters="my_environments"
|
||||
/>
|
||||
<command name="performance"
|
||||
available_in_toybox="true"
|
||||
icon="Command_Performance_Icon"
|
||||
label_ref="Command_Performance_Label"
|
||||
tooltip_ref="Command_Performance_Tooltip"
|
||||
execute_function="Floater.ToggleOrBringToFront"
|
||||
execute_parameters="performance"
|
||||
is_running_function="Floater.IsOpen"
|
||||
is_running_parameters="performance"
|
||||
/>
|
||||
</commands>
|
||||
|
|
|
|||
|
|
@ -8171,7 +8171,7 @@
|
|||
<key>Comment</key>
|
||||
<string>Duration in seconds of the login SRV request timeout</string>
|
||||
<key>Persist</key>
|
||||
<integer>0</integer>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>F32</string>
|
||||
<key>Value</key>
|
||||
|
|
@ -25712,6 +25712,39 @@ Change of this parameter will affect the layout of buttons in notification toast
|
|||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
<key>FSTargetFPS</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Desired minimum FPS</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>U32</string>
|
||||
<key>Value</key>
|
||||
<integer>25</integer>
|
||||
</map>
|
||||
<key>FSAutoTuneFPS</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Allow the viewer to adjust your settings to achieve target FPS</string>
|
||||
<key>Persist</key>
|
||||
<integer>0</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
<key>FSPerfFloaterSmoothingPeriods</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Number of periods to smooth the stats over</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>U32</string>
|
||||
<key>Value</key>
|
||||
<integer>50</integer>
|
||||
</map>
|
||||
<key>FSAutoUnmuteSounds</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
|
|
@ -25734,5 +25767,115 @@ Change of this parameter will affect the layout of buttons in notification toast
|
|||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
<key>RenderJellyDollsAsImpostors</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Use an impostor instead of a JellyDoll for better visuals (true)</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>1</integer>
|
||||
</map>
|
||||
<key>FSPerfStatsCaptureEnabled</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Enable/disable render time data to support autotune.</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>1</integer>
|
||||
</map>
|
||||
<key>FSAutoTuneImpostorByDistEnabled</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Enable/disable using MaxNonImpostor to limit avatar rendering by distance.</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>1</integer>
|
||||
</map>
|
||||
<key>FSAllowSelfImpostor</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Allow own render time to impostor your avatar.</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
<key>FSShowTunedART</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Show the tuned render time in the avatar display.</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
<key>FSRenderAvatarMaxART</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Render Time Limit in microseconds (0.0 = no limit)</string>
|
||||
<key>Persist</key>
|
||||
<integer>0</integer>
|
||||
<key>Type</key>
|
||||
<string>F32</string>
|
||||
<key>Value</key>
|
||||
<real>4.699</real>
|
||||
</map>
|
||||
<key>FSAutoTuneRenderFarClipMin</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>The lowest draw distance that auto tune is allowed to use</string>
|
||||
<key>Persist</key>
|
||||
<integer>0</integer>
|
||||
<key>Type</key>
|
||||
<string>F32</string>
|
||||
<key>Value</key>
|
||||
<real>32.0</real>
|
||||
</map>
|
||||
<key>FSAutoTuneRenderFarClipTarget</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>The draw distance that auto tune will try to achieve</string>
|
||||
<key>Persist</key>
|
||||
<integer>0</integer>
|
||||
<key>Type</key>
|
||||
<string>F32</string>
|
||||
<key>Value</key>
|
||||
<real>256.0</real>
|
||||
</map>
|
||||
<key>FSAutoTuneImpostorFarAwayDistance</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Avatars beyond this range will automatically be optimized</string>
|
||||
<key>Persist</key>
|
||||
<integer>0</integer>
|
||||
<key>Type</key>
|
||||
<string>F32</string>
|
||||
<key>Value</key>
|
||||
<real>64.0</real>
|
||||
</map>
|
||||
<key>FSTuningFPSStrategy</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Strategy to use when tuning FPS. 0=Tune avatar rendering only, 1=Tune both avatar and global scene settings.</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>U32</string>
|
||||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
</map>
|
||||
</llsd>
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,98 @@
|
|||
/**
|
||||
* @file fsfloaterperformance.h
|
||||
*
|
||||
* This is forked directly from an early access release of llfloaterperformance.h
|
||||
*
|
||||
* $LicenseInfo:firstyear=2021&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2021, Linden Research, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#ifndef FS_FLOATERPERFORMANCE_H
|
||||
#define FS_FLOATERPERFORMANCE_H
|
||||
|
||||
#include "llfloater.h"
|
||||
#include "lllistcontextmenu.h"
|
||||
|
||||
class LLCharacter;
|
||||
class LLNameListCtrl;
|
||||
class LLComboBox;
|
||||
|
||||
class FSFloaterPerformance : public LLFloater
|
||||
{
|
||||
public:
|
||||
FSFloaterPerformance(const LLSD& key);
|
||||
virtual ~FSFloaterPerformance();
|
||||
|
||||
/*virtual*/ BOOL postBuild();
|
||||
/*virtual*/ void draw();
|
||||
|
||||
void showSelectedPanel(LLPanel* selected_panel);
|
||||
void showMainPanel();
|
||||
void hidePanels();
|
||||
|
||||
void detachItem(const LLUUID& item_id);
|
||||
|
||||
void onAvatarListRightClick(LLUICtrl* ctrl, S32 x, S32 y);
|
||||
|
||||
void onCustomAction (const LLSD& userdata, const LLUUID& av_id);
|
||||
bool isActionChecked(const LLSD& userdata, const LLUUID& av_id);
|
||||
void onExtendedAction(const LLSD& userdata, const LLUUID& av_id);
|
||||
|
||||
private:
|
||||
void initBackBtn(LLPanel* panel);
|
||||
void populateHUDList();
|
||||
void populateObjectList();
|
||||
void populateNearbyList();
|
||||
|
||||
void onChangeQuality(const LLSD& data);
|
||||
void onClickHideAvatars();
|
||||
void onClickExceptions();
|
||||
void onClickFocusAvatar();
|
||||
|
||||
void updateMaxComplexity();
|
||||
void updateComplexityText();
|
||||
void updateMaxRenderTime();
|
||||
void updateMaxRenderTimeText();
|
||||
|
||||
void getNearbyAvatars(std::vector<LLCharacter*> &valid_nearby_avs);
|
||||
|
||||
LLPanel* mMainPanel;
|
||||
LLPanel* mNearbyPanel;
|
||||
LLPanel* mComplexityPanel;
|
||||
LLPanel* mHUDsPanel;
|
||||
LLPanel* mSettingsPanel;
|
||||
LLPanel* mAutoTunePanel;
|
||||
LLNameListCtrl* mHUDList;
|
||||
LLNameListCtrl* mObjectList;
|
||||
LLNameListCtrl* mNearbyList;
|
||||
LLComboBox* mNearbyCombo;
|
||||
|
||||
LLListContextMenu* mContextMenu;
|
||||
|
||||
LLTimer* mUpdateTimer;
|
||||
|
||||
S32 mNearbyMaxComplexity;
|
||||
|
||||
boost::signals2::connection mComplexityChangedSignal;
|
||||
boost::signals2::connection mMaxARTChangedSignal;
|
||||
};
|
||||
|
||||
#endif // FS_FLOATERPERFORMANCE_H
|
||||
|
|
@ -0,0 +1,419 @@
|
|||
/**
|
||||
* @file fsperfstats.cpp
|
||||
* @brief Stats collection to support perf floater and auto tune
|
||||
*
|
||||
* $LicenseInfo:firstyear=2021&license=fsviewerlgpl$
|
||||
* Phoenix Firestorm Viewer Source Code
|
||||
* Copyright (C) 2021, The Phoenix Firestorm Project, 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
|
||||
*
|
||||
* The Phoenix Firestorm Project, Inc., 1831 Oakwood Drive, Fairmont, Minnesota 56031-3225 USA
|
||||
* http://www.firestormviewer.org
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#include "llviewerprecompiledheaders.h"
|
||||
#include "fsperfstats.h"
|
||||
#include "llcontrol.h"
|
||||
#include "pipeline.h"
|
||||
#include "llagentcamera.h"
|
||||
#include "llvoavatar.h"
|
||||
#include "llworld.h"
|
||||
|
||||
extern LLControlGroup gSavedSettings;
|
||||
|
||||
namespace FSPerfStats
|
||||
{
|
||||
#ifdef USAGE_TRACKING
|
||||
std::atomic<int64_t> inUse{0};
|
||||
std::atomic<int64_t> inUseAvatar{0};
|
||||
std::atomic<int64_t> inUseScene{0};
|
||||
std::atomic<int64_t> inUseAttachment{0};
|
||||
std::atomic<int64_t> inUseAttachmentRigged{0};
|
||||
std::atomic<int64_t> inUseAttachmentUnRigged{0};
|
||||
#endif
|
||||
|
||||
std::atomic<int64_t> tunedAvatars{0};
|
||||
U32 targetFPS; // desired FPS
|
||||
U64 renderAvatarMaxART_ns{(U64)(ART_UNLIMITED_NANOS)}; // highest render time we'll allow without culling features
|
||||
U32 fpsTuningStrategy{0}; // linked to FSTuningFPSStrategy
|
||||
U32 lastGlobalPrefChange{0};
|
||||
std::mutex bufferToggleLock{};
|
||||
bool autoTune{false};
|
||||
|
||||
std::atomic<int> StatsRecorder::writeBuffer{0};
|
||||
bool StatsRecorder::collectionEnabled{true};
|
||||
LLUUID StatsRecorder::focusAv{LLUUID::null};
|
||||
std::array<StatsRecorder::StatsTypeMatrix,2> StatsRecorder::statsDoubleBuffer{ {} };
|
||||
std::array<StatsRecorder::StatsSummaryArray,2> StatsRecorder::max{ {} };
|
||||
std::array<StatsRecorder::StatsSummaryArray,2> StatsRecorder::sum{ {} };
|
||||
|
||||
|
||||
StatsRecorder::StatsRecorder():q(1024*16),t(&StatsRecorder::run)
|
||||
{
|
||||
// create a queue
|
||||
// create a thread to consume from the queue
|
||||
|
||||
FSPerfStats::targetFPS = gSavedSettings.getU32("FSTargetFPS");
|
||||
FSPerfStats::autoTune = gSavedSettings.getBOOL("FSAutoTuneFPS");
|
||||
|
||||
updateRenderCostLimitFromSettings();
|
||||
|
||||
t.detach();
|
||||
}
|
||||
|
||||
// static
|
||||
void StatsRecorder::toggleBuffer()
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED;
|
||||
using ST = StatType_t;
|
||||
|
||||
bool unreliable{false};
|
||||
static LLCachedControl<U32> smoothingPeriods(gSavedSettings, "FSPerfFloaterSmoothingPeriods");
|
||||
|
||||
auto& sceneStats = statsDoubleBuffer[writeBuffer][static_cast<size_t>(ObjType_t::OT_GENERAL)][LLUUID::null];
|
||||
auto& lastStats = statsDoubleBuffer[writeBuffer ^ 1][static_cast<size_t>(ObjType_t::OT_GENERAL)][LLUUID::null];
|
||||
|
||||
static constexpr std::initializer_list<StatType_t> sceneStatsToAvg = {
|
||||
StatType_t::RENDER_FRAME,
|
||||
StatType_t::RENDER_DISPLAY,
|
||||
StatType_t::RENDER_HUDS,
|
||||
StatType_t::RENDER_UI,
|
||||
StatType_t::RENDER_SWAP,
|
||||
// RENDER_LFS,
|
||||
// RENDER_MESHREPO,
|
||||
StatType_t::RENDER_IDLE };
|
||||
|
||||
static constexpr std::initializer_list<StatType_t> avatarStatsToAvg = {
|
||||
StatType_t::RENDER_GEOMETRY,
|
||||
StatType_t::RENDER_SHADOWS,
|
||||
StatType_t::RENDER_COMBINED,
|
||||
StatType_t::RENDER_IDLE };
|
||||
|
||||
|
||||
if( sceneStats[static_cast<size_t>(StatType_t::RENDER_FPSLIMIT)] != 0 || sceneStats[static_cast<size_t>(StatType_t::RENDER_SLEEP)] != 0 )
|
||||
{
|
||||
unreliable = true;
|
||||
lastStats[static_cast<size_t>(StatType_t::RENDER_FPSLIMIT)] = sceneStats[static_cast<size_t>(StatType_t::RENDER_FPSLIMIT)];
|
||||
lastStats[static_cast<size_t>(StatType_t::RENDER_SLEEP)] = sceneStats[static_cast<size_t>(StatType_t::RENDER_SLEEP)];
|
||||
}
|
||||
|
||||
if(!unreliable)
|
||||
{
|
||||
// only use these stats when things are reliable.
|
||||
|
||||
for(auto & statEntry : sceneStatsToAvg)
|
||||
{
|
||||
auto avg = lastStats[static_cast<size_t>(statEntry)];
|
||||
auto val = sceneStats[static_cast<size_t>(statEntry)];
|
||||
sceneStats[static_cast<size_t>(statEntry)] = avg + (val/smoothingPeriods) - (avg/smoothingPeriods);
|
||||
// LL_INFOS("scenestats") << "Scenestat: " << static_cast<size_t>(statEntry) << " before=" << avg << " new=" << val << " newavg=" << statsDoubleBuffer[writeBuffer][static_cast<size_t>(ObjType_t::OT_GENERAL)][LLUUID::null][static_cast<size_t>(statEntry)] << LL_ENDL;
|
||||
}
|
||||
|
||||
auto& statsMap = statsDoubleBuffer[writeBuffer][static_cast<size_t>(ObjType_t::OT_ATTACHMENT)];
|
||||
for(auto& stat_entry : statsMap)
|
||||
{
|
||||
auto val = stat_entry.second[static_cast<size_t>(ST::RENDER_COMBINED)];
|
||||
if(val>smoothingPeriods){
|
||||
auto avg = statsDoubleBuffer[writeBuffer ^ 1][static_cast<size_t>(ObjType_t::OT_ATTACHMENT)][stat_entry.first][static_cast<size_t>(ST::RENDER_COMBINED)];
|
||||
stat_entry.second[static_cast<size_t>(ST::RENDER_COMBINED)] = avg + (val/smoothingPeriods) - (avg/smoothingPeriods);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
auto& statsMapAv = statsDoubleBuffer[writeBuffer][static_cast<size_t>(ObjType_t::OT_AVATAR)];
|
||||
for(auto& stat_entry : statsMapAv)
|
||||
{
|
||||
for(auto& stat : avatarStatsToAvg)
|
||||
{
|
||||
auto val = stat_entry.second[static_cast<size_t>(stat)];
|
||||
if(val>smoothingPeriods)
|
||||
{
|
||||
auto avg = statsDoubleBuffer[writeBuffer ^ 1][static_cast<size_t>(ObjType_t::OT_AVATAR)][stat_entry.first][static_cast<size_t>(stat)];
|
||||
stat_entry.second[static_cast<size_t>(stat)] = avg + (val/smoothingPeriods) - (avg/smoothingPeriods);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// swap the buffers
|
||||
if(enabled())
|
||||
{
|
||||
std::lock_guard<std::mutex> lock{bufferToggleLock};
|
||||
writeBuffer ^= 1;
|
||||
}; // note we are relying on atomic updates here. The risk is low and would cause minor errors in the stats display.
|
||||
}
|
||||
|
||||
// clean the write maps in all cases.
|
||||
auto& statsTypeMatrix = statsDoubleBuffer[writeBuffer];
|
||||
for(auto& statsMap : statsTypeMatrix)
|
||||
{
|
||||
LL_PROFILE_ZONE_NAMED("Clear stats maps");
|
||||
for(auto& stat_entry : statsMap)
|
||||
{
|
||||
std::fill_n(stat_entry.second.begin() ,static_cast<size_t>(ST::STATS_COUNT),0);
|
||||
}
|
||||
statsMap.clear();
|
||||
}
|
||||
for(int i=0; i< static_cast<size_t>(ObjType_t::OT_COUNT); i++)
|
||||
{
|
||||
LL_PROFILE_ZONE_NAMED("clear max/sum");
|
||||
max[writeBuffer][i].fill(0);
|
||||
sum[writeBuffer][i].fill(0);
|
||||
}
|
||||
|
||||
// and now adjust the visuals.
|
||||
if(autoTune)
|
||||
{
|
||||
updateAvatarParams();
|
||||
}
|
||||
}
|
||||
|
||||
// clear buffers when we change region or need a hard reset.
|
||||
// static
|
||||
void StatsRecorder::clearStatsBuffers()
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED;
|
||||
using ST = StatType_t;
|
||||
|
||||
auto& statsTypeMatrix = statsDoubleBuffer[writeBuffer];
|
||||
for(auto& statsMap : statsTypeMatrix)
|
||||
{
|
||||
LL_PROFILE_ZONE_NAMED("Clear stats maps");
|
||||
for(auto& stat_entry : statsMap)
|
||||
{
|
||||
std::fill_n(stat_entry.second.begin() ,static_cast<size_t>(ST::STATS_COUNT),0);
|
||||
}
|
||||
statsMap.clear();
|
||||
}
|
||||
for(int i=0; i< static_cast<size_t>(ObjType_t::OT_COUNT); i++)
|
||||
{
|
||||
LL_PROFILE_ZONE_NAMED("clear max/sum");
|
||||
max[writeBuffer][i].fill(0);
|
||||
sum[writeBuffer][i].fill(0);
|
||||
}
|
||||
// swap the clean buffers in
|
||||
if(enabled())
|
||||
{
|
||||
std::lock_guard<std::mutex> lock{bufferToggleLock};
|
||||
writeBuffer ^= 1;
|
||||
};
|
||||
// repeat before we start processing new stuff
|
||||
for(auto& statsMap : statsTypeMatrix)
|
||||
{
|
||||
LL_PROFILE_ZONE_NAMED("Clear stats maps");
|
||||
for(auto& stat_entry : statsMap)
|
||||
{
|
||||
std::fill_n(stat_entry.second.begin() ,static_cast<size_t>(ST::STATS_COUNT),0);
|
||||
}
|
||||
statsMap.clear();
|
||||
}
|
||||
for(int i=0; i< static_cast<size_t>(ObjType_t::OT_COUNT); i++)
|
||||
{
|
||||
LL_PROFILE_ZONE_NAMED("clear max/sum");
|
||||
max[writeBuffer][i].fill(0);
|
||||
sum[writeBuffer][i].fill(0);
|
||||
}
|
||||
}
|
||||
|
||||
// static
|
||||
void StatsRecorder::updateSettingsFromRenderCostLimit()
|
||||
{
|
||||
static LLCachedControl<F32> maxRenderCost_us(gSavedSettings, "FSRenderAvatarMaxART");
|
||||
if( (F32)maxRenderCost_us != log10( ( (F32)FSPerfStats::renderAvatarMaxART_ns )/1000 ) )
|
||||
{
|
||||
if( FSPerfStats::renderAvatarMaxART_ns != 0 )
|
||||
{
|
||||
gSavedSettings.setF32( "FSRenderAvatarMaxART", log10( ( (F32)FSPerfStats::renderAvatarMaxART_ns )/1000 ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
gSavedSettings.setF32( "FSRenderAvatarMaxART",log10( FSPerfStats::ART_UNLIMITED_NANOS/1000 ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// static
|
||||
void StatsRecorder::updateRenderCostLimitFromSettings()
|
||||
{
|
||||
const auto newval = gSavedSettings.getF32("FSRenderAvatarMaxART");
|
||||
if(newval < log10(FSPerfStats::ART_UNLIMITED_NANOS/1000))
|
||||
{
|
||||
FSPerfStats::renderAvatarMaxART_ns = pow(10,newval)*1000;
|
||||
}
|
||||
else
|
||||
{
|
||||
FSPerfStats::renderAvatarMaxART_ns = 0;
|
||||
};
|
||||
}
|
||||
|
||||
//static
|
||||
int StatsRecorder::countNearbyAvatars(S32 distance)
|
||||
{
|
||||
const auto our_pos = gAgentCamera.getCameraPositionGlobal();
|
||||
|
||||
std::vector<LLVector3d> positions;
|
||||
uuid_vec_t avatar_ids;
|
||||
LLWorld::getInstance()->getAvatars(&avatar_ids, &positions, our_pos, distance);
|
||||
return positions.size();
|
||||
}
|
||||
|
||||
// static
|
||||
void StatsRecorder::updateAvatarParams()
|
||||
{
|
||||
static LLCachedControl<F32> drawDistance(gSavedSettings, "RenderFarClip");
|
||||
static LLCachedControl<F32> userMinDrawDistance(gSavedSettings, "FSAutoTuneRenderFarClipMin");
|
||||
static LLCachedControl<F32> userTargetDrawDistance(gSavedSettings, "FSAutoTuneRenderFarClipTarget");
|
||||
static LLCachedControl<F32> impostorDistance(gSavedSettings, "FSAutoTuneImpostorFarAwayDistance");
|
||||
static LLCachedControl<bool> impostorDistanceTuning(gSavedSettings, "FSAutoTuneImpostorByDistEnabled");
|
||||
static LLCachedControl<U32> maxNonImpostors (gSavedSettings, "IndirectMaxNonImpostors");
|
||||
|
||||
if(impostorDistanceTuning)
|
||||
{
|
||||
// if we have less than the user's "max Non-Impostors" avatars within the desired range then adjust the limit.
|
||||
// also adjusts back up again for nearby crowds.
|
||||
auto count = countNearbyAvatars(std::min(drawDistance, impostorDistance));
|
||||
if( count != maxNonImpostors )
|
||||
{
|
||||
gSavedSettings.setU32("IndirectMaxNonImpostors", (count < LLVOAvatar::NON_IMPOSTORS_MAX_SLIDER)?count : LLVOAvatar::NON_IMPOSTORS_MAX_SLIDER);
|
||||
LL_DEBUGS("AutoTune") << "There are " << count << "avatars within " << std::min(drawDistance, impostorDistance) << "m of the camera" << LL_ENDL;
|
||||
}
|
||||
}
|
||||
|
||||
auto av_render_max_raw = FSPerfStats::StatsRecorder::getMax(ObjType_t::OT_AVATAR, FSPerfStats::StatType_t::RENDER_COMBINED);
|
||||
// Is our target frame time lower than current? If so we need to take action to reduce draw overheads.
|
||||
// cumulative avatar time (includes idle processing, attachments and base av)
|
||||
auto tot_avatar_time_raw = FSPerfStats::StatsRecorder::getSum(ObjType_t::OT_AVATAR, FSPerfStats::StatType_t::RENDER_COMBINED);
|
||||
// sleep time is basically forced sleep when window out of focus
|
||||
auto tot_sleep_time_raw = FSPerfStats::StatsRecorder::getSceneStat(FSPerfStats::StatType_t::RENDER_SLEEP);
|
||||
// similar to sleep time, induced by FPS limit
|
||||
auto tot_limit_time_raw = FSPerfStats::StatsRecorder::getSceneStat(FSPerfStats::StatType_t::RENDER_FPSLIMIT);
|
||||
|
||||
|
||||
// the time spent this frame on the "doFrame" call. Treated as "tot time for frame"
|
||||
auto tot_frame_time_raw = FSPerfStats::StatsRecorder::getSceneStat(FSPerfStats::StatType_t::RENDER_FRAME);
|
||||
|
||||
if( tot_sleep_time_raw != 0 )
|
||||
{
|
||||
// Note: we do not average sleep
|
||||
// if at some point we need to, the averaging will need to take this into account or
|
||||
// we forever think we're in the background due to residuals.
|
||||
LL_DEBUGS() << "No tuning when not in focus" << LL_ENDL;
|
||||
return;
|
||||
}
|
||||
|
||||
// The frametime budget we have based on the target FPS selected
|
||||
auto target_frame_time_raw = (U64)llround((F64)LLTrace::BlockTimer::countsPerSecond()/(targetFPS==0?1:targetFPS));
|
||||
// LL_INFOS() << "Effective FPS(raw):" << tot_frame_time_raw << " Target:" << target_frame_time_raw << LL_ENDL;
|
||||
|
||||
if( tot_limit_time_raw != 0)
|
||||
{
|
||||
// This could be problematic.
|
||||
tot_frame_time_raw -= tot_limit_time_raw;
|
||||
}
|
||||
// 1) Is the target frame tim lower than current?
|
||||
if( target_frame_time_raw <= tot_frame_time_raw )
|
||||
{
|
||||
// if so we've got work to do
|
||||
|
||||
// how much of the frame was spent on non avatar related work?
|
||||
U32 non_avatar_time_raw = tot_frame_time_raw - tot_avatar_time_raw;
|
||||
|
||||
// If the target frame time < non avatar frame time thne adjusting avatars is only goin gto get us so far.
|
||||
U64 target_avatar_time_raw;
|
||||
if(target_frame_time_raw < non_avatar_time_raw)
|
||||
{
|
||||
// we cannnot do this by avatar adjustment alone.
|
||||
if((gFrameCount - FSPerfStats::lastGlobalPrefChange) > 10) // give changes a short time to take effect.
|
||||
{
|
||||
if(FSPerfStats::fpsTuningStrategy == 1)
|
||||
{
|
||||
// 1 - hack the water to opaque. all non opaque have a significant hit, this is a big boost for (arguably) a minor visual hit.
|
||||
// the other reflection options make comparatively little change and iof this overshoots we'll be stepping back up later
|
||||
if(LLPipeline::RenderReflectionDetail != -2)
|
||||
{
|
||||
gSavedSettings.setS32("RenderReflectionDetail", -2);
|
||||
FSPerfStats::lastGlobalPrefChange = gFrameCount;
|
||||
return;
|
||||
}
|
||||
else // deliberately "else" here so we only do these in steps
|
||||
{
|
||||
// step down the DD by 10m per update
|
||||
auto new_dd = (drawDistance-10>userMinDrawDistance)?(drawDistance - 10) : userMinDrawDistance;
|
||||
if(new_dd != drawDistance)
|
||||
{
|
||||
gSavedSettings.setF32("RenderFarClip", new_dd);
|
||||
FSPerfStats::lastGlobalPrefChange = gFrameCount;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
target_avatar_time_raw = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
// desired avatar budget.
|
||||
target_avatar_time_raw = target_frame_time_raw - non_avatar_time_raw;
|
||||
}
|
||||
|
||||
if( target_avatar_time_raw < tot_avatar_time_raw )
|
||||
{
|
||||
// we need to spend less time drawing avatars to meet our budget
|
||||
// Note: working in usecs now cos reasons.
|
||||
auto new_render_limit_ns {renderAvatarMaxART_ns};
|
||||
// max render this frame may be higher than the last (cos new entrants and jitter) so make sure we are heading in the right direction
|
||||
if(FSPerfStats::raw_to_ns(av_render_max_raw) < renderAvatarMaxART_ns)
|
||||
{
|
||||
new_render_limit_ns = FSPerfStats::raw_to_ns(av_render_max_raw);
|
||||
}
|
||||
else
|
||||
{
|
||||
new_render_limit_ns = renderAvatarMaxART_ns;
|
||||
}
|
||||
new_render_limit_ns -= FSPerfStats::ART_MIN_ADJUST_DOWN_NANOS;
|
||||
|
||||
// bounce at the bottom to prevent "no limit"
|
||||
new_render_limit_ns = std::max((U64)new_render_limit_ns, (U64)FSPerfStats::ART_MINIMUM_NANOS);
|
||||
|
||||
// assign the new value
|
||||
renderAvatarMaxART_ns = new_render_limit_ns;
|
||||
// LL_DEBUGS() << "AUTO_TUNE: avatar_budget adjusted to:" << new_render_limit_ns << LL_ENDL;
|
||||
}
|
||||
// LL_DEBUGS() << "AUTO_TUNE: Target frame time:"<< FSPerfStats::raw_to_us(target_frame_time_raw) << "usecs (non_avatar is " << FSPerfStats::raw_to_us(non_avatar_time_raw) << "usecs) Max cost limited=" << renderAvatarMaxART_ns << LL_ENDL;
|
||||
}
|
||||
else if( FSPerfStats::raw_to_ns(target_frame_time_raw) > (FSPerfStats::raw_to_ns(tot_frame_time_raw) + renderAvatarMaxART_ns) )
|
||||
{
|
||||
if( FSPerfStats::tunedAvatars >= 0 )
|
||||
{
|
||||
// if we have more time to spare let's shift up little in the hope we'll restore an avatar.
|
||||
renderAvatarMaxART_ns += FSPerfStats::ART_MIN_ADJUST_UP_NANOS;
|
||||
}
|
||||
if( drawDistance < userTargetDrawDistance )
|
||||
{
|
||||
gSavedSettings.setF32("RenderFarClip", drawDistance + 10.);
|
||||
}
|
||||
if( (target_frame_time_raw * 1.5) > tot_frame_time_raw &&
|
||||
FSPerfStats::tunedAvatars == 0 &&
|
||||
drawDistance >= userTargetDrawDistance)
|
||||
{
|
||||
// if everything else is "max" and we have 50% headroom let's knock the water quality up a notch at a time.
|
||||
auto water = gSavedSettings.getS32("RenderReflectionDetail");
|
||||
gSavedSettings.setS32("RenderReflectionDetail", water+1);
|
||||
}
|
||||
}
|
||||
updateSettingsFromRenderCostLimit();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,498 @@
|
|||
#pragma once
|
||||
#ifndef FS_PERFSTATS_H_INCLUDED
|
||||
#define FS_PERFSTATS_H_INCLUDED
|
||||
/**
|
||||
* @file fsperfstats.h
|
||||
* @brief Statistics collection to support autotune and perf flaoter.
|
||||
*
|
||||
* $LicenseInfo:firstyear=2021&license=fsviewerlgpl$
|
||||
* Phoenix Firestorm Viewer Source Code
|
||||
* Copyright (C) 2021, The Phoenix Firestorm Project, 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
|
||||
*
|
||||
* The Phoenix Firestorm Project, Inc., 1831 Oakwood Drive, Fairmont, Minnesota 56031-3225 USA
|
||||
* http://www.firestormviewer.org
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#include <atomic>
|
||||
#include <chrono>
|
||||
#include <array>
|
||||
#include <unordered_map>
|
||||
#include <mutex>
|
||||
#include "lluuid.h"
|
||||
#include "llfasttimer.h"
|
||||
#include "blockingconcurrentqueue.h"
|
||||
#include "llapp.h"
|
||||
#include "llprofiler.h"
|
||||
#include "pipeline.h"
|
||||
|
||||
// Additional logging options. These can skew inworld numbers so onyl use for debugging and tracking issues
|
||||
#ifdef FS_HAS_TELEMETRY_SUPPORT
|
||||
// USAGE_TRACKING - displays overlapping stats that may imply double counting.
|
||||
// ATTACHMENT_TRACKING - displays detailed tracking info for Avatar and Attachment. very heavy overhead.
|
||||
// #define USAGE_TRACKING
|
||||
// #define ATTACHMENT_TRACKING
|
||||
#else
|
||||
#undef USAGE_TRACKING
|
||||
#undef ATTACHMENT_TRACKING
|
||||
#endif
|
||||
|
||||
extern U32 gFrameCount;
|
||||
extern LLUUID gAgentID;
|
||||
namespace FSPerfStats
|
||||
{
|
||||
#ifdef USAGE_TRACKING
|
||||
extern std::atomic<int64_t> inUse;
|
||||
extern std::atomic<int64_t> inUseAvatar;
|
||||
extern std::atomic<int64_t> inUseScene;
|
||||
extern std::atomic<int64_t> inUseAttachment;
|
||||
extern std::atomic<int64_t> inUseAttachmentRigged;
|
||||
extern std::atomic<int64_t> inUseAttachmentUnRigged;
|
||||
#endif
|
||||
// Note if changing these, they should correspond with the log range of the correpsonding sliders
|
||||
constexpr U64 ART_UNLIMITED_NANOS{50000000};
|
||||
constexpr U64 ART_MINIMUM_NANOS{100000};
|
||||
constexpr U64 ART_MIN_ADJUST_UP_NANOS{10000};
|
||||
constexpr U64 ART_MIN_ADJUST_DOWN_NANOS{10000};
|
||||
|
||||
constexpr F32 PREFERRED_DD{180};
|
||||
|
||||
extern std::atomic<int64_t> tunedAvatars;
|
||||
extern U32 targetFPS; // desired FPS
|
||||
extern U64 renderAvatarMaxART_ns;
|
||||
extern U32 fpsTuningStrategy;
|
||||
extern U32 lastGlobalPrefChange;
|
||||
extern std::mutex bufferToggleLock;
|
||||
extern bool autoTune;
|
||||
|
||||
enum class ObjType_t{
|
||||
OT_GENERAL=0, // Also Unknown. Used for n/a type stats such as scenery
|
||||
OT_AVATAR,
|
||||
OT_ATTACHMENT,
|
||||
OT_HUD,
|
||||
OT_COUNT
|
||||
};
|
||||
enum class StatType_t{
|
||||
RENDER_GEOMETRY=0,
|
||||
RENDER_SHADOWS,
|
||||
RENDER_HUDS,
|
||||
RENDER_UI,
|
||||
RENDER_COMBINED,
|
||||
RENDER_SWAP,
|
||||
RENDER_FRAME,
|
||||
RENDER_DISPLAY,
|
||||
RENDER_SLEEP,
|
||||
RENDER_LFS,
|
||||
RENDER_MESHREPO,
|
||||
RENDER_FPSLIMIT,
|
||||
RENDER_FPS,
|
||||
RENDER_IDLE,
|
||||
RENDER_DONE, // toggle buffer & clearbuffer (see processUpdate for hackery)
|
||||
STATS_COUNT
|
||||
};
|
||||
|
||||
struct StatsRecord
|
||||
{
|
||||
StatType_t statType;
|
||||
ObjType_t objType;
|
||||
LLUUID avID;
|
||||
LLUUID objID;
|
||||
uint64_t time;
|
||||
bool isRigged;
|
||||
bool isHUD;
|
||||
};
|
||||
|
||||
class StatsRecorder{
|
||||
using Queue = moodycamel::BlockingConcurrentQueue<StatsRecord>;
|
||||
public:
|
||||
|
||||
static inline StatsRecorder& getInstance()
|
||||
{
|
||||
static StatsRecorder instance;
|
||||
// volatile int dummy{};
|
||||
return instance;
|
||||
}
|
||||
static inline void setFocusAv(const LLUUID& avID){focusAv = avID;};
|
||||
static inline const LLUUID& getFocusAv(){return (focusAv);};
|
||||
static inline void send(StatsRecord&& u){StatsRecorder::getInstance().q.enqueue(u);};
|
||||
static void endFrame(){StatsRecorder::getInstance().q.enqueue(StatsRecord{StatType_t::RENDER_DONE, ObjType_t::OT_GENERAL, LLUUID::null, LLUUID::null, 0});};
|
||||
static void clearStats(){StatsRecorder::getInstance().q.enqueue(StatsRecord{StatType_t::RENDER_DONE, ObjType_t::OT_GENERAL, LLUUID::null, LLUUID::null, 1});};
|
||||
|
||||
static inline void setEnabled(bool on_or_off){collectionEnabled=on_or_off;};
|
||||
static inline void enable() { collectionEnabled=true; };
|
||||
static inline void disable() { collectionEnabled=false; };
|
||||
static inline bool enabled() { return(collectionEnabled); };
|
||||
|
||||
static inline int getReadBufferIndex() { return (writeBuffer ^ 1); };
|
||||
// static inline const StatsTypeMatrix& getCurrentStatsMatrix(){ return statsDoubleBuffer[getReadBufferIndex()];}
|
||||
static inline uint64_t get(ObjType_t otype, LLUUID id, StatType_t type)
|
||||
{
|
||||
return statsDoubleBuffer[getReadBufferIndex()][static_cast<size_t>(otype)][id][static_cast<size_t>(type)];
|
||||
}
|
||||
static inline uint64_t getSceneStat(StatType_t type)
|
||||
{
|
||||
return statsDoubleBuffer[getReadBufferIndex()][static_cast<size_t>(ObjType_t::OT_GENERAL)][LLUUID::null][static_cast<size_t>(type)];
|
||||
}
|
||||
|
||||
static inline uint64_t getSum(ObjType_t otype, StatType_t type)
|
||||
{
|
||||
return sum[getReadBufferIndex()][static_cast<size_t>(otype)][static_cast<size_t>(type)];
|
||||
}
|
||||
static inline uint64_t getMax(ObjType_t otype, StatType_t type)
|
||||
{
|
||||
return max[getReadBufferIndex()][static_cast<size_t>(otype)][static_cast<size_t>(type)];
|
||||
}
|
||||
static void updateSettingsFromRenderCostLimit();
|
||||
static void updateRenderCostLimitFromSettings();
|
||||
static void updateAvatarParams();
|
||||
private:
|
||||
StatsRecorder();
|
||||
|
||||
static int countNearbyAvatars(S32 distance);
|
||||
// StatsArray is a uint64_t for each possible statistic type.
|
||||
using StatsArray = std::array<uint64_t, static_cast<size_t>(FSPerfStats::StatType_t::STATS_COUNT)>;
|
||||
using StatsMap = std::unordered_map<LLUUID, StatsArray, FSUUIDHash>;
|
||||
using StatsTypeMatrix = std::array<StatsMap, static_cast<size_t>(FSPerfStats::ObjType_t::OT_COUNT)>;
|
||||
using StatsSummaryArray = std::array<StatsArray, static_cast<size_t>(FSPerfStats::ObjType_t::OT_COUNT)>;
|
||||
|
||||
static std::atomic<int> writeBuffer;
|
||||
static LLUUID focusAv;
|
||||
static std::array<StatsTypeMatrix,2> statsDoubleBuffer;
|
||||
static std::array<StatsSummaryArray,2> max;
|
||||
static std::array<StatsSummaryArray,2> sum;
|
||||
static bool collectionEnabled;
|
||||
|
||||
|
||||
void processUpdate(const StatsRecord& upd)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED;
|
||||
// LL_INFOS("perfstats") << "processing update:" << LL_ENDL;
|
||||
using ST = StatType_t;
|
||||
// Note: nullptr is used as the key for global stats
|
||||
#ifdef FS_HAS_TELEMETRY_SUPPORT
|
||||
static char avstr[36];
|
||||
static char obstr[36];
|
||||
#endif
|
||||
|
||||
if (upd.statType == StatType_t::RENDER_DONE && upd.objType == ObjType_t::OT_GENERAL && upd.time == 0)
|
||||
{
|
||||
// LL_INFOS("perfstats") << "End of Frame Toggle Buffer:" << gFrameCount << LL_ENDL;
|
||||
toggleBuffer();
|
||||
return;
|
||||
}
|
||||
if (upd.statType == StatType_t::RENDER_DONE && upd.objType == ObjType_t::OT_GENERAL && upd.time == 1)
|
||||
{
|
||||
// LL_INFOS("perfstats") << "New region - clear buffers:" << gFrameCount << LL_ENDL;
|
||||
clearStatsBuffers();
|
||||
return;
|
||||
}
|
||||
|
||||
auto ot{upd.objType};
|
||||
auto& key{upd.objID};
|
||||
auto& avKey{upd.avID};
|
||||
auto type {upd.statType};
|
||||
auto val {upd.time};
|
||||
|
||||
#ifdef FS_HAS_TELEMETRY_SUPPORT
|
||||
LL_PROFILE_ZONE_TEXT(key.toStringFast(obstr), 36);
|
||||
LL_PROFILE_ZONE_TEXT(avKey.toStringFast(avstr), 36);
|
||||
LL_PROFILE_ZONE_NUM(val);
|
||||
#endif
|
||||
|
||||
if (ot == ObjType_t::OT_GENERAL)
|
||||
{
|
||||
// LL_INFOS("perfstats") << "General update:" << LL_ENDL;
|
||||
doUpd(key, ot, type,val);
|
||||
return;
|
||||
}
|
||||
|
||||
if (ot == ObjType_t::OT_AVATAR)
|
||||
{
|
||||
// LL_INFOS("perfstats") << "Avatar update:" << LL_ENDL;
|
||||
doUpd(avKey, ot, type, val);
|
||||
return;
|
||||
}
|
||||
|
||||
if (ot == ObjType_t::OT_ATTACHMENT)
|
||||
{
|
||||
if( !upd.isRigged && !upd.isHUD )
|
||||
{
|
||||
// For all attachments that are not rigged we add them to the avatar (for all avatars) cost.
|
||||
doUpd(avKey, ObjType_t::OT_AVATAR, type, val);
|
||||
}
|
||||
if( avKey == focusAv )
|
||||
{
|
||||
// For attachments that are for the focusAv (self for now) we record them for the attachment/complexity view
|
||||
if(upd.isHUD)
|
||||
{
|
||||
ot = ObjType_t::OT_HUD;
|
||||
}
|
||||
// LL_INFOS("perfstats") << "frame: " << gFrameCount << " Attachment update("<< (type==StatType_t::RENDER_GEOMETRY?"GEOMETRY":"SHADOW") << ": " << key.asString() << " = " << val << LL_ENDL;
|
||||
doUpd(key, ot, type, val);
|
||||
}
|
||||
else
|
||||
{
|
||||
// LL_INFOS("perfstats") << "frame: " << gFrameCount << " non-self Att update("<< (type==StatType_t::RENDER_GEOMETRY?"GEOMETRY":"SHADOW") << ": " << key.asString() << " = " << val << " for av " << avKey.asString() << LL_ENDL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static inline void doUpd(const LLUUID& key, ObjType_t ot, StatType_t type, uint64_t val)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED;
|
||||
using ST = StatType_t;
|
||||
StatsMap& stm {statsDoubleBuffer[writeBuffer][static_cast<size_t>(ot)]};
|
||||
auto& thisAsset = stm[key];
|
||||
|
||||
thisAsset[static_cast<size_t>(type)] += val;
|
||||
thisAsset[static_cast<size_t>(ST::RENDER_COMBINED)] += val;
|
||||
|
||||
sum[writeBuffer][static_cast<size_t>(ot)][static_cast<size_t>(type)] += val;
|
||||
sum[writeBuffer][static_cast<size_t>(ot)][static_cast<size_t>(ST::RENDER_COMBINED)] += val;
|
||||
|
||||
if(max[writeBuffer][static_cast<size_t>(ot)][static_cast<size_t>(type)] < thisAsset[static_cast<size_t>(type)])
|
||||
{
|
||||
max[writeBuffer][static_cast<size_t>(ot)][static_cast<size_t>(type)] = thisAsset[static_cast<size_t>(type)];
|
||||
}
|
||||
if(max[writeBuffer][static_cast<size_t>(ot)][static_cast<size_t>(ST::RENDER_COMBINED)] < thisAsset[static_cast<size_t>(ST::RENDER_COMBINED)])
|
||||
{
|
||||
max[writeBuffer][static_cast<size_t>(ot)][static_cast<size_t>(ST::RENDER_COMBINED)] = thisAsset[static_cast<size_t>(ST::RENDER_COMBINED)];
|
||||
}
|
||||
}
|
||||
|
||||
static void toggleBuffer();
|
||||
static void clearStatsBuffers();
|
||||
|
||||
// thread entry
|
||||
static void run()
|
||||
{
|
||||
StatsRecord upd[10];
|
||||
auto& instance {StatsRecorder::getInstance()};
|
||||
LL_PROFILER_THREAD_BEGIN("PerfStats");
|
||||
|
||||
while( enabled() && !LLApp::isExiting() )
|
||||
{
|
||||
auto count = instance.q.wait_dequeue_bulk_timed(upd, 10, std::chrono::milliseconds(10));
|
||||
if(count)
|
||||
{
|
||||
// LL_INFOS("perfstats") << "processing " << count << " updates." << LL_ENDL;
|
||||
for(auto i =0; i < count; i++)
|
||||
{
|
||||
instance.processUpdate(upd[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
LL_PROFILER_THREAD_END("PerfStats");
|
||||
}
|
||||
|
||||
Queue q;
|
||||
std::thread t;
|
||||
|
||||
~StatsRecorder() = default;
|
||||
StatsRecorder(const StatsRecorder&) = delete;
|
||||
StatsRecorder& operator=(const StatsRecorder&) = delete;
|
||||
|
||||
};
|
||||
|
||||
template <enum ObjType_t ObjTypeDiscriminator>
|
||||
class RecordTime
|
||||
{
|
||||
|
||||
private:
|
||||
RecordTime(const RecordTime&) = delete;
|
||||
RecordTime() = delete;
|
||||
U64 start;
|
||||
public:
|
||||
StatsRecord stat;
|
||||
|
||||
RecordTime( const LLUUID& av, const LLUUID& id, StatType_t type, bool isRiggedAtt=false, bool isHUDAtt=false):
|
||||
start{LLTrace::BlockTimer::getCPUClockCount64()},
|
||||
stat{type, ObjTypeDiscriminator, std::move(av), std::move(id), 0, isRiggedAtt, isHUDAtt}
|
||||
{
|
||||
LL_PROFILE_ZONE_COLOR(tracy::Color::Orange);
|
||||
#ifdef USAGE_TRACKING
|
||||
if(stat.objType == FSPerfStats::ObjType_t::OT_ATTACHMENT)
|
||||
{
|
||||
if(!stat.isRigged && FSPerfStats::inUseAvatar){FSZoneText("OVERLAP AVATAR",14);}
|
||||
|
||||
LL_PROFILE_PLOT_SQ("InUse", (int64_t)FSPerfStats::inUse, (int64_t)FSPerfStats::inUse+1);
|
||||
FSPerfStats::inUse++;
|
||||
LL_PROFILE_PLOT_SQ("InUseAttachment", (int64_t)FSPerfStats::inUseAttachment, (int64_t)FSPerfStats::inUseAttachment+1);
|
||||
FSPerfStats::inUseAttachment++;
|
||||
if (stat.isRigged)
|
||||
{
|
||||
LL_PROFILE_PLOT_SQ("InUseAttachmentRigged", (int64_t)FSPerfStats::inUseAttachmentRigged,(int64_t)FSPerfStats::inUseAttachmentRigged+1);
|
||||
FSPerfStats::inUseAttachmentRigged++;
|
||||
}
|
||||
else
|
||||
{
|
||||
LL_PROFILE_PLOT_SQ("InUseAttachmentUnRigged", (int64_t)FSPerfStats::inUseAttachmentUnRigged,(int64_t)FSPerfStats::inUseAttachmentUnRigged+1);
|
||||
FSPerfStats::inUseAttachmentUnRigged++;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
};
|
||||
|
||||
template < ObjType_t OD = ObjTypeDiscriminator,
|
||||
std::enable_if_t<OD == ObjType_t::OT_GENERAL> * = nullptr>
|
||||
RecordTime( StatType_t type ):RecordTime<ObjTypeDiscriminator>(LLUUID::null, LLUUID::null, type )
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED;
|
||||
#ifdef USAGE_TRACKING
|
||||
LL_PROFILE_PLOT_SQ("InUseScene", (int64_t)FSPerfStats::inUseScene, (int64_t)FSPerfStats::inUseScene+1);
|
||||
FSPerfStats::inUseScene++;
|
||||
LL_PROFILE_PLOT_SQ("InUse", (int64_t)FSPerfStats::inUse, (int64_t)FSPerfStats::inUse+1);
|
||||
FSPerfStats::inUse++;
|
||||
#endif
|
||||
};
|
||||
|
||||
template < ObjType_t OD = ObjTypeDiscriminator,
|
||||
std::enable_if_t<OD == ObjType_t::OT_AVATAR> * = nullptr>
|
||||
RecordTime( const LLUUID & av, StatType_t type ):RecordTime<ObjTypeDiscriminator>(std::move(av), LLUUID::null, type)
|
||||
{
|
||||
LL_PROFILE_ZONE_COLOR(tracy::Color::Purple);
|
||||
|
||||
#ifdef USAGE_TRACKING
|
||||
if(FSPerfStats::inUseAvatar){FSZoneText("OVERLAP AVATAR",14);}
|
||||
|
||||
LL_PROFILE_PLOT_SQ("InUseAv", (int64_t)FSPerfStats::inUseAvatar, (int64_t)FSPerfStats::inUseAvatar+1);
|
||||
FSPerfStats::inUseAvatar++;
|
||||
LL_PROFILE_PLOT_SQ("InUse", (int64_t)FSPerfStats::inUse, (int64_t)FSPerfStats::inUse+1);
|
||||
FSPerfStats::inUse++;
|
||||
#endif
|
||||
|
||||
};
|
||||
|
||||
~RecordTime()
|
||||
{
|
||||
if(!FSPerfStats::StatsRecorder::enabled())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
LL_PROFILE_ZONE_COLOR(tracy::Color::Red);
|
||||
|
||||
#ifdef USAGE_TRACKING
|
||||
LL_PROFILE_PLOT_SQ("InUse", (int64_t)FSPerfStats::inUse,(int64_t)FSPerfStats::inUse-1);
|
||||
--FSPerfStats::inUse;
|
||||
if (stat.objType == FSPerfStats::ObjType_t::OT_ATTACHMENT)
|
||||
{
|
||||
LL_PROFILE_PLOT_SQ("InUseAttachment", (int64_t)FSPerfStats::inUseAttachment,(int64_t)FSPerfStats::inUseAttachment-1);
|
||||
--FSPerfStats::inUseAttachment;
|
||||
if (stat.isRigged)
|
||||
{
|
||||
LL_PROFILE_PLOT_SQ("InUseAttachmentRigged", (int64_t)FSPerfStats::inUseAttachmentRigged,(int64_t)FSPerfStats::inUseAttachmentRigged-1);
|
||||
--FSPerfStats::inUseAttachmentRigged;
|
||||
}
|
||||
else
|
||||
{
|
||||
LL_PROFILE_PLOT_SQ("InUseAttachmentUnRigged", (int64_t)FSPerfStats::inUseAttachmentUnRigged,(int64_t)FSPerfStats::inUseAttachmentUnRigged-1);
|
||||
--FSPerfStats::inUseAttachmentUnRigged;
|
||||
}
|
||||
}
|
||||
if (stat.objType == FSPerfStats::ObjType_t::OT_GENERAL)
|
||||
{
|
||||
LL_PROFILE_PLOT_SQ("InUseScene", (int64_t)FSPerfStats::inUseScene,(int64_t)FSPerfStats::inUseScene-1);
|
||||
--FSPerfStats::inUseScene;
|
||||
}
|
||||
if( stat.objType == FSPerfStats::ObjType_t::OT_AVATAR )
|
||||
{
|
||||
LL_PROFILE_PLOT_SQ("InUseAv", (int64_t)FSPerfStats::inUseAvatar, (int64_t)FSPerfStats::inUseAvatar-1);
|
||||
--FSPerfStats::inUseAvatar;
|
||||
}
|
||||
#endif
|
||||
stat.time = LLTrace::BlockTimer::getCPUClockCount64() - start;
|
||||
|
||||
#ifdef ATTACHMENT_TRACKING
|
||||
static char obstr[36];
|
||||
static char avstr[36];
|
||||
LL_PROFILE_ZONE_NUM(static_cast<U64>(stat.objType));
|
||||
LL_PROFILE_ZONE_TEXT(stat.avID.toStringFast(avstr), 36);
|
||||
LL_PROFILE_ZONE_TEXT(stat.objID.toStringFast(obstr), 36);
|
||||
LL_PROFILE_ZONE_NUM(stat.time);
|
||||
#endif
|
||||
|
||||
StatsRecorder::send(std::move(stat));
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
inline double raw_to_ns(U64 raw) { return (static_cast<double>(raw) * 1000000000.0) / (F64)LLTrace::BlockTimer::countsPerSecond(); };
|
||||
inline double raw_to_us(U64 raw) { return (static_cast<double>(raw) * 1000000.0) / (F64)LLTrace::BlockTimer::countsPerSecond(); };
|
||||
inline double raw_to_ms(U64 raw) { return (static_cast<double>(raw) * 1000.0) / (F64)LLTrace::BlockTimer::countsPerSecond(); };
|
||||
|
||||
using RecordSceneTime = RecordTime<ObjType_t::OT_GENERAL>;
|
||||
using RecordAvatarTime = RecordTime<ObjType_t::OT_AVATAR>;
|
||||
using RecordAttachmentTime = RecordTime<ObjType_t::OT_ATTACHMENT>;
|
||||
using RecordHudAttachmentTime = RecordTime<ObjType_t::OT_HUD>;
|
||||
|
||||
};// namespace FSPerfStats
|
||||
|
||||
// helper functions
|
||||
using RATptr = std::unique_ptr<FSPerfStats::RecordAttachmentTime>;
|
||||
|
||||
template <typename T>
|
||||
static inline void trackAttachments(const T * vobj, bool isRigged, RATptr* ratPtrp)
|
||||
{
|
||||
if( !vobj ){ ratPtrp->reset(); return;};
|
||||
|
||||
const T* rootAtt{vobj};
|
||||
if (rootAtt->isAttachment())
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED;
|
||||
|
||||
while( !rootAtt->isRootEdit() )
|
||||
{
|
||||
rootAtt = (T*)(rootAtt->getParent());
|
||||
}
|
||||
|
||||
auto avPtr = (T*)(rootAtt->getParent());
|
||||
if(!avPtr){ratPtrp->reset(); return;}
|
||||
|
||||
auto& av = avPtr->getID();
|
||||
auto& obj = rootAtt->getAttachmentItemID();
|
||||
if (!*ratPtrp || (*ratPtrp)->stat.objID != obj || (*ratPtrp)->stat.avID != av)
|
||||
{
|
||||
#if TRACY_ENABLE && defined(ATTACHMENT_TRACKING)
|
||||
LL_PROFILE_ZONE_NAMED_COLOR( "trackAttachments:new", tracy::Color::Red);
|
||||
auto& str = rootAtt->getAttachmentItemName();
|
||||
LL_PROFILE_ZONE_TEXT(str.c_str(), str.size());
|
||||
LL_PROFILE_ZONE_TEXT(isRigged ? "Rigged" : "Unrigged", 8);
|
||||
static char avStr[36];
|
||||
av.toStringFast(avStr);
|
||||
static char obStr[4];
|
||||
obj.toShortString(obStr);
|
||||
LL_PROFILE_ZONE_TEXT( avStr, 36);
|
||||
LL_PROFILE_ZONE_TEXT( obStr, 4);
|
||||
#endif
|
||||
if (*ratPtrp)
|
||||
{
|
||||
// deliberately reset to ensure destruction before construction of replacement.
|
||||
ratPtrp->reset();
|
||||
};
|
||||
*ratPtrp = std::make_unique<FSPerfStats::RecordAttachmentTime>( av,
|
||||
obj,
|
||||
( (LLPipeline::sShadowRender)?FSPerfStats::StatType_t::RENDER_SHADOWS : FSPerfStats::StatType_t::RENDER_GEOMETRY ),
|
||||
isRigged,
|
||||
rootAtt->isHUDAttachment());
|
||||
}
|
||||
}
|
||||
return;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -285,6 +285,7 @@
|
|||
#include "fsassetblacklist.h"
|
||||
|
||||
// #include "fstelemetry.h" // <FS:Beq> Tracy profiler support
|
||||
#include "fsperfstats.h" // <FS:Beq> performance stats support
|
||||
|
||||
#if LL_LINUX && LL_GTK
|
||||
#include "glib.h"
|
||||
|
|
@ -1570,6 +1571,7 @@ void LLAppViewer::initMaxHeapSize()
|
|||
}
|
||||
|
||||
static LLTrace::BlockTimerStatHandle FTM_MESSAGES("System Messages");
|
||||
static LLTrace::BlockTimerStatHandle FTM_MESSAGES2("System Messages2");
|
||||
static LLTrace::BlockTimerStatHandle FTM_SLEEP1("Sleep1");
|
||||
static LLTrace::BlockTimerStatHandle FTM_SLEEP2("Sleep2");
|
||||
static LLTrace::BlockTimerStatHandle FTM_YIELD("Yield");
|
||||
|
|
@ -1634,6 +1636,9 @@ bool LLAppViewer::doFrame()
|
|||
{
|
||||
LL_RECORD_BLOCK_TIME(FTM_FRAME);
|
||||
|
||||
// <FS:Beq> Perfstats collection Frame boundary
|
||||
{FSPerfStats::RecordSceneTime T (FSPerfStats::StatType_t::RENDER_FRAME);
|
||||
|
||||
LLEventPump& mainloop(LLEventPumps::instance().obtain("mainloop"));
|
||||
LLSD newFrame;
|
||||
// <FS:Beq> profiling enablement.
|
||||
|
|
@ -1677,6 +1682,7 @@ bool LLAppViewer::doFrame()
|
|||
LLTimer frameTimer;
|
||||
|
||||
nd::etw::logFrame(); // <FS:ND> Write the start of each frame. Even if our Provider (Firestorm) would be enabled, this has only light impact. Does nothing on OSX and Linux.
|
||||
{FSPerfStats::RecordSceneTime T (FSPerfStats::StatType_t::RENDER_IDLE); // <FS:Beq/> perf stats
|
||||
{
|
||||
LL_PROFILE_ZONE_NAMED( "df blocktimer" )
|
||||
LLTrace::BlockTimer::processTimes();
|
||||
|
|
@ -1688,9 +1694,9 @@ bool LLAppViewer::doFrame()
|
|||
|
||||
//clear call stack records
|
||||
LL_CLEAR_CALLSTACKS();
|
||||
|
||||
} // <FS:Beq/> perf stats
|
||||
{
|
||||
// LL_PROFILE_ZONE_NAMED( "df processMiscNativeEvents" ) // <FS:Beq/> remove misplaced zone marker (see FTM_MESSAGES)
|
||||
{FSPerfStats::RecordSceneTime T (FSPerfStats::StatType_t::RENDER_IDLE); // <FS:Beq> ensure we have the entire top scope of frame covered
|
||||
// <FS:Ansariel> MaxFPS Viewer-Chui merge error
|
||||
// Check if we need to restore rendering masks.
|
||||
if (restore_rendering_masks)
|
||||
|
|
@ -1731,7 +1737,7 @@ bool LLAppViewer::doFrame()
|
|||
|
||||
if (gViewerWindow)
|
||||
{
|
||||
LL_RECORD_BLOCK_TIME(FTM_MESSAGES);
|
||||
LL_RECORD_BLOCK_TIME(FTM_MESSAGES2);
|
||||
if (!restoreErrorTrap())
|
||||
{
|
||||
LL_WARNS() << " Someone took over my signal/exception handler (post messagehandling)!" << LL_ENDL;
|
||||
|
|
@ -1756,12 +1762,12 @@ bool LLAppViewer::doFrame()
|
|||
// canonical per-frame event
|
||||
mainloop.post(newFrame);
|
||||
}
|
||||
|
||||
{
|
||||
LL_PROFILE_ZONE_NAMED( "df suspend" )
|
||||
// give listeners a chance to run
|
||||
llcoro::suspend();
|
||||
}
|
||||
}// <FS:Beq> ensure we have the entire top scope of frame covered
|
||||
|
||||
if (!LLApp::isExiting())
|
||||
{
|
||||
|
|
@ -1778,6 +1784,7 @@ bool LLAppViewer::doFrame()
|
|||
&& (gHeadlessClient || !gViewerWindow->getShowProgress())
|
||||
&& !gFocusMgr.focusLocked())
|
||||
{
|
||||
FSPerfStats::RecordSceneTime T (FSPerfStats::StatType_t::RENDER_IDLE);
|
||||
LL_PROFILE_ZONE_NAMED( "df JoystickKeyboard" )
|
||||
joystick->scanJoystick();
|
||||
gKeyboard->scanKeyboard();
|
||||
|
|
@ -1788,12 +1795,13 @@ bool LLAppViewer::doFrame()
|
|||
if (fsCrouchToggle && fsCrouchToggleStatus)
|
||||
{
|
||||
gAgent.moveUp(-1);
|
||||
}
|
||||
}
|
||||
// </FS:Ansariel>
|
||||
}
|
||||
|
||||
// Update state based on messages, user input, object idle.
|
||||
{
|
||||
FSPerfStats::RecordSceneTime T (FSPerfStats::StatType_t::RENDER_IDLE);
|
||||
LL_PROFILE_ZONE_NAMED( "df pauseMainloopTimeout" )
|
||||
pauseMainloopTimeout(); // *TODO: Remove. Messages shouldn't be stalling for 20+ seconds!
|
||||
}
|
||||
|
|
@ -1810,6 +1818,7 @@ bool LLAppViewer::doFrame()
|
|||
|
||||
if (gDoDisconnect && (LLStartUp::getStartupState() == STATE_STARTED))
|
||||
{
|
||||
LL_PROFILE_ZONE_NAMED("Shutdown:SaveSnapshot");
|
||||
pauseMainloopTimeout();
|
||||
saveFinalSnapshot();
|
||||
disconnectViewer();
|
||||
|
|
@ -1820,7 +1829,7 @@ bool LLAppViewer::doFrame()
|
|||
// *TODO: Should we run display() even during gHeadlessClient? DK 2011-02-18
|
||||
if (!LLApp::isExiting() && !gHeadlessClient && gViewerWindow)
|
||||
{
|
||||
LL_PROFILE_ZONE_NAMED( "df Display" )
|
||||
LL_PROFILE_ZONE_NAMED("df Display")
|
||||
pingMainloopTimeout("Main:Display");
|
||||
gGLActive = TRUE;
|
||||
|
||||
|
|
@ -1844,14 +1853,15 @@ bool LLAppViewer::doFrame()
|
|||
//last_call = LLTimer::getTotalTime();
|
||||
// </FS:Ansariel>
|
||||
|
||||
}
|
||||
{
|
||||
LL_PROFILE_ZONE_NAMED( "df Snapshot" )
|
||||
FSPerfStats::RecordSceneTime T(FSPerfStats::StatType_t::RENDER_IDLE);
|
||||
LL_PROFILE_ZONE_NAMED("df Snapshot")
|
||||
pingMainloopTimeout("Main:Snapshot");
|
||||
LLFloaterSnapshot::update(); // take snapshots
|
||||
LLFloaterOutfitSnapshot::update();
|
||||
gGLActive = FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
|
|
@ -1888,6 +1898,7 @@ bool LLAppViewer::doFrame()
|
|||
// of equal priority on Windows
|
||||
if (milliseconds_to_sleep > 0)
|
||||
{
|
||||
FSPerfStats::RecordSceneTime T ( FSPerfStats::StatType_t::RENDER_SLEEP );
|
||||
ms_sleep(milliseconds_to_sleep);
|
||||
// also pause worker threads during this wait period
|
||||
LLAppViewer::getTextureCache()->pause();
|
||||
|
|
@ -1972,6 +1983,7 @@ bool LLAppViewer::doFrame()
|
|||
if (fsLimitFramerate && LLStartUp::getStartupState() == STATE_STARTED && !gTeleportDisplay && !logoutRequestSent() && max_fps > F_APPROXIMATELY_ZERO)
|
||||
{
|
||||
// Sleep a while to limit frame rate.
|
||||
FSPerfStats::RecordSceneTime T ( FSPerfStats::StatType_t::RENDER_FPSLIMIT );
|
||||
F32 min_frame_time = 1.f / (F32)max_fps;
|
||||
S32 milliseconds_to_sleep = llclamp((S32)((min_frame_time - frameTimer.getElapsedTimeF64()) * 1000.f), 0, 1000);
|
||||
if (milliseconds_to_sleep > 0)
|
||||
|
|
@ -2011,6 +2023,7 @@ bool LLAppViewer::doFrame()
|
|||
LL_INFOS() << "Exiting main_loop" << LL_ENDL;
|
||||
}
|
||||
|
||||
}FSPerfStats::StatsRecorder::endFrame();
|
||||
LL_PROFILER_FRAME_END
|
||||
|
||||
return ! LLApp::isRunning();
|
||||
|
|
@ -5833,6 +5846,7 @@ void LLAppViewer::idle()
|
|||
|
||||
if (!(logoutRequestSent() && hasSavedFinalSnapshot()))
|
||||
{
|
||||
FSPerfStats::tunedAvatars=0; // <FS:Beq> reset the number of avatars that have been tweaked.
|
||||
gObjectList.update(gAgent);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -244,6 +244,12 @@ void LLAvatarRenderNotifier::updateNotificationAgent(U32 agentComplexity)
|
|||
// save the value for use in following messages
|
||||
mLatestAgentComplexity = agentComplexity;
|
||||
|
||||
static LLCachedControl<U32> show_my_complexity_changes(gSavedSettings, "ShowMyComplexityChanges", 20);
|
||||
if (!show_my_complexity_changes)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!isAgentAvatarValid() || !gAgentWearables.areWearablesLoaded())
|
||||
{
|
||||
// data not ready, nothing to show.
|
||||
|
|
@ -291,7 +297,8 @@ static const char* e_hud_messages[] =
|
|||
};
|
||||
|
||||
LLHUDRenderNotifier::LLHUDRenderNotifier() :
|
||||
mReportedHUDWarning(WARN_NONE)
|
||||
mReportedHUDWarning(WARN_NONE),
|
||||
mHUDsCount(0)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
@ -307,6 +314,15 @@ void LLHUDRenderNotifier::updateNotificationHUD(hud_complexity_list_t complexity
|
|||
return;
|
||||
}
|
||||
|
||||
mHUDComplexityList = complexity;
|
||||
mHUDsCount = mHUDComplexityList.size();
|
||||
|
||||
static LLCachedControl<U32> show_my_complexity_changes(gSavedSettings, "ShowMyComplexityChanges", 20);
|
||||
if (!show_my_complexity_changes)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO:
|
||||
// Find a way to show message with list of issues, but without making it too large
|
||||
// and intrusive.
|
||||
|
|
|
|||
|
|
@ -30,6 +30,9 @@
|
|||
#define LL_llavatarrendernotifier_H
|
||||
|
||||
#include "llnotificationptr.h"
|
||||
#include "llviewerobject.h"
|
||||
#include "llhudobject.h"
|
||||
|
||||
|
||||
class LLViewerRegion;
|
||||
|
||||
|
|
@ -63,6 +66,25 @@ struct LLHUDComplexity
|
|||
|
||||
typedef std::list<LLHUDComplexity> hud_complexity_list_t;
|
||||
|
||||
struct LLObjectComplexity
|
||||
{
|
||||
LLObjectComplexity()
|
||||
{
|
||||
reset();
|
||||
}
|
||||
void reset()
|
||||
{
|
||||
objectId = LLUUID::null;
|
||||
objectName = "";
|
||||
objectCost = 0;
|
||||
}
|
||||
LLUUID objectId;
|
||||
std::string objectName;
|
||||
U32 objectCost;
|
||||
};
|
||||
|
||||
typedef std::list<LLObjectComplexity> object_complexity_list_t;
|
||||
|
||||
// Class to notify user about drastic changes in agent's render weights or if other agents
|
||||
// reported that user's agent is too 'heavy' for their settings
|
||||
class LLAvatarRenderNotifier : public LLSingleton<LLAvatarRenderNotifier>
|
||||
|
|
@ -77,6 +99,9 @@ public:
|
|||
void updateNotificationState();
|
||||
void updateNotificationAgent(U32 agentComplexity);
|
||||
|
||||
void setObjectComplexityList(object_complexity_list_t object_list) { mObjectComplexityList = object_list; }
|
||||
object_complexity_list_t getObjectComplexityList() { return mObjectComplexityList; }
|
||||
|
||||
private:
|
||||
|
||||
LLNotificationPtr mNotificationPtr;
|
||||
|
|
@ -109,6 +134,8 @@ private:
|
|||
// Used to detect changes in voavatar's rezzed status.
|
||||
// If value decreases - there were changes in outfit.
|
||||
S32 mLastOutfitRezStatus;
|
||||
|
||||
object_complexity_list_t mObjectComplexityList;
|
||||
};
|
||||
|
||||
// Class to notify user about heavy set of HUD
|
||||
|
|
@ -121,6 +148,9 @@ public:
|
|||
void updateNotificationHUD(hud_complexity_list_t complexity);
|
||||
bool isNotificationVisible();
|
||||
|
||||
hud_complexity_list_t getHUDComplexityList() { return mHUDComplexityList; }
|
||||
S32 getHUDsCount() { return mHUDsCount; }
|
||||
|
||||
private:
|
||||
enum EWarnLevel
|
||||
{
|
||||
|
|
@ -141,6 +171,8 @@ private:
|
|||
EWarnLevel mReportedHUDWarning;
|
||||
LLHUDComplexity mLatestHUDComplexity;
|
||||
LLFrameTimer mHUDPopUpDelayTimer;
|
||||
hud_complexity_list_t mHUDComplexityList;
|
||||
S32 mHUDsCount;
|
||||
};
|
||||
|
||||
#endif /* ! defined(LL_llavatarrendernotifier_H) */
|
||||
|
|
|
|||
|
|
@ -80,6 +80,7 @@ void LLControlAvatar::initInstance()
|
|||
|
||||
const LLVOAvatar *LLControlAvatar::getAttachedAvatar() const
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED;
|
||||
if (mRootVolp && mRootVolp->isAttachment())
|
||||
{
|
||||
return mRootVolp->getAvatarAncestor();
|
||||
|
|
@ -89,6 +90,7 @@ const LLVOAvatar *LLControlAvatar::getAttachedAvatar() const
|
|||
|
||||
LLVOAvatar *LLControlAvatar::getAttachedAvatar()
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED;
|
||||
if (mRootVolp && mRootVolp->isAttachment())
|
||||
{
|
||||
return mRootVolp->getAvatarAncestor();
|
||||
|
|
|
|||
|
|
@ -50,6 +50,7 @@
|
|||
#include "lldrawpoolwlsky.h"
|
||||
#include "llglslshader.h"
|
||||
#include "llglcommonfunc.h"
|
||||
#include "fsperfstats.h" // <FS:Beq> performance stats support
|
||||
|
||||
S32 LLDrawPool::sNumDrawPools = 0;
|
||||
|
||||
|
|
@ -388,10 +389,21 @@ void LLRenderPass::renderGroup(LLSpatialGroup* group, U32 type, U32 mask, BOOL t
|
|||
{
|
||||
LLSpatialGroup::drawmap_elem_t& draw_info = group->mDrawMap[type];
|
||||
|
||||
std::unique_ptr<FSPerfStats::RecordAttachmentTime> ratPtr{}; // <FS:Beq/> Perf stats
|
||||
for (LLSpatialGroup::drawmap_elem_t::iterator k = draw_info.begin(); k != draw_info.end(); ++k)
|
||||
{
|
||||
LLDrawInfo *pparams = *k;
|
||||
if (pparams) {
|
||||
// <FS:Beq> Capture render times
|
||||
if(pparams->mFace)
|
||||
{
|
||||
LLViewerObject* vobj = pparams->mFace->getViewerObject();
|
||||
if(vobj->isAttachment())
|
||||
{
|
||||
trackAttachments( vobj, pparams->mFace->isState(LLFace::RIGGED),&ratPtr);
|
||||
}
|
||||
}
|
||||
// </FS:Beq>
|
||||
pushBatch(*pparams, mask, texture);
|
||||
}
|
||||
}
|
||||
|
|
@ -404,11 +416,22 @@ void LLRenderPass::renderTexture(U32 type, U32 mask, BOOL batch_textures)
|
|||
|
||||
void LLRenderPass::pushBatches(U32 type, U32 mask, BOOL texture, BOOL batch_textures)
|
||||
{
|
||||
std::unique_ptr<FSPerfStats::RecordAttachmentTime> ratPtr{};
|
||||
for (LLCullResult::drawinfo_iterator i = gPipeline.beginRenderMap(type); i != gPipeline.endRenderMap(type); ++i)
|
||||
{
|
||||
LLDrawInfo* pparams = *i;
|
||||
if (pparams)
|
||||
{
|
||||
// <FS:Beq> Capture render times
|
||||
if(pparams->mFace)
|
||||
{
|
||||
LLViewerObject* vobj = pparams->mFace->getViewerObject();
|
||||
if(vobj->isAttachment())
|
||||
{
|
||||
trackAttachments( vobj, pparams->mFace->isState(LLFace::RIGGED),&ratPtr);
|
||||
}
|
||||
}
|
||||
// </FS:Beq>
|
||||
pushBatch(*pparams, mask, texture, batch_textures);
|
||||
}
|
||||
}
|
||||
|
|
@ -416,11 +439,22 @@ void LLRenderPass::pushBatches(U32 type, U32 mask, BOOL texture, BOOL batch_text
|
|||
|
||||
void LLRenderPass::pushMaskBatches(U32 type, U32 mask, BOOL texture, BOOL batch_textures)
|
||||
{
|
||||
std::unique_ptr<FSPerfStats::RecordAttachmentTime> ratPtr{};
|
||||
for (LLCullResult::drawinfo_iterator i = gPipeline.beginRenderMap(type); i != gPipeline.endRenderMap(type); ++i)
|
||||
{
|
||||
LLDrawInfo* pparams = *i;
|
||||
if (pparams)
|
||||
{
|
||||
// <FS:Beq> Capture render times
|
||||
if((*pparams).mFace)
|
||||
{
|
||||
LLViewerObject* vobj = (*pparams).mFace->getViewerObject();
|
||||
if(vobj->isAttachment())
|
||||
{
|
||||
trackAttachments( vobj, (*pparams).mFace->isState(LLFace::RIGGED),&ratPtr);
|
||||
}
|
||||
}
|
||||
// </FS:Beq>
|
||||
if (LLGLSLShader::sCurBoundShaderPtr)
|
||||
{
|
||||
LLGLSLShader::sCurBoundShaderPtr->setMinimumAlpha(pparams->mAlphaMaskCutoff);
|
||||
|
|
|
|||
|
|
@ -48,6 +48,7 @@
|
|||
#include "lldrawpoolwater.h"
|
||||
#include "llspatialpartition.h"
|
||||
#include "llglcommonfunc.h"
|
||||
#include "fsperfstats.h" // <FS:Beq> performance stats support
|
||||
|
||||
BOOL LLDrawPoolAlpha::sShowDebugAlpha = FALSE;
|
||||
|
||||
|
|
@ -341,6 +342,7 @@ void LLDrawPoolAlpha::render(S32 pass)
|
|||
|
||||
void LLDrawPoolAlpha::renderAlphaHighlight(U32 mask)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED;
|
||||
for (LLCullResult::sg_iterator i = gPipeline.beginAlphaGroups(); i != gPipeline.endAlphaGroups(); ++i)
|
||||
{
|
||||
LLSpatialGroup* group = *i;
|
||||
|
|
@ -349,9 +351,20 @@ void LLDrawPoolAlpha::renderAlphaHighlight(U32 mask)
|
|||
{
|
||||
LLSpatialGroup::drawmap_elem_t& draw_info = group->mDrawMap[LLRenderPass::PASS_ALPHA];
|
||||
|
||||
std::unique_ptr<FSPerfStats::RecordAttachmentTime> ratPtr{}; // <FS:Beq/> Render time Stats collection
|
||||
for (LLSpatialGroup::drawmap_elem_t::iterator k = draw_info.begin(); k != draw_info.end(); ++k)
|
||||
{
|
||||
LLDrawInfo& params = **k;
|
||||
// <FS:Beq> Capture render times
|
||||
if(params.mFace)
|
||||
{
|
||||
LLViewerObject* vobj = (LLViewerObject *)params.mFace->getViewerObject();
|
||||
if(vobj->isAttachment())
|
||||
{
|
||||
trackAttachments( vobj, params.mFace->isState(LLFace::RIGGED), &ratPtr );
|
||||
}
|
||||
}
|
||||
// </FS:Beq>
|
||||
|
||||
if (params.mParticle)
|
||||
{
|
||||
|
|
@ -477,6 +490,7 @@ void LLDrawPoolAlpha::RestoreTexSetup(bool tex_setup)
|
|||
|
||||
void LLDrawPoolAlpha::renderSimples(U32 mask, std::vector<LLDrawInfo*>& simples)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED;
|
||||
gPipeline.enableLightsDynamic();
|
||||
simple_shader->bind();
|
||||
simple_shader->bindTexture(LLShaderMgr::BUMP_MAP, LLViewerFetchedTexture::sFlatNormalImagep);
|
||||
|
|
@ -485,8 +499,17 @@ void LLDrawPoolAlpha::renderSimples(U32 mask, std::vector<LLDrawInfo*>& simples)
|
|||
simple_shader->uniform1f(LLShaderMgr::ENVIRONMENT_INTENSITY, 0.0f);
|
||||
simple_shader->uniform1f(LLShaderMgr::EMISSIVE_BRIGHTNESS, 0.0f);
|
||||
bool use_shaders = gPipeline.canUseVertexShaders();
|
||||
std::unique_ptr<FSPerfStats::RecordAttachmentTime> ratPtr{};// <FS:Beq> Render time Stats collection
|
||||
for (LLDrawInfo* draw : simples)
|
||||
{
|
||||
// <FS:Beq> Capture render times
|
||||
LL_PROFILE_ZONE_NAMED("Simples");
|
||||
auto vobj = draw->mFace?draw->mFace->getViewerObject():nullptr;
|
||||
if(vobj && vobj->isAttachment())
|
||||
{
|
||||
trackAttachments( vobj, draw->mFace->isState(LLFace::RIGGED), &ratPtr );
|
||||
}
|
||||
// </FS:Beq>
|
||||
bool tex_setup = TexSetup(draw, use_shaders, false, simple_shader);
|
||||
LLGLEnableFunc stencil_test(GL_STENCIL_TEST, draw->mSelected, &LLGLCommonFunc::selected_stencil_test);
|
||||
gGL.blendFunc((LLRender::eBlendFactor) draw->mBlendFuncSrc, (LLRender::eBlendFactor) draw->mBlendFuncDst, mAlphaSFactor, mAlphaDFactor);
|
||||
|
|
@ -503,8 +526,17 @@ void LLDrawPoolAlpha::renderFullbrights(U32 mask, std::vector<LLDrawInfo*>& full
|
|||
fullbright_shader->bind();
|
||||
fullbright_shader->uniform1f(LLShaderMgr::EMISSIVE_BRIGHTNESS, 1.0f);
|
||||
bool use_shaders = gPipeline.canUseVertexShaders();
|
||||
std::unique_ptr<FSPerfStats::RecordAttachmentTime> ratPtr{}; // <FS:Beq> Render time Stats collection
|
||||
for (LLDrawInfo* draw : fullbrights)
|
||||
{
|
||||
// <FS:Beq> Capture render times
|
||||
LL_PROFILE_ZONE_NAMED("Fullbrights");
|
||||
auto vobj = draw->mFace?draw->mFace->getViewerObject():nullptr;
|
||||
if(vobj && vobj->isAttachment())
|
||||
{
|
||||
trackAttachments( vobj, draw->mFace->isState(LLFace::RIGGED), &ratPtr );
|
||||
}
|
||||
// </FS:Beq>
|
||||
bool tex_setup = TexSetup(draw, use_shaders, false, fullbright_shader);
|
||||
|
||||
LLGLEnableFunc stencil_test(GL_STENCIL_TEST, draw->mSelected, &LLGLCommonFunc::selected_stencil_test);
|
||||
|
|
@ -518,13 +550,24 @@ void LLDrawPoolAlpha::renderFullbrights(U32 mask, std::vector<LLDrawInfo*>& full
|
|||
|
||||
void LLDrawPoolAlpha::renderMaterials(U32 mask, std::vector<LLDrawInfo*>& materials)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED;// <FS:Beq> Tracy markup
|
||||
LLGLSLShader::bindNoShader();
|
||||
current_shader = NULL;
|
||||
|
||||
gPipeline.enableLightsDynamic();
|
||||
bool use_shaders = gPipeline.canUseVertexShaders();
|
||||
std::unique_ptr<FSPerfStats::RecordAttachmentTime> ratPtr{}; // <FS:Beq/> Render time Stats collection
|
||||
for (LLDrawInfo* draw : materials)
|
||||
{
|
||||
// <FS:Beq> Capture render times
|
||||
LL_PROFILE_ZONE_NAMED("Materials");
|
||||
auto vobj = draw->mFace?draw->mFace->getViewerObject():nullptr;
|
||||
if(vobj && vobj->isAttachment())
|
||||
{
|
||||
trackAttachments( vobj, draw->mFace->isState(LLFace::RIGGED), &ratPtr );
|
||||
}
|
||||
// </FS:Beq>
|
||||
|
||||
U32 mask = draw->mShaderMask;
|
||||
|
||||
llassert(mask < LLMaterial::SHADER_COUNT);
|
||||
|
|
@ -605,8 +648,18 @@ void LLDrawPoolAlpha::renderEmissives(U32 mask, std::vector<LLDrawInfo*>& emissi
|
|||
// don't touch color, add to alpha (glow)
|
||||
gGL.blendFunc(LLRender::BF_ZERO, LLRender::BF_ONE, LLRender::BF_ONE, LLRender::BF_ONE);
|
||||
bool use_shaders = gPipeline.canUseVertexShaders();
|
||||
std::unique_ptr<FSPerfStats::RecordAttachmentTime> ratPtr{}; // <FS:Beq/> Render time Stats collection
|
||||
for (LLDrawInfo* draw : emissives)
|
||||
{
|
||||
// <FS:Beq> Capture render times
|
||||
LL_PROFILE_ZONE_NAMED("Emissives");
|
||||
auto vobj = draw->mFace?draw->mFace->getViewerObject():nullptr;
|
||||
if(vobj && vobj->isAttachment())
|
||||
{
|
||||
trackAttachments( vobj, draw->mFace->isState(LLFace::RIGGED), &ratPtr );
|
||||
}
|
||||
// </FS:Beq>
|
||||
|
||||
bool tex_setup = TexSetup(draw, use_shaders, false, emissive_shader);
|
||||
drawEmissive(mask, draw);
|
||||
RestoreTexSetup(tex_setup);
|
||||
|
|
@ -664,6 +717,7 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, S32 pass)
|
|||
|
||||
LLSpatialGroup::drawmap_elem_t& draw_info = group->mDrawMap[LLRenderPass::PASS_ALPHA];
|
||||
|
||||
std::unique_ptr<FSPerfStats::RecordAttachmentTime> ratPtr{}; // <FS:Beq/> Render time Stats collection
|
||||
for (LLSpatialGroup::drawmap_elem_t::iterator k = draw_info.begin(); k != draw_info.end(); ++k)
|
||||
{
|
||||
LLDrawInfo& params = **k;
|
||||
|
|
@ -679,6 +733,18 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, S32 pass)
|
|||
continue;
|
||||
}
|
||||
|
||||
// <FS:Beq> Capture render times
|
||||
if(params.mFace)
|
||||
{
|
||||
LLViewerObject* vobj = (LLViewerObject *)params.mFace->getViewerObject();
|
||||
|
||||
if(vobj->isAttachment())
|
||||
{
|
||||
trackAttachments( vobj, params.mFace->isState(LLFace::RIGGED), &ratPtr );
|
||||
}
|
||||
}
|
||||
// </FS:Beq>
|
||||
|
||||
// Fix for bug - NORSPEC-271
|
||||
// If the face is more than 90% transparent, then don't update the Depth buffer for Dof
|
||||
// We don't want the nearly invisible objects to cause of DoF effects
|
||||
|
|
@ -858,7 +924,9 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, S32 pass)
|
|||
gGL.matrixMode(LLRender::MM_MODELVIEW);
|
||||
}
|
||||
}
|
||||
|
||||
// <FS:Beq> performance stats
|
||||
ratPtr.reset(); // force the final batch to terminate to avoid double counting on the subsidiary batches for FB and Emmissives
|
||||
// </FS:Beq>
|
||||
if (batch_fullbrights)
|
||||
{
|
||||
light_enabled = false;
|
||||
|
|
|
|||
|
|
@ -59,6 +59,8 @@
|
|||
// void drawBoxOutline(const LLVector3& pos,const LLVector3& size); // llspatialpartition.cpp
|
||||
// </FS:Zi>
|
||||
#include "llnetmap.h"
|
||||
#include "fsperfstats.h" // <FS:Beq> performance stats support
|
||||
|
||||
|
||||
static U32 sDataMask = LLDrawPoolAvatar::VERTEX_DATA_MASK;
|
||||
static U32 sBufferUsage = GL_STREAM_DRAW_ARB;
|
||||
|
|
@ -605,13 +607,16 @@ void LLDrawPoolAvatar::renderShadow(S32 pass)
|
|||
{
|
||||
return;
|
||||
}
|
||||
FSPerfStats::RecordAvatarTime T(avatarp->getID(), FSPerfStats::StatType_t::RENDER_SHADOWS);
|
||||
|
||||
LLVOAvatar::AvatarOverallAppearance oa = avatarp->getOverallAppearance();
|
||||
BOOL impostor = !LLPipeline::sImpostorRender && avatarp->isImpostor();
|
||||
// <FS:Beq> plain old impostors are passing through the shadow pipeline
|
||||
// if (oa == LLVOAvatar::AOA_INVISIBLE ||
|
||||
// (impostor && oa == LLVOAvatar::AOA_JELLYDOLL))
|
||||
// Note: Impostors should not cast shadows, also all JDs are impostor nowadays so we do not need the extra check at all.
|
||||
if (impostor || (oa == LLVOAvatar::AOA_INVISIBLE) )
|
||||
// also no shadows if the shadows are causing this avatar to breach the limit.
|
||||
if ( avatarp->isTooSlowWithShadows() || impostor || (oa == LLVOAvatar::AOA_INVISIBLE) )
|
||||
// </FS:Beq>
|
||||
{
|
||||
// No shadows for jellydolled or invisible avs.
|
||||
|
|
@ -1556,6 +1561,7 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass)
|
|||
|
||||
if (pass == -1)
|
||||
{
|
||||
LL_PROFILE_ZONE_NAMED("pass -1");
|
||||
for (S32 i = 1; i < getNumPasses(); i++)
|
||||
{ //skip foot shadows
|
||||
prerender();
|
||||
|
|
@ -1572,7 +1578,7 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass)
|
|||
return;
|
||||
}
|
||||
|
||||
LLVOAvatar *avatarp = NULL;
|
||||
LLVOAvatar *avatarp { nullptr };
|
||||
|
||||
if (single_avatar)
|
||||
{
|
||||
|
|
@ -1580,6 +1586,7 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass)
|
|||
}
|
||||
else
|
||||
{
|
||||
LL_PROFILE_ZONE_NAMED("Find avatarp"); // <FS:Beq/> Tracy markup
|
||||
const LLFace *facep = mDrawFace[0];
|
||||
if (!facep->getDrawable())
|
||||
{
|
||||
|
|
@ -1592,11 +1599,16 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass)
|
|||
{
|
||||
return;
|
||||
}
|
||||
FSPerfStats::RecordAvatarTime T(avatarp->getID(), FSPerfStats::StatType_t::RENDER_GEOMETRY);
|
||||
|
||||
// <FS:Zi> Add avatar hitbox debug
|
||||
{
|
||||
LL_PROFILE_ZONE_NAMED("cached control renderhitboxes");
|
||||
static LLCachedControl<bool> render_hitbox(gSavedSettings, "DebugRenderHitboxes", false);
|
||||
|
||||
if (render_hitbox && pass == 2)
|
||||
{
|
||||
LL_PROFILE_ZONE_NAMED("render_hitbox");
|
||||
LLGLSLShader* current_shader_program = NULL;
|
||||
|
||||
// load the debug output shader
|
||||
|
|
@ -1675,10 +1687,14 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass)
|
|||
}
|
||||
}
|
||||
}
|
||||
// </FS:Zi>
|
||||
|
||||
}// </FS:Zi>
|
||||
// <FS:Beq> rendertime Tracy annotations
|
||||
{
|
||||
LL_PROFILE_ZONE_NAMED("check fully_loaded");
|
||||
// </FS:Beq>
|
||||
if (!single_avatar && !avatarp->isFullyLoaded() )
|
||||
{
|
||||
LL_PROFILE_ZONE_NAMED("avatar not loaded");
|
||||
if (pass==0 && (!gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_PARTICLES) || LLViewerPartSim::getMaxPartCount() <= 0))
|
||||
{
|
||||
// debug code to draw a sphere in place of avatar
|
||||
|
|
@ -1701,9 +1717,14 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass)
|
|||
// don't render please
|
||||
return;
|
||||
}
|
||||
}// <FS:Beq/> rendertime Tracy annotations
|
||||
|
||||
BOOL impostor = !LLPipeline::sImpostorRender && avatarp->isImpostor() && !single_avatar;
|
||||
|
||||
// <FS:Beq> rendertime Tracy annotations
|
||||
{
|
||||
LL_PROFILE_ZONE_NAMED("check appearance");
|
||||
// </FS:Beq>
|
||||
if (( /*avatarp->isInMuteList() // <FS:Ansariel> Partially undo MAINT-5700: Draw imposter for muted avatars
|
||||
||*/ impostor
|
||||
|| (LLVOAvatar::AOA_NORMAL != avatarp->getOverallAppearance() && !avatarp->needsImpostorUpdate()) ) && pass != 0)
|
||||
|
|
@ -1711,6 +1732,7 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass)
|
|||
{ //don't draw anything but the impostor for impostored avatars
|
||||
return;
|
||||
}
|
||||
}// <FS:Beq/> rendertime Tracy annotations
|
||||
|
||||
if (pass == 0 && !impostor && LLPipeline::sUnderWaterRender)
|
||||
{ //don't draw foot shadows under water
|
||||
|
|
@ -1726,6 +1748,7 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass)
|
|||
|
||||
if (pass == 0)
|
||||
{
|
||||
LL_PROFILE_ZONE_NAMED("pass 0");
|
||||
if (!LLPipeline::sReflectionRender)
|
||||
{
|
||||
LLVOAvatar::sNumVisibleAvatars++;
|
||||
|
|
@ -1734,6 +1757,7 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass)
|
|||
// if (impostor || (LLVOAvatar::AV_DO_NOT_RENDER == avatarp->getVisualMuteSettings() && !avatarp->needsImpostorUpdate()))
|
||||
if (impostor || (LLVOAvatar::AOA_NORMAL != avatarp->getOverallAppearance() && !avatarp->needsImpostorUpdate()))
|
||||
{
|
||||
LL_PROFILE_ZONE_NAMED("render impostor");
|
||||
if (LLPipeline::sRenderDeferred && !LLPipeline::sReflectionRender && avatarp->mImpostor.isComplete())
|
||||
{
|
||||
// <FS:Ansariel> FIRE-9179: Crash fix
|
||||
|
|
@ -1759,6 +1783,7 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass)
|
|||
|
||||
if (pass == 1)
|
||||
{
|
||||
LL_PROFILE_ZONE_NAMED("render rigid meshes (eyeballs)");
|
||||
// render rigid meshes (eyeballs) first
|
||||
avatarp->renderRigid();
|
||||
return;
|
||||
|
|
@ -1766,12 +1791,15 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass)
|
|||
|
||||
if (pass == 3)
|
||||
{
|
||||
LL_PROFILE_ZONE_NAMED("pass 3");
|
||||
if (is_deferred_render)
|
||||
{
|
||||
LL_PROFILE_ZONE_NAMED("deferred rigged simple");
|
||||
renderDeferredRiggedSimple(avatarp);
|
||||
}
|
||||
else
|
||||
{
|
||||
LL_PROFILE_ZONE_NAMED("non-deferred rigged");
|
||||
renderRiggedSimple(avatarp);
|
||||
|
||||
if (LLPipeline::sRenderDeferred)
|
||||
|
|
@ -1795,12 +1823,15 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass)
|
|||
|
||||
if (pass == 4)
|
||||
{
|
||||
LL_PROFILE_ZONE_NAMED("pass 4");
|
||||
if (is_deferred_render)
|
||||
{
|
||||
LL_PROFILE_ZONE_NAMED("deferred rigged bump");
|
||||
renderDeferredRiggedBump(avatarp);
|
||||
}
|
||||
else
|
||||
{
|
||||
LL_PROFILE_ZONE_NAMED("non-deferred fullbright");
|
||||
renderRiggedFullbright(avatarp);
|
||||
}
|
||||
|
||||
|
|
@ -1809,6 +1840,7 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass)
|
|||
|
||||
if (is_deferred_render && pass >= 5 && pass <= 21)
|
||||
{
|
||||
LL_PROFILE_ZONE_NAMED("deferred passes 5-21");
|
||||
S32 p = pass-5;
|
||||
|
||||
if (p != 1 &&
|
||||
|
|
@ -1816,6 +1848,7 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass)
|
|||
p != 9 &&
|
||||
p != 13)
|
||||
{
|
||||
LL_PROFILE_ZONE_NAMED("deferred rigged material");
|
||||
renderDeferredRiggedMaterial(avatarp, p);
|
||||
}
|
||||
return;
|
||||
|
|
@ -1826,6 +1859,7 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass)
|
|||
|
||||
if (pass == 5)
|
||||
{
|
||||
LL_PROFILE_ZONE_NAMED("rigged shiny");
|
||||
renderRiggedShinySimple(avatarp);
|
||||
|
||||
return;
|
||||
|
|
@ -1833,6 +1867,7 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass)
|
|||
|
||||
if (pass == 6)
|
||||
{
|
||||
LL_PROFILE_ZONE_NAMED("rigged FB shiny");
|
||||
renderRiggedFullbrightShiny(avatarp);
|
||||
return;
|
||||
}
|
||||
|
|
@ -1841,10 +1876,12 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass)
|
|||
{
|
||||
if (pass == 7)
|
||||
{
|
||||
LL_PROFILE_ZONE_NAMED("pass 7 rigged Alpha");
|
||||
renderRiggedAlpha(avatarp);
|
||||
|
||||
if (LLPipeline::sRenderDeferred && !is_post_deferred_render)
|
||||
{ //render transparent materials under water
|
||||
LL_PROFILE_ZONE_NAMED("rigged Alpha Blend");
|
||||
LLGLEnable blend(GL_BLEND);
|
||||
|
||||
gGL.setColorMask(true, true);
|
||||
|
|
@ -1865,6 +1902,7 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass)
|
|||
|
||||
if (pass == 8)
|
||||
{
|
||||
LL_PROFILE_ZONE_NAMED("pass 8 rigged FB Alpha");
|
||||
renderRiggedFullbrightAlpha(avatarp);
|
||||
return;
|
||||
}
|
||||
|
|
@ -1881,6 +1919,7 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass)
|
|||
}
|
||||
|
||||
{
|
||||
LL_PROFILE_ZONE_NAMED("post deferred rigged Alpha");
|
||||
LLGLEnable blend(GL_BLEND);
|
||||
renderDeferredRiggedMaterial(avatarp, p);
|
||||
}
|
||||
|
|
@ -1888,6 +1927,7 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass)
|
|||
}
|
||||
else if (pass == 9)
|
||||
{
|
||||
LL_PROFILE_ZONE_NAMED("pass 9 - rigged glow");
|
||||
renderRiggedGlow(avatarp);
|
||||
return;
|
||||
}
|
||||
|
|
@ -1895,6 +1935,7 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass)
|
|||
|
||||
if (pass == 13)
|
||||
{
|
||||
LL_PROFILE_ZONE_NAMED("pass 13 - rigged glow");
|
||||
renderRiggedGlow(avatarp);
|
||||
|
||||
return;
|
||||
|
|
@ -1902,6 +1943,7 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass)
|
|||
|
||||
if ((sShaderLevel >= SHADER_LEVEL_CLOTH))
|
||||
{
|
||||
LL_PROFILE_ZONE_NAMED("shader level > CLOTH");
|
||||
LLMatrix4 rot_mat;
|
||||
LLViewerCamera::getInstance()->getMatrixToLocal(rot_mat);
|
||||
LLMatrix4 cfr(OGL_TO_CFR_ROTATION);
|
||||
|
|
@ -1927,6 +1969,7 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass)
|
|||
|
||||
if( !single_avatar || (avatarp == single_avatar) )
|
||||
{
|
||||
LL_PROFILE_ZONE_NAMED("renderSkinned");
|
||||
avatarp->renderSkinned();
|
||||
}
|
||||
}
|
||||
|
|
@ -2328,6 +2371,7 @@ void LLDrawPoolAvatar::renderRigged(LLVOAvatar* avatar, U32 type, bool glow)
|
|||
|
||||
stop_glerror();
|
||||
|
||||
std::unique_ptr<FSPerfStats::RecordAttachmentTime> ratPtr{};// <FS:Beq/> Perf stats capture
|
||||
for (U32 i = 0; i < mRiggedFace[type].size(); ++i)
|
||||
{
|
||||
LLFace* face = mRiggedFace[type][i];
|
||||
|
|
@ -2350,7 +2394,14 @@ void LLDrawPoolAvatar::renderRigged(LLVOAvatar* avatar, U32 type, bool glow)
|
|||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
// <FS:Beq> Capture render times
|
||||
if(vobj->isAttachment())
|
||||
{
|
||||
trackAttachments( vobj, true, &ratPtr);
|
||||
}
|
||||
// </FS:Beq>
|
||||
|
||||
LLVolume* volume = vobj->getVolume();
|
||||
S32 te = face->getTEOffset();
|
||||
|
||||
|
|
@ -2651,11 +2702,15 @@ static LLTrace::BlockTimerStatHandle FTM_RIGGED_VBO("Rigged VBO");
|
|||
void LLDrawPoolAvatar::updateRiggedVertexBuffers(LLVOAvatar* avatar)
|
||||
{
|
||||
LL_RECORD_BLOCK_TIME(FTM_RIGGED_VBO);
|
||||
|
||||
// <FS:Beq> render stats collection
|
||||
if(!avatar)return; // in theory this never happens...right
|
||||
FSPerfStats::RecordAvatarTime T( avatar->getID(), ( (LLPipeline::sShadowRender)?FSPerfStats::StatType_t::RENDER_SHADOWS : FSPerfStats::StatType_t::RENDER_GEOMETRY ) );
|
||||
// </FS:Beq>
|
||||
//update rigged vertex buffers
|
||||
for (U32 type = 0; type < NUM_RIGGED_PASSES; ++type)
|
||||
{
|
||||
LL_PROFILE_ZONE_NAMED("Pass");
|
||||
std::unique_ptr<FSPerfStats::RecordAttachmentTime> ratPtr{};
|
||||
for (U32 i = 0; i < mRiggedFace[type].size(); ++i)
|
||||
{
|
||||
LL_PROFILE_ZONE_NAMED("Face");
|
||||
|
|
@ -2672,7 +2727,12 @@ void LLDrawPoolAvatar::updateRiggedVertexBuffers(LLVOAvatar* avatar)
|
|||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// <FS:Beq> Capture render times
|
||||
if(vobj->isAttachment())
|
||||
{
|
||||
trackAttachments( vobj, true, &ratPtr );
|
||||
}
|
||||
// </FS:Beq>
|
||||
LLVolume* volume = vobj->getVolume();
|
||||
S32 te = face->getTEOffset();
|
||||
|
||||
|
|
|
|||
|
|
@ -47,6 +47,7 @@
|
|||
#include "pipeline.h"
|
||||
#include "llspatialpartition.h"
|
||||
#include "llviewershadermgr.h"
|
||||
#include "fsperfstats.h" // <FS:Beq> performance stats support
|
||||
|
||||
//#include "llimagebmp.h"
|
||||
//#include "../tools/imdebug/imdebug.h"
|
||||
|
|
@ -640,13 +641,22 @@ void LLDrawPoolBump::endFullbrightShiny()
|
|||
}
|
||||
|
||||
void LLDrawPoolBump::renderGroup(LLSpatialGroup* group, U32 type, U32 mask, BOOL texture = TRUE)
|
||||
{
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED;
|
||||
LLSpatialGroup::drawmap_elem_t& draw_info = group->mDrawMap[type];
|
||||
|
||||
std::unique_ptr<FSPerfStats::RecordAttachmentTime> ratPtr{}; // <FS:Beq/> render time capture
|
||||
for (LLSpatialGroup::drawmap_elem_t::iterator k = draw_info.begin(); k != draw_info.end(); ++k)
|
||||
{
|
||||
LLDrawInfo& params = **k;
|
||||
// <FS:Beq> Capture render times
|
||||
LLViewerObject* vobj = (LLViewerObject *)params.mFace->getViewerObject();
|
||||
|
||||
if( vobj && vobj->isAttachment() )
|
||||
{
|
||||
trackAttachments( vobj, params.mFace->isState(LLFace::RIGGED), &ratPtr );
|
||||
}
|
||||
// </FS:Beq>
|
||||
applyModelMatrix(params);
|
||||
|
||||
if (params.mGroup)
|
||||
|
|
@ -888,10 +898,21 @@ void LLDrawPoolBump::renderDeferred(S32 pass)
|
|||
|
||||
U32 mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_TANGENT | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_COLOR;
|
||||
|
||||
std::unique_ptr<FSPerfStats::RecordAttachmentTime> ratPtr{}; // <FS:Beq/> render time capture
|
||||
for (LLCullResult::drawinfo_iterator i = begin; i != end; ++i)
|
||||
{
|
||||
LLDrawInfo& params = **i;
|
||||
|
||||
// <FS:Beq> Capture render times
|
||||
if(params.mFace)
|
||||
{
|
||||
LLViewerObject* vobj = (LLViewerObject *)params.mFace->getViewerObject();
|
||||
|
||||
if(vobj && vobj->isAttachment())
|
||||
{
|
||||
trackAttachments( vobj, params.mFace->isState(LLFace::RIGGED), &ratPtr );
|
||||
}
|
||||
}
|
||||
// </FS:Beq>
|
||||
gDeferredBumpProgram.setMinimumAlpha(params.mAlphaMaskCutoff);
|
||||
LLDrawPoolBump::bindBumpMap(params, bump_channel);
|
||||
pushBatch(params, mask, TRUE);
|
||||
|
|
@ -1499,9 +1520,21 @@ void LLDrawPoolBump::renderBump(U32 type, U32 mask)
|
|||
LLCullResult::drawinfo_iterator begin = gPipeline.beginRenderMap(type);
|
||||
LLCullResult::drawinfo_iterator end = gPipeline.endRenderMap(type);
|
||||
|
||||
std::unique_ptr<FSPerfStats::RecordAttachmentTime> ratPtr{}; // <FS:Beq/> render time capture
|
||||
for (LLCullResult::drawinfo_iterator i = begin; i != end; ++i)
|
||||
{
|
||||
LLDrawInfo& params = **i;
|
||||
// <FS:Beq> Capture render times
|
||||
if(params.mFace)
|
||||
{
|
||||
LLViewerObject* vobj = (LLViewerObject *)params.mFace->getViewerObject();
|
||||
|
||||
if( vobj && vobj->isAttachment() )
|
||||
{
|
||||
trackAttachments( vobj, params.mFace->isState(LLFace::RIGGED), &ratPtr );
|
||||
}
|
||||
}
|
||||
// </FS:Beq>
|
||||
|
||||
if (LLDrawPoolBump::bindBumpMap(params))
|
||||
{
|
||||
|
|
@ -1512,6 +1545,7 @@ void LLDrawPoolBump::renderBump(U32 type, U32 mask)
|
|||
|
||||
void LLDrawPoolBump::pushBatch(LLDrawInfo& params, U32 mask, BOOL texture, BOOL batch_textures)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED;
|
||||
applyModelMatrix(params);
|
||||
|
||||
bool tex_setup = false;
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@
|
|||
#include "llviewershadermgr.h"
|
||||
#include "pipeline.h"
|
||||
#include "llglcommonfunc.h"
|
||||
#include "fsperfstats.h" // <FS:Beq> performance stats support
|
||||
|
||||
S32 diffuse_channel = -1;
|
||||
|
||||
|
|
@ -135,10 +136,23 @@ void LLDrawPoolMaterials::renderDeferred(S32 pass)
|
|||
LLCullResult::drawinfo_iterator begin = gPipeline.beginRenderMap(type);
|
||||
LLCullResult::drawinfo_iterator end = gPipeline.endRenderMap(type);
|
||||
|
||||
std::unique_ptr<FSPerfStats::RecordAttachmentTime> ratPtr{}; // <FS:Beq/> render time capture
|
||||
for (LLCullResult::drawinfo_iterator i = begin; i != end; ++i)
|
||||
{
|
||||
LLDrawInfo& params = **i;
|
||||
|
||||
|
||||
// <FS:Beq> Capture render times
|
||||
if(params.mFace)
|
||||
{
|
||||
LLViewerObject* vobj = (LLViewerObject *)params.mFace->getViewerObject();
|
||||
|
||||
if( vobj && vobj->isAttachment() )
|
||||
{
|
||||
trackAttachments( vobj, params.mFace->isState(LLFace::RIGGED), &ratPtr );
|
||||
}
|
||||
}
|
||||
// </FS:Beq>
|
||||
|
||||
mShader->uniform4f(LLShaderMgr::SPECULAR_COLOR, params.mSpecColor.mV[0], params.mSpecColor.mV[1], params.mSpecColor.mV[2], params.mSpecColor.mV[3]);
|
||||
mShader->uniform1f(LLShaderMgr::ENVIRONMENT_INTENSITY, params.mEnvIntensity);
|
||||
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@
|
|||
#include "llspatialpartition.h"
|
||||
#include "llviewershadermgr.h"
|
||||
#include "llrender.h"
|
||||
#include "fsperfstats.h"
|
||||
|
||||
static LLGLSLShader* simple_shader = NULL;
|
||||
static LLGLSLShader* fullbright_shader = NULL;
|
||||
|
|
@ -224,7 +225,7 @@ void LLDrawPoolSimple::render(S32 pass)
|
|||
LLGLDisable blend(GL_BLEND);
|
||||
|
||||
{ //render simple
|
||||
LL_RECORD_BLOCK_TIME(FTM_RENDER_SIMPLE);
|
||||
LL_RECORD_BLOCK_TIME(FTM_RENDER_SIMPLE);
|
||||
gPipeline.enableLightsDynamic();
|
||||
|
||||
if (mShaderLevel > 0)
|
||||
|
|
|
|||
|
|
@ -228,12 +228,15 @@ BOOL LLViewerDynamicTexture::updateAllInstances()
|
|||
BOOL ret = FALSE ;
|
||||
for( S32 order = 0; order < ORDER_COUNT; order++ )
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED;
|
||||
for (instance_list_t::iterator iter = LLViewerDynamicTexture::sInstances[order].begin();
|
||||
iter != LLViewerDynamicTexture::sInstances[order].end(); ++iter)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED;
|
||||
LLViewerDynamicTexture *dynamicTexture = *iter;
|
||||
if (dynamicTexture->needsRender())
|
||||
{
|
||||
{
|
||||
LL_PROFILE_ZONE_NAMED("needsRender");
|
||||
glClear(GL_DEPTH_BUFFER_BIT);
|
||||
gDepthDirty = TRUE;
|
||||
|
||||
|
|
@ -241,13 +244,19 @@ BOOL LLViewerDynamicTexture::updateAllInstances()
|
|||
dynamicTexture->setBoundTarget(use_fbo ? &gPipeline.mBake : nullptr);
|
||||
dynamicTexture->preRender(); // Must be called outside of startRender()
|
||||
result = FALSE;
|
||||
{
|
||||
LL_PROFILE_ZONE_NAMED("DynTexture->render");
|
||||
if (dynamicTexture->render())
|
||||
{
|
||||
ret = TRUE ;
|
||||
result = TRUE;
|
||||
sNumRenders++;
|
||||
}
|
||||
}
|
||||
{
|
||||
LL_PROFILE_ZONE_NAMED("flush");
|
||||
gGL.flush();
|
||||
}
|
||||
LLVertexBuffer::unbind();
|
||||
dynamicTexture->setBoundTarget(nullptr);
|
||||
dynamicTexture->postRender(result);
|
||||
|
|
|
|||
|
|
@ -59,6 +59,7 @@
|
|||
// [RLVa:KB] - Checked: RLVa-2.0.0
|
||||
#include "rlvhandler.h"
|
||||
// [/RLVa:KB]
|
||||
#include "fsperfstats.h" // <FS:Beq> performance stats support
|
||||
|
||||
#if LL_LINUX
|
||||
// Work-around spurious used before init warning on Vector4a
|
||||
|
|
@ -651,6 +652,13 @@ void renderFace(LLDrawable* drawable, LLFace *face)
|
|||
LLVOVolume* vobj = drawable->getVOVolume();
|
||||
if (vobj)
|
||||
{
|
||||
// <FS:Beq> Placeholder - This function emits drawcalls but is only used in one place and not useful for stats.
|
||||
// TODO(Beq) if we need this consider moving it to llSelectMgr loop instead to reduce overhead.
|
||||
// std::unique_ptr<FSPerfStats::RecordAttachmentTime> ratPtr{};
|
||||
// if(vobj->isAttachment())
|
||||
// {
|
||||
// trackAttachments(vobj, LLPipeline::sShadowRender, &ratPtr);
|
||||
// }
|
||||
LLVolume* volume = NULL;
|
||||
|
||||
if (drawable->isState(LLDrawable::RIGGED))
|
||||
|
|
@ -1251,6 +1259,11 @@ bool LLFace::canRenderAsMask()
|
|||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// <FS:Beq> shortcircuit fully alpha faces
|
||||
if (getViewerObject()->isHUDAttachment()) { return false; }
|
||||
if (te->getAlpha() == 0.0f && (te->getGlow() == 0.f)) { LL_PROFILE_ZONE_NAMED("beqshortcircuit invisible"); return true; }
|
||||
// </FS:Beq>
|
||||
|
||||
LLMaterial* mat = te->getMaterialParams();
|
||||
if (mat && mat->getDiffuseAlphaMode() == LLMaterial::DIFFUSE_ALPHA_MODE_BLEND)
|
||||
|
|
|
|||
|
|
@ -64,6 +64,7 @@
|
|||
#include "llnotificationhandler.h"
|
||||
#include "llnotificationmanager.h"
|
||||
#include "llnotificationsutil.h"
|
||||
#include "llviewercontrol.h"
|
||||
|
||||
|
||||
LLFloaterAutoReplaceSettings::LLFloaterAutoReplaceSettings(const LLSD& key)
|
||||
|
|
|
|||
|
|
@ -91,7 +91,6 @@ BOOL LLFloaterAvatarRenderSettings::postBuild()
|
|||
LLFloater::postBuild();
|
||||
mAvatarSettingsList = getChild<LLNameListCtrl>("render_settings_list");
|
||||
mAvatarSettingsList->setRightMouseDownCallback(boost::bind(&LLFloaterAvatarRenderSettings::onAvatarListRightClick, this, _1, _2, _3));
|
||||
getChild<LLFilterEditor>("people_filter_input")->setCommitCallback(boost::bind(&LLFloaterAvatarRenderSettings::onFilterEdit, this, _2));
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
|
@ -135,37 +134,13 @@ void LLFloaterAvatarRenderSettings::updateList()
|
|||
{
|
||||
item_params.value = iter->first;
|
||||
LLAvatarNameCache::get(iter->first, &av_name);
|
||||
if(!isHiddenRow(av_name.getCompleteName()))
|
||||
{
|
||||
item_params.columns.add().value(av_name.getCompleteName()).column("name");
|
||||
std::string setting = getString(iter->second == 1 ? "av_never_render" : "av_always_render");
|
||||
item_params.columns.add().value(setting).column("setting");
|
||||
std::string timestamp = createTimestamp(LLRenderMuteList::getInstance()->getVisualMuteDate(iter->first));
|
||||
item_params.columns.add().value(timestamp).column("timestamp");
|
||||
mAvatarSettingsList->addNameItemRow(item_params);
|
||||
}
|
||||
item_params.columns.add().value(av_name.getCompleteName()).column("name");
|
||||
std::string setting = getString(iter->second == 1 ? "av_never_render" : "av_always_render");
|
||||
item_params.columns.add().value(setting).column("setting");
|
||||
mAvatarSettingsList->addNameItemRow(item_params);
|
||||
}
|
||||
}
|
||||
|
||||
void LLFloaterAvatarRenderSettings::onFilterEdit(const std::string& search_string)
|
||||
{
|
||||
std::string filter_upper = search_string;
|
||||
LLStringUtil::toUpper(filter_upper);
|
||||
if (mNameFilter != filter_upper)
|
||||
{
|
||||
mNameFilter = filter_upper;
|
||||
mNeedsUpdate = true;
|
||||
}
|
||||
}
|
||||
|
||||
bool LLFloaterAvatarRenderSettings::isHiddenRow(const std::string& av_name)
|
||||
{
|
||||
if (mNameFilter.empty()) return false;
|
||||
std::string upper_name = av_name;
|
||||
LLStringUtil::toUpper(upper_name);
|
||||
return std::string::npos == upper_name.find(mNameFilter);
|
||||
}
|
||||
|
||||
static LLVOAvatar* find_avatar(const LLUUID& id)
|
||||
{
|
||||
LLViewerObject *obj = gObjectList.findObject(id);
|
||||
|
|
@ -216,6 +191,10 @@ bool LLFloaterAvatarRenderSettings::isActionChecked(const LLSD& userdata, const
|
|||
{
|
||||
return (visual_setting == S32(LLVOAvatar::AV_RENDER_NORMALLY));
|
||||
}
|
||||
else if ("non_default" == command_name)
|
||||
{
|
||||
return (visual_setting != S32(LLVOAvatar::AV_RENDER_NORMALLY));
|
||||
}
|
||||
else if ("never" == command_name)
|
||||
{
|
||||
return (visual_setting == S32(LLVOAvatar::AV_DO_NOT_RENDER));
|
||||
|
|
|
|||
|
|
@ -50,7 +50,6 @@ public:
|
|||
void onAvatarListRightClick(LLUICtrl* ctrl, S32 x, S32 y);
|
||||
|
||||
void updateList();
|
||||
void onFilterEdit(const std::string& search_string);
|
||||
void onCustomAction (const LLSD& userdata, const LLUUID& av_id);
|
||||
bool isActionChecked(const LLSD& userdata, const LLUUID& av_id);
|
||||
void onClickAdd(const LLSD& userdata);
|
||||
|
|
@ -61,15 +60,12 @@ public:
|
|||
static void setNeedsUpdate();
|
||||
|
||||
private:
|
||||
bool isHiddenRow(const std::string& av_name);
|
||||
void callbackAvatarPicked(const uuid_vec_t& ids, S32 visual_setting);
|
||||
void removePicker();
|
||||
|
||||
bool mNeedsUpdate;
|
||||
LLListContextMenu* mContextMenu;
|
||||
LLNameListCtrl* mAvatarSettingsList;
|
||||
|
||||
std::string mNameFilter;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -53,6 +53,7 @@
|
|||
#include "llfloaterreg.h"
|
||||
#include "llfloaterabout.h"
|
||||
#include "llfavoritesbar.h"
|
||||
#include "llfloaterpreferencesgraphicsadvanced.h"
|
||||
#include "llfloatersidepanelcontainer.h"
|
||||
// <FS:Ansariel> [FS communication UI]
|
||||
//#include "llfloaterimsession.h"
|
||||
|
|
@ -84,7 +85,6 @@
|
|||
#include "llviewereventrecorder.h"
|
||||
#include "llviewermessage.h"
|
||||
#include "llviewerwindow.h"
|
||||
#include "llviewershadermgr.h"
|
||||
#include "llviewerthrottle.h"
|
||||
#include "llvoavatarself.h"
|
||||
#include "llvotree.h"
|
||||
|
|
@ -108,11 +108,9 @@
|
|||
#include "lltextbox.h"
|
||||
#include "llui.h"
|
||||
#include "llviewerobjectlist.h"
|
||||
#include "llvoavatar.h"
|
||||
#include "llvovolume.h"
|
||||
#include "llwindow.h"
|
||||
#include "llworld.h"
|
||||
#include "pipeline.h"
|
||||
#include "lluictrlfactory.h"
|
||||
#include "llviewermedia.h"
|
||||
#include "llpluginclassmedia.h"
|
||||
|
|
@ -128,8 +126,6 @@
|
|||
#include "llpresetsmanager.h"
|
||||
#include "llviewercontrol.h"
|
||||
#include "llpresetsmanager.h"
|
||||
#include "llfeaturemanager.h"
|
||||
#include "llviewertexturelist.h"
|
||||
|
||||
#include "llsearchableui.h"
|
||||
|
||||
|
|
@ -143,18 +139,19 @@
|
|||
#include "llaudioengine.h" // <FS:Ansariel> Output device selection
|
||||
#include "llavatarname.h" // <FS:CR> Deeper name cache stuffs
|
||||
#include "llclipboard.h" // <FS:Zi> Support preferences search SLURLs
|
||||
#include "lleventtimer.h"
|
||||
#include "llviewermenufile.h" // <FS:LO> FIRE-23606 Reveal path to external script editor in prefernces
|
||||
#include "lldiriterator.h" // <Kadah> for populating the fonts combo
|
||||
#include "lleventtimer.h"
|
||||
#include "llline.h"
|
||||
#include "lllocationhistory.h"
|
||||
#include "llpanelblockedlist.h"
|
||||
#include "llpanelmaininventory.h"
|
||||
#include "llscrolllistctrl.h"
|
||||
#include "llspellcheck.h"
|
||||
#include "llsdserialize.h" // KB: SkinsSelector
|
||||
#include "llspellcheck.h"
|
||||
#include "lltoolbarview.h"
|
||||
#include "llviewermenufile.h" // <FS:LO> FIRE-23606 Reveal path to external script editor in prefernces
|
||||
#include "llviewernetwork.h" // <FS:AW opensim search support>
|
||||
#include "llviewershadermgr.h"
|
||||
#include "NACLantispam.h"
|
||||
#include "../llcrashlogger/llcrashlogger.h"
|
||||
#if LL_WINDOWS
|
||||
|
|
@ -168,9 +165,11 @@
|
|||
#endif
|
||||
// </FS:LO>
|
||||
|
||||
#include "fsperfstats.h"// <FS:Beq/> perfstats
|
||||
|
||||
// <FS:Zi> FIRE-19539 - Include the alert messages in Prefs>Notifications>Alerts in preference Search.
|
||||
#include "llfiltereditor.h"
|
||||
|
||||
#include "llviewershadermgr.h"
|
||||
//<FS:HG> FIRE-6340, FIRE-6567 - Setting Bandwidth issues
|
||||
//const F32 BANDWIDTH_UPDATER_TIMEOUT = 0.5f;
|
||||
char const* const VISIBILITY_DEFAULT = "default";
|
||||
|
|
@ -507,6 +506,8 @@ LLFloaterPreference::LLFloaterPreference(const LLSD& key)
|
|||
|
||||
LLAvatarPropertiesProcessor::getInstance()->addObserver( gAgent.getID(), this );
|
||||
|
||||
mComplexityChangedSignal = gSavedSettings.getControl("RenderAvatarMaxComplexity")->getCommitSignal()->connect(boost::bind(&LLFloaterPreference::updateComplexityText, this));
|
||||
|
||||
mCommitCallbackRegistrar.add("Pref.ClearLog", boost::bind(&LLConversationLog::onClearLog, &LLConversationLog::instance()));
|
||||
mCommitCallbackRegistrar.add("Pref.DeleteTranscripts", boost::bind(&LLFloaterPreference::onDeleteTranscripts, this));
|
||||
mCommitCallbackRegistrar.add("UpdateFilter", boost::bind(&LLFloaterPreference::onUpdateFilterTerm, this, false)); // <FS:ND/> Hook up for filtering
|
||||
|
|
@ -892,6 +893,7 @@ void LLFloaterPreference::onDoNotDisturbResponseChanged()
|
|||
LLFloaterPreference::~LLFloaterPreference()
|
||||
{
|
||||
LLConversationLog::instance().removeObserver(this);
|
||||
mComplexityChangedSignal.disconnect();
|
||||
}
|
||||
|
||||
// <FS:Zi> FIRE-19539 - Include the alert messages in Prefs>Notifications>Alerts in preference Search.
|
||||
|
|
@ -1276,33 +1278,6 @@ void LLFloaterPreference::onRenderOptionEnable()
|
|||
refreshEnabledGraphics();
|
||||
}
|
||||
|
||||
void LLFloaterPreferenceGraphicsAdvanced::onRenderOptionEnable()
|
||||
{
|
||||
LLFloaterPreference* instance = LLFloaterReg::findTypedInstance<LLFloaterPreference>("preferences");
|
||||
if (instance)
|
||||
{
|
||||
instance->refresh();
|
||||
}
|
||||
|
||||
refreshEnabledGraphics();
|
||||
}
|
||||
|
||||
void LLFloaterPreferenceGraphicsAdvanced::onAdvancedAtmosphericsEnable()
|
||||
{
|
||||
LLFloaterPreference* instance = LLFloaterReg::findTypedInstance<LLFloaterPreference>("preferences");
|
||||
if (instance)
|
||||
{
|
||||
instance->refresh();
|
||||
}
|
||||
|
||||
refreshEnabledGraphics();
|
||||
}
|
||||
|
||||
void LLFloaterPreferenceGraphicsAdvanced::refreshEnabledGraphics()
|
||||
{
|
||||
refreshEnabledState();
|
||||
}
|
||||
|
||||
void LLFloaterPreference::onAvatarImpostorsEnable()
|
||||
{
|
||||
refreshEnabledGraphics();
|
||||
|
|
@ -2325,129 +2300,6 @@ void LLFloaterPreference::onCopySearch()
|
|||
}
|
||||
// </FS:Zi>
|
||||
|
||||
void LLFloaterPreferenceGraphicsAdvanced::refreshEnabledState()
|
||||
{
|
||||
LLComboBox* ctrl_reflections = getChild<LLComboBox>("Reflections");
|
||||
LLTextBox* reflections_text = getChild<LLTextBox>("ReflectionsText");
|
||||
|
||||
// Reflections
|
||||
BOOL reflections = gGLManager.mHasCubeMap && LLCubeMap::sUseCubeMaps;
|
||||
ctrl_reflections->setEnabled(reflections);
|
||||
reflections_text->setEnabled(reflections);
|
||||
|
||||
// Transparent Water
|
||||
LLCheckBoxCtrl* transparent_water_ctrl = getChild<LLCheckBoxCtrl>("TransparentWater");
|
||||
|
||||
// Bump & Shiny
|
||||
LLCheckBoxCtrl* bumpshiny_ctrl = getChild<LLCheckBoxCtrl>("BumpShiny");
|
||||
bool bumpshiny = gGLManager.mHasCubeMap && LLCubeMap::sUseCubeMaps && LLFeatureManager::getInstance()->isFeatureAvailable("RenderObjectBump");
|
||||
bumpshiny_ctrl->setEnabled(bumpshiny ? TRUE : FALSE);
|
||||
|
||||
// Avatar Mode
|
||||
// Enable Avatar Shaders
|
||||
LLCheckBoxCtrl* ctrl_avatar_vp = getChild<LLCheckBoxCtrl>("AvatarVertexProgram");
|
||||
// Avatar Render Mode
|
||||
LLCheckBoxCtrl* ctrl_avatar_cloth = getChild<LLCheckBoxCtrl>("AvatarCloth");
|
||||
|
||||
bool avatar_vp_enabled = LLFeatureManager::getInstance()->isFeatureAvailable("RenderAvatarVP");
|
||||
if (LLViewerShaderMgr::sInitialized)
|
||||
{
|
||||
S32 max_avatar_shader = LLViewerShaderMgr::instance()->mMaxAvatarShaderLevel;
|
||||
avatar_vp_enabled = (max_avatar_shader > 0) ? TRUE : FALSE;
|
||||
}
|
||||
|
||||
ctrl_avatar_vp->setEnabled(avatar_vp_enabled);
|
||||
|
||||
if (gSavedSettings.getBOOL("RenderAvatarVP") == FALSE)
|
||||
{
|
||||
ctrl_avatar_cloth->setEnabled(FALSE);
|
||||
}
|
||||
else
|
||||
{
|
||||
ctrl_avatar_cloth->setEnabled(TRUE);
|
||||
}
|
||||
|
||||
/* <FS:LO> remove orphaned code left over from EEP
|
||||
// Vertex Shaders, Global Shader Enable
|
||||
// SL-12594 Basic shaders are always enabled. DJH TODO clean up now-orphaned state handling code
|
||||
LLSliderCtrl* terrain_detail = getChild<LLSliderCtrl>("TerrainDetail"); // can be linked with control var
|
||||
LLTextBox* terrain_text = getChild<LLTextBox>("TerrainDetailText");
|
||||
terrain_detail->setEnabled(FALSE);
|
||||
terrain_text->setEnabled(FALSE);
|
||||
*/
|
||||
|
||||
// WindLight
|
||||
LLCheckBoxCtrl* ctrl_wind_light = getChild<LLCheckBoxCtrl>("WindLightUseAtmosShaders");
|
||||
LLSliderCtrl* sky = getChild<LLSliderCtrl>("SkyMeshDetail");
|
||||
LLTextBox* sky_text = getChild<LLTextBox>("SkyMeshDetailText");
|
||||
// [RLVa:KB] - Checked: 2010-03-18 (RLVa-1.2.0a) | Modified: RLVa-0.2.0a
|
||||
// "Atmospheric Shaders" can't be disabled - but can be enabled - under @setenv=n
|
||||
ctrl_wind_light->setEnabled( (RlvActions::canChangeEnvironment()) || (!gSavedSettings.getBOOL("WindLightUseAtmosShaders")));
|
||||
// [/RLVa:KB]
|
||||
// ctrl_wind_light->setEnabled(TRUE);
|
||||
sky->setEnabled(TRUE);
|
||||
sky_text->setEnabled(TRUE);
|
||||
|
||||
//Deferred/SSAO/Shadows
|
||||
LLCheckBoxCtrl* ctrl_deferred = getChild<LLCheckBoxCtrl>("UseLightShaders");
|
||||
|
||||
BOOL enabled = LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferred") &&
|
||||
((bumpshiny_ctrl && bumpshiny_ctrl->get()) ? TRUE : FALSE) &&
|
||||
((transparent_water_ctrl && transparent_water_ctrl->get()) ? TRUE : FALSE) &&
|
||||
gGLManager.mHasFramebufferObject &&
|
||||
gSavedSettings.getBOOL("RenderAvatarVP") &&
|
||||
(ctrl_wind_light->get()) ? TRUE : FALSE;
|
||||
|
||||
ctrl_deferred->setEnabled(enabled);
|
||||
|
||||
LLCheckBoxCtrl* ctrl_ssao = getChild<LLCheckBoxCtrl>("UseSSAO");
|
||||
LLCheckBoxCtrl* ctrl_dof = getChild<LLCheckBoxCtrl>("UseDoF");
|
||||
LLComboBox* ctrl_shadow = getChild<LLComboBox>("ShadowDetail");
|
||||
LLTextBox* shadow_text = getChild<LLTextBox>("RenderShadowDetailText");
|
||||
|
||||
// note, okay here to get from ctrl_deferred as it's twin, ctrl_deferred2 will alway match it
|
||||
enabled = enabled && LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferredSSAO") && (ctrl_deferred->get() ? TRUE : FALSE);
|
||||
|
||||
ctrl_deferred->set(gSavedSettings.getBOOL("RenderDeferred"));
|
||||
|
||||
ctrl_ssao->setEnabled(enabled);
|
||||
ctrl_dof->setEnabled(enabled);
|
||||
|
||||
enabled = enabled && LLFeatureManager::getInstance()->isFeatureAvailable("RenderShadowDetail");
|
||||
|
||||
ctrl_shadow->setEnabled(enabled);
|
||||
shadow_text->setEnabled(enabled);
|
||||
|
||||
// Hardware settings
|
||||
F32 mem_multiplier = gSavedSettings.getF32("RenderTextureMemoryMultiple");
|
||||
S32Megabytes min_tex_mem = LLViewerTextureList::getMinVideoRamSetting();
|
||||
S32Megabytes max_tex_mem = LLViewerTextureList::getMaxVideoRamSetting(false, mem_multiplier);
|
||||
getChild<LLSliderCtrl>("GraphicsCardTextureMemory")->setMinValue(min_tex_mem.value());
|
||||
getChild<LLSliderCtrl>("GraphicsCardTextureMemory")->setMaxValue(max_tex_mem.value());
|
||||
|
||||
if (!LLFeatureManager::getInstance()->isFeatureAvailable("RenderVBOEnable") ||
|
||||
!gGLManager.mHasVertexBufferObject)
|
||||
{
|
||||
getChildView("vbo")->setEnabled(FALSE);
|
||||
}
|
||||
|
||||
if (!LLFeatureManager::getInstance()->isFeatureAvailable("RenderCompressTextures") ||
|
||||
!gGLManager.mHasVertexBufferObject)
|
||||
{
|
||||
getChildView("texture compression")->setEnabled(FALSE);
|
||||
}
|
||||
|
||||
// if no windlight shaders, turn off nighttime brightness, gamma, and fog distance
|
||||
LLUICtrl* gamma_ctrl = getChild<LLUICtrl>("gamma");
|
||||
gamma_ctrl->setEnabled(!gPipeline.canUseWindLightShaders());
|
||||
getChildView("(brightness, lower is brighter)")->setEnabled(!gPipeline.canUseWindLightShaders());
|
||||
getChildView("fog")->setEnabled(!gPipeline.canUseWindLightShaders());
|
||||
getChildView("antialiasing restart")->setVisible(!LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferred"));
|
||||
|
||||
// now turn off any features that are unavailable
|
||||
disableUnavailableSettings();
|
||||
}
|
||||
|
||||
|
||||
// static
|
||||
void LLAvatarComplexityControls::setIndirectControls()
|
||||
|
|
@ -2594,118 +2446,6 @@ void LLFloaterPreference::disableUnavailableSettings()
|
|||
}
|
||||
}
|
||||
|
||||
void LLFloaterPreferenceGraphicsAdvanced::disableUnavailableSettings()
|
||||
{
|
||||
LLComboBox* ctrl_reflections = getChild<LLComboBox>("Reflections");
|
||||
LLTextBox* reflections_text = getChild<LLTextBox>("ReflectionsText");
|
||||
LLCheckBoxCtrl* ctrl_avatar_vp = getChild<LLCheckBoxCtrl>("AvatarVertexProgram");
|
||||
LLCheckBoxCtrl* ctrl_avatar_cloth = getChild<LLCheckBoxCtrl>("AvatarCloth");
|
||||
LLCheckBoxCtrl* ctrl_wind_light = getChild<LLCheckBoxCtrl>("WindLightUseAtmosShaders");
|
||||
LLCheckBoxCtrl* ctrl_deferred = getChild<LLCheckBoxCtrl>("UseLightShaders");
|
||||
LLComboBox* ctrl_shadows = getChild<LLComboBox>("ShadowDetail");
|
||||
LLTextBox* shadows_text = getChild<LLTextBox>("RenderShadowDetailText");
|
||||
LLCheckBoxCtrl* ctrl_ssao = getChild<LLCheckBoxCtrl>("UseSSAO");
|
||||
LLCheckBoxCtrl* ctrl_dof = getChild<LLCheckBoxCtrl>("UseDoF");
|
||||
LLSliderCtrl* sky = getChild<LLSliderCtrl>("SkyMeshDetail");
|
||||
LLTextBox* sky_text = getChild<LLTextBox>("SkyMeshDetailText");
|
||||
|
||||
// disabled windlight
|
||||
if (!LLFeatureManager::getInstance()->isFeatureAvailable("WindLightUseAtmosShaders"))
|
||||
{
|
||||
ctrl_wind_light->setEnabled(FALSE);
|
||||
ctrl_wind_light->setValue(FALSE);
|
||||
|
||||
sky->setEnabled(FALSE);
|
||||
sky_text->setEnabled(FALSE);
|
||||
|
||||
//deferred needs windlight, disable deferred
|
||||
ctrl_shadows->setEnabled(FALSE);
|
||||
ctrl_shadows->setValue(0);
|
||||
shadows_text->setEnabled(FALSE);
|
||||
|
||||
ctrl_ssao->setEnabled(FALSE);
|
||||
ctrl_ssao->setValue(FALSE);
|
||||
|
||||
ctrl_dof->setEnabled(FALSE);
|
||||
ctrl_dof->setValue(FALSE);
|
||||
|
||||
ctrl_deferred->setEnabled(FALSE);
|
||||
ctrl_deferred->setValue(FALSE);
|
||||
}
|
||||
|
||||
// disabled deferred
|
||||
if (!LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferred") ||
|
||||
!gGLManager.mHasFramebufferObject)
|
||||
{
|
||||
ctrl_shadows->setEnabled(FALSE);
|
||||
ctrl_shadows->setValue(0);
|
||||
shadows_text->setEnabled(FALSE);
|
||||
|
||||
ctrl_ssao->setEnabled(FALSE);
|
||||
ctrl_ssao->setValue(FALSE);
|
||||
|
||||
ctrl_dof->setEnabled(FALSE);
|
||||
ctrl_dof->setValue(FALSE);
|
||||
|
||||
ctrl_deferred->setEnabled(FALSE);
|
||||
ctrl_deferred->setValue(FALSE);
|
||||
}
|
||||
|
||||
// disabled deferred SSAO
|
||||
if (!LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferredSSAO"))
|
||||
{
|
||||
ctrl_ssao->setEnabled(FALSE);
|
||||
ctrl_ssao->setValue(FALSE);
|
||||
}
|
||||
|
||||
// disabled deferred shadows
|
||||
if (!LLFeatureManager::getInstance()->isFeatureAvailable("RenderShadowDetail"))
|
||||
{
|
||||
ctrl_shadows->setEnabled(FALSE);
|
||||
ctrl_shadows->setValue(0);
|
||||
shadows_text->setEnabled(FALSE);
|
||||
}
|
||||
|
||||
// disabled reflections
|
||||
if (!LLFeatureManager::getInstance()->isFeatureAvailable("RenderReflectionDetail"))
|
||||
{
|
||||
ctrl_reflections->setEnabled(FALSE);
|
||||
ctrl_reflections->setValue(FALSE);
|
||||
reflections_text->setEnabled(FALSE);
|
||||
}
|
||||
|
||||
// disabled av
|
||||
if (!LLFeatureManager::getInstance()->isFeatureAvailable("RenderAvatarVP"))
|
||||
{
|
||||
ctrl_avatar_vp->setEnabled(FALSE);
|
||||
ctrl_avatar_vp->setValue(FALSE);
|
||||
|
||||
ctrl_avatar_cloth->setEnabled(FALSE);
|
||||
ctrl_avatar_cloth->setValue(FALSE);
|
||||
|
||||
//deferred needs AvatarVP, disable deferred
|
||||
ctrl_shadows->setEnabled(FALSE);
|
||||
ctrl_shadows->setValue(0);
|
||||
shadows_text->setEnabled(FALSE);
|
||||
|
||||
ctrl_ssao->setEnabled(FALSE);
|
||||
ctrl_ssao->setValue(FALSE);
|
||||
|
||||
ctrl_dof->setEnabled(FALSE);
|
||||
ctrl_dof->setValue(FALSE);
|
||||
|
||||
ctrl_deferred->setEnabled(FALSE);
|
||||
ctrl_deferred->setValue(FALSE);
|
||||
}
|
||||
|
||||
// disabled cloth
|
||||
if (!LLFeatureManager::getInstance()->isFeatureAvailable("RenderAvatarCloth"))
|
||||
{
|
||||
ctrl_avatar_cloth->setEnabled(FALSE);
|
||||
ctrl_avatar_cloth->setValue(FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
void LLFloaterPreference::refresh()
|
||||
{
|
||||
LLPanel::refresh();
|
||||
|
|
@ -2730,32 +2470,6 @@ void LLFloaterPreference::refresh()
|
|||
updateClickActionViews();
|
||||
}
|
||||
|
||||
void LLFloaterPreferenceGraphicsAdvanced::refresh()
|
||||
{
|
||||
getChild<LLUICtrl>("fsaa")->setValue((LLSD::Integer) gSavedSettings.getU32("RenderFSAASamples"));
|
||||
|
||||
// sliders and their text boxes
|
||||
// mPostProcess = gSavedSettings.getS32("RenderGlowResolutionPow");
|
||||
// slider text boxes
|
||||
updateSliderText(getChild<LLSliderCtrl>("ObjectMeshDetail", true), getChild<LLTextBox>("ObjectMeshDetailText", true));
|
||||
updateSliderText(getChild<LLSliderCtrl>("FlexibleMeshDetail", true), getChild<LLTextBox>("FlexibleMeshDetailText", true));
|
||||
updateSliderText(getChild<LLSliderCtrl>("TreeMeshDetail", true), getChild<LLTextBox>("TreeMeshDetailText", true));
|
||||
updateSliderText(getChild<LLSliderCtrl>("AvatarMeshDetail", true), getChild<LLTextBox>("AvatarMeshDetailText", true));
|
||||
updateSliderText(getChild<LLSliderCtrl>("AvatarPhysicsDetail", true), getChild<LLTextBox>("AvatarPhysicsDetailText", true));
|
||||
updateSliderText(getChild<LLSliderCtrl>("TerrainMeshDetail", true), getChild<LLTextBox>("TerrainMeshDetailText", true));
|
||||
updateSliderText(getChild<LLSliderCtrl>("RenderPostProcess", true), getChild<LLTextBox>("PostProcessText", true));
|
||||
updateSliderText(getChild<LLSliderCtrl>("SkyMeshDetail", true), getChild<LLTextBox>("SkyMeshDetailText", true));
|
||||
updateSliderText(getChild<LLSliderCtrl>("TerrainDetail", true), getChild<LLTextBox>("TerrainDetailText", true));
|
||||
LLAvatarComplexityControls::setIndirectControls();
|
||||
setMaxNonImpostorsText(
|
||||
gSavedSettings.getU32("RenderAvatarMaxNonImpostors"),
|
||||
getChild<LLTextBox>("IndirectMaxNonImpostorsText", true));
|
||||
LLAvatarComplexityControls::setText(
|
||||
gSavedSettings.getU32("RenderAvatarMaxComplexity"),
|
||||
getChild<LLTextBox>("IndirectMaxComplexityText", true));
|
||||
refreshEnabledState();
|
||||
}
|
||||
|
||||
void LLFloaterPreference::onCommitWindowedMode()
|
||||
{
|
||||
refresh();
|
||||
|
|
@ -3119,64 +2833,7 @@ void LLFloaterPreference::updateMaxComplexityLabel(const LLSD& newvalue)
|
|||
}
|
||||
// </FS:Ansariel>
|
||||
|
||||
void LLFloaterPreferenceGraphicsAdvanced::updateSliderText(LLSliderCtrl* ctrl, LLTextBox* text_box)
|
||||
{
|
||||
if (text_box == NULL || ctrl== NULL)
|
||||
return;
|
||||
|
||||
// get range and points when text should change
|
||||
F32 value = (F32)ctrl->getValue().asReal();
|
||||
F32 min = ctrl->getMinValue();
|
||||
F32 max = ctrl->getMaxValue();
|
||||
F32 range = max - min;
|
||||
llassert(range > 0);
|
||||
F32 midPoint = min + range / 3.0f;
|
||||
F32 highPoint = min + (2.0f * range / 3.0f);
|
||||
|
||||
// choose the right text
|
||||
if (value < midPoint)
|
||||
{
|
||||
text_box->setText(LLTrans::getString("GraphicsQualityLow"));
|
||||
}
|
||||
else if (value < highPoint)
|
||||
{
|
||||
text_box->setText(LLTrans::getString("GraphicsQualityMid"));
|
||||
}
|
||||
else
|
||||
{
|
||||
text_box->setText(LLTrans::getString("GraphicsQualityHigh"));
|
||||
}
|
||||
}
|
||||
|
||||
void LLFloaterPreferenceGraphicsAdvanced::updateMaxNonImpostors()
|
||||
{
|
||||
// Called when the IndirectMaxNonImpostors control changes
|
||||
// Responsible for fixing the slider label (IndirectMaxNonImpostorsText) and setting RenderAvatarMaxNonImpostors
|
||||
LLSliderCtrl* ctrl = getChild<LLSliderCtrl>("IndirectMaxNonImpostors",true);
|
||||
U32 value = ctrl->getValue().asInteger();
|
||||
|
||||
if (0 == value || LLVOAvatar::NON_IMPOSTORS_MAX_SLIDER <= value)
|
||||
{
|
||||
value=0;
|
||||
}
|
||||
gSavedSettings.setU32("RenderAvatarMaxNonImpostors", value);
|
||||
LLVOAvatar::updateImpostorRendering(value); // make it effective immediately
|
||||
setMaxNonImpostorsText(value, getChild<LLTextBox>("IndirectMaxNonImpostorsText"));
|
||||
}
|
||||
|
||||
void LLFloaterPreferenceGraphicsAdvanced::setMaxNonImpostorsText(U32 value, LLTextBox* text_box)
|
||||
{
|
||||
if (0 == value)
|
||||
{
|
||||
text_box->setText(LLTrans::getString("no_limit"));
|
||||
}
|
||||
else
|
||||
{
|
||||
text_box->setText(llformat("%d", value));
|
||||
}
|
||||
}
|
||||
|
||||
void LLAvatarComplexityControls::updateMax(LLSliderCtrl* slider, LLTextBox* value_label)
|
||||
void LLAvatarComplexityControls::updateMax(LLSliderCtrl* slider, LLTextBox* value_label, bool short_val)
|
||||
{
|
||||
// Called when the IndirectMaxComplexity control changes
|
||||
// Responsible for fixing the slider label (IndirectMaxComplexityText) and setting RenderAvatarMaxComplexity
|
||||
|
|
@ -3198,10 +2855,10 @@ void LLAvatarComplexityControls::updateMax(LLSliderCtrl* slider, LLTextBox* valu
|
|||
}
|
||||
|
||||
gSavedSettings.setU32("RenderAvatarMaxComplexity", (U32)max_arc);
|
||||
setText(max_arc, value_label);
|
||||
setText(max_arc, value_label, short_val);
|
||||
}
|
||||
|
||||
void LLAvatarComplexityControls::setText(U32 value, LLTextBox* text_box)
|
||||
void LLAvatarComplexityControls::setText(U32 value, LLTextBox* text_box, bool short_val)
|
||||
{
|
||||
if (0 == value)
|
||||
{
|
||||
|
|
@ -3210,28 +2867,45 @@ void LLAvatarComplexityControls::setText(U32 value, LLTextBox* text_box)
|
|||
else
|
||||
{
|
||||
// <FS:Ansariel> Proper number formatting with delimiter
|
||||
//text_box->setText(llformat("%d", value));
|
||||
//std::string text_value = short_val ? llformat("%d", value / 1000) : llformat("%d", value);
|
||||
//text_box->setText(text_value);
|
||||
std::string output_string;
|
||||
LLLocale locale("");
|
||||
LLResMgr::getInstance()->getIntegerString(output_string, value);
|
||||
LLResMgr::getInstance()->getIntegerString(output_string, (short_val ? value / 1000 : value));
|
||||
text_box->setText(output_string);
|
||||
}
|
||||
}
|
||||
|
||||
// <FS:Beq> redner time controls
|
||||
void LLAvatarComplexityControls::updateMaxRenderTime(LLSliderCtrl* slider, LLTextBox* value_label, bool short_val)
|
||||
{
|
||||
setRenderTimeText((F32)(FSPerfStats::renderAvatarMaxART_ns/1000), value_label, short_val);
|
||||
}
|
||||
|
||||
void LLAvatarComplexityControls::setRenderTimeText(F32 value, LLTextBox* text_box, bool short_val)
|
||||
{
|
||||
if (0 == value)
|
||||
{
|
||||
text_box->setText(LLTrans::getString("no_limit"));
|
||||
}
|
||||
else
|
||||
{
|
||||
text_box->setText(llformat("%.0f", value));
|
||||
}
|
||||
}
|
||||
// </FS:Beq>
|
||||
void LLFloaterPreference::updateMaxComplexity()
|
||||
{
|
||||
// Called when the IndirectMaxComplexity control changes
|
||||
LLAvatarComplexityControls::updateMax(
|
||||
getChild<LLSliderCtrl>("IndirectMaxComplexity"),
|
||||
getChild<LLTextBox>("IndirectMaxComplexityText"));
|
||||
}
|
||||
|
||||
LLFloaterPreferenceGraphicsAdvanced* floater_graphics_advanced = LLFloaterReg::findTypedInstance<LLFloaterPreferenceGraphicsAdvanced>("prefs_graphics_advanced");
|
||||
if (floater_graphics_advanced)
|
||||
{
|
||||
LLAvatarComplexityControls::updateMax(
|
||||
floater_graphics_advanced->getChild<LLSliderCtrl>("IndirectMaxComplexity"),
|
||||
floater_graphics_advanced->getChild<LLTextBox>("IndirectMaxComplexityText"));
|
||||
}
|
||||
void LLFloaterPreference::updateComplexityText()
|
||||
{
|
||||
LLAvatarComplexityControls::setText(gSavedSettings.getU32("RenderAvatarMaxComplexity"),
|
||||
getChild<LLTextBox>("IndirectMaxComplexityText", true));
|
||||
}
|
||||
|
||||
bool LLFloaterPreference::loadFromFilename(const std::string& filename, std::map<std::string, std::string> &label_map)
|
||||
|
|
@ -3273,22 +2947,6 @@ bool LLFloaterPreference::loadFromFilename(const std::string& filename, std::map
|
|||
return true;
|
||||
}
|
||||
|
||||
void LLFloaterPreferenceGraphicsAdvanced::updateMaxComplexity()
|
||||
{
|
||||
// Called when the IndirectMaxComplexity control changes
|
||||
LLAvatarComplexityControls::updateMax(
|
||||
getChild<LLSliderCtrl>("IndirectMaxComplexity"),
|
||||
getChild<LLTextBox>("IndirectMaxComplexityText"));
|
||||
|
||||
LLFloaterPreference* floater_preferences = LLFloaterReg::findTypedInstance<LLFloaterPreference>("preferences");
|
||||
if (floater_preferences)
|
||||
{
|
||||
LLAvatarComplexityControls::updateMax(
|
||||
floater_preferences->getChild<LLSliderCtrl>("IndirectMaxComplexity"),
|
||||
floater_preferences->getChild<LLTextBox>("IndirectMaxComplexityText"));
|
||||
}
|
||||
}
|
||||
|
||||
void LLFloaterPreference::onChangeMaturity()
|
||||
{
|
||||
U8 sim_access = gSavedSettings.getU32("PreferredMaturity");
|
||||
|
|
@ -5050,18 +4708,6 @@ void LLPanelPreferenceControls::onCancelKeyBind()
|
|||
pControlsTable->deselectAllItems();
|
||||
}
|
||||
|
||||
LLFloaterPreferenceGraphicsAdvanced::LLFloaterPreferenceGraphicsAdvanced(const LLSD& key)
|
||||
: LLFloater(key)
|
||||
{
|
||||
mCommitCallbackRegistrar.add("Pref.RenderOptionUpdate", boost::bind(&LLFloaterPreferenceGraphicsAdvanced::onRenderOptionEnable, this));
|
||||
mCommitCallbackRegistrar.add("Pref.UpdateIndirectMaxNonImpostors", boost::bind(&LLFloaterPreferenceGraphicsAdvanced::updateMaxNonImpostors,this));
|
||||
mCommitCallbackRegistrar.add("Pref.UpdateIndirectMaxComplexity", boost::bind(&LLFloaterPreferenceGraphicsAdvanced::updateMaxComplexity,this));
|
||||
}
|
||||
|
||||
LLFloaterPreferenceGraphicsAdvanced::~LLFloaterPreferenceGraphicsAdvanced()
|
||||
{
|
||||
}
|
||||
|
||||
LLFloaterPreferenceProxy::LLFloaterPreferenceProxy(const LLSD& key)
|
||||
: LLFloater(key),
|
||||
mSocksSettingsDirty(false)
|
||||
|
|
@ -5071,41 +4717,6 @@ LLFloaterPreferenceProxy::LLFloaterPreferenceProxy(const LLSD& key)
|
|||
mCommitCallbackRegistrar.add("Proxy.Change", boost::bind(&LLFloaterPreferenceProxy::onChangeSocksSettings, this));
|
||||
}
|
||||
|
||||
BOOL LLFloaterPreferenceGraphicsAdvanced::postBuild()
|
||||
{
|
||||
// Don't do this on Mac as their braindead GL versioning
|
||||
// sets this when 8x and 16x are indeed available
|
||||
//
|
||||
#if !LL_DARWIN
|
||||
if (gGLManager.mIsIntel || gGLManager.mGLVersion < 3.f)
|
||||
{ //remove FSAA settings above "4x"
|
||||
LLComboBox* combo = getChild<LLComboBox>("fsaa");
|
||||
combo->remove("8x");
|
||||
combo->remove("16x");
|
||||
}
|
||||
|
||||
LLCheckBoxCtrl *use_HiDPI = getChild<LLCheckBoxCtrl>("use HiDPI");
|
||||
use_HiDPI->setVisible(FALSE);
|
||||
#endif
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void LLFloaterPreferenceGraphicsAdvanced::onOpen(const LLSD& key)
|
||||
{
|
||||
refresh();
|
||||
}
|
||||
|
||||
void LLFloaterPreferenceGraphicsAdvanced::onClickCloseBtn(bool app_quitting)
|
||||
{
|
||||
LLFloaterPreference* instance = LLFloaterReg::findTypedInstance<LLFloaterPreference>("preferences");
|
||||
if (instance)
|
||||
{
|
||||
instance->cancel();
|
||||
}
|
||||
updateMaxComplexity();
|
||||
}
|
||||
|
||||
LLFloaterPreferenceProxy::~LLFloaterPreferenceProxy()
|
||||
{
|
||||
}
|
||||
|
|
|
|||
|
|
@ -120,12 +120,10 @@ public:
|
|||
// updates click/double-click action controls depending on values from settings.xml
|
||||
void updateClickActionViews();
|
||||
|
||||
// <FS:CR> Make onBtnOk() public for settings backup panel
|
||||
//protected:
|
||||
void onBtnOK(const LLSD& userdata);
|
||||
protected:
|
||||
// </FS:CR>
|
||||
void onBtnCancel(const LLSD& userdata);
|
||||
void onBtnOK(const LLSD& userdata);
|
||||
void onBtnCancel(const LLSD& userdata);
|
||||
|
||||
protected:
|
||||
|
||||
//void onClickClearCache(); // Clear viewer texture cache, file cache on next startup // AO: was protected, moved to public
|
||||
void onClickBrowserClearCache(); // Clear web history and caches as well as viewer caches above
|
||||
|
|
@ -301,6 +299,7 @@ private:
|
|||
void onDeleteTranscriptsResponse(const LLSD& notification, const LLSD& response);
|
||||
void updateDeleteTranscriptsButton();
|
||||
void updateMaxComplexity();
|
||||
void updateComplexityText();
|
||||
static bool loadFromFilename(const std::string& filename, std::map<std::string, std::string> &label_map);
|
||||
|
||||
static std::string sSkin;
|
||||
|
|
@ -321,6 +320,8 @@ private:
|
|||
LLSearchEditor *mFilterEdit;
|
||||
std::unique_ptr< ll::prefs::SearchData > mSearchData;
|
||||
|
||||
boost::signals2::connection mComplexityChangedSignal;
|
||||
|
||||
void onUpdateFilterTerm( bool force = false );
|
||||
void collectSearchableItems();
|
||||
|
||||
|
|
@ -473,37 +474,15 @@ private:
|
|||
S32 mEditingMode;
|
||||
};
|
||||
|
||||
class LLFloaterPreferenceGraphicsAdvanced : public LLFloater
|
||||
{
|
||||
public:
|
||||
LLFloaterPreferenceGraphicsAdvanced(const LLSD& key);
|
||||
~LLFloaterPreferenceGraphicsAdvanced();
|
||||
/*virtual*/ BOOL postBuild();
|
||||
void onOpen(const LLSD& key);
|
||||
void onClickCloseBtn(bool app_quitting);
|
||||
void disableUnavailableSettings();
|
||||
void refreshEnabledGraphics();
|
||||
void refreshEnabledState();
|
||||
void updateSliderText(LLSliderCtrl* ctrl, LLTextBox* text_box);
|
||||
void updateMaxNonImpostors();
|
||||
void setMaxNonImpostorsText(U32 value, LLTextBox* text_box);
|
||||
void updateMaxComplexity();
|
||||
void setMaxComplexityText(U32 value, LLTextBox* text_box);
|
||||
static void setIndirectControls();
|
||||
static void setIndirectMaxNonImpostors();
|
||||
static void setIndirectMaxArc();
|
||||
void refresh();
|
||||
// callback for when client modifies a render option
|
||||
void onRenderOptionEnable();
|
||||
void onAdvancedAtmosphericsEnable();
|
||||
LOG_CLASS(LLFloaterPreferenceGraphicsAdvanced);
|
||||
};
|
||||
|
||||
class LLAvatarComplexityControls
|
||||
{
|
||||
public:
|
||||
static void updateMax(LLSliderCtrl* slider, LLTextBox* value_label);
|
||||
static void setText(U32 value, LLTextBox* text_box);
|
||||
static void updateMax(LLSliderCtrl* slider, LLTextBox* value_label, bool short_val = false);
|
||||
static void setText(U32 value, LLTextBox* text_box, bool short_val = false);
|
||||
// <FS:Beq> for render time support
|
||||
static void updateMaxRenderTime(LLSliderCtrl* slider, LLTextBox* value_label, bool short_val = false);
|
||||
static void setRenderTimeText(F32 value, LLTextBox* text_box, bool short_val = false);
|
||||
// </FS:Beq>
|
||||
static void setIndirectControls();
|
||||
static void setIndirectMaxNonImpostors();
|
||||
static void setIndirectMaxArc();
|
||||
|
|
|
|||
|
|
@ -0,0 +1,474 @@
|
|||
/**
|
||||
* @file llfloaterpreferencesgraphicsadvanced.cpp
|
||||
* @brief floater for adjusting camera position
|
||||
*
|
||||
* $LicenseInfo:firstyear=2021&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2021, Linden Research, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#include "llviewerprecompiledheaders.h"
|
||||
#include "llfloaterpreferencesgraphicsadvanced.h"
|
||||
|
||||
#include "llcheckboxctrl.h"
|
||||
#include "llcombobox.h"
|
||||
#include "llfeaturemanager.h"
|
||||
#include "llfloaterpreference.h"
|
||||
#include "llfloaterreg.h"
|
||||
#include "llsliderctrl.h"
|
||||
#include "lltextbox.h"
|
||||
#include "lltrans.h"
|
||||
#include "llviewershadermgr.h"
|
||||
#include "llviewertexturelist.h"
|
||||
#include "llvoavatar.h"
|
||||
#include "pipeline.h"
|
||||
#include "llviewercontrol.h"
|
||||
#include "rlvactions.h"
|
||||
|
||||
LLFloaterPreferenceGraphicsAdvanced::LLFloaterPreferenceGraphicsAdvanced(const LLSD& key)
|
||||
: LLFloater(key)
|
||||
{
|
||||
mCommitCallbackRegistrar.add("Pref.RenderOptionUpdate", boost::bind(&LLFloaterPreferenceGraphicsAdvanced::onRenderOptionEnable, this));
|
||||
mCommitCallbackRegistrar.add("Pref.UpdateIndirectMaxNonImpostors", boost::bind(&LLFloaterPreferenceGraphicsAdvanced::updateMaxNonImpostors,this));
|
||||
mCommitCallbackRegistrar.add("Pref.UpdateIndirectMaxComplexity", boost::bind(&LLFloaterPreferenceGraphicsAdvanced::updateMaxComplexity,this));
|
||||
|
||||
mCommitCallbackRegistrar.add("Pref.Cancel", boost::bind(&LLFloaterPreferenceGraphicsAdvanced::onBtnCancel, this, _2));
|
||||
mCommitCallbackRegistrar.add("Pref.OK", boost::bind(&LLFloaterPreferenceGraphicsAdvanced::onBtnOK, this, _2));
|
||||
}
|
||||
|
||||
LLFloaterPreferenceGraphicsAdvanced::~LLFloaterPreferenceGraphicsAdvanced()
|
||||
{
|
||||
mComplexityChangedSignal.disconnect();
|
||||
}
|
||||
|
||||
BOOL LLFloaterPreferenceGraphicsAdvanced::postBuild()
|
||||
{
|
||||
// Don't do this on Mac as their braindead GL versioning
|
||||
// sets this when 8x and 16x are indeed available
|
||||
//
|
||||
#if !LL_DARWIN
|
||||
if (gGLManager.mIsIntel || gGLManager.mGLVersion < 3.f)
|
||||
{ //remove FSAA settings above "4x"
|
||||
LLComboBox* combo = getChild<LLComboBox>("fsaa");
|
||||
combo->remove("8x");
|
||||
combo->remove("16x");
|
||||
}
|
||||
|
||||
LLCheckBoxCtrl *use_HiDPI = getChild<LLCheckBoxCtrl>("use HiDPI");
|
||||
use_HiDPI->setVisible(FALSE);
|
||||
#endif
|
||||
|
||||
mComplexityChangedSignal = gSavedSettings.getControl("RenderAvatarMaxComplexity")->getCommitSignal()->connect(boost::bind(&LLFloaterPreferenceGraphicsAdvanced::updateComplexityText, this));
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void LLFloaterPreferenceGraphicsAdvanced::onOpen(const LLSD& key)
|
||||
{
|
||||
refresh();
|
||||
}
|
||||
|
||||
void LLFloaterPreferenceGraphicsAdvanced::onClickCloseBtn(bool app_quitting)
|
||||
{
|
||||
LLFloaterPreference* instance = LLFloaterReg::findTypedInstance<LLFloaterPreference>("preferences");
|
||||
if (instance)
|
||||
{
|
||||
instance->cancel();
|
||||
}
|
||||
updateMaxComplexity();
|
||||
}
|
||||
|
||||
void LLFloaterPreferenceGraphicsAdvanced::onRenderOptionEnable()
|
||||
{
|
||||
LLFloaterPreference* instance = LLFloaterReg::findTypedInstance<LLFloaterPreference>("preferences");
|
||||
if (instance)
|
||||
{
|
||||
instance->refresh();
|
||||
}
|
||||
|
||||
refreshEnabledGraphics();
|
||||
}
|
||||
|
||||
void LLFloaterPreferenceGraphicsAdvanced::onAdvancedAtmosphericsEnable()
|
||||
{
|
||||
LLFloaterPreference* instance = LLFloaterReg::findTypedInstance<LLFloaterPreference>("preferences");
|
||||
if (instance)
|
||||
{
|
||||
instance->refresh();
|
||||
}
|
||||
|
||||
refreshEnabledGraphics();
|
||||
}
|
||||
|
||||
void LLFloaterPreferenceGraphicsAdvanced::refresh()
|
||||
{
|
||||
getChild<LLUICtrl>("fsaa")->setValue((LLSD::Integer) gSavedSettings.getU32("RenderFSAASamples"));
|
||||
|
||||
// sliders and their text boxes
|
||||
// mPostProcess = gSavedSettings.getS32("RenderGlowResolutionPow");
|
||||
// slider text boxes
|
||||
updateSliderText(getChild<LLSliderCtrl>("ObjectMeshDetail", true), getChild<LLTextBox>("ObjectMeshDetailText", true));
|
||||
updateSliderText(getChild<LLSliderCtrl>("FlexibleMeshDetail", true), getChild<LLTextBox>("FlexibleMeshDetailText", true));
|
||||
updateSliderText(getChild<LLSliderCtrl>("TreeMeshDetail", true), getChild<LLTextBox>("TreeMeshDetailText", true));
|
||||
updateSliderText(getChild<LLSliderCtrl>("AvatarMeshDetail", true), getChild<LLTextBox>("AvatarMeshDetailText", true));
|
||||
updateSliderText(getChild<LLSliderCtrl>("AvatarPhysicsDetail", true), getChild<LLTextBox>("AvatarPhysicsDetailText", true));
|
||||
updateSliderText(getChild<LLSliderCtrl>("TerrainMeshDetail", true), getChild<LLTextBox>("TerrainMeshDetailText", true));
|
||||
updateSliderText(getChild<LLSliderCtrl>("RenderPostProcess", true), getChild<LLTextBox>("PostProcessText", true));
|
||||
updateSliderText(getChild<LLSliderCtrl>("SkyMeshDetail", true), getChild<LLTextBox>("SkyMeshDetailText", true));
|
||||
updateSliderText(getChild<LLSliderCtrl>("TerrainDetail", true), getChild<LLTextBox>("TerrainDetailText", true));
|
||||
LLAvatarComplexityControls::setIndirectControls();
|
||||
setMaxNonImpostorsText(
|
||||
gSavedSettings.getU32("RenderAvatarMaxNonImpostors"),
|
||||
getChild<LLTextBox>("IndirectMaxNonImpostorsText", true));
|
||||
LLAvatarComplexityControls::setText(
|
||||
gSavedSettings.getU32("RenderAvatarMaxComplexity"),
|
||||
getChild<LLTextBox>("IndirectMaxComplexityText", true));
|
||||
refreshEnabledState();
|
||||
}
|
||||
|
||||
void LLFloaterPreferenceGraphicsAdvanced::refreshEnabledGraphics()
|
||||
{
|
||||
refreshEnabledState();
|
||||
}
|
||||
|
||||
void LLFloaterPreferenceGraphicsAdvanced::updateMaxComplexity()
|
||||
{
|
||||
// Called when the IndirectMaxComplexity control changes
|
||||
LLAvatarComplexityControls::updateMax(
|
||||
getChild<LLSliderCtrl>("IndirectMaxComplexity"),
|
||||
getChild<LLTextBox>("IndirectMaxComplexityText"));
|
||||
}
|
||||
|
||||
void LLFloaterPreferenceGraphicsAdvanced::updateComplexityText()
|
||||
{
|
||||
LLAvatarComplexityControls::setText(gSavedSettings.getU32("RenderAvatarMaxComplexity"),
|
||||
getChild<LLTextBox>("IndirectMaxComplexityText", true));
|
||||
}
|
||||
|
||||
void LLFloaterPreferenceGraphicsAdvanced::updateSliderText(LLSliderCtrl* ctrl, LLTextBox* text_box)
|
||||
{
|
||||
if (text_box == NULL || ctrl== NULL)
|
||||
return;
|
||||
|
||||
// get range and points when text should change
|
||||
F32 value = (F32)ctrl->getValue().asReal();
|
||||
F32 min = ctrl->getMinValue();
|
||||
F32 max = ctrl->getMaxValue();
|
||||
F32 range = max - min;
|
||||
llassert(range > 0);
|
||||
F32 midPoint = min + range / 3.0f;
|
||||
F32 highPoint = min + (2.0f * range / 3.0f);
|
||||
|
||||
// choose the right text
|
||||
if (value < midPoint)
|
||||
{
|
||||
text_box->setText(LLTrans::getString("GraphicsQualityLow"));
|
||||
}
|
||||
else if (value < highPoint)
|
||||
{
|
||||
text_box->setText(LLTrans::getString("GraphicsQualityMid"));
|
||||
}
|
||||
else
|
||||
{
|
||||
text_box->setText(LLTrans::getString("GraphicsQualityHigh"));
|
||||
}
|
||||
}
|
||||
|
||||
void LLFloaterPreferenceGraphicsAdvanced::updateMaxNonImpostors()
|
||||
{
|
||||
// Called when the IndirectMaxNonImpostors control changes
|
||||
// Responsible for fixing the slider label (IndirectMaxNonImpostorsText) and setting RenderAvatarMaxNonImpostors
|
||||
LLSliderCtrl* ctrl = getChild<LLSliderCtrl>("IndirectMaxNonImpostors",true);
|
||||
U32 value = ctrl->getValue().asInteger();
|
||||
|
||||
if (0 == value || LLVOAvatar::NON_IMPOSTORS_MAX_SLIDER <= value)
|
||||
{
|
||||
value=0;
|
||||
}
|
||||
gSavedSettings.setU32("RenderAvatarMaxNonImpostors", value);
|
||||
LLVOAvatar::updateImpostorRendering(value); // make it effective immediately
|
||||
setMaxNonImpostorsText(value, getChild<LLTextBox>("IndirectMaxNonImpostorsText"));
|
||||
}
|
||||
|
||||
void LLFloaterPreferenceGraphicsAdvanced::setMaxNonImpostorsText(U32 value, LLTextBox* text_box)
|
||||
{
|
||||
if (0 == value)
|
||||
{
|
||||
text_box->setText(LLTrans::getString("no_limit"));
|
||||
}
|
||||
else
|
||||
{
|
||||
text_box->setText(llformat("%d", value));
|
||||
}
|
||||
}
|
||||
|
||||
void LLFloaterPreferenceGraphicsAdvanced::disableUnavailableSettings()
|
||||
{
|
||||
LLComboBox* ctrl_reflections = getChild<LLComboBox>("Reflections");
|
||||
LLTextBox* reflections_text = getChild<LLTextBox>("ReflectionsText");
|
||||
LLCheckBoxCtrl* ctrl_avatar_vp = getChild<LLCheckBoxCtrl>("AvatarVertexProgram");
|
||||
LLCheckBoxCtrl* ctrl_avatar_cloth = getChild<LLCheckBoxCtrl>("AvatarCloth");
|
||||
LLCheckBoxCtrl* ctrl_wind_light = getChild<LLCheckBoxCtrl>("WindLightUseAtmosShaders");
|
||||
LLCheckBoxCtrl* ctrl_deferred = getChild<LLCheckBoxCtrl>("UseLightShaders");
|
||||
LLComboBox* ctrl_shadows = getChild<LLComboBox>("ShadowDetail");
|
||||
LLTextBox* shadows_text = getChild<LLTextBox>("RenderShadowDetailText");
|
||||
LLCheckBoxCtrl* ctrl_ssao = getChild<LLCheckBoxCtrl>("UseSSAO");
|
||||
LLCheckBoxCtrl* ctrl_dof = getChild<LLCheckBoxCtrl>("UseDoF");
|
||||
LLSliderCtrl* sky = getChild<LLSliderCtrl>("SkyMeshDetail");
|
||||
LLTextBox* sky_text = getChild<LLTextBox>("SkyMeshDetailText");
|
||||
|
||||
// disabled windlight
|
||||
if (!LLFeatureManager::getInstance()->isFeatureAvailable("WindLightUseAtmosShaders"))
|
||||
{
|
||||
ctrl_wind_light->setEnabled(FALSE);
|
||||
ctrl_wind_light->setValue(FALSE);
|
||||
|
||||
sky->setEnabled(FALSE);
|
||||
sky_text->setEnabled(FALSE);
|
||||
|
||||
//deferred needs windlight, disable deferred
|
||||
ctrl_shadows->setEnabled(FALSE);
|
||||
ctrl_shadows->setValue(0);
|
||||
shadows_text->setEnabled(FALSE);
|
||||
|
||||
ctrl_ssao->setEnabled(FALSE);
|
||||
ctrl_ssao->setValue(FALSE);
|
||||
|
||||
ctrl_dof->setEnabled(FALSE);
|
||||
ctrl_dof->setValue(FALSE);
|
||||
|
||||
ctrl_deferred->setEnabled(FALSE);
|
||||
ctrl_deferred->setValue(FALSE);
|
||||
}
|
||||
|
||||
// disabled deferred
|
||||
if (!LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferred") ||
|
||||
!gGLManager.mHasFramebufferObject)
|
||||
{
|
||||
ctrl_shadows->setEnabled(FALSE);
|
||||
ctrl_shadows->setValue(0);
|
||||
shadows_text->setEnabled(FALSE);
|
||||
|
||||
ctrl_ssao->setEnabled(FALSE);
|
||||
ctrl_ssao->setValue(FALSE);
|
||||
|
||||
ctrl_dof->setEnabled(FALSE);
|
||||
ctrl_dof->setValue(FALSE);
|
||||
|
||||
ctrl_deferred->setEnabled(FALSE);
|
||||
ctrl_deferred->setValue(FALSE);
|
||||
}
|
||||
|
||||
// disabled deferred SSAO
|
||||
if (!LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferredSSAO"))
|
||||
{
|
||||
ctrl_ssao->setEnabled(FALSE);
|
||||
ctrl_ssao->setValue(FALSE);
|
||||
}
|
||||
|
||||
// disabled deferred shadows
|
||||
if (!LLFeatureManager::getInstance()->isFeatureAvailable("RenderShadowDetail"))
|
||||
{
|
||||
ctrl_shadows->setEnabled(FALSE);
|
||||
ctrl_shadows->setValue(0);
|
||||
shadows_text->setEnabled(FALSE);
|
||||
}
|
||||
|
||||
// disabled reflections
|
||||
if (!LLFeatureManager::getInstance()->isFeatureAvailable("RenderReflectionDetail"))
|
||||
{
|
||||
ctrl_reflections->setEnabled(FALSE);
|
||||
ctrl_reflections->setValue(FALSE);
|
||||
reflections_text->setEnabled(FALSE);
|
||||
}
|
||||
|
||||
// disabled av
|
||||
if (!LLFeatureManager::getInstance()->isFeatureAvailable("RenderAvatarVP"))
|
||||
{
|
||||
ctrl_avatar_vp->setEnabled(FALSE);
|
||||
ctrl_avatar_vp->setValue(FALSE);
|
||||
|
||||
ctrl_avatar_cloth->setEnabled(FALSE);
|
||||
ctrl_avatar_cloth->setValue(FALSE);
|
||||
|
||||
//deferred needs AvatarVP, disable deferred
|
||||
ctrl_shadows->setEnabled(FALSE);
|
||||
ctrl_shadows->setValue(0);
|
||||
shadows_text->setEnabled(FALSE);
|
||||
|
||||
ctrl_ssao->setEnabled(FALSE);
|
||||
ctrl_ssao->setValue(FALSE);
|
||||
|
||||
ctrl_dof->setEnabled(FALSE);
|
||||
ctrl_dof->setValue(FALSE);
|
||||
|
||||
ctrl_deferred->setEnabled(FALSE);
|
||||
ctrl_deferred->setValue(FALSE);
|
||||
}
|
||||
|
||||
// disabled cloth
|
||||
if (!LLFeatureManager::getInstance()->isFeatureAvailable("RenderAvatarCloth"))
|
||||
{
|
||||
ctrl_avatar_cloth->setEnabled(FALSE);
|
||||
ctrl_avatar_cloth->setValue(FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
void LLFloaterPreferenceGraphicsAdvanced::refreshEnabledState()
|
||||
{
|
||||
LLComboBox* ctrl_reflections = getChild<LLComboBox>("Reflections");
|
||||
LLTextBox* reflections_text = getChild<LLTextBox>("ReflectionsText");
|
||||
|
||||
// Reflections
|
||||
BOOL reflections = gGLManager.mHasCubeMap && LLCubeMap::sUseCubeMaps;
|
||||
ctrl_reflections->setEnabled(reflections);
|
||||
reflections_text->setEnabled(reflections);
|
||||
|
||||
// Transparent Water
|
||||
LLCheckBoxCtrl* transparent_water_ctrl = getChild<LLCheckBoxCtrl>("TransparentWater");
|
||||
|
||||
// Bump & Shiny
|
||||
LLCheckBoxCtrl* bumpshiny_ctrl = getChild<LLCheckBoxCtrl>("BumpShiny");
|
||||
bool bumpshiny = gGLManager.mHasCubeMap && LLCubeMap::sUseCubeMaps && LLFeatureManager::getInstance()->isFeatureAvailable("RenderObjectBump");
|
||||
bumpshiny_ctrl->setEnabled(bumpshiny ? TRUE : FALSE);
|
||||
|
||||
// Avatar Mode
|
||||
// Enable Avatar Shaders
|
||||
LLCheckBoxCtrl* ctrl_avatar_vp = getChild<LLCheckBoxCtrl>("AvatarVertexProgram");
|
||||
// Avatar Render Mode
|
||||
LLCheckBoxCtrl* ctrl_avatar_cloth = getChild<LLCheckBoxCtrl>("AvatarCloth");
|
||||
|
||||
bool avatar_vp_enabled = LLFeatureManager::getInstance()->isFeatureAvailable("RenderAvatarVP");
|
||||
if (LLViewerShaderMgr::sInitialized)
|
||||
{
|
||||
S32 max_avatar_shader = LLViewerShaderMgr::instance()->mMaxAvatarShaderLevel;
|
||||
avatar_vp_enabled = (max_avatar_shader > 0) ? TRUE : FALSE;
|
||||
}
|
||||
|
||||
ctrl_avatar_vp->setEnabled(avatar_vp_enabled);
|
||||
|
||||
if (gSavedSettings.getBOOL("RenderAvatarVP") == FALSE)
|
||||
{
|
||||
ctrl_avatar_cloth->setEnabled(FALSE);
|
||||
}
|
||||
else
|
||||
{
|
||||
ctrl_avatar_cloth->setEnabled(TRUE);
|
||||
}
|
||||
|
||||
/* <FS:LO> remove orphaned code left over from EEP
|
||||
// Vertex Shaders, Global Shader Enable
|
||||
// SL-12594 Basic shaders are always enabled. DJH TODO clean up now-orphaned state handling code
|
||||
LLSliderCtrl* terrain_detail = getChild<LLSliderCtrl>("TerrainDetail"); // can be linked with control var
|
||||
LLTextBox* terrain_text = getChild<LLTextBox>("TerrainDetailText");
|
||||
|
||||
terrain_detail->setEnabled(FALSE);
|
||||
terrain_text->setEnabled(FALSE);
|
||||
*/
|
||||
|
||||
// WindLight
|
||||
LLCheckBoxCtrl* ctrl_wind_light = getChild<LLCheckBoxCtrl>("WindLightUseAtmosShaders");
|
||||
LLSliderCtrl* sky = getChild<LLSliderCtrl>("SkyMeshDetail");
|
||||
LLTextBox* sky_text = getChild<LLTextBox>("SkyMeshDetailText");
|
||||
// [RLVa:KB] - Checked: 2010-03-18 (RLVa-1.2.0a) | Modified: RLVa-0.2.0a
|
||||
// "Atmospheric Shaders" can't be disabled - but can be enabled - under @setenv=n
|
||||
ctrl_wind_light->setEnabled((RlvActions::canChangeEnvironment()) || (!gSavedSettings.getBOOL("WindLightUseAtmosShaders")));
|
||||
// [/RLVa:KB]
|
||||
// ctrl_wind_light->setEnabled(TRUE);
|
||||
sky->setEnabled(TRUE);
|
||||
sky_text->setEnabled(TRUE);
|
||||
|
||||
//Deferred/SSAO/Shadows
|
||||
LLCheckBoxCtrl* ctrl_deferred = getChild<LLCheckBoxCtrl>("UseLightShaders");
|
||||
|
||||
BOOL enabled = LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferred") &&
|
||||
((bumpshiny_ctrl && bumpshiny_ctrl->get()) ? TRUE : FALSE) &&
|
||||
((transparent_water_ctrl && transparent_water_ctrl->get()) ? TRUE : FALSE) &&
|
||||
gGLManager.mHasFramebufferObject &&
|
||||
gSavedSettings.getBOOL("RenderAvatarVP") &&
|
||||
(ctrl_wind_light->get()) ? TRUE : FALSE;
|
||||
|
||||
ctrl_deferred->setEnabled(enabled);
|
||||
|
||||
LLCheckBoxCtrl* ctrl_ssao = getChild<LLCheckBoxCtrl>("UseSSAO");
|
||||
LLCheckBoxCtrl* ctrl_dof = getChild<LLCheckBoxCtrl>("UseDoF");
|
||||
LLComboBox* ctrl_shadow = getChild<LLComboBox>("ShadowDetail");
|
||||
LLTextBox* shadow_text = getChild<LLTextBox>("RenderShadowDetailText");
|
||||
|
||||
// note, okay here to get from ctrl_deferred as it's twin, ctrl_deferred2 will alway match it
|
||||
enabled = enabled && LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferredSSAO") && (ctrl_deferred->get() ? TRUE : FALSE);
|
||||
|
||||
ctrl_deferred->set(gSavedSettings.getBOOL("RenderDeferred"));
|
||||
|
||||
ctrl_ssao->setEnabled(enabled);
|
||||
ctrl_dof->setEnabled(enabled);
|
||||
|
||||
enabled = enabled && LLFeatureManager::getInstance()->isFeatureAvailable("RenderShadowDetail");
|
||||
|
||||
ctrl_shadow->setEnabled(enabled);
|
||||
shadow_text->setEnabled(enabled);
|
||||
|
||||
// Hardware settings
|
||||
F32 mem_multiplier = gSavedSettings.getF32("RenderTextureMemoryMultiple");
|
||||
S32Megabytes min_tex_mem = LLViewerTextureList::getMinVideoRamSetting();
|
||||
S32Megabytes max_tex_mem = LLViewerTextureList::getMaxVideoRamSetting(false, mem_multiplier);
|
||||
getChild<LLSliderCtrl>("GraphicsCardTextureMemory")->setMinValue(min_tex_mem.value());
|
||||
getChild<LLSliderCtrl>("GraphicsCardTextureMemory")->setMaxValue(max_tex_mem.value());
|
||||
|
||||
if (!LLFeatureManager::getInstance()->isFeatureAvailable("RenderVBOEnable") ||
|
||||
!gGLManager.mHasVertexBufferObject)
|
||||
{
|
||||
getChildView("vbo")->setEnabled(FALSE);
|
||||
}
|
||||
|
||||
if (!LLFeatureManager::getInstance()->isFeatureAvailable("RenderCompressTextures") ||
|
||||
!gGLManager.mHasVertexBufferObject)
|
||||
{
|
||||
getChildView("texture compression")->setEnabled(FALSE);
|
||||
}
|
||||
|
||||
// if no windlight shaders, turn off nighttime brightness, gamma, and fog distance
|
||||
LLUICtrl* gamma_ctrl = getChild<LLUICtrl>("gamma");
|
||||
gamma_ctrl->setEnabled(!gPipeline.canUseWindLightShaders());
|
||||
getChildView("(brightness, lower is brighter)")->setEnabled(!gPipeline.canUseWindLightShaders());
|
||||
getChildView("fog")->setEnabled(!gPipeline.canUseWindLightShaders());
|
||||
getChildView("antialiasing restart")->setVisible(!LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferred"));
|
||||
|
||||
// now turn off any features that are unavailable
|
||||
disableUnavailableSettings();
|
||||
}
|
||||
|
||||
void LLFloaterPreferenceGraphicsAdvanced::onBtnOK(const LLSD& userdata)
|
||||
{
|
||||
LLFloaterPreference* instance = LLFloaterReg::getTypedInstance<LLFloaterPreference>("preferences");
|
||||
if (instance)
|
||||
{
|
||||
instance->onBtnOK(userdata);
|
||||
}
|
||||
}
|
||||
|
||||
void LLFloaterPreferenceGraphicsAdvanced::onBtnCancel(const LLSD& userdata)
|
||||
{
|
||||
LLFloaterPreference* instance = LLFloaterReg::getTypedInstance<LLFloaterPreference>("preferences");
|
||||
if (instance)
|
||||
{
|
||||
instance->onBtnCancel(userdata);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,65 @@
|
|||
/**
|
||||
* @file llfloaterpreferencesgraphicsadvanced.h
|
||||
*
|
||||
* $LicenseInfo:firstyear=2021&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2021, Linden Research, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#ifndef LLFLOATERPREFERENCEGRAPHICSADVANCED_H
|
||||
#define LLFLOATERPREFERENCEGRAPHICSADVANCED_H
|
||||
|
||||
#include "llcontrol.h"
|
||||
#include "llfloater.h"
|
||||
|
||||
class LLSliderCtrl;
|
||||
class LLTextBox;
|
||||
|
||||
class LLFloaterPreferenceGraphicsAdvanced : public LLFloater
|
||||
{
|
||||
public:
|
||||
LLFloaterPreferenceGraphicsAdvanced(const LLSD& key);
|
||||
~LLFloaterPreferenceGraphicsAdvanced();
|
||||
/*virtual*/ BOOL postBuild();
|
||||
void onOpen(const LLSD& key);
|
||||
void onClickCloseBtn(bool app_quitting);
|
||||
void disableUnavailableSettings();
|
||||
void refreshEnabledGraphics();
|
||||
void refreshEnabledState();
|
||||
void updateSliderText(LLSliderCtrl* ctrl, LLTextBox* text_box);
|
||||
void updateMaxNonImpostors();
|
||||
void setMaxNonImpostorsText(U32 value, LLTextBox* text_box);
|
||||
void updateMaxComplexity();
|
||||
void updateComplexityText();
|
||||
void refresh();
|
||||
// callback for when client modifies a render option
|
||||
void onRenderOptionEnable();
|
||||
void onAdvancedAtmosphericsEnable();
|
||||
LOG_CLASS(LLFloaterPreferenceGraphicsAdvanced);
|
||||
|
||||
protected:
|
||||
void onBtnOK(const LLSD& userdata);
|
||||
void onBtnCancel(const LLSD& userdata);
|
||||
|
||||
boost::signals2::connection mComplexityChangedSignal;
|
||||
};
|
||||
|
||||
#endif //LLFLOATERPREFERENCEGRAPHICSADVANCED_H
|
||||
|
||||
|
|
@ -71,9 +71,11 @@ LLNameListCtrl::LLNameListCtrl(const LLNameListCtrl::Params& p)
|
|||
mNameColumnIndex(p.name_column.column_index),
|
||||
mNameColumn(p.name_column.column_name),
|
||||
mAllowCallingCardDrop(p.allow_calling_card_drop),
|
||||
mShortNames(p.short_names)
|
||||
mShortNames(p.short_names),
|
||||
// <FS:Ansariel> Fix Baker's NameListCtrl un-fix
|
||||
//mPendingLookupsRemaining(0)
|
||||
//mPendingLookupsRemaining(0),
|
||||
mHoverIconName("Info_Small"),
|
||||
mNameListType(INDIVIDUAL)
|
||||
{}
|
||||
|
||||
// public
|
||||
|
|
@ -140,7 +142,12 @@ BOOL LLNameListCtrl::handleDragAndDrop(
|
|||
|
||||
void LLNameListCtrl::showInspector(const LLUUID& avatar_id, bool is_group, bool is_experience)
|
||||
{
|
||||
if(is_experience)
|
||||
if (isSpecialType())
|
||||
{
|
||||
mIconClickedSignal(avatar_id);
|
||||
return;
|
||||
}
|
||||
if(is_experience)
|
||||
{
|
||||
LLFloaterReg::showInstance("experience_profile", avatar_id, true);
|
||||
return;
|
||||
|
|
@ -224,14 +231,16 @@ BOOL LLNameListCtrl::handleToolTip(S32 x, S32 y, MASK mask)
|
|||
S32 column_index = getColumnIndexFromOffset(x);
|
||||
LLNameListItem* hit_item = dynamic_cast<LLNameListItem*>(hitItem(x, y));
|
||||
LLFloater* floater = gFloaterView->getParentFloater(this);
|
||||
if (floater
|
||||
|
||||
|
||||
if (floater
|
||||
&& floater->isFrontmost()
|
||||
&& hit_item
|
||||
&& column_index == mNameColumnIndex)
|
||||
&& ((column_index == mNameColumnIndex) || isSpecialType()))
|
||||
{
|
||||
// ...this is the column with the avatar name
|
||||
LLUUID avatar_id = hit_item->getUUID();
|
||||
if (avatar_id.notNull())
|
||||
// ...this is the column with the avatar name
|
||||
LLUUID item_id = isSpecialType() ? hit_item->getSpecialID() : hit_item->getUUID();
|
||||
if (item_id.notNull())
|
||||
{
|
||||
// ...valid avatar id
|
||||
|
||||
|
|
@ -239,13 +248,13 @@ BOOL LLNameListCtrl::handleToolTip(S32 x, S32 y, MASK mask)
|
|||
if (hit_cell)
|
||||
{
|
||||
S32 row_index = getItemIndex(hit_item);
|
||||
LLRect cell_rect = getCellRect(row_index, column_index);
|
||||
LLRect cell_rect = getCellRect(row_index, isSpecialType() ? getNumColumns() - 1 : column_index);
|
||||
// Convert rect local to screen coordinates
|
||||
LLRect sticky_rect;
|
||||
localRectToScreen(cell_rect, &sticky_rect);
|
||||
|
||||
// Spawn at right side of cell
|
||||
LLPointer<LLUIImage> icon = LLUI::getUIImage("Info_Small");
|
||||
LLPointer<LLUIImage> icon = LLUI::getUIImage(mHoverIconName);
|
||||
S32 screenX = sticky_rect.mRight - info_icon_size;
|
||||
S32 screenY = sticky_rect.mTop - (sticky_rect.getHeight() - icon->getHeight()) / 2;
|
||||
LLCoordGL pos(screenX, screenY);
|
||||
|
|
@ -259,7 +268,7 @@ BOOL LLNameListCtrl::handleToolTip(S32 x, S32 y, MASK mask)
|
|||
|
||||
LLToolTip::Params params;
|
||||
params.background_visible(false);
|
||||
params.click_callback(boost::bind(&LLNameListCtrl::showInspector, this, avatar_id, is_group, is_experience));
|
||||
params.click_callback(boost::bind(&LLNameListCtrl::showInspector, this, item_id, is_group, is_experience));
|
||||
params.delay_time(0.0f); // spawn instantly on hover
|
||||
params.image(icon);
|
||||
params.message("");
|
||||
|
|
@ -336,6 +345,7 @@ LLScrollListItem* LLNameListCtrl::addNameItemRow(
|
|||
|
||||
// use supplied name by default
|
||||
std::string fullname = name_item.name;
|
||||
|
||||
switch(name_item.target)
|
||||
{
|
||||
case GROUP:
|
||||
|
|
@ -354,8 +364,10 @@ LLScrollListItem* LLNameListCtrl::addNameItemRow(
|
|||
}
|
||||
break;
|
||||
case SPECIAL:
|
||||
// just use supplied name
|
||||
break;
|
||||
{
|
||||
item->setSpecialID(name_item.special_id());
|
||||
return item;
|
||||
}
|
||||
case INDIVIDUAL:
|
||||
{
|
||||
LLAvatarName av_name;
|
||||
|
|
@ -366,7 +378,7 @@ LLScrollListItem* LLNameListCtrl::addNameItemRow(
|
|||
else if (LLAvatarNameCache::get(id, &av_name))
|
||||
{
|
||||
if (mShortNames)
|
||||
fullname = av_name.getDisplayName();
|
||||
fullname = av_name.getDisplayName(true);
|
||||
else
|
||||
fullname = av_name.getCompleteName();
|
||||
}
|
||||
|
|
@ -437,7 +449,8 @@ void LLNameListCtrl::removeNameItem(const LLUUID& agent_id)
|
|||
for (item_list::iterator it = getItemList().begin(); it != getItemList().end(); it++)
|
||||
{
|
||||
LLScrollListItem* item = *it;
|
||||
if (item->getUUID() == agent_id)
|
||||
LLUUID cur_id = isSpecialType() ? dynamic_cast<LLNameListItem*>(item)->getSpecialID() : item->getUUID();
|
||||
if (cur_id == agent_id)
|
||||
{
|
||||
idx = getItemIndex(item);
|
||||
break;
|
||||
|
|
@ -469,6 +482,34 @@ LLScrollListItem* LLNameListCtrl::getNameItemByAgentId(const LLUUID& agent_id)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
void LLNameListCtrl::selectItemBySpecialId(const LLUUID& special_id)
|
||||
{
|
||||
if (special_id.isNull())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for (item_list::iterator it = getItemList().begin(); it != getItemList().end(); it++)
|
||||
{
|
||||
LLNameListItem* item = dynamic_cast<LLNameListItem*>(*it);
|
||||
if (item && item->getSpecialID() == special_id)
|
||||
{
|
||||
item->setSelected(TRUE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LLUUID LLNameListCtrl::getSelectedSpecialId()
|
||||
{
|
||||
LLNameListItem* item = dynamic_cast<LLNameListItem*>(getFirstSelected());
|
||||
if(item)
|
||||
{
|
||||
return item->getSpecialID();
|
||||
}
|
||||
return LLUUID();
|
||||
}
|
||||
|
||||
void LLNameListCtrl::onAvatarNameCache(const LLUUID& agent_id,
|
||||
const LLAvatarName& av_name,
|
||||
std::string suffix,
|
||||
|
|
|
|||
|
|
@ -52,6 +52,8 @@ public:
|
|||
void setIsGroup(bool is_group) { mIsGroup = is_group; }
|
||||
bool isExperience() const { return mIsExperience; }
|
||||
void setIsExperience(bool is_experience) { mIsExperience = is_experience; }
|
||||
void setSpecialID(const LLUUID& special_id) { mSpecialID = special_id; }
|
||||
const LLUUID& getSpecialID() const { return mSpecialID; }
|
||||
|
||||
protected:
|
||||
friend class LLNameListCtrl;
|
||||
|
|
@ -74,6 +76,8 @@ protected:
|
|||
private:
|
||||
bool mIsGroup;
|
||||
bool mIsExperience;
|
||||
|
||||
LLUUID mSpecialID;
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -104,10 +108,12 @@ public:
|
|||
{
|
||||
Optional<std::string> name;
|
||||
Optional<ENameType, NameTypeNames> target;
|
||||
Optional<LLUUID> special_id;
|
||||
|
||||
NameItem()
|
||||
: name("name"),
|
||||
target("target", INDIVIDUAL)
|
||||
target("target", INDIVIDUAL),
|
||||
special_id("special_id", LLUUID())
|
||||
{}
|
||||
};
|
||||
|
||||
|
|
@ -168,6 +174,9 @@ public:
|
|||
|
||||
LLScrollListItem* getNameItemByAgentId(const LLUUID& agent_id);
|
||||
|
||||
void selectItemBySpecialId(const LLUUID& special_id);
|
||||
LLUUID getSelectedSpecialId();
|
||||
|
||||
// LLView interface
|
||||
/*virtual*/ BOOL handleDragAndDrop(S32 x, S32 y, MASK mask,
|
||||
BOOL drop, EDragAndDropType cargo_type, void *cargo_data,
|
||||
|
|
@ -182,6 +191,12 @@ public:
|
|||
/*virtual*/ void updateColumns(bool force_update);
|
||||
|
||||
/*virtual*/ void mouseOverHighlightNthItem( S32 index );
|
||||
|
||||
bool isSpecialType() { return (mNameListType == SPECIAL); }
|
||||
|
||||
void setNameListType(e_name_type type) { mNameListType = type; }
|
||||
void setHoverIconName(std::string icon_name) { mHoverIconName = icon_name; }
|
||||
|
||||
private:
|
||||
void showInspector(const LLUUID& avatar_id, bool is_group, bool is_experience = false);
|
||||
void onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name, std::string suffix, std::string prefix, LLHandle<LLNameListItem> item);
|
||||
|
|
@ -196,17 +211,28 @@ private:
|
|||
avatar_name_cache_connection_map_t mAvatarNameCacheConnections;
|
||||
avatar_name_cache_connection_map_t mGroupNameCacheConnections;
|
||||
|
||||
// <FS:Ansariel> Fix Baker's NameListCtrl un-fix
|
||||
// S32 mPendingLookupsRemaining;
|
||||
// namelist_complete_signal_t mNameListCompleteSignal;
|
||||
//
|
||||
//public:
|
||||
// boost::signals2::connection setOnNameListCompleteCallback(boost::function<void(bool)> onNameListCompleteCallback)
|
||||
// {
|
||||
// return mNameListCompleteSignal.connect(onNameListCompleteCallback);
|
||||
// }
|
||||
// </FS:Ansariel>
|
||||
// <FS:Ansariel> Fix Baker's NameListCtrl un-fix
|
||||
//S32 mPendingLookupsRemaining;
|
||||
//namelist_complete_signal_t mNameListCompleteSignal;
|
||||
// </FS:Ansariel>
|
||||
|
||||
std::string mHoverIconName;
|
||||
e_name_type mNameListType;
|
||||
|
||||
boost::signals2::signal<void(const LLUUID &)> mIconClickedSignal;
|
||||
|
||||
public:
|
||||
// <FS:Ansariel> Fix Baker's NameListCtrl un-fix
|
||||
//boost::signals2::connection setOnNameListCompleteCallback(boost::function<void(bool)> onNameListCompleteCallback)
|
||||
//{
|
||||
// return mNameListCompleteSignal.connect(onNameListCompleteCallback);
|
||||
//}
|
||||
// </FS:Ansariel>
|
||||
|
||||
boost::signals2::connection setIconClickedCallback(boost::function<void(const LLUUID &)> cb)
|
||||
{
|
||||
return mIconClickedSignal.connect(cb);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -42,6 +42,7 @@
|
|||
#include "llagentcamera.h"
|
||||
#include "llfile.h"
|
||||
#include "quickprefs.h"
|
||||
#include "fsperfstats.h" // <FS:Beq/> avoid triggering reloads while autotuning
|
||||
|
||||
LLPresetsManager::LLPresetsManager()
|
||||
// <FS:Ansariel> Graphic preset controls independent from XUI
|
||||
|
|
@ -708,7 +709,9 @@ void LLPresetsManager::handleGraphicPresetControlChanged(LLControlVariablePtr co
|
|||
{
|
||||
LL_DEBUGS() << "Handling graphic preset control change: control = " << control->getName() << " - new = " << new_value << " - old = " << old_value << LL_ENDL;
|
||||
|
||||
if (!mIsLoadingPreset && (!mIsDrawDistanceSteppingActive || control->getName() != "RenderFarClip"))
|
||||
if (!mIsLoadingPreset &&
|
||||
(!mIsDrawDistanceSteppingActive || control->getName() != "RenderFarClip") &&
|
||||
(!FSPerfStats::autoTune) )
|
||||
{
|
||||
LL_DEBUGS() << "Trigger graphic preset control changed signal" << LL_ENDL;
|
||||
|
||||
|
|
|
|||
|
|
@ -1142,6 +1142,7 @@ public:
|
|||
|
||||
virtual S32 frustumCheck(const LLViewerOctreeGroup* group)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED;
|
||||
S32 res = AABBInFrustumNoFarClipGroupBounds(group);
|
||||
if (res != 0)
|
||||
{
|
||||
|
|
@ -1152,6 +1153,7 @@ public:
|
|||
|
||||
virtual S32 frustumCheckObjects(const LLViewerOctreeGroup* group)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED;
|
||||
S32 res = AABBInFrustumNoFarClipObjectBounds(group);
|
||||
if (res != 0)
|
||||
{
|
||||
|
|
@ -1162,6 +1164,7 @@ public:
|
|||
|
||||
virtual void processGroup(LLViewerOctreeGroup* base_group)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED;
|
||||
LLSpatialGroup* group = (LLSpatialGroup*)base_group;
|
||||
if (group->needsUpdate() ||
|
||||
group->getVisible(LLViewerCamera::sCurCameraID) < LLDrawable::getCurrentFrame() - 1)
|
||||
|
|
|
|||
|
|
@ -210,7 +210,7 @@
|
|||
#include "llenvironment.h"
|
||||
|
||||
#include "llstacktrace.h"
|
||||
|
||||
#include "fsperfstats.h"
|
||||
#if LL_WINDOWS
|
||||
#include "lldxhardware.h"
|
||||
#endif
|
||||
|
|
@ -2155,6 +2155,10 @@ bool idle_startup()
|
|||
update_static_eyes();
|
||||
// </FS:KC>
|
||||
|
||||
// <FS:Beq>
|
||||
gAgent.addRegionChangedCallback(boost::bind(&FSPerfStats::StatsRecorder::clearStats));
|
||||
// </FS:Beq>
|
||||
|
||||
// *Note: this is where gWorldMap used to be initialized.
|
||||
|
||||
// register null callbacks for audio until the audio system is initialized
|
||||
|
|
@ -4257,6 +4261,10 @@ bool process_login_success_response(U32 &first_sim_size_x, U32 &first_sim_size_y
|
|||
// unpack login data needed by the application
|
||||
text = response["agent_id"].asString();
|
||||
if(!text.empty()) gAgentID.set(text);
|
||||
// <FS:Beq> Performance floater initialisation
|
||||
FSPerfStats::StatsRecorder::setEnabled(gSavedSettings.getBOOL("FSPerfStatsCaptureEnabled"));
|
||||
FSPerfStats::StatsRecorder::setFocusAv(gAgentID);
|
||||
// </FS:Beq>
|
||||
// gDebugInfo["AgentID"] = text;
|
||||
// [SL:KB] - Patch: Viewer-CrashReporting | Checked: 2010-11-16 (Catznip-2.6.0a) | Added: Catznip-2.4.0b
|
||||
if (gCrashSettings.getBOOL("CrashSubmitName"))
|
||||
|
|
|
|||
|
|
@ -587,10 +587,10 @@ void LLStatusBar::refresh()
|
|||
|
||||
// <FS:Ansariel> FIRE-14482: Show FPS in status bar
|
||||
static LLCachedControl<bool> fsStatusBarShowFPS(gSavedSettings, "FSStatusBarShowFPS");
|
||||
if (fsStatusBarShowFPS && mFPSUpdateTimer.getElapsedTimeF32() > 0.5f)
|
||||
if (fsStatusBarShowFPS && mFPSUpdateTimer.getElapsedTimeF32() > 1.f)
|
||||
{
|
||||
mFPSUpdateTimer.reset();
|
||||
mFPSText->setText(llformat("%.1f", LLTrace::get_frame_recording().getPeriodMeanPerSec(LLStatViewer::FPS)));
|
||||
mFPSText->setText(llformat("%.1f", LLTrace::get_frame_recording().getPeriodMedianPerSec(LLStatViewer::FPS)));
|
||||
}
|
||||
// </FS:Ansariel>
|
||||
|
||||
|
|
|
|||
|
|
@ -107,7 +107,7 @@
|
|||
#include "llviewerregion.h"
|
||||
#include "NACLantispam.h"
|
||||
#include "nd/ndlogthrottle.h"
|
||||
|
||||
#include "fsperfstats.h"
|
||||
// <FS:Zi> Run Prio 0 default bento pose in the background to fix splayed hands, open mouths, etc.
|
||||
#include "llanimationstates.h"
|
||||
|
||||
|
|
@ -1059,6 +1059,40 @@ void handleDiskCacheSizeChanged(const LLSD& newValue)
|
|||
}
|
||||
// </FS:Ansariel>
|
||||
|
||||
// <FS:Beq> perrf floater stuffs
|
||||
void handleTargetFPSChanged(const LLSD& newValue)
|
||||
{
|
||||
const auto targetFPS = gSavedSettings.getU32("FSTargetFPS");
|
||||
FSPerfStats::targetFPS = targetFPS;
|
||||
}
|
||||
|
||||
// <FS:Beq> perrf floater stuffs
|
||||
void handleAutoTuneFPSChanged(const LLSD& newValue)
|
||||
{
|
||||
const auto newval = gSavedSettings.getBOOL("FSAutoTuneFPS");
|
||||
FSPerfStats::autoTune = newval;
|
||||
if(newval && FSPerfStats::renderAvatarMaxART_ns == 0) // If we've enabled autotune we override "unlimited" to max
|
||||
{
|
||||
gSavedSettings.setF32("FSRenderAvatarMaxART",log10(FSPerfStats::ART_UNLIMITED_NANOS-1000));//triggers callback to update static var
|
||||
}
|
||||
}
|
||||
|
||||
void handleRenderAvatarMaxARTChanged(const LLSD& newValue)
|
||||
{
|
||||
FSPerfStats::StatsRecorder::updateRenderCostLimitFromSettings();
|
||||
}
|
||||
void handleFPSTuningStrategyChanged(const LLSD& newValue)
|
||||
{
|
||||
const auto newval = gSavedSettings.getU32("FSTuningFPSStrategy");
|
||||
FSPerfStats::fpsTuningStrategy = newval;
|
||||
}
|
||||
void handlePerformanceStatsEnabledChanged(const LLSD& newValue)
|
||||
{
|
||||
const auto newval = gSavedSettings.getBOOL("FSPerfStatsCaptureEnabled");
|
||||
FSPerfStats::StatsRecorder::setEnabled(newval);
|
||||
}
|
||||
// </FS:Beq>
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void settings_setup_listeners()
|
||||
|
|
@ -1313,6 +1347,14 @@ void settings_setup_listeners()
|
|||
|
||||
// <FS:Ansariel> Better asset cache size control
|
||||
gSavedSettings.getControl("FSDiskCacheSize")->getSignal()->connect(boost::bind(&handleDiskCacheSizeChanged, _2));
|
||||
|
||||
// <FS:Beq> perf floater controls
|
||||
gSavedSettings.getControl("FSTargetFPS")->getSignal()->connect(boost::bind(&handleTargetFPSChanged, _2));
|
||||
gSavedSettings.getControl("FSAutoTuneFPS")->getSignal()->connect(boost::bind(&handleAutoTuneFPSChanged, _2));
|
||||
gSavedSettings.getControl("FSRenderAvatarMaxART")->getSignal()->connect(boost::bind(&handleRenderAvatarMaxARTChanged, _2));
|
||||
gSavedSettings.getControl("FSTuningFPSStrategy")->getSignal()->connect(boost::bind(&handleFPSTuningStrategyChanged, _2));
|
||||
gSavedSettings.getControl("FSPerfStatsCaptureEnabled")->getSignal()->connect(boost::bind(&handlePerformanceStatsEnabledChanged, _2));
|
||||
// </FS:Beq>
|
||||
}
|
||||
|
||||
#if TEST_CACHED_CONTROL
|
||||
|
|
|
|||
|
|
@ -85,6 +85,7 @@
|
|||
// [/RLVa:KB]
|
||||
#include "llpresetsmanager.h"
|
||||
#include "fsdata.h"
|
||||
#include "fsperfstats.h" // <FS:Beq> performance stats support
|
||||
|
||||
extern LLPointer<LLViewerTexture> gStartTexture;
|
||||
extern bool gShiftFrame;
|
||||
|
|
@ -280,6 +281,7 @@ static LLTrace::BlockTimerStatHandle FTM_EEP_UPDATE("Env Update");
|
|||
// Paint the display!
|
||||
void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
|
||||
{
|
||||
FSPerfStats::RecordSceneTime T (FSPerfStats::StatType_t::RENDER_DISPLAY); // <FS:Beq/> render time capture - This is the main stat for overall rendering.
|
||||
LL_RECORD_BLOCK_TIME(FTM_RENDER);
|
||||
|
||||
LLViewerCamera& camera = LLViewerCamera::instance(); // <FS:Ansariel> Factor out calls to getInstance
|
||||
|
|
@ -1192,6 +1194,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
|
|||
|
||||
void render_hud_attachments()
|
||||
{
|
||||
FSPerfStats::RecordSceneTime T ( FSPerfStats::StatType_t::RENDER_HUDS); // <FS:Beq/> render time capture - Primary contributor to HUDs (though these end up in render batches)
|
||||
gGL.matrixMode(LLRender::MM_PROJECTION);
|
||||
gGL.pushMatrix();
|
||||
gGL.matrixMode(LLRender::MM_MODELVIEW);
|
||||
|
|
@ -1399,6 +1402,7 @@ bool setup_hud_matrices(const LLRect& screen_region)
|
|||
|
||||
void render_ui(F32 zoom_factor, int subfield)
|
||||
{
|
||||
FSPerfStats::RecordSceneTime T ( FSPerfStats::StatType_t::RENDER_UI ); // <FS:Beq/> render time capture - Primary UI stat can have HUD time overlap (TODO)
|
||||
LL_RECORD_BLOCK_TIME(FTM_RENDER_UI);
|
||||
|
||||
LLGLState::checkStates();
|
||||
|
|
@ -1492,6 +1496,7 @@ static LLTrace::BlockTimerStatHandle FTM_SWAP("Swap");
|
|||
|
||||
void swap()
|
||||
{
|
||||
FSPerfStats::RecordSceneTime T ( FSPerfStats::StatType_t::RENDER_SWAP ); // <FS:Beq/> render time capture - Swap buffer time - can signify excessive data transfer to/from GPU
|
||||
LL_RECORD_BLOCK_TIME(FTM_SWAP);
|
||||
|
||||
if (gDisplaySwapBuffers)
|
||||
|
|
|
|||
|
|
@ -105,9 +105,12 @@
|
|||
#include "llfloaterpathfindingconsole.h"
|
||||
#include "llfloaterpathfindinglinksets.h"
|
||||
#include "llfloaterpay.h"
|
||||
// #include "llfloaterperformance.h" <FS:Beq/> rename to fs as ll version no released
|
||||
#include "fsfloaterperformance.h"
|
||||
#include "llfloaterperms.h"
|
||||
#include "llfloaterpostprocess.h"
|
||||
#include "llfloaterpreference.h"
|
||||
#include "llfloaterpreferencesgraphicsadvanced.h"
|
||||
#include "llfloaterpreferenceviewadvanced.h"
|
||||
#include "llfloaterpreviewtrash.h"
|
||||
#include "llfloaterproperties.h"
|
||||
|
|
@ -379,10 +382,11 @@ void LLViewerFloaterReg::registerFloaters()
|
|||
LLFloaterReg::add("pathfinding_linksets", "floater_pathfinding_linksets.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterPathfindingLinksets>);
|
||||
LLFloaterReg::add("pathfinding_console", "floater_pathfinding_console.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterPathfindingConsole>);
|
||||
LLFloaterReg::add("people", "floater_people.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSidePanelContainer>);
|
||||
//LLFloaterReg::add("performance", "floater_performance.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterPerformance>);
|
||||
LLFloaterReg::add("perms_default", "floater_perms_default.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterPermsDefault>);
|
||||
LLFloaterReg::add("places", "floater_places.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSidePanelContainer>);
|
||||
LLFloaterReg::add("preferences", "floater_preferences.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterPreference>);
|
||||
LLFloaterReg::add("prefs_graphics_advanced", "floater_preferences_graphics_advanced.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterPreferenceGraphicsAdvanced>);
|
||||
// LLFloaterReg::add("prefs_graphics_advanced", "floater_preferences_graphics_advanced.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterPreferenceGraphicsAdvanced>);
|
||||
LLFloaterReg::add("prefs_view_advanced", "floater_preferences_view_advanced.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterPreferenceViewAdvanced>);
|
||||
LLFloaterReg::add("prefs_proxy", "floater_preferences_proxy.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterPreferenceProxy>);
|
||||
LLFloaterReg::add("prefs_spellchecker_import", "floater_spellcheck_import.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSpellCheckerImport>);
|
||||
|
|
@ -500,6 +504,7 @@ void LLViewerFloaterReg::registerFloaters()
|
|||
LLFloaterReg::add("media_lists", "floater_media_lists.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<FloaterMediaLists>);
|
||||
LLFloaterReg::add("money_tracker", "floater_fs_money_tracker.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<FSMoneyTracker>);
|
||||
LLFloaterReg::add("particle_editor","floater_particle_editor.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<ParticleEditor>);
|
||||
LLFloaterReg::add("performance", "floater_performance.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<FSFloaterPerformance>);
|
||||
LLFloaterReg::add(PHOTOTOOLS_FLOATER, "floater_phototools.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<FloaterQuickPrefs>);
|
||||
LLFloaterReg::add("phototools_camera", "floater_phototools_camera.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterCamera>);
|
||||
LLFloaterReg::add("publish_classified_fs", "floater_publish_classified.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<FSPublishClassifiedFloater>);
|
||||
|
|
|
|||
|
|
@ -55,6 +55,7 @@
|
|||
#include "m3math.h"
|
||||
#include "m4math.h"
|
||||
#include "llmatrix4a.h"
|
||||
#include "fsperfstats.h" // <FS:Beq> performance stats support
|
||||
|
||||
#if !LL_DARWIN && !LL_LINUX
|
||||
extern PFNGLWEIGHTPOINTERARBPROC glWeightPointerARB;
|
||||
|
|
@ -222,6 +223,7 @@ int compare_int(const void *a, const void *b)
|
|||
//--------------------------------------------------------------------
|
||||
U32 LLViewerJointMesh::drawShape( F32 pixelArea, BOOL first_pass, BOOL is_dummy)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED;
|
||||
if (!mValid || !mMesh || !mFace || !mVisible ||
|
||||
!mFace->getVertexBuffer() ||
|
||||
mMesh->getNumFaces() == 0 ||
|
||||
|
|
@ -230,6 +232,15 @@ U32 LLViewerJointMesh::drawShape( F32 pixelArea, BOOL first_pass, BOOL is_dummy)
|
|||
return 0;
|
||||
}
|
||||
|
||||
// <FS:Beq> render time capture
|
||||
// TODO(Beq) This path does not appear to have attachments. Prove this then remove.
|
||||
std::unique_ptr<FSPerfStats::RecordAttachmentTime> ratPtr{};
|
||||
auto vobj = mFace->getViewerObject();
|
||||
if( vobj && vobj->isAttachment() )
|
||||
{
|
||||
trackAttachments( vobj, mFace->isState(LLFace::RIGGED), &ratPtr );
|
||||
}
|
||||
// </FS:Beq>
|
||||
U32 triangle_count = 0;
|
||||
|
||||
S32 diffuse_channel = LLDrawPoolAvatar::sDiffuseChannel;
|
||||
|
|
|
|||
|
|
@ -3868,6 +3868,9 @@ bool check_avatar_render_mode(U32 mode)
|
|||
return FSAvatarRenderPersistence::instance().getAvatarRenderSettings(avatar->getID()) == LLVOAvatar::AV_ALWAYS_RENDER;
|
||||
// [/RLVa:KB]
|
||||
// return (avatar->getVisualMuteSettings() == LLVOAvatar::AV_ALWAYS_RENDER);
|
||||
case 4:
|
||||
return FSAvatarRenderPersistence::instance().getAvatarRenderSettings(avatar->getID()) != LLVOAvatar::AV_RENDER_NORMALLY;
|
||||
// return FSAvatarRenderPersistence::instance().getAvatarRenderSettings(avatar->getID()) == LLVOAvatar::AV_RENDER_NORMALLY;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
|
@ -3895,6 +3898,8 @@ class LLAvatarCheckImpostorMode : public view_listener_t
|
|||
// return (avatar->getVisualMuteSettings() == LLVOAvatar::AV_DO_NOT_RENDER);
|
||||
// case 2:
|
||||
// return (avatar->getVisualMuteSettings() == LLVOAvatar::AV_ALWAYS_RENDER);
|
||||
// case 4:
|
||||
// return (avatar->getVisualMuteSettings() != LLVOAvatar::AV_RENDER_NORMALLY);
|
||||
// default:
|
||||
// return false;
|
||||
//}
|
||||
|
|
|
|||
|
|
@ -1361,6 +1361,7 @@ bool LLViewerOctreeCull::earlyFail(LLViewerOctreeGroup* group)
|
|||
//virtual
|
||||
void LLViewerOctreeCull::traverse(const OctreeNode* n)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED;
|
||||
LLViewerOctreeGroup* group = (LLViewerOctreeGroup*) n->getListener(0);
|
||||
|
||||
if (earlyFail(group))
|
||||
|
|
@ -1371,14 +1372,17 @@ void LLViewerOctreeCull::traverse(const OctreeNode* n)
|
|||
if (mRes == 2 ||
|
||||
(mRes && group->hasState(LLViewerOctreeGroup::SKIP_FRUSTUM_CHECK)))
|
||||
{ //fully in, just add everything
|
||||
LL_PROFILE_ZONE_NAMED("AllInside");
|
||||
OctreeTraveler::traverse(n);
|
||||
}
|
||||
else
|
||||
{
|
||||
LL_PROFILE_ZONE_NAMED("Check inside?");
|
||||
mRes = frustumCheck(group);
|
||||
|
||||
if (mRes)
|
||||
{ //at least partially in, run on down
|
||||
LL_PROFILE_ZONE_NAMED("PartiallyIn");
|
||||
OctreeTraveler::traverse(n);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -3810,13 +3810,13 @@ void append_xui_tooltip(LLView* viewp, LLToolTip::Params& params)
|
|||
}
|
||||
}
|
||||
|
||||
static LLTrace::BlockTimerStatHandle ftm("Update UI");
|
||||
static LLTrace::BlockTimerStatHandle FTM_UPDATE_UI("Update UI"); // <FS:Beq/> rename to sensible symbol
|
||||
|
||||
// Update UI based on stored mouse position from mouse-move
|
||||
// event processing.
|
||||
void LLViewerWindow::updateUI()
|
||||
{
|
||||
LL_RECORD_BLOCK_TIME(ftm);
|
||||
LL_RECORD_BLOCK_TIME(FTM_UPDATE_UI); // <FS:Beq/> rename to sensible symbol
|
||||
|
||||
static std::string last_handle_msg;
|
||||
|
||||
|
|
|
|||
|
|
@ -134,6 +134,7 @@
|
|||
#include "fslslbridge.h" // <FS:PP> Movelock position refresh
|
||||
|
||||
#include "fsdiscordconnect.h" // <FS:LO> tapping a place that happens on landing in world to start up discord
|
||||
#include "fsperfstats.h" // <FS:Beq> performance stats support
|
||||
|
||||
extern F32 SPEED_ADJUST_MAX;
|
||||
extern F32 SPEED_ADJUST_MAX_SEC;
|
||||
|
|
@ -601,7 +602,6 @@ bool LLVOAvatar::sLimitNonImpostors = false; // True unless RenderAvatarMaxNonIm
|
|||
F32 LLVOAvatar::sRenderDistance = 256.f;
|
||||
S32 LLVOAvatar::sNumVisibleAvatars = 0;
|
||||
S32 LLVOAvatar::sNumLODChangesThisFrame = 0;
|
||||
|
||||
// const LLUUID LLVOAvatar::sStepSoundOnLand("e8af4a28-aa83-4310-a7c4-c047e15ea0df"); - <FS:PP> Commented out for FIRE-3169: Option to change the default footsteps sound
|
||||
const LLUUID LLVOAvatar::sStepSounds[LL_MCODE_END] =
|
||||
{
|
||||
|
|
@ -2696,7 +2696,10 @@ void LLVOAvatar::idleUpdate(LLAgent &agent, const F64 &time)
|
|||
LL_INFOS() << "Warning! Idle on dead avatar" << LL_ENDL;
|
||||
return;
|
||||
}
|
||||
|
||||
// <FS:Beq> record time and refresh "tooSlow" status
|
||||
FSPerfStats::RecordAvatarTime T(getID(), FSPerfStats::StatType_t::RENDER_IDLE); // per avatar "idle" time.
|
||||
updateTooSlow();
|
||||
// </FS:Beq>;
|
||||
// <FS:CR> Use LLCachedControl
|
||||
static LLCachedControl<bool> disable_all_render_types(gSavedSettings, "DisableAllRenderTypes");
|
||||
if (!(gPipeline.hasRenderType(mIsControlAvatar ? LLPipeline::RENDER_TYPE_CONTROL_AV : LLPipeline::RENDER_TYPE_AVATAR))
|
||||
|
|
@ -2704,7 +2707,11 @@ void LLVOAvatar::idleUpdate(LLAgent &agent, const F64 &time)
|
|||
&& !(disable_all_render_types) && !isSelf())
|
||||
// </FS:CR>
|
||||
{
|
||||
return;
|
||||
if (!mIsControlAvatar)
|
||||
{
|
||||
idleUpdateNameTag( mLastRootPos );
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Update should be happening max once per frame.
|
||||
|
|
@ -2736,7 +2743,7 @@ void LLVOAvatar::idleUpdate(LLAgent &agent, const F64 &time)
|
|||
//</FS:Beq>
|
||||
}
|
||||
|
||||
LLScopedContextString str("avatar_idle_update " + getFullname());
|
||||
// LLScopedContextString str("avatar_idle_update " + getFullname()); // <FS:Beq> remove unused scoped string
|
||||
|
||||
checkTextureLoading() ;
|
||||
|
||||
|
|
@ -3399,14 +3406,12 @@ void LLVOAvatar::idleUpdateNameTag(const LLVector3& root_pos_last)
|
|||
fRlvShowAvName = (fRlvShowAvTag) && (RlvActions::canShowName(RlvActions::SNC_DEFAULT, getID()));
|
||||
}
|
||||
// [/RLVa:KB]
|
||||
BOOL visible_avatar = isVisible() || mNeedsAnimUpdate;
|
||||
BOOL visible_chat = useChatBubbles && (mChats.size() || mTyping);
|
||||
BOOL visible_typing = useTypingBubbles && mTyping;
|
||||
BOOL render_name = visible_chat ||
|
||||
visible_typing ||
|
||||
(visible_avatar &&
|
||||
// [RLVa:KB] - Checked: RLVa-2.0.1
|
||||
(fRlvShowAvTag) &&
|
||||
((fRlvShowAvTag) &&
|
||||
// [/RLVa:KB]
|
||||
((sRenderName == RENDER_NAME_ALWAYS) ||
|
||||
(sRenderName == RENDER_NAME_FADE && time_visible < NAME_SHOW_TIME)));
|
||||
|
|
@ -4209,6 +4214,7 @@ void LLVOAvatar::slamPosition()
|
|||
|
||||
bool LLVOAvatar::isVisuallyMuted()
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED; // <FS:Beq/> Tracy accounting for imposter testing.
|
||||
bool muted = false;
|
||||
|
||||
// <FS:Ansariel> FIRE-11783: Always visually mute avatars that are muted
|
||||
|
|
@ -4261,6 +4267,7 @@ bool LLVOAvatar::isVisuallyMuted()
|
|||
|
||||
bool LLVOAvatar::isInMuteList() const
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED; // <FS:Beq/> Tracy accounting for imposter testing.
|
||||
bool muted = false;
|
||||
F64 now = LLFrameTimer::getTotalSeconds();
|
||||
if (now < mCachedMuteListUpdateTime)
|
||||
|
|
@ -4694,11 +4701,12 @@ void LLVOAvatar::updateFootstepSounds()
|
|||
void LLVOAvatar::computeUpdatePeriod()
|
||||
{
|
||||
bool visually_muted = isVisuallyMuted();
|
||||
bool slow = isTooSlowWithoutShadows();// <FS:Beq/> the geometry alone is forcing this to be slow so we must imposter
|
||||
if (mDrawable.notNull()
|
||||
&& isVisible()
|
||||
&& (!isSelf() || visually_muted)
|
||||
&& !isUIAvatar()
|
||||
&& (sLimitNonImpostors || visually_muted)
|
||||
&& (sLimitNonImpostors || visually_muted || slow) // <FS:Beq/> imposter slow avatars irrespective of nonimposter setting.
|
||||
&& !mNeedsAnimUpdate
|
||||
&& !sFreezeCounter)
|
||||
{
|
||||
|
|
@ -4710,8 +4718,11 @@ void LLVOAvatar::computeUpdatePeriod()
|
|||
const S32 UPDATE_RATE_SLOW = 64;
|
||||
const S32 UPDATE_RATE_MED = 48;
|
||||
const S32 UPDATE_RATE_FAST = 32;
|
||||
|
||||
if (visually_muted)
|
||||
if(slow)
|
||||
{
|
||||
mUpdatePeriod = UPDATE_RATE_FAST;
|
||||
}
|
||||
else if (visually_muted)
|
||||
{ // visually muted avatars update at lowest rate
|
||||
mUpdatePeriod = UPDATE_RATE_SLOW;
|
||||
}
|
||||
|
|
@ -5569,6 +5580,7 @@ bool LLVOAvatar::shouldAlphaMask()
|
|||
//-----------------------------------------------------------------------------
|
||||
U32 LLVOAvatar::renderSkinned()
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED; // <FS:Beq/> Tracy accounting for imposter testing.
|
||||
U32 num_indices = 0;
|
||||
|
||||
if (!mIsBuilt)
|
||||
|
|
@ -5805,6 +5817,7 @@ U32 LLVOAvatar::renderSkinned()
|
|||
|
||||
U32 LLVOAvatar::renderTransparent(BOOL first_pass)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED; // <FS:Beq/> Tracy accounting for render tracking
|
||||
U32 num_indices = 0;
|
||||
if( isWearingWearableType( LLWearableType::WT_SKIRT ) && (isUIAvatar() || isTextureVisible(TEX_SKIRT_BAKED)) )
|
||||
{
|
||||
|
|
@ -5857,6 +5870,7 @@ U32 LLVOAvatar::renderTransparent(BOOL first_pass)
|
|||
//-----------------------------------------------------------------------------
|
||||
U32 LLVOAvatar::renderRigid()
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED; // <FS:Beq/> Tracy accounting for render tracking
|
||||
U32 num_indices = 0;
|
||||
|
||||
if (!mIsBuilt)
|
||||
|
|
@ -5906,6 +5920,7 @@ U32 LLVOAvatar::renderRigid()
|
|||
|
||||
U32 LLVOAvatar::renderImpostor(LLColor4U color, S32 diffuse_channel)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED; // <FS:Beq/> Tracy accounting for render tracking
|
||||
if (!mImpostor.isComplete())
|
||||
{
|
||||
return 0;
|
||||
|
|
@ -6921,6 +6936,7 @@ const LLUUID& LLVOAvatar::getID() const
|
|||
LLJoint *LLVOAvatar::getJoint( const JointKey &name )
|
||||
// </FS:ND>
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED;
|
||||
//<FS:ND> Query by JointKey rather than just a string, the key can be a U32 index for faster lookup
|
||||
//joint_map_t::iterator iter = mJointMap.find( name );
|
||||
|
||||
|
|
@ -9116,6 +9132,95 @@ BOOL LLVOAvatar::isFullyLoaded() const
|
|||
// return (mRenderUnloadedAvatar || mFullyLoaded);
|
||||
}
|
||||
|
||||
// <FS:Beq> use Avatar Render Time as complexity metric
|
||||
// markARTStale - Mark stale and set the frameupdate to now so that we can wait at least one frame to get a revised number.
|
||||
void LLVOAvatar::markARTStale()
|
||||
{
|
||||
mARTStale=true;
|
||||
mLastARTUpdateFrame = LLFrameTimer::getFrameCount();
|
||||
}
|
||||
|
||||
// Udpate Avatar state based on render time
|
||||
void LLVOAvatar::updateTooSlow()
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED;
|
||||
static LLCachedControl<bool> alwaysRenderFriends(gSavedSettings, "AlwaysRenderFriends");
|
||||
static LLCachedControl<bool> allowSelfImpostor(gSavedSettings, "FSAllowSelfImpostor");
|
||||
const auto id = getID();
|
||||
|
||||
// mTooSlow - Is the avatar flagged as being slow (includes shadow time)
|
||||
// mTooSlowWithoutShadows - Is the avatar flagged as being slow even with shadows removed.
|
||||
// mARTStale - the rendertime we have is stale because of an update. We need to force a re-render to re-assess slowness
|
||||
|
||||
if( mARTStale )
|
||||
{
|
||||
if ( LLFrameTimer::getFrameCount() - mLastARTUpdateFrame < 5 )
|
||||
{
|
||||
// LL_INFOS() << this->getFullname() << " marked stale " << LL_ENDL;
|
||||
// we've not had a chance to update yet (allow a few to be certain a full frame has passed)
|
||||
return;
|
||||
}
|
||||
|
||||
mARTStale = false;
|
||||
mTooSlow = false;
|
||||
mTooSlowWithoutShadows = false;
|
||||
// LL_INFOS() << this->getFullname() << " refreshed ART combined = " << mRenderTime << " @ " << mLastARTUpdateFrame << LL_ENDL;
|
||||
}
|
||||
|
||||
// Either we're not stale or we've updated.
|
||||
|
||||
U64 render_time_raw;
|
||||
U64 render_geom_time_raw;
|
||||
|
||||
if( !mTooSlow )
|
||||
{
|
||||
// we are fully rendered, so we use the live values
|
||||
std::lock_guard<std::mutex> lock{FSPerfStats::bufferToggleLock};
|
||||
render_time_raw = FSPerfStats::StatsRecorder::get(FSPerfStats::ObjType_t::OT_AVATAR, id, FSPerfStats::StatType_t::RENDER_COMBINED);
|
||||
render_geom_time_raw = FSPerfStats::StatsRecorder::get(FSPerfStats::ObjType_t::OT_AVATAR, id, FSPerfStats::StatType_t::RENDER_GEOMETRY);
|
||||
}
|
||||
else
|
||||
{
|
||||
// use the cached values.
|
||||
render_time_raw = mRenderTime;
|
||||
render_geom_time_raw = mGeomTime;
|
||||
}
|
||||
if( (FSPerfStats::renderAvatarMaxART_ns > 0) &&
|
||||
(FSPerfStats::raw_to_ns(render_time_raw) >= FSPerfStats::renderAvatarMaxART_ns) )
|
||||
{
|
||||
if( !mTooSlow ) // if we were previously not slow (with or without shadows.)
|
||||
{
|
||||
// if we weren't capped, we are now
|
||||
mLastARTUpdateFrame = LLFrameTimer::getFrameCount();
|
||||
mRenderTime = render_time_raw;
|
||||
mGeomTime = render_geom_time_raw;
|
||||
mARTStale = false;
|
||||
mTooSlow = true;
|
||||
}
|
||||
if(!mTooSlowWithoutShadows) // if we were not previously above the full impostor cap
|
||||
{
|
||||
bool render_friend_or_exception = ( alwaysRenderFriends && LLAvatarTracker::instance().isBuddy( id ) ) ||
|
||||
( getVisualMuteSettings() == LLVOAvatar::AV_ALWAYS_RENDER );
|
||||
if( (!isSelf() || allowSelfImpostor) && !render_friend_or_exception )
|
||||
{
|
||||
// Note: slow rendering Friends still get their shadows zapped.
|
||||
mTooSlowWithoutShadows = (FSPerfStats::raw_to_ns(render_geom_time_raw) >= FSPerfStats::renderAvatarMaxART_ns);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// LL_INFOS() << this->getFullname() << " ("<< (combined?"combined":"geometry") << ") good render time = " << FSPerfStats::raw_to_ns(render_time_raw) << " vs ("<< LLVOAvatar::sRenderTimeCap_ns << " set @ " << mLastARTUpdateFrame << LL_ENDL;
|
||||
mTooSlow = false;
|
||||
mTooSlowWithoutShadows = false;
|
||||
}
|
||||
if(mTooSlow)
|
||||
{
|
||||
FSPerfStats::tunedAvatars++; // <FS:Beq> increment the number of avatars that have been tweaked.
|
||||
}
|
||||
}
|
||||
// </FS:Beq>
|
||||
|
||||
bool LLVOAvatar::isTooComplex() const
|
||||
{
|
||||
bool too_complex;
|
||||
|
|
@ -10130,7 +10235,6 @@ void LLVOAvatar::processAvatarAppearance( LLMessageSystem* mesgsys )
|
|||
//bool enable_verbose_dumps = gSavedSettings.getBOOL("DebugAvatarAppearanceMessage");
|
||||
static LLCachedControl<bool> enable_verbose_dumps(gSavedSettings, "DebugAvatarAppearanceMessage");
|
||||
// </FS:CR>
|
||||
std::string dump_prefix = getFullname() + "_" + (isSelf()?"s":"o") + "_";
|
||||
if (gSavedSettings.getBOOL("BlockAvatarAppearanceMessages"))
|
||||
{
|
||||
LL_WARNS() << "Blocking AvatarAppearance message" << LL_ENDL;
|
||||
|
|
@ -10143,6 +10247,7 @@ void LLVOAvatar::processAvatarAppearance( LLMessageSystem* mesgsys )
|
|||
parseAppearanceMessage(mesgsys, *contents);
|
||||
if (enable_verbose_dumps)
|
||||
{
|
||||
std::string dump_prefix = getFullname() + "_" + (isSelf()?"s":"o") + "_";
|
||||
dumpAppearanceMsgParams(dump_prefix + "appearance_msg", *contents);
|
||||
}
|
||||
|
||||
|
|
@ -10424,7 +10529,6 @@ void LLVOAvatar::applyParsedAppearanceMessage(LLAppearanceMessageContents& conte
|
|||
|
||||
updateMeshTextures();
|
||||
updateMeshVisibility();
|
||||
|
||||
}
|
||||
|
||||
LLViewerTexture* LLVOAvatar::getBakedTexture(const U8 te)
|
||||
|
|
@ -11407,7 +11511,14 @@ void LLVOAvatar::updateImpostors()
|
|||
// virtual
|
||||
BOOL LLVOAvatar::isImpostor()
|
||||
{
|
||||
return isVisuallyMuted() || (sLimitNonImpostors && (mUpdatePeriod > 1));
|
||||
// <FS:Beq> render time handling using tooSlow()
|
||||
// return isVisuallyMuted() || (sLimitNonImpostors && (mUpdatePeriod > 1));
|
||||
return (
|
||||
isVisuallyMuted() ||
|
||||
isTooSlowWithoutShadows() ||
|
||||
(sLimitNonImpostors && (mUpdatePeriod > 1) )
|
||||
);
|
||||
// </FS:Beq>
|
||||
}
|
||||
|
||||
BOOL LLVOAvatar::shouldImpostor(const F32 rank_factor)
|
||||
|
|
@ -11420,6 +11531,15 @@ BOOL LLVOAvatar::shouldImpostor(const F32 rank_factor)
|
|||
{
|
||||
return true;
|
||||
}
|
||||
// <FS:Beq> render time handling using tooSlow()
|
||||
// return sLimitNonImpostors && (mVisibilityRank > sMaxNonImpostors * rank_factor);
|
||||
// static LLCachedControl<bool> render_jellys_As_imposters(gSavedSettings, "RenderJellyDollsAsImpostors");
|
||||
|
||||
if (isTooSlowWithoutShadows())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
// </FS:Beq>
|
||||
return sLimitNonImpostors && (mVisibilityRank > sMaxNonImpostors * rank_factor);
|
||||
}
|
||||
|
||||
|
|
@ -11595,6 +11715,7 @@ void LLVOAvatar::updateVisualComplexity()
|
|||
LL_DEBUGS("AvatarRender") << "avatar " << getID() << " appearance changed" << LL_ENDL;
|
||||
// Set the cache time to in the past so it's updated ASAP
|
||||
mVisualComplexityStale = true;
|
||||
markARTStale();
|
||||
}
|
||||
|
||||
// Account for the complexity of a single top-level object associated
|
||||
|
|
@ -11606,6 +11727,7 @@ void LLVOAvatar::accountRenderComplexityForObject(
|
|||
LLVOVolume::texture_cost_t& textures,
|
||||
U32& cost,
|
||||
hud_complexity_list_t& hud_complexity_list,
|
||||
object_complexity_list_t& object_complexity_list,
|
||||
// <FS:Ansariel> Show per-item complexity in COF
|
||||
std::map<LLUUID, U32>& item_complexity,
|
||||
std::map<LLUUID, U32>& temp_item_complexity)
|
||||
|
|
@ -11628,12 +11750,12 @@ void LLVOAvatar::accountRenderComplexityForObject(
|
|||
F32 attachment_volume_cost = 0;
|
||||
F32 attachment_texture_cost = 0;
|
||||
F32 attachment_children_cost = 0;
|
||||
const F32 animated_object_attachment_surcharge = 1000;
|
||||
const F32 animated_object_attachment_surcharge = 1000;
|
||||
|
||||
if (attached_object->isAnimatedObject())
|
||||
{
|
||||
attachment_volume_cost += animated_object_attachment_surcharge;
|
||||
}
|
||||
if (attached_object->isAnimatedObject())
|
||||
{
|
||||
attachment_volume_cost += animated_object_attachment_surcharge;
|
||||
}
|
||||
attachment_volume_cost += volume->getRenderCost(textures);
|
||||
|
||||
const_child_list_t children = volume->getChildren();
|
||||
|
|
@ -11668,6 +11790,15 @@ void LLVOAvatar::accountRenderComplexityForObject(
|
|||
// Limit attachment complexity to avoid signed integer flipping of the wearer's ACI
|
||||
cost += (U32)llclamp(attachment_total_cost, MIN_ATTACHMENT_COMPLEXITY, max_attachment_complexity);
|
||||
|
||||
if (isSelf())
|
||||
{
|
||||
LLObjectComplexity object_complexity;
|
||||
object_complexity.objectName = attached_object->getAttachmentItemName();
|
||||
object_complexity.objectId = attached_object->getAttachmentItemID();
|
||||
object_complexity.objectCost = attachment_total_cost;
|
||||
object_complexity_list.push_back(object_complexity);
|
||||
}
|
||||
|
||||
// <FS:Ansariel> Show per-item complexity in COF
|
||||
if (isSelf())
|
||||
{
|
||||
|
|
@ -11679,8 +11810,8 @@ void LLVOAvatar::accountRenderComplexityForObject(
|
|||
{
|
||||
temp_item_complexity.insert(std::make_pair(attached_object->getID(), (U32)attachment_total_cost));
|
||||
}
|
||||
}
|
||||
// </FS:Ansariel>
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -11775,6 +11906,8 @@ void LLVOAvatar::calculateUpdateRenderComplexity()
|
|||
U32 cost = VISUAL_COMPLEXITY_UNKNOWN;
|
||||
LLVOVolume::texture_cost_t textures;
|
||||
hud_complexity_list_t hud_complexity_list;
|
||||
object_complexity_list_t object_complexity_list;
|
||||
|
||||
//<FS:Beq> BOM constrain number of bake requests when BOM not supported
|
||||
// for (U8 baked_index = 0; baked_index < BAKED_NUM_INDICES; baked_index++)
|
||||
for (U8 baked_index = 0; baked_index < getNumBakes(); baked_index++)
|
||||
|
|
@ -11822,8 +11955,8 @@ void LLVOAvatar::calculateUpdateRenderComplexity()
|
|||
{
|
||||
accountRenderComplexityForObject(volp, max_attachment_complexity,
|
||||
// <FS:Ansariel> Show per-item complexity in COF
|
||||
//textures, cost, hud_complexity_list);
|
||||
textures, cost, hud_complexity_list, item_complexity, temp_item_complexity);
|
||||
//textures, cost, hud_complexity_list, object_complexity_list);
|
||||
textures, cost, hud_complexity_list, object_complexity_list, item_complexity, temp_item_complexity);
|
||||
// </FS:Ansariel>
|
||||
}
|
||||
}
|
||||
|
|
@ -11849,8 +11982,8 @@ void LLVOAvatar::calculateUpdateRenderComplexity()
|
|||
const LLViewerObject* attached_object = attachment_iter->get();
|
||||
accountRenderComplexityForObject(attached_object, max_attachment_complexity,
|
||||
// <FS:Ansariel> Show per-item complexity in COF
|
||||
//textures, cost, hud_complexity_list);
|
||||
textures, cost, hud_complexity_list, item_complexity, temp_item_complexity);
|
||||
//textures, cost, hud_complexity_list, object_complexity_list);
|
||||
textures, cost, hud_complexity_list, object_complexity_list, item_complexity, temp_item_complexity);
|
||||
// </FS:Ansariel>
|
||||
}
|
||||
}
|
||||
|
|
@ -11912,13 +12045,13 @@ void LLVOAvatar::calculateUpdateRenderComplexity()
|
|||
mVisualComplexity = cost;
|
||||
mVisualComplexityStale = false;
|
||||
|
||||
static LLCachedControl<U32> show_my_complexity_changes(gSavedSettings, "ShowMyComplexityChanges", 20);
|
||||
|
||||
if (isSelf() && show_my_complexity_changes)
|
||||
if (isSelf())
|
||||
{
|
||||
// Avatar complexity
|
||||
LLAvatarRenderNotifier::getInstance()->updateNotificationAgent(mVisualComplexity);
|
||||
|
||||
LLAvatarRenderNotifier::getInstance()->setObjectComplexityList(object_complexity_list);
|
||||
|
||||
// HUD complexity
|
||||
LLHUDRenderNotifier::getInstance()->updateNotificationHUD(hud_complexity_list);
|
||||
}
|
||||
|
|
@ -11937,6 +12070,7 @@ void LLVOAvatar::setVisualMuteSettings(VisualMuteSettings set)
|
|||
mVisuallyMuteSetting = set;
|
||||
mNeedsImpostorUpdate = TRUE;
|
||||
mLastImpostorUpdateReason = 7;
|
||||
markARTStale();// <FS:Beq> Force a refresh of the ART to take into account new setting.
|
||||
|
||||
// <FS:Ansariel> [FS Persisted Avatar Render Settings]
|
||||
//LLRenderMuteList::getInstance()->saveVisualMuteSetting(getID(), S32(set));
|
||||
|
|
@ -12089,7 +12223,7 @@ LLVOAvatar::AvatarOverallAppearance LLVOAvatar::getOverallAppearance() const
|
|||
}
|
||||
else // !isSelf()
|
||||
{
|
||||
if (isInMuteList())
|
||||
if (isInMuteList())
|
||||
{
|
||||
result = AOA_INVISIBLE;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -311,6 +311,7 @@ public:
|
|||
LLVOVolume::texture_cost_t& textures,
|
||||
U32& cost,
|
||||
hud_complexity_list_t& hud_complexity_list,
|
||||
object_complexity_list_t& object_complexity_list,
|
||||
// <FS:Ansariel> Show per-item complexity in COF
|
||||
std::map<LLUUID, U32>& item_complexity,
|
||||
std::map<LLUUID, U32>& temp_item_complexity);
|
||||
|
|
@ -354,6 +355,7 @@ public:
|
|||
static F32 sPhysicsLODFactor; // user-settable physics LOD factor
|
||||
static BOOL sJointDebug; // output total number of joints being touched for each avatar
|
||||
static BOOL sDebugAvatarRotation;
|
||||
static U64 sRenderTimeLimit_ns; // <FS:Beq/> nanosecond time limit for avatar rendering 0 is unlimited.
|
||||
static LLPartSysData sCloud;
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
|
|
@ -367,6 +369,17 @@ public:
|
|||
//--------------------------------------------------------------------
|
||||
public:
|
||||
BOOL isFullyLoaded() const;
|
||||
// <FS:Beq> check and return current state relative to limits
|
||||
// default will test only the geometry (combined=false).
|
||||
// this allows us to disable shadows separately on complex avatars.
|
||||
inline bool isTooSlowWithShadows() const {return mTooSlow;};
|
||||
inline bool isTooSlowWithoutShadows() const {return mTooSlowWithoutShadows;};
|
||||
inline bool isTooSlow(bool combined = false) const
|
||||
{
|
||||
return(combined?mTooSlow:mTooSlowWithoutShadows);
|
||||
}
|
||||
void updateTooSlow();
|
||||
// </FS:Beq>
|
||||
virtual bool isTooComplex() const; // <FS:Ansariel> FIRE-29012: Standalone animesh avatars get affected by complexity limit; changed to virtual
|
||||
bool visualParamWeightsAreDefault();
|
||||
virtual bool getIsCloud() const;
|
||||
|
|
@ -388,6 +401,7 @@ public:
|
|||
void logMetricsTimerRecord(const std::string& phase_name, F32 elapsed, bool completed);
|
||||
|
||||
void calcMutedAVColor();
|
||||
void markARTStale();
|
||||
|
||||
protected:
|
||||
LLViewerStats::PhaseMap& getPhases() { return mPhases; }
|
||||
|
|
@ -405,6 +419,15 @@ private:
|
|||
LLColor4 mMutedAVColor;
|
||||
LLFrameTimer mFullyLoadedTimer;
|
||||
LLFrameTimer mRuthTimer;
|
||||
U32 mLastARTUpdateFrame{0};
|
||||
U64 mRenderTime{0};
|
||||
U64 mGeomTime{0};
|
||||
bool mARTStale{true};
|
||||
bool mARTCapped{false};
|
||||
// <FS:Beq> variables to hold "slowness" status
|
||||
bool mTooSlow{false};
|
||||
bool mTooSlowWithoutShadows{false};
|
||||
// </FS:Beq>
|
||||
|
||||
private:
|
||||
LLViewerStats::PhaseMap mPhases;
|
||||
|
|
@ -1188,6 +1211,8 @@ public:
|
|||
// COF version of last appearance message received for this av.
|
||||
S32 mLastUpdateReceivedCOFVersion;
|
||||
|
||||
U64 getLastART() const { return mRenderTime; }
|
||||
|
||||
/** Diagnostics
|
||||
** **
|
||||
*******************************************************************************/
|
||||
|
|
|
|||
|
|
@ -91,6 +91,7 @@
|
|||
#include "rlvlocks.h"
|
||||
// [/RLVa:KB]
|
||||
#include "llviewernetwork.h"
|
||||
#include "fsperfstats.h" // <FS:Beq> performance stats support
|
||||
|
||||
const F32 FORCE_SIMPLE_RENDER_AREA = 512.f;
|
||||
const F32 FORCE_CULL_AREA = 8.f;
|
||||
|
|
@ -5545,7 +5546,7 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep,
|
|||
}
|
||||
}
|
||||
|
||||
if (type == LLRenderPass::PASS_ALPHA)
|
||||
// if (type == LLRenderPass::PASS_ALPHA) // <FS:Beq> allow tracking through pipeline
|
||||
{ //for alpha sorting
|
||||
facep->setDrawInfo(draw_info);
|
||||
}
|
||||
|
|
@ -5761,6 +5762,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
|
|||
LL_RECORD_BLOCK_TIME(FTM_REBUILD_VOLUME_FACE_LIST);
|
||||
|
||||
//get all the faces into a list
|
||||
std::unique_ptr<FSPerfStats::RecordAttachmentTime> ratPtr{}; // <FS:Beq/> render time capture
|
||||
for (LLSpatialGroup::element_iter drawable_iter = group->getDataBegin();
|
||||
drawable_iter != group->getDataEnd(); ++drawable_iter)
|
||||
{
|
||||
|
|
@ -5783,6 +5785,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
|
|||
continue;
|
||||
}
|
||||
|
||||
|
||||
//<FS:Beq> Stop doing stupid stuff we don;t need to.
|
||||
// Moving this inside a debug enabled check
|
||||
// std::string vobj_name = llformat("Vol%p", vobj);
|
||||
|
|
@ -5793,6 +5796,12 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
|
|||
{
|
||||
continue;
|
||||
}
|
||||
// <FS:Beq> Capture render times
|
||||
if(vobj->isAttachment())
|
||||
{
|
||||
trackAttachments( vobj, drawablep->isState(LLDrawable::RIGGED),&ratPtr);
|
||||
}
|
||||
// </FS:Beq>
|
||||
|
||||
LLVolume* volume = vobj->getVolume();
|
||||
if (volume)
|
||||
|
|
@ -6360,7 +6369,7 @@ static LLTrace::BlockTimerStatHandle FTM_REBUILD_MESH_FLUSH("Flush Mesh");
|
|||
void LLVolumeGeometryManager::rebuildMesh(LLSpatialGroup* group)
|
||||
{
|
||||
llassert(group);
|
||||
LL_RECORD_BLOCK_TIME(FTM_REBUILD_VOLUME_VB);// <FS:Beq> move out one scope (but are these even useful as dupes?)
|
||||
// LL_RECORD_BLOCK_TIME(FTM_REBUILD_VOLUME_VB);// <FS:Beq> High volume remove (roughly 1000:1 ratio to inside the if statement)
|
||||
if (group && group->hasState(LLSpatialGroup::MESH_DIRTY) && !group->hasState(LLSpatialGroup::GEOM_DIRTY))
|
||||
{
|
||||
LL_RECORD_BLOCK_TIME(FTM_REBUILD_VOLUME_VB);
|
||||
|
|
@ -6381,13 +6390,21 @@ void LLVolumeGeometryManager::rebuildMesh(LLSpatialGroup* group)
|
|||
|
||||
U32 buffer_count = 0;
|
||||
|
||||
std::unique_ptr<FSPerfStats::RecordAttachmentTime> ratPtr{}; // <FS:Beq/> capture render times
|
||||
for (LLSpatialGroup::element_iter drawable_iter = group->getDataBegin(); drawable_iter != group->getDataEnd(); ++drawable_iter)
|
||||
{
|
||||
LLDrawable* drawablep = (LLDrawable*)(*drawable_iter)->getDrawable();
|
||||
|
||||
if (drawablep && !drawablep->isDead() && drawablep->isState(LLDrawable::REBUILD_ALL) && !drawablep->isState(LLDrawable::RIGGED) )
|
||||
{
|
||||
LL_PROFILE_ZONE_NAMED("Rebuild all non-Rigged");
|
||||
LLVOVolume* vobj = drawablep->getVOVolume();
|
||||
// <FS:Beq> capture render times
|
||||
if( vobj && vobj->isAttachment() )
|
||||
{
|
||||
trackAttachments( vobj, drawablep->isState(LLDrawable::RIGGED), &ratPtr );
|
||||
}
|
||||
// </FS:Beq>
|
||||
//<FS:Beq> avoid unfortunate sleep during trylock by static check
|
||||
//if(debugLoggingEnabled("AnimatedObjectsLinkset"))
|
||||
static auto debug_logging_on = debugLoggingEnabled("AnimatedObjectsLinkset");
|
||||
|
|
@ -6801,10 +6818,18 @@ U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace
|
|||
U32 indices_index = 0;
|
||||
U16 index_offset = 0;
|
||||
|
||||
std::unique_ptr<FSPerfStats::RecordAttachmentTime> ratPtr; // <FS:Beq/> capture render times
|
||||
while (face_iter < i)
|
||||
{
|
||||
//update face indices for new buffer
|
||||
facep = *face_iter;
|
||||
LLViewerObject* vobj = facep->getViewerObject();
|
||||
// <FS:Beq> capture render times
|
||||
if(vobj && vobj->isAttachment())
|
||||
{
|
||||
trackAttachments(vobj, LLPipeline::sShadowRender, &ratPtr);
|
||||
}
|
||||
// </FS:Beq>
|
||||
if (buffer.isNull())
|
||||
{
|
||||
// Bulk allocation failed
|
||||
|
|
@ -7020,8 +7045,12 @@ U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace
|
|||
else if (is_alpha)
|
||||
{
|
||||
// can we safely treat this as an alpha mask?
|
||||
if (facep->getFaceColor().mV[3] <= 0.f)
|
||||
// <FS:Beq> Nothing actually sets facecolor use the TE alpha instead.
|
||||
// if (facep->getFaceColor().mV[3] <= 0.f)
|
||||
if (te->getAlpha() <=0.f || facep->getFaceColor().mV[3] <= 0.f)
|
||||
// </FS:Beq>
|
||||
{ //100% transparent, don't render unless we're highlighting transparent
|
||||
LL_PROFILE_ZONE_NAMED("facep->alpha -> invisible");
|
||||
registerFace(group, facep, LLRenderPass::PASS_ALPHA_INVISIBLE);
|
||||
}
|
||||
else if (facep->canRenderAsMask())
|
||||
|
|
|
|||
|
|
@ -370,6 +370,7 @@ bool LLPipeline::sReflectionRender = false;
|
|||
bool LLPipeline::sDistortionRender = false;
|
||||
bool LLPipeline::sImpostorRender = false;
|
||||
bool LLPipeline::sImpostorRenderAlphaDepthPass = false;
|
||||
bool LLPipeline::sShowJellyDollAsImpostor = true;
|
||||
bool LLPipeline::sUnderWaterRender = false;
|
||||
bool LLPipeline::sTextureBindTest = false;
|
||||
bool LLPipeline::sRenderFrameTest = false;
|
||||
|
|
@ -1195,6 +1196,7 @@ void LLPipeline::refreshCachedSettings()
|
|||
LLPipeline::sAutoMaskAlphaDeferred = gSavedSettings.getBOOL("RenderAutoMaskAlphaDeferred");
|
||||
LLPipeline::sAutoMaskAlphaNonDeferred = gSavedSettings.getBOOL("RenderAutoMaskAlphaNonDeferred");
|
||||
LLPipeline::sUseFarClip = gSavedSettings.getBOOL("RenderUseFarClip");
|
||||
LLPipeline::sShowJellyDollAsImpostor = gSavedSettings.getBOOL("RenderJellyDollsAsImpostors");
|
||||
LLVOAvatar::sMaxNonImpostors = gSavedSettings.getU32("RenderAvatarMaxNonImpostors");
|
||||
LLVOAvatar::updateImpostorRendering(LLVOAvatar::sMaxNonImpostors);
|
||||
LLPipeline::sDelayVBUpdate = gSavedSettings.getBOOL("RenderDelayVBUpdate");
|
||||
|
|
@ -2829,6 +2831,7 @@ void LLPipeline::doOcclusion(LLCamera& camera, LLRenderTarget& source, LLRenderT
|
|||
|
||||
void LLPipeline::doOcclusion(LLCamera& camera)
|
||||
{
|
||||
LL_PROFILE_ZONE_NAMED("doOcclusion");
|
||||
if (LLPipeline::sUseOcclusion > 1 && !LLSpatialPartition::sTeleportRequested &&
|
||||
(sCull->hasOcclusionGroups() || LLVOCachePartition::sNeedsOcclusionCheck))
|
||||
{
|
||||
|
|
@ -3544,6 +3547,8 @@ void LLPipeline::stateSort(LLCamera& camera, LLCullResult &result)
|
|||
//LLVertexBuffer::unbind();
|
||||
|
||||
grabReferences(result);
|
||||
{
|
||||
LL_PROFILE_ZONE_NAMED("checkOcclusionAndRebuildMesh");
|
||||
for (LLCullResult::sg_iterator iter = sCull->beginDrawableGroups(); iter != sCull->endDrawableGroups(); ++iter)
|
||||
{
|
||||
LLSpatialGroup* group = *iter;
|
||||
|
|
@ -3567,9 +3572,11 @@ void LLPipeline::stateSort(LLCamera& camera, LLCullResult &result)
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (LLViewerCamera::sCurCameraID == LLViewerCamera::CAMERA_WORLD)
|
||||
{
|
||||
LL_PROFILE_ZONE_NAMED("WorldCamera");
|
||||
LLSpatialGroup* last_group = NULL;
|
||||
BOOL fov_changed = LLViewerCamera::getInstance()->isDefaultFOVChanged();
|
||||
for (LLCullResult::bridge_iterator i = sCull->beginVisibleBridge(); i != sCull->endVisibleBridge(); ++i)
|
||||
|
|
@ -3603,7 +3610,8 @@ void LLPipeline::stateSort(LLCamera& camera, LLCullResult &result)
|
|||
last_group->mLastUpdateDistance = last_group->mDistance;
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
LL_PROFILE_ZONE_NAMED("StateSort: visible groups");
|
||||
for (LLCullResult::sg_iterator iter = sCull->beginVisibleGroups(); iter != sCull->endVisibleGroups(); ++iter)
|
||||
{
|
||||
LLSpatialGroup* group = *iter;
|
||||
|
|
@ -3622,7 +3630,7 @@ void LLPipeline::stateSort(LLCamera& camera, LLCullResult &result)
|
|||
group->rebuildMesh();
|
||||
}
|
||||
}
|
||||
}
|
||||
}}
|
||||
|
||||
{
|
||||
LL_RECORD_BLOCK_TIME(FTM_STATESORT_DRAWABLE);
|
||||
|
|
@ -3978,6 +3986,8 @@ void LLPipeline::postSort(LLCamera& camera)
|
|||
|
||||
LL_PUSH_CALLSTACKS();
|
||||
//rebuild drawable geometry
|
||||
{
|
||||
LL_PROFILE_ZONE_NAMED("PostSort: rebuildGeom");
|
||||
for (LLCullResult::sg_iterator i = sCull->beginDrawableGroups(); i != sCull->endDrawableGroups(); ++i)
|
||||
{
|
||||
LLSpatialGroup* group = *i;
|
||||
|
|
@ -3996,6 +4006,8 @@ void LLPipeline::postSort(LLCamera& camera)
|
|||
|
||||
|
||||
//build render map
|
||||
{
|
||||
LL_PROFILE_ZONE_NAMED("build render map");
|
||||
for (LLCullResult::sg_iterator i = sCull->beginVisibleGroups(); i != sCull->endVisibleGroups(); ++i)
|
||||
{
|
||||
LLSpatialGroup* group = *i;
|
||||
|
|
@ -4041,6 +4053,7 @@ void LLPipeline::postSort(LLCamera& camera)
|
|||
|
||||
if (hasRenderType(LLPipeline::RENDER_TYPE_PASS_ALPHA))
|
||||
{
|
||||
LL_PROFILE_ZONE_NAMED("Collect Alpha groups");
|
||||
LLSpatialGroup::draw_map_t::iterator alpha = group->mDrawMap.find(LLRenderPass::PASS_ALPHA);
|
||||
|
||||
if (alpha != group->mDrawMap.end())
|
||||
|
|
@ -4066,6 +4079,7 @@ void LLPipeline::postSort(LLCamera& camera)
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//flush particle VB
|
||||
if (LLVOPartGroup::sVB)
|
||||
|
|
@ -4091,12 +4105,15 @@ void LLPipeline::postSort(LLCamera& camera)
|
|||
|
||||
glBeginQueryARB(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN, mMeshDirtyQueryObject);
|
||||
}*/
|
||||
|
||||
{
|
||||
LL_PROFILE_ZONE_NAMED("rebuild delayed upd groups");
|
||||
//pack vertex buffers for groups that chose to delay their updates
|
||||
for (LLSpatialGroup::sg_vector_t::iterator iter = mMeshDirtyGroup.begin(); iter != mMeshDirtyGroup.end(); ++iter)
|
||||
{
|
||||
(*iter)->rebuildMesh();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*if (use_transform_feedback)
|
||||
{
|
||||
|
|
@ -4105,12 +4122,17 @@ void LLPipeline::postSort(LLCamera& camera)
|
|||
|
||||
mMeshDirtyGroup.clear();
|
||||
|
||||
{
|
||||
LL_PROFILE_ZONE_NAMED("sort alpha groups");
|
||||
if (!sShadowRender)
|
||||
{
|
||||
std::sort(sCull->beginAlphaGroups(), sCull->endAlphaGroups(), LLSpatialGroup::CompareDepthGreater());
|
||||
}
|
||||
}
|
||||
|
||||
LL_PUSH_CALLSTACKS();
|
||||
{
|
||||
LL_PROFILE_ZONE_NAMED("beacon rendering flags");
|
||||
// only render if the flag is set. The flag is only set if we are in edit mode or the toggle is set in the menus
|
||||
// Ansariel: Make beacons also show when beacons floater is closed.
|
||||
if (/*LLFloaterReg::instanceVisible("beacons") &&*/ !sShadowRender)
|
||||
|
|
@ -4164,6 +4186,7 @@ void LLPipeline::postSort(LLCamera& camera)
|
|||
forAllVisibleDrawables(renderSoundHighlights);
|
||||
}
|
||||
}
|
||||
}
|
||||
LL_PUSH_CALLSTACKS();
|
||||
// If managing your telehub, draw beacons at telehub and currently selected spawnpoint.
|
||||
if (LLFloaterTelehub::renderBeacons())
|
||||
|
|
@ -4173,6 +4196,7 @@ void LLPipeline::postSort(LLCamera& camera)
|
|||
|
||||
if (!sShadowRender)
|
||||
{
|
||||
LL_PROFILE_ZONE_NAMED("Render face highlights");
|
||||
mSelectedFaces.clear();
|
||||
|
||||
LLPipeline::setRenderHighlightTextureChannel(gFloaterTools->getPanelFace()->getTextureChannelToEdit());
|
||||
|
|
@ -11248,9 +11272,11 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar)
|
|||
<< " is " << ( too_complex ? "" : "not ") << "too complex"
|
||||
<< LL_ENDL;
|
||||
|
||||
bool too_slow = avatar->isTooSlowWithoutShadows(); // <FS:Beq/> only if we really have to do we imposter.
|
||||
|
||||
pushRenderTypeMask();
|
||||
|
||||
if (visually_muted || too_complex)
|
||||
if ( !too_slow && ( visually_muted || too_complex ) )
|
||||
{
|
||||
andRenderTypeMask(LLPipeline::RENDER_TYPE_AVATAR,
|
||||
LLPipeline::RENDER_TYPE_CONTROL_AV,
|
||||
|
|
|
|||
|
|
@ -600,6 +600,7 @@ public:
|
|||
static bool sDistortionRender;
|
||||
static bool sImpostorRender;
|
||||
static bool sImpostorRenderAlphaDepthPass;
|
||||
static bool sShowJellyDollAsImpostor;
|
||||
static bool sUnderWaterRender;
|
||||
static bool sRenderGlow;
|
||||
static bool sTextureBindTest;
|
||||
|
|
|
|||
|
|
@ -1318,6 +1318,12 @@
|
|||
<color
|
||||
name="OutfitGalleryItemUnselected"
|
||||
value="0.4 0.4 0.4 1" />
|
||||
<color
|
||||
name="PanelGray"
|
||||
value="0.27 0.27 0.27 1" />
|
||||
<color
|
||||
name="PerformanceMid"
|
||||
value="1 0.8 0 1" />
|
||||
|
||||
<!-- <FS:CR> Script Editor Colors -->
|
||||
<color
|
||||
|
|
|
|||
|
|
@ -1315,6 +1315,12 @@
|
|||
<color
|
||||
name="OutfitGalleryItemUnselected"
|
||||
value="0.4 0.4 0.4 1" />
|
||||
<color
|
||||
name="PanelGray"
|
||||
value="0.27 0.27 0.27 1" />
|
||||
<color
|
||||
name="PerformanceMid"
|
||||
value="1 0.8 0 1" />
|
||||
|
||||
<!-- <FS:CR> Script Editor Colors -->
|
||||
<color
|
||||
|
|
|
|||
|
|
@ -1270,8 +1270,11 @@
|
|||
name="OutfitGalleryItemUnselected"
|
||||
value="0.4 0.4 0.4 1" />
|
||||
<color
|
||||
name="AddPaymentPanel"
|
||||
name="PanelGray"
|
||||
value="0.27 0.27 0.27 1" />
|
||||
<color
|
||||
name="PerformanceMid"
|
||||
value="1 0.8 0 1" />
|
||||
|
||||
<!-- <FS:CR> Script Editor Colors -->
|
||||
<color
|
||||
|
|
|
|||
|
|
@ -158,6 +158,7 @@ with the same filename but different name
|
|||
<texture name="Command_Move_Icon" file_name="toolbar_icons/move.png" preload="true" />
|
||||
<texture name="Command_Environments_Icon" file_name="toolbar_icons/environments.png" preload="true" />
|
||||
<texture name="Command_People_Icon" file_name="toolbar_icons/people.png" preload="true" />
|
||||
<texture name="Command_Performance_Icon" file_name="toolbar_icons/performance.png" preload="true" />
|
||||
<texture name="Command_Picks_Icon" file_name="toolbar_icons/picks.png" preload="true" />
|
||||
<texture name="Command_Places_Icon" file_name="toolbar_icons/places.png" preload="true" />
|
||||
<texture name="Command_Preferences_Icon" file_name="toolbar_icons/preferences.png" preload="true" />
|
||||
|
|
|
|||
Binary file not shown.
|
After Width: | Height: | Size: 451 B |
|
|
@ -1,12 +1,12 @@
|
|||
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
|
||||
<floater name="floater_avatar_render_settings" title="EINSTELLUNGEN ZUR DARSTELLUNG VON AVATAREN">
|
||||
<floater name="floater_avatar_render_settings" title="Ausnahmen Avatardarstellung">
|
||||
<string name="av_never_render" value="Nie"/>
|
||||
<string name="av_always_render" value="Immer"/>
|
||||
<filter_editor label="Nach Personen filtern" name="people_filter_input"/>
|
||||
<menu_button name="plus_btn" tool_tip="Aktionen für ausgewählte Person"/>
|
||||
<name_list name="render_settings_list">
|
||||
<name_list.columns label="Name" name="name"/>
|
||||
<name_list.columns label="Darstellungseinstellung" name="setting"/>
|
||||
<name_list.columns label="Hinzugefügt am" name="timestamp"/>
|
||||
<name_list.columns label="Komplette Details" name="setting"/>
|
||||
</name_list>
|
||||
<panel name="add_subpanel">
|
||||
<menu_button name="plus_btn" label="Hinzufügen..." tool_tip="Aktionen für ausgewählte Person"/>
|
||||
</panel>
|
||||
</floater>
|
||||
|
|
|
|||
|
|
@ -1,16 +1,16 @@
|
|||
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
|
||||
<floater name="avatarrendersettings" title="Avatar-Anzeigeeinstellungen">
|
||||
<floater name="avatarrendersettings" title="Avatar-Anzeigeausnahmen">
|
||||
<floater.string name="av_render_never">
|
||||
Niemals
|
||||
</floater.string>
|
||||
<floater.string name="av_render_always">
|
||||
Komplett
|
||||
Immer
|
||||
</floater.string>
|
||||
<filter_editor label="Avatare filtern" name="filter_input"/>
|
||||
<menu_button name="plus_btn" tool_tip="Person zur Liste hinzufügen"/>
|
||||
<name_list name="avatar_list">
|
||||
<name_list.columns label="Name" name="name"/>
|
||||
<name_list.columns label="Anzeigeeinstellung" name="render_setting" width="125"/>
|
||||
<name_list.columns label="Komplette Details" name="render_setting" width="125"/>
|
||||
</name_list>
|
||||
<button name="close_btn" label="Schließen"/>
|
||||
</floater>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,98 @@
|
|||
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
|
||||
<floater name="performance" title="Grafik-Performance-Verbesserung (experimentell)">
|
||||
<floater.string name="frame_stats">
|
||||
Frame: [TOT_FRAME_TIME]ms - Szenerie:[SCENERY_FRAME_PCT]% Avatare:[AV_FRAME_PCT]% UI:[UI_FRAME_PCT]% HUDs:[HUDS_FRAME_PCT]% Swap:[SWAP_FRAME_PCT]% Tasks:[IDLE_FRAME_PCT]%
|
||||
</floater.string>
|
||||
<floater.string name="limit_fps">
|
||||
FPS limitiert auf [FPSCAP] FPS
|
||||
</floater.string>
|
||||
<floater.string name="tuning_fps">
|
||||
Auto-Anpassung-Ziel [FPSTARGET] FPS
|
||||
</floater.string>
|
||||
<floater.string name="av_frame_pct">
|
||||
[AV_FRAME_PCT]%
|
||||
</floater.string>
|
||||
<floater.string name="huds_frame_pct">
|
||||
[HUDS_FRAME_PCT]%
|
||||
</floater.string>
|
||||
<floater.string name="focus_fps">
|
||||
Im Hintergrund
|
||||
</floater.string>
|
||||
<floater.string name="tot_av_template">
|
||||
Gesamt: [TOT_AV] ([TOT_AV_TIME]μs)
|
||||
</floater.string>
|
||||
<floater.string name="tot_att_template">
|
||||
Gesamt: [TOT_ATT] ([TOT_ATT_TIME]μs)
|
||||
</floater.string>
|
||||
<panel name="panel_top">
|
||||
<panel name="fps_subpanel">
|
||||
<text name="fps_lbl">
|
||||
Bilder pro Sekunde
|
||||
</text>
|
||||
<text name="fps_desc1_lbl">
|
||||
5-10 Sekunden warten auf Effekt der Anpassungen.
|
||||
</text>
|
||||
<text name="frame_breakdown">
|
||||
Frame-Aufschlüsselung erfolgt hier.
|
||||
</text>
|
||||
</panel>
|
||||
<panel name="target_subpanel">
|
||||
<text name="settings_lbl">
|
||||
Auto-Anpassung Ziel-FPS
|
||||
</text>
|
||||
<check_box label="Auto-Anpassung" name="AutoTuneFPS" tool_tip="Der Viewer wird automatisch versuchen, die Ziel-FPS zu erreichen." />
|
||||
<text name="settings_desc">
|
||||
Einstellungen automatisch für FPS anpassen.
|
||||
</text>
|
||||
<combo_box name="FSTuningFPSStrategy">
|
||||
<combo_box.item label="Nur Avatar-Einstellungen" name="av_only" />
|
||||
<combo_box.item label="Avatar und Szenerie" name="av_and_scene" />
|
||||
</combo_box>
|
||||
<spinner name="target_fps" tooltip="Ziel-FPS - Der Viewer wird automatisch versuchen, die gewünschte FPS durch Anpassung der Einstellungen zu erreichen." />
|
||||
</panel>
|
||||
</panel>
|
||||
<panel name="panel_performance_main">
|
||||
<panel name="settings_subpanel">
|
||||
<text name="settings_lbl">
|
||||
Grafik-Einstellungen
|
||||
</text>
|
||||
<text name="settings_desc">
|
||||
Einstellungen für Distanz, Wasser, Beleuchtung uvm.
|
||||
</text>
|
||||
</panel>
|
||||
<panel name="nearby_subpanel">
|
||||
<text name="avatars_nearby_lbl">
|
||||
Avatar in der Nähe
|
||||
</text>
|
||||
<text name="avatars_nearby_desc">
|
||||
Einstellen, welche Avatare vollständig dargestellt werden.
|
||||
</text>
|
||||
<text name="avatars_frme_pct_lbl">
|
||||
Benötigte
|
||||
Renderzeit
|
||||
für Avatare
|
||||
</text>
|
||||
</panel>
|
||||
<panel name="complexity_subpanel">
|
||||
<text name="complexity_lbl">
|
||||
Eigene Avatar-Komplexität
|
||||
</text>
|
||||
<text name="complexity_info">
|
||||
Sei ein guter Einwohner - verwalte den Einfluss des eigenen Avatars.
|
||||
</text>
|
||||
</panel>
|
||||
<panel name="huds_subpanel">
|
||||
<text name="huds_lbl">
|
||||
Aktive HUDs
|
||||
</text>
|
||||
<text name="huds_desc">
|
||||
Entfernen von HUDs kann Geschwindigkeit verbessern.
|
||||
</text>
|
||||
<text name="huds_frme_pct_lbl">
|
||||
Benötigte
|
||||
Renderzeit
|
||||
für HUDs
|
||||
</text>
|
||||
</panel>
|
||||
</panel>
|
||||
</floater>
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
|
||||
<floater name="prefs_graphics_advanced" title="ERWEITERTE GRAFIKEINSTELLUNGEN">
|
||||
<floater name="prefs_graphics_advanced" title="Erweiterte Grafikeinstellungen">
|
||||
<text name="GeneralText">
|
||||
Allgemein
|
||||
</text>
|
||||
|
|
|
|||
|
|
@ -22,9 +22,9 @@
|
|||
<menu_item_call label="Hineinzoomen" name="Zoom In"/>
|
||||
<menu_item_call label="Bezahlen" name="Pay..."/>
|
||||
<menu_item_call label="Objektprofil" name="Object Inspect"/>
|
||||
<menu_item_check label="Normal darstellen" name="RenderNormally"/>
|
||||
<menu_item_check label="Nicht darstellen" name="DoNotRender"/>
|
||||
<menu_item_check label="Komplett darstellen" name="AlwaysRenderFully"/>
|
||||
<menu_item_check label="Immer komplett darstellen" name="AlwaysRenderFully"/>
|
||||
<menu_item_check label="Nie komplett darstellen" name="DoNotRender"/>
|
||||
<menu_item_check label="Darstellungsausnahme entfernen" name="RenderNormally"/>
|
||||
<menu_item_call label="Partikeleigentümer blockieren" name="Mute Particle"/>
|
||||
<menu_item_call label="Untersuchen" name="Object_Inspect_Floater"/>
|
||||
<menu_item_call label="Skript-Info" name="ScriptInfo"/>
|
||||
|
|
|
|||
|
|
@ -21,9 +21,9 @@
|
|||
<menu_item_call label="XML ausgeben" name="Dump XML"/>
|
||||
<menu_item_call label="Hineinzoomen" name="Zoom In"/>
|
||||
<menu_item_call label="Bezahlen" name="Pay..."/>
|
||||
<menu_item_check label="Normal darstellen" name="RenderNormally"/>
|
||||
<menu_item_check label="Nicht darstellen" name="DoNotRender"/>
|
||||
<menu_item_check label="Komplett darstellen" name="AlwaysRenderFully"/>
|
||||
<menu_item_check label="Immer komplett darstellen" name="AlwaysRenderFully"/>
|
||||
<menu_item_check label="Nie komplett darstellen" name="DoNotRender"/>
|
||||
<menu_item_check label="Darstellungsausnahme entfernen" name="RenderNormally"/>
|
||||
<menu_item_call label="Nicht anzeigen" name="Derender"/>
|
||||
<menu_item_call label="Nicht anzeigen & Blacklist" name="DerenderPermanent"/>
|
||||
<menu_item_call label="Skript-Info" name="ScriptInfo"/>
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
|
||||
<context_menu name="Settings">
|
||||
<menu_item_check label="Standard" name="default"/>
|
||||
<menu_item_check label="Immer darstellen" name="always_render"/>
|
||||
<menu_item_check label="Nie darstellen" name="never_render"/>
|
||||
<menu_item_check label="Immer komplett darstellen" name="always_render"/>
|
||||
<menu_item_check label="Nie komplett darstellen" name="never_render"/>
|
||||
<menu_item_check label="Von Ausnahmen entfernen" name="default"/>
|
||||
</context_menu>
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
|
||||
<toggleable_menu name="menu_settings_add.xml">
|
||||
<menu_item_call label="Einwohner immer darstellen..." name="add_avatar_always_render"/>
|
||||
<menu_item_call label="Einwohner nie darstellen..." name="add_avatar_never_render"/>
|
||||
<menu_item_call label="Einwohner immer komplett darstellen..." name="add_avatar_always_render"/>
|
||||
<menu_item_call label="Einwohner nie komplett darstellen..." name="add_avatar_never_render"/>
|
||||
</toggleable_menu>
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
|
||||
<context_menu name="Avatar Render Settings Menu">
|
||||
<menu_item_call label="Normal darstellen (entfernt von Liste)" name="av_render_normal"/>
|
||||
<menu_item_call label="Nicht darstellen" name="av_render_never"/>
|
||||
<menu_item_call label="Komplett darstellen" name="av_render_always"/>
|
||||
<menu_item_call label="Immer komplett darstellen" name="av_render_always"/>
|
||||
<menu_item_call label="Nie komplett darstellen" name="av_render_never"/>
|
||||
<menu_item_call label="Ausnahme entfernen" name="av_render_normal"/>
|
||||
</context_menu>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,8 @@
|
|||
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
|
||||
<context_menu name="Settings">
|
||||
<menu_item_check label="Immer komplett darstellen" name="always_render" />
|
||||
<menu_item_check label="Nie komplett darstellen" name="never_render" />
|
||||
<menu_item_check label="Darstellungsausnahme entfernen" name="default" />
|
||||
<menu_item_call label="Avatar untersuchen" name="inspect" />
|
||||
<menu_item_call label="Avatar heranzoomen" name="zoom" />
|
||||
</context_menu>
|
||||
|
|
@ -136,6 +136,7 @@
|
|||
<menu_item_check label="Koordinaten" name="Coordinates"/>
|
||||
<menu_item_check label="Parzelleneigenschaften" name="Parcel Properties"/>
|
||||
<menu_item_check label="Menü „Erweitert“" name="Show Advanced Menu"/>
|
||||
<menu_item_check label="Grafikgeschwindigkeit verbessern..." name="Performance"/>
|
||||
</menu>
|
||||
<menu_item_call label="Nach Hause teleportieren" name="Teleport Home"/>
|
||||
<menu_item_call label="Diesen Ort als Zuhause festlegen" name="Set Home to Here"/>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,35 @@
|
|||
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
|
||||
<panel name="panel_performance_autotune">
|
||||
<text name="back_lbl">
|
||||
Zurück
|
||||
</text>
|
||||
<text name="settings_title">
|
||||
Auto-Anpassung-Einstellungen
|
||||
</text>
|
||||
<text name="quality_lbl">
|
||||
Entfernteste Avatare
|
||||
</text>
|
||||
<check_box label="Distanz-basierte Optimierung" name="FSAutoTuneImpostorByDistEnabled" tool_tip="Falls aktiviert wird die Einstellung MaxNonImpostors angepasst, um komplett dargestellte Avatare auf den angegebenen Radius zu beschränken." />
|
||||
<spinner label="Entferntester kompl. Avatar" name="ffa_autotune" />
|
||||
<text name="distant_av_advice">
|
||||
Avatare in größerer Entfernung haben weiterhin einen hohen Einfluss.
|
||||
Entfernung von der Kamera setzen, ab dem ein Avatar optimiert wird.
|
||||
</text>
|
||||
<text name="distance_lbl">
|
||||
Sichtweiten-
|
||||
Tuning-Limit
|
||||
</text>
|
||||
<spinner label="Minimale Distanz" name="min_dd_autotune" />
|
||||
<spinner label="Präferierte Distanz" name="pref_dd_autotune" />
|
||||
<text name="distance_desc1">
|
||||
Beim Anpassen der Szenerie-Parameter wird Auto-Anpassung die Sichtweite zwischen dem Minimum und der Präferenz optimieren.
|
||||
</text>
|
||||
<text name="sundry_lbl">
|
||||
Verschiedene Einstellungen
|
||||
</text>
|
||||
<check_box label="Optimierung von eigenem Avatar erlauben" name="alow_self_impostor" tool_tip="Falls aktiviert, kann der Viewer den eigenen Avatar als Impostor darstellen." />
|
||||
<check_box label="Optimierte Renderzeit anzeigen" name="show_tuned_art" tool_tip="Falls aktiviert, wird in der Zeit-Spalte die aktuelle Renderzeit und nicht die Renderzeit vor Optimierung angezeigt." />
|
||||
<text name="sundry_desc1">
|
||||
Diese Optionen kontrollieren eher subtile Einstellungen. In der Online-Hilfe finden sich weitere Informationen darüber, was diese genau bedeuten.
|
||||
</text>
|
||||
</panel>
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
|
||||
<panel name="panel_performance_complexity">
|
||||
<text name="back_lbl">
|
||||
Zurück
|
||||
</text>
|
||||
<text name="attachments_title">
|
||||
Avatar-Attachment-Komplexität
|
||||
</text>
|
||||
<text name="tot_att_count">
|
||||
Gesamt: 50 (120000.10μs)
|
||||
</text>
|
||||
<text name="attachments_desc1">
|
||||
Attachments machen den Avatar komplexer und langsamer zu rendern.
|
||||
</text>
|
||||
<text name="attachments_desc2">
|
||||
Dieses Fenster zeigt alle Attachments des eigenen Avatars.
|
||||
</text>
|
||||
<text name="attachments_desc3">
|
||||
Attachments können einfach ausgewählt und durch Klick auf „X“ entfernt werden.
|
||||
</text>
|
||||
<name_list name="obj_list">
|
||||
<name_list.columns label="Zeit (μs)" name="art_value" tool_tip="Benötigte Zeit in Millisekunden zum Rendern des Attachments." />
|
||||
<name_list.columns name="complex_value" tool_tip="Attachment-Komplexität (ARC)" />
|
||||
<name_list.columns label="Attachment-Name" tool_tip="Zum Entfernen auf „X“ klicken." name="name" />
|
||||
</name_list>
|
||||
</panel>
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
|
||||
<panel name="panel_performance_huds">
|
||||
<text name="back_lbl">
|
||||
Zurück
|
||||
</text>
|
||||
<text name="huds_title">
|
||||
Aktive HUDs
|
||||
</text>
|
||||
<text name="huds_desc1">
|
||||
Das Entfernen unbenötigter HUDs spart Speicher und kann den Viewer schneller machen.
|
||||
</text>
|
||||
<text name="huds_desc2">
|
||||
HUDs enthalten oftmals viele Skripte und erzeugen zudem Serverseitigen Lag.
|
||||
</text>
|
||||
<text name="huds_desc3">
|
||||
Hinweis: Minimieren-Buttons von HUDs entfernt diese nicht. Entfernen duch Klick auf „X“.
|
||||
</text>
|
||||
<name_list name="hud_list">
|
||||
<name_list.columns label="Zeit (μs)" name="art_value" tool_tip="Benötigte Zeit in Millisekunden zum Rendern des HUD." />
|
||||
<name_list.columns label="Name" tool_tip="Zum Entfernen auf „X“ klicken." name="name" />
|
||||
</name_list>
|
||||
</panel>
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
|
||||
<panel name="panel_performance_nearby">
|
||||
<text name="back_lbl">
|
||||
Zurück
|
||||
</text>
|
||||
<text name="av_nearby_title">
|
||||
Avatare in der Nähe
|
||||
</text>
|
||||
<text name="tot_av_count">
|
||||
Gesamt: 50 (120000.10μs)
|
||||
</text>
|
||||
<text name="av_nearby_desc">
|
||||
Komplexeste Avatare verstecken, um Geschwindigkeit zu erhören
|
||||
</text>
|
||||
<slider tool_tip="Definiert, aber welcher Komplexität ein Avatar als Impostor dargestellt wird" label="Max. Komplexität (K)" name="IndirectMaxComplexity" />
|
||||
<slider tool_tip="Definiert, aber wann ein Avatar als zu komplex zum Darstellen erachtet wird (Einheit: Mikrosekunden)" label="Max. Renderzeit (μs)" name="FSRenderAvatarMaxART" />
|
||||
<text name="FSRenderAvatarMaxARTText">
|
||||
Kein Limit
|
||||
</text>
|
||||
<name_list name="nearby_list">
|
||||
<name_list.columns tool_tip="Balkendiagram der benötigten Renderzeit (inkl. Auto-Anpassung) in Prozent, basierend auf dem Langsamsten." name="art_visual" />
|
||||
<name_list.columns tool_tip="Avatar-Renderzeit (ART). Tatsächlich benötigte Zeit in Mikrosekunden für die Darstellung des Avatars vor Auto-Anpassung." name="art_value" />
|
||||
<name_list.columns tool_tip="Avatar-Komplexität (ARC) basierend auf Standard-Berechnung." name="complex_value" />
|
||||
<name_list.columns tool_tip="Zeigt Auto-Anpassung: I = Impostor, S = Kein Schatten." name="state" />
|
||||
<name_list.columns label="Name" name="name"/>
|
||||
</name_list>
|
||||
<text name="av_nearby_desc2">
|
||||
Per Rechts-Klick auf einen Avatar kann auch die Darstellung angepasst werden.
|
||||
</text>
|
||||
<button label="Ausnahmen..." name="exceptions_btn" />
|
||||
<check_box label="Freunde immer komplett darstellen" name="display_friends" />
|
||||
<check_box label="Alle Avatare verstecken (Gut für Landschaftsaufnahmen) " name="hide_avatars" />
|
||||
<text name="name_tags_textbox">
|
||||
Avatar namen:
|
||||
</text>
|
||||
<radio_group name="name_tag_mode">
|
||||
<radio_item label="An" name="radio" />
|
||||
<radio_item label="Aus" name="radio2" />
|
||||
<radio_item label="Kurz anzeigen" name="radio3" />
|
||||
</radio_group>
|
||||
</panel>
|
||||
|
|
@ -0,0 +1,87 @@
|
|||
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
|
||||
<panel name="panel_performance_preferences">
|
||||
<text name="back_lbl">
|
||||
Zurück
|
||||
</text>
|
||||
<text name="settings_title">
|
||||
Grafik-Einstellungen
|
||||
</text>
|
||||
<text name="quality_lbl">
|
||||
Qualität vs. Geschwindigkeit
|
||||
</text>
|
||||
<text name="FasterText">
|
||||
Schnell
|
||||
</text>
|
||||
<text name="BetterText">
|
||||
Qualität
|
||||
</text>
|
||||
<text name="ShadersPrefText">
|
||||
Niedrig
|
||||
</text>
|
||||
<text name="ShadersPrefText2">
|
||||
Mittel
|
||||
</text>
|
||||
<text name="ShadersPrefText3">
|
||||
Hoch
|
||||
</text>
|
||||
<text name="ShadersPrefText4">
|
||||
Ultra
|
||||
</text>
|
||||
<text name="quality_desc">
|
||||
Auswahl einer Voreinstellung setzt alle manuellen Anpassungen zurück.
|
||||
</text>
|
||||
<text name="distance_lbl">
|
||||
Distanz Sichtbarkeit
|
||||
</text>
|
||||
<text name="faster_lbl">
|
||||
Schnell
|
||||
</text>
|
||||
<text name="farther_lbl">
|
||||
Weiter
|
||||
</text>
|
||||
<text name="distance_desc1">
|
||||
Für bessere Performance niedrig halten, Erhöhen für weitere Sichtbarkeit.
|
||||
</text>
|
||||
<text name="environment_lbl">
|
||||
Umgebung
|
||||
</text>
|
||||
<text name="enhancements_desc">
|
||||
Reduzieren / Entfernen von Schatten kann die FPS deutlich erhöhren,
|
||||
beeinflusst aber das Ambiente und Aussehen der Szenerie.
|
||||
</text>
|
||||
<text name="RenderShadowDetailText">
|
||||
Schatten-Quellen:
|
||||
</text>
|
||||
<combo_box name="ShadowDetail">
|
||||
<combo_box.item label="Keine" name="0" />
|
||||
<combo_box.item label="Sonne/Mond" name="1" />
|
||||
<combo_box.item label="Sonne/Mond + Projektoren" name="2" />
|
||||
</combo_box>
|
||||
<text name="water_lbl">
|
||||
Wasser
|
||||
</text>
|
||||
<text name="water_desc">
|
||||
Reduzieren der Wasser-Qualität kann die FPS deutlich erhöhen.
|
||||
</text>
|
||||
<text name="ReflectionsText">
|
||||
Wasser-Reflektionen:
|
||||
</text>
|
||||
<combo_box name="Reflections">
|
||||
<combo_box.item label="Keine (undurchsichtig)" name="-2" />
|
||||
<combo_box.item label="Keine (transparent)" name="-1" />
|
||||
<combo_box.item label="Minimal" name="0" />
|
||||
<combo_box.item label="Terrain und Bäume" name="1" />
|
||||
<combo_box.item label="Alle statischen Objekte" name="2" />
|
||||
<combo_box.item label="Alle Avatare und Objekte" name="3" />
|
||||
<combo_box.item label="Alles" name="4" />
|
||||
</combo_box>
|
||||
<text name="photo_lbl">
|
||||
Fotografie
|
||||
</text>
|
||||
<text name="photo_desc">
|
||||
Fotografen benötigen hohe Qualität, allerdings
|
||||
häuftig auf Kosten der Performance. Fototools
|
||||
können helfen, die richtige Balance zu finden.
|
||||
</text>
|
||||
<button name="open_phototools" label="Fototools" tool_tip="Öffnet dedizierte Fototools für fortgeschrittene Einstellungen." />
|
||||
</panel>
|
||||
|
|
@ -5902,6 +5902,9 @@ Setzen Sie den Editorpfad in Anführungszeichen
|
|||
<string name="Command_People_Label">
|
||||
Leute
|
||||
</string>
|
||||
<string name="Command_Performance_Label">
|
||||
Grafikgeschwindigkeit
|
||||
</string>
|
||||
<string name="Command_Picks_Label">
|
||||
Auswahlen
|
||||
</string>
|
||||
|
|
@ -6104,6 +6107,9 @@ Setzen Sie den Editorpfad in Anführungszeichen
|
|||
<string name="Command_People_Tooltip">
|
||||
Freunde, Gruppen und Leute in der Nähe
|
||||
</string>
|
||||
<string name="Command_Performance_Tooltip">
|
||||
Grafikgeschwindigkeit verbessern
|
||||
</string>
|
||||
<string name="Command_Picks_Tooltip">
|
||||
Orte, die in Ihrem Profil als Favoriten angezeigt werden sollen
|
||||
</string>
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@
|
|||
</floater.string>
|
||||
<panel
|
||||
background_opaque="false"
|
||||
bg_alpha_color="AddPaymentPanel"
|
||||
bg_alpha_color="PanelGray"
|
||||
border_visible="false"
|
||||
background_visible="true"
|
||||
label="wrapper_panel"
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@
|
|||
save_rect="true"
|
||||
single_instance="true"
|
||||
reuse_instance="true"
|
||||
title="AVATAR RENDER SETTINGS"
|
||||
title="Avatar Display Exceptions"
|
||||
width="300">
|
||||
<string
|
||||
name="av_never_render"
|
||||
|
|
@ -18,53 +18,45 @@
|
|||
<string
|
||||
name="av_always_render"
|
||||
value="Always"/>
|
||||
<filter_editor
|
||||
follows="left|top|right"
|
||||
height="23"
|
||||
layout="topleft"
|
||||
left="8"
|
||||
right="-47"
|
||||
label="Filter People"
|
||||
max_length_chars="300"
|
||||
name="people_filter_input"
|
||||
text_color="Black"
|
||||
text_pad_left="10"
|
||||
top="4" />
|
||||
<menu_button
|
||||
follows="top|right"
|
||||
height="25"
|
||||
image_hover_unselected="Toolbar_Middle_Over"
|
||||
image_overlay="AddItem_Off"
|
||||
image_selected="Toolbar_Middle_Selected"
|
||||
image_unselected="Toolbar_Middle_Off"
|
||||
layout="topleft"
|
||||
left_pad="7"
|
||||
menu_filename="menu_avatar_rendering_settings_add.xml"
|
||||
menu_position="bottomleft"
|
||||
name="plus_btn"
|
||||
tool_tip="Actions on selected person"
|
||||
top="3"
|
||||
width="31" />
|
||||
<name_list
|
||||
bottom="-8"
|
||||
bottom="-33"
|
||||
draw_heading="true"
|
||||
follows="all"
|
||||
left="8"
|
||||
multi_select="false"
|
||||
name="render_settings_list"
|
||||
right="-8"
|
||||
top="32">
|
||||
top="0">
|
||||
<name_list.columns
|
||||
label="Name"
|
||||
name="name"
|
||||
relative_width="0.5" />
|
||||
relative_width="0.65" />
|
||||
<name_list.columns
|
||||
label="Render setting"
|
||||
label="Full detail"
|
||||
name="setting"
|
||||
relative_width="0.25" />
|
||||
<name_list.columns
|
||||
label="Date added"
|
||||
name="timestamp"
|
||||
relative_width="0.25" />
|
||||
relative_width="0.35" />
|
||||
</name_list>
|
||||
<panel
|
||||
bg_alpha_color="ScrollBgWriteableColor"
|
||||
background_visible="true"
|
||||
background_opaque="false"
|
||||
bevel_style="none"
|
||||
follows="bottom|left|right"
|
||||
name="add_subpanel"
|
||||
layout="topleft"
|
||||
height="28"
|
||||
top_pad="0">
|
||||
<menu_button
|
||||
follows="bottom|left"
|
||||
height="25"
|
||||
label="Add someone..."
|
||||
layout="topleft"
|
||||
menu_filename="menu_avatar_rendering_settings_add.xml"
|
||||
menu_position="bottomleft"
|
||||
name="plus_btn"
|
||||
tool_tip="Actions on selected person"
|
||||
top="1"
|
||||
left="8"
|
||||
width="120" />
|
||||
</panel>
|
||||
</floater>
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
<floater
|
||||
name="avatarrendersettings"
|
||||
help_topic="fs_avatar_render_settings"
|
||||
title="Avatar Render Settings"
|
||||
title="Avatar Display Exceptions"
|
||||
min_width="350"
|
||||
min_height="320"
|
||||
width="450"
|
||||
|
|
@ -18,7 +18,7 @@
|
|||
Never
|
||||
</floater.string>
|
||||
<floater.string name="av_render_always">
|
||||
Fully
|
||||
Always
|
||||
</floater.string>
|
||||
<filter_editor
|
||||
follows="left|top|right"
|
||||
|
|
@ -66,7 +66,7 @@
|
|||
label="Name"
|
||||
name="name" />
|
||||
<name_list.columns
|
||||
label="Render Setting"
|
||||
label="Full detail"
|
||||
name="render_setting"
|
||||
width="100" />
|
||||
</name_list>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,514 @@
|
|||
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
|
||||
<floater
|
||||
height="652"
|
||||
layout="topleft"
|
||||
name="performance"
|
||||
help_topic="fs_performance_floater"
|
||||
save_rect="true"
|
||||
title="Improve Graphics Speed (Experimental)"
|
||||
can_resize="true"
|
||||
min_height="652"
|
||||
max_height="652"
|
||||
min_width="580"
|
||||
width="580">
|
||||
<floater.string name="frame_stats">
|
||||
Frame: [TOT_FRAME_TIME]ms - Scenery:[SCENERY_FRAME_PCT]% Avatars:[AV_FRAME_PCT]% UI:[UI_FRAME_PCT]% HUDS:[HUDS_FRAME_PCT]% SWAP:[SWAP_FRAME_PCT]% TASKS:[IDLE_FRAME_PCT]%
|
||||
</floater.string>
|
||||
<floater.string name="limit_fps">
|
||||
FPS capped at [FPSCAP] fps
|
||||
</floater.string>
|
||||
<floater.string name="tuning_fps">
|
||||
Auto Tune target [FPSTARGET] fps
|
||||
</floater.string>
|
||||
<floater.string name="av_frame_pct">
|
||||
[AV_FRAME_PCT]%
|
||||
</floater.string>
|
||||
<floater.string name="huds_frame_pct">
|
||||
[HUDS_FRAME_PCT]%
|
||||
</floater.string>
|
||||
<floater.string name="focus_fps">
|
||||
In Background
|
||||
</floater.string>
|
||||
<floater.string name="tot_av_template">
|
||||
Total: [TOT_AV] ([TOT_AV_TIME]μs)
|
||||
</floater.string>
|
||||
<floater.string name="tot_att_template">
|
||||
Total: [TOT_ATT] ([TOT_ATT_TIME]μs)
|
||||
</floater.string>
|
||||
<panel
|
||||
bevel_style="none"
|
||||
follows="left|top|right"
|
||||
height="600"
|
||||
width="580"
|
||||
name="panel_top"
|
||||
visible="true"
|
||||
layout="topleft"
|
||||
left="0"
|
||||
top="0">
|
||||
<panel
|
||||
bg_alpha_color="black"
|
||||
background_visible="true"
|
||||
background_opaque="false"
|
||||
border="false"
|
||||
bevel_style="none"
|
||||
follows="left|top|right"
|
||||
height="55"
|
||||
width="560"
|
||||
name="fps_subpanel"
|
||||
layout="topleft"
|
||||
left="10"
|
||||
top="5">
|
||||
<text
|
||||
follows="left|top"
|
||||
font="SansSerifHuge"
|
||||
text_color="White"
|
||||
height="20"
|
||||
layout="topleft"
|
||||
left="20"
|
||||
top="8"
|
||||
name="fps_value"
|
||||
width="42">
|
||||
167
|
||||
</text>
|
||||
<text
|
||||
follows="left|top"
|
||||
font="SansSerifLarge"
|
||||
text_color="White"
|
||||
height="20"
|
||||
layout="topleft"
|
||||
left_pad="3"
|
||||
top="13"
|
||||
name="fps_lbl"
|
||||
width="150">
|
||||
frames per second
|
||||
</text>
|
||||
<text
|
||||
follows="left|top"
|
||||
font="SansSerifLarge"
|
||||
text_color="DrYellow"
|
||||
height="28"
|
||||
layout="topleft"
|
||||
left_pad="10"
|
||||
name="fps_warning"
|
||||
top="13"
|
||||
width="150">
|
||||
</text>
|
||||
<text
|
||||
follows="top|right"
|
||||
text_color="White"
|
||||
height="40"
|
||||
layout="topleft"
|
||||
left="395"
|
||||
top="5"
|
||||
name="fps_desc1_lbl"
|
||||
width="150"
|
||||
wrap="true">
|
||||
Allow 5-10 seconds for changes to take full effect.
|
||||
</text>
|
||||
<text
|
||||
follows="left|top|right"
|
||||
font="MonospaceMedium"
|
||||
text_color="White"
|
||||
height="20"
|
||||
layout="topleft"
|
||||
halign="center"
|
||||
left="5"
|
||||
top="38"
|
||||
name="frame_breakdown"
|
||||
width="550">
|
||||
[--------------------Frame breakdown will appear here.---------------------]
|
||||
</text>
|
||||
</panel>
|
||||
<panel
|
||||
bg_alpha_color="black"
|
||||
background_visible="true"
|
||||
background_opaque="false"
|
||||
border="false"
|
||||
bevel_style="none"
|
||||
follows="left|top|right"
|
||||
height="55"
|
||||
width="560"
|
||||
name="target_subpanel"
|
||||
layout="topleft"
|
||||
left="10"
|
||||
top_pad="0">
|
||||
<text
|
||||
follows="left|top"
|
||||
font="SansSerifLarge"
|
||||
text_color="White"
|
||||
height="20"
|
||||
layout="topleft"
|
||||
left="10"
|
||||
name="settings_lbl"
|
||||
top="7"
|
||||
width="240">
|
||||
Auto-Tune Frame Rate
|
||||
</text>
|
||||
<check_box
|
||||
control_name="FSAutoTuneFPS"
|
||||
follows="top|right"
|
||||
height="16"
|
||||
initial_value="false"
|
||||
label="Auto tune for FPS"
|
||||
layout="topleft"
|
||||
left_pad="40"
|
||||
name="AutoTuneFPS"
|
||||
top_delta="0"
|
||||
tool_tip="The viewer will attempt to adjust settings to meet the target FPS."
|
||||
width="50">
|
||||
</check_box>
|
||||
<text
|
||||
follows="left|top"
|
||||
font="SansSerif"
|
||||
text_color="White"
|
||||
height="20"
|
||||
layout="topleft"
|
||||
left="10"
|
||||
name="settings_desc"
|
||||
top_pad="3"
|
||||
width="275">
|
||||
Automatically adjust settings to maintain FPS
|
||||
</text>
|
||||
<combo_box
|
||||
follows="top|right"
|
||||
font="SansSerif"
|
||||
text_color="White"
|
||||
height="20"
|
||||
layout="topleft"
|
||||
left_pad="5"
|
||||
control_name="FSTuningFPSStrategy"
|
||||
name="FSTuningFPSStrategy"
|
||||
top_delta="0"
|
||||
width="150">
|
||||
<combo_box.item
|
||||
label="Tune Avatars Only"
|
||||
name="av_only"
|
||||
value="0" />
|
||||
<combo_box.item
|
||||
label="Avatar and scene"
|
||||
name="av_and_scene"
|
||||
value="1" />
|
||||
</combo_box>
|
||||
<spinner
|
||||
name="target_fps"
|
||||
control_name="FSTargetFPS"
|
||||
font="SansSerifLarge"
|
||||
tooltip="Target FPS - The desired FPS level. The viewer will attempt to achieve this by adjusting your graphics settings."
|
||||
layout="topleft"
|
||||
follows="right|top"
|
||||
right="-55"
|
||||
top_pad="-32"
|
||||
height="40"
|
||||
visible="true"
|
||||
decimal_digits="0"
|
||||
increment="1"
|
||||
initial_value="25"
|
||||
max_val="200"
|
||||
min_val="1"
|
||||
width="40"
|
||||
label="" />
|
||||
<button
|
||||
height="16"
|
||||
width="16"
|
||||
layout="topleft"
|
||||
mouse_opaque="true"
|
||||
follows="right|top"
|
||||
name="target_btn"
|
||||
top="19"
|
||||
image_selected="Icon_Gear"
|
||||
image_pressed="Icon_Gear"
|
||||
image_unselected="Icon_Gear"
|
||||
right="-20"
|
||||
is_toggle="true">
|
||||
</button>
|
||||
</panel>
|
||||
</panel>
|
||||
<panel
|
||||
bevel_style="none"
|
||||
follows="left|top|right"
|
||||
height="540"
|
||||
width="580"
|
||||
name="panel_performance_main"
|
||||
visible="true"
|
||||
layout="topleft"
|
||||
left="0"
|
||||
top="115">
|
||||
<panel
|
||||
bg_alpha_color="PanelGray"
|
||||
background_visible="true"
|
||||
background_opaque="false"
|
||||
border="true"
|
||||
bevel_style="none"
|
||||
follows="left|top|right"
|
||||
height="50"
|
||||
width="560"
|
||||
name="settings_subpanel"
|
||||
layout="topleft"
|
||||
left="10"
|
||||
top_pad="10">
|
||||
<text
|
||||
follows="left|top"
|
||||
font="SansSerifLarge"
|
||||
text_color="White"
|
||||
height="20"
|
||||
layout="topleft"
|
||||
left="10"
|
||||
name="settings_lbl"
|
||||
top="7"
|
||||
width="180">
|
||||
Graphics settings
|
||||
</text>
|
||||
<text
|
||||
follows="left|top"
|
||||
font="SansSerif"
|
||||
text_color="White"
|
||||
height="20"
|
||||
layout="topleft"
|
||||
left="10"
|
||||
name="settings_desc"
|
||||
top_pad="0"
|
||||
width="395">
|
||||
Choose settings for distance, water, lighting and more.
|
||||
</text>
|
||||
<icon
|
||||
height="16"
|
||||
width="16"
|
||||
image_name="Arrow_Right_Off"
|
||||
mouse_opaque="true"
|
||||
name="icon_arrow3"
|
||||
follows="right|top"
|
||||
top="19"
|
||||
right="-20"/>
|
||||
</panel>
|
||||
<panel
|
||||
bg_alpha_color="PanelGray"
|
||||
background_visible="true"
|
||||
background_opaque="false"
|
||||
border="true"
|
||||
bevel_style="none"
|
||||
follows="left|top|right"
|
||||
height="50"
|
||||
width="560"
|
||||
name="nearby_subpanel"
|
||||
layout="topleft"
|
||||
top_pad="10">
|
||||
<text
|
||||
follows="left|top"
|
||||
font="SansSerifLarge"
|
||||
text_color="White"
|
||||
height="20"
|
||||
layout="topleft"
|
||||
left="10"
|
||||
name="avatars_nearby_lbl"
|
||||
top="7"
|
||||
width="205">
|
||||
Avatars nearby
|
||||
</text>
|
||||
<text
|
||||
follows="left|top"
|
||||
font="SansSerif"
|
||||
text_color="White"
|
||||
height="20"
|
||||
layout="topleft"
|
||||
left="10"
|
||||
name="avatars_nearby_desc"
|
||||
top_pad="0"
|
||||
width="345">
|
||||
Manage which nearby avatars are fully displayed.
|
||||
</text>
|
||||
<text
|
||||
follows="top|right"
|
||||
font="SansSerifSmall"
|
||||
text_color="White"
|
||||
height="28"
|
||||
layout="topleft"
|
||||
left_pad="10"
|
||||
name="avatars_frme_pct_lbl"
|
||||
top="8"
|
||||
width="75">
|
||||
Time spent
|
||||
drawing
|
||||
avatars
|
||||
</text>
|
||||
<text
|
||||
follows="top|right"
|
||||
font="SansSerifHuge"
|
||||
text_color="White"
|
||||
height="20"
|
||||
layout="topleft"
|
||||
left_pad="10"
|
||||
top="14"
|
||||
name="av_frame_stats"
|
||||
width="62">
|
||||
00%
|
||||
</text>
|
||||
<icon
|
||||
height="16"
|
||||
width="16"
|
||||
image_name="Arrow_Right_Off"
|
||||
mouse_opaque="true"
|
||||
name="icon_arrow2"
|
||||
follows="right|top"
|
||||
top="19"
|
||||
right="-20"/>
|
||||
</panel>
|
||||
<panel
|
||||
bg_alpha_color="PanelGray"
|
||||
background_visible="true"
|
||||
background_opaque="false"
|
||||
border="true"
|
||||
bevel_style="none"
|
||||
follows="left|top|right"
|
||||
height="50"
|
||||
width="560"
|
||||
name="complexity_subpanel"
|
||||
layout="topleft"
|
||||
top_pad="10">
|
||||
<text
|
||||
follows="left|top"
|
||||
font="SansSerifLarge"
|
||||
text_color="White"
|
||||
height="20"
|
||||
layout="topleft"
|
||||
left="10"
|
||||
name="complexity_lbl"
|
||||
top="7"
|
||||
width="180">
|
||||
Your avatar complexity
|
||||
</text>
|
||||
<text
|
||||
follows="left|top"
|
||||
font="SansSerif"
|
||||
text_color="White"
|
||||
height="20"
|
||||
layout="topleft"
|
||||
left="10"
|
||||
name="complexity_info"
|
||||
top_pad="0"
|
||||
width="455">
|
||||
Be a good citizen. Manage the impact of your avatar
|
||||
</text>
|
||||
<icon
|
||||
height="16"
|
||||
width="16"
|
||||
image_name="Arrow_Right_Off"
|
||||
mouse_opaque="true"
|
||||
name="icon_arrow4"
|
||||
follows="right|top"
|
||||
top="19"
|
||||
right="-20"/>
|
||||
</panel>
|
||||
<panel
|
||||
bg_alpha_color="PanelGray"
|
||||
background_visible="true"
|
||||
background_opaque="false"
|
||||
border="true"
|
||||
bevel_style="none"
|
||||
follows="left|top|right"
|
||||
height="50"
|
||||
width="560"
|
||||
name="huds_subpanel"
|
||||
layout="topleft"
|
||||
top_pad="10">
|
||||
<text
|
||||
follows="left|top"
|
||||
font="SansSerifLarge"
|
||||
text_color="White"
|
||||
height="20"
|
||||
layout="topleft"
|
||||
left="10"
|
||||
name="huds_lbl"
|
||||
top="7"
|
||||
width="135">
|
||||
Your active HUDs
|
||||
</text>
|
||||
<text
|
||||
follows="left|top"
|
||||
font="SansSerif"
|
||||
text_color="White"
|
||||
height="20"
|
||||
layout="topleft"
|
||||
left="10"
|
||||
name="huds_desc"
|
||||
top_pad="0"
|
||||
width="345">
|
||||
Removing unnecessary HUDs may improve speed.
|
||||
</text>
|
||||
<text
|
||||
follows="top|right"
|
||||
font="SansSerifSmall"
|
||||
text_color="White"
|
||||
height="28"
|
||||
layout="topleft"
|
||||
left_pad="10"
|
||||
name="huds_frme_pct_lbl"
|
||||
top="8"
|
||||
width="75">
|
||||
Time spent
|
||||
drawing
|
||||
HUDs
|
||||
</text>
|
||||
<text
|
||||
follows="top|right"
|
||||
font="SansSerifHuge"
|
||||
text_color="White"
|
||||
height="20"
|
||||
layout="topleft"
|
||||
left_pad="10"
|
||||
top="14"
|
||||
name="huds_frame_stats"
|
||||
width="62">
|
||||
00%
|
||||
</text>
|
||||
<icon
|
||||
height="16"
|
||||
width="16"
|
||||
image_name="Arrow_Right_Off"
|
||||
mouse_opaque="true"
|
||||
name="icon_arrow4"
|
||||
follows="right|top"
|
||||
top="19"
|
||||
right="-20"/>
|
||||
</panel>
|
||||
</panel>
|
||||
<panel
|
||||
filename="panel_performance_nearby.xml"
|
||||
follows="all"
|
||||
layout="topleft"
|
||||
left="0"
|
||||
name="panel_performance_nearby"
|
||||
visible="false"
|
||||
top="115" />
|
||||
<panel
|
||||
filename="panel_performance_complexity.xml"
|
||||
follows="all"
|
||||
layout="topleft"
|
||||
left="0"
|
||||
name="panel_performance_complexity"
|
||||
visible="false"
|
||||
top="115" />
|
||||
<panel
|
||||
filename="panel_performance_preferences.xml"
|
||||
follows="all"
|
||||
layout="topleft"
|
||||
left="0"
|
||||
name="panel_performance_preferences"
|
||||
visible="false"
|
||||
top="115" />
|
||||
<panel
|
||||
filename="panel_performance_huds.xml"
|
||||
follows="all"
|
||||
layout="topleft"
|
||||
left="0"
|
||||
name="panel_performance_huds"
|
||||
visible="false"
|
||||
top="115" />
|
||||
<panel
|
||||
filename="panel_performance_autotune.xml"
|
||||
follows="all"
|
||||
layout="topleft"
|
||||
left="0"
|
||||
name="panel_performance_autotune"
|
||||
visible="false"
|
||||
top="115" />
|
||||
</floater>
|
||||
|
|
@ -6,7 +6,7 @@
|
|||
help_topic="Preferences_Graphics_Advanced"
|
||||
single_instance="true"
|
||||
save_rect="true"
|
||||
title="ADVANCED GRAPHICS PREFERENCES"
|
||||
title="Advanced Graphics Preferences"
|
||||
width="800">
|
||||
|
||||
<!-- This block shows Advanced Settings -->
|
||||
|
|
|
|||
|
|
@ -169,18 +169,18 @@
|
|||
<menu_item_separator />
|
||||
|
||||
<menu_item_check
|
||||
name="RenderNormally"
|
||||
label="Render Normally">
|
||||
name="AlwaysRenderFully"
|
||||
label="Always Display Full Detail">
|
||||
<menu_item_check.on_check
|
||||
function="Avatar.CheckImpostorMode"
|
||||
parameter="0" />
|
||||
parameter="2" />
|
||||
<menu_item_check.on_click
|
||||
function="Avatar.SetImpostorMode"
|
||||
parameter="0" />
|
||||
parameter="2" />
|
||||
</menu_item_check>
|
||||
<menu_item_check
|
||||
name="DoNotRender"
|
||||
label="Do Not Render">
|
||||
label="Never Display Full Detail">
|
||||
<menu_item_check.on_check
|
||||
function="Avatar.CheckImpostorMode"
|
||||
parameter="1" />
|
||||
|
|
@ -189,14 +189,14 @@
|
|||
parameter="1" />
|
||||
</menu_item_check>
|
||||
<menu_item_check
|
||||
name="AlwaysRenderFully"
|
||||
label="Render Fully">
|
||||
<menu_item_check.on_check
|
||||
name="RenderNormally"
|
||||
label="Remove From Display Exceptions">
|
||||
<menu_item_check.on_visible
|
||||
function="Avatar.CheckImpostorMode"
|
||||
parameter="2" />
|
||||
parameter="4" />
|
||||
<menu_item_check.on_click
|
||||
function="Avatar.SetImpostorMode"
|
||||
parameter="2" />
|
||||
parameter="0" />
|
||||
</menu_item_check>
|
||||
|
||||
<menu_item_call
|
||||
|
|
|
|||
|
|
@ -197,18 +197,18 @@
|
|||
<menu_item_separator />
|
||||
|
||||
<menu_item_check
|
||||
name="RenderNormally"
|
||||
label="Render Normally">
|
||||
name="AlwaysRenderFully"
|
||||
label="Always Display Full Detail">
|
||||
<menu_item_check.on_check
|
||||
function="Avatar.CheckImpostorMode"
|
||||
parameter="0" />
|
||||
parameter="2" />
|
||||
<menu_item_check.on_click
|
||||
function="Avatar.SetImpostorMode"
|
||||
parameter="0" />
|
||||
parameter="2" />
|
||||
</menu_item_check>
|
||||
<menu_item_check
|
||||
name="DoNotRender"
|
||||
label="Do Not Render">
|
||||
label="Never Display Full Detail">
|
||||
<menu_item_check.on_check
|
||||
function="Avatar.CheckImpostorMode"
|
||||
parameter="1" />
|
||||
|
|
@ -217,14 +217,14 @@
|
|||
parameter="1" />
|
||||
</menu_item_check>
|
||||
<menu_item_check
|
||||
name="AlwaysRenderFully"
|
||||
label="Render Fully">
|
||||
<menu_item_check.on_check
|
||||
name="RenderNormally"
|
||||
label="Remove From Display Exceptions">
|
||||
<menu_item_check.on_visible
|
||||
function="Avatar.CheckImpostorMode"
|
||||
parameter="2" />
|
||||
parameter="4" />
|
||||
<menu_item_check.on_click
|
||||
function="Avatar.SetImpostorMode"
|
||||
parameter="2" />
|
||||
parameter="0" />
|
||||
</menu_item_check>
|
||||
|
||||
<menu_item_call
|
||||
|
|
|
|||
|
|
@ -3,24 +3,25 @@
|
|||
layout="topleft"
|
||||
name="Settings">
|
||||
<menu_item_check
|
||||
label="Default"
|
||||
layout="topleft"
|
||||
name="default">
|
||||
<on_click function="Settings.SetRendering" parameter="default"/>
|
||||
<on_check function="Settings.IsSelected" parameter="default" />
|
||||
</menu_item_check>
|
||||
<menu_item_check
|
||||
label="Always render"
|
||||
label="Always full detail"
|
||||
layout="topleft"
|
||||
name="always_render">
|
||||
<on_click function="Settings.SetRendering" parameter="always"/>
|
||||
<on_check function="Settings.IsSelected" parameter="always" />
|
||||
<on_check function="Settings.IsSelected" parameter="always" />
|
||||
</menu_item_check>
|
||||
<menu_item_check
|
||||
label="Never render"
|
||||
label="Never full detail"
|
||||
layout="topleft"
|
||||
name="never_render">
|
||||
<on_click function="Settings.SetRendering" parameter="never"/>
|
||||
<on_check function="Settings.IsSelected" parameter="never" />
|
||||
</menu_item_check>
|
||||
<on_check function="Settings.IsSelected" parameter="never" />
|
||||
</menu_item_check>
|
||||
<menu_item_check
|
||||
label="Remove from exceptions"
|
||||
layout="topleft"
|
||||
name="default">
|
||||
<on_click function="Settings.SetRendering" parameter="default"/>
|
||||
<on_check function="Settings.IsSelected" parameter="default" />
|
||||
<on_visible function="Settings.IsSelected" parameter="non_default" />
|
||||
</menu_item_check>
|
||||
</context_menu>
|
||||
|
|
|
|||
|
|
@ -4,13 +4,13 @@
|
|||
left="0" bottom="0" visible="false"
|
||||
mouse_opaque="false">
|
||||
<menu_item_call
|
||||
label="Always Render a Resident..."
|
||||
label="Always full detail..."
|
||||
name="add_avatar_always_render">
|
||||
<on_click
|
||||
function="Settings.AddNewEntry" parameter="always"/>
|
||||
</menu_item_call>
|
||||
<menu_item_call
|
||||
label="Never Render a Resident..."
|
||||
label="Never full detail..."
|
||||
name="add_avatar_never_render">
|
||||
<on_click
|
||||
function="Settings.AddNewEntry" parameter="never"/>
|
||||
|
|
|
|||
|
|
@ -3,15 +3,15 @@
|
|||
layout="topleft"
|
||||
name="Avatar Render Settings Menu">
|
||||
<menu_item_call
|
||||
label="Render Normally (removes from list)"
|
||||
label="Always Full Detail"
|
||||
layout="topleft"
|
||||
name="av_render_normal">
|
||||
name="av_render_always">
|
||||
<menu_item_call.on_click
|
||||
function="Avatar.ChangeRenderSetting"
|
||||
parameter="0" />
|
||||
parameter="2" />
|
||||
</menu_item_call>
|
||||
<menu_item_call
|
||||
label="Do Not Render"
|
||||
label="Never Full Detail"
|
||||
layout="topleft"
|
||||
name="av_render_never">
|
||||
<menu_item_call.on_click
|
||||
|
|
@ -19,11 +19,11 @@
|
|||
parameter="1" />
|
||||
</menu_item_call>
|
||||
<menu_item_call
|
||||
label="Render Fully"
|
||||
label="Remove From Exceptions"
|
||||
layout="topleft"
|
||||
name="av_render_always">
|
||||
name="av_render_normal">
|
||||
<menu_item_call.on_click
|
||||
function="Avatar.ChangeRenderSetting"
|
||||
parameter="2" />
|
||||
parameter="0" />
|
||||
</menu_item_call>
|
||||
</context_menu>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,41 @@
|
|||
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
|
||||
<context_menu
|
||||
layout="topleft"
|
||||
name="Settings">
|
||||
<menu_item_check
|
||||
label="Always full detail"
|
||||
layout="topleft"
|
||||
name="always_render">
|
||||
<on_click function="Settings.SetRendering" parameter="always"/>
|
||||
<on_check function="Settings.IsSelected" parameter="always" />
|
||||
</menu_item_check>
|
||||
<menu_item_check
|
||||
label="Never full detail"
|
||||
layout="topleft"
|
||||
name="never_render">
|
||||
<on_click function="Settings.SetRendering" parameter="never"/>
|
||||
<on_check function="Settings.IsSelected" parameter="never" />
|
||||
</menu_item_check>
|
||||
<menu_item_check
|
||||
label="Remove from exceptions"
|
||||
layout="topleft"
|
||||
name="default">
|
||||
<on_click function="Settings.SetRendering" parameter="default"/>
|
||||
<on_check function="Settings.IsSelected" parameter="default" />
|
||||
<on_visible function="Settings.IsSelected" parameter="non_default" />
|
||||
</menu_item_check>
|
||||
<menu_item_separator />
|
||||
<menu_item_call
|
||||
label="Inspect Avatar"
|
||||
name="inspect">
|
||||
<menu_item_call.on_click
|
||||
function="Avatar.Extended" parameter="inspect"/>
|
||||
</menu_item_call>
|
||||
<menu_item_call
|
||||
label="Zoom to Avatar"
|
||||
tool_tip="Move camera to view this avatar."
|
||||
name="zoom">
|
||||
<menu_item_call.on_click
|
||||
function="Avatar.Extended" parameter="zoom"/>
|
||||
</menu_item_call>
|
||||
</context_menu>
|
||||
|
|
@ -221,13 +221,16 @@
|
|||
</pie_menu>
|
||||
<pie_menu
|
||||
name="RenderMenu"
|
||||
label="Render >">
|
||||
label="Display >">
|
||||
<pie_slice
|
||||
name="RenderNormally"
|
||||
label="Normally">
|
||||
<pie_slice.on_click
|
||||
function="Avatar.SetImpostorMode"
|
||||
parameter="0" />
|
||||
<pie_slice.on_visible
|
||||
function="Avatar.CheckImpostorMode"
|
||||
parameter="4" />
|
||||
</pie_slice>
|
||||
<pie_slice
|
||||
name="DoNotRender"
|
||||
|
|
|
|||
|
|
@ -195,13 +195,16 @@
|
|||
</pie_slice>
|
||||
<pie_menu
|
||||
name="RenderMenu"
|
||||
label="Render >">
|
||||
label="Display >">
|
||||
<pie_slice
|
||||
name="RenderNormally"
|
||||
label="Normally">
|
||||
<pie_slice.on_click
|
||||
function="Avatar.SetImpostorMode"
|
||||
parameter="0" />
|
||||
<pie_slice.on_visible
|
||||
function="Avatar.CheckImpostorMode"
|
||||
parameter="4" />
|
||||
</pie_slice>
|
||||
<pie_slice
|
||||
name="DoNotRender"
|
||||
|
|
|
|||
|
|
@ -1198,7 +1198,16 @@
|
|||
parameter="UseDebugMenus" />
|
||||
</menu_item_check>
|
||||
</menu>
|
||||
|
||||
<menu_item_check
|
||||
label="Improve graphics speed..."
|
||||
name="Performance">
|
||||
<menu_item_check.on_click
|
||||
function="Floater.Toggle"
|
||||
parameter="performance" />
|
||||
<menu_item_check.on_check
|
||||
function="Floater.Visible"
|
||||
parameter="performance" />
|
||||
</menu_item_check>
|
||||
<menu_item_separator/>
|
||||
|
||||
<menu_item_call
|
||||
|
|
|
|||
|
|
@ -0,0 +1,230 @@
|
|||
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
|
||||
<panel
|
||||
bevel_style="none"
|
||||
follows="left|top"
|
||||
height="530"
|
||||
width="580"
|
||||
name="panel_performance_autotune"
|
||||
layout="topleft"
|
||||
left="0"
|
||||
top="0">
|
||||
<button
|
||||
height="16"
|
||||
width="16"
|
||||
layout="topleft"
|
||||
mouse_opaque="true"
|
||||
follows="left|top"
|
||||
name="back_btn"
|
||||
top="7"
|
||||
image_selected="Arrow_Left_Off"
|
||||
image_pressed="Arrow_Left_Off"
|
||||
image_unselected="Arrow_Left_Off"
|
||||
left="15"
|
||||
is_toggle="true">
|
||||
</button>
|
||||
<text
|
||||
follows="left|top"
|
||||
height="20"
|
||||
layout="topleft"
|
||||
left_pad="3"
|
||||
top="10"
|
||||
name="back_lbl"
|
||||
width="40">
|
||||
Back
|
||||
</text>
|
||||
<text
|
||||
follows="left|top"
|
||||
font="SansSerifLarge"
|
||||
text_color="white"
|
||||
height="20"
|
||||
layout="topleft"
|
||||
left="20"
|
||||
top_pad="10"
|
||||
name="settings_title"
|
||||
width="300">
|
||||
Auto Tune Preferences
|
||||
</text>
|
||||
<view_border
|
||||
bevel_style="in"
|
||||
height="0"
|
||||
layout="topleft"
|
||||
name="border1"
|
||||
left="20"
|
||||
top_pad="8"
|
||||
width="540" />
|
||||
<text
|
||||
follows="left|top"
|
||||
font="SansSerifSmall"
|
||||
text_color="White"
|
||||
height="40"
|
||||
layout="topleft"
|
||||
top_pad="20"
|
||||
left="20"
|
||||
name="quality_lbl"
|
||||
width="100"
|
||||
wrap="true">
|
||||
Distant Avatars
|
||||
</text>
|
||||
<check_box
|
||||
control_name="FSAutoTuneImpostorByDistEnabled"
|
||||
height="19"
|
||||
label="Enable distance based optimization"
|
||||
layout="topleft"
|
||||
follows="top|left"
|
||||
left_pad="40"
|
||||
name="FSAutoTuneImpostorByDistEnabled"
|
||||
tool_tip="When enabled the viewer will adjust the MaxNonImpostors setting to limit fully rendered avatars to those within the defined radius."
|
||||
top_delta="0"
|
||||
width="190"
|
||||
label_wrap="true" />
|
||||
<spinner
|
||||
control_name="FSAutoTuneImpostorFarAwayDistance"
|
||||
height="20"
|
||||
layout="topleft"
|
||||
label="Farthest full avatar"
|
||||
label_width="80"
|
||||
label_wrap="true"
|
||||
follows="top|left"
|
||||
name="ffa_autotune"
|
||||
left_pad="40"
|
||||
decimal_digits="2"
|
||||
min_val="16"
|
||||
max_val="256"
|
||||
width="140" >
|
||||
</spinner>
|
||||
<text
|
||||
follows="left|top"
|
||||
font="SansSerifSmall"
|
||||
text_color="White"
|
||||
height="28"
|
||||
layout="topleft"
|
||||
top_pad="15"
|
||||
left="160"
|
||||
name="distant_av_advice"
|
||||
width="450">
|
||||
Avatars that are further away still have a high impact.
|
||||
Set the distance from camera beyond which an avatar will be optimized.
|
||||
</text>
|
||||
<view_border
|
||||
bevel_style="in"
|
||||
height="0"
|
||||
layout="topleft"
|
||||
name="border2"
|
||||
top_pad="8"
|
||||
left="20"
|
||||
width="540" />
|
||||
<text
|
||||
follows="left|top"
|
||||
font="SansSerifSmall"
|
||||
text_color="White"
|
||||
height="36"
|
||||
layout="topleft"
|
||||
top_pad="20"
|
||||
left="20"
|
||||
name="distance_lbl"
|
||||
width="100"
|
||||
wrap="true">
|
||||
Visibility distance tuning limits
|
||||
</text>
|
||||
<spinner
|
||||
control_name="FSAutoTuneRenderFarClipMin"
|
||||
height="20"
|
||||
layout="topleft"
|
||||
label="Minimum Distance"
|
||||
label_width="80"
|
||||
label_wrap="true"
|
||||
top_delta="0"
|
||||
follows="top|left"
|
||||
name="min_dd_autotune"
|
||||
decimal_digits="2"
|
||||
left_pad="40"
|
||||
min_val="32"
|
||||
max_val="256"
|
||||
width="140">
|
||||
</spinner>
|
||||
<spinner
|
||||
control_name="FSAutoTuneRenderFarClipTarget"
|
||||
height="20"
|
||||
layout="topleft"
|
||||
label="Preferred distance"
|
||||
label_width="80"
|
||||
label_wrap="true"
|
||||
follows="top|left"
|
||||
name="pref_dd_autotune"
|
||||
left_pad="20"
|
||||
min_val="32"
|
||||
max_val="256"
|
||||
width="140">
|
||||
</spinner>
|
||||
<text
|
||||
follows="left|top"
|
||||
font="SansSerifSmall"
|
||||
text_color="White"
|
||||
height="38"
|
||||
layout="topleft"
|
||||
top_pad="15"
|
||||
left="160"
|
||||
name="distance_desc1"
|
||||
wrap="true"
|
||||
width="400">
|
||||
When adjusting scene parameters, autotune will optimize draw distance to between the minimum and the preferred.
|
||||
</text>
|
||||
<view_border
|
||||
bevel_style="in"
|
||||
height="0"
|
||||
layout="topleft"
|
||||
name="border2"
|
||||
top_pad="8"
|
||||
left="20"
|
||||
width="540" />
|
||||
<text
|
||||
follows="left|top"
|
||||
font="SansSerifSmall"
|
||||
text_color="White"
|
||||
height="36"
|
||||
layout="topleft"
|
||||
top_pad="20"
|
||||
left="20"
|
||||
name="sundry_lbl"
|
||||
width="100"
|
||||
wrap="true">
|
||||
Sundry Settings
|
||||
</text>
|
||||
<check_box
|
||||
control_name="FSAllowSelfImpostor"
|
||||
height="19"
|
||||
label="Allow your own avatar to be optimized"
|
||||
layout="topleft"
|
||||
follows="top|left"
|
||||
left_pad="40"
|
||||
name="alow_self_impostor"
|
||||
tool_tip="When enabled the viewer may render your own avatar as an impostor."
|
||||
top_delta="0"
|
||||
width="190"
|
||||
label_wrap="true" />
|
||||
<check_box
|
||||
control_name="FSShowTunedART"
|
||||
height="19"
|
||||
label="Show optimized render time"
|
||||
layout="topleft"
|
||||
follows="top|left"
|
||||
left_delta="0"
|
||||
name="show_tuned_art"
|
||||
tool_tip="When enabled the Time column shows the current render time not the pre-tuning render time."
|
||||
top_pad="0"
|
||||
width="190"
|
||||
label_wrap="true" />
|
||||
<text
|
||||
follows="left|top"
|
||||
font="SansSerifSmall"
|
||||
text_color="White"
|
||||
height="38"
|
||||
layout="topleft"
|
||||
top_pad="15"
|
||||
left="160"
|
||||
name="sundry_desc1"
|
||||
wrap="true"
|
||||
width="400">
|
||||
These options control more subtle settings. Use the online help page to get more information on what these do.
|
||||
</text>
|
||||
</panel>
|
||||
|
|
@ -0,0 +1,116 @@
|
|||
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
|
||||
<panel bevel_style="none"
|
||||
follows="left|top"
|
||||
height="530"
|
||||
width="580"
|
||||
name="panel_performance_complexity"
|
||||
layout="topleft"
|
||||
left="0"
|
||||
top="0">
|
||||
<button height="16"
|
||||
width="16"
|
||||
layout="topleft"
|
||||
mouse_opaque="true"
|
||||
follows="left|top"
|
||||
name="back_btn"
|
||||
top="7"
|
||||
image_selected="Arrow_Left_Off"
|
||||
image_pressed="Arrow_Left_Off"
|
||||
image_unselected="Arrow_Left_Off"
|
||||
left="15"
|
||||
is_toggle="true">
|
||||
</button>
|
||||
<text follows="left|top"
|
||||
height="20"
|
||||
layout="topleft"
|
||||
left_pad="3"
|
||||
top="10"
|
||||
name="back_lbl"
|
||||
width="40">
|
||||
Back
|
||||
</text>
|
||||
<text follows="left|top"
|
||||
font="SansSerifLarge"
|
||||
text_color="white"
|
||||
height="20"
|
||||
layout="topleft"
|
||||
left="20"
|
||||
top_pad="10"
|
||||
name="attachments_title"
|
||||
width="250">
|
||||
Avatar attachment complexity
|
||||
</text>
|
||||
<text follows="right|top"
|
||||
font="SansSerifLarge"
|
||||
text_color="White"
|
||||
height="20"
|
||||
layout="topleft"
|
||||
right="-40"
|
||||
top_delta="0"
|
||||
name="tot_att_count"
|
||||
halign="right"
|
||||
width="200">
|
||||
Total: 50 (120000.10μs)
|
||||
</text>
|
||||
<text follows="left|top"
|
||||
font="SansSerifSmall"
|
||||
text_color="White"
|
||||
height="18"
|
||||
layout="topleft"
|
||||
top_pad="5"
|
||||
left="20"
|
||||
name="attachments_desc1"
|
||||
width="580">
|
||||
Attachments make your avatar more complex and slower to render.
|
||||
</text>
|
||||
<text follows="left|top"
|
||||
font="SansSerifSmall"
|
||||
text_color="White"
|
||||
height="18"
|
||||
layout="topleft"
|
||||
top_pad="3"
|
||||
left="20"
|
||||
name="attachments_desc2"
|
||||
width="580">
|
||||
This screen allows you to view the attachments of your own avatar.
|
||||
</text>
|
||||
<text follows="left|top"
|
||||
font="SansSerifSmall"
|
||||
text_color="White"
|
||||
height="18"
|
||||
layout="topleft"
|
||||
top_pad="3"
|
||||
left="20"
|
||||
name="attachments_desc3"
|
||||
width="580">
|
||||
You may remove your own attachments quickly and easily by hitting the 'X'.
|
||||
</text>
|
||||
<name_list left="20"
|
||||
column_padding="1"
|
||||
draw_stripes="true"
|
||||
draw_heading="true"
|
||||
height="379"
|
||||
follows="left|top"
|
||||
sort_column="1"
|
||||
sort_ascending="false"
|
||||
multi_select="false"
|
||||
layout="topleft"
|
||||
name="obj_list"
|
||||
top_pad="10"
|
||||
width="540">
|
||||
<name_list.columns label=""
|
||||
name="art_visual"
|
||||
width="90" />
|
||||
<name_list.columns label="Time (μs)"
|
||||
name="art_value"
|
||||
tool_tip="Time taken to render this attachment (microseconds)"
|
||||
width="80" />
|
||||
<name_list.columns label="ARC"
|
||||
name="complex_value"
|
||||
tool_tip="Item complexity (ARC)"
|
||||
width="40" />
|
||||
<name_list.columns label="Attachment name"
|
||||
tool_tip="Click the 'X' to detach"
|
||||
name="name" />
|
||||
</name_list>
|
||||
</panel>
|
||||
|
|
@ -0,0 +1,100 @@
|
|||
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
|
||||
<panel bevel_style="none"
|
||||
follows="left|top"
|
||||
height="530"
|
||||
width="580"
|
||||
name="panel_performance_huds"
|
||||
layout="topleft"
|
||||
left="0"
|
||||
top="0">
|
||||
<button height="16"
|
||||
width="16"
|
||||
layout="topleft"
|
||||
mouse_opaque="true"
|
||||
follows="left|top"
|
||||
name="back_btn"
|
||||
top="7"
|
||||
image_selected="Arrow_Left_Off"
|
||||
image_pressed="Arrow_Left_Off"
|
||||
image_unselected="Arrow_Left_Off"
|
||||
left="15"
|
||||
is_toggle="true">
|
||||
</button>
|
||||
<text follows="left|top"
|
||||
height="20"
|
||||
layout="topleft"
|
||||
left_pad="3"
|
||||
top="10"
|
||||
name="back_lbl"
|
||||
width="40">
|
||||
Back
|
||||
</text>
|
||||
<text follows="left|top"
|
||||
font="SansSerifLarge"
|
||||
text_color="White"
|
||||
height="20"
|
||||
layout="topleft"
|
||||
left="20"
|
||||
top_pad="10"
|
||||
name="huds_title"
|
||||
width="135">
|
||||
Your active HUDs
|
||||
</text>
|
||||
<text follows="left|top"
|
||||
font="SansSerifSmall"
|
||||
text_color="White"
|
||||
height="18"
|
||||
layout="topleft"
|
||||
top_pad="5"
|
||||
left="20"
|
||||
name="huds_desc1"
|
||||
width="540">
|
||||
Detaching HUDs you aren't using saves memory and can make the viewer run faster.
|
||||
</text>
|
||||
<text follows="left|top"
|
||||
font="SansSerifSmall"
|
||||
text_color="White"
|
||||
height="18"
|
||||
layout="topleft"
|
||||
top_pad="3"
|
||||
left="20"
|
||||
name="huds_desc2"
|
||||
width="540">
|
||||
HUDs are often heavily scripted and also contribute to server-side lag.
|
||||
</text>
|
||||
<text follows="left|top"
|
||||
font="SansSerifSmall"
|
||||
text_color="White"
|
||||
height="18"
|
||||
layout="topleft"
|
||||
top_pad="3"
|
||||
left="20"
|
||||
name="huds_desc3"
|
||||
width="540">
|
||||
Note: Using a HUD's minimize button does not detach it. Use the X to remove it.
|
||||
</text>
|
||||
<name_list
|
||||
column_padding="1"
|
||||
draw_stripes="true"
|
||||
draw_heading="true"
|
||||
height="380"
|
||||
follows="left|top"
|
||||
layout="topleft"
|
||||
name="hud_list"
|
||||
top_pad="10"
|
||||
width="540">
|
||||
<name_list.columns
|
||||
label=""
|
||||
name="art_visual"
|
||||
width="90" />
|
||||
<name_list.columns
|
||||
label="Time (μs)"
|
||||
name="art_value"
|
||||
tool_tip="Time taken to render this HUD (microseconds)"
|
||||
width="80" />
|
||||
<name_list.columns
|
||||
label="Name"
|
||||
tool_tip="Click the 'X' to detach"
|
||||
name="name" />
|
||||
</name_list>
|
||||
</panel>
|
||||
|
|
@ -0,0 +1,273 @@
|
|||
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
|
||||
<panel
|
||||
bevel_style="none"
|
||||
follows="left|top|right"
|
||||
height="530"
|
||||
width="580"
|
||||
name="panel_performance_nearby"
|
||||
layout="topleft"
|
||||
left="0"
|
||||
top="0">
|
||||
<button
|
||||
height="16"
|
||||
width="16"
|
||||
layout="topleft"
|
||||
mouse_opaque="true"
|
||||
follows="left|top"
|
||||
name="back_btn"
|
||||
top="7"
|
||||
image_selected="Arrow_Left_Off"
|
||||
image_pressed="Arrow_Left_Off"
|
||||
image_unselected="Arrow_Left_Off"
|
||||
left="15"
|
||||
is_toggle="true">
|
||||
</button>
|
||||
<text
|
||||
follows="left|top"
|
||||
height="20"
|
||||
layout="topleft"
|
||||
left_pad="3"
|
||||
top="10"
|
||||
name="back_lbl"
|
||||
width="40">
|
||||
Back
|
||||
</text>
|
||||
<text
|
||||
follows="left|top"
|
||||
font="SansSerifLarge"
|
||||
text_color="White"
|
||||
height="20"
|
||||
layout="topleft"
|
||||
left="20"
|
||||
top_pad="10"
|
||||
name="av_nearby_title"
|
||||
width="205">
|
||||
Avatars nearby</text>
|
||||
<text
|
||||
follows="right|top"
|
||||
font="SansSerifLarge"
|
||||
text_color="White"
|
||||
height="20"
|
||||
layout="topleft"
|
||||
right="-40"
|
||||
top_delta="0"
|
||||
name="tot_av_count"
|
||||
halign="right"
|
||||
width="200">
|
||||
Total: 50 (120000.10μs)
|
||||
</text>
|
||||
<text
|
||||
follows="left|top"
|
||||
font="SansSerifSmall"
|
||||
text_color="White"
|
||||
height="18"
|
||||
layout="topleft"
|
||||
left="20"
|
||||
top_pad="5"
|
||||
name="av_nearby_desc"
|
||||
width="580">
|
||||
Hide the most complex avatars to boost speed.
|
||||
</text>
|
||||
<slider
|
||||
control_name="IndirectMaxComplexity"
|
||||
visible="false"
|
||||
tool_tip="Controls at what point a visually complex avatar is drawn as a Impostor"
|
||||
follows="left|top"
|
||||
height="16"
|
||||
initial_value="101"
|
||||
increment="1"
|
||||
label="Maximum complexity (K)"
|
||||
text_color="White"
|
||||
label_width="165"
|
||||
layout="topleft"
|
||||
min_val="1"
|
||||
max_val="101"
|
||||
name="IndirectMaxComplexity"
|
||||
show_text="false"
|
||||
top_pad="10"
|
||||
width="300">
|
||||
</slider>
|
||||
<text
|
||||
type="string"
|
||||
visible="false"
|
||||
length="1"
|
||||
follows="left|top"
|
||||
height="16"
|
||||
layout="topleft"
|
||||
top_delta="0"
|
||||
left_delta="304"
|
||||
text_color="White"
|
||||
name="IndirectMaxComplexityText"
|
||||
width="65">
|
||||
0
|
||||
</text>
|
||||
<slider
|
||||
control_name="FSRenderAvatarMaxART"
|
||||
tool_tip="Controls when a visually complex avatar is considered to be taking too long to render (unit: microseconds)"
|
||||
follows="left|top"
|
||||
height="16"
|
||||
initial_value="4.7"
|
||||
increment="0.01"
|
||||
label="Maximum render time (μs)"
|
||||
text_color="White"
|
||||
label_width="165"
|
||||
layout="topleft"
|
||||
min_val="2"
|
||||
max_val="4.7"
|
||||
name="FSRenderAvatarMaxART"
|
||||
show_text="false"
|
||||
left_delta="-304"
|
||||
top_delta="-16"
|
||||
width="490">
|
||||
</slider>
|
||||
<text
|
||||
type="string"
|
||||
length="1"
|
||||
follows="left|top"
|
||||
height="16"
|
||||
layout="topleft"
|
||||
top_delta="0"
|
||||
left_pad="5"
|
||||
text_color="White"
|
||||
name="FSRenderAvatarMaxARTText"
|
||||
width="65">
|
||||
no limit
|
||||
</text>
|
||||
<name_list
|
||||
column_padding="1"
|
||||
draw_stripes="true"
|
||||
draw_heading="true"
|
||||
height="280"
|
||||
left="20"
|
||||
follows="left|top|right"
|
||||
layout="topleft"
|
||||
sort_column="art_value"
|
||||
short_names="true"
|
||||
name="nearby_list"
|
||||
name_column="name"
|
||||
top_pad="10"
|
||||
width="540">
|
||||
<name_list.columns
|
||||
label=""
|
||||
tool_tip="Bar graph showing current render time (includes auto-tuning) as % of slowest."
|
||||
name="art_visual"
|
||||
width="90" />
|
||||
<name_list.columns
|
||||
label="Time (μs)"
|
||||
tool_tip="Avatar Render Time. Actual time taken to render this avatar before any auto-tuning (in microseconds)."
|
||||
name="art_value"
|
||||
width="80" />
|
||||
<name_list.columns
|
||||
label="ARC"
|
||||
tool_tip="Complexity (ARC) based on standard rules."
|
||||
name="complex_value"
|
||||
width="40" />
|
||||
<name_list.columns
|
||||
label=""
|
||||
tool_tip="Shows any tuning. I=Impostor, S=no shadow."
|
||||
name="state"
|
||||
width="15" />
|
||||
<name_list.columns
|
||||
label="Name"
|
||||
name="name"/>
|
||||
</name_list>
|
||||
<text
|
||||
follows="left|top"
|
||||
font="SansSerifSmall"
|
||||
text_color="White"
|
||||
height="18"
|
||||
layout="topleft"
|
||||
left="20"
|
||||
top_pad="10"
|
||||
name="av_nearby_desc2"
|
||||
width="580">
|
||||
You can also right-click on an avatar in-world to control display.
|
||||
</text>
|
||||
<button
|
||||
height="23"
|
||||
label="Exceptions..."
|
||||
layout="topleft"
|
||||
left="460"
|
||||
top_delta="2"
|
||||
name="exceptions_btn"
|
||||
width="100">
|
||||
</button>
|
||||
<check_box
|
||||
control_name="AlwaysRenderFriends"
|
||||
height="16"
|
||||
initial_value="true"
|
||||
label="Always display friends in full detail"
|
||||
label_text.text_color="White"
|
||||
layout="topleft"
|
||||
name="display_friends"
|
||||
top_pad="3"
|
||||
left="18"
|
||||
width="256">
|
||||
</check_box>
|
||||
<view_border
|
||||
bevel_style="in"
|
||||
height="0"
|
||||
layout="topleft"
|
||||
name="border"
|
||||
top_pad="15"
|
||||
left="20"
|
||||
width="540"/>
|
||||
<check_box
|
||||
height="16"
|
||||
initial_value="true"
|
||||
label="Hide avatars completely."
|
||||
layout="topleft"
|
||||
name="hide_avatars"
|
||||
top_delta="15"
|
||||
left="18"
|
||||
width="280">
|
||||
</check_box>
|
||||
<text
|
||||
type="string"
|
||||
length="1"
|
||||
follows="left|top"
|
||||
height="15"
|
||||
layout="topleft"
|
||||
left="20"
|
||||
name="name_tags_textbox"
|
||||
top_pad="10"
|
||||
width="400">
|
||||
Name tags:
|
||||
</text>
|
||||
<radio_group
|
||||
control_name="AvatarNameTagMode"
|
||||
height="20"
|
||||
layout="topleft"
|
||||
left="120"
|
||||
top_delta="0"
|
||||
name="name_tag_mode">
|
||||
<radio_item
|
||||
label="Off"
|
||||
name="radio"
|
||||
top_delta="20"
|
||||
layout="topleft"
|
||||
height="16"
|
||||
left="0"
|
||||
value="0"
|
||||
width="75" />
|
||||
<radio_item
|
||||
label="On"
|
||||
left_pad="0"
|
||||
layout="topleft"
|
||||
top_delta="0"
|
||||
height="16"
|
||||
name="radio2"
|
||||
value="1"
|
||||
width="75" />
|
||||
<radio_item
|
||||
label="Show briefly"
|
||||
left_pad="0"
|
||||
name="radio3"
|
||||
height="16"
|
||||
layout="topleft"
|
||||
top_delta="0"
|
||||
value="2"
|
||||
width="160" />
|
||||
</radio_group>
|
||||
|
||||
</panel>
|
||||
|
|
@ -0,0 +1,518 @@
|
|||
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
|
||||
<panel
|
||||
bevel_style="none"
|
||||
follows="left|top"
|
||||
height="530"
|
||||
width="580"
|
||||
name="panel_performance_preferences"
|
||||
layout="topleft"
|
||||
left="0"
|
||||
top="0">
|
||||
<button
|
||||
height="16"
|
||||
width="16"
|
||||
layout="topleft"
|
||||
mouse_opaque="true"
|
||||
follows="left|top"
|
||||
name="back_btn"
|
||||
top="7"
|
||||
image_selected="Arrow_Left_Off"
|
||||
image_pressed="Arrow_Left_Off"
|
||||
image_unselected="Arrow_Left_Off"
|
||||
left="15"
|
||||
is_toggle="true">
|
||||
</button>
|
||||
<text
|
||||
follows="left|top"
|
||||
height="20"
|
||||
layout="topleft"
|
||||
left_pad="3"
|
||||
top="10"
|
||||
name="back_lbl"
|
||||
width="40">
|
||||
Back
|
||||
</text>
|
||||
<text
|
||||
follows="left|top"
|
||||
font="SansSerifLarge"
|
||||
text_color="white"
|
||||
height="20"
|
||||
layout="topleft"
|
||||
left="20"
|
||||
top_pad="10"
|
||||
name="settings_title"
|
||||
width="300">
|
||||
Graphics settings
|
||||
</text>
|
||||
<view_border
|
||||
bevel_style="in"
|
||||
height="0"
|
||||
layout="topleft"
|
||||
name="border1"
|
||||
left="20"
|
||||
top_pad="8"
|
||||
width="540"/>
|
||||
<text
|
||||
follows="left|top"
|
||||
font="SansSerifSmall"
|
||||
text_color="White"
|
||||
height="36"
|
||||
layout="topleft"
|
||||
top_pad="20"
|
||||
left="20"
|
||||
name="quality_lbl"
|
||||
width="100"
|
||||
wrap="true">
|
||||
Quality vs speed
|
||||
</text>
|
||||
<text
|
||||
type="string"
|
||||
length="1"
|
||||
follows="left|top"
|
||||
height="12"
|
||||
layout="topleft"
|
||||
left_pad="40"
|
||||
name="FasterText"
|
||||
top_delta="0"
|
||||
width="40">
|
||||
Faster
|
||||
</text>
|
||||
<icon
|
||||
color="Slidermark"
|
||||
height="14"
|
||||
image_name="Rounded_Square"
|
||||
layout="topleft"
|
||||
left_delta="48"
|
||||
name="LowGraphicsDivet"
|
||||
top_delta="-2"
|
||||
width="2" />
|
||||
<icon
|
||||
color="Slidermark"
|
||||
height="14"
|
||||
image_name="Rounded_Square"
|
||||
layout="topleft"
|
||||
left_pad="41"
|
||||
name="LowMidGraphicsDivet"
|
||||
top_delta="0"
|
||||
width="2" />
|
||||
<icon
|
||||
color="Slidermark"
|
||||
height="14"
|
||||
image_name="Rounded_Square"
|
||||
layout="topleft"
|
||||
left_pad="41"
|
||||
name="MidGraphicsDivet"
|
||||
top_delta="0"
|
||||
width="2" />
|
||||
<icon
|
||||
color="Slidermark"
|
||||
height="14"
|
||||
image_name="Rounded_Square"
|
||||
layout="topleft"
|
||||
left_pad="41"
|
||||
name="MidHighGraphicsDivet"
|
||||
top_delta="0"
|
||||
width="2" />
|
||||
<icon
|
||||
color="Slidermark"
|
||||
height="14"
|
||||
image_name="Rounded_Square"
|
||||
layout="topleft"
|
||||
left_pad="41"
|
||||
name="HighGraphicsDivet"
|
||||
top_delta="0"
|
||||
width="2" />
|
||||
<icon
|
||||
color="Slidermark"
|
||||
height="14"
|
||||
image_name="Rounded_Square"
|
||||
layout="topleft"
|
||||
left_pad="41"
|
||||
name="HighUltraGraphicsDivet"
|
||||
top_delta="0"
|
||||
width="2" />
|
||||
<icon
|
||||
color="Slidermark"
|
||||
height="14"
|
||||
image_name="Rounded_Square"
|
||||
layout="topleft"
|
||||
left_pad="41"
|
||||
name="UltraGraphicsDivet"
|
||||
top_delta="0"
|
||||
width="2" />
|
||||
<text
|
||||
type="string"
|
||||
length="1"
|
||||
follows="left|top"
|
||||
height="12"
|
||||
layout="topleft"
|
||||
left_delta="20"
|
||||
name="BetterText"
|
||||
top_delta="0"
|
||||
width="100">
|
||||
Better Quality
|
||||
</text>
|
||||
<slider
|
||||
control_name="RenderQualityPerformance"
|
||||
decimal_digits="0"
|
||||
follows="left|top"
|
||||
height="16"
|
||||
increment="1"
|
||||
initial_value="0"
|
||||
layout="topleft"
|
||||
left_delta="-285"
|
||||
max_val="6"
|
||||
name="QualityPerformanceSelection"
|
||||
show_text="false"
|
||||
top_delta="-1"
|
||||
width="275">
|
||||
<slider.commit_callback
|
||||
function="Pref.QualityPerformance"/>
|
||||
</slider>
|
||||
<text
|
||||
type="string"
|
||||
length="1"
|
||||
follows="left|top"
|
||||
halign="center"
|
||||
height="12"
|
||||
layout="topleft"
|
||||
left="190"
|
||||
name="ShadersPrefText"
|
||||
top_delta="20"
|
||||
width="80">
|
||||
Low
|
||||
</text>
|
||||
<text
|
||||
type="string"
|
||||
length="1"
|
||||
follows="left|top"
|
||||
halign="center"
|
||||
height="12"
|
||||
layout="topleft"
|
||||
left_delta="87"
|
||||
name="ShadersPrefText2"
|
||||
top_delta="0"
|
||||
width="80">
|
||||
Mid
|
||||
</text>
|
||||
<text
|
||||
type="string"
|
||||
length="1"
|
||||
follows="left|top"
|
||||
halign="center"
|
||||
height="12"
|
||||
layout="topleft"
|
||||
left_delta="87"
|
||||
name="ShadersPrefText3"
|
||||
top_delta="0"
|
||||
width="80">
|
||||
High
|
||||
</text>
|
||||
<text
|
||||
type="string"
|
||||
length="1"
|
||||
follows="left|top"
|
||||
halign="center"
|
||||
height="12"
|
||||
layout="topleft"
|
||||
left_delta="85"
|
||||
name="ShadersPrefText4"
|
||||
top_delta="0"
|
||||
width="80">
|
||||
Ultra
|
||||
</text>
|
||||
<text
|
||||
follows="left|top"
|
||||
font="SansSerifSmall"
|
||||
text_color="White"
|
||||
height="18"
|
||||
layout="topleft"
|
||||
top_pad="15"
|
||||
left="160"
|
||||
name="quality_desc"
|
||||
width="450">
|
||||
Choosing a preset will reset all manual changes you have made.
|
||||
</text>
|
||||
<view_border
|
||||
bevel_style="in"
|
||||
height="0"
|
||||
layout="topleft"
|
||||
name="border2"
|
||||
top_pad="5"
|
||||
left="20"
|
||||
width="540"/>
|
||||
<text
|
||||
follows="left|top"
|
||||
font="SansSerifSmall"
|
||||
text_color="White"
|
||||
height="36"
|
||||
layout="topleft"
|
||||
top_pad="20"
|
||||
left="20"
|
||||
name="distance_lbl"
|
||||
width="100"
|
||||
wrap="true">
|
||||
Visibility distance
|
||||
</text>
|
||||
<text
|
||||
follows="left|top"
|
||||
font="SansSerifSmall"
|
||||
text_color="White"
|
||||
height="18"
|
||||
layout="topleft"
|
||||
left_pad="40"
|
||||
name="faster_lbl"
|
||||
width="40"
|
||||
top_delta="0">
|
||||
Faster
|
||||
</text>
|
||||
<slider
|
||||
control_name="RenderFarClip"
|
||||
decimal_digits="0"
|
||||
follows="left|top"
|
||||
top_delta="-1"
|
||||
height="16"
|
||||
increment="8"
|
||||
initial_value="160"
|
||||
label_width="90"
|
||||
slider_label.halign="right"
|
||||
layout="topleft"
|
||||
min_val="32"
|
||||
max_val="1024"
|
||||
name="draw_distance"
|
||||
left_pad="5"
|
||||
width="310" />
|
||||
<text
|
||||
type="string"
|
||||
length="1"
|
||||
follows="left|top"
|
||||
height="12"
|
||||
layout="topleft"
|
||||
left_pad="-8"
|
||||
top_delta="0"
|
||||
name="draw_distance_m"
|
||||
width="20">
|
||||
m
|
||||
</text>
|
||||
<text
|
||||
follows="left|top"
|
||||
font="SansSerifSmall"
|
||||
text_color="White"
|
||||
height="18"
|
||||
layout="topleft"
|
||||
left_pad="0"
|
||||
top_delta="1"
|
||||
name="farther_lbl"
|
||||
width="40">
|
||||
Farther
|
||||
</text>
|
||||
<text
|
||||
follows="left|top"
|
||||
font="SansSerifSmall"
|
||||
text_color="White"
|
||||
height="18"
|
||||
layout="topleft"
|
||||
top_pad="15"
|
||||
left="160"
|
||||
name="distance_desc1"
|
||||
width="450">
|
||||
Keep this low for better performance, increase it to see further afield.
|
||||
</text>
|
||||
<view_border
|
||||
bevel_style="in"
|
||||
height="0"
|
||||
layout="topleft"
|
||||
name="border3"
|
||||
top_pad="5"
|
||||
left="20"
|
||||
width="540"/>
|
||||
<text
|
||||
follows="left|top"
|
||||
font="SansSerifSmall"
|
||||
text_color="White"
|
||||
height="18"
|
||||
layout="topleft"
|
||||
top_pad="20"
|
||||
left="20"
|
||||
name="environment_lbl"
|
||||
width="100">
|
||||
Environment
|
||||
</text>
|
||||
<text
|
||||
follows="left|top"
|
||||
font="SansSerifSmall"
|
||||
text_color="White"
|
||||
height="18"
|
||||
layout="topleft"
|
||||
top_delta="0"
|
||||
left="160"
|
||||
name="enhancements_desc"
|
||||
width="450">
|
||||
Reducing / eliminating shadows can be a boost to FPS but impacts
|
||||
the ambience and appearance of the scene.
|
||||
</text>
|
||||
<text
|
||||
type="string"
|
||||
length="1"
|
||||
follows="left|top"
|
||||
height="16"
|
||||
layout="topleft"
|
||||
left="160"
|
||||
name="RenderShadowDetailText"
|
||||
text_readonly_color="LabelDisabledColor"
|
||||
top_pad="20"
|
||||
width="128">
|
||||
Shadow sources:
|
||||
</text>
|
||||
<combo_box
|
||||
control_name="RenderShadowDetail"
|
||||
height="18"
|
||||
layout="topleft"
|
||||
right="-20"
|
||||
top_delta="0"
|
||||
name="ShadowDetail"
|
||||
width="150">
|
||||
<combo_box.item
|
||||
label="None"
|
||||
name="0"
|
||||
value="0"/>
|
||||
<combo_box.item
|
||||
label="Sun/Moon"
|
||||
name="1"
|
||||
value="1"/>
|
||||
<combo_box.item
|
||||
label="Sun/Moon + Projectors"
|
||||
name="2"
|
||||
value="2"/>
|
||||
</combo_box>
|
||||
<view_border
|
||||
bevel_style="in"
|
||||
height="0"
|
||||
layout="topleft"
|
||||
name="border3"
|
||||
top_pad="7"
|
||||
left="20"
|
||||
width="540"/>
|
||||
<text
|
||||
follows="left|top"
|
||||
font="SansSerifSmall"
|
||||
text_color="White"
|
||||
height="18"
|
||||
layout="topleft"
|
||||
top_pad="20"
|
||||
left="20"
|
||||
name="water_lbl"
|
||||
width="100">
|
||||
Water
|
||||
</text>
|
||||
<text
|
||||
follows="left|top"
|
||||
font="SansSerifSmall"
|
||||
text_color="White"
|
||||
height="18"
|
||||
layout="topleft"
|
||||
top_delta="0"
|
||||
left="160"
|
||||
name="water_desc"
|
||||
width="450">
|
||||
Reducing water effects quality can greatly improve frame rate.
|
||||
</text>
|
||||
<text
|
||||
type="string"
|
||||
length="1"
|
||||
follows="left|top"
|
||||
height="16"
|
||||
layout="topleft"
|
||||
name="ReflectionsText"
|
||||
text_readonly_color="LabelDisabledColor"
|
||||
top_pad="16"
|
||||
left="160"
|
||||
width="128">
|
||||
Water Reflections:
|
||||
</text>
|
||||
<combo_box
|
||||
control_name="RenderReflectionDetail"
|
||||
height="18"
|
||||
layout="topleft"
|
||||
right="-20"
|
||||
top_delta="0"
|
||||
name="Reflections"
|
||||
width="150">
|
||||
<combo_box.item
|
||||
label="None; opaque"
|
||||
name="-2"
|
||||
value="-2"/>
|
||||
<combo_box.item
|
||||
label="None; transparent"
|
||||
name="-1"
|
||||
value="-1"/>
|
||||
<combo_box.item
|
||||
label="Minimal"
|
||||
name="0"
|
||||
value="0"/>
|
||||
<combo_box.item
|
||||
label="Terrain and trees"
|
||||
name="1"
|
||||
value="1"/>
|
||||
<combo_box.item
|
||||
label="All static objects"
|
||||
name="2"
|
||||
value="2"/>
|
||||
<combo_box.item
|
||||
label="All avatars and objects"
|
||||
name="3"
|
||||
value="3"/>
|
||||
<combo_box.item
|
||||
label="Everything"
|
||||
name="4"
|
||||
value="4"/>
|
||||
</combo_box>
|
||||
<view_border
|
||||
bevel_style="in"
|
||||
height="0"
|
||||
layout="topleft"
|
||||
name="border4"
|
||||
top_pad="7"
|
||||
left="20"
|
||||
width="540"/>
|
||||
<text
|
||||
follows="left|top"
|
||||
font="SansSerifSmall"
|
||||
text_color="White"
|
||||
height="18"
|
||||
layout="topleft"
|
||||
top_pad="20"
|
||||
left="20"
|
||||
name="photo_lbl"
|
||||
width="100">
|
||||
Photography
|
||||
</text>
|
||||
<text
|
||||
follows="left|top"
|
||||
font="SansSerifSmall"
|
||||
text_color="White"
|
||||
height="48"
|
||||
layout="topleft"
|
||||
top_delta="0"
|
||||
left="160"
|
||||
name="photo_desc"
|
||||
width="350">
|
||||
Photographers need high quality, but this is often
|
||||
at the cost of frame rate. [APP_NAME] phototools can
|
||||
help you find the right balance.
|
||||
</text>
|
||||
<button
|
||||
name="open_phototools"
|
||||
label="Phototools"
|
||||
tool_tip="Open the dedicated photo tools for advanced photo settings."
|
||||
top_delta="0"
|
||||
right="-20"
|
||||
height="23"
|
||||
width="120"
|
||||
follows="bottom|right"
|
||||
layout="topleft">
|
||||
<button.init_callback
|
||||
function="Button.SetFloaterToggle"
|
||||
parameter="phototools"/>
|
||||
</button>
|
||||
</panel>
|
||||
|
|
@ -2665,6 +2665,7 @@ Try enclosing path to the editor with double quotes.
|
|||
<string name="Command_MiniMap_Label">Mini-map</string>
|
||||
<string name="Command_Move_Label">Walk / run / fly</string>
|
||||
<string name="Command_People_Label">People</string>
|
||||
<string name="Command_Performance_Label">Graphics speed</string>
|
||||
<string name="Command_Picks_Label">Picks</string>
|
||||
<string name="Command_Places_Label">Places</string>
|
||||
<string name="Command_Preferences_Label">Preferences</string>
|
||||
|
|
@ -2730,6 +2731,7 @@ Try enclosing path to the editor with double quotes.
|
|||
<string name="Command_MiniMap_Tooltip">Show nearby people (CTRL+SHIFT+M)</string>
|
||||
<string name="Command_Move_Tooltip">Moving your avatar</string>
|
||||
<string name="Command_People_Tooltip">Friends, groups, and nearby people (CTRL+SHIFT+A)</string>
|
||||
<string name="Command_Performance_Tooltip">Tune graphics settings</string>
|
||||
<string name="Command_Picks_Tooltip">Places to show as favorites in your profile</string>
|
||||
<string name="Command_Places_Tooltip">Places you've saved (ALT+H)</string>
|
||||
<string name="Command_Preferences_Tooltip">Preferences (CTRL+P)</string>
|
||||
|
|
@ -2928,7 +2930,7 @@ Try enclosing path to the editor with double quotes.
|
|||
<string name="preset_combo_label">-Empty list-</string>
|
||||
<string name="Default">Default</string>
|
||||
<string name="none_paren_cap">(None)</string>
|
||||
<string name="no_limit">No Limit</string>
|
||||
<string name="no_limit">No limit</string>
|
||||
|
||||
<string name="Mav_Details_MAV_FOUND_DEGENERATE_TRIANGLES">
|
||||
The physics shape contains triangles which are too small. Try simplifying the physics model.
|
||||
|
|
|
|||
|
|
@ -1,12 +1,12 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
|
||||
<floater name="floater_avatar_render_settings" title="Ustawienia renderowania awatarów">
|
||||
<floater name="floater_avatar_render_settings" title="Wyjątki renderowania awatarów">
|
||||
<string name="av_never_render" value="Nigdy"/>
|
||||
<string name="av_always_render" value="Zawsze"/>
|
||||
<filter_editor label="Filtruj ludzi" name="people_filter_input" />
|
||||
<menu_button name="plus_btn" tool_tip="Akcje dotyczące wybranej osoby" />
|
||||
<name_list name="render_settings_list">
|
||||
<name_list.columns label="Imię" name="name" />
|
||||
<name_list.columns label="Renderowanie" name="setting" />
|
||||
<name_list.columns label="Dodano" name="timestamp" />
|
||||
<name_list.columns label="Pełne detale" name="setting" />
|
||||
</name_list>
|
||||
<panel name="add_subpanel">
|
||||
<menu_button label="Dodaj kogoś..." name="plus_btn" tool_tip="Działania na wybranej osobie" />
|
||||
</panel>
|
||||
</floater>
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue