Merge branch 'master' of github.com:singularity-viewer/SingularityViewer
Conflicts: indra/newview/hippogridmanager.cpp indra/newview/hippogridmanager.h
This commit is contained in:
@@ -30,8 +30,6 @@ include(BuildVersion)
|
||||
|
||||
include(UnixInstall)
|
||||
|
||||
set (DISABLE_FATAL_WARNINGS CACHE BOOL TRUE)
|
||||
|
||||
if (NOT CMAKE_CONFIGURATION_TYPES AND NOT CMAKE_BUILD_TYPE)
|
||||
set(CMAKE_BUILD_TYPE Release CACHE STRING
|
||||
"Build type. One of: Debug Release RelWithDebInfo" FORCE)
|
||||
|
||||
@@ -270,10 +270,10 @@ endif (DARWIN)
|
||||
|
||||
if (LINUX OR DARWIN)
|
||||
if(${CMAKE_C_COMPILER} MATCHES "gcc*")
|
||||
set(UNIX_WARNINGS "-Wall -Wno-sign-compare -Wno-trigraphs")
|
||||
set(UNIX_WARNINGS "-Wall -Wno-sign-compare -Wno-trigraphs")
|
||||
set(UNIX_CXX_WARNINGS "${UNIX_WARNINGS} -Wno-reorder -Wno-non-virtual-dtor -Woverloaded-virtual")
|
||||
elseif(${CMAKE_C_COMPILER} MATCHES "clang*")
|
||||
set(UNIX_WARNINGS "-Wall -Wno-sign-compare -Wno-trigraphs -Wno-tautological-compare -Wno-char-subscripts -Wno-gnu -Wno-logical-op-parentheses -Wno-non-virtual-dtor ")
|
||||
set(UNIX_WARNINGS "-Wall -Wno-sign-compare -Wno-trigraphs -Wno-tautological-compare -Wno-char-subscripts -Wno-gnu -Wno-logical-op-parentheses -Wno-non-virtual-dtor")
|
||||
set(UNIX_WARNINGS "${UNIX_WARNINGS} -Woverloaded-virtual -Wno-parentheses-equality -Wno-reorder -Wno-unused-function -Wno-unused-value -Wno-unused-variable")
|
||||
set(UNIX_CXX_WARNINGS "${UNIX_WARNINGS}")
|
||||
elseif(${CMAKE_C_COMPILER} MATCHES "icc")
|
||||
@@ -281,8 +281,11 @@ if (LINUX OR DARWIN)
|
||||
set(UNIX_CXX_WARNINGS "${UNIX_WARNINGS}")
|
||||
endif()
|
||||
|
||||
# Use -DDISABLE_FATAL_WARNINGS:BOOL=FALSE during configuration to enable fatal warnings.
|
||||
set(DISABLE_FATAL_WARNINGS TRUE CACHE BOOL "Set this to FALSE to enable fatal warnings.")
|
||||
if (NOT DISABLE_FATAL_WARNINGS)
|
||||
set(UNIX_WARNINGS "${UNIX_WARNINGS} -Werror")
|
||||
set(UNIX_CXX_WARNINGS "${UNIX_CXX_WARNINGS} -Werror")
|
||||
endif (NOT DISABLE_FATAL_WARNINGS)
|
||||
|
||||
set(CMAKE_C_FLAGS "${UNIX_WARNINGS} ${CMAKE_C_FLAGS}")
|
||||
|
||||
@@ -203,7 +203,6 @@ inline T* get_ptr_in_map(const std::map<K,T*>& inmap, const K& key)
|
||||
template <typename K, typename T>
|
||||
inline bool is_in_map(const std::map<K,T>& inmap, const K& key)
|
||||
{
|
||||
typedef typename std::map<K,T>::const_iterator map_iter;
|
||||
if(inmap.find(key) == inmap.end())
|
||||
{
|
||||
return false;
|
||||
|
||||
@@ -22,6 +22,7 @@ include_directories(
|
||||
)
|
||||
|
||||
set(llmessage_SOURCE_FILES
|
||||
aiaverage.cpp
|
||||
aicurl.cpp
|
||||
aicurleasyrequeststatemachine.cpp
|
||||
aicurlperservice.cpp
|
||||
@@ -109,6 +110,7 @@ set(llmessage_SOURCE_FILES
|
||||
set(llmessage_HEADER_FILES
|
||||
CMakeLists.txt
|
||||
|
||||
aiaverage.h
|
||||
aicurl.h
|
||||
aicurleasyrequeststatemachine.h
|
||||
aicurlperservice.h
|
||||
|
||||
81
indra/llmessage/aiaverage.cpp
Normal file
81
indra/llmessage/aiaverage.cpp
Normal file
@@ -0,0 +1,81 @@
|
||||
/**
|
||||
* @file aiaverage.cpp
|
||||
* @brief Implementation of AIAverage
|
||||
*
|
||||
* Copyright (c) 2013, Aleric Inglewood.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* There are special exceptions to the terms and conditions of the GPL as
|
||||
* it is applied to this Source Code. View the full text of the exception
|
||||
* in the file doc/FLOSS-exception.txt in this software distribution.
|
||||
*
|
||||
* CHANGELOG
|
||||
* and additional copyright holders.
|
||||
*
|
||||
* 11/04/2013
|
||||
* Initial version, written by Aleric Inglewood @ SL
|
||||
*/
|
||||
|
||||
#include "sys.h"
|
||||
#include "aiaverage.h"
|
||||
#include "llerror.h" // llassert
|
||||
|
||||
void AIAverage::cleanup(U64 clock_tick)
|
||||
{
|
||||
// This expression can fail because the curl thread caches the time in
|
||||
// sTime_10ms for the duration of an entire loop. Therefore, the time can
|
||||
// go into the next 40ms and a texture fetch worker thread might call
|
||||
// cleanup() with that time, setting mCurrentClock to a value (one)
|
||||
// larger than sTime_10ms / 4. Next, the curl thread can continue to call
|
||||
// this function with the smaller value; in that case just add the new
|
||||
// data to the current bucket.
|
||||
//
|
||||
// Or, this is just the one-time initialization that happens the first
|
||||
// time this is called. In that case initialize just mCurrentClock:
|
||||
// the rest is already initialized upon construction.
|
||||
if (LL_LIKELY(clock_tick > mCurrentClock))
|
||||
{
|
||||
// Advance to the next bucket.
|
||||
++mCurrentBucket;
|
||||
mCurrentBucket %= mNrOfBuckets;
|
||||
// Initialize the new bucket.
|
||||
mData[mCurrentBucket].time = clock_tick;
|
||||
// Clean up old buckets.
|
||||
U64 old_time = clock_tick - mNrOfBuckets;
|
||||
if (LL_UNLIKELY(mTail == mCurrentBucket) || // Extremely unlikely: only happens when data was added EVERY clock tick for the past mNrOfBuckets clock ticks.
|
||||
mData[mTail].time <= old_time)
|
||||
{
|
||||
do
|
||||
{
|
||||
mSum -= mData[mTail].sum;
|
||||
mN -= mData[mTail].n;
|
||||
mData[mTail].sum = 0;
|
||||
mData[mTail].n = 0;
|
||||
++mTail;
|
||||
if (LL_UNLIKELY(mTail == mNrOfBuckets))
|
||||
{
|
||||
mTail = 0;
|
||||
}
|
||||
}
|
||||
while (mData[mTail].time <= old_time);
|
||||
}
|
||||
// This was set to zero when mTail passed this point (likely not this call, but a few calls ago).
|
||||
llassert(mData[mCurrentBucket].sum == 0 &&
|
||||
mData[mCurrentBucket].n == 0);
|
||||
}
|
||||
mCurrentClock = clock_tick;
|
||||
return;
|
||||
}
|
||||
|
||||
108
indra/llmessage/aiaverage.h
Normal file
108
indra/llmessage/aiaverage.h
Normal file
@@ -0,0 +1,108 @@
|
||||
/**
|
||||
* @file aiaverage.h
|
||||
* @brief Definition of class AIAverage
|
||||
*
|
||||
* Copyright (c) 2013, Aleric Inglewood.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* There are special exceptions to the terms and conditions of the GPL as
|
||||
* it is applied to this Source Code. View the full text of the exception
|
||||
* in the file doc/FLOSS-exception.txt in this software distribution.
|
||||
*
|
||||
* CHANGELOG
|
||||
* and additional copyright holders.
|
||||
*
|
||||
* 11/04/2013
|
||||
* Initial version, written by Aleric Inglewood @ SL
|
||||
*/
|
||||
|
||||
#ifndef AIAVERAGE_H
|
||||
#define AIAVERAGE_H
|
||||
|
||||
#include "llpreprocessor.h"
|
||||
#include "stdtypes.h" // U32, U64
|
||||
#include "llthread.h" // LLMutex
|
||||
#include <cstddef> // size_t
|
||||
#include <vector>
|
||||
|
||||
class AIAverage {
|
||||
private:
|
||||
struct Data {
|
||||
U32 sum; // Accumulated sum of the 'n' passed to operator()(size_t n, U64 clock_tick) with clock_tick == time.
|
||||
U32 n; // The number of calls to operator().
|
||||
U64 time; // The clock_tick as passed to operator()(size_t n, U64 clock_tick) that sum corresponds to.
|
||||
};
|
||||
|
||||
U64 mCurrentClock; // The current (last) time that operator() was called with, or -1 when not initialized.
|
||||
int mTail; // The oldest bucket with still valid data.
|
||||
int mCurrentBucket; // The bucket that corresponds to mCurrentClock.
|
||||
size_t mSum; // The sum of all the 'n' passed to operator()(size_t n, U64 clock_tick) for all passed mNrOfBuckets time units.
|
||||
U32 mN; // The number of calls to operator().
|
||||
int const mNrOfBuckets; // Size of mData.
|
||||
std::vector<Data> mData; // The buckets.
|
||||
LLMutex mLock; // Mutex for all of the above data.
|
||||
|
||||
public:
|
||||
AIAverage(int number_of_buckets) : mCurrentClock(~(U64)0), mTail(0), mCurrentBucket(0), mSum(0), mN(0), mNrOfBuckets(number_of_buckets), mData(number_of_buckets)
|
||||
{
|
||||
// Fill mData with all zeroes (much faster than adding a constructor to Data).
|
||||
std::memset(&*mData.begin(), 0, number_of_buckets * sizeof(Data));
|
||||
}
|
||||
size_t addData(U32 n, U64 clock_tick)
|
||||
{
|
||||
DoutEntering(dc::curl, "AIAverage::addData(" << n << ", " << clock_tick << ")");
|
||||
mLock.lock();
|
||||
if (LL_UNLIKELY(clock_tick != mCurrentClock))
|
||||
{
|
||||
cleanup(clock_tick);
|
||||
}
|
||||
mSum += n;
|
||||
mN += 1;
|
||||
mData[mCurrentBucket].sum += n;
|
||||
mData[mCurrentBucket].n += 1;
|
||||
size_t sum = mSum;
|
||||
mLock.unlock();
|
||||
Dout(dc::curl, "Current sum: " << sum << ", average: " << (sum / mN));
|
||||
return sum;
|
||||
}
|
||||
size_t truncateData(U64 clock_tick)
|
||||
{
|
||||
mLock.lock();
|
||||
if (clock_tick != mCurrentClock)
|
||||
{
|
||||
cleanup(clock_tick);
|
||||
}
|
||||
size_t sum = mSum;
|
||||
mLock.unlock();
|
||||
return sum;
|
||||
}
|
||||
double getAverage(double avg_no_data)
|
||||
{
|
||||
mLock.lock();
|
||||
double avg = mSum;
|
||||
llassert(mN != 0 || mSum == 0);
|
||||
if (LL_UNLIKELY(mN == 0))
|
||||
avg = avg_no_data;
|
||||
else
|
||||
avg /= mN;
|
||||
mLock.unlock();
|
||||
return avg;
|
||||
}
|
||||
|
||||
private:
|
||||
void cleanup(U64 clock_tick);
|
||||
};
|
||||
|
||||
#endif // AIAVERAGE
|
||||
@@ -1267,8 +1267,9 @@ static int const HTTP_REDIRECTS_DEFAULT = 10;
|
||||
LLChannelDescriptors const BufferedCurlEasyRequest::sChannels;
|
||||
LLMutex BufferedCurlEasyRequest::sResponderCallbackMutex;
|
||||
bool BufferedCurlEasyRequest::sShuttingDown = false;
|
||||
AIAverage BufferedCurlEasyRequest::sHTTPBandwidth(25);
|
||||
|
||||
BufferedCurlEasyRequest::BufferedCurlEasyRequest() : mRequestTransferedBytes(0), mResponseTransferedBytes(0), mBufferEventsTarget(NULL), mStatus(HTTP_INTERNAL_ERROR_OTHER)
|
||||
BufferedCurlEasyRequest::BufferedCurlEasyRequest() : mRequestTransferedBytes(0), mTotalRawBytes(0), mBufferEventsTarget(NULL), mStatus(HTTP_INTERNAL_ERROR_OTHER)
|
||||
{
|
||||
AICurlInterface::Stats::BufferedCurlEasyRequest_count++;
|
||||
}
|
||||
@@ -1332,7 +1333,7 @@ void BufferedCurlEasyRequest::resetState(void)
|
||||
mOutput.reset();
|
||||
mInput.reset();
|
||||
mRequestTransferedBytes = 0;
|
||||
mResponseTransferedBytes = 0;
|
||||
mTotalRawBytes = 0;
|
||||
mBufferEventsTarget = NULL;
|
||||
mStatus = HTTP_INTERNAL_ERROR_OTHER;
|
||||
}
|
||||
|
||||
@@ -45,6 +45,7 @@
|
||||
#include <map>
|
||||
#include <boost/intrusive_ptr.hpp>
|
||||
#include "aithreadsafe.h"
|
||||
#include "aiaverage.h"
|
||||
|
||||
class AICurlEasyRequest;
|
||||
class AIPerServiceRequestQueue;
|
||||
@@ -89,7 +90,7 @@ class AIPerServiceRequestQueue {
|
||||
static threadsafe_instance_map_type sInstanceMap; // Map of AIPerServiceRequestQueue instances with the hostname as key.
|
||||
|
||||
friend class AIThreadSafeSimpleDC<AIPerServiceRequestQueue>; //threadsafe_PerServiceRequestQueue
|
||||
AIPerServiceRequestQueue(void) : mQueuedCommands(0), mAdded(0), mQueueEmpty(false), mQueueFull(false), mRequestStarvation(false) { }
|
||||
AIPerServiceRequestQueue(void) : mQueuedCommands(0), mAdded(0), mQueueEmpty(false), mQueueFull(false), mRequestStarvation(false), mHTTPBandwidth(25) { } // 25 = 1000 ms / 40 ms.
|
||||
|
||||
public:
|
||||
typedef instance_map_type::iterator iterator;
|
||||
@@ -124,6 +125,8 @@ class AIPerServiceRequestQueue {
|
||||
static bool sQueueFull; // Set to true when sTotalQueued is still larger than zero after popping any queue.
|
||||
static bool sRequestStarvation; // Set to true when any queue was about to be popped when sTotalQueued was already zero.
|
||||
|
||||
AIAverage mHTTPBandwidth; // Keeps track on number of bytes received for this service in the past second.
|
||||
|
||||
public:
|
||||
void added_to_command_queue(void) { ++mQueuedCommands; }
|
||||
void removed_from_command_queue(void) { --mQueuedCommands; llassert(mQueuedCommands >= 0); }
|
||||
@@ -141,14 +144,17 @@ class AIPerServiceRequestQueue {
|
||||
S32 pipelined_requests(void) const { return mQueuedCommands + mQueuedRequests.size() + mAdded; }
|
||||
static S32 total_queued_size(void) { return sTotalQueued; }
|
||||
|
||||
AIAverage& bandwidth(void) { return mHTTPBandwidth; }
|
||||
AIAverage const& bandwidth(void) const { return mHTTPBandwidth; }
|
||||
|
||||
// Returns true if curl can handle another request for this host.
|
||||
// Should return false if the maximum allowed HTTP bandwidth is reached, or when
|
||||
// the latency between request and actual delivery becomes too large.
|
||||
static bool wantsMoreHTTPRequestsFor(AIPerServiceRequestQueuePtr const& per_service, bool too_much_bandwidth);
|
||||
static bool wantsMoreHTTPRequestsFor(AIPerServiceRequestQueuePtr const& per_service, F32 max_kbps, bool no_bandwidth_throttling);
|
||||
|
||||
private:
|
||||
// Disallow copying.
|
||||
AIPerServiceRequestQueue(AIPerServiceRequestQueue const&) { }
|
||||
AIPerServiceRequestQueue(AIPerServiceRequestQueue const&) : mHTTPBandwidth(0) { }
|
||||
};
|
||||
|
||||
namespace AICurlPrivate {
|
||||
|
||||
@@ -396,6 +396,9 @@ class BufferedCurlEasyRequest : public CurlEasyRequest {
|
||||
// Post-initialization, set the parent to pass the events to.
|
||||
void send_buffer_events_to(AIBufferedCurlEasyRequestEvents* target) { mBufferEventsTarget = target; }
|
||||
|
||||
// Called whenever new body data was (might be) received. Keeps track of the used HTTP bandwidth.
|
||||
void update_body_bandwidth(void);
|
||||
|
||||
protected:
|
||||
// Events from this class.
|
||||
/*virtual*/ void received_HTTP_header(void);
|
||||
@@ -411,13 +414,14 @@ class BufferedCurlEasyRequest : public CurlEasyRequest {
|
||||
U32 mStatus; // HTTP status, decoded from the first header line.
|
||||
std::string mReason; // The "reason" from the same header line.
|
||||
U32 mRequestTransferedBytes;
|
||||
U32 mResponseTransferedBytes;
|
||||
size_t mTotalRawBytes; // Raw body data (still, possibly, compressed) received from the server so far.
|
||||
AIBufferedCurlEasyRequestEvents* mBufferEventsTarget;
|
||||
|
||||
public:
|
||||
static LLChannelDescriptors const sChannels; // Channel object for mInput (channel out()) and mOutput (channel in()).
|
||||
static LLMutex sResponderCallbackMutex; // Locked while calling back any overridden ResponderBase::finished and/or accessing sShuttingDown.
|
||||
static bool sShuttingDown; // If true, no additional calls to ResponderBase::finished will be made anymore.
|
||||
static AIAverage sHTTPBandwidth; // HTTP bandwidth usage of all services combined.
|
||||
|
||||
private:
|
||||
// This class may only be created by constructing a ThreadSafeBufferedCurlEasyRequest.
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
#include "aihttptimeoutpolicy.h"
|
||||
#include "aihttptimeout.h"
|
||||
#include "aicurlperservice.h"
|
||||
#include "aiaverage.h"
|
||||
#include "lltimer.h" // ms_sleep, get_clock_count
|
||||
#include "llhttpstatuscodes.h"
|
||||
#include "llbuffer.h"
|
||||
@@ -1829,6 +1830,8 @@ void MultiHandle::check_msg_queue(void)
|
||||
void MultiHandle::finish_easy_request(AICurlEasyRequest const& easy_request, CURLcode result)
|
||||
{
|
||||
AICurlEasyRequest_wat curl_easy_request_w(*easy_request);
|
||||
// Final body bandwidth update.
|
||||
curl_easy_request_w->update_body_bandwidth();
|
||||
// Store the result in the easy handle.
|
||||
curl_easy_request_w->storeResult(result);
|
||||
#ifdef CWDEBUG
|
||||
@@ -2023,10 +2026,10 @@ void BufferedCurlEasyRequest::processOutput(void)
|
||||
if (responseCode == HTTP_INTERNAL_ERROR_LOW_SPEED)
|
||||
{
|
||||
// Rewrite error to something understandable.
|
||||
responseReason = llformat("Connection to \"%s\" stalled: download speed dropped below %u bytes/s for %u seconds (up till that point, %s received a total of %u bytes). "
|
||||
responseReason = llformat("Connection to \"%s\" stalled: download speed dropped below %u bytes/s for %u seconds (up till that point, %s received a total of %lu bytes). "
|
||||
"To change these values, go to Advanced --> Debug Settings and change CurlTimeoutLowSpeedLimit and CurlTimeoutLowSpeedTime respectively.",
|
||||
mResponder->getURL().c_str(), mResponder->getHTTPTimeoutPolicy().getLowSpeedLimit(), mResponder->getHTTPTimeoutPolicy().getLowSpeedTime(),
|
||||
mResponder->getName(), mResponseTransferedBytes);
|
||||
mResponder->getName(), mTotalRawBytes);
|
||||
}
|
||||
setopt(CURLOPT_FRESH_CONNECT, TRUE);
|
||||
}
|
||||
@@ -2093,7 +2096,9 @@ size_t BufferedCurlEasyRequest::curlWriteCallback(char* data, size_t size, size_
|
||||
// BufferedCurlEasyRequest::setBodyLimit is never called, so buffer_w->mBodyLimit is infinite.
|
||||
//S32 bytes = llmin(size * nmemb, buffer_w->mBodyLimit); buffer_w->mBodyLimit -= bytes;
|
||||
self_w->getOutput()->append(sChannels.in(), (U8 const*)data, bytes);
|
||||
self_w->mResponseTransferedBytes += bytes; // Accumulate data received from the server.
|
||||
// Update HTTP bandwith.
|
||||
self_w->update_body_bandwidth();
|
||||
// Update timeout administration.
|
||||
if (self_w->httptimeout()->data_received(bytes)) // Update timeout administration.
|
||||
{
|
||||
// Transfer timed out. Return 0 which will abort with error CURLE_WRITE_ERROR.
|
||||
@@ -2102,6 +2107,25 @@ size_t BufferedCurlEasyRequest::curlWriteCallback(char* data, size_t size, size_
|
||||
return bytes;
|
||||
}
|
||||
|
||||
void BufferedCurlEasyRequest::update_body_bandwidth(void)
|
||||
{
|
||||
double size_download; // Total amount of raw bytes received so far (ie. still compressed, 'bytes' is uncompressed).
|
||||
getinfo(CURLINFO_SIZE_DOWNLOAD, &size_download);
|
||||
size_t total_raw_bytes = size_download;
|
||||
size_t raw_bytes = total_raw_bytes - mTotalRawBytes;
|
||||
mTotalRawBytes = total_raw_bytes;
|
||||
// Note that in some cases (like HTTP_PARTIAL_CONTENT), the output of CURLINFO_SIZE_DOWNLOAD lags
|
||||
// behind and will return 0 the first time, and the value of the previous chunk the next time.
|
||||
// The last call from MultiHandle::finish_easy_request recorrects this, in that case.
|
||||
if (raw_bytes > 0)
|
||||
{
|
||||
U64 const sTime_40ms = curlthread::HTTPTimeout::sTime_10ms >> 2;
|
||||
AIAverage& http_bandwidth(PerServiceRequestQueue_wat(*getPerServicePtr())->bandwidth());
|
||||
http_bandwidth.addData(raw_bytes, sTime_40ms);
|
||||
sHTTPBandwidth.addData(raw_bytes, sTime_40ms);
|
||||
}
|
||||
}
|
||||
|
||||
//static
|
||||
size_t BufferedCurlEasyRequest::curlReadCallback(char* data, size_t size, size_t nmemb, void* user_data)
|
||||
{
|
||||
@@ -2189,6 +2213,11 @@ size_t BufferedCurlEasyRequest::curlHeaderCallback(char* data, size_t size, size
|
||||
self_w->httptimeout()->being_redirected();
|
||||
}
|
||||
}
|
||||
// Update HTTP bandwidth.
|
||||
U64 const sTime_40ms = curlthread::HTTPTimeout::sTime_10ms >> 2;
|
||||
AIAverage& http_bandwidth(PerServiceRequestQueue_wat(*self_w->getPerServicePtr())->bandwidth());
|
||||
http_bandwidth.addData(header_len, sTime_40ms);
|
||||
sHTTPBandwidth.addData(header_len, sTime_40ms);
|
||||
// Update timeout administration. This must be done after the status is already known.
|
||||
if (self_w->httptimeout()->data_received(header_len/*,*/ ASSERT_ONLY_COMMA(self_w->upload_error_status())))
|
||||
{
|
||||
@@ -2533,6 +2562,14 @@ U32 getNumHTTPAdded(void)
|
||||
return AICurlPrivate::curlthread::MultiHandle::total_added_size();
|
||||
}
|
||||
|
||||
size_t getHTTPBandwidth(void)
|
||||
{
|
||||
using namespace AICurlPrivate;
|
||||
|
||||
U64 const sTime_40ms = get_clock_count() * curlthread::HTTPTimeout::sClockWidth_40ms;
|
||||
return BufferedCurlEasyRequest::sHTTPBandwidth.truncateData(sTime_40ms);
|
||||
}
|
||||
|
||||
} // namespace AICurlInterface
|
||||
|
||||
// Return true if we want at least one more HTTP request for this host.
|
||||
@@ -2560,7 +2597,7 @@ U32 getNumHTTPAdded(void)
|
||||
// running requests (in MultiHandle::mAddedEasyRequests)).
|
||||
//
|
||||
//static
|
||||
bool AIPerServiceRequestQueue::wantsMoreHTTPRequestsFor(AIPerServiceRequestQueuePtr const& per_service, bool too_much_bandwidth)
|
||||
bool AIPerServiceRequestQueue::wantsMoreHTTPRequestsFor(AIPerServiceRequestQueuePtr const& per_service, F32 max_kbps, bool no_bandwidth_throttling)
|
||||
{
|
||||
using namespace AICurlPrivate;
|
||||
using namespace AICurlPrivate::curlthread;
|
||||
@@ -2587,17 +2624,21 @@ bool AIPerServiceRequestQueue::wantsMoreHTTPRequestsFor(AIPerServiceRequestQueue
|
||||
|
||||
// Check if it's ok to get a new request for this particular host and update the per-host threshold.
|
||||
|
||||
AIAverage* http_bandwidth_ptr;
|
||||
|
||||
// Atomic read max_pipelined_requests_per_service for the below calculations.
|
||||
S32 const max_pipelined_requests_per_service_cache = max_pipelined_requests_per_service;
|
||||
{
|
||||
PerServiceRequestQueue_rat per_service_r(*per_service);
|
||||
S32 const pipelined_requests_per_service = per_service_r->pipelined_requests();
|
||||
PerServiceRequestQueue_wat per_service_w(*per_service);
|
||||
S32 const pipelined_requests_per_service = per_service_w->pipelined_requests();
|
||||
reject = pipelined_requests_per_service >= max_pipelined_requests_per_service_cache;
|
||||
equal = pipelined_requests_per_service == max_pipelined_requests_per_service_cache;
|
||||
increment_threshold = per_service_r->mRequestStarvation;
|
||||
decrement_threshold = per_service_r->mQueueFull && !per_service_r->mQueueEmpty;
|
||||
increment_threshold = per_service_w->mRequestStarvation;
|
||||
decrement_threshold = per_service_w->mQueueFull && !per_service_w->mQueueEmpty;
|
||||
// Reset flags.
|
||||
per_service_r->mQueueFull = per_service_r->mQueueEmpty = per_service_r->mRequestStarvation = false;
|
||||
per_service_w->mQueueFull = per_service_w->mQueueEmpty = per_service_w->mRequestStarvation = false;
|
||||
// Grab per service bandwidth object.
|
||||
http_bandwidth_ptr = &per_service_w->bandwidth();
|
||||
}
|
||||
if (decrement_threshold)
|
||||
{
|
||||
@@ -2621,10 +2662,69 @@ bool AIPerServiceRequestQueue::wantsMoreHTTPRequestsFor(AIPerServiceRequestQueue
|
||||
return false;
|
||||
}
|
||||
|
||||
//AIFIXME: better bandwidth check here.
|
||||
if (too_much_bandwidth)
|
||||
if (!no_bandwidth_throttling)
|
||||
{
|
||||
return false; // wait
|
||||
// Throttle on bandwidth usage.
|
||||
|
||||
static size_t throttle_fraction = 1024; // A value between 0 and 1024: each service is throttled when it uses more than max_bandwidth * (throttle_fraction/1024) bandwidth.
|
||||
static AIAverage fraction(25); // Average over 25 * 40ms = 1 second.
|
||||
static U64 last_sTime_40ms = 0;
|
||||
|
||||
// Truncate the sums to the last second, and get their value.
|
||||
U64 const sTime_40ms = get_clock_count() * HTTPTimeout::sClockWidth_40ms; // Time in 40ms units.
|
||||
size_t const max_bandwidth = 125.f * max_kbps; // Convert kbps to bytes per second.
|
||||
size_t const total_bandwidth = BufferedCurlEasyRequest::sHTTPBandwidth.truncateData(sTime_40ms); // Bytes received in the past second.
|
||||
size_t const service_bandwidth = http_bandwidth_ptr->truncateData(sTime_40ms); // Idem for just this service.
|
||||
if (sTime_40ms > last_sTime_40ms)
|
||||
{
|
||||
// Only add throttle_fraction once every 40 ms at most.
|
||||
// It's ok to ignore other values in the same 40 ms because the value only changes on the scale of 1 second.
|
||||
fraction.addData(throttle_fraction, sTime_40ms);
|
||||
last_sTime_40ms = sTime_40ms;
|
||||
}
|
||||
double fraction_avg = fraction.getAverage(1024.0); // throttle_fraction averaged over the past second, or 1024 if there is no data.
|
||||
|
||||
// Adjust throttle_fraction based on total bandwidth usage.
|
||||
if (total_bandwidth == 0)
|
||||
throttle_fraction = 1024;
|
||||
else
|
||||
{
|
||||
// This is the main formula. It can be made plausible by assuming
|
||||
// an equilibrium where total_bandwidth == max_bandwidth and
|
||||
// thus throttle_fraction == fraction_avg for more than a second.
|
||||
//
|
||||
// Then, more bandwidth is being used (for example because another
|
||||
// service starts downloading). Assuming that all services that use
|
||||
// a significant portion of the bandwidth, the new service included,
|
||||
// must be throttled (all using the same bandwidth; note that the
|
||||
// new service is immediately throttled at the same value), then
|
||||
// the limit should be reduced linear with the fraction:
|
||||
// max_bandwidth / total_bandwidth.
|
||||
//
|
||||
// For example, let max_bandwidth be 1. Let there be two throttled
|
||||
// services, each using 0.5 (fraction_avg = 1024/2). Lets the new
|
||||
// service use what it can: also 0.5 - then without reduction the
|
||||
// total_bandwidth would become 1.5, and throttle_fraction would
|
||||
// become (1024/2) * 1/1.5 = 1024/3: from 2 to 3 services.
|
||||
//
|
||||
// In reality, total_bandwidth would rise linear from 1.0 to 1.5 in
|
||||
// one second if the throttle fraction wasn't changed. However it is
|
||||
// changed here. The end result is that any change more or less
|
||||
// linear fades away in one second.
|
||||
throttle_fraction = fraction_avg * max_bandwidth / total_bandwidth;
|
||||
}
|
||||
if (throttle_fraction > 1024)
|
||||
throttle_fraction = 1024;
|
||||
if (total_bandwidth > max_bandwidth)
|
||||
{
|
||||
throttle_fraction *= 0.95;
|
||||
}
|
||||
|
||||
// Throttle this service if it uses too much bandwidth.
|
||||
if (service_bandwidth > (max_bandwidth * throttle_fraction / 1024))
|
||||
{
|
||||
return false; // wait
|
||||
}
|
||||
}
|
||||
|
||||
// Check if it's ok to get a new request based on the total number of requests and increment the threshold if appropriate.
|
||||
|
||||
@@ -97,8 +97,9 @@ namespace curlthread {
|
||||
// HTTPTimeout
|
||||
|
||||
//static
|
||||
F64 const HTTPTimeout::sClockWidth_10ms = 100.0 / calc_clock_frequency(); // Time between two clock ticks, in 10ms units.
|
||||
U64 HTTPTimeout::sTime_10ms; // Time in 10ms units, set once per select() exit.
|
||||
F64 const HTTPTimeout::sClockWidth_10ms = 100.0 / calc_clock_frequency(); // Time between two clock ticks, in 10ms units.
|
||||
F64 const HTTPTimeout::sClockWidth_40ms = HTTPTimeout::sClockWidth_10ms * 0.25; // Time between two clock ticks, in 40ms units.
|
||||
U64 HTTPTimeout::sTime_10ms; // Time in 10ms units, set once per select() exit.
|
||||
|
||||
// CURL-THREAD
|
||||
// This is called when body data was sent to the server socket.
|
||||
|
||||
@@ -89,6 +89,7 @@ class HTTPTimeout : public LLRefCount {
|
||||
U64 mStalled; // The time (sTime_10ms) at which this transaction is considered to be stalling if nothing is transfered anymore.
|
||||
public:
|
||||
static F64 const sClockWidth_10ms; // Time between two clock ticks in 10 ms units.
|
||||
static F64 const sClockWidth_40ms; // Time between two clock ticks in 40 ms units.
|
||||
static U64 sTime_10ms; // Time since the epoch in 10 ms units.
|
||||
#if defined(CWDEBUG) || defined(DEBUG_CURLIO)
|
||||
ThreadSafeBufferedCurlEasyRequest* mLockObj;
|
||||
|
||||
@@ -50,7 +50,6 @@
|
||||
#include "lldarray.h"
|
||||
#include "lldir.h"
|
||||
#include "llerror.h"
|
||||
#include "llerrorlegacy.h"
|
||||
#include "llfasttimer.h"
|
||||
#include "llhttpclient.h"
|
||||
#include "llhttpnodeadapter.h"
|
||||
|
||||
@@ -4921,7 +4921,18 @@ This should be as low as possible, but too low may break functionality</string>
|
||||
<key>Value</key>
|
||||
<integer>-1</integer>
|
||||
</map>
|
||||
<key>DebugStatModeTexture</key>
|
||||
<key>DebugStatModeHTTPTexture</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Mode of stat in Statistics floater</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>S32</string>
|
||||
<key>Value</key>
|
||||
<integer>-1</integer>
|
||||
</map>
|
||||
<key>DebugStatModeUDPTexture</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Mode of stat in Statistics floater</string>
|
||||
@@ -15140,6 +15151,17 @@ This should be as low as possible, but too low may break functionality</string>
|
||||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
<key>UseTypingBubbles</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Show typing indicator in avatar nametags</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
<key>UseDebugMenus</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
|
||||
@@ -329,6 +329,7 @@ void LLPrefsAscentChat::refreshValues()
|
||||
mHideTypingNotification = gSavedSettings.getBOOL("AscentHideTypingNotification");
|
||||
mShowGroupNameInChatIM = gSavedSettings.getBOOL("OptionShowGroupNameInChatIM");
|
||||
mShowDisplayNameChanges = gSavedSettings.getBOOL("ShowDisplayNameChanges");
|
||||
mUseTypingBubbles = gSavedSettings.getBOOL("UseTypingBubbles");
|
||||
mPlayTypingSound = gSavedSettings.getBOOL("PlayTypingSound");
|
||||
mHideNotificationsInChat = gSavedSettings.getBOOL("HideNotificationsInChat");
|
||||
mEnableMUPose = gSavedSettings.getBOOL("AscentAllowMUpose");
|
||||
@@ -545,6 +546,7 @@ void LLPrefsAscentChat::cancel()
|
||||
gSavedSettings.setBOOL("AscentHideTypingNotification", mHideTypingNotification);
|
||||
gSavedSettings.setBOOL("OptionShowGroupNameInChatIM", mShowGroupNameInChatIM);
|
||||
gSavedSettings.setBOOL("ShowDisplayNameChanges", mShowDisplayNameChanges);
|
||||
gSavedSettings.setBOOL("UseTypingBubbles", mUseTypingBubbles);
|
||||
gSavedSettings.setBOOL("PlayTypingSound", mPlayTypingSound);
|
||||
gSavedSettings.setBOOL("HideNotificationsInChat", mHideNotificationsInChat);
|
||||
gSavedSettings.setBOOL("AscentAllowMUpose", mEnableMUPose);
|
||||
|
||||
@@ -66,6 +66,7 @@ protected:
|
||||
BOOL mHideTypingNotification;
|
||||
BOOL mShowGroupNameInChatIM;
|
||||
bool mShowDisplayNameChanges;
|
||||
bool mUseTypingBubbles;
|
||||
BOOL mPlayTypingSound;
|
||||
BOOL mHideNotificationsInChat;
|
||||
BOOL mEnableMUPose;
|
||||
|
||||
@@ -69,42 +69,6 @@ HippoGridInfo::HippoGridInfo(const std::string& gridName) :
|
||||
// ********************************************************************
|
||||
// Getters
|
||||
|
||||
HippoGridInfo::Platform HippoGridInfo::getPlatform()
|
||||
{
|
||||
return mPlatform;
|
||||
}
|
||||
|
||||
bool HippoGridInfo::isOpenSimulator() const
|
||||
{
|
||||
return (mPlatform == HippoGridInfo::PLATFORM_OPENSIM || mPlatform == HippoGridInfo::PLATFORM_AURORA);
|
||||
}
|
||||
|
||||
bool HippoGridInfo::isAurora() const
|
||||
{
|
||||
return (mPlatform == HippoGridInfo::PLATFORM_AURORA);
|
||||
}
|
||||
|
||||
bool HippoGridInfo::isSecondLife() const
|
||||
{
|
||||
return (mPlatform == HippoGridInfo::PLATFORM_SECONDLIFE);
|
||||
}
|
||||
|
||||
bool HippoGridInfo::isInProductionGrid() const
|
||||
{
|
||||
llassert(mPlatform == HippoGridInfo::PLATFORM_SECONDLIFE);
|
||||
return mIsInProductionGrid;
|
||||
}
|
||||
|
||||
bool HippoGridInfo::isAvination() const
|
||||
{
|
||||
return mIsInAvination;
|
||||
}
|
||||
|
||||
const std::string& HippoGridInfo::getGridName() const
|
||||
{
|
||||
return mGridName;
|
||||
}
|
||||
|
||||
const std::string& HippoGridInfo::getGridOwner() const
|
||||
{
|
||||
if(isSecondLife())
|
||||
@@ -118,73 +82,6 @@ const std::string& HippoGridInfo::getGridOwner() const
|
||||
}
|
||||
}
|
||||
|
||||
const std::string& HippoGridInfo::getLoginUri() const
|
||||
{
|
||||
return mLoginUri;
|
||||
}
|
||||
|
||||
const std::string& HippoGridInfo::getLoginPage() const
|
||||
{
|
||||
return mLoginPage;
|
||||
}
|
||||
|
||||
const std::string& HippoGridInfo::getHelperUri() const
|
||||
{
|
||||
return mHelperUri;
|
||||
}
|
||||
|
||||
const std::string& HippoGridInfo::getWebSite() const
|
||||
{
|
||||
return mWebSite;
|
||||
}
|
||||
|
||||
const std::string& HippoGridInfo::getSupportUrl() const
|
||||
{
|
||||
return mSupportUrl;
|
||||
}
|
||||
|
||||
const std::string& HippoGridInfo::getRegisterUrl() const
|
||||
{
|
||||
return mRegisterUrl;
|
||||
}
|
||||
|
||||
const std::string& HippoGridInfo::getPasswordUrl() const
|
||||
{
|
||||
return mPasswordUrl;
|
||||
}
|
||||
|
||||
const std::string& HippoGridInfo::getSearchUrl() const
|
||||
{
|
||||
return mSearchUrl;
|
||||
}
|
||||
|
||||
const std::string& HippoGridInfo::getGridMessage() const
|
||||
{
|
||||
return mGridMessage;
|
||||
}
|
||||
|
||||
bool HippoGridInfo::isRenderCompat() const
|
||||
{
|
||||
return mRenderCompat;
|
||||
}
|
||||
|
||||
const std::string& HippoGridInfo::getCurrencySymbol() const
|
||||
{
|
||||
return mCurrencySymbol;
|
||||
}
|
||||
|
||||
const std::string& HippoGridInfo::getCurrencyText() const
|
||||
{
|
||||
return mCurrencyText;
|
||||
}
|
||||
|
||||
const std::string& HippoGridInfo::getRealCurrencySymbol() const
|
||||
{
|
||||
return mRealCurrencySymbol;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// ********************************************************************
|
||||
// Setters
|
||||
|
||||
@@ -484,8 +381,11 @@ void HippoGridInfo::onXmlCharacterData(void* userData, const XML_Char* s, int le
|
||||
{
|
||||
case XML_GRIDNICK:
|
||||
{
|
||||
if (self->mGridNick == "") self->mGridNick.assign(s, len);
|
||||
self->mGridNick = sanitizeGridNick(self->mGridNick);
|
||||
if (self->mGridNick == "")
|
||||
{
|
||||
self->mGridNick.assign(s, len);
|
||||
self->mGridNick = sanitizeGridNick(self->mGridNick);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -517,7 +417,15 @@ void HippoGridInfo::onXmlCharacterData(void* userData, const XML_Char* s, int le
|
||||
break;
|
||||
}
|
||||
|
||||
case XML_GRIDNAME: self->mGridName.assign(s, len); break;
|
||||
case XML_GRIDNAME:
|
||||
{
|
||||
if (self->mGridName == "")
|
||||
{
|
||||
self->mGridName.assign(s, len);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case XML_LOGINPAGE: self->mLoginPage.assign(s, len); break;
|
||||
case XML_WEBSITE: self->mWebSite.assign(s, len); break;
|
||||
case XML_SUPPORT: self->mSupportUrl.assign(s, len); break;
|
||||
@@ -788,13 +696,6 @@ HippoGridInfo* HippoGridManager::getGrid(const std::string& grid) const
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
HippoGridInfo* HippoGridManager::getConnectedGrid() const
|
||||
{
|
||||
return (mConnectedGrid)? mConnectedGrid: getCurrentGrid();
|
||||
}
|
||||
|
||||
|
||||
HippoGridInfo* HippoGridManager::getCurrentGrid() const
|
||||
{
|
||||
HippoGridInfo* grid = getGrid(mCurrentGrid);
|
||||
|
||||
@@ -36,33 +36,33 @@ public:
|
||||
|
||||
explicit HippoGridInfo(const std::string& gridName);
|
||||
|
||||
Platform getPlatform();
|
||||
bool isOpenSimulator() const;
|
||||
bool isAurora() const;
|
||||
bool isSecondLife() const;
|
||||
bool isAvination() const;
|
||||
bool isInProductionGrid() const; // Should only be called if isSecondLife() returns true.
|
||||
const std::string& getGridName() const;
|
||||
Platform getPlatform() { return mPlatform; }
|
||||
bool isOpenSimulator() const { return (mPlatform == PLATFORM_OPENSIM || mPlatform == PLATFORM_AURORA); }
|
||||
bool isAurora() const { return (mPlatform == PLATFORM_AURORA); }
|
||||
bool isSecondLife() const { return (mPlatform == PLATFORM_SECONDLIFE); }
|
||||
bool isAvination() const { return mIsInAvination; }
|
||||
bool isInProductionGrid() const { llassert(mPlatform == PLATFORM_SECONDLIFE); return mIsInProductionGrid; } // Should only be called if isSecondLife() returns true.
|
||||
const std::string& getGridName() const { return mGridName; }
|
||||
const std::string& getGridOwner() const;
|
||||
const std::string& getLoginUri() const;
|
||||
const std::string& getLoginPage() const;
|
||||
const std::string& getHelperUri() const;
|
||||
const std::string& getWebSite() const;
|
||||
const std::string& getSupportUrl() const;
|
||||
const std::string& getRegisterUrl() const;
|
||||
const std::string& getPasswordUrl() const;
|
||||
const std::string& getLoginUri() const { return mLoginUri; }
|
||||
const std::string& getLoginPage() const { return mLoginPage; }
|
||||
const std::string& getHelperUri() const { return mHelperUri; }
|
||||
const std::string& getWebSite() const { return mWebSite; }
|
||||
const std::string& getSupportUrl() const { return mSupportUrl; }
|
||||
const std::string& getRegisterUrl() const { return mRegisterUrl; }
|
||||
const std::string& getPasswordUrl() const { return mPasswordUrl; }
|
||||
// Returns the url base used for the Web Search tab
|
||||
const std::string& getSearchUrl() const;
|
||||
const std::string& getGridMessage() const;
|
||||
const std::string& getSearchUrl() const { return mSearchUrl; }
|
||||
const std::string& getGridMessage() const { return mGridMessage; }
|
||||
const std::string& getVoiceConnector() const { return mVoiceConnector; }
|
||||
std::string getSearchUrl(SearchType ty, bool is_web) const;
|
||||
bool isRenderCompat() const;
|
||||
std::string getGridNick();
|
||||
bool isRenderCompat() const { return mRenderCompat; }
|
||||
std::string getGridNick();
|
||||
int getMaxAgentGroups() const { return mMaxAgentGroups; }
|
||||
|
||||
const std::string& getCurrencySymbol() const;
|
||||
const std::string& getCurrencyText() const;
|
||||
const std::string& getRealCurrencySymbol() const;
|
||||
const std::string& getCurrencySymbol() const { return mCurrencySymbol; }
|
||||
const std::string& getCurrencyText() const { return mCurrencyText; }
|
||||
const std::string& getRealCurrencySymbol() const { return mRealCurrencySymbol; }
|
||||
std::string getUploadFee() const;
|
||||
std::string getGroupCreationFee() const;
|
||||
std::string getDirectoryFee() const;
|
||||
@@ -160,7 +160,8 @@ public:
|
||||
void discardAndReload();
|
||||
|
||||
HippoGridInfo* getGrid(const std::string& grid) const;
|
||||
HippoGridInfo* getConnectedGrid() const;
|
||||
HippoGridInfo* getConnectedGrid() const { return mConnectedGrid ? mConnectedGrid : getCurrentGrid(); }
|
||||
|
||||
HippoGridInfo* getCurrentGrid() const;
|
||||
const std::string& getDefaultGridNick() const;
|
||||
const std::string& getCurrentGridNick() const;
|
||||
|
||||
@@ -133,7 +133,7 @@ BOOL HippoPanelGridsImpl::postBuild()
|
||||
requires<LLButton>("btn_add");
|
||||
requires<LLButton>("btn_copy");
|
||||
requires<LLButton>("btn_default");
|
||||
//requires<LLButton>("btn_gridinfo");
|
||||
requires<LLButton>("btn_gridinfo");
|
||||
requires<LLButton>("btn_help_render_compat");
|
||||
if (!checkRequirements()) return false;
|
||||
|
||||
@@ -146,7 +146,7 @@ BOOL HippoPanelGridsImpl::postBuild()
|
||||
childSetAction("btn_add", onClickAdd, this);
|
||||
childSetAction("btn_copy", onClickCopy, this);
|
||||
childSetAction("btn_default", onClickDefault, this);
|
||||
//childSetAction("btn_gridinfo", onClickGridInfo, this);
|
||||
childSetAction("btn_gridinfo", onClickGridInfo, this);
|
||||
childSetAction("btn_help_render_compat", onClickHelpRenderCompat, this);
|
||||
childSetAction("btn_advanced", onClickAdvanced, this);
|
||||
|
||||
|
||||
@@ -4,14 +4,20 @@ Second Life - Linux Voice Support README
|
||||
WHAT IS IT?
|
||||
-=-=-=-=-=-
|
||||
|
||||
Linux Voice Support is a new feature in testing which allows users
|
||||
of the Linux Second Life client to participate in voice-chat with other
|
||||
residents and groups inside Second Life, with an appropriate
|
||||
headset/microphone.
|
||||
Linux Voice Support is a feature in testing which allows users of the Linux
|
||||
Second Life client to participate in voice-chat with other residents and
|
||||
groups inside Second Life, with an appropriate headset/microphone.
|
||||
|
||||
Linux Voice Support is currently EXPERIMENTAL and is known to still
|
||||
have some compatibility issues.
|
||||
|
||||
SINGULARITY MULTI-VOICE
|
||||
-=-=-=-=-=-=-=-=-=-=-=-
|
||||
Singularity multi-voice is an experimental feature that allows you to run multiple
|
||||
SLVoice daemons at the same time, in order to do this, the debug setting VoiceMultiInstance
|
||||
must be TRUE, this allows multiple instances of the viewer to run concurrently and
|
||||
each connect to voice.
|
||||
|
||||
REQUIREMENTS
|
||||
-=-=-=-=-=-=
|
||||
|
||||
@@ -29,6 +35,13 @@ systems:
|
||||
* Fedora Core 6 with (unknown) audio chipset
|
||||
* Ubuntu 8.04 (Hardy) with (unknown) audio chipset
|
||||
|
||||
TESTING YOUR SETTINGS
|
||||
-=-=-=-=-=-=-=-=-=-=-
|
||||
|
||||
* The Second Life region 'Voice Echo Canyon' is a great place for testing
|
||||
your hardware settings and quality - it will 'echo' your voice back to you
|
||||
when you speak.
|
||||
|
||||
KNOWN PROBLEMS
|
||||
-=-=-=-=-=-=-=
|
||||
|
||||
@@ -41,12 +54,12 @@ TROUBLESHOOTING
|
||||
PROBLEM 1: I don't see a white dot over the head of my avatar or other
|
||||
Voice-using avatars.
|
||||
SOLUTION:
|
||||
a. Ensure that 'Enable voice chat' is enabled in the Voice Chat
|
||||
preferences window and that you are in a voice-enabled area (you
|
||||
will see a blue headphone icon in the SL menu-bar).
|
||||
a. Ensure that 'Enable voice chat' is enabled in the 'Voice Chat' section of the
|
||||
Preferences window, and that you are in a voice-enabled area
|
||||
(you will see a blue headphone icon in the SL menu-bar).
|
||||
b. If the above does not help, exit Second Life and ensure that any
|
||||
remaining 'SLVoice' processes (as reported by 'ps', 'top' or similar)
|
||||
are killed.
|
||||
are killed before restarting.
|
||||
|
||||
PROBLEM 2: I have a white dot over my head but I never see (or hear!) anyone
|
||||
except myself listed in the Active Speakers dialog when I'm sure that other
|
||||
@@ -65,12 +78,13 @@ c. Update to the latest version of ALSA manually. For a guide, see the
|
||||
|
||||
PROBLEM 3: I can hear other people, but they cannot hear me.
|
||||
SOLUTION:
|
||||
a. Ensure that you have the 'Talk' button activated while you are trying to
|
||||
speak.
|
||||
a. Ensure that you have the 'Talk' button (at the bottom of the Second Life
|
||||
window)activated while you are trying to speak.
|
||||
b. Ensure that your microphone jack is inserted into the correct socket of your
|
||||
sound card, where appropriate.
|
||||
c. Use your system mixer-setting program or the 'alsamixer' program to ensure
|
||||
that microphone input is set as the active input source and is not muted.
|
||||
c. Use your system mixer-setting program (such as the PulseAudio 'volume
|
||||
control' applet or the ALSA 'alsamixer' program) to ensure that microphone
|
||||
input is set as the active input source and is not muted.
|
||||
d. Verify that audio input works in other applications, i.e. Audacity
|
||||
|
||||
PROBLEM 4: Other people just hear bursts of loud noise when I speak.
|
||||
|
||||
@@ -15,7 +15,7 @@ Life itself - please see <http://www.secondlife.com/whatis/>.
|
||||
5.3. Blank window after minimizing it
|
||||
5.4. Audio
|
||||
5.5. 'Alt' key for camera controls doesn't work
|
||||
5.6. In-world streaming movie/music playback
|
||||
5.6. In-world streaming movie, music and Flash playback
|
||||
6. Advanced Troubleshooting
|
||||
6.1. Audio
|
||||
6.2. OpenGL
|
||||
@@ -75,10 +75,11 @@ Life Linux client is very similar to that for Windows, as detailed at:
|
||||
3. INSTALLING & RUNNING
|
||||
-=-=-=-=-=-=-=-=-=-=-=-
|
||||
|
||||
The Second Life Linux client entirely runs out of the directory you have
|
||||
unpacked it into - no installation step is required.
|
||||
The Singularity Linux client can entirely run from the directory you have
|
||||
unpacked it into - no installation step is required. If you wish to
|
||||
perform a separate installation step anyway, you may run './install.sh'
|
||||
|
||||
Run ./secondlife from the installation directory to start Second Life.
|
||||
Run ./singularity from the installation directory to start Singularity.
|
||||
|
||||
For in-world MOVIE and MUSIC PLAYBACK, you will need (32-bit) GStreamer 0.10
|
||||
installed on your system. This is optional - it is not required for general
|
||||
@@ -168,12 +169,15 @@ SOLUTION:- Some window managers eat the Alt key for their own purposes; you
|
||||
example, the 'Windows' key!) which will allow the Alt key to function
|
||||
properly with mouse actions in Second Life and other applications.
|
||||
|
||||
PROBLEM 6:- In-world movie and/or music playback doesn't work for me.
|
||||
PROBLEM 6:- In-world movie, music, or Flash playback doesn't work for me.
|
||||
SOLUTION:- You need to have a working installation of GStreamer 0.10; this
|
||||
is usually an optional package for most versions of Linux. If you have
|
||||
installed GStreamer 0.10 and you can play some music/movies but not others
|
||||
then you need to install a wider selection of GStreamer plugins, either
|
||||
from your vendor or an appropriate third party.
|
||||
from your vendor (i.e. the 'Ugly' plugins) or an appropriate third party.
|
||||
For Flash playback, you need to have Flash 10 installed for your normal
|
||||
web browser (for example, Firefox). PulseAudio is required for Flash
|
||||
volume control / muting to fully function inside Second Life.
|
||||
|
||||
|
||||
6. ADVANCED TROUBLESHOOTING
|
||||
|
||||
106
indra/newview/linux_tools/install.sh
Normal file
106
indra/newview/linux_tools/install.sh
Normal file
@@ -0,0 +1,106 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Install Singularity Viewer. This script can install the viewer both
|
||||
# system-wide and for an individual user.
|
||||
|
||||
VT102_STYLE_NORMAL='\E[0m'
|
||||
VT102_COLOR_RED='\E[31m'
|
||||
|
||||
SCRIPTSRC=`readlink -f "$0" || echo "$0"`
|
||||
RUN_PATH=`dirname "${SCRIPTSRC}" || echo .`
|
||||
tarball_path=${RUN_PATH}
|
||||
|
||||
function prompt()
|
||||
{
|
||||
local prompt=$1
|
||||
local input
|
||||
|
||||
echo -n "$prompt"
|
||||
|
||||
while read input; do
|
||||
case $input in
|
||||
[Yy]* )
|
||||
return 1
|
||||
;;
|
||||
[Nn]* )
|
||||
return 0
|
||||
;;
|
||||
* )
|
||||
echo "Please enter yes or no."
|
||||
echo -n "$prompt"
|
||||
esac
|
||||
done
|
||||
}
|
||||
|
||||
function die()
|
||||
{
|
||||
warn $1
|
||||
exit 1
|
||||
}
|
||||
|
||||
function warn()
|
||||
{
|
||||
echo -n -e $VT102_COLOR_RED
|
||||
echo $1
|
||||
echo -n -e $VT102_STYLE_NORMAL
|
||||
}
|
||||
|
||||
function homedir_install()
|
||||
{
|
||||
warn "You are not running as a privileged user, so you will only be able"
|
||||
warn "to install Singularity Viewer in your home directory. If you"
|
||||
warn "would like to install Singularity Viewer system-wide, please run"
|
||||
warn "this script as the root user, or with the 'sudo' command."
|
||||
echo
|
||||
|
||||
prompt "Proceed with the installation? [Y/N]: "
|
||||
if [[ $? == 0 ]]; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
install_to_prefix "$HOME/.singularity-install"
|
||||
$HOME/.singularity-install/refresh_desktop_app_entry.sh
|
||||
}
|
||||
|
||||
function root_install()
|
||||
{
|
||||
local default_prefix="/opt/singularity-install"
|
||||
|
||||
echo -n "Enter the desired installation directory [${default_prefix}]: ";
|
||||
read
|
||||
if [[ "$REPLY" = "" ]] ; then
|
||||
local install_prefix=$default_prefix
|
||||
else
|
||||
local install_prefix=$REPLY
|
||||
fi
|
||||
|
||||
install_to_prefix "$install_prefix"
|
||||
|
||||
mkdir -p /usr/local/share/applications
|
||||
${install_prefix}/refresh_desktop_app_entry.sh
|
||||
}
|
||||
|
||||
function install_to_prefix()
|
||||
{
|
||||
test -e "$1" && backup_previous_installation "$1"
|
||||
mkdir -p "$1" || die "Failed to create installation directory!"
|
||||
|
||||
echo " - Installing to $1"
|
||||
|
||||
cp -a "${tarball_path}"/* "$1/" || die "Failed to complete the installation!"
|
||||
}
|
||||
|
||||
function backup_previous_installation()
|
||||
{
|
||||
local backup_dir="$1".backup-$(date -I)
|
||||
echo " - Backing up previous installation to $backup_dir"
|
||||
|
||||
mv "$1" "$backup_dir" || die "Failed to create backup of existing installation!"
|
||||
}
|
||||
|
||||
|
||||
if [ "$UID" == "0" ]; then
|
||||
root_install
|
||||
else
|
||||
homedir_install
|
||||
fi
|
||||
36
indra/newview/linux_tools/refresh_desktop_app_entry.sh
Normal file
36
indra/newview/linux_tools/refresh_desktop_app_entry.sh
Normal file
@@ -0,0 +1,36 @@
|
||||
#!/bin/bash
|
||||
|
||||
SCRIPTSRC=`readlink -f "$0" || echo "$0"`
|
||||
RUN_PATH=`dirname "${SCRIPTSRC}" || echo .`
|
||||
|
||||
install_prefix=${RUN_PATH}
|
||||
|
||||
function install_desktop_entry()
|
||||
{
|
||||
local installation_prefix="$1"
|
||||
local desktop_entries_dir="$2"
|
||||
|
||||
local desktop_entry="\
|
||||
[Desktop Entry]\n\
|
||||
Name=Singularity\n\
|
||||
Comment=Client for Online Virtual Worlds, such as Second Life\n\
|
||||
Exec=${installation_prefix}/singularity\n\
|
||||
Icon=${installation_prefix}/singularity_icon.png\n\
|
||||
Terminal=false\n\
|
||||
Type=Application\n\
|
||||
Categories=Application;Network;\n\
|
||||
StartupNotify=true\n\
|
||||
X-Desktop-File-Install-Version=3.0"
|
||||
|
||||
echo " - Installing menu entries in ${desktop_entries_dir}"
|
||||
mkdir -vp "${desktop_entries_dir}"
|
||||
echo -e $desktop_entry > "${desktop_entries_dir}/singularity-viewer.desktop" || "Failed to install application menu!"
|
||||
}
|
||||
|
||||
if [ "$UID" == "0" ]; then
|
||||
# system-wide
|
||||
install_desktop_entry "$install_prefix" /usr/local/share/applications
|
||||
else
|
||||
# user-specific
|
||||
install_desktop_entry "$install_prefix" "$HOME/.local/share/applications"
|
||||
fi
|
||||
@@ -4,10 +4,10 @@
|
||||
## These options are for self-assisted troubleshooting during this beta
|
||||
## testing phase; you should not usually need to touch them.
|
||||
|
||||
## - Avoids using any OpenAL audio driver.
|
||||
#export LL_BAD_OPENAL_DRIVER=x
|
||||
## - Avoids using any FMOD Ex audio driver.
|
||||
#export LL_BAD_FMODEX_DRIVER=x
|
||||
## - Avoids using any OpenAL audio driver.
|
||||
#export LL_BAD_OPENAL_DRIVER=x
|
||||
## - Avoids using any FMOD audio driver.
|
||||
#export LL_BAD_FMOD_DRIVER=x
|
||||
|
||||
@@ -20,7 +20,6 @@
|
||||
## - Avoids using the FMOD or FMOD Ex ESD audio driver.
|
||||
#export LL_BAD_FMOD_ESD=x
|
||||
|
||||
|
||||
## - Avoids the optional OpenGL extensions which have proven most problematic
|
||||
## on some hardware. Disabling this option may cause BETTER PERFORMANCE but
|
||||
## may also cause CRASHES and hangs on some unstable combinations of drivers
|
||||
@@ -109,6 +108,10 @@ cd "${RUN_PATH}"
|
||||
|
||||
# Re-register the secondlife:// protocol handler every launch, for now.
|
||||
./register_secondlifeprotocol.sh
|
||||
|
||||
# Re-register the application with the desktop system every launch, for now.
|
||||
./refresh_desktop_app_entry.sh
|
||||
|
||||
## Before we mess with LD_LIBRARY_PATH, save the old one to restore for
|
||||
## subprocesses that care.
|
||||
export SAVED_LD_LIBRARY_PATH="${LD_LIBRARY_PATH}"
|
||||
@@ -147,16 +150,11 @@ fi
|
||||
export SL_CMD='$LL_WRAPPER bin/$VIEWER_BINARY'
|
||||
export SL_OPT="`cat gridargs.dat` $@"
|
||||
|
||||
# Run the program
|
||||
# Run the program.
|
||||
eval ${SL_ENV} ${SL_CMD} ${SL_OPT} || LL_RUN_ERR=runerr
|
||||
|
||||
# Handle any resulting errors
|
||||
if [ -n "$LL_RUN_ERR" ]; then
|
||||
LL_RUN_ERR_MSG=""
|
||||
if [ "$LL_RUN_ERR" = "runerr" ]; then
|
||||
# generic error running the binary
|
||||
echo '*** Bad shutdown. ***'
|
||||
|
||||
|
||||
fi
|
||||
if [ -n "$LL_RUN_ERR" = "runerr" ]; then
|
||||
# generic error running the binary
|
||||
echo '*** Bad shutdown. ***'
|
||||
fi
|
||||
|
||||
@@ -3,10 +3,9 @@
|
||||
* @brief Processes responses received for asset upload requests.
|
||||
*
|
||||
* $LicenseInfo:firstyear=2007&license=viewergpl$
|
||||
*
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (c) 2007-2009, Linden Research, Inc.
|
||||
*
|
||||
* Second Life Viewer Source Code
|
||||
* The source code in this file ("Source Code") is provided by Linden Lab
|
||||
* to you under the terms of the GNU General Public License, version 2.0
|
||||
* ("GPL"), unless you have obtained a separate licensing agreement
|
||||
@@ -53,7 +52,6 @@
|
||||
#include "llviewerobject.h"
|
||||
#include "llviewercontrol.h"
|
||||
#include "llviewerobjectlist.h"
|
||||
#include "llviewermenufile.h"
|
||||
#include "llviewertexlayer.h"
|
||||
#include "llviewerwindow.h"
|
||||
#include "lltrans.h"
|
||||
@@ -255,6 +253,7 @@ void LLAssetUploadResponder::result(const LLSD& content)
|
||||
lldebugs << "LLAssetUploadResponder::result from capabilities" << llendl;
|
||||
|
||||
std::string state = content["state"];
|
||||
|
||||
if (state == "upload")
|
||||
{
|
||||
uploadUpload(content);
|
||||
@@ -343,6 +342,7 @@ void LLNewAgentInventoryResponder::error(U32 statusNum, const std::string& reaso
|
||||
//LLImportColladaAssetCache::getInstance()->assetUploaded(mVFileID, LLUUID(), FALSE);
|
||||
}
|
||||
|
||||
|
||||
//virtual
|
||||
void LLNewAgentInventoryResponder::uploadFailure(const LLSD& content)
|
||||
{
|
||||
@@ -351,6 +351,7 @@ void LLNewAgentInventoryResponder::uploadFailure(const LLSD& content)
|
||||
(*mCallBack)(false, mUserData);
|
||||
}
|
||||
LLAssetUploadResponder::uploadFailure(content);
|
||||
|
||||
//LLImportColladaAssetCache::getInstance()->assetUploaded(mVFileID, content["new_asset"], FALSE);
|
||||
}
|
||||
|
||||
@@ -397,10 +398,14 @@ void LLNewAgentInventoryResponder::uploadComplete(const LLSD& content)
|
||||
|
||||
// continue uploading for bulk uploads
|
||||
|
||||
if (!gUploadQueue.empty())
|
||||
/* Singu Note: sUploadQueue was never getting populated, anywhere! Therefore, this entire block never was reached.
|
||||
** I have condensed it to here in the hopes it may one day see use. Apparently, it came in with Siana's prep work
|
||||
** for mesh upload (697dd7e9298282590f8cf858a58335f70302532b), but we never needed it.
|
||||
static std::deque<std::string> sUploadQueue;
|
||||
if (!sUploadQueue.empty())
|
||||
{
|
||||
std::string next_file = gUploadQueue.front();
|
||||
gUploadQueue.pop_front();
|
||||
std::string next_file = sUploadQueue.front();
|
||||
sUploadQueue.pop_front();
|
||||
if (next_file.empty()) return;
|
||||
std::string name = gDirUtilp->getBaseFileName(next_file, true);
|
||||
|
||||
@@ -448,6 +453,7 @@ void LLNewAgentInventoryResponder::uploadComplete(const LLSD& content)
|
||||
expected_upload_cost,
|
||||
userdata);
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
LLSendTexLayerResponder::LLSendTexLayerResponder(const LLSD& post_data,
|
||||
@@ -698,6 +704,7 @@ void LLUpdateTaskInventoryResponder::uploadComplete(const LLSD& content)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
// LLNewAgentInventoryVariablePriceResponder::Impl //
|
||||
/////////////////////////////////////////////////////
|
||||
@@ -1165,3 +1172,4 @@ void LLNewAgentInventoryVariablePriceResponder::showConfirmationDialog(
|
||||
boost::intrusive_ptr<LLNewAgentInventoryVariablePriceResponder>(this)));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -238,25 +238,52 @@ void LLFloaterStats::buildStats()
|
||||
// Network statistics
|
||||
LLStatView *net_statviewp = stat_viewp->addStatView("network stat view", "Network", "OpenDebugStatNet", rect);
|
||||
|
||||
stat_barp = net_statviewp->addStat("Packets In", &(LLViewerStats::getInstance()->mPacketsInStat), "DebugStatModePacketsIn");
|
||||
stat_barp = net_statviewp->addStat("UDP Packets In", &(LLViewerStats::getInstance()->mPacketsInStat), "DebugStatModePacketsIn");
|
||||
stat_barp->setUnitLabel("/sec");
|
||||
|
||||
stat_barp = net_statviewp->addStat("Packets Out", &(LLViewerStats::getInstance()->mPacketsOutStat), "DebugStatModePacketsOut");
|
||||
stat_barp = net_statviewp->addStat("UDP Packets Out", &(LLViewerStats::getInstance()->mPacketsOutStat), "DebugStatModePacketsOut");
|
||||
stat_barp->setUnitLabel("/sec");
|
||||
|
||||
stat_barp = net_statviewp->addStat("HTTP Textures", &(LLViewerStats::getInstance()->mHTTPTextureKBitStat), "DebugStatModeHTTPTexture");
|
||||
stat_barp->setUnitLabel(" kbps");
|
||||
stat_barp->mMinBar = 0.f;
|
||||
stat_barp->mMaxBar = gSavedSettings.getF32("HTTPThrottleBandwidth") * 2; // Times two because we'll have over shoots.
|
||||
stat_barp->mTickSpacing = 1.f;
|
||||
while (stat_barp->mTickSpacing < stat_barp->mMaxBar / 8)
|
||||
stat_barp->mTickSpacing *= 2.f;
|
||||
stat_barp->mLabelSpacing = 2 * stat_barp->mTickSpacing;
|
||||
stat_barp->mPerSec = FALSE;
|
||||
stat_barp->mDisplayMean = FALSE;
|
||||
|
||||
stat_barp = net_statviewp->addStat("UDP Textures", &(LLViewerStats::getInstance()->mUDPTextureKBitStat), "DebugStatModeUDPTexture");
|
||||
stat_barp->setUnitLabel(" kbps");
|
||||
stat_barp->mMinBar = 0.f;
|
||||
stat_barp->mMaxBar = 1024.f;
|
||||
stat_barp->mTickSpacing = 128.f;
|
||||
stat_barp->mLabelSpacing = 256.f;
|
||||
|
||||
stat_barp = net_statviewp->addStat("Objects", &(LLViewerStats::getInstance()->mObjectKBitStat), "DebugStatModeObjects");
|
||||
stat_barp->setUnitLabel(" kbps");
|
||||
stat_barp->mMinBar = 0.f;
|
||||
stat_barp->mMaxBar = 1024.f;
|
||||
stat_barp->mTickSpacing = 128.f;
|
||||
stat_barp->mLabelSpacing = 256.f;
|
||||
|
||||
stat_barp = net_statviewp->addStat("Texture", &(LLViewerStats::getInstance()->mTextureKBitStat), "DebugStatModeTexture");
|
||||
stat_barp = net_statviewp->addStat("Assets (UDP)", &(LLViewerStats::getInstance()->mAssetKBitStat), "DebugStatModeAsset");
|
||||
stat_barp->setUnitLabel(" kbps");
|
||||
stat_barp->mMinBar = 0.f;
|
||||
stat_barp->mMaxBar = 1024.f;
|
||||
stat_barp->mTickSpacing = 128.f;
|
||||
stat_barp->mLabelSpacing = 256.f;
|
||||
|
||||
stat_barp = net_statviewp->addStat("Asset", &(LLViewerStats::getInstance()->mAssetKBitStat), "DebugStatModeAsset");
|
||||
stat_barp = net_statviewp->addStat("Layers (UDP)", &(LLViewerStats::getInstance()->mLayersKBitStat), "DebugStatModeLayers");
|
||||
stat_barp->setUnitLabel(" kbps");
|
||||
stat_barp->mMinBar = 0.f;
|
||||
stat_barp->mMaxBar = 1024.f;
|
||||
stat_barp->mTickSpacing = 128.f;
|
||||
stat_barp->mLabelSpacing = 256.f;
|
||||
|
||||
stat_barp = net_statviewp->addStat("Layers", &(LLViewerStats::getInstance()->mLayersKBitStat), "DebugStatModeLayers");
|
||||
stat_barp->setUnitLabel(" kbps");
|
||||
|
||||
stat_barp = net_statviewp->addStat("Actual In", &(LLViewerStats::getInstance()->mActualInKBitStat),
|
||||
stat_barp = net_statviewp->addStat("Actual In (UDP)", &(LLViewerStats::getInstance()->mActualInKBitStat),
|
||||
"DebugStatModeActualIn", TRUE, FALSE);
|
||||
stat_barp->setUnitLabel(" kbps");
|
||||
stat_barp->mMinBar = 0.f;
|
||||
@@ -264,7 +291,7 @@ void LLFloaterStats::buildStats()
|
||||
stat_barp->mTickSpacing = 128.f;
|
||||
stat_barp->mLabelSpacing = 256.f;
|
||||
|
||||
stat_barp = net_statviewp->addStat("Actual Out", &(LLViewerStats::getInstance()->mActualOutKBitStat),
|
||||
stat_barp = net_statviewp->addStat("Actual Out (UDP)", &(LLViewerStats::getInstance()->mActualOutKBitStat),
|
||||
"DebugStatModeActualOut", TRUE, FALSE);
|
||||
stat_barp->setUnitLabel(" kbps");
|
||||
stat_barp->mMinBar = 0.f;
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
|
||||
#include "lltexturefetch.h"
|
||||
|
||||
#include "llcurl.h"
|
||||
#include "aicurl.h"
|
||||
#include "lldir.h"
|
||||
#include "llhttpclient.h"
|
||||
#include "llhttpstatuscodes.h"
|
||||
@@ -1273,7 +1273,8 @@ bool LLTextureFetchWorker::doWork(S32 param)
|
||||
|
||||
// Let AICurl decide if we can process more HTTP requests at the moment or not.
|
||||
static const LLCachedControl<F32> throttle_bandwidth("HTTPThrottleBandwidth", 2000);
|
||||
if (!AIPerServiceRequestQueue::wantsMoreHTTPRequestsFor(mPerServicePtr, mFetcher->getTextureBandwidth() > throttle_bandwidth))
|
||||
bool const no_bandwidth_throttling = gHippoGridManager->getConnectedGrid()->isAvination();
|
||||
if (!AIPerServiceRequestQueue::wantsMoreHTTPRequestsFor(mPerServicePtr, throttle_bandwidth, no_bandwidth_throttling))
|
||||
{
|
||||
return false ; //wait.
|
||||
}
|
||||
@@ -1290,16 +1291,8 @@ bool LLTextureFetchWorker::doWork(S32 param)
|
||||
mLoaded = FALSE;
|
||||
mGetStatus = 0;
|
||||
mGetReason.clear();
|
||||
// Note: comparing mFetcher->getTextureBandwidth() with throttle_bandwidth is a bit like
|
||||
// comparing apples and oranges, but it's only debug output. The first is the averaged
|
||||
// bandwidth used for the body of successfully downloaded textures, averaged over roughtly
|
||||
// 10 seconds, in kbits/s. The latter is the limit of the actual http curl downloads,
|
||||
// including header and failures for anything (not just textures), averaged over the last
|
||||
// second, also in kbits/s.
|
||||
static const LLCachedControl<F32> throttle_bandwidth("HTTPThrottleBandwidth", 2000);
|
||||
LL_DEBUGS("Texture") << "HTTP GET: " << mID << " Offset: " << mRequestedOffset
|
||||
<< " Bytes: " << mRequestedSize
|
||||
<< " Bandwidth(kbps): " << mFetcher->getTextureBandwidth() << "/" << throttle_bandwidth
|
||||
<< LL_ENDL;
|
||||
setPriority(LLWorkerThread::PRIORITY_LOW | mWorkPriority);
|
||||
mState = WAIT_HTTP_REQ;
|
||||
@@ -2041,7 +2034,6 @@ LLTextureFetch::LLTextureFetch(LLTextureCache* cache, LLImageDecodeThread* image
|
||||
mBadPacketCount(0),
|
||||
mTextureCache(cache),
|
||||
mImageDecodeThread(imagedecodethread),
|
||||
mTextureBandwidth(0),
|
||||
mHTTPTextureBits(0),
|
||||
mTotalHTTPRequests(0),
|
||||
mQAMode(qa_mode),
|
||||
|
||||
@@ -79,9 +79,6 @@ public:
|
||||
bool receiveImageHeader(const LLHost& host, const LLUUID& id, U8 codec, U16 packets, U32 totalbytes, U16 data_size, U8* data);
|
||||
bool receiveImagePacket(const LLHost& host, const LLUUID& id, U16 packet_num, U16 data_size, U8* data);
|
||||
|
||||
void setTextureBandwidth(F32 bandwidth) { mTextureBandwidth = bandwidth; }
|
||||
F32 getTextureBandwidth() { return mTextureBandwidth; }
|
||||
|
||||
// Debug
|
||||
BOOL isFromLocalCache(const LLUUID& id);
|
||||
S32 getFetchState(const LLUUID& id, F32& decode_progress_p, F32& requested_priority_p,
|
||||
@@ -164,7 +161,6 @@ private:
|
||||
queue_t mHTTPTextureQueue;
|
||||
typedef std::map<LLHost,std::set<LLUUID> > cancel_queue_t;
|
||||
cancel_queue_t mCancelQueue;
|
||||
F32 mTextureBandwidth;
|
||||
LLTextureInfo mTextureInfo;
|
||||
|
||||
U32 mHTTPTextureBits;
|
||||
|
||||
@@ -70,6 +70,7 @@ namespace AICurlInterface {
|
||||
U32 getNumHTTPQueued(void);
|
||||
U32 getNumHTTPAdded(void);
|
||||
U32 getNumHTTPRunning(void);
|
||||
size_t getHTTPBandwidth(void);
|
||||
} // namespace AICurlInterface
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
@@ -620,17 +621,15 @@ void LLGLTexMemBar::draw()
|
||||
text_color, LLFontGL::LEFT, LLFontGL::TOP);
|
||||
|
||||
left += LLFontGL::getFontMonospace()->getWidth(text);
|
||||
// This bandwidth is averaged over roughly 10 seconds (in kbps) and therefore pretty inaccurate.
|
||||
// Also, it only takes into account actual texture data (not headers etc). But all it is used for
|
||||
// is for the color of some text in the texture console, so I guess it doesn't matter.
|
||||
F32 bandwidth = LLAppViewer::getTextureFetch()->getTextureBandwidth();
|
||||
// This bandwidth is averaged over 1 seconds (in kbps).
|
||||
F32 bandwidth = AICurlInterface::getHTTPBandwidth() / 125.f; // Convert from bytes/s to kbps.
|
||||
// This is the maximum bandwidth allowed for curl transactions (of any type and averaged per second),
|
||||
// that is actually used to limit the number of HTTP texture requests (and only those).
|
||||
// Comparing that with 'bandwidth' is a bit like comparing apples and oranges, but again... who really cares.
|
||||
F32 max_bandwidth = gSavedSettings.getF32("HTTPThrottleBandwidth");
|
||||
static const LLCachedControl<F32> max_bandwidth("HTTPThrottleBandwidth", 2000);
|
||||
color = bandwidth > max_bandwidth ? LLColor4::red : bandwidth > max_bandwidth*.75f ? LLColor4::yellow : text_color;
|
||||
color[VALPHA] = text_color[VALPHA];
|
||||
text = llformat("BW:%.0f/%.0f",bandwidth, max_bandwidth);
|
||||
text = llformat("BW:%.0f/%.0f", bandwidth, max_bandwidth.get());
|
||||
LLFontGL::getFontMonospace()->renderUTF8(text, 0, left, v_offset + line_height*2,
|
||||
color, LLFontGL::LEFT, LLFontGL::TOP);
|
||||
|
||||
|
||||
@@ -3,10 +3,9 @@
|
||||
* @brief "File" menu in the main menu bar.
|
||||
*
|
||||
* $LicenseInfo:firstyear=2002&license=viewergpl$
|
||||
*
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (c) 2002-2009, Linden Research, Inc.
|
||||
*
|
||||
* Second Life Viewer Source Code
|
||||
* The source code in this file ("Source Code") is provided by Linden Lab
|
||||
* to you under the terms of the GNU General Public License, version 2.0
|
||||
* ("GPL"), unless you have obtained a separate licensing agreement
|
||||
@@ -63,11 +62,9 @@
|
||||
#include "lltrans.h"
|
||||
#include "llfloaterbuycurrency.h"
|
||||
// <edit>
|
||||
#include "llselectmgr.h"
|
||||
#include "floaterlocalassetbrowse.h"
|
||||
#include "llassettype.h"
|
||||
#include "llinventorytype.h"
|
||||
#include "llbvhloader.h"
|
||||
#include "lllocalinventory.h"
|
||||
// </edit>
|
||||
|
||||
// linden libraries
|
||||
@@ -89,12 +86,9 @@
|
||||
#include <boost/tokenizer.hpp>
|
||||
|
||||
#include "hippogridmanager.h"
|
||||
#include "importtracker.h"
|
||||
|
||||
using namespace LLOldEvents;
|
||||
|
||||
std::deque<std::string> gUploadQueue;
|
||||
|
||||
typedef LLMemberListener<LLView> view_listener_t;
|
||||
|
||||
|
||||
@@ -502,6 +496,15 @@ class LLFileMinimizeAllWindows : public view_listener_t
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
class LLFileLocalAssetBrowser : public view_listener_t
|
||||
{
|
||||
bool handleEvent(LLPointer<LLEvent>, const LLSD&)
|
||||
{
|
||||
FloaterLocalAssetBrowser::show(0);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
// </edit>
|
||||
|
||||
class LLFileSavePreview : public view_listener_t
|
||||
@@ -600,20 +603,6 @@ class LLFileTakeSnapshotToDisk : public view_listener_t
|
||||
}
|
||||
};
|
||||
|
||||
class LLFileLogOut : public view_listener_t
|
||||
{
|
||||
bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
|
||||
{
|
||||
std::string command(gDirUtilp->getExecutableDir() + gDirUtilp->getDirDelimiter() + gDirUtilp->getExecutableFilename());
|
||||
gSavedSettings.setBOOL("ShowConsoleWindow", FALSE);
|
||||
gViewerWindow->getWindow()->ShellEx(command);
|
||||
gSavedSettings.setBOOL("ShowConsoleWindow", FALSE);
|
||||
LLAppViewer::instance()->userQuit();
|
||||
gSavedSettings.setBOOL("ShowConsoleWindow", FALSE);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
class LLFileQuit : public view_listener_t
|
||||
{
|
||||
bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
|
||||
@@ -696,7 +685,7 @@ void upload_new_resource(const std::string& src_filename, std::string name,
|
||||
"No file extension for the file: '%s'\nPlease make sure the file has a correct file extension",
|
||||
short_name.c_str());
|
||||
args["FILE"] = short_name;
|
||||
upload_error(error_message, "NofileExtension", filename, args);
|
||||
upload_error(error_message, "NoFileExtension", filename, args);
|
||||
return;
|
||||
}
|
||||
else if (codec == IMG_CODEC_J2C)
|
||||
@@ -992,16 +981,10 @@ void temp_upload_callback(const LLUUID& uuid, void* user_data, S32 result, LLExt
|
||||
perms->setMaskEveryone(PERM_ALL);
|
||||
perms->setMaskGroup(PERM_ALL);
|
||||
perms->setMaskNext(PERM_ALL);
|
||||
|
||||
LLUUID destination = gInventory.findCategoryUUIDForType(LLFolderType::FT_TEXTURE);
|
||||
BOOL bUseSystemInventory = (gSavedSettings.getBOOL("AscentUseSystemFolder") && gSavedSettings.getBOOL("AscentSystemTemporary"));
|
||||
if (bUseSystemInventory)
|
||||
{
|
||||
destination = gSystemFolderAssets;
|
||||
}
|
||||
|
||||
LLViewerInventoryItem* item = new LLViewerInventoryItem(
|
||||
item_id,
|
||||
destination,
|
||||
gInventory.findCategoryUUIDForType(LLFolderType::FT_TEXTURE),
|
||||
*perms,
|
||||
uuid,
|
||||
(LLAssetType::EType)data->mAssetInfo.mType,
|
||||
@@ -1011,16 +994,10 @@ void temp_upload_callback(const LLUUID& uuid, void* user_data, S32 result, LLExt
|
||||
LLSaleInfo::DEFAULT,
|
||||
0,
|
||||
time_corrected());
|
||||
if (bUseSystemInventory)
|
||||
{
|
||||
LLLocalInventory::addItem(item);
|
||||
}
|
||||
else
|
||||
{
|
||||
item->updateServer(TRUE);
|
||||
gInventory.updateItem(item);
|
||||
gInventory.notifyObservers();
|
||||
}
|
||||
|
||||
item->updateServer(TRUE);
|
||||
gInventory.updateItem(item);
|
||||
gInventory.notifyObservers();
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1129,40 +1106,44 @@ void upload_done_callback(const LLUUID& uuid, void* user_data, S32 result, LLExt
|
||||
data = NULL;
|
||||
}
|
||||
|
||||
static LLAssetID upload_new_resource_prep(const LLTransactionID& tid,
|
||||
LLAssetType::EType asset_type,
|
||||
LLInventoryType::EType& inventory_type,
|
||||
std::string& name,
|
||||
const std::string& display_name,
|
||||
std::string& description)
|
||||
static LLAssetID upload_new_resource_prep(
|
||||
const LLTransactionID& tid,
|
||||
LLAssetType::EType asset_type,
|
||||
LLInventoryType::EType& inventory_type,
|
||||
std::string& name,
|
||||
const std::string& display_name,
|
||||
std::string& description)
|
||||
{
|
||||
LLAssetID uuid = generate_asset_id_for_new_upload(tid);
|
||||
|
||||
increase_new_upload_stats(asset_type);
|
||||
|
||||
assign_defaults_and_show_upload_message(asset_type,
|
||||
inventory_type,
|
||||
name,
|
||||
display_name,
|
||||
description);
|
||||
assign_defaults_and_show_upload_message(
|
||||
asset_type,
|
||||
inventory_type,
|
||||
name,
|
||||
display_name,
|
||||
description);
|
||||
|
||||
return uuid;
|
||||
}
|
||||
|
||||
LLSD generate_new_resource_upload_capability_body(LLAssetType::EType asset_type,
|
||||
const std::string& name,
|
||||
const std::string& desc,
|
||||
LLFolderType::EType destination_folder_type,
|
||||
LLInventoryType::EType inv_type,
|
||||
U32 next_owner_perms,
|
||||
U32 group_perms,
|
||||
U32 everyone_perms)
|
||||
LLSD generate_new_resource_upload_capability_body(
|
||||
LLAssetType::EType asset_type,
|
||||
const std::string& name,
|
||||
const std::string& desc,
|
||||
LLFolderType::EType destination_folder_type,
|
||||
LLInventoryType::EType inv_type,
|
||||
U32 next_owner_perms,
|
||||
U32 group_perms,
|
||||
U32 everyone_perms)
|
||||
{
|
||||
LLSD body;
|
||||
|
||||
body["folder_id"] = gInventory.findCategoryUUIDForType(destination_folder_type == LLFolderType::FT_NONE ?
|
||||
LLFolderType::assetTypeToFolderType(asset_type) :
|
||||
destination_folder_type);
|
||||
body["folder_id"] = gInventory.findCategoryUUIDForType(
|
||||
destination_folder_type == LLFolderType::FT_NONE ?
|
||||
LLFolderType::assetTypeToFolderType(asset_type) :
|
||||
destination_folder_type);
|
||||
|
||||
body["asset_type"] = LLAssetType::lookup(asset_type);
|
||||
body["inventory_type"] = LLInventoryType::lookup(inv_type);
|
||||
@@ -1175,28 +1156,36 @@ LLSD generate_new_resource_upload_capability_body(LLAssetType::EType asset_type,
|
||||
return body;
|
||||
}
|
||||
|
||||
bool upload_new_resource(const LLTransactionID &tid, LLAssetType::EType asset_type,
|
||||
std::string name,
|
||||
std::string desc, S32 compression_info,
|
||||
LLFolderType::EType destination_folder_type,
|
||||
LLInventoryType::EType inv_type,
|
||||
U32 next_owner_perms,
|
||||
U32 group_perms,
|
||||
U32 everyone_perms,
|
||||
const std::string& display_name,
|
||||
LLAssetStorage::LLStoreAssetCallback callback,
|
||||
S32 expected_upload_cost,
|
||||
void *userdata,
|
||||
void (*callback2)(bool, void*))
|
||||
bool upload_new_resource(
|
||||
const LLTransactionID &tid,
|
||||
LLAssetType::EType asset_type,
|
||||
std::string name,
|
||||
std::string desc,
|
||||
S32 compression_info,
|
||||
LLFolderType::EType destination_folder_type,
|
||||
LLInventoryType::EType inv_type,
|
||||
U32 next_owner_perms,
|
||||
U32 group_perms,
|
||||
U32 everyone_perms,
|
||||
const std::string& display_name,
|
||||
LLAssetStorage::LLStoreAssetCallback callback,
|
||||
S32 expected_upload_cost,
|
||||
void *userdata,
|
||||
void (*callback2)(bool, void*))
|
||||
{
|
||||
if(gDisconnected)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
LLAssetID uuid = upload_new_resource_prep(tid, asset_type, inv_type,
|
||||
name, display_name, desc);
|
||||
LLAssetID uuid =
|
||||
upload_new_resource_prep(
|
||||
tid,
|
||||
asset_type,
|
||||
inv_type,
|
||||
name,
|
||||
display_name,
|
||||
desc);
|
||||
llinfos << "*** Uploading: "
|
||||
<< "\nType: " << LLAssetType::lookup(asset_type)
|
||||
<< "\nUUID: " << uuid
|
||||
@@ -1216,6 +1205,7 @@ bool upload_new_resource(const LLTransactionID &tid, LLAssetType::EType asset_ty
|
||||
// </edit>
|
||||
{
|
||||
llinfos << "New Agent Inventory via capability" << llendl;
|
||||
|
||||
LLSD body;
|
||||
body["folder_id"] = gInventory.findCategoryUUIDForType((destination_folder_type == LLFolderType::FT_NONE) ? LLFolderType::assetTypeToFolderType(asset_type) : destination_folder_type);
|
||||
body["asset_type"] = LLAssetType::lookup(asset_type);
|
||||
@@ -1227,8 +1217,15 @@ bool upload_new_resource(const LLTransactionID &tid, LLAssetType::EType asset_ty
|
||||
body["everyone_mask"] = LLSD::Integer(everyone_perms);
|
||||
body["expected_upload_cost"] = LLSD::Integer(expected_upload_cost);
|
||||
|
||||
LLHTTPClient::post(url, body,
|
||||
new LLNewAgentInventoryResponder(body, uuid, asset_type, callback2, userdata));
|
||||
LLHTTPClient::post(
|
||||
url,
|
||||
body,
|
||||
new LLNewAgentInventoryResponder(
|
||||
body,
|
||||
uuid,
|
||||
asset_type,
|
||||
callback2,
|
||||
userdata));
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1274,12 +1271,14 @@ bool upload_new_resource(const LLTransactionID &tid, LLAssetType::EType asset_ty
|
||||
{
|
||||
asset_callback = callback;
|
||||
}
|
||||
gAssetStorage->storeAssetData(data->mAssetInfo.mTransactionID, data->mAssetInfo.mType,
|
||||
asset_callback,
|
||||
(void*)data,
|
||||
temporary,
|
||||
TRUE,
|
||||
temporary);
|
||||
gAssetStorage->storeAssetData(
|
||||
data->mAssetInfo.mTransactionID,
|
||||
data->mAssetInfo.mType,
|
||||
asset_callback,
|
||||
(void*)data,
|
||||
temporary,
|
||||
TRUE,
|
||||
temporary);
|
||||
}
|
||||
|
||||
// Return true when a call to a callback function will follow.
|
||||
@@ -1330,6 +1329,7 @@ void assign_defaults_and_show_upload_message(LLAssetType::EType asset_type,
|
||||
}
|
||||
LLStringUtil::stripNonprintable(name);
|
||||
LLStringUtil::stripNonprintable(description);
|
||||
|
||||
if (name.empty())
|
||||
{
|
||||
name = "(No Name)";
|
||||
@@ -1345,6 +1345,7 @@ void assign_defaults_and_show_upload_message(LLAssetType::EType asset_type,
|
||||
LLUploadDialog::modalUploadDialog(upload_message);
|
||||
}
|
||||
|
||||
|
||||
void init_menu_file()
|
||||
{
|
||||
(new LLFileUploadImage())->registerListener(gMenuHolder, "File.UploadImage");
|
||||
@@ -1358,13 +1359,13 @@ void init_menu_file()
|
||||
(new LLFileEnableCloseAllWindows())->registerListener(gMenuHolder, "File.EnableCloseAllWindows");
|
||||
// <edit>
|
||||
(new LLFileMinimizeAllWindows())->registerListener(gMenuHolder, "File.MinimizeAllWindows");
|
||||
(new LLFileLocalAssetBrowser())->registerListener(gMenuHolder, "File.LocalAssetBrowser");
|
||||
// </edit>
|
||||
(new LLFileSavePreview())->registerListener(gMenuHolder, "File.SavePreview");
|
||||
(new LLFileSavePreviewPNG())->registerListener(gMenuHolder, "File.SavePreviewPNG");
|
||||
(new LLFileTakeSnapshot())->registerListener(gMenuHolder, "File.TakeSnapshot");
|
||||
(new LLFileTakeSnapshotToDisk())->registerListener(gMenuHolder, "File.TakeSnapshotToDisk");
|
||||
(new LLFileQuit())->registerListener(gMenuHolder, "File.Quit");
|
||||
(new LLFileLogOut())->registerListener(gMenuHolder, "File.LogOut");
|
||||
(new LLFileEnableUpload())->registerListener(gMenuHolder, "File.EnableUpload");
|
||||
(new LLFileEnableUploadModel())->registerListener(gMenuHolder, "File.EnableUploadModel");
|
||||
|
||||
|
||||
@@ -48,8 +48,6 @@ class NewResourceItemCallback : public LLInventoryCallback
|
||||
|
||||
class LLTransactionID;
|
||||
|
||||
extern std::deque<std::string> gUploadQueue;
|
||||
|
||||
void init_menu_file();
|
||||
|
||||
void upload_new_resource(const std::string& src_filename,
|
||||
|
||||
@@ -67,6 +67,10 @@
|
||||
class AIHTTPTimeoutPolicy;
|
||||
extern AIHTTPTimeoutPolicy viewerStatsResponder_timeout;
|
||||
|
||||
namespace AICurlInterface {
|
||||
size_t getHTTPBandwidth(void);
|
||||
}
|
||||
|
||||
class StatAttributes
|
||||
{
|
||||
public:
|
||||
@@ -210,7 +214,8 @@ LLViewerStats::LLViewerStats() :
|
||||
mLayersKBitStat("layerskbitstat"),
|
||||
mObjectKBitStat("objectkbitstat"),
|
||||
mAssetKBitStat("assetkbitstat"),
|
||||
mTextureKBitStat("texturekbitstat"),
|
||||
mHTTPTextureKBitStat("httptexturekbitstat"),
|
||||
mUDPTextureKBitStat("udptexturekbitstat"),
|
||||
mMallocStat("mallocstat"),
|
||||
mVFSPendingOperations("vfspendingoperations"),
|
||||
mObjectsDrawnStat("objectsdrawnstat"),
|
||||
@@ -300,7 +305,8 @@ void LLViewerStats::resetStats()
|
||||
stats.mKBitStat.reset();
|
||||
stats.mLayersKBitStat.reset();
|
||||
stats.mObjectKBitStat.reset();
|
||||
stats.mTextureKBitStat.reset();
|
||||
stats.mHTTPTextureKBitStat.reset();
|
||||
stats.mUDPTextureKBitStat.reset();
|
||||
stats.mVFSPendingOperations.reset();
|
||||
stats.mAssetKBitStat.reset();
|
||||
stats.mPacketsInStat.reset();
|
||||
@@ -673,13 +679,13 @@ void update_statistics()
|
||||
|
||||
// Only update texture stats periodically so that they are less noisy
|
||||
{
|
||||
static const F32 texture_stats_freq = 10.f;
|
||||
static const F32 texture_stats_freq = 0.25f;
|
||||
static LLFrameTimer texture_stats_timer;
|
||||
if (texture_stats_timer.getElapsedTimeF32() >= texture_stats_freq)
|
||||
{
|
||||
stats.mTextureKBitStat.addValue(LLViewerTextureList::sTextureBits/1024.f);
|
||||
stats.mHTTPTextureKBitStat.addValue(AICurlInterface::getHTTPBandwidth()/125.f);
|
||||
stats.mUDPTextureKBitStat.addValue(LLViewerTextureList::sTextureBits/1024.f);
|
||||
stats.mTexturePacketsStat.addValue(LLViewerTextureList::sTexturePackets);
|
||||
LLAppViewer::getTextureFetch()->setTextureBandwidth(LLViewerTextureList::sTextureBits/1024.f/texture_stats_timer.getElapsedTimeF32());
|
||||
gTotalTextureBytes += LLViewerTextureList::sTextureBits / 8;
|
||||
LLViewerTextureList::sTextureBits = 0;
|
||||
LLViewerTextureList::sTexturePackets = 0;
|
||||
|
||||
@@ -43,7 +43,8 @@ public:
|
||||
mLayersKBitStat,
|
||||
mObjectKBitStat,
|
||||
mAssetKBitStat,
|
||||
mTextureKBitStat,
|
||||
mHTTPTextureKBitStat,
|
||||
mUDPTextureKBitStat,
|
||||
mVFSPendingOperations,
|
||||
mObjectsDrawnStat,
|
||||
mObjectsCulledStat,
|
||||
|
||||
@@ -687,8 +687,6 @@ void LLViewerTextureList::updateImages(F32 max_time)
|
||||
}
|
||||
cleared = FALSE;
|
||||
|
||||
LLAppViewer::getTextureFetch()->setTextureBandwidth(LLViewerStats::getInstance()->mTextureKBitStat.getMeanPerSec());
|
||||
|
||||
S32 global_raw_memory;
|
||||
{
|
||||
global_raw_memory = *AIAccess<S32>(LLImageRaw::sGlobalRawMemory);
|
||||
|
||||
@@ -2830,14 +2830,17 @@ void LLVOAvatar::idleUpdateNameTag(const LLVector3& root_pos_last)
|
||||
static const LLCachedControl<F32> NAME_SHOW_TIME("RenderNameShowTime",10); // seconds
|
||||
static const LLCachedControl<F32> FADE_DURATION("RenderNameFadeDuration",1); // seconds
|
||||
static const LLCachedControl<bool> use_chat_bubbles("UseChatBubbles",false);
|
||||
static const LLCachedControl<bool> use_typing_bubbles("UseTypingBubbles");
|
||||
static const LLCachedControl<bool> render_name_hide_self("RenderNameHideSelf",false);
|
||||
static const LLCachedControl<bool> allow_nameplate_override ("CCSAllowNameplateOverride", true);
|
||||
// [RLVa:KB] - Checked: 2009-07-08 (RLVa-1.0.0e) | Added: RLVa-0.2.0b
|
||||
// [RLVa:KB] - Checked: 2010-04-04 (RLVa-1.2.2a) | Added: RLVa-0.2.0b
|
||||
bool fRlvShowNames = gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES);
|
||||
// [/RLVa:KB]
|
||||
BOOL visible_avatar = isVisible() || mNeedsAnimUpdate;
|
||||
BOOL visible_chat = use_chat_bubbles && (mChats.size() || mTyping);
|
||||
bool visible_typing = use_typing_bubbles && mTyping;
|
||||
BOOL render_name = visible_chat ||
|
||||
visible_typing ||
|
||||
(visible_avatar &&
|
||||
// [RLVa:KB] - Checked: 2010-04-04 (RLVa-1.2.2a) | Added: RLVa-1.0.0h
|
||||
( (!fRlvShowNames) || (RlvSettings::getShowNameTags()) ) &&
|
||||
@@ -2871,6 +2874,11 @@ void LLVOAvatar::idleUpdateNameTag(const LLVector3& root_pos_last)
|
||||
mVisibleChat = visible_chat;
|
||||
new_name = TRUE;
|
||||
}
|
||||
if (visible_typing != mVisibleTyping)
|
||||
{
|
||||
mVisibleTyping = visible_typing;
|
||||
new_name = true;
|
||||
}
|
||||
|
||||
// [RLVa:KB] - Checked: 2010-04-04 (RLVa-1.2.2a) | Added: RLVa-0.2.0b
|
||||
if (fRlvShowNames)
|
||||
@@ -2895,7 +2903,7 @@ void LLVOAvatar::idleUpdateNameTag(const LLVector3& root_pos_last)
|
||||
if (mAppAngle > 5.f)
|
||||
{
|
||||
const F32 START_FADE_TIME = NAME_SHOW_TIME - FADE_DURATION;
|
||||
if (!visible_chat && sRenderName == RENDER_NAME_FADE && time_visible > START_FADE_TIME)
|
||||
if (!visible_chat && !visible_typing && sRenderName == RENDER_NAME_FADE && time_visible > START_FADE_TIME)
|
||||
{
|
||||
alpha = 1.f - (time_visible - START_FADE_TIME) / FADE_DURATION;
|
||||
}
|
||||
@@ -3271,7 +3279,7 @@ void LLVOAvatar::idleUpdateNameTagText(BOOL new_name)
|
||||
new_name = TRUE;
|
||||
}
|
||||
|
||||
if (mVisibleChat)
|
||||
if (mVisibleChat || mVisibleTyping)
|
||||
{
|
||||
mNameText->setFont(LLFontGL::getFontSansSerif());
|
||||
mNameText->setTextAlignment(LLHUDNameTag::ALIGN_TEXT_LEFT);
|
||||
@@ -3281,6 +3289,8 @@ void LLVOAvatar::idleUpdateNameTagText(BOOL new_name)
|
||||
mNameText->clearString();
|
||||
|
||||
LLColor4 new_chat = gColors.getColor( "AvatarNameColor" );
|
||||
if (mVisibleChat)
|
||||
{
|
||||
LLColor4 normal_chat = lerp(new_chat, LLColor4(0.8f, 0.8f, 0.8f, 1.f), 0.7f);
|
||||
LLColor4 old_chat = lerp(normal_chat, LLColor4(0.6f, 0.6f, 0.6f, 1.f), 0.7f);
|
||||
if (mTyping && mChats.size() >= MAX_BUBBLE_CHAT_UTTERANCES)
|
||||
@@ -3320,6 +3330,7 @@ void LLVOAvatar::idleUpdateNameTagText(BOOL new_name)
|
||||
mNameText->addLine(chat_iter->mText, old_chat, style);
|
||||
}
|
||||
}
|
||||
}
|
||||
mNameText->setVisibleOffScreen(TRUE);
|
||||
|
||||
if (mTyping)
|
||||
@@ -3351,7 +3362,7 @@ void LLVOAvatar::idleUpdateNameTagText(BOOL new_name)
|
||||
void LLVOAvatar::addNameTagLine(const std::string& line, const LLColor4& color, S32 style, const LLFontGL* font)
|
||||
{
|
||||
llassert(mNameText);
|
||||
if (mVisibleChat)
|
||||
if (mVisibleChat || mVisibleTyping)
|
||||
{
|
||||
mNameText->addLabel(line);
|
||||
}
|
||||
|
||||
@@ -814,6 +814,7 @@ public:
|
||||
void stopTyping() { mTyping = FALSE; mIdleTimer.reset();}
|
||||
private:
|
||||
BOOL mVisibleChat;
|
||||
bool mVisibleTyping;
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// Lip synch morphs
|
||||
|
||||
@@ -37,6 +37,9 @@
|
||||
<on_click function="Object.ImportUpload" />
|
||||
<on_enable function="Object.EnableImport" />
|
||||
</menu_item_call>
|
||||
<menu_item_call label="Change Local Textures" mouse_opaque="true" name="Change Local Textures">
|
||||
<on_click function="File.LocalAssetBrowser"/>
|
||||
</menu_item_call>
|
||||
<menu_item_separator enabled="true" label="-----------" mouse_opaque="true" name="separator" />
|
||||
<menu_item_call enabled="true" label="Set Default Permissions..."
|
||||
mouse_opaque="true" name="perm prefs" >
|
||||
@@ -44,6 +47,9 @@
|
||||
</menu_item_call>
|
||||
<menu_item_separator bottom="-94" enabled="true" height="8" label="-----------" left="0"
|
||||
mouse_opaque="true" name="separator" width="243" />
|
||||
<menu_item_call label="Minimize All Windows" mouse_opaque="true" name="Minimize All Windows">
|
||||
<on_click function="File.MinimizeAllWindows"/>
|
||||
</menu_item_call>
|
||||
<menu_item_call bottom="-113" enabled="true" height="19" label="Close Window" left="0"
|
||||
mouse_opaque="true" name="Close Window" shortcut="control|W" width="243">
|
||||
<on_click function="File.CloseWindow" userdata="" />
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
<check_box bottom_delta="-20" follows="left|top" control_name="OptionShowGroupNameInChatIM" initial_value="false"
|
||||
label="Show group name in chat" tool_tip="The name of the group will also be displayed if the IM is from group chat." name="append_group_name_check"/>
|
||||
<check_box bottom_delta="-20" follows="left|top" control_name="ShowDisplayNameChanges" label="Show display name changes" tool_tip="When checked, a notification will come up in chat whenever someone's display name changes." name="display_name_change"/>
|
||||
<check_box bottom_delta="-20" follows="left|top" control_name="UseTypingBubbles" label="Use overhead typing indicator bubbles" name="use_typing_bubbles"/>
|
||||
<text bottom="-150" left="10" follows="left|top" name="objects_link_text_box3">Show links on chatting object names in chat history for:</text>
|
||||
<radio_group bottom_delta="-26" control_name="LinksForChattingObjects" tool_tip="Enables a link to show you the owner of the speaking object."
|
||||
follows="top" height="20" left="20" name="objects_link" width="350">
|
||||
|
||||
@@ -30,17 +30,17 @@
|
||||
<!-- Buttons -->
|
||||
<button label="Delete" label_selected="Delete" enabled="true" name="btn_delete"
|
||||
height="18" width="75" left="120" bottom_delta="-27"
|
||||
halign="center"
|
||||
halign="center" tool_type="Delete the selected grid from the list"
|
||||
follows="left|top" scale_image="true"
|
||||
font="SansSerifSmall" mouse_opaque="true" />
|
||||
<button label="Add" label_selected="Add" enabled="true" name="btn_add"
|
||||
<button label="Create" label_selected="Add" enabled="true" name="btn_add"
|
||||
height="18" width="75" left_delta="78" bottom_delta="0"
|
||||
halign="center"
|
||||
halign="center" tool_tip="Add a new grid to the list"
|
||||
follows="left|top" scale_image="true"
|
||||
font="SansSerifSmall" mouse_opaque="true" />
|
||||
<button label="Copy" label_selected="Copy" enabled="true" name="btn_copy"
|
||||
height="18" width="75" left_delta="78" bottom_delta="0"
|
||||
halign="center"
|
||||
halign="center" tool_tip="Create a new entry using the selected entry as template"
|
||||
follows="left|top" scale_image="true"
|
||||
font="SansSerifSmall" mouse_opaque="true" />
|
||||
<!-- Advanced -->
|
||||
@@ -65,11 +65,11 @@
|
||||
font="SansSerifSmall"
|
||||
follows="left|top|right" border_visible="false" mouse_opaque="false"
|
||||
drop_shadow_visible="true" border_drop_shadow_visible="false" />
|
||||
<!--<button label="Get Grid Info" label_selected="Get Grid Info" enabled="true" name="btn_gridinfo"
|
||||
<button label="Refresh Grid URLs" enabled="true" name="btn_gridinfo"
|
||||
height="18" width="100" left="120" bottom_delta="-22"
|
||||
halign="center"
|
||||
halign="center" tool_tip="Retrieve all grid info from the given Login URI (overwriting the current URLs, see Advanced)"
|
||||
follows="left|top" scale_image="true"
|
||||
font="SansSerifSmall" mouse_opaque="true" />-->
|
||||
font="SansSerifSmall" mouse_opaque="true" />
|
||||
<!-- Platform -->
|
||||
<text type="string" length="1" enabled="true" name="platform_label"
|
||||
height="10" width="100" left="12" bottom_delta="-32"
|
||||
|
||||
@@ -1,16 +1,27 @@
|
||||
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
|
||||
<floater name="toolbox floater" title="" short_title="Construire">
|
||||
<button label="" label_selected="" name="button focus" tool_tip="Mise au point"/>
|
||||
<button label="" label_selected="" name="button move" tool_tip="Déplacer"/>
|
||||
<button label="" label_selected="" name="button edit" tool_tip="Modifier"/>
|
||||
<button label="" label_selected="" name="button create" tool_tip="Créer"/>
|
||||
<button label="" label_selected="" name="button land" tool_tip="Terrain"/>
|
||||
|
||||
<!-- Main floater tabs -->
|
||||
|
||||
<button name="button focus" tool_tip="Mise au point"/>
|
||||
<button name="button move" tool_tip="Déplacer"/>
|
||||
<button name="button edit" tool_tip="Modifier"/>
|
||||
<button name="button create" tool_tip="Créer"/>
|
||||
<button name="button land" tool_tip="Terrain"/>
|
||||
|
||||
<!-- Focus panel -->
|
||||
|
||||
<check_box label="Zoom" name="radio zoom"/>
|
||||
<check_box label="Orbite (Ctrl)" name="radio orbit"/>
|
||||
<check_box label="Panoramique (Ctrl-Maj)" name="radio pan"/>
|
||||
|
||||
<!-- Move panel -->
|
||||
|
||||
<check_box label="Déplacer" name="radio move"/>
|
||||
<check_box label="Orbite (Ctrl)" name="radio lift"/>
|
||||
<check_box label="Faire tourner (Ctrl-Maj)" name="radio spin"/>
|
||||
|
||||
<!-- Edit panel -->
|
||||
<check_box label="Positionner" name="radio position"/>
|
||||
<check_box label="Pivoter (Ctrl)" name="radio rotate"/>
|
||||
<check_box label="Étirer (Ctrl-Maj)" name="radio stretch"/>
|
||||
@@ -32,11 +43,20 @@
|
||||
</combo_box>
|
||||
<check_box label="Étirer les deux côtés" name="checkbox uniform"/>
|
||||
<check_box label="Étirer les textures" name="checkbox stretch textures"/>
|
||||
<check_box label="Utiliser la grille" name="checkbox snap to grid"/>
|
||||
<check_box label="Limiter le 'drag distance'" name="checkbox limit drag distance"/>
|
||||
<check_box label="Editer l'axe sur le 'Root'" name="checkbox actual root"/>
|
||||
<check_box label="Montrer les ojb. invisibles" name="checkbox show highlight"/>
|
||||
<check_box label="Grille" name="checkbox snap to grid"/>
|
||||
<button label="Options" label_selected="Options" name="Options"/>
|
||||
|
||||
<!-- Help text -->
|
||||
|
||||
<text name="text status">
|
||||
Glissez pour déplacer, Maj-glissez pour copier.
|
||||
</text>
|
||||
|
||||
<!-- Create panel -->
|
||||
|
||||
<button name="ToolCube" tool_tip="Cube"/>
|
||||
<button name="ToolPrism" tool_tip="Prisme droit"/>
|
||||
<button name="ToolPyramid" tool_tip="Pyramide"/>
|
||||
@@ -56,6 +76,9 @@
|
||||
<check_box label="Copier la sélection" name="checkbox copy selection"/>
|
||||
<check_box label="Centrer" name="checkbox copy centers"/>
|
||||
<check_box label="Pivoter" name="checkbox copy rotates"/>
|
||||
|
||||
<!-- Land panel -->
|
||||
|
||||
<check_box label="Sélectionner le terrain" name="radio select land"/>
|
||||
<check_box label="Aplatir" name="radio flatten"/>
|
||||
<check_box label="Élever" name="radio raise"/>
|
||||
@@ -73,12 +96,12 @@
|
||||
<text name="Strength:">
|
||||
Force
|
||||
</text>
|
||||
<text name="obj_count">
|
||||
Objets sélectionnés : [COUNT]
|
||||
</text>
|
||||
<text name="prim_count">
|
||||
Prims : [COUNT]
|
||||
Prims : [COUNT]
|
||||
</text>
|
||||
|
||||
<!-- Sub-tabs -->
|
||||
|
||||
<tab_container name="Object Info Tabs">
|
||||
<panel label="Général" name="General">
|
||||
<text name="Name:">
|
||||
@@ -97,15 +120,10 @@
|
||||
<text name="Owner:">
|
||||
Propriétaire :
|
||||
</text>
|
||||
|
||||
<button label="Profil" label_selected="Profil" name="button last owner profile"/>
|
||||
<text bg_visible="false" border_drop_shadow_visible="false" border_visible="false"
|
||||
bottom_delta="-20" drop_shadow_visible="true" follows="left|top"
|
||||
font="SansSerifSmall" h_pad="0" halign="left" height="16" left="10"
|
||||
mouse_opaque="true" name="Last Owner:" v_pad="0" width="78">
|
||||
<text name="Last Owner:">
|
||||
Dernier Proprio :
|
||||
</text>
|
||||
|
||||
<text name="Owner Name">
|
||||
Thrax Linden
|
||||
</text>
|
||||
@@ -124,7 +142,7 @@
|
||||
<text name="perm_modify">
|
||||
Vous pouvez modifier cet objet.
|
||||
</text>
|
||||
<check_box label="Partager avec le groupe" name="checkbox share with group" tool_tip="Autorise tous les membres du groupe choisi à utiliser et à partager vos droits pour cet objet. Pour activer les restrictions de rôles, vous devez d'abord cliquer sur Transférer."/>
|
||||
<check_box label="Partager avec le groupe" name="checkbox share with group" tool_tip="Autorise tous les membres du groupe choisi à utiliser et à partager vos droits pour cet objet. Pour activer les restrictions de rôles, vous devez d'abord cliquer sur Transférer."/>
|
||||
<string name="text deed continued">
|
||||
Transférer
|
||||
</string>
|
||||
@@ -132,12 +150,14 @@
|
||||
Transférer
|
||||
</string>
|
||||
<button label="Céder" label_selected="Céder" name="button deed" tool_tip="Les objets partagés par un groupe peuvent être cédés par un officier."/>
|
||||
<check_box label="Autoriser tout le monde à déplacer" name="checkbox allow everyone move"/>
|
||||
<check_box label="Autoriser tout le monde à copier" name="checkbox allow everyone copy"/>
|
||||
<check_box label="Afficher dans la recherche" name="search_check" tool_tip="Affiche l'objet dans les résultats de recherche"/>
|
||||
<text name="text anyone can">Tout le monde peux:</text>
|
||||
<check_box label="Déplacer" name="checkbox allow everyone move"/>
|
||||
<check_box label="Copier" name="checkbox allow everyone copy"/>
|
||||
<check_box name="checkbox allow export" label="Exporter"/>
|
||||
<check_box label="Afficher dans la recherche" name="search_check" tool_tip="Affiche l'objet dans les résultats de recherche"/>
|
||||
<check_box label="À vendre" name="checkbox for sale"/>
|
||||
<text name="Cost">
|
||||
Prix : [CURRENCY]
|
||||
Prix : [CURRENCY]
|
||||
</text>
|
||||
<radio_group name="sale type">
|
||||
<radio_item name="Original">
|
||||
@@ -151,26 +171,26 @@
|
||||
</radio_item>
|
||||
</radio_group>
|
||||
<text name="Next owner can:">
|
||||
Le prochain propriétaire pourra :
|
||||
Le prochain propriétaire pourra :
|
||||
</text>
|
||||
<check_box label="Modifier" name="checkbox next owner can modify"/>
|
||||
<check_box label="Copier" left_delta="66" name="checkbox next owner can copy"/>
|
||||
<check_box label="Revendre/Donner" name="checkbox next owner can transfer"/>
|
||||
<text name="label click action">
|
||||
Action du clic-gauche :
|
||||
Action du clic-gauche :
|
||||
</text>
|
||||
<combo_box name="clickaction" width="178">
|
||||
<combo_item name="Touch/grab(default)">
|
||||
Toucher/attraper (défaut)
|
||||
</combo_item>
|
||||
<combo_item name="Sitonobject">
|
||||
S'asseoir sur l'objet
|
||||
S'asseoir sur l'objet
|
||||
</combo_item>
|
||||
<combo_item name="Buyobject">
|
||||
Acheter l'objet
|
||||
Acheter l'objet
|
||||
</combo_item>
|
||||
<combo_item name="Payobject">
|
||||
Payer l'objet
|
||||
Payer l'objet
|
||||
</combo_item>
|
||||
<combo_item name="Open">
|
||||
Ouvrir
|
||||
@@ -183,24 +203,14 @@
|
||||
</combo_item>
|
||||
</combo_box>
|
||||
<button bottom="-338" label="Copier la Clef" tool_tip="Copie la clef dans le presse-papier." width="80"/>
|
||||
<text name="B:">
|
||||
B :
|
||||
</text>
|
||||
<text name="O:">
|
||||
O :
|
||||
</text>
|
||||
<text name="G:">
|
||||
G :
|
||||
</text>
|
||||
<text name="E:">
|
||||
E :
|
||||
</text>
|
||||
<text name="N:">
|
||||
N :
|
||||
</text>
|
||||
<text name="F:">
|
||||
F :
|
||||
</text>
|
||||
<panel name="pathfinding_attrs_panel">
|
||||
<text name="pathfinding_attributes_label">
|
||||
Pathfinding :
|
||||
</text>
|
||||
<text name="pathfinding_attributes_value">
|
||||
Tester
|
||||
</text>
|
||||
</panel>
|
||||
<string name="text modify info 1">
|
||||
Vous pouvez modifier cet objet.
|
||||
</string>
|
||||
@@ -217,13 +227,13 @@
|
||||
Sélectionnez l'objet en entier.
|
||||
</string>
|
||||
<string name="Cost Default">
|
||||
Prix : [CURRENCY]
|
||||
Prix : [CURRENCY]
|
||||
</string>
|
||||
<string name="Cost Total">
|
||||
Prix total : [CURRENCY]
|
||||
Prix total : [CURRENCY]
|
||||
</string>
|
||||
<string name="Cost Per Unit">
|
||||
Prix par : [CURRENCY]
|
||||
Prix par : [CURRENCY]
|
||||
</string>
|
||||
<string name="Cost Mixed">
|
||||
Prix mixte
|
||||
@@ -232,19 +242,12 @@
|
||||
Vente mixte
|
||||
</string>
|
||||
</panel>
|
||||
|
||||
<!-- Object sub-tab -->
|
||||
|
||||
<panel label="Objet" name="Object">
|
||||
<text name="select_single">
|
||||
|
||||
</text>
|
||||
<text name="edit_object">
|
||||
|
||||
</text>
|
||||
<button bottom="-26" follows="top|right" font="SansSerifSmall" halign="center"
|
||||
height="18" label="Lier" left="10" mouse_opaque="true" name="link_obj" enabled="true"
|
||||
tool_tip="" width="50" />
|
||||
<button bottom_delta="0" follows="top|right" font="SansSerifSmall" halign="center"
|
||||
height="18" label="Delier" left_delta="50" mouse_opaque="true" name="unlink_obj" enabled="true"
|
||||
tool_tip="Unlinks linkset." width="50" />
|
||||
<button label="Lier" name="link_obj"/>
|
||||
<button label="Delier" name="unlink_obj"/>
|
||||
<check_box label="Verrouillé" name="checkbox locked" tool_tip="Empêche l'objet d'être déplacé ou supprimé. Utile pendant la construction pour éviter les modifications involontaires."/>
|
||||
<check_box label="Physique" name="Physical Checkbox Ctrl" tool_tip="Permet à l'objet d'être poussé et affecté par la gravité"/>
|
||||
<check_box label="Temporaire" name="Temporary Checkbox Ctrl" tool_tip="L'objet est supprimé 2 mn après sa création."/>
|
||||
@@ -252,21 +255,12 @@
|
||||
<text name="label position">
|
||||
Position (mètres)
|
||||
</text>
|
||||
<spinner label="X" name="Pos X"/>
|
||||
<spinner label="Y" name="Pos Y"/>
|
||||
<spinner label="Z" name="Pos Z"/>
|
||||
<text name="label size">
|
||||
Taille (mètres)
|
||||
</text>
|
||||
<spinner label="X" name="Scale X"/>
|
||||
<spinner label="Y" name="Scale Y"/>
|
||||
<spinner label="Z" name="Scale Z"/>
|
||||
<text name="label rotation">
|
||||
Rotation (degrés)
|
||||
</text>
|
||||
<spinner label="X" name="Rot X"/>
|
||||
<spinner label="Y" name="Rot Y"/>
|
||||
<spinner label="Z" name="Rot Z"/>
|
||||
<text name="label material">
|
||||
Matériau
|
||||
</text>
|
||||
@@ -414,12 +408,15 @@
|
||||
</combo_item>
|
||||
</combo_box>
|
||||
</panel>
|
||||
|
||||
<!-- Features sub-tab -->
|
||||
|
||||
<panel label="Attributs" name="Features">
|
||||
<text name="select_single">
|
||||
Sélectionnez un prim pour modifier les attributs.
|
||||
</text>
|
||||
<text name="edit_object">
|
||||
Modifiez les attributs de l'objet :
|
||||
Modifiez les attributs de l'objet :
|
||||
</text>
|
||||
<check_box label="Flexibilité" name="Flexible1D Checkbox Ctrl" tool_tip="Donne à l'objet de la souplesse sur l'axe des Z (côté client uniquement)."/>
|
||||
<spinner label="Souplesse" name="FlexNumSections"/>
|
||||
@@ -539,9 +536,7 @@
|
||||
<text name="tex scale">
|
||||
Répétitions par face
|
||||
</text>
|
||||
<spinner label="Horizontal (U)" name="TexScaleU"/>
|
||||
<check_box label="Inverser" name="checkbox flip s"/>
|
||||
<spinner label="Vertical (V)" name="TexScaleV"/>
|
||||
<check_box label="Inverser" name="checkbox flip t"/>
|
||||
<text name="tex rotate">
|
||||
Rotation (degrés)
|
||||
@@ -561,21 +556,17 @@
|
||||
<text name="tex offset">
|
||||
Décalage
|
||||
</text>
|
||||
<spinner label="Horizontal (U)" name="TexOffsetU"/>
|
||||
<spinner label="Vertical (V)" name="TexOffsetV"/>
|
||||
<text name="textbox autofix">
|
||||
Ajuster la texture du média
|
||||
(chargement préalable)
|
||||
</text>
|
||||
<button label="Ajuster" label_selected="Ajuster" left="140" name="button align" width="45"/>
|
||||
|
||||
<text name="textbox params">Paramètres</text>
|
||||
<button label="Copier" name="copytextures" tool_tip="Copie les paramètres de la texture dans le presse papier" width="55"/>
|
||||
<button label="Coller" name="pastetextures" tool_tip="Colle les paramètres de la texture du presse papier" width="55"/>
|
||||
</panel>
|
||||
<panel label="Contenu" name="Contents">
|
||||
<button label="Nouveau script" label_selected="Nouveau script" name="button new script"/>
|
||||
<button label="Permissions" name="button permissions"/>
|
||||
</panel>
|
||||
</tab_container>
|
||||
<panel name="land info panel">
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
<menu_item_call label="Import multiples ([UPLOADFEE] par fichier)" name="Bulk Upload"/>
|
||||
<menu_item_call label="Import XML" name="Import"/>
|
||||
<menu_item_call label="Import avec textures" name="Import2"/>
|
||||
<menu_item_call label="Changer les textures locales" name="Change Local Textures"/>
|
||||
<menu_item_separator/>
|
||||
<menu_item_call label="Définir les droits par défaut " name="perm prefs"/>
|
||||
<menu_item_separator/>
|
||||
@@ -15,6 +16,7 @@
|
||||
<menu_item_call label="Enregistrer la texture sur le disque dur en PNG" name="Save Preview AsPNG..."/>
|
||||
|
||||
<menu_item_separator/>
|
||||
<menu_item_call label="Minimiser toutes les fenêtres" name="Minimize All Windows"/>
|
||||
<menu_item_call label="Fermer la fenêtre" name="Close Window"/>
|
||||
<menu_item_call label="Fermer toutes les fenêtres" name="Close All Windows"/>
|
||||
<menu_item_separator label="-----------" name="separator3"/>
|
||||
@@ -240,4 +242,4 @@
|
||||
</menu>
|
||||
<menu_item_call label="A propos de Singularity" name="About Second Life..."/>
|
||||
</menu>
|
||||
</menu_bar>
|
||||
</menu_bar>
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
<check_box label="Permet d'utiliser "/me" aussi bien que ":"" name="allow_mu_pose_check"/>
|
||||
<check_box label="Ajoute les fins des commentaires (RP mode)" tool_tip="Ajoute automatiquement "))" à chaque message commençant par "((", et vice-versa." name="close_ooc_check"/>
|
||||
<check_box label="Montre les changements de display name" tool_tip="" name="display_name_change"/>
|
||||
<check_box label="Le texte ecris défile au dessus de l'avi" name="use_typing_bubbles"/>
|
||||
<text name="objects_link_text_box3">Active un lien qui montre le nom du propriétaire dans l'historique du chat pour :</text>
|
||||
<radio_group tool_tip="Enables a link to show you the owner of the speaking object." name="objects_link">
|
||||
<radio_item name="no_object">Aucun objet</radio_item>
|
||||
|
||||
@@ -71,6 +71,7 @@
|
||||
<check_box label="Prendre discrètement un photo, sur votre disque dur" tool_tip="Permet de prendre une photo en mode "espionnage", sans bruit d'appareil, ni mouvement de caméra, ni gesture. (Uniquement vers le disque dur)." name="quiet_snapshots_check"/>
|
||||
<check_box label="En vous levant, annule les permissions que l'objet a sur votre avatar" tool_tip="Evite que l'objet garde le contrôle de votre avatar, comme par exemple les animations." name="revoke_perms_on_stand_up_check"/>
|
||||
<check_box label="Désactive le "Click to sit" automatique" tool_tip="Désactive llSitTarget. Vous devrez sélectionner vous même la fonction "sit" sur l'objet." name="disable_click_sit_check"/>
|
||||
<check_box left_delta="210" label="Sur les objets qui ne sont pas a vous" tool_tip="" name="disable_click_sit_own_check"/>
|
||||
<check_box label="Affiche les changements de décomptes de scripts de la région." name="totalscriptjumps" tool_tip="Dépendant du seuil que vous choisissez dans la fenêtre à droite."/>
|
||||
<spinner left_delta="350" name="ScriptJumpCount" tool_tip="Threshold for the script jump message [Default: 100]"/>
|
||||
</panel>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
|
||||
<panel label="Vanity" name="ascvan">
|
||||
<tab_container label="Singularity Vanity" name="Ascent Vanity">
|
||||
<panel name="ascvan">
|
||||
<tab_container name="Ascent Vanity">
|
||||
<panel label="Principal" name="General">
|
||||
<check_box label="Lorsque c'est possible, sauver le setting personnalisé par compte." tool_tip="Sauve le settings customisé pour chaque alt." name="use_account_settings_check"/>
|
||||
<check_box label="Masquer la barre de 'TP in progress'" tool_tip="Ceci permet de continuer des lire vos IMs durant le TP." name="disable_tp_screen_check"/>
|
||||
@@ -46,13 +46,7 @@
|
||||
<check_box name="color_linden_check" tool_tip="Color Linden Chat"/>
|
||||
<check_box name="color_muted_check" tool_tip="Color Muted Chat"/>
|
||||
</panel>
|
||||
<panel label="Body Dyn. (Bouger les nénés)" name="Body Dynamics">
|
||||
<check_box label="Activer les "physics" des nénés voire du popotin des avatars ^^" name="EmBreastsToggle"/>
|
||||
<slider name="EmeraldBoobMass" label="Masse :" />
|
||||
<slider name="EmeraldBoobHardness" label="Rebond :"/>
|
||||
<slider name="EmeraldBoobVelMax" label="Vélocité max :"/>
|
||||
<slider name="EmeraldBoobFriction" label="Friction :"/>
|
||||
<slider name="EmeraldBoobVelMin" label="Vélocité min :"/>
|
||||
<panel label="Body Dyn.(Offset de l'avatar)" name="Body Dynamics">
|
||||
<text name="av_mod_textbox" follows="top">Modifier l'offset de l'avatar</text>
|
||||
<spinner label="X Modif." name="X Modifier"/>
|
||||
<spinner label="Y Modif." name="Y Modifier"/>
|
||||
|
||||
@@ -3,36 +3,31 @@
|
||||
<text name="text_box">Bande passante max:</text>
|
||||
<text name="text_box2">kbps (kilobits par seconde)</text>
|
||||
<text name="text_box3">Bande passante de la texture:</text>
|
||||
<slider left_delta="150" name="tex_bandwidth" width="140"/>
|
||||
<text left_delta="146" name="text_box2">kbps (kilobits par seconde)</text>
|
||||
<slider left_delta="145" name="tex_bandwidth" width="145"/>
|
||||
<text left_delta="150" name="text_box4">kbps (kilobits par seconde)</text>
|
||||
<text name="use_http_for">Utiliser HTTP pour:</text>
|
||||
<check_box left_delta="100" label="Textures" name="http_textures"/>
|
||||
<check_box label="Inventaire" name="http_inventory"/>
|
||||
<text name="cache_size_label_l">Taille du cache:</text>
|
||||
<text name="text_box5">Mo</text>
|
||||
<button label="Vider la mémoire cache" label_selected="Vider le cache" name="clear_cache" width="150"/>
|
||||
<button label="Vider le cache" name="clear_cache" width="130"/>
|
||||
<text name="cache_location_label">Emplacement du cache:</text>
|
||||
<button label="Modifier" label_selected="Modifier" name="set_cache"/>
|
||||
<button label="Réinitialiser" label_selected="Réinitialiser" name="reset_cache"/>
|
||||
<check_box label="Port de connexion personnalisé" name="connection_port_enabled"/>
|
||||
<spinner label="Numéro de port:" label_width="95" name="connection_port" width="170"/>
|
||||
<text name="socks5_auth_label">Proxy Http:</text>
|
||||
<check_box label="Port de Connexion personnalisé" name="connection_port_enabled"/>
|
||||
<spinner label="Num. du Port:" name="connection_port"/>
|
||||
<radio_group name="socks5_http_proxy_type">
|
||||
<radio_item name="None">aucun</radio_item>
|
||||
<radio_item name="None">Aucun</radio_item>
|
||||
<radio_item name="Socks">Socks</radio_item>
|
||||
<radio_item name="Web">Web</radio_item>
|
||||
</radio_group>
|
||||
<check_box label="Activer SOCKS 5 Proxy" name="socks5_proxy_enabled"/>
|
||||
<text name="socks5_host_label">Hôte Socks 5:</text>
|
||||
<line_editor name="socks5_proxy_host" tool_tip=""/>
|
||||
<spinner label="Numéro de port:" label_width="80" name="socks5_proxy_port"/>
|
||||
<text name="socks5_host_label">Hôte Socks 5 :</text>
|
||||
<spinner label="Num. du Port:" name="socks5_proxy_port"/>
|
||||
<text name="socks5_auth_label2">Authentification:</text>
|
||||
<radio_group name="socks5_auth">
|
||||
<radio_item name="None" tool_tip="">aucune</radio_item>
|
||||
<radio_item name="UserPass" tool_tip="">Nom/Mot de passe</radio_item>
|
||||
<radio_item name="None">Aucune</radio_item>
|
||||
<radio_item name="UserPass">Nom/Mot de passe</radio_item>
|
||||
</radio_group>
|
||||
<text name="socks5_username_label">Nom:</text>
|
||||
<line_editor name="socks5_proxy_username"/>
|
||||
<text name="socks5_password_label">Mot de Passe:</text>
|
||||
<line_editor name="socks5_proxy_password"/>
|
||||
</panel>
|
||||
|
||||
@@ -7,6 +7,9 @@
|
||||
<text name="text_box2">
|
||||
kbps (kilobits por segundo)
|
||||
</text>
|
||||
<text name="text_box4">
|
||||
kbps (kilobits por segundo)
|
||||
</text>
|
||||
<text name="cache_size_label_l">
|
||||
Tamanho do Cachê de Disco:
|
||||
</text>
|
||||
|
||||
@@ -1,35 +1,36 @@
|
||||
#!/usr/bin/python
|
||||
# @file viewer_manifest.py
|
||||
# @author Ryan Williams
|
||||
# @brief Description of all installer viewer files, and methods for packaging
|
||||
# them into installers for all supported platforms.
|
||||
#
|
||||
# $LicenseInfo:firstyear=2006&license=viewergpl$
|
||||
#
|
||||
# Copyright (c) 2006-2009, Linden Research, Inc.
|
||||
#
|
||||
# Second Life Viewer Source Code
|
||||
# The source code in this file ("Source Code") is provided by Linden Lab
|
||||
# to you under the terms of the GNU General Public License, version 2.0
|
||||
# ("GPL"), unless you have obtained a separate licensing agreement
|
||||
# ("Other License"), formally executed by you and Linden Lab. Terms of
|
||||
# the GPL can be found in doc/GPL-license.txt in this distribution, or
|
||||
# online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
|
||||
#
|
||||
# There are special exceptions to the terms and conditions of the GPL as
|
||||
# it is applied to this Source Code. View the full text of the exception
|
||||
# in the file doc/FLOSS-exception.txt in this software distribution, or
|
||||
# online at
|
||||
# http://secondlifegrid.net/programs/open_source/licensing/flossexception
|
||||
#
|
||||
# By copying, modifying or distributing this software, you acknowledge
|
||||
# that you have read and understood your obligations described above,
|
||||
# and agree to abide by those obligations.
|
||||
#
|
||||
# ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
|
||||
# WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
|
||||
# COMPLETENESS OR PERFORMANCE.
|
||||
# $/LicenseInfo$
|
||||
#!/usr/bin/env python
|
||||
"""\
|
||||
@file viewer_manifest.py
|
||||
@author Ryan Williams
|
||||
@brief Description of all installer viewer files, and methods for packaging
|
||||
them into installers for all supported platforms.
|
||||
|
||||
$LicenseInfo:firstyear=2006&license=viewergpl$
|
||||
Second Life Viewer Source Code
|
||||
Copyright (c) 2006-2009, Linden Research, Inc.
|
||||
|
||||
The source code in this file ("Source Code") is provided by Linden Lab
|
||||
to you under the terms of the GNU General Public License, version 2.0
|
||||
("GPL"), unless you have obtained a separate licensing agreement
|
||||
("Other License"), formally executed by you and Linden Lab. Terms of
|
||||
the GPL can be found in doc/GPL-license.txt in this distribution, or
|
||||
online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
|
||||
|
||||
There are special exceptions to the terms and conditions of the GPL as
|
||||
it is applied to this Source Code. View the full text of the exception
|
||||
in the file doc/FLOSS-exception.txt in this software distribution, or
|
||||
online at
|
||||
http://secondlifegrid.net/programs/open_source/licensing/flossexception
|
||||
|
||||
By copying, modifying or distributing this software, you acknowledge
|
||||
that you have read and understood your obligations described above,
|
||||
and agree to abide by those obligations.
|
||||
|
||||
ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
|
||||
WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
|
||||
COMPLETENESS OR PERFORMANCE.
|
||||
$/LicenseInfo$
|
||||
"""
|
||||
import sys
|
||||
import os.path
|
||||
import re
|
||||
@@ -56,10 +57,13 @@ class ViewerManifest(LLManifest):
|
||||
|
||||
# include the entire shaders directory recursively
|
||||
self.path("shaders")
|
||||
|
||||
# ... and the entire windlight directory
|
||||
self.path("windlight")
|
||||
|
||||
# ... and the hunspell dictionaries
|
||||
self.path("dictionaries")
|
||||
|
||||
self.end_prefix("app_settings")
|
||||
|
||||
if self.prefix(src="character"):
|
||||
@@ -104,6 +108,7 @@ class ViewerManifest(LLManifest):
|
||||
self.path("*/*/*.html")
|
||||
self.path("*/*/*.gif")
|
||||
self.end_prefix("*/html")
|
||||
|
||||
self.end_prefix("skins")
|
||||
|
||||
# Files in the newview/ directory
|
||||
@@ -359,6 +364,7 @@ class WindowsManifest(ViewerManifest):
|
||||
result += 'File ' + pkg_file + '\n'
|
||||
else:
|
||||
result += 'Delete ' + wpath(os.path.join('$INSTDIR', rel_file)) + '\n'
|
||||
|
||||
# at the end of a delete, just rmdir all the directories
|
||||
if not install:
|
||||
deleted_file_dirs = [os.path.dirname(pair[1].replace(self.get_dst_prefix()+os.path.sep,'')) for pair in self.file_list]
|
||||
@@ -695,6 +701,9 @@ class LinuxManifest(ViewerManifest):
|
||||
self.path("wrapper.sh",self.wrapper_name())
|
||||
self.path("handle_secondlifeprotocol.sh")
|
||||
self.path("register_secondlifeprotocol.sh")
|
||||
self.path("refresh_desktop_app_entry.sh")
|
||||
self.path("launch_url.sh")
|
||||
self.path("install.sh")
|
||||
self.end_prefix("linux_tools")
|
||||
|
||||
# Create an appropriate gridargs.dat for this package, denoting required grid.
|
||||
@@ -707,7 +716,6 @@ class LinuxManifest(ViewerManifest):
|
||||
self.path("secondlife-bin","bin/"+self.binary_name())
|
||||
self.path("../linux_crash_logger/linux-crash-logger","linux-crash-logger.bin")
|
||||
|
||||
self.path("linux_tools/launch_url.sh","launch_url.sh")
|
||||
self.path("../llplugin/slplugin/SLPlugin", "bin/SLPlugin")
|
||||
if self.prefix("res-sdl"):
|
||||
self.path("*")
|
||||
|
||||
Reference in New Issue
Block a user