Merge remote-tracking branch 'remotes/origin/DRTVWR-563' into DRTVWR-559
commit
197ac7cc20
|
|
@ -151,7 +151,7 @@ LLTexLayerParamAlpha::LLTexLayerParamAlpha(const LLTexLayerParamAlpha& pOther)
|
|||
mCachedProcessedTexture(pOther.mCachedProcessedTexture),
|
||||
mStaticImageTGA(pOther.mStaticImageTGA),
|
||||
mStaticImageRaw(pOther.mStaticImageRaw),
|
||||
mNeedsCreateTexture(pOther.mNeedsCreateTexture),
|
||||
mNeedsCreateTexture(pOther.mNeedsCreateTexture.load()),
|
||||
mStaticImageInvalid(pOther.mStaticImageInvalid),
|
||||
mAvgDistortionVec(pOther.mAvgDistortionVec),
|
||||
mCachedEffectiveWeight(pOther.mCachedEffectiveWeight)
|
||||
|
|
|
|||
|
|
@ -100,7 +100,7 @@ private:
|
|||
LLPointer<LLGLTexture> mCachedProcessedTexture;
|
||||
LLPointer<LLImageTGA> mStaticImageTGA;
|
||||
LLPointer<LLImageRaw> mStaticImageRaw;
|
||||
BOOL mNeedsCreateTexture;
|
||||
std::atomic<BOOL> mNeedsCreateTexture;
|
||||
BOOL mStaticImageInvalid;
|
||||
LL_ALIGN_16(LLVector4a mAvgDistortionVec);
|
||||
F32 mCachedEffectiveWeight;
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@ include_directories(
|
|||
# ${LLCOMMON_LIBRARIES})
|
||||
|
||||
set(llcommon_SOURCE_FILES
|
||||
commoncontrol.cpp
|
||||
indra_constants.cpp
|
||||
llallocator.cpp
|
||||
llallocator_heap_profile.cpp
|
||||
|
|
@ -130,6 +131,7 @@ set(llcommon_HEADER_FILES
|
|||
|
||||
chrono.h
|
||||
classic_callback.h
|
||||
commoncontrol.h
|
||||
ctype_workaround.h
|
||||
fix_macros.h
|
||||
indra_constants.h
|
||||
|
|
|
|||
|
|
@ -0,0 +1,106 @@
|
|||
/**
|
||||
* @file commoncontrol.cpp
|
||||
* @author Nat Goodspeed
|
||||
* @date 2022-06-08
|
||||
* @brief Implementation for commoncontrol.
|
||||
*
|
||||
* $LicenseInfo:firstyear=2022&license=viewerlgpl$
|
||||
* Copyright (c) 2022, Linden Research, Inc.
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
// Precompiled header
|
||||
#include "linden_common.h"
|
||||
// associated header
|
||||
#include "commoncontrol.h"
|
||||
// STL headers
|
||||
// std headers
|
||||
// external library headers
|
||||
// other Linden headers
|
||||
#include "llevents.h"
|
||||
#include "llsdutil.h"
|
||||
|
||||
LLSD LL::CommonControl::access(const LLSD& params)
|
||||
{
|
||||
// We can't actually introduce a link-time dependency on llxml, or on any
|
||||
// global LLControlGroup (*koff* gSavedSettings *koff*) but we can issue a
|
||||
// runtime query. If we're running as part of a viewer with
|
||||
// LLViewerControlListener, we can use that to interact with any
|
||||
// instantiated LLControGroup.
|
||||
LLSD response;
|
||||
{
|
||||
LLEventStream reply("reply");
|
||||
LLTempBoundListener connection = reply.listen("listener",
|
||||
[&response] (const LLSD& event)
|
||||
{
|
||||
response = event;
|
||||
return false;
|
||||
});
|
||||
LLSD rparams{ params };
|
||||
rparams["reply"] = reply.getName();
|
||||
LLEventPumps::instance().obtain("LLViewerControl").post(rparams);
|
||||
}
|
||||
// LLViewerControlListener responds immediately. If it's listening at all,
|
||||
// it will already have set response.
|
||||
if (! response.isDefined())
|
||||
{
|
||||
LLTHROW(NoListener("No LLViewerControl listener instantiated"));
|
||||
}
|
||||
LLSD error{ response["error"] };
|
||||
if (error.isDefined())
|
||||
{
|
||||
LLTHROW(ParamError(error));
|
||||
}
|
||||
response.erase("error");
|
||||
response.erase("reqid");
|
||||
return response;
|
||||
}
|
||||
|
||||
/// set control group.key to defined default value
|
||||
LLSD LL::CommonControl::set_default(const std::string& group, const std::string& key)
|
||||
{
|
||||
return access(llsd::map("op", "set",
|
||||
"group", group, "key", key))["value"];
|
||||
}
|
||||
|
||||
/// set control group.key to specified value
|
||||
LLSD LL::CommonControl::set(const std::string& group, const std::string& key, const LLSD& value)
|
||||
{
|
||||
return access(llsd::map("op", "set",
|
||||
"group", group, "key", key, "value", value))["value"];
|
||||
}
|
||||
|
||||
/// toggle boolean control group.key
|
||||
LLSD LL::CommonControl::toggle(const std::string& group, const std::string& key)
|
||||
{
|
||||
return access(llsd::map("op", "toggle",
|
||||
"group", group, "key", key))["value"];
|
||||
}
|
||||
|
||||
/// get the definition for control group.key, (! isDefined()) if bad
|
||||
/// ["name"], ["type"], ["value"], ["comment"]
|
||||
LLSD LL::CommonControl::get_def(const std::string& group, const std::string& key)
|
||||
{
|
||||
return access(llsd::map("op", "get",
|
||||
"group", group, "key", key));
|
||||
}
|
||||
|
||||
/// get the value of control group.key
|
||||
LLSD LL::CommonControl::get(const std::string& group, const std::string& key)
|
||||
{
|
||||
return access(llsd::map("op", "get",
|
||||
"group", group, "key", key))["value"];
|
||||
}
|
||||
|
||||
/// get defined groups
|
||||
std::vector<std::string> LL::CommonControl::get_groups()
|
||||
{
|
||||
auto groups{ access(llsd::map("op", "groups"))["groups"] };
|
||||
return { groups.beginArray(), groups.endArray() };
|
||||
}
|
||||
|
||||
/// get definitions for all variables in group
|
||||
LLSD LL::CommonControl::get_vars(const std::string& group)
|
||||
{
|
||||
return access(llsd::map("op", "vars", "group", group))["vars"];
|
||||
}
|
||||
|
|
@ -0,0 +1,75 @@
|
|||
/**
|
||||
* @file commoncontrol.h
|
||||
* @author Nat Goodspeed
|
||||
* @date 2022-06-08
|
||||
* @brief Access LLViewerControl LLEventAPI, if process has one.
|
||||
*
|
||||
* $LicenseInfo:firstyear=2022&license=viewerlgpl$
|
||||
* Copyright (c) 2022, Linden Research, Inc.
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#if ! defined(LL_COMMONCONTROL_H)
|
||||
#define LL_COMMONCONTROL_H
|
||||
|
||||
#include <vector>
|
||||
#include "llexception.h"
|
||||
#include "llsd.h"
|
||||
|
||||
namespace LL
|
||||
{
|
||||
class CommonControl
|
||||
{
|
||||
public:
|
||||
struct Error: public LLException
|
||||
{
|
||||
Error(const std::string& what): LLException(what) {}
|
||||
};
|
||||
|
||||
/// Exception thrown if there's no LLViewerControl LLEventAPI
|
||||
struct NoListener: public Error
|
||||
{
|
||||
NoListener(const std::string& what): Error(what) {}
|
||||
};
|
||||
|
||||
struct ParamError: public Error
|
||||
{
|
||||
ParamError(const std::string& what): Error(what) {}
|
||||
};
|
||||
|
||||
/// set control group.key to defined default value
|
||||
static
|
||||
LLSD set_default(const std::string& group, const std::string& key);
|
||||
|
||||
/// set control group.key to specified value
|
||||
static
|
||||
LLSD set(const std::string& group, const std::string& key, const LLSD& value);
|
||||
|
||||
/// toggle boolean control group.key
|
||||
static
|
||||
LLSD toggle(const std::string& group, const std::string& key);
|
||||
|
||||
/// get the definition for control group.key, (! isDefined()) if bad
|
||||
/// ["name"], ["type"], ["value"], ["comment"]
|
||||
static
|
||||
LLSD get_def(const std::string& group, const std::string& key);
|
||||
|
||||
/// get the value of control group.key
|
||||
static
|
||||
LLSD get(const std::string& group, const std::string& key);
|
||||
|
||||
/// get defined groups
|
||||
static
|
||||
std::vector<std::string> get_groups();
|
||||
|
||||
/// get definitions for all variables in group
|
||||
static
|
||||
LLSD get_vars(const std::string& group);
|
||||
|
||||
private:
|
||||
static
|
||||
LLSD access(const LLSD& params);
|
||||
};
|
||||
} // namespace LL
|
||||
|
||||
#endif /* ! defined(LL_COMMONCONTROL_H) */
|
||||
|
|
@ -526,6 +526,7 @@ S32 LLAPRFile::seek(apr_file_t* file_handle, apr_seek_where_t where, S32 offset)
|
|||
//static
|
||||
S32 LLAPRFile::readEx(const std::string& filename, void *buf, S32 offset, S32 nbytes, LLVolatileAPRPool* pool)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED;
|
||||
//*****************************************
|
||||
LLAPRFilePoolScope scope(pool);
|
||||
apr_file_t* file_handle = open(filename, scope.getVolatileAPRPool(), APR_READ|APR_BINARY);
|
||||
|
|
@ -570,6 +571,7 @@ S32 LLAPRFile::readEx(const std::string& filename, void *buf, S32 offset, S32 nb
|
|||
//static
|
||||
S32 LLAPRFile::writeEx(const std::string& filename, void *buf, S32 offset, S32 nbytes, LLVolatileAPRPool* pool)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED;
|
||||
apr_int32_t flags = APR_CREATE|APR_WRITE|APR_BINARY;
|
||||
if (offset < 0)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -29,11 +29,6 @@
|
|||
|
||||
#include "llframetimer.h"
|
||||
|
||||
// We don't bother building a stand alone lib; we just need to include the one source file for Tracy support
|
||||
//#if LL_PROFILER_CONFIGURATION == LL_PROFILER_CONFIG_TRACY || LL_PROFILER_CONFIGURATION == LL_PROFILER_CONFIG_TRACY_FAST_TIMER
|
||||
// #include "TracyClient.cpp"
|
||||
//#endif // LL_PROFILER_CONFIGURATION
|
||||
|
||||
// Static members
|
||||
//LLTimer LLFrameTimer::sInternalTimer;
|
||||
U64 LLFrameTimer::sStartTotalTime = totalTime();
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@
|
|||
# include <sys/types.h>
|
||||
# include <mach/task.h>
|
||||
# include <mach/mach_init.h>
|
||||
#include <mach/mach_host.h>
|
||||
#elif LL_LINUX
|
||||
# include <unistd.h>
|
||||
#endif
|
||||
|
|
@ -109,6 +110,50 @@ void LLMemory::updateMemoryInfo()
|
|||
{
|
||||
sAvailPhysicalMemInKB = U32Kilobytes(0);
|
||||
}
|
||||
|
||||
#elif defined(LL_DARWIN)
|
||||
task_vm_info info;
|
||||
mach_msg_type_number_t infoCount = TASK_VM_INFO_COUNT;
|
||||
// MACH_TASK_BASIC_INFO reports the same resident_size, but does not tell us the reusable bytes or phys_footprint.
|
||||
if (task_info(mach_task_self(), TASK_VM_INFO, reinterpret_cast<task_info_t>(&info), &infoCount) == KERN_SUCCESS)
|
||||
{
|
||||
// Our Windows definition of PagefileUsage is documented by Microsoft as "the total amount of
|
||||
// memory that the memory manager has committed for a running process", which is rss.
|
||||
sAllocatedPageSizeInKB = U32Bytes(info.resident_size);
|
||||
|
||||
// Activity Monitor => Inspect Process => Real Memory Size appears to report resident_size
|
||||
// Activity monitor => main window memory column appears to report phys_footprint, which spot checks as at least 30% less.
|
||||
// I think that is because of compression, which isn't going to give us a consistent measurement. We want uncompressed totals.
|
||||
//
|
||||
// In between is resident_size - reusable. This is what Chrome source code uses, with source comments saying it is 'the "Real Memory" value
|
||||
// reported for the app by the Memory Monitor in Instruments.' It is still about 8% bigger than phys_footprint.
|
||||
//
|
||||
// (On Windows, we use WorkingSetSize.)
|
||||
sAllocatedMemInKB = U32Bytes(info.resident_size - info.reusable);
|
||||
}
|
||||
else
|
||||
{
|
||||
LL_WARNS() << "task_info failed" << LL_ENDL;
|
||||
}
|
||||
|
||||
// Total installed and available physical memory are properties of the host, not just our process.
|
||||
vm_statistics64_data_t vmstat;
|
||||
mach_msg_type_number_t count = HOST_VM_INFO64_COUNT;
|
||||
mach_port_t host = mach_host_self();
|
||||
vm_size_t page_size;
|
||||
host_page_size(host, &page_size);
|
||||
kern_return_t result = host_statistics64(host, HOST_VM_INFO64, reinterpret_cast<host_info_t>(&vmstat), &count);
|
||||
if (result == KERN_SUCCESS) {
|
||||
// This is what Chrome reports as 'the "Physical Memory Free" value reported by the Memory Monitor in Instruments.'
|
||||
// Note though that inactive pages are not included here and not yet free, but could become so under memory pressure.
|
||||
sAvailPhysicalMemInKB = U32Bytes(vmstat.free_count * page_size);
|
||||
sMaxPhysicalMemInKB = LLMemoryInfo::getHardwareMemSize();
|
||||
}
|
||||
else
|
||||
{
|
||||
LL_WARNS() << "task_info failed" << LL_ENDL;
|
||||
}
|
||||
|
||||
#else
|
||||
//not valid for other systems for now.
|
||||
sAllocatedMemInKB = U64Bytes(LLMemory::getCurrentRSS());
|
||||
|
|
|
|||
|
|
@ -134,6 +134,10 @@ extern thread_local bool gProfilerEnabled;
|
|||
#define LL_PROFILE_ZONE_ERR(name) LL_PROFILE_ZONE_NAMED_COLOR( name, 0XFF0000 ) // RGB yellow
|
||||
#define LL_PROFILE_ZONE_INFO(name) LL_PROFILE_ZONE_NAMED_COLOR( name, 0X00FFFF ) // RGB cyan
|
||||
#define LL_PROFILE_ZONE_WARN(name) LL_PROFILE_ZONE_NAMED_COLOR( name, 0x0FFFF00 ) // RGB red
|
||||
//#define LL_PROFILE_ALLOC(ptr, size) TracyAlloc(ptr, size) // memory allocation tracking currently not working
|
||||
//#define LL_PROFILE_FREE(ptr) TracyFree(ptr)
|
||||
#define LL_PROFILE_ALLOC(ptr, size) (void)(ptr); (void)(size);
|
||||
#define LL_PROFILE_FREE(ptr) (void)(ptr);
|
||||
#endif
|
||||
#else
|
||||
#define LL_PROFILER_FRAME_END
|
||||
|
|
|
|||
|
|
@ -26,20 +26,26 @@
|
|||
#include "linden_common.h"
|
||||
#include "llqueuedthread.h"
|
||||
|
||||
#include <chrono>
|
||||
|
||||
#include "llstl.h"
|
||||
#include "lltimer.h" // ms_sleep()
|
||||
#include "lltracethreadrecorder.h"
|
||||
#include "llmutex.h"
|
||||
|
||||
//============================================================================
|
||||
|
||||
// MAIN THREAD
|
||||
LLQueuedThread::LLQueuedThread(const std::string& name, bool threaded, bool should_pause) :
|
||||
LLThread(name),
|
||||
mThreaded(threaded),
|
||||
mIdleThread(TRUE),
|
||||
mNextHandle(0),
|
||||
mStarted(FALSE)
|
||||
LLThread(name),
|
||||
mIdleThread(TRUE),
|
||||
mNextHandle(0),
|
||||
mStarted(FALSE),
|
||||
mThreaded(threaded),
|
||||
mRequestQueue(name, 1024 * 1024)
|
||||
{
|
||||
llassert(threaded); // not threaded implementation is deprecated
|
||||
mMainQueue = LL::WorkQueue::getInstance("mainloop");
|
||||
|
||||
if (mThreaded)
|
||||
{
|
||||
if(should_pause)
|
||||
|
|
@ -69,6 +75,11 @@ void LLQueuedThread::shutdown()
|
|||
unpause(); // MAIN THREAD
|
||||
if (mThreaded)
|
||||
{
|
||||
if (mRequestQueue.size() == 0)
|
||||
{
|
||||
mRequestQueue.close();
|
||||
}
|
||||
|
||||
S32 timeout = 100;
|
||||
for ( ; timeout>0; timeout--)
|
||||
{
|
||||
|
|
@ -104,6 +115,8 @@ void LLQueuedThread::shutdown()
|
|||
{
|
||||
LL_WARNS() << "~LLQueuedThread() called with active requests: " << active_count << LL_ENDL;
|
||||
}
|
||||
|
||||
mRequestQueue.close();
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
|
@ -112,6 +125,7 @@ void LLQueuedThread::shutdown()
|
|||
// virtual
|
||||
S32 LLQueuedThread::update(F32 max_time_ms)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED;
|
||||
if (!mStarted)
|
||||
{
|
||||
if (!mThreaded)
|
||||
|
|
@ -125,29 +139,34 @@ S32 LLQueuedThread::update(F32 max_time_ms)
|
|||
|
||||
S32 LLQueuedThread::updateQueue(F32 max_time_ms)
|
||||
{
|
||||
F64 max_time = (F64)max_time_ms * .001;
|
||||
LLTimer timer;
|
||||
S32 pending = 1;
|
||||
|
||||
LL_PROFILE_ZONE_SCOPED;
|
||||
// Frame Update
|
||||
if (mThreaded)
|
||||
{
|
||||
pending = getPending();
|
||||
if(pending > 0)
|
||||
// schedule a call to threadedUpdate for every call to updateQueue
|
||||
if (!isQuitting())
|
||||
{
|
||||
mRequestQueue.post([=]()
|
||||
{
|
||||
LL_PROFILE_ZONE_NAMED_CATEGORY_THREAD("qt - update");
|
||||
mIdleThread = FALSE;
|
||||
threadedUpdate();
|
||||
mIdleThread = TRUE;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
if(getPending() > 0)
|
||||
{
|
||||
unpause();
|
||||
}
|
||||
unpause();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
while (pending > 0)
|
||||
{
|
||||
pending = processNextRequest();
|
||||
if (max_time && timer.getElapsedTimeF64() > max_time)
|
||||
break;
|
||||
}
|
||||
mRequestQueue.runFor(std::chrono::microseconds((int) (max_time_ms*1000.f)));
|
||||
threadedUpdate();
|
||||
}
|
||||
return pending;
|
||||
return getPending();
|
||||
}
|
||||
|
||||
void LLQueuedThread::incQueue()
|
||||
|
|
@ -166,11 +185,7 @@ void LLQueuedThread::incQueue()
|
|||
// May be called from any thread
|
||||
S32 LLQueuedThread::getPending()
|
||||
{
|
||||
S32 res;
|
||||
lockData();
|
||||
res = mRequestQueue.size();
|
||||
unlockData();
|
||||
return res;
|
||||
return mRequestQueue.size();
|
||||
}
|
||||
|
||||
// MAIN thread
|
||||
|
|
@ -195,35 +210,28 @@ void LLQueuedThread::waitOnPending()
|
|||
// MAIN thread
|
||||
void LLQueuedThread::printQueueStats()
|
||||
{
|
||||
lockData();
|
||||
if (!mRequestQueue.empty())
|
||||
U32 size = mRequestQueue.size();
|
||||
if (size > 0)
|
||||
{
|
||||
QueuedRequest *req = *mRequestQueue.begin();
|
||||
LL_INFOS() << llformat("Pending Requests:%d Current status:%d", mRequestQueue.size(), req->getStatus()) << LL_ENDL;
|
||||
LL_INFOS() << llformat("Pending Requests:%d ", mRequestQueue.size()) << LL_ENDL;
|
||||
}
|
||||
else
|
||||
{
|
||||
LL_INFOS() << "Queued Thread Idle" << LL_ENDL;
|
||||
}
|
||||
unlockData();
|
||||
}
|
||||
|
||||
// MAIN thread
|
||||
LLQueuedThread::handle_t LLQueuedThread::generateHandle()
|
||||
{
|
||||
lockData();
|
||||
while ((mNextHandle == nullHandle()) || (mRequestHash.find(mNextHandle)))
|
||||
{
|
||||
mNextHandle++;
|
||||
}
|
||||
const LLQueuedThread::handle_t res = mNextHandle++;
|
||||
unlockData();
|
||||
U32 res = ++mNextHandle;
|
||||
return res;
|
||||
}
|
||||
|
||||
// MAIN thread
|
||||
bool LLQueuedThread::addRequest(QueuedRequest* req)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED;
|
||||
if (mStatus == QUITTING)
|
||||
{
|
||||
return false;
|
||||
|
|
@ -231,14 +239,14 @@ bool LLQueuedThread::addRequest(QueuedRequest* req)
|
|||
|
||||
lockData();
|
||||
req->setStatus(STATUS_QUEUED);
|
||||
mRequestQueue.insert(req);
|
||||
mRequestHash.insert(req);
|
||||
mRequestHash.insert(req);
|
||||
#if _DEBUG
|
||||
// LL_INFOS() << llformat("LLQueuedThread::Added req [%08d]",handle) << LL_ENDL;
|
||||
#endif
|
||||
unlockData();
|
||||
|
||||
incQueue();
|
||||
llassert(!mDataLock->isSelfLocked());
|
||||
mRequestQueue.post([this, req]() { processRequest(req); });
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
@ -246,6 +254,7 @@ bool LLQueuedThread::addRequest(QueuedRequest* req)
|
|||
// MAIN thread
|
||||
bool LLQueuedThread::waitForResult(LLQueuedThread::handle_t handle, bool auto_complete)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED;
|
||||
llassert (handle != nullHandle());
|
||||
bool res = false;
|
||||
bool waspaused = isPaused();
|
||||
|
|
@ -312,6 +321,7 @@ LLQueuedThread::status_t LLQueuedThread::getRequestStatus(handle_t handle)
|
|||
|
||||
void LLQueuedThread::abortRequest(handle_t handle, bool autocomplete)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD;
|
||||
lockData();
|
||||
QueuedRequest* req = (QueuedRequest*)mRequestHash.find(handle);
|
||||
if (req)
|
||||
|
|
@ -333,30 +343,9 @@ void LLQueuedThread::setFlags(handle_t handle, U32 flags)
|
|||
unlockData();
|
||||
}
|
||||
|
||||
void LLQueuedThread::setPriority(handle_t handle, U32 priority)
|
||||
{
|
||||
lockData();
|
||||
QueuedRequest* req = (QueuedRequest*)mRequestHash.find(handle);
|
||||
if (req)
|
||||
{
|
||||
if(req->getStatus() == STATUS_INPROGRESS)
|
||||
{
|
||||
// not in list
|
||||
req->setPriority(priority);
|
||||
}
|
||||
else if(req->getStatus() == STATUS_QUEUED)
|
||||
{
|
||||
// remove from list then re-insert
|
||||
llverify(mRequestQueue.erase(req) == 1);
|
||||
req->setPriority(priority);
|
||||
mRequestQueue.insert(req);
|
||||
}
|
||||
}
|
||||
unlockData();
|
||||
}
|
||||
|
||||
bool LLQueuedThread::completeRequest(handle_t handle)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED;
|
||||
bool res = false;
|
||||
lockData();
|
||||
QueuedRequest* req = (QueuedRequest*)mRequestHash.find(handle);
|
||||
|
|
@ -399,89 +388,115 @@ bool LLQueuedThread::check()
|
|||
//============================================================================
|
||||
// Runs on its OWN thread
|
||||
|
||||
S32 LLQueuedThread::processNextRequest()
|
||||
void LLQueuedThread::processRequest(LLQueuedThread::QueuedRequest* req)
|
||||
{
|
||||
QueuedRequest *req;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD;
|
||||
|
||||
mIdleThread = FALSE;
|
||||
//threadedUpdate();
|
||||
|
||||
// Get next request from pool
|
||||
lockData();
|
||||
|
||||
while(1)
|
||||
if ((req->getFlags() & FLAG_ABORT) || (mStatus == QUITTING))
|
||||
{
|
||||
req = NULL;
|
||||
if (mRequestQueue.empty())
|
||||
LL_PROFILE_ZONE_NAMED_CATEGORY_THREAD("qtpr - abort");
|
||||
req->setStatus(STATUS_ABORTED);
|
||||
req->finishRequest(false);
|
||||
if (req->getFlags() & FLAG_AUTO_COMPLETE)
|
||||
{
|
||||
break;
|
||||
}
|
||||
req = *mRequestQueue.begin();
|
||||
mRequestQueue.erase(mRequestQueue.begin());
|
||||
if ((req->getFlags() & FLAG_ABORT) || (mStatus == QUITTING))
|
||||
{
|
||||
req->setStatus(STATUS_ABORTED);
|
||||
req->finishRequest(false);
|
||||
if (req->getFlags() & FLAG_AUTO_COMPLETE)
|
||||
{
|
||||
mRequestHash.erase(req);
|
||||
req->deleteRequest();
|
||||
mRequestHash.erase(req);
|
||||
req->deleteRequest();
|
||||
// check();
|
||||
}
|
||||
continue;
|
||||
}
|
||||
llassert_always(req->getStatus() == STATUS_QUEUED);
|
||||
break;
|
||||
unlockData();
|
||||
}
|
||||
U32 start_priority = 0 ;
|
||||
if (req)
|
||||
{
|
||||
req->setStatus(STATUS_INPROGRESS);
|
||||
start_priority = req->getPriority();
|
||||
}
|
||||
unlockData();
|
||||
else
|
||||
{
|
||||
llassert_always(req->getStatus() == STATUS_QUEUED);
|
||||
|
||||
// This is the only place we will call req->setStatus() after
|
||||
// it has initially been seet to STATUS_QUEUED, so it is
|
||||
// safe to access req.
|
||||
if (req)
|
||||
{
|
||||
// process request
|
||||
bool complete = req->processRequest();
|
||||
if (req)
|
||||
{
|
||||
req->setStatus(STATUS_INPROGRESS);
|
||||
}
|
||||
unlockData();
|
||||
|
||||
if (complete)
|
||||
{
|
||||
lockData();
|
||||
req->setStatus(STATUS_COMPLETE);
|
||||
req->finishRequest(true);
|
||||
if (req->getFlags() & FLAG_AUTO_COMPLETE)
|
||||
{
|
||||
mRequestHash.erase(req);
|
||||
req->deleteRequest();
|
||||
// check();
|
||||
}
|
||||
unlockData();
|
||||
}
|
||||
else
|
||||
{
|
||||
lockData();
|
||||
req->setStatus(STATUS_QUEUED);
|
||||
mRequestQueue.insert(req);
|
||||
unlockData();
|
||||
if (mThreaded && start_priority < PRIORITY_NORMAL)
|
||||
{
|
||||
ms_sleep(1); // sleep the thread a little
|
||||
}
|
||||
}
|
||||
|
||||
LLTrace::get_thread_recorder()->pushToParent();
|
||||
}
|
||||
// This is the only place we will call req->setStatus() after
|
||||
// it has initially been seet to STATUS_QUEUED, so it is
|
||||
// safe to access req.
|
||||
if (req)
|
||||
{
|
||||
// process request
|
||||
bool complete = req->processRequest();
|
||||
|
||||
S32 pending = getPending();
|
||||
return pending;
|
||||
if (complete)
|
||||
{
|
||||
LL_PROFILE_ZONE_NAMED_CATEGORY_THREAD("qtpr - complete");
|
||||
lockData();
|
||||
req->setStatus(STATUS_COMPLETE);
|
||||
req->finishRequest(true);
|
||||
if (req->getFlags() & FLAG_AUTO_COMPLETE)
|
||||
{
|
||||
mRequestHash.erase(req);
|
||||
req->deleteRequest();
|
||||
// check();
|
||||
}
|
||||
unlockData();
|
||||
}
|
||||
else
|
||||
{
|
||||
LL_PROFILE_ZONE_NAMED_CATEGORY_THREAD("qtpr - retry");
|
||||
//put back on queue and try again in 0.1ms
|
||||
lockData();
|
||||
req->setStatus(STATUS_QUEUED);
|
||||
|
||||
unlockData();
|
||||
|
||||
llassert(!mDataLock->isSelfLocked());
|
||||
|
||||
#if 0
|
||||
// try again on next frame
|
||||
// NOTE: tried using "post" with a time in the future, but this
|
||||
// would invariably cause this thread to wait for a long time (10+ ms)
|
||||
// while work is pending
|
||||
bool ret = LL::WorkQueue::postMaybe(
|
||||
mMainQueue,
|
||||
[=]()
|
||||
{
|
||||
LL_PROFILE_ZONE_NAMED("processRequest - retry");
|
||||
mRequestQueue.post([=]()
|
||||
{
|
||||
LL_PROFILE_ZONE_NAMED("processRequest - retry"); // <-- not redundant, track retry on both queues
|
||||
processRequest(req);
|
||||
});
|
||||
});
|
||||
llassert(ret);
|
||||
#else
|
||||
using namespace std::chrono_literals;
|
||||
auto retry_time = LL::WorkQueue::TimePoint::clock::now() + 16ms;
|
||||
mRequestQueue.post([=]
|
||||
{
|
||||
LL_PROFILE_ZONE_NAMED("processRequest - retry");
|
||||
while (LL::WorkQueue::TimePoint::clock::now() < retry_time)
|
||||
{
|
||||
std::this_thread::yield(); //note: don't use LLThread::yield here to avoid
|
||||
}
|
||||
processRequest(req);
|
||||
});
|
||||
#endif
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mIdleThread = TRUE;
|
||||
}
|
||||
|
||||
// virtual
|
||||
bool LLQueuedThread::runCondition()
|
||||
{
|
||||
// mRunCondition must be locked here
|
||||
if (mRequestQueue.empty() && mIdleThread)
|
||||
if (mRequestQueue.size() == 0 && mIdleThread)
|
||||
return false;
|
||||
else
|
||||
return true;
|
||||
|
|
@ -495,18 +510,13 @@ void LLQueuedThread::run()
|
|||
startThread();
|
||||
mStarted = TRUE;
|
||||
|
||||
while (1)
|
||||
|
||||
/*while (1)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED;
|
||||
// this will block on the condition until runCondition() returns true, the thread is unpaused, or the thread leaves the RUNNING state.
|
||||
checkPause();
|
||||
|
||||
if (isQuitting())
|
||||
{
|
||||
LLTrace::get_thread_recorder()->pushToParent();
|
||||
endThread();
|
||||
break;
|
||||
}
|
||||
|
||||
mIdleThread = FALSE;
|
||||
|
||||
threadedUpdate();
|
||||
|
|
@ -515,12 +525,18 @@ void LLQueuedThread::run()
|
|||
|
||||
if (pending_work == 0)
|
||||
{
|
||||
//LL_PROFILE_ZONE_NAMED("LLQueuedThread - sleep");
|
||||
mIdleThread = TRUE;
|
||||
ms_sleep(1);
|
||||
//ms_sleep(1);
|
||||
}
|
||||
//LLThread::yield(); // thread should yield after each request
|
||||
}
|
||||
}*/
|
||||
mRequestQueue.runUntilClose();
|
||||
|
||||
endThread();
|
||||
LL_INFOS() << "LLQueuedThread " << mName << " EXITING." << LL_ENDL;
|
||||
|
||||
|
||||
}
|
||||
|
||||
// virtual
|
||||
|
|
@ -540,10 +556,9 @@ void LLQueuedThread::threadedUpdate()
|
|||
|
||||
//============================================================================
|
||||
|
||||
LLQueuedThread::QueuedRequest::QueuedRequest(LLQueuedThread::handle_t handle, U32 priority, U32 flags) :
|
||||
LLQueuedThread::QueuedRequest::QueuedRequest(LLQueuedThread::handle_t handle, U32 flags) :
|
||||
LLSimpleHashEntry<LLQueuedThread::handle_t>(handle),
|
||||
mStatus(STATUS_UNKNOWN),
|
||||
mPriority(priority),
|
||||
mFlags(flags)
|
||||
{
|
||||
}
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@
|
|||
|
||||
#include "llthread.h"
|
||||
#include "llsimplehash.h"
|
||||
#include "workqueue.h"
|
||||
|
||||
//============================================================================
|
||||
// Note: ~LLQueuedThread is O(N) N=# of queued threads, assumed to be small
|
||||
|
|
@ -45,15 +46,6 @@ class LL_COMMON_API LLQueuedThread : public LLThread
|
|||
{
|
||||
//------------------------------------------------------------------------
|
||||
public:
|
||||
enum priority_t {
|
||||
PRIORITY_IMMEDIATE = 0x7FFFFFFF,
|
||||
PRIORITY_URGENT = 0x40000000,
|
||||
PRIORITY_HIGH = 0x30000000,
|
||||
PRIORITY_NORMAL = 0x20000000,
|
||||
PRIORITY_LOW = 0x10000000,
|
||||
PRIORITY_LOWBITS = 0x0FFFFFFF,
|
||||
PRIORITY_HIGHBITS = 0x70000000
|
||||
};
|
||||
enum status_t {
|
||||
STATUS_EXPIRED = -1,
|
||||
STATUS_UNKNOWN = 0,
|
||||
|
|
@ -82,28 +74,17 @@ public:
|
|||
virtual ~QueuedRequest(); // use deleteRequest()
|
||||
|
||||
public:
|
||||
QueuedRequest(handle_t handle, U32 priority, U32 flags = 0);
|
||||
QueuedRequest(handle_t handle, U32 flags = 0);
|
||||
|
||||
status_t getStatus()
|
||||
{
|
||||
return mStatus;
|
||||
}
|
||||
U32 getPriority() const
|
||||
{
|
||||
return mPriority;
|
||||
}
|
||||
U32 getFlags() const
|
||||
{
|
||||
return mFlags;
|
||||
}
|
||||
bool higherPriority(const QueuedRequest& second) const
|
||||
{
|
||||
if ( mPriority == second.mPriority)
|
||||
return mHashKey < second.mHashKey;
|
||||
else
|
||||
return mPriority > second.mPriority;
|
||||
}
|
||||
|
||||
|
||||
protected:
|
||||
status_t setStatus(status_t newstatus)
|
||||
{
|
||||
|
|
@ -121,28 +102,11 @@ public:
|
|||
virtual void finishRequest(bool completed); // Always called from thread after request has completed or aborted
|
||||
virtual void deleteRequest(); // Only method to delete a request
|
||||
|
||||
void setPriority(U32 pri)
|
||||
{
|
||||
// Only do this on a request that is not in a queued list!
|
||||
mPriority = pri;
|
||||
};
|
||||
|
||||
protected:
|
||||
LLAtomicBase<status_t> mStatus;
|
||||
U32 mPriority;
|
||||
U32 mFlags;
|
||||
};
|
||||
|
||||
protected:
|
||||
struct queued_request_less
|
||||
{
|
||||
bool operator()(const QueuedRequest* lhs, const QueuedRequest* rhs) const
|
||||
{
|
||||
return lhs->higherPriority(*rhs); // higher priority in front of queue (set)
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
|
||||
public:
|
||||
|
|
@ -167,7 +131,7 @@ private:
|
|||
protected:
|
||||
handle_t generateHandle();
|
||||
bool addRequest(QueuedRequest* req);
|
||||
S32 processNextRequest(void);
|
||||
void processRequest(QueuedRequest* req);
|
||||
void incQueue();
|
||||
|
||||
public:
|
||||
|
|
@ -186,7 +150,6 @@ public:
|
|||
status_t getRequestStatus(handle_t handle);
|
||||
void abortRequest(handle_t handle, bool autocomplete);
|
||||
void setFlags(handle_t handle, U32 flags);
|
||||
void setPriority(handle_t handle, U32 priority);
|
||||
bool completeRequest(handle_t handle);
|
||||
// This is public for support classes like LLWorkerThread,
|
||||
// but generally the methods above should be used.
|
||||
|
|
@ -200,8 +163,10 @@ protected:
|
|||
BOOL mStarted; // required when mThreaded is false to call startThread() from update()
|
||||
LLAtomicBool mIdleThread; // request queue is empty (or we are quitting) and the thread is idle
|
||||
|
||||
typedef std::set<QueuedRequest*, queued_request_less> request_queue_t;
|
||||
request_queue_t mRequestQueue;
|
||||
//typedef std::set<QueuedRequest*, queued_request_less> request_queue_t;
|
||||
//request_queue_t mRequestQueue;
|
||||
LL::WorkQueue mRequestQueue;
|
||||
LL::WorkQueue::weak_t mMainQueue;
|
||||
|
||||
enum { REQUEST_HASH_SIZE = 512 }; // must be power of 2
|
||||
typedef LLSimpleHash<handle_t, REQUEST_HASH_SIZE> request_hash_t;
|
||||
|
|
|
|||
|
|
@ -710,20 +710,28 @@ static U32Kilobytes LLMemoryAdjustKBResult(U32Kilobytes inKB)
|
|||
}
|
||||
#endif
|
||||
|
||||
#if LL_DARWIN
|
||||
// static
|
||||
U32Kilobytes LLMemoryInfo::getHardwareMemSize()
|
||||
{
|
||||
// This might work on Linux as well. Someone check...
|
||||
uint64_t phys = 0;
|
||||
int mib[2] = { CTL_HW, HW_MEMSIZE };
|
||||
|
||||
size_t len = sizeof(phys);
|
||||
sysctl(mib, 2, &phys, &len, NULL, 0);
|
||||
|
||||
return U64Bytes(phys);
|
||||
}
|
||||
#endif
|
||||
|
||||
U32Kilobytes LLMemoryInfo::getPhysicalMemoryKB() const
|
||||
{
|
||||
#if LL_WINDOWS
|
||||
return LLMemoryAdjustKBResult(U32Kilobytes(mStatsMap["Total Physical KB"].asInteger()));
|
||||
|
||||
#elif LL_DARWIN
|
||||
// This might work on Linux as well. Someone check...
|
||||
uint64_t phys = 0;
|
||||
int mib[2] = { CTL_HW, HW_MEMSIZE };
|
||||
|
||||
size_t len = sizeof(phys);
|
||||
sysctl(mib, 2, &phys, &len, NULL, 0);
|
||||
|
||||
return U64Bytes(phys);
|
||||
return getHardwareMemSize();
|
||||
|
||||
#elif LL_LINUX
|
||||
U64 phys = 0;
|
||||
|
|
|
|||
|
|
@ -117,7 +117,10 @@ public:
|
|||
LLMemoryInfo(); ///< Default constructor
|
||||
void stream(std::ostream& s) const; ///< output text info to s
|
||||
|
||||
U32Kilobytes getPhysicalMemoryKB() const;
|
||||
U32Kilobytes getPhysicalMemoryKB() const;
|
||||
#if LL_DARWIN
|
||||
static U32Kilobytes getHardwareMemSize(); // Because some Mac linkers won't let us reference extern gSysMemory from a different lib.
|
||||
#endif
|
||||
|
||||
//get the available memory infomation in KiloBytes.
|
||||
static void getAvailableMemoryKB(U32Kilobytes& avail_physical_mem_kb, U32Kilobytes& avail_virtual_mem_kb);
|
||||
|
|
|
|||
|
|
@ -30,6 +30,9 @@
|
|||
|
||||
#include "u64.h"
|
||||
|
||||
#include <chrono>
|
||||
#include <thread>
|
||||
|
||||
#if LL_WINDOWS
|
||||
# include "llwin32headerslean.h"
|
||||
#elif LL_LINUX || LL_DARWIN
|
||||
|
|
@ -64,7 +67,13 @@ LLTimer* LLTimer::sTimer = NULL;
|
|||
#if LL_WINDOWS
|
||||
void ms_sleep(U32 ms)
|
||||
{
|
||||
Sleep(ms);
|
||||
LL_PROFILE_ZONE_SCOPED;
|
||||
using TimePoint = std::chrono::steady_clock::time_point;
|
||||
auto resume_time = TimePoint::clock::now() + std::chrono::milliseconds(ms);
|
||||
while (TimePoint::clock::now() < resume_time)
|
||||
{
|
||||
std::this_thread::yield(); //note: don't use LLThread::yield here to avoid yielding for too long
|
||||
}
|
||||
}
|
||||
|
||||
U32 micro_sleep(U64 us, U32 max_yields)
|
||||
|
|
|
|||
|
|
@ -133,11 +133,11 @@ S32 LLWorkerThread::update(F32 max_time_ms)
|
|||
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
LLWorkerThread::handle_t LLWorkerThread::addWorkRequest(LLWorkerClass* workerclass, S32 param, U32 priority)
|
||||
LLWorkerThread::handle_t LLWorkerThread::addWorkRequest(LLWorkerClass* workerclass, S32 param)
|
||||
{
|
||||
handle_t handle = generateHandle();
|
||||
|
||||
WorkRequest* req = new WorkRequest(handle, priority, workerclass, param);
|
||||
WorkRequest* req = new WorkRequest(handle, workerclass, param);
|
||||
|
||||
bool res = addRequest(req);
|
||||
if (!res)
|
||||
|
|
@ -160,8 +160,8 @@ void LLWorkerThread::deleteWorker(LLWorkerClass* workerclass)
|
|||
//============================================================================
|
||||
// Runs on its OWN thread
|
||||
|
||||
LLWorkerThread::WorkRequest::WorkRequest(handle_t handle, U32 priority, LLWorkerClass* workerclass, S32 param) :
|
||||
LLQueuedThread::QueuedRequest(handle, priority),
|
||||
LLWorkerThread::WorkRequest::WorkRequest(handle_t handle, LLWorkerClass* workerclass, S32 param) :
|
||||
LLQueuedThread::QueuedRequest(handle),
|
||||
mWorkerClass(workerclass),
|
||||
mParam(param)
|
||||
{
|
||||
|
|
@ -180,6 +180,7 @@ void LLWorkerThread::WorkRequest::deleteRequest()
|
|||
// virtual
|
||||
bool LLWorkerThread::WorkRequest::processRequest()
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED;
|
||||
LLWorkerClass* workerclass = getWorkerClass();
|
||||
workerclass->setWorking(true);
|
||||
bool complete = workerclass->doWork(getParam());
|
||||
|
|
@ -190,6 +191,7 @@ bool LLWorkerThread::WorkRequest::processRequest()
|
|||
// virtual
|
||||
void LLWorkerThread::WorkRequest::finishRequest(bool completed)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED;
|
||||
LLWorkerClass* workerclass = getWorkerClass();
|
||||
workerclass->finishWork(getParam(), completed);
|
||||
U32 flags = LLWorkerClass::WCF_WORK_FINISHED | (completed ? 0 : LLWorkerClass::WCF_WORK_ABORTED);
|
||||
|
|
@ -203,7 +205,6 @@ LLWorkerClass::LLWorkerClass(LLWorkerThread* workerthread, const std::string& na
|
|||
: mWorkerThread(workerthread),
|
||||
mWorkerClassName(name),
|
||||
mRequestHandle(LLWorkerThread::nullHandle()),
|
||||
mRequestPriority(LLWorkerThread::PRIORITY_NORMAL),
|
||||
mMutex(),
|
||||
mWorkFlags(0)
|
||||
{
|
||||
|
|
@ -292,7 +293,7 @@ bool LLWorkerClass::yield()
|
|||
//----------------------------------------------------------------------------
|
||||
|
||||
// calls startWork, adds doWork() to queue
|
||||
void LLWorkerClass::addWork(S32 param, U32 priority)
|
||||
void LLWorkerClass::addWork(S32 param)
|
||||
{
|
||||
mMutex.lock();
|
||||
llassert_always(!(mWorkFlags & (WCF_WORKING|WCF_HAVE_WORK)));
|
||||
|
|
@ -306,7 +307,7 @@ void LLWorkerClass::addWork(S32 param, U32 priority)
|
|||
startWork(param);
|
||||
clearFlags(WCF_WORK_FINISHED|WCF_WORK_ABORTED);
|
||||
setFlags(WCF_HAVE_WORK);
|
||||
mRequestHandle = mWorkerThread->addWorkRequest(this, param, priority);
|
||||
mRequestHandle = mWorkerThread->addWorkRequest(this, param);
|
||||
mMutex.unlock();
|
||||
}
|
||||
|
||||
|
|
@ -321,7 +322,6 @@ void LLWorkerClass::abortWork(bool autocomplete)
|
|||
if (mRequestHandle != LLWorkerThread::nullHandle())
|
||||
{
|
||||
mWorkerThread->abortRequest(mRequestHandle, autocomplete);
|
||||
mWorkerThread->setPriority(mRequestHandle, LLQueuedThread::PRIORITY_IMMEDIATE);
|
||||
setFlags(WCF_ABORT_REQUESTED);
|
||||
}
|
||||
mMutex.unlock();
|
||||
|
|
@ -395,16 +395,5 @@ void LLWorkerClass::scheduleDelete()
|
|||
}
|
||||
}
|
||||
|
||||
void LLWorkerClass::setPriority(U32 priority)
|
||||
{
|
||||
mMutex.lock();
|
||||
if (mRequestHandle != LLWorkerThread::nullHandle() && mRequestPriority != priority)
|
||||
{
|
||||
mRequestPriority = priority;
|
||||
mWorkerThread->setPriority(mRequestHandle, priority);
|
||||
}
|
||||
mMutex.unlock();
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
|
||||
|
|
|
|||
|
|
@ -56,7 +56,7 @@ public:
|
|||
virtual ~WorkRequest(); // use deleteRequest()
|
||||
|
||||
public:
|
||||
WorkRequest(handle_t handle, U32 priority, LLWorkerClass* workerclass, S32 param);
|
||||
WorkRequest(handle_t handle, LLWorkerClass* workerclass, S32 param);
|
||||
|
||||
S32 getParam()
|
||||
{
|
||||
|
|
@ -90,7 +90,7 @@ public:
|
|||
|
||||
/*virtual*/ S32 update(F32 max_time_ms);
|
||||
|
||||
handle_t addWorkRequest(LLWorkerClass* workerclass, S32 param, U32 priority = PRIORITY_NORMAL);
|
||||
handle_t addWorkRequest(LLWorkerClass* workerclass, S32 param);
|
||||
|
||||
S32 getNumDeletes() { return (S32)mDeleteList.size(); } // debug
|
||||
|
||||
|
|
@ -151,10 +151,6 @@ public:
|
|||
bool isWorking() { return getFlags(WCF_WORKING); }
|
||||
bool wasAborted() { return getFlags(WCF_ABORT_REQUESTED); }
|
||||
|
||||
// setPriority(): changes the priority of a request
|
||||
void setPriority(U32 priority);
|
||||
U32 getPriority() { return mRequestPriority; }
|
||||
|
||||
const std::string& getName() const { return mWorkerClassName; }
|
||||
|
||||
protected:
|
||||
|
|
@ -169,7 +165,7 @@ protected:
|
|||
void setWorkerThread(LLWorkerThread* workerthread);
|
||||
|
||||
// addWork(): calls startWork, adds doWork() to queue
|
||||
void addWork(S32 param, U32 priority = LLWorkerThread::PRIORITY_NORMAL);
|
||||
void addWork(S32 param);
|
||||
|
||||
// abortWork(): requests that work be aborted
|
||||
void abortWork(bool autocomplete);
|
||||
|
|
@ -193,7 +189,6 @@ protected:
|
|||
LLWorkerThread* mWorkerThread;
|
||||
std::string mWorkerClassName;
|
||||
handle_t mRequestHandle;
|
||||
U32 mRequestPriority; // last priority set
|
||||
|
||||
private:
|
||||
LLMutex mMutex;
|
||||
|
|
|
|||
|
|
@ -17,14 +17,17 @@
|
|||
// std headers
|
||||
// external library headers
|
||||
// other Linden headers
|
||||
#include "commoncontrol.h"
|
||||
#include "llerror.h"
|
||||
#include "llevents.h"
|
||||
#include "llsd.h"
|
||||
#include "stringize.h"
|
||||
|
||||
LL::ThreadPool::ThreadPool(const std::string& name, size_t threads, size_t capacity):
|
||||
super(name),
|
||||
mQueue(name, capacity),
|
||||
mName("ThreadPool:" + name),
|
||||
mThreadCount(threads)
|
||||
mThreadCount(getConfiguredWidth(name, threads))
|
||||
{}
|
||||
|
||||
void LL::ThreadPool::start()
|
||||
|
|
@ -86,3 +89,58 @@ void LL::ThreadPool::run()
|
|||
{
|
||||
mQueue.runUntilClose();
|
||||
}
|
||||
|
||||
//static
|
||||
size_t LL::ThreadPool::getConfiguredWidth(const std::string& name, size_t dft)
|
||||
{
|
||||
LLSD poolSizes;
|
||||
try
|
||||
{
|
||||
poolSizes = LL::CommonControl::get("Global", "ThreadPoolSizes");
|
||||
// "ThreadPoolSizes" is actually a map containing the sizes of
|
||||
// interest -- or should be, if this process has an
|
||||
// LLViewerControlListener instance and its settings include
|
||||
// "ThreadPoolSizes". If we failed to retrieve it, perhaps we're in a
|
||||
// program that doesn't define that, or perhaps there's no such
|
||||
// setting, or perhaps we're asking too early, before the LLEventAPI
|
||||
// itself has been instantiated. In any of those cases, it seems worth
|
||||
// warning.
|
||||
if (! poolSizes.isDefined())
|
||||
{
|
||||
// Note: we don't warn about absence of an override key for a
|
||||
// particular ThreadPool name, that's fine. This warning is about
|
||||
// complete absence of a ThreadPoolSizes setting, which we expect
|
||||
// in a normal viewer session.
|
||||
LL_WARNS("ThreadPool") << "No 'ThreadPoolSizes' setting for ThreadPool '"
|
||||
<< name << "'" << LL_ENDL;
|
||||
}
|
||||
}
|
||||
catch (const LL::CommonControl::Error& exc)
|
||||
{
|
||||
// We don't want ThreadPool to *require* LLViewerControlListener.
|
||||
// Just log it and carry on.
|
||||
LL_WARNS("ThreadPool") << "Can't check 'ThreadPoolSizes': " << exc.what() << LL_ENDL;
|
||||
}
|
||||
|
||||
LL_DEBUGS("ThreadPool") << "ThreadPoolSizes = " << poolSizes << LL_ENDL;
|
||||
// LLSD treats an undefined value as an empty map when asked to retrieve a
|
||||
// key, so we don't need this to be conditional.
|
||||
LLSD sizeSpec{ poolSizes[name] };
|
||||
// We retrieve sizeSpec as LLSD, rather than immediately as LLSD::Integer,
|
||||
// so we can distinguish the case when it's undefined.
|
||||
return sizeSpec.isInteger() ? sizeSpec.asInteger() : dft;
|
||||
}
|
||||
|
||||
//static
|
||||
size_t LL::ThreadPool::getWidth(const std::string& name, size_t dft)
|
||||
{
|
||||
auto instance{ getInstance(name) };
|
||||
if (instance)
|
||||
{
|
||||
return instance->getWidth();
|
||||
}
|
||||
else
|
||||
{
|
||||
return getConfiguredWidth(name, dft);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,14 +22,25 @@
|
|||
namespace LL
|
||||
{
|
||||
|
||||
class ThreadPool
|
||||
class ThreadPool: public LLInstanceTracker<ThreadPool, std::string>
|
||||
{
|
||||
private:
|
||||
using super = LLInstanceTracker<ThreadPool, std::string>;
|
||||
public:
|
||||
/**
|
||||
* Pass ThreadPool a string name. This can be used to look up the
|
||||
* relevant WorkQueue.
|
||||
*
|
||||
* The number of threads you pass sets the compile-time default. But
|
||||
* if the user has overridden the LLSD map in the "ThreadPoolSizes"
|
||||
* setting with a key matching this ThreadPool name, that setting
|
||||
* overrides this parameter.
|
||||
*
|
||||
* Pass an explicit capacity to limit the size of the queue.
|
||||
* Constraining the queue can cause a submitter to block. Do not
|
||||
* constrain any ThreadPool accepting work from the main thread.
|
||||
*/
|
||||
ThreadPool(const std::string& name, size_t threads=1, size_t capacity=1024);
|
||||
ThreadPool(const std::string& name, size_t threads=1, size_t capacity=1024*1024);
|
||||
virtual ~ThreadPool();
|
||||
|
||||
/**
|
||||
|
|
@ -57,6 +68,25 @@ namespace LL
|
|||
*/
|
||||
virtual void run();
|
||||
|
||||
/**
|
||||
* getConfiguredWidth() returns the setting, if any, for the specified
|
||||
* ThreadPool name. Returns dft if the "ThreadPoolSizes" map does not
|
||||
* contain the specified name.
|
||||
*/
|
||||
static
|
||||
size_t getConfiguredWidth(const std::string& name, size_t dft=0);
|
||||
|
||||
/**
|
||||
* This getWidth() returns the width of the instantiated ThreadPool
|
||||
* with the specified name, if any. If no instance exists, returns its
|
||||
* getConfiguredWidth() if any. If there's no instance and no relevant
|
||||
* override, return dft. Presumably dft should match the threads
|
||||
* parameter passed to the ThreadPool constructor call that will
|
||||
* eventually instantiate the ThreadPool with that name.
|
||||
*/
|
||||
static
|
||||
size_t getWidth(const std::string& name, size_t dft);
|
||||
|
||||
private:
|
||||
void run(const std::string& name);
|
||||
|
||||
|
|
|
|||
|
|
@ -161,10 +161,16 @@ namespace LL
|
|||
void postEvery(const std::chrono::duration<Rep, Period>& interval,
|
||||
CALLABLE&& callable);
|
||||
|
||||
template <typename CALLABLE>
|
||||
bool tryPost(const TimePoint& time, CALLABLE&& callable)
|
||||
{
|
||||
return mQueue.tryPush(TimedWork(time, std::move(callable)));
|
||||
}
|
||||
|
||||
template <typename CALLABLE>
|
||||
bool tryPost(CALLABLE&& callable)
|
||||
{
|
||||
return mQueue.tryPush(TimedWork(TimePoint::clock::now(), std::move(callable)));
|
||||
return mQueue.tryPush(TimePoint::clock::now(), std::move(callable));
|
||||
}
|
||||
|
||||
/*------------------------- handshake API --------------------------*/
|
||||
|
|
|
|||
|
|
@ -113,6 +113,7 @@ void HttpLibcurl::shutdown()
|
|||
|
||||
void HttpLibcurl::start(int policy_count)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK;
|
||||
llassert_always(policy_count <= HTTP_POLICY_CLASS_LIMIT);
|
||||
llassert_always(! mMultiHandles); // One-time call only
|
||||
|
||||
|
|
@ -143,6 +144,7 @@ void HttpLibcurl::start(int policy_count)
|
|||
// sleep otherwise ask for a normal polling interval.
|
||||
HttpService::ELoopSpeed HttpLibcurl::processTransport()
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK;
|
||||
HttpService::ELoopSpeed ret(HttpService::REQUEST_SLEEP);
|
||||
|
||||
// Give libcurl some cycles to do I/O & callbacks
|
||||
|
|
@ -168,6 +170,7 @@ HttpService::ELoopSpeed HttpLibcurl::processTransport()
|
|||
CURLMcode status(CURLM_CALL_MULTI_PERFORM);
|
||||
do
|
||||
{
|
||||
LL_PROFILE_ZONE_NAMED_CATEGORY_NETWORK("httppt - curl_multi_perform");
|
||||
running = 0;
|
||||
status = curl_multi_perform(mMultiHandles[policy_class], &running);
|
||||
}
|
||||
|
|
@ -176,31 +179,34 @@ HttpService::ELoopSpeed HttpLibcurl::processTransport()
|
|||
// Run completion on anything done
|
||||
CURLMsg * msg(NULL);
|
||||
int msgs_in_queue(0);
|
||||
while ((msg = curl_multi_info_read(mMultiHandles[policy_class], &msgs_in_queue)))
|
||||
{
|
||||
if (CURLMSG_DONE == msg->msg)
|
||||
{
|
||||
CURL * handle(msg->easy_handle);
|
||||
CURLcode result(msg->data.result);
|
||||
{
|
||||
LL_PROFILE_ZONE_NAMED_CATEGORY_NETWORK("httppt - curl_multi_info_read");
|
||||
while ((msg = curl_multi_info_read(mMultiHandles[policy_class], &msgs_in_queue)))
|
||||
{
|
||||
if (CURLMSG_DONE == msg->msg)
|
||||
{
|
||||
CURL* handle(msg->easy_handle);
|
||||
CURLcode result(msg->data.result);
|
||||
|
||||
completeRequest(mMultiHandles[policy_class], handle, result);
|
||||
handle = NULL; // No longer valid on return
|
||||
ret = HttpService::NORMAL; // If anything completes, we may have a free slot.
|
||||
// Turning around quickly reduces connection gap by 7-10mS.
|
||||
}
|
||||
else if (CURLMSG_NONE == msg->msg)
|
||||
{
|
||||
// Ignore this... it shouldn't mean anything.
|
||||
;
|
||||
}
|
||||
else
|
||||
{
|
||||
LL_WARNS_ONCE(LOG_CORE) << "Unexpected message from libcurl. Msg code: "
|
||||
<< msg->msg
|
||||
<< LL_ENDL;
|
||||
}
|
||||
msgs_in_queue = 0;
|
||||
}
|
||||
completeRequest(mMultiHandles[policy_class], handle, result);
|
||||
handle = NULL; // No longer valid on return
|
||||
ret = HttpService::NORMAL; // If anything completes, we may have a free slot.
|
||||
// Turning around quickly reduces connection gap by 7-10mS.
|
||||
}
|
||||
else if (CURLMSG_NONE == msg->msg)
|
||||
{
|
||||
// Ignore this... it shouldn't mean anything.
|
||||
;
|
||||
}
|
||||
else
|
||||
{
|
||||
LL_WARNS_ONCE(LOG_CORE) << "Unexpected message from libcurl. Msg code: "
|
||||
<< msg->msg
|
||||
<< LL_ENDL;
|
||||
}
|
||||
msgs_in_queue = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (! mActiveOps.empty())
|
||||
|
|
@ -214,6 +220,7 @@ HttpService::ELoopSpeed HttpLibcurl::processTransport()
|
|||
// Caller has provided us with a ref count on op.
|
||||
void HttpLibcurl::addOp(const HttpOpRequest::ptr_t &op)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK;
|
||||
llassert_always(op->mReqPolicy < mPolicyCount);
|
||||
llassert_always(mMultiHandles[op->mReqPolicy] != NULL);
|
||||
|
||||
|
|
@ -257,6 +264,7 @@ void HttpLibcurl::addOp(const HttpOpRequest::ptr_t &op)
|
|||
// method to kill the request.
|
||||
bool HttpLibcurl::cancel(HttpHandle handle)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK;
|
||||
HttpOpRequest::ptr_t op = HttpOpRequest::fromHandle<HttpOpRequest>(handle);
|
||||
active_set_t::iterator it(mActiveOps.find(op));
|
||||
if (mActiveOps.end() == it)
|
||||
|
|
@ -282,6 +290,7 @@ bool HttpLibcurl::cancel(HttpHandle handle)
|
|||
// op to the reply queue with refcount intact.
|
||||
void HttpLibcurl::cancelRequest(const HttpOpRequest::ptr_t &op)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK;
|
||||
// Deactivate request
|
||||
op->mCurlActive = false;
|
||||
|
||||
|
|
@ -308,6 +317,7 @@ void HttpLibcurl::cancelRequest(const HttpOpRequest::ptr_t &op)
|
|||
// Keep them synchronized as necessary.
|
||||
bool HttpLibcurl::completeRequest(CURLM * multi_handle, CURL * handle, CURLcode status)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK;
|
||||
HttpHandle ophandle(NULL);
|
||||
|
||||
CURLcode ccode(CURLE_OK);
|
||||
|
|
@ -445,6 +455,7 @@ int HttpLibcurl::getActiveCountInClass(int policy_class) const
|
|||
|
||||
void HttpLibcurl::policyUpdated(int policy_class)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK;
|
||||
if (policy_class < 0 || policy_class >= mPolicyCount || ! mMultiHandles)
|
||||
{
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -62,7 +62,6 @@ HttpOperation::HttpOperation():
|
|||
mReplyQueue(),
|
||||
mUserHandler(),
|
||||
mReqPolicy(HttpRequest::DEFAULT_POLICY_ID),
|
||||
mReqPriority(0U),
|
||||
mTracing(HTTP_TRACE_OFF),
|
||||
mMyHandle(LLCORE_HTTP_HANDLE_INVALID)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -181,7 +181,6 @@ protected:
|
|||
public:
|
||||
// Request Data
|
||||
HttpRequest::policy_t mReqPolicy;
|
||||
HttpRequest::priority_t mReqPriority;
|
||||
|
||||
// Reply Data
|
||||
HttpStatus mStatus;
|
||||
|
|
|
|||
|
|
@ -200,6 +200,7 @@ HttpOpRequest::~HttpOpRequest()
|
|||
|
||||
void HttpOpRequest::stageFromRequest(HttpService * service)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK;
|
||||
HttpOpRequest::ptr_t self(boost::dynamic_pointer_cast<HttpOpRequest>(shared_from_this()));
|
||||
service->getPolicy().addOp(self); // transfers refcount
|
||||
}
|
||||
|
|
@ -207,6 +208,7 @@ void HttpOpRequest::stageFromRequest(HttpService * service)
|
|||
|
||||
void HttpOpRequest::stageFromReady(HttpService * service)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK;
|
||||
HttpOpRequest::ptr_t self(boost::dynamic_pointer_cast<HttpOpRequest>(shared_from_this()));
|
||||
service->getTransport().addOp(self); // transfers refcount
|
||||
}
|
||||
|
|
@ -214,6 +216,7 @@ void HttpOpRequest::stageFromReady(HttpService * service)
|
|||
|
||||
void HttpOpRequest::stageFromActive(HttpService * service)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK;
|
||||
if (mReplyLength)
|
||||
{
|
||||
// If non-zero, we received and processed a Content-Range
|
||||
|
|
@ -250,6 +253,7 @@ void HttpOpRequest::stageFromActive(HttpService * service)
|
|||
|
||||
void HttpOpRequest::visitNotifier(HttpRequest * request)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK;
|
||||
if (mUserHandler)
|
||||
{
|
||||
HttpResponse * response = new HttpResponse();
|
||||
|
|
@ -292,6 +296,7 @@ void HttpOpRequest::visitNotifier(HttpRequest * request)
|
|||
|
||||
HttpStatus HttpOpRequest::cancel()
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK;
|
||||
mStatus = HttpStatus(HttpStatus::LLCORE, HE_OP_CANCELED);
|
||||
|
||||
addAsReply();
|
||||
|
|
@ -301,12 +306,12 @@ HttpStatus HttpOpRequest::cancel()
|
|||
|
||||
|
||||
HttpStatus HttpOpRequest::setupGet(HttpRequest::policy_t policy_id,
|
||||
HttpRequest::priority_t priority,
|
||||
const std::string & url,
|
||||
const HttpOptions::ptr_t & options,
|
||||
const HttpHeaders::ptr_t & headers)
|
||||
{
|
||||
setupCommon(policy_id, priority, url, NULL, options, headers);
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK;
|
||||
setupCommon(policy_id, url, NULL, options, headers);
|
||||
mReqMethod = HOR_GET;
|
||||
|
||||
return HttpStatus();
|
||||
|
|
@ -314,14 +319,14 @@ HttpStatus HttpOpRequest::setupGet(HttpRequest::policy_t policy_id,
|
|||
|
||||
|
||||
HttpStatus HttpOpRequest::setupGetByteRange(HttpRequest::policy_t policy_id,
|
||||
HttpRequest::priority_t priority,
|
||||
const std::string & url,
|
||||
size_t offset,
|
||||
size_t len,
|
||||
const HttpOptions::ptr_t & options,
|
||||
const HttpHeaders::ptr_t & headers)
|
||||
{
|
||||
setupCommon(policy_id, priority, url, NULL, options, headers);
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK;
|
||||
setupCommon(policy_id, url, NULL, options, headers);
|
||||
mReqMethod = HOR_GET;
|
||||
mReqOffset = offset;
|
||||
mReqLength = len;
|
||||
|
|
@ -335,13 +340,13 @@ HttpStatus HttpOpRequest::setupGetByteRange(HttpRequest::policy_t policy_id,
|
|||
|
||||
|
||||
HttpStatus HttpOpRequest::setupPost(HttpRequest::policy_t policy_id,
|
||||
HttpRequest::priority_t priority,
|
||||
const std::string & url,
|
||||
BufferArray * body,
|
||||
const HttpOptions::ptr_t & options,
|
||||
const HttpHeaders::ptr_t & headers)
|
||||
{
|
||||
setupCommon(policy_id, priority, url, body, options, headers);
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK;
|
||||
setupCommon(policy_id, url, body, options, headers);
|
||||
mReqMethod = HOR_POST;
|
||||
|
||||
return HttpStatus();
|
||||
|
|
@ -349,13 +354,13 @@ HttpStatus HttpOpRequest::setupPost(HttpRequest::policy_t policy_id,
|
|||
|
||||
|
||||
HttpStatus HttpOpRequest::setupPut(HttpRequest::policy_t policy_id,
|
||||
HttpRequest::priority_t priority,
|
||||
const std::string & url,
|
||||
BufferArray * body,
|
||||
const HttpOptions::ptr_t & options,
|
||||
const HttpHeaders::ptr_t & headers)
|
||||
{
|
||||
setupCommon(policy_id, priority, url, body, options, headers);
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK;
|
||||
setupCommon(policy_id, url, body, options, headers);
|
||||
mReqMethod = HOR_PUT;
|
||||
|
||||
return HttpStatus();
|
||||
|
|
@ -363,12 +368,12 @@ HttpStatus HttpOpRequest::setupPut(HttpRequest::policy_t policy_id,
|
|||
|
||||
|
||||
HttpStatus HttpOpRequest::setupDelete(HttpRequest::policy_t policy_id,
|
||||
HttpRequest::priority_t priority,
|
||||
const std::string & url,
|
||||
const HttpOptions::ptr_t & options,
|
||||
const HttpHeaders::ptr_t & headers)
|
||||
{
|
||||
setupCommon(policy_id, priority, url, NULL, options, headers);
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK;
|
||||
setupCommon(policy_id, url, NULL, options, headers);
|
||||
mReqMethod = HOR_DELETE;
|
||||
|
||||
return HttpStatus();
|
||||
|
|
@ -376,13 +381,13 @@ HttpStatus HttpOpRequest::setupDelete(HttpRequest::policy_t policy_id,
|
|||
|
||||
|
||||
HttpStatus HttpOpRequest::setupPatch(HttpRequest::policy_t policy_id,
|
||||
HttpRequest::priority_t priority,
|
||||
const std::string & url,
|
||||
BufferArray * body,
|
||||
const HttpOptions::ptr_t & options,
|
||||
const HttpHeaders::ptr_t & headers)
|
||||
{
|
||||
setupCommon(policy_id, priority, url, body, options, headers);
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK;
|
||||
setupCommon(policy_id, url, body, options, headers);
|
||||
mReqMethod = HOR_PATCH;
|
||||
|
||||
return HttpStatus();
|
||||
|
|
@ -390,12 +395,12 @@ HttpStatus HttpOpRequest::setupPatch(HttpRequest::policy_t policy_id,
|
|||
|
||||
|
||||
HttpStatus HttpOpRequest::setupCopy(HttpRequest::policy_t policy_id,
|
||||
HttpRequest::priority_t priority,
|
||||
const std::string & url,
|
||||
const HttpOptions::ptr_t & options,
|
||||
const HttpHeaders::ptr_t &headers)
|
||||
{
|
||||
setupCommon(policy_id, priority, url, NULL, options, headers);
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK;
|
||||
setupCommon(policy_id, url, NULL, options, headers);
|
||||
mReqMethod = HOR_COPY;
|
||||
|
||||
return HttpStatus();
|
||||
|
|
@ -403,12 +408,12 @@ HttpStatus HttpOpRequest::setupCopy(HttpRequest::policy_t policy_id,
|
|||
|
||||
|
||||
HttpStatus HttpOpRequest::setupMove(HttpRequest::policy_t policy_id,
|
||||
HttpRequest::priority_t priority,
|
||||
const std::string & url,
|
||||
const HttpOptions::ptr_t & options,
|
||||
const HttpHeaders::ptr_t &headers)
|
||||
{
|
||||
setupCommon(policy_id, priority, url, NULL, options, headers);
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK;
|
||||
setupCommon(policy_id, url, NULL, options, headers);
|
||||
mReqMethod = HOR_MOVE;
|
||||
|
||||
return HttpStatus();
|
||||
|
|
@ -416,15 +421,14 @@ HttpStatus HttpOpRequest::setupMove(HttpRequest::policy_t policy_id,
|
|||
|
||||
|
||||
void HttpOpRequest::setupCommon(HttpRequest::policy_t policy_id,
|
||||
HttpRequest::priority_t priority,
|
||||
const std::string & url,
|
||||
BufferArray * body,
|
||||
const HttpOptions::ptr_t & options,
|
||||
const HttpHeaders::ptr_t & headers)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK;
|
||||
mProcFlags = 0U;
|
||||
mReqPolicy = policy_id;
|
||||
mReqPriority = priority;
|
||||
mReqURL = url;
|
||||
if (body)
|
||||
{
|
||||
|
|
@ -465,6 +469,7 @@ void HttpOpRequest::setupCommon(HttpRequest::policy_t policy_id,
|
|||
// *TODO: Move this to _httplibcurl where it belongs.
|
||||
HttpStatus HttpOpRequest::prepareRequest(HttpService * service)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK;
|
||||
// Scrub transport and result data for retried op case
|
||||
mCurlActive = false;
|
||||
mCurlHandle = NULL;
|
||||
|
|
@ -773,6 +778,7 @@ HttpStatus HttpOpRequest::prepareRequest(HttpService * service)
|
|||
|
||||
size_t HttpOpRequest::writeCallback(void * data, size_t size, size_t nmemb, void * userdata)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK;
|
||||
HttpOpRequest::ptr_t op(HttpOpRequest::fromHandle<HttpOpRequest>(userdata));
|
||||
|
||||
if (! op->mReplyBody)
|
||||
|
|
@ -788,6 +794,7 @@ size_t HttpOpRequest::writeCallback(void * data, size_t size, size_t nmemb, void
|
|||
|
||||
size_t HttpOpRequest::readCallback(void * data, size_t size, size_t nmemb, void * userdata)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK;
|
||||
HttpOpRequest::ptr_t op(HttpOpRequest::fromHandle<HttpOpRequest>(userdata));
|
||||
|
||||
if (! op->mReqBody)
|
||||
|
|
@ -819,6 +826,7 @@ size_t HttpOpRequest::readCallback(void * data, size_t size, size_t nmemb, void
|
|||
|
||||
int HttpOpRequest::seekCallback(void *userdata, curl_off_t offset, int origin)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK;
|
||||
HttpOpRequest::ptr_t op(HttpOpRequest::fromHandle<HttpOpRequest>(userdata));
|
||||
|
||||
if (!op->mReqBody)
|
||||
|
|
@ -850,6 +858,7 @@ int HttpOpRequest::seekCallback(void *userdata, curl_off_t offset, int origin)
|
|||
|
||||
size_t HttpOpRequest::headerCallback(void * data, size_t size, size_t nmemb, void * userdata)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK;
|
||||
static const char status_line[] = "HTTP/";
|
||||
static const size_t status_line_len = sizeof(status_line) - 1;
|
||||
static const char con_ran_line[] = "content-range";
|
||||
|
|
@ -999,6 +1008,7 @@ size_t HttpOpRequest::headerCallback(void * data, size_t size, size_t nmemb, voi
|
|||
|
||||
CURLcode HttpOpRequest::curlSslCtxCallback(CURL *curl, void *sslctx, void *userdata)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK;
|
||||
HttpOpRequest::ptr_t op(HttpOpRequest::fromHandle<HttpOpRequest>(userdata));
|
||||
|
||||
if (op->mCallbackSSLVerify)
|
||||
|
|
@ -1025,6 +1035,7 @@ CURLcode HttpOpRequest::curlSslCtxCallback(CURL *curl, void *sslctx, void *userd
|
|||
|
||||
int HttpOpRequest::sslCertVerifyCallback(X509_STORE_CTX *ctx, void *param)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK;
|
||||
HttpOpRequest::ptr_t op(HttpOpRequest::fromHandle<HttpOpRequest>(param));
|
||||
|
||||
if (op->mCallbackSSLVerify)
|
||||
|
|
@ -1037,6 +1048,7 @@ int HttpOpRequest::sslCertVerifyCallback(X509_STORE_CTX *ctx, void *param)
|
|||
|
||||
int HttpOpRequest::debugCallback(CURL * handle, curl_infotype info, char * buffer, size_t len, void * userdata)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK;
|
||||
HttpOpRequest::ptr_t op(HttpOpRequest::fromHandle<HttpOpRequest>(userdata));
|
||||
|
||||
std::string safe_line;
|
||||
|
|
|
|||
|
|
@ -105,13 +105,11 @@ public:
|
|||
/// Threading: called by application thread
|
||||
///
|
||||
HttpStatus setupGet(HttpRequest::policy_t policy_id,
|
||||
HttpRequest::priority_t priority,
|
||||
const std::string & url,
|
||||
const HttpOptions::ptr_t & options,
|
||||
const HttpHeaders::ptr_t & headers);
|
||||
|
||||
HttpStatus setupGetByteRange(HttpRequest::policy_t policy_id,
|
||||
HttpRequest::priority_t priority,
|
||||
const std::string & url,
|
||||
size_t offset,
|
||||
size_t len,
|
||||
|
|
@ -119,40 +117,34 @@ public:
|
|||
const HttpHeaders::ptr_t & headers);
|
||||
|
||||
HttpStatus setupPost(HttpRequest::policy_t policy_id,
|
||||
HttpRequest::priority_t priority,
|
||||
const std::string & url,
|
||||
BufferArray * body,
|
||||
const HttpOptions::ptr_t & options,
|
||||
const HttpHeaders::ptr_t & headers);
|
||||
|
||||
HttpStatus setupPut(HttpRequest::policy_t policy_id,
|
||||
HttpRequest::priority_t priority,
|
||||
const std::string & url,
|
||||
BufferArray * body,
|
||||
const HttpOptions::ptr_t & options,
|
||||
const HttpHeaders::ptr_t & headers);
|
||||
|
||||
HttpStatus setupDelete(HttpRequest::policy_t policy_id,
|
||||
HttpRequest::priority_t priority,
|
||||
const std::string & url,
|
||||
const HttpOptions::ptr_t & options,
|
||||
const HttpHeaders::ptr_t & headers);
|
||||
|
||||
HttpStatus setupPatch(HttpRequest::policy_t policy_id,
|
||||
HttpRequest::priority_t priority,
|
||||
const std::string & url,
|
||||
BufferArray * body,
|
||||
const HttpOptions::ptr_t & options,
|
||||
const HttpHeaders::ptr_t & headers);
|
||||
|
||||
HttpStatus setupCopy(HttpRequest::policy_t policy_id,
|
||||
HttpRequest::priority_t priority,
|
||||
const std::string & url,
|
||||
const HttpOptions::ptr_t & options,
|
||||
const HttpHeaders::ptr_t & headers);
|
||||
|
||||
HttpStatus setupMove(HttpRequest::policy_t policy_id,
|
||||
HttpRequest::priority_t priority,
|
||||
const std::string & url,
|
||||
const HttpOptions::ptr_t & options,
|
||||
const HttpHeaders::ptr_t & headers);
|
||||
|
|
@ -172,7 +164,6 @@ protected:
|
|||
// Threading: called by application thread
|
||||
//
|
||||
void setupCommon(HttpRequest::policy_t policy_id,
|
||||
HttpRequest::priority_t priority,
|
||||
const std::string & url,
|
||||
BufferArray * body,
|
||||
const HttpOptions::ptr_t & options,
|
||||
|
|
@ -239,19 +230,6 @@ public:
|
|||
|
||||
|
||||
|
||||
/// HttpOpRequestCompare isn't an operation but a uniform comparison
|
||||
/// functor for STL containers that order by priority. Mainly
|
||||
/// used for the ready queue container but defined here.
|
||||
class HttpOpRequestCompare
|
||||
{
|
||||
public:
|
||||
bool operator()(const HttpOpRequest * lhs, const HttpOpRequest * rhs)
|
||||
{
|
||||
return lhs->mReqPriority > rhs->mReqPriority;
|
||||
}
|
||||
}; // end class HttpOpRequestCompare
|
||||
|
||||
|
||||
// ---------------------------------------
|
||||
// Free functions
|
||||
// ---------------------------------------
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@
|
|||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#if 0 // DEPRECATED
|
||||
#include "_httpopsetpriority.h"
|
||||
|
||||
#include "httpresponse.h"
|
||||
|
|
@ -61,3 +62,5 @@ void HttpOpSetPriority::stageFromRequest(HttpService * service)
|
|||
|
||||
|
||||
} // end namespace LLCore
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@
|
|||
#ifndef _LLCORE_HTTP_SETPRIORITY_H_
|
||||
#define _LLCORE_HTTP_SETPRIORITY_H_
|
||||
|
||||
|
||||
#if 0 // DEPRECATED
|
||||
#include "httpcommon.h"
|
||||
#include "httprequest.h"
|
||||
#include "_httpoperation.h"
|
||||
|
|
@ -49,7 +49,7 @@ namespace LLCore
|
|||
class HttpOpSetPriority : public HttpOperation
|
||||
{
|
||||
public:
|
||||
HttpOpSetPriority(HttpHandle handle, HttpRequest::priority_t priority);
|
||||
HttpOpSetPriority(HttpHandle handle);
|
||||
|
||||
virtual ~HttpOpSetPriority();
|
||||
|
||||
|
|
@ -63,10 +63,10 @@ public:
|
|||
protected:
|
||||
// Request Data
|
||||
HttpHandle mHandle;
|
||||
HttpRequest::priority_t mPriority;
|
||||
}; // end class HttpOpSetPriority
|
||||
|
||||
} // end namespace LLCore
|
||||
#endif
|
||||
|
||||
#endif // _LLCORE_HTTP_SETPRIORITY_H_
|
||||
|
||||
|
|
|
|||
|
|
@ -330,37 +330,6 @@ HttpService::ELoopSpeed HttpPolicy::processReadyQueue()
|
|||
return result;
|
||||
}
|
||||
|
||||
|
||||
bool HttpPolicy::changePriority(HttpHandle handle, HttpRequest::priority_t priority)
|
||||
{
|
||||
for (int policy_class(0); policy_class < mClasses.size(); ++policy_class)
|
||||
{
|
||||
ClassState & state(*mClasses[policy_class]);
|
||||
// We don't scan retry queue because a priority change there
|
||||
// is meaningless. The request will be issued based on retry
|
||||
// intervals not priority value, which is now moot.
|
||||
|
||||
// Scan ready queue for requests that match policy
|
||||
HttpReadyQueue::container_type & c(state.mReadyQueue.get_container());
|
||||
for (HttpReadyQueue::container_type::iterator iter(c.begin()); c.end() != iter;)
|
||||
{
|
||||
HttpReadyQueue::container_type::iterator cur(iter++);
|
||||
|
||||
if ((*cur)->getHandle() == handle)
|
||||
{
|
||||
HttpOpRequest::ptr_t op(*cur);
|
||||
c.erase(cur); // All iterators are now invalidated
|
||||
op->mReqPriority = priority;
|
||||
state.mReadyQueue.push(op); // Re-insert using adapter class
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool HttpPolicy::cancel(HttpHandle handle)
|
||||
{
|
||||
for (int policy_class(0); policy_class < mClasses.size(); ++policy_class)
|
||||
|
|
|
|||
|
|
@ -110,12 +110,6 @@ public:
|
|||
/// Threading: called by worker thread
|
||||
void retryOp(const opReqPtr_t &);
|
||||
|
||||
/// Attempt to change the priority of an earlier request.
|
||||
/// Request that Shadows HttpService's method
|
||||
///
|
||||
/// Threading: called by worker thread
|
||||
bool changePriority(HttpHandle handle, HttpRequest::priority_t priority);
|
||||
|
||||
/// Attempt to cancel a previous request.
|
||||
/// Shadows HttpService's method as well
|
||||
///
|
||||
|
|
|
|||
|
|
@ -80,6 +80,7 @@ HttpService::HttpService()
|
|||
|
||||
HttpService::~HttpService()
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK;
|
||||
mExitRequested = 1U;
|
||||
if (RUNNING == sState)
|
||||
{
|
||||
|
|
@ -131,6 +132,7 @@ HttpService::~HttpService()
|
|||
|
||||
void HttpService::init(HttpRequestQueue * queue)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK;
|
||||
llassert_always(! sInstance);
|
||||
llassert_always(NOT_INITIALIZED == sState);
|
||||
sInstance = new HttpService();
|
||||
|
|
@ -145,6 +147,7 @@ void HttpService::init(HttpRequestQueue * queue)
|
|||
|
||||
void HttpService::term()
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK;
|
||||
if (sInstance)
|
||||
{
|
||||
if (RUNNING == sState && sInstance->mThread)
|
||||
|
|
@ -196,6 +199,7 @@ bool HttpService::isStopped()
|
|||
/// Threading: callable by consumer thread *once*.
|
||||
void HttpService::startThread()
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK;
|
||||
llassert_always(! mThread || STOPPED == sState);
|
||||
llassert_always(INITIALIZED == sState || STOPPED == sState);
|
||||
|
||||
|
|
@ -220,22 +224,6 @@ void HttpService::stopRequested()
|
|||
}
|
||||
|
||||
|
||||
/// Threading: callable by worker thread.
|
||||
bool HttpService::changePriority(HttpHandle handle, HttpRequest::priority_t priority)
|
||||
{
|
||||
bool found(false);
|
||||
|
||||
// Skip the request queue as we currently don't leave earlier
|
||||
// requests sitting there. Start with the ready queue...
|
||||
found = mPolicy->changePriority(handle, priority);
|
||||
|
||||
// If not there, we could try the transport/active queue but priority
|
||||
// doesn't really have much effect there so we don't waste cycles.
|
||||
|
||||
return found;
|
||||
}
|
||||
|
||||
|
||||
/// Try to find the given request handle on any of the request
|
||||
/// queues and cancel the operation.
|
||||
///
|
||||
|
|
@ -244,6 +232,7 @@ bool HttpService::changePriority(HttpHandle handle, HttpRequest::priority_t prio
|
|||
/// Threading: callable by worker thread.
|
||||
bool HttpService::cancel(HttpHandle handle)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK;
|
||||
bool canceled(false);
|
||||
|
||||
// Request can't be on request queue so skip that.
|
||||
|
|
@ -264,6 +253,7 @@ bool HttpService::cancel(HttpHandle handle)
|
|||
/// Threading: callable by worker thread.
|
||||
void HttpService::shutdown()
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK;
|
||||
// Disallow future enqueue of requests
|
||||
mRequestQueue->stopQueue();
|
||||
|
||||
|
|
@ -293,6 +283,8 @@ void HttpService::shutdown()
|
|||
// requested to stop.
|
||||
void HttpService::threadRun(LLCoreInt::HttpThread * thread)
|
||||
{
|
||||
LL_PROFILER_SET_THREAD_NAME("HttpService");
|
||||
|
||||
boost::this_thread::disable_interruption di;
|
||||
|
||||
LLThread::registerThreadID();
|
||||
|
|
@ -300,6 +292,7 @@ void HttpService::threadRun(LLCoreInt::HttpThread * thread)
|
|||
ELoopSpeed loop(REQUEST_SLEEP);
|
||||
while (! mExitRequested)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK;
|
||||
try
|
||||
{
|
||||
loop = processRequestQueue(loop);
|
||||
|
|
@ -344,6 +337,7 @@ void HttpService::threadRun(LLCoreInt::HttpThread * thread)
|
|||
|
||||
HttpService::ELoopSpeed HttpService::processRequestQueue(ELoopSpeed loop)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK;
|
||||
HttpRequestQueue::OpContainer ops;
|
||||
const bool wait_for_req(REQUEST_SLEEP == loop);
|
||||
|
||||
|
|
@ -384,6 +378,7 @@ HttpService::ELoopSpeed HttpService::processRequestQueue(ELoopSpeed loop)
|
|||
HttpStatus HttpService::getPolicyOption(HttpRequest::EPolicyOption opt, HttpRequest::policy_t pclass,
|
||||
long * ret_value)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK;
|
||||
if (opt < HttpRequest::PO_CONNECTION_LIMIT // option must be in range
|
||||
|| opt >= HttpRequest::PO_LAST // ditto
|
||||
|| (! sOptionDesc[opt].mIsLong) // datatype is long
|
||||
|
|
@ -416,6 +411,7 @@ HttpStatus HttpService::getPolicyOption(HttpRequest::EPolicyOption opt, HttpRequ
|
|||
HttpStatus HttpService::getPolicyOption(HttpRequest::EPolicyOption opt, HttpRequest::policy_t pclass,
|
||||
std::string * ret_value)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK;
|
||||
HttpStatus status(HttpStatus::LLCORE, LLCore::HE_INVALID_ARG);
|
||||
|
||||
if (opt < HttpRequest::PO_CONNECTION_LIMIT // option must be in range
|
||||
|
|
@ -443,6 +439,7 @@ HttpStatus HttpService::getPolicyOption(HttpRequest::EPolicyOption opt, HttpRequ
|
|||
HttpStatus HttpService::getPolicyOption(HttpRequest::EPolicyOption opt, HttpRequest::policy_t pclass,
|
||||
HttpRequest::policyCallback_t * ret_value)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK;
|
||||
HttpStatus status(HttpStatus::LLCORE, LLCore::HE_INVALID_ARG);
|
||||
|
||||
if (opt < HttpRequest::PO_CONNECTION_LIMIT // option must be in range
|
||||
|
|
@ -472,6 +469,7 @@ HttpStatus HttpService::getPolicyOption(HttpRequest::EPolicyOption opt, HttpRequ
|
|||
HttpStatus HttpService::setPolicyOption(HttpRequest::EPolicyOption opt, HttpRequest::policy_t pclass,
|
||||
long value, long * ret_value)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK;
|
||||
HttpStatus status(HttpStatus::LLCORE, LLCore::HE_INVALID_ARG);
|
||||
|
||||
if (opt < HttpRequest::PO_CONNECTION_LIMIT // option must be in range
|
||||
|
|
@ -517,6 +515,7 @@ HttpStatus HttpService::setPolicyOption(HttpRequest::EPolicyOption opt, HttpRequ
|
|||
HttpStatus HttpService::setPolicyOption(HttpRequest::EPolicyOption opt, HttpRequest::policy_t pclass,
|
||||
const std::string & value, std::string * ret_value)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK;
|
||||
HttpStatus status(HttpStatus::LLCORE, LLCore::HE_INVALID_ARG);
|
||||
|
||||
if (opt < HttpRequest::PO_CONNECTION_LIMIT // option must be in range
|
||||
|
|
@ -548,6 +547,7 @@ HttpStatus HttpService::setPolicyOption(HttpRequest::EPolicyOption opt, HttpRequ
|
|||
HttpStatus HttpService::setPolicyOption(HttpRequest::EPolicyOption opt, HttpRequest::policy_t pclass,
|
||||
HttpRequest::policyCallback_t value, HttpRequest::policyCallback_t * ret_value)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK;
|
||||
HttpStatus status(HttpStatus::LLCORE, LLCore::HE_INVALID_ARG);
|
||||
|
||||
if (opt < HttpRequest::PO_CONNECTION_LIMIT // option must be in range
|
||||
|
|
|
|||
|
|
@ -146,15 +146,6 @@ public:
|
|||
/// Threading: callable by worker thread.
|
||||
void shutdown();
|
||||
|
||||
/// Try to find the given request handle on any of the request
|
||||
/// queues and reset the priority (and queue position) of the
|
||||
/// request if found.
|
||||
///
|
||||
/// @return True if the request was found somewhere.
|
||||
///
|
||||
/// Threading: callable by worker thread.
|
||||
bool changePriority(HttpHandle handle, HttpRequest::priority_t priority);
|
||||
|
||||
/// Try to find the given request handle on any of the request
|
||||
/// queues and cancel the operation.
|
||||
///
|
||||
|
|
|
|||
|
|
@ -469,11 +469,11 @@ bool WorkingSet::reload(LLCore::HttpRequest * hr, LLCore::HttpOptions::ptr_t & o
|
|||
LLCore::HttpHandle handle;
|
||||
if (offset || length)
|
||||
{
|
||||
handle = hr->requestGetByteRange(0, 0, buffer, offset, length, opt, mHeaders, LLCore::HttpHandler::ptr_t(this, NoOpDeletor));
|
||||
handle = hr->requestGetByteRange(0, buffer, offset, length, opt, mHeaders, LLCore::HttpHandler::ptr_t(this, NoOpDeletor));
|
||||
}
|
||||
else
|
||||
{
|
||||
handle = hr->requestGet(0, 0, buffer, opt, mHeaders, LLCore::HttpHandler::ptr_t(this, NoOpDeletor));
|
||||
handle = hr->requestGet(0, buffer, opt, mHeaders, LLCore::HttpHandler::ptr_t(this, NoOpDeletor));
|
||||
}
|
||||
if (! handle)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -32,7 +32,6 @@
|
|||
#include "_httppolicy.h"
|
||||
#include "_httpoperation.h"
|
||||
#include "_httpoprequest.h"
|
||||
#include "_httpopsetpriority.h"
|
||||
#include "_httpopcancel.h"
|
||||
#include "_httpopsetget.h"
|
||||
|
||||
|
|
@ -183,16 +182,16 @@ HttpStatus HttpRequest::getStatus() const
|
|||
|
||||
|
||||
HttpHandle HttpRequest::requestGet(policy_t policy_id,
|
||||
priority_t priority,
|
||||
const std::string & url,
|
||||
const HttpOptions::ptr_t & options,
|
||||
const HttpHeaders::ptr_t & headers,
|
||||
HttpHandler::ptr_t user_handler)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK;
|
||||
HttpStatus status;
|
||||
|
||||
HttpOpRequest::ptr_t op(new HttpOpRequest());
|
||||
if (! (status = op->setupGet(policy_id, priority, url, options, headers)))
|
||||
if (! (status = op->setupGet(policy_id, url, options, headers)))
|
||||
{
|
||||
mLastReqStatus = status;
|
||||
return LLCORE_HTTP_HANDLE_INVALID;
|
||||
|
|
@ -210,7 +209,6 @@ HttpHandle HttpRequest::requestGet(policy_t policy_id,
|
|||
|
||||
|
||||
HttpHandle HttpRequest::requestGetByteRange(policy_t policy_id,
|
||||
priority_t priority,
|
||||
const std::string & url,
|
||||
size_t offset,
|
||||
size_t len,
|
||||
|
|
@ -218,10 +216,11 @@ HttpHandle HttpRequest::requestGetByteRange(policy_t policy_id,
|
|||
const HttpHeaders::ptr_t & headers,
|
||||
HttpHandler::ptr_t user_handler)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK;
|
||||
HttpStatus status;
|
||||
|
||||
HttpOpRequest::ptr_t op(new HttpOpRequest());
|
||||
if (! (status = op->setupGetByteRange(policy_id, priority, url, offset, len, options, headers)))
|
||||
if (! (status = op->setupGetByteRange(policy_id, url, offset, len, options, headers)))
|
||||
{
|
||||
mLastReqStatus = status;
|
||||
return LLCORE_HTTP_HANDLE_INVALID;
|
||||
|
|
@ -239,7 +238,6 @@ HttpHandle HttpRequest::requestGetByteRange(policy_t policy_id,
|
|||
|
||||
|
||||
HttpHandle HttpRequest::requestPost(policy_t policy_id,
|
||||
priority_t priority,
|
||||
const std::string & url,
|
||||
BufferArray * body,
|
||||
const HttpOptions::ptr_t & options,
|
||||
|
|
@ -249,7 +247,7 @@ HttpHandle HttpRequest::requestPost(policy_t policy_id,
|
|||
HttpStatus status;
|
||||
|
||||
HttpOpRequest::ptr_t op(new HttpOpRequest());
|
||||
if (! (status = op->setupPost(policy_id, priority, url, body, options, headers)))
|
||||
if (! (status = op->setupPost(policy_id, url, body, options, headers)))
|
||||
{
|
||||
mLastReqStatus = status;
|
||||
return LLCORE_HTTP_HANDLE_INVALID;
|
||||
|
|
@ -267,7 +265,6 @@ HttpHandle HttpRequest::requestPost(policy_t policy_id,
|
|||
|
||||
|
||||
HttpHandle HttpRequest::requestPut(policy_t policy_id,
|
||||
priority_t priority,
|
||||
const std::string & url,
|
||||
BufferArray * body,
|
||||
const HttpOptions::ptr_t & options,
|
||||
|
|
@ -277,7 +274,7 @@ HttpHandle HttpRequest::requestPut(policy_t policy_id,
|
|||
HttpStatus status;
|
||||
|
||||
HttpOpRequest::ptr_t op (new HttpOpRequest());
|
||||
if (! (status = op->setupPut(policy_id, priority, url, body, options, headers)))
|
||||
if (! (status = op->setupPut(policy_id, url, body, options, headers)))
|
||||
{
|
||||
mLastReqStatus = status;
|
||||
return LLCORE_HTTP_HANDLE_INVALID;
|
||||
|
|
@ -294,7 +291,6 @@ HttpHandle HttpRequest::requestPut(policy_t policy_id,
|
|||
}
|
||||
|
||||
HttpHandle HttpRequest::requestDelete(policy_t policy_id,
|
||||
priority_t priority,
|
||||
const std::string & url,
|
||||
const HttpOptions::ptr_t & options,
|
||||
const HttpHeaders::ptr_t & headers,
|
||||
|
|
@ -303,7 +299,7 @@ HttpHandle HttpRequest::requestDelete(policy_t policy_id,
|
|||
HttpStatus status;
|
||||
|
||||
HttpOpRequest::ptr_t op(new HttpOpRequest());
|
||||
if (!(status = op->setupDelete(policy_id, priority, url, options, headers)))
|
||||
if (!(status = op->setupDelete(policy_id, url, options, headers)))
|
||||
{
|
||||
mLastReqStatus = status;
|
||||
return LLCORE_HTTP_HANDLE_INVALID;
|
||||
|
|
@ -320,7 +316,6 @@ HttpHandle HttpRequest::requestDelete(policy_t policy_id,
|
|||
}
|
||||
|
||||
HttpHandle HttpRequest::requestPatch(policy_t policy_id,
|
||||
priority_t priority,
|
||||
const std::string & url,
|
||||
BufferArray * body,
|
||||
const HttpOptions::ptr_t & options,
|
||||
|
|
@ -330,7 +325,7 @@ HttpHandle HttpRequest::requestPatch(policy_t policy_id,
|
|||
HttpStatus status;
|
||||
|
||||
HttpOpRequest::ptr_t op (new HttpOpRequest());
|
||||
if (!(status = op->setupPatch(policy_id, priority, url, body, options, headers)))
|
||||
if (!(status = op->setupPatch(policy_id, url, body, options, headers)))
|
||||
{
|
||||
mLastReqStatus = status;
|
||||
return LLCORE_HTTP_HANDLE_INVALID;
|
||||
|
|
@ -347,7 +342,6 @@ HttpHandle HttpRequest::requestPatch(policy_t policy_id,
|
|||
}
|
||||
|
||||
HttpHandle HttpRequest::requestCopy(policy_t policy_id,
|
||||
priority_t priority,
|
||||
const std::string & url,
|
||||
const HttpOptions::ptr_t & options,
|
||||
const HttpHeaders::ptr_t & headers,
|
||||
|
|
@ -356,7 +350,7 @@ HttpHandle HttpRequest::requestCopy(policy_t policy_id,
|
|||
HttpStatus status;
|
||||
|
||||
HttpOpRequest::ptr_t op(new HttpOpRequest());
|
||||
if (!(status = op->setupCopy(policy_id, priority, url, options, headers)))
|
||||
if (!(status = op->setupCopy(policy_id, url, options, headers)))
|
||||
{
|
||||
mLastReqStatus = status;
|
||||
return LLCORE_HTTP_HANDLE_INVALID;
|
||||
|
|
@ -374,7 +368,6 @@ HttpHandle HttpRequest::requestCopy(policy_t policy_id,
|
|||
}
|
||||
|
||||
HttpHandle HttpRequest::requestMove(policy_t policy_id,
|
||||
priority_t priority,
|
||||
const std::string & url,
|
||||
const HttpOptions::ptr_t & options,
|
||||
const HttpHeaders::ptr_t & headers,
|
||||
|
|
@ -383,7 +376,7 @@ HttpHandle HttpRequest::requestMove(policy_t policy_id,
|
|||
HttpStatus status;
|
||||
|
||||
HttpOpRequest::ptr_t op (new HttpOpRequest());
|
||||
if (!(status = op->setupMove(policy_id, priority, url, options, headers)))
|
||||
if (!(status = op->setupMove(policy_id, url, options, headers)))
|
||||
{
|
||||
mLastReqStatus = status;
|
||||
return LLCORE_HTTP_HANDLE_INVALID;
|
||||
|
|
@ -483,24 +476,6 @@ HttpHandle HttpRequest::requestCancel(HttpHandle request, HttpHandler::ptr_t use
|
|||
}
|
||||
|
||||
|
||||
HttpHandle HttpRequest::requestSetPriority(HttpHandle request, priority_t priority,
|
||||
HttpHandler::ptr_t handler)
|
||||
{
|
||||
HttpStatus status;
|
||||
|
||||
HttpOperation::ptr_t op (new HttpOpSetPriority(request, priority));
|
||||
op->setReplyPath(mReplyQueue, handler);
|
||||
if (! (status = mRequestQueue->addOp(op))) // transfers refcount
|
||||
{
|
||||
mLastReqStatus = status;
|
||||
return LLCORE_HTTP_HANDLE_INVALID;
|
||||
}
|
||||
|
||||
mLastReqStatus = status;
|
||||
return op->getHandle();
|
||||
}
|
||||
|
||||
|
||||
// ====================================
|
||||
// Utility Methods
|
||||
// ====================================
|
||||
|
|
|
|||
|
|
@ -95,7 +95,6 @@ private:
|
|||
|
||||
public:
|
||||
typedef unsigned int policy_t;
|
||||
typedef unsigned int priority_t;
|
||||
|
||||
typedef boost::shared_ptr<HttpRequest> ptr_t;
|
||||
typedef boost::weak_ptr<HttpRequest> wptr_t;
|
||||
|
|
@ -316,8 +315,6 @@ public:
|
|||
///
|
||||
/// @param policy_id Default or user-defined policy class under
|
||||
/// which this request is to be serviced.
|
||||
/// @param priority Standard priority scheme inherited from
|
||||
/// Indra code base (U32-type scheme).
|
||||
/// @param url URL with any encoded query parameters to
|
||||
/// be accessed.
|
||||
/// @param options Optional instance of an HttpOptions object
|
||||
|
|
@ -346,7 +343,6 @@ public:
|
|||
/// case, @see getStatus() will return more info.
|
||||
///
|
||||
HttpHandle requestGet(policy_t policy_id,
|
||||
priority_t priority,
|
||||
const std::string & url,
|
||||
const HttpOptions::ptr_t & options,
|
||||
const HttpHeaders::ptr_t & headers,
|
||||
|
|
@ -377,7 +373,6 @@ public:
|
|||
/// - Referer:
|
||||
///
|
||||
/// @param policy_id @see requestGet()
|
||||
/// @param priority "
|
||||
/// @param url "
|
||||
/// @param offset Offset of first byte into resource to be returned.
|
||||
/// @param len Count of bytes to be returned
|
||||
|
|
@ -387,7 +382,6 @@ public:
|
|||
/// @return "
|
||||
///
|
||||
HttpHandle requestGetByteRange(policy_t policy_id,
|
||||
priority_t priority,
|
||||
const std::string & url,
|
||||
size_t offset,
|
||||
size_t len,
|
||||
|
|
@ -418,7 +412,6 @@ public:
|
|||
/// - Expect:
|
||||
///
|
||||
/// @param policy_id @see requestGet()
|
||||
/// @param priority "
|
||||
/// @param url "
|
||||
/// @param body Byte stream to be sent as the body. No
|
||||
/// further encoding or escaping will be done
|
||||
|
|
@ -429,7 +422,6 @@ public:
|
|||
/// @return "
|
||||
///
|
||||
HttpHandle requestPost(policy_t policy_id,
|
||||
priority_t priority,
|
||||
const std::string & url,
|
||||
BufferArray * body,
|
||||
const HttpOptions::ptr_t & options,
|
||||
|
|
@ -459,7 +451,6 @@ public:
|
|||
/// - Content-Type:
|
||||
///
|
||||
/// @param policy_id @see requestGet()
|
||||
/// @param priority "
|
||||
/// @param url "
|
||||
/// @param body Byte stream to be sent as the body. No
|
||||
/// further encoding or escaping will be done
|
||||
|
|
@ -470,7 +461,6 @@ public:
|
|||
/// @return "
|
||||
///
|
||||
HttpHandle requestPut(policy_t policy_id,
|
||||
priority_t priority,
|
||||
const std::string & url,
|
||||
BufferArray * body,
|
||||
const HttpOptions::ptr_t & options,
|
||||
|
|
@ -483,7 +473,6 @@ public:
|
|||
/// encoding and communicating the content types.
|
||||
///
|
||||
/// @param policy_id @see requestGet()
|
||||
/// @param priority "
|
||||
/// @param url "
|
||||
/// @param options @see requestGet()K(optional)
|
||||
/// @param headers "
|
||||
|
|
@ -491,7 +480,6 @@ public:
|
|||
/// @return "
|
||||
///
|
||||
HttpHandle requestDelete(policy_t policy_id,
|
||||
priority_t priority,
|
||||
const std::string & url,
|
||||
const HttpOptions::ptr_t & options,
|
||||
const HttpHeaders::ptr_t & headers,
|
||||
|
|
@ -502,7 +490,6 @@ public:
|
|||
/// encoding and communicating the content types.
|
||||
///
|
||||
/// @param policy_id @see requestGet()
|
||||
/// @param priority "
|
||||
/// @param url "
|
||||
/// @param body Byte stream to be sent as the body. No
|
||||
/// further encoding or escaping will be done
|
||||
|
|
@ -513,7 +500,6 @@ public:
|
|||
/// @return "
|
||||
///
|
||||
HttpHandle requestPatch(policy_t policy_id,
|
||||
priority_t priority,
|
||||
const std::string & url,
|
||||
BufferArray * body,
|
||||
const HttpOptions::ptr_t & options,
|
||||
|
|
@ -525,7 +511,6 @@ public:
|
|||
/// encoding and communicating the content types.
|
||||
///
|
||||
/// @param policy_id @see requestGet()
|
||||
/// @param priority "
|
||||
/// @param url "
|
||||
/// @param options @see requestGet()K(optional)
|
||||
/// @param headers "
|
||||
|
|
@ -533,7 +518,6 @@ public:
|
|||
/// @return "
|
||||
///
|
||||
HttpHandle requestCopy(policy_t policy_id,
|
||||
priority_t priority,
|
||||
const std::string & url,
|
||||
const HttpOptions::ptr_t & options,
|
||||
const HttpHeaders::ptr_t & headers,
|
||||
|
|
@ -544,7 +528,6 @@ public:
|
|||
/// encoding and communicating the content types.
|
||||
///
|
||||
/// @param policy_id @see requestGet()
|
||||
/// @param priority "
|
||||
/// @param url "
|
||||
/// @param options @see requestGet()K(optional)
|
||||
/// @param headers "
|
||||
|
|
@ -552,7 +535,6 @@ public:
|
|||
/// @return "
|
||||
///
|
||||
HttpHandle requestMove(policy_t policy_id,
|
||||
priority_t priority,
|
||||
const std::string & url,
|
||||
const HttpOptions::ptr_t & options,
|
||||
const HttpHeaders::ptr_t & headers,
|
||||
|
|
@ -593,18 +575,6 @@ public:
|
|||
|
||||
HttpHandle requestCancel(HttpHandle request, HttpHandler::ptr_t);
|
||||
|
||||
/// Request that a previously-issued request be reprioritized.
|
||||
/// The status of whether the change itself succeeded arrives
|
||||
/// via notification.
|
||||
///
|
||||
/// @param request Handle of previously-issued request to
|
||||
/// be changed.
|
||||
/// @param priority New priority value.
|
||||
/// @param handler @see requestGet()
|
||||
/// @return "
|
||||
///
|
||||
HttpHandle requestSetPriority(HttpHandle request, priority_t priority, HttpHandler::ptr_t handler);
|
||||
|
||||
/// @}
|
||||
|
||||
/// @name UtilityMethods
|
||||
|
|
|
|||
|
|
@ -614,7 +614,6 @@ void HttpRequestTestObjectType::test<7>()
|
|||
// Issue a GET that can't connect
|
||||
mStatus = HttpStatus(HttpStatus::EXT_CURL_EASY, CURLE_COULDNT_CONNECT);
|
||||
HttpHandle handle = req->requestGetByteRange(HttpRequest::DEFAULT_POLICY_ID,
|
||||
0U,
|
||||
"http://127.0.0.1:2/nothing/here",
|
||||
0,
|
||||
0,
|
||||
|
|
@ -716,7 +715,6 @@ void HttpRequestTestObjectType::test<8>()
|
|||
// Issue a GET that *can* connect
|
||||
mStatus = HttpStatus(200);
|
||||
HttpHandle handle = req->requestGet(HttpRequest::DEFAULT_POLICY_ID,
|
||||
0U,
|
||||
url_base,
|
||||
HttpOptions::ptr_t(),
|
||||
HttpHeaders::ptr_t(),
|
||||
|
|
@ -812,7 +810,6 @@ void HttpRequestTestObjectType::test<9>()
|
|||
// Issue a GET that *can* connect
|
||||
mStatus = HttpStatus(200);
|
||||
HttpHandle handle = req->requestGetByteRange(HttpRequest::DEFAULT_POLICY_ID,
|
||||
0U,
|
||||
url_base,
|
||||
0,
|
||||
0,
|
||||
|
|
@ -913,7 +910,6 @@ void HttpRequestTestObjectType::test<10>()
|
|||
body->append(body_text, strlen(body_text));
|
||||
mStatus = HttpStatus(200);
|
||||
HttpHandle handle = req->requestPut(HttpRequest::DEFAULT_POLICY_ID,
|
||||
0U,
|
||||
url_base,
|
||||
body,
|
||||
HttpOptions::ptr_t(),
|
||||
|
|
@ -1020,7 +1016,6 @@ void HttpRequestTestObjectType::test<11>()
|
|||
body->append(body_text, strlen(body_text));
|
||||
mStatus = HttpStatus(200);
|
||||
HttpHandle handle = req->requestPost(HttpRequest::DEFAULT_POLICY_ID,
|
||||
0U,
|
||||
url_base,
|
||||
body,
|
||||
HttpOptions::ptr_t(),
|
||||
|
|
@ -1127,7 +1122,6 @@ void HttpRequestTestObjectType::test<12>()
|
|||
// Issue a GET that *can* connect
|
||||
mStatus = HttpStatus(200);
|
||||
HttpHandle handle = req->requestGetByteRange(HttpRequest::DEFAULT_POLICY_ID,
|
||||
0U,
|
||||
url_base,
|
||||
0,
|
||||
0,
|
||||
|
|
@ -1240,7 +1234,6 @@ void HttpRequestTestObjectType::test<13>()
|
|||
regex_container_t::value_type(boost::regex("X-LL-Special", boost::regex::icase),
|
||||
boost::regex(".*", boost::regex::icase)));
|
||||
HttpHandle handle = req->requestGetByteRange(HttpRequest::DEFAULT_POLICY_ID,
|
||||
0U,
|
||||
url_base,
|
||||
0,
|
||||
0,
|
||||
|
|
@ -1346,7 +1339,6 @@ void HttpRequestTestObjectType::test<14>()
|
|||
// Issue a GET that sleeps
|
||||
mStatus = HttpStatus(HttpStatus::EXT_CURL_EASY, CURLE_OPERATION_TIMEDOUT);
|
||||
HttpHandle handle = req->requestGetByteRange(HttpRequest::DEFAULT_POLICY_ID,
|
||||
0U,
|
||||
url_base,
|
||||
0,
|
||||
0,
|
||||
|
|
@ -1454,7 +1446,6 @@ void HttpRequestTestObjectType::test<15>()
|
|||
mStatus = HttpStatus(200);
|
||||
handler.mCheckContentType = "application/llsd+xml";
|
||||
HttpHandle handle = req->requestGet(HttpRequest::DEFAULT_POLICY_ID,
|
||||
0U,
|
||||
url_base,
|
||||
HttpOptions::ptr_t(),
|
||||
HttpHeaders::ptr_t(),
|
||||
|
|
@ -1609,7 +1600,6 @@ void HttpRequestTestObjectType::test<16>()
|
|||
boost::regex("X-Reflect-content-encoding", boost::regex::icase),
|
||||
boost::regex(".*", boost::regex::icase)));
|
||||
HttpHandle handle = req->requestGet(HttpRequest::DEFAULT_POLICY_ID,
|
||||
0U,
|
||||
url_base + "reflect/",
|
||||
options,
|
||||
HttpHeaders::ptr_t(),
|
||||
|
|
@ -1684,7 +1674,6 @@ void HttpRequestTestObjectType::test<16>()
|
|||
boost::regex("X-Reflect-content-encoding", boost::regex::icase),
|
||||
boost::regex(".*", boost::regex::icase)));
|
||||
handle = req->requestGetByteRange(HttpRequest::DEFAULT_POLICY_ID,
|
||||
0U,
|
||||
url_base + "reflect/",
|
||||
0,
|
||||
47,
|
||||
|
|
@ -1863,7 +1852,6 @@ void HttpRequestTestObjectType::test<17>()
|
|||
boost::regex("X-Reflect-transfer_encoding", boost::regex::icase),
|
||||
boost::regex(".*chunked.*", boost::regex::icase)));
|
||||
HttpHandle handle = req->requestPost(HttpRequest::DEFAULT_POLICY_ID,
|
||||
0U,
|
||||
url_base + "reflect/",
|
||||
ba,
|
||||
options,
|
||||
|
|
@ -2049,7 +2037,6 @@ void HttpRequestTestObjectType::test<18>()
|
|||
boost::regex(".*", boost::regex::icase)));
|
||||
|
||||
HttpHandle handle = req->requestPut(HttpRequest::DEFAULT_POLICY_ID,
|
||||
0U,
|
||||
url_base + "reflect/",
|
||||
ba,
|
||||
options,
|
||||
|
|
@ -2249,7 +2236,6 @@ void HttpRequestTestObjectType::test<19>()
|
|||
boost::regex("X-Reflect-content-encoding", boost::regex::icase),
|
||||
boost::regex(".*", boost::regex::icase)));
|
||||
HttpHandle handle = req->requestGet(HttpRequest::DEFAULT_POLICY_ID,
|
||||
0U,
|
||||
url_base + "reflect/",
|
||||
options,
|
||||
headers,
|
||||
|
|
@ -2457,7 +2443,6 @@ void HttpRequestTestObjectType::test<20>()
|
|||
boost::regex(".*", boost::regex::icase)));
|
||||
|
||||
HttpHandle handle = req->requestPost(HttpRequest::DEFAULT_POLICY_ID,
|
||||
0U,
|
||||
url_base + "reflect/",
|
||||
ba,
|
||||
options,
|
||||
|
|
@ -2666,7 +2651,6 @@ void HttpRequestTestObjectType::test<21>()
|
|||
boost::regex("X-Reflect-content-type", boost::regex::icase),
|
||||
boost::regex("text/html", boost::regex::icase)));
|
||||
HttpHandle handle = req->requestPut(HttpRequest::DEFAULT_POLICY_ID,
|
||||
0U,
|
||||
url_base + "reflect/",
|
||||
ba,
|
||||
options,
|
||||
|
|
@ -2797,7 +2781,6 @@ void HttpRequestTestObjectType::test<22>()
|
|||
char buffer[128];
|
||||
sprintf(buffer, "/bug2295/%d/", i);
|
||||
HttpHandle handle = req->requestGetByteRange(HttpRequest::DEFAULT_POLICY_ID,
|
||||
0U,
|
||||
url_base + buffer,
|
||||
0,
|
||||
25,
|
||||
|
|
@ -2829,7 +2812,6 @@ void HttpRequestTestObjectType::test<22>()
|
|||
char buffer[128];
|
||||
sprintf(buffer, "/bug2295/00000012/%d/", i);
|
||||
HttpHandle handle = req->requestGetByteRange(HttpRequest::DEFAULT_POLICY_ID,
|
||||
0U,
|
||||
url_base + buffer,
|
||||
0,
|
||||
25,
|
||||
|
|
@ -2861,7 +2843,6 @@ void HttpRequestTestObjectType::test<22>()
|
|||
char buffer[128];
|
||||
sprintf(buffer, "/bug2295/inv_cont_range/%d/", i);
|
||||
HttpHandle handle = req->requestGetByteRange(HttpRequest::DEFAULT_POLICY_ID,
|
||||
0U,
|
||||
url_base + buffer,
|
||||
0,
|
||||
25,
|
||||
|
|
@ -2984,7 +2965,6 @@ void HttpRequestTestObjectType::test<23>()
|
|||
std::ostringstream url;
|
||||
url << url_base << i << "/";
|
||||
HttpHandle handle = req->requestGetByteRange(HttpRequest::DEFAULT_POLICY_ID,
|
||||
0U,
|
||||
url.str(),
|
||||
0,
|
||||
0,
|
||||
|
|
|
|||
|
|
@ -418,7 +418,7 @@ bool LLCrashLogger::runCrashLogPost(std::string host, LLSD data, std::string msg
|
|||
updateApplication(llformat("%s, try %d...", msg.c_str(), i+1));
|
||||
|
||||
LL_INFOS("CRASHREPORT") << "POST crash data to " << host << LL_ENDL;
|
||||
LLCore::HttpHandle handle = LLCoreHttpUtil::requestPostWithLLSD(httpRequest.get(), LLCore::HttpRequest::DEFAULT_POLICY_ID, 0,
|
||||
LLCore::HttpHandle handle = LLCoreHttpUtil::requestPostWithLLSD(httpRequest.get(), LLCore::HttpRequest::DEFAULT_POLICY_ID,
|
||||
host, data, httpOpts, LLCore::HttpHeaders::ptr_t(), LLCore::HttpHandler::ptr_t(new LLCrashLoggerHandler));
|
||||
|
||||
if (handle == LLCORE_HTTP_HANDLE_INVALID)
|
||||
|
|
|
|||
|
|
@ -45,8 +45,7 @@ void LLLFSThread::initClass(bool local_is_threaded)
|
|||
//static
|
||||
S32 LLLFSThread::updateClass(U32 ms_elapsed)
|
||||
{
|
||||
sLocal->update((F32)ms_elapsed);
|
||||
return sLocal->getPending();
|
||||
return sLocal->update((F32)ms_elapsed);
|
||||
}
|
||||
|
||||
//static
|
||||
|
|
@ -58,6 +57,7 @@ void LLLFSThread::cleanupClass()
|
|||
{
|
||||
sLocal->update(0);
|
||||
}
|
||||
sLocal->shutdown();
|
||||
delete sLocal;
|
||||
sLocal = NULL;
|
||||
}
|
||||
|
|
@ -65,8 +65,7 @@ void LLLFSThread::cleanupClass()
|
|||
//----------------------------------------------------------------------------
|
||||
|
||||
LLLFSThread::LLLFSThread(bool threaded) :
|
||||
LLQueuedThread("LFS", threaded),
|
||||
mPriorityCounter(PRIORITY_LOWBITS)
|
||||
LLQueuedThread("LFS", threaded)
|
||||
{
|
||||
if(!mLocalAPRFilePoolp)
|
||||
{
|
||||
|
|
@ -84,14 +83,12 @@ LLLFSThread::~LLLFSThread()
|
|||
|
||||
LLLFSThread::handle_t LLLFSThread::read(const std::string& filename, /* Flawfinder: ignore */
|
||||
U8* buffer, S32 offset, S32 numbytes,
|
||||
Responder* responder, U32 priority)
|
||||
Responder* responder)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED;
|
||||
handle_t handle = generateHandle();
|
||||
|
||||
if (priority == 0) priority = PRIORITY_NORMAL | priorityCounter();
|
||||
else if (priority < PRIORITY_LOW) priority |= PRIORITY_LOW; // All reads are at least PRIORITY_LOW
|
||||
|
||||
Request* req = new Request(this, handle, priority,
|
||||
Request* req = new Request(this, handle,
|
||||
FILE_READ, filename,
|
||||
buffer, offset, numbytes,
|
||||
responder);
|
||||
|
|
@ -107,13 +104,12 @@ LLLFSThread::handle_t LLLFSThread::read(const std::string& filename, /* Flawfind
|
|||
|
||||
LLLFSThread::handle_t LLLFSThread::write(const std::string& filename,
|
||||
U8* buffer, S32 offset, S32 numbytes,
|
||||
Responder* responder, U32 priority)
|
||||
Responder* responder)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED;
|
||||
handle_t handle = generateHandle();
|
||||
|
||||
if (priority == 0) priority = PRIORITY_LOW | priorityCounter();
|
||||
|
||||
Request* req = new Request(this, handle, priority,
|
||||
Request* req = new Request(this, handle,
|
||||
FILE_WRITE, filename,
|
||||
buffer, offset, numbytes,
|
||||
responder);
|
||||
|
|
@ -130,11 +126,11 @@ LLLFSThread::handle_t LLLFSThread::write(const std::string& filename,
|
|||
//============================================================================
|
||||
|
||||
LLLFSThread::Request::Request(LLLFSThread* thread,
|
||||
handle_t handle, U32 priority,
|
||||
handle_t handle,
|
||||
operation_t op, const std::string& filename,
|
||||
U8* buffer, S32 offset, S32 numbytes,
|
||||
Responder* responder) :
|
||||
QueuedRequest(handle, priority, FLAG_AUTO_COMPLETE),
|
||||
QueuedRequest(handle, FLAG_AUTO_COMPLETE),
|
||||
mThread(thread),
|
||||
mOperation(op),
|
||||
mFileName(filename),
|
||||
|
|
@ -157,6 +153,7 @@ LLLFSThread::Request::~Request()
|
|||
// virtual, called from own thread
|
||||
void LLLFSThread::Request::finishRequest(bool completed)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED;
|
||||
if (mResponder.notNull())
|
||||
{
|
||||
mResponder->completed(completed ? mBytesRead : 0);
|
||||
|
|
@ -166,6 +163,7 @@ void LLLFSThread::Request::finishRequest(bool completed)
|
|||
|
||||
void LLLFSThread::Request::deleteRequest()
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED;
|
||||
if (getStatus() == STATUS_QUEUED)
|
||||
{
|
||||
LL_ERRS() << "Attempt to delete a queued LLLFSThread::Request!" << LL_ENDL;
|
||||
|
|
@ -180,6 +178,7 @@ void LLLFSThread::Request::deleteRequest()
|
|||
|
||||
bool LLLFSThread::Request::processRequest()
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED;
|
||||
bool complete = false;
|
||||
if (mOperation == FILE_READ)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -68,7 +68,7 @@ public:
|
|||
|
||||
public:
|
||||
Request(LLLFSThread* thread,
|
||||
handle_t handle, U32 priority,
|
||||
handle_t handle,
|
||||
operation_t op, const std::string& filename,
|
||||
U8* buffer, S32 offset, S32 numbytes,
|
||||
Responder* responder);
|
||||
|
|
@ -120,22 +120,15 @@ public:
|
|||
// Return a Request handle
|
||||
handle_t read(const std::string& filename, /* Flawfinder: ignore */
|
||||
U8* buffer, S32 offset, S32 numbytes,
|
||||
Responder* responder, U32 pri=0);
|
||||
Responder* responder);
|
||||
handle_t write(const std::string& filename,
|
||||
U8* buffer, S32 offset, S32 numbytes,
|
||||
Responder* responder, U32 pri=0);
|
||||
|
||||
// Misc
|
||||
U32 priorityCounter() { return mPriorityCounter-- & PRIORITY_LOWBITS; } // Use to order IO operations
|
||||
Responder* responder);
|
||||
|
||||
// static initializers
|
||||
static void initClass(bool local_is_threaded = TRUE); // Setup sLocal
|
||||
static S32 updateClass(U32 ms_elapsed);
|
||||
static void cleanupClass(); // Delete sLocal
|
||||
|
||||
|
||||
private:
|
||||
U32 mPriorityCounter;
|
||||
|
||||
public:
|
||||
static LLLFSThread* sLocal; // Default local file thread
|
||||
|
|
|
|||
|
|
@ -798,7 +798,6 @@ U8* LLImageBase::allocateDataSize(S32 width, S32 height, S32 ncomponents, S32 si
|
|||
// LLImageRaw
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
S32 LLImageRaw::sGlobalRawMemory = 0;
|
||||
S32 LLImageRaw::sRawImageCount = 0;
|
||||
|
||||
LLImageRaw::LLImageRaw()
|
||||
|
|
@ -856,16 +855,13 @@ LLImageRaw::~LLImageRaw()
|
|||
U8* LLImageRaw::allocateData(S32 size)
|
||||
{
|
||||
U8* res = LLImageBase::allocateData(size);
|
||||
sGlobalRawMemory += getDataSize();
|
||||
return res;
|
||||
}
|
||||
|
||||
// virtual
|
||||
U8* LLImageRaw::reallocateData(S32 size)
|
||||
{
|
||||
sGlobalRawMemory -= getDataSize();
|
||||
U8* res = LLImageBase::reallocateData(size);
|
||||
sGlobalRawMemory += getDataSize();
|
||||
return res;
|
||||
}
|
||||
|
||||
|
|
@ -878,7 +874,6 @@ void LLImageRaw::releaseData()
|
|||
// virtual
|
||||
void LLImageRaw::deleteData()
|
||||
{
|
||||
sGlobalRawMemory -= getDataSize();
|
||||
LLImageBase::deleteData();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -276,7 +276,6 @@ protected:
|
|||
void setDataAndSize(U8 *data, S32 width, S32 height, S8 components) ;
|
||||
|
||||
public:
|
||||
static S32 sGlobalRawMemory;
|
||||
static S32 sRawImageCount;
|
||||
|
||||
private:
|
||||
|
|
|
|||
|
|
@ -146,6 +146,7 @@ bool LLImageJ2C::initEncode(LLImageRaw &raw_image, int blocks_size, int precinct
|
|||
|
||||
bool LLImageJ2C::decode(LLImageRaw *raw_imagep, F32 decode_time)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
|
||||
return decodeChannels(raw_imagep, decode_time, 0, 4);
|
||||
}
|
||||
|
||||
|
|
@ -153,6 +154,7 @@ bool LLImageJ2C::decode(LLImageRaw *raw_imagep, F32 decode_time)
|
|||
// Returns true to mean done, whether successful or not.
|
||||
bool LLImageJ2C::decodeChannels(LLImageRaw *raw_imagep, F32 decode_time, S32 first_channel, S32 max_channel_count )
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
|
||||
LLTimer elapsed;
|
||||
|
||||
bool res = true;
|
||||
|
|
|
|||
|
|
@ -28,64 +28,88 @@
|
|||
|
||||
#include "llimageworker.h"
|
||||
#include "llimagedxt.h"
|
||||
#include "threadpool.h"
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
class ImageRequest
|
||||
{
|
||||
public:
|
||||
ImageRequest(const LLPointer<LLImageFormatted>& image,
|
||||
S32 discard, BOOL needs_aux,
|
||||
const LLPointer<LLImageDecodeThread::Responder>& responder);
|
||||
virtual ~ImageRequest();
|
||||
|
||||
/*virtual*/ bool processRequest();
|
||||
/*virtual*/ void finishRequest(bool completed);
|
||||
|
||||
private:
|
||||
// LLPointers stored in ImageRequest MUST be LLPointer instances rather
|
||||
// than references: we need to increment the refcount when storing these.
|
||||
// input
|
||||
LLPointer<LLImageFormatted> mFormattedImage;
|
||||
S32 mDiscardLevel;
|
||||
BOOL mNeedsAux;
|
||||
// output
|
||||
LLPointer<LLImageRaw> mDecodedImageRaw;
|
||||
LLPointer<LLImageRaw> mDecodedImageAux;
|
||||
BOOL mDecodedRaw;
|
||||
BOOL mDecodedAux;
|
||||
LLPointer<LLImageDecodeThread::Responder> mResponder;
|
||||
};
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
// MAIN THREAD
|
||||
LLImageDecodeThread::LLImageDecodeThread(bool threaded)
|
||||
: LLQueuedThread("imagedecode", threaded)
|
||||
LLImageDecodeThread::LLImageDecodeThread(bool /*threaded*/)
|
||||
{
|
||||
mCreationMutex = new LLMutex();
|
||||
mThreadPool.reset(new LL::ThreadPool("ImageDecode", 8));
|
||||
mThreadPool->start();
|
||||
}
|
||||
|
||||
//virtual
|
||||
LLImageDecodeThread::~LLImageDecodeThread()
|
||||
{
|
||||
delete mCreationMutex ;
|
||||
}
|
||||
{}
|
||||
|
||||
// MAIN THREAD
|
||||
// virtual
|
||||
S32 LLImageDecodeThread::update(F32 max_time_ms)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
|
||||
LLMutexLock lock(mCreationMutex);
|
||||
for (creation_list_t::iterator iter = mCreationList.begin();
|
||||
iter != mCreationList.end(); ++iter)
|
||||
{
|
||||
creation_info& info = *iter;
|
||||
ImageRequest* req = new ImageRequest(info.handle, info.image,
|
||||
info.priority, info.discard, info.needs_aux,
|
||||
info.responder);
|
||||
|
||||
bool res = addRequest(req);
|
||||
if (!res)
|
||||
{
|
||||
LL_ERRS() << "request added after LLLFSThread::cleanupClass()" << LL_ENDL;
|
||||
}
|
||||
}
|
||||
mCreationList.clear();
|
||||
S32 res = LLQueuedThread::update(max_time_ms);
|
||||
return res;
|
||||
return getPending();
|
||||
}
|
||||
|
||||
LLImageDecodeThread::handle_t LLImageDecodeThread::decodeImage(LLImageFormatted* image,
|
||||
U32 priority, S32 discard, BOOL needs_aux, Responder* responder)
|
||||
S32 LLImageDecodeThread::getPending()
|
||||
{
|
||||
return mThreadPool->getQueue().size();
|
||||
}
|
||||
|
||||
LLImageDecodeThread::handle_t LLImageDecodeThread::decodeImage(
|
||||
const LLPointer<LLImageFormatted>& image,
|
||||
S32 discard,
|
||||
BOOL needs_aux,
|
||||
const LLPointer<LLImageDecodeThread::Responder>& responder)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
|
||||
LLMutexLock lock(mCreationMutex);
|
||||
handle_t handle = generateHandle();
|
||||
mCreationList.push_back(creation_info(handle, image, priority, discard, needs_aux, responder));
|
||||
return handle;
|
||||
|
||||
// Instantiate the ImageRequest right in the lambda, why not?
|
||||
mThreadPool->getQueue().post(
|
||||
[req = ImageRequest(image, discard, needs_aux, responder)]
|
||||
() mutable
|
||||
{
|
||||
auto done = req.processRequest();
|
||||
req.finishRequest(done);
|
||||
});
|
||||
|
||||
// It's important to our consumer (LLTextureFetchWorker) that we return a
|
||||
// nonzero handle. It is NOT important that the nonzero handle be unique:
|
||||
// nothing is ever done with it except to compare it to zero, or zero it.
|
||||
return 17;
|
||||
}
|
||||
|
||||
// Used by unit test only
|
||||
// Returns the size of the mutex guarded list as an indication of sanity
|
||||
S32 LLImageDecodeThread::tut_size()
|
||||
void LLImageDecodeThread::shutdown()
|
||||
{
|
||||
LLMutexLock lock(mCreationMutex);
|
||||
S32 res = mCreationList.size();
|
||||
return res;
|
||||
mThreadPool->close();
|
||||
}
|
||||
|
||||
LLImageDecodeThread::Responder::~Responder()
|
||||
|
|
@ -94,11 +118,10 @@ LLImageDecodeThread::Responder::~Responder()
|
|||
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
LLImageDecodeThread::ImageRequest::ImageRequest(handle_t handle, LLImageFormatted* image,
|
||||
U32 priority, S32 discard, BOOL needs_aux,
|
||||
LLImageDecodeThread::Responder* responder)
|
||||
: LLQueuedThread::QueuedRequest(handle, priority, FLAG_AUTO_COMPLETE),
|
||||
mFormattedImage(image),
|
||||
ImageRequest::ImageRequest(const LLPointer<LLImageFormatted>& image,
|
||||
S32 discard, BOOL needs_aux,
|
||||
const LLPointer<LLImageDecodeThread::Responder>& responder)
|
||||
: mFormattedImage(image),
|
||||
mDiscardLevel(discard),
|
||||
mNeedsAux(needs_aux),
|
||||
mDecodedRaw(FALSE),
|
||||
|
|
@ -107,7 +130,7 @@ LLImageDecodeThread::ImageRequest::ImageRequest(handle_t handle, LLImageFormatte
|
|||
{
|
||||
}
|
||||
|
||||
LLImageDecodeThread::ImageRequest::~ImageRequest()
|
||||
ImageRequest::~ImageRequest()
|
||||
{
|
||||
mDecodedImageRaw = NULL;
|
||||
mDecodedImageAux = NULL;
|
||||
|
|
@ -118,10 +141,10 @@ LLImageDecodeThread::ImageRequest::~ImageRequest()
|
|||
|
||||
|
||||
// Returns true when done, whether or not decode was successful.
|
||||
bool LLImageDecodeThread::ImageRequest::processRequest()
|
||||
bool ImageRequest::processRequest()
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
|
||||
const F32 decode_time_slice = .1f;
|
||||
const F32 decode_time_slice = 0.f; //disable time slicing
|
||||
bool done = true;
|
||||
if (!mDecodedRaw && mFormattedImage.notNull())
|
||||
{
|
||||
|
|
@ -145,7 +168,7 @@ bool LLImageDecodeThread::ImageRequest::processRequest()
|
|||
mFormattedImage->getHeight(),
|
||||
mFormattedImage->getComponents());
|
||||
}
|
||||
done = mFormattedImage->decode(mDecodedImageRaw, decode_time_slice); // 1ms
|
||||
done = mFormattedImage->decode(mDecodedImageRaw, decode_time_slice);
|
||||
// some decoders are removing data when task is complete and there were errors
|
||||
mDecodedRaw = done && mDecodedImageRaw->getData();
|
||||
}
|
||||
|
|
@ -158,14 +181,14 @@ bool LLImageDecodeThread::ImageRequest::processRequest()
|
|||
mFormattedImage->getHeight(),
|
||||
1);
|
||||
}
|
||||
done = mFormattedImage->decodeChannels(mDecodedImageAux, decode_time_slice, 4, 4); // 1ms
|
||||
done = mFormattedImage->decodeChannels(mDecodedImageAux, decode_time_slice, 4, 4);
|
||||
mDecodedAux = done && mDecodedImageAux->getData();
|
||||
}
|
||||
|
||||
return done;
|
||||
}
|
||||
|
||||
void LLImageDecodeThread::ImageRequest::finishRequest(bool completed)
|
||||
void ImageRequest::finishRequest(bool completed)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
|
||||
if (mResponder.notNull())
|
||||
|
|
@ -175,10 +198,3 @@ void LLImageDecodeThread::ImageRequest::finishRequest(bool completed)
|
|||
}
|
||||
// Will automatically be deleted
|
||||
}
|
||||
|
||||
// Used by unit test only
|
||||
// Checks that a responder exists for this instance so that something can happen when completion is reached
|
||||
bool LLImageDecodeThread::ImageRequest::tut_isOK()
|
||||
{
|
||||
return mResponder.notNull();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,9 +29,13 @@
|
|||
|
||||
#include "llimage.h"
|
||||
#include "llpointer.h"
|
||||
#include "llworkerthread.h"
|
||||
|
||||
class LLImageDecodeThread : public LLQueuedThread
|
||||
namespace LL
|
||||
{
|
||||
class ThreadPool;
|
||||
} // namespace LL
|
||||
|
||||
class LLImageDecodeThread
|
||||
{
|
||||
public:
|
||||
class Responder : public LLThreadSafeRefCount
|
||||
|
|
@ -42,63 +46,24 @@ public:
|
|||
virtual void completed(bool success, LLImageRaw* raw, LLImageRaw* aux) = 0;
|
||||
};
|
||||
|
||||
class ImageRequest : public LLQueuedThread::QueuedRequest
|
||||
{
|
||||
protected:
|
||||
virtual ~ImageRequest(); // use deleteRequest()
|
||||
|
||||
public:
|
||||
ImageRequest(handle_t handle, LLImageFormatted* image,
|
||||
U32 priority, S32 discard, BOOL needs_aux,
|
||||
LLImageDecodeThread::Responder* responder);
|
||||
|
||||
/*virtual*/ bool processRequest();
|
||||
/*virtual*/ void finishRequest(bool completed);
|
||||
|
||||
// Used by unit tests to check the consitency of the request instance
|
||||
bool tut_isOK();
|
||||
|
||||
private:
|
||||
// input
|
||||
LLPointer<LLImageFormatted> mFormattedImage;
|
||||
S32 mDiscardLevel;
|
||||
BOOL mNeedsAux;
|
||||
// output
|
||||
LLPointer<LLImageRaw> mDecodedImageRaw;
|
||||
LLPointer<LLImageRaw> mDecodedImageAux;
|
||||
BOOL mDecodedRaw;
|
||||
BOOL mDecodedAux;
|
||||
LLPointer<LLImageDecodeThread::Responder> mResponder;
|
||||
};
|
||||
|
||||
public:
|
||||
LLImageDecodeThread(bool threaded = true);
|
||||
virtual ~LLImageDecodeThread();
|
||||
|
||||
handle_t decodeImage(LLImageFormatted* image,
|
||||
U32 priority, S32 discard, BOOL needs_aux,
|
||||
Responder* responder);
|
||||
// meant to resemble LLQueuedThread::handle_t
|
||||
typedef U32 handle_t;
|
||||
handle_t decodeImage(const LLPointer<LLImageFormatted>& image,
|
||||
S32 discard, BOOL needs_aux,
|
||||
const LLPointer<Responder>& responder);
|
||||
S32 getPending();
|
||||
S32 update(F32 max_time_ms);
|
||||
void shutdown();
|
||||
|
||||
// Used by unit tests to check the consistency of the thread instance
|
||||
S32 tut_size();
|
||||
|
||||
private:
|
||||
struct creation_info
|
||||
{
|
||||
handle_t handle;
|
||||
LLPointer<LLImageFormatted> image;
|
||||
U32 priority;
|
||||
S32 discard;
|
||||
BOOL needs_aux;
|
||||
LLPointer<Responder> responder;
|
||||
creation_info(handle_t h, LLImageFormatted* i, U32 p, S32 d, BOOL aux, Responder* r)
|
||||
: handle(h), image(i), priority(p), discard(d), needs_aux(aux), responder(r)
|
||||
{}
|
||||
};
|
||||
typedef std::list<creation_info> creation_list_t;
|
||||
creation_list_t mCreationList;
|
||||
LLMutex* mCreationMutex;
|
||||
// As of SL-17483, LLImageDecodeThread is no longer itself an
|
||||
// LLQueuedThread - instead this is the API by which we submit work to the
|
||||
// "ImageDecode" ThreadPool.
|
||||
std::unique_ptr<LL::ThreadPool> mThreadPool;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -125,42 +125,11 @@ namespace tut
|
|||
}
|
||||
};
|
||||
|
||||
// Test wrapper declaration : image worker
|
||||
// Note: this class is not meant to be instantiated outside an LLImageDecodeThread instance
|
||||
// but it's not a bad idea to get its public API a good shake as part of a thorough unit test set.
|
||||
// Some gotcha with the destructor though (see below).
|
||||
struct imagerequest_test
|
||||
{
|
||||
// Instance to be tested
|
||||
LLImageDecodeThread::ImageRequest* mRequest;
|
||||
bool done;
|
||||
|
||||
// Constructor and destructor of the test wrapper
|
||||
imagerequest_test()
|
||||
{
|
||||
done = false;
|
||||
|
||||
mRequest = new LLImageDecodeThread::ImageRequest(0, 0,
|
||||
LLQueuedThread::PRIORITY_NORMAL, 0, FALSE,
|
||||
new responder_test(&done));
|
||||
}
|
||||
~imagerequest_test()
|
||||
{
|
||||
// We should delete the object *but*, because its destructor is protected, that cannot be
|
||||
// done from outside an LLImageDecodeThread instance... So we leak memory here... It's fine...
|
||||
//delete mRequest;
|
||||
}
|
||||
};
|
||||
|
||||
// Tut templating thingamagic: test group, object and test instance
|
||||
typedef test_group<imagedecodethread_test> imagedecodethread_t;
|
||||
typedef imagedecodethread_t::object imagedecodethread_object_t;
|
||||
tut::imagedecodethread_t tut_imagedecodethread("LLImageDecodeThread");
|
||||
|
||||
typedef test_group<imagerequest_test> imagerequest_t;
|
||||
typedef imagerequest_t::object imagerequest_object_t;
|
||||
tut::imagerequest_t tut_imagerequest("LLImageRequest");
|
||||
|
||||
// ---------------------------------------------------------------------------------------
|
||||
// Test functions
|
||||
// Notes:
|
||||
|
|
@ -172,64 +141,18 @@ namespace tut
|
|||
// ---------------------------------------------------------------------------------------
|
||||
// Test the LLImageDecodeThread interface
|
||||
// ---------------------------------------------------------------------------------------
|
||||
//
|
||||
// Note on Unit Testing Queued Thread Classes
|
||||
//
|
||||
// Since methods on such a class are called on a separate loop and that we can't insert tut
|
||||
// ensure() calls in there, we exercise the class with 2 sets of tests:
|
||||
// - 1: Test as a single threaded instance: We declare the class but ask for no thread
|
||||
// to be spawned (easy with LLThreads since there's a boolean argument on the constructor
|
||||
// just for that). We can then unit test each public method like we do on a normal class.
|
||||
// - 2: Test as a threaded instance: We let the thread launch and check that its external
|
||||
// behavior is as expected (i.e. it runs, can accept a work order and processes
|
||||
// it). Typically though there's no guarantee that this exercises all the methods of the
|
||||
// class which is why we also need the previous "non threaded" set of unit tests for
|
||||
// complete coverage.
|
||||
//
|
||||
// ---------------------------------------------------------------------------------------
|
||||
|
||||
template<> template<>
|
||||
void imagedecodethread_object_t::test<1>()
|
||||
{
|
||||
// Test a *non threaded* instance of the class
|
||||
mThread = new LLImageDecodeThread(false);
|
||||
ensure("LLImageDecodeThread: non threaded constructor failed", mThread != NULL);
|
||||
// Test that we start with an empty list right at creation
|
||||
ensure("LLImageDecodeThread: non threaded init state incorrect", mThread->tut_size() == 0);
|
||||
// Insert something in the queue
|
||||
bool done = false;
|
||||
LLImageDecodeThread::handle_t decodeHandle = mThread->decodeImage(NULL, LLQueuedThread::PRIORITY_NORMAL, 0, FALSE, new responder_test(&done));
|
||||
// Verifies we got a valid handle
|
||||
ensure("LLImageDecodeThread: non threaded decodeImage(), returned handle is null", decodeHandle != 0);
|
||||
// Verifies that we do now have something in the queued list
|
||||
ensure("LLImageDecodeThread: non threaded decodeImage() insertion in threaded list failed", mThread->tut_size() == 1);
|
||||
// Trigger queue handling "manually" (on a threaded instance, this is done on the thread loop)
|
||||
S32 res = mThread->update(0);
|
||||
// Verifies that we successfully handled the list
|
||||
ensure("LLImageDecodeThread: non threaded update() list handling test failed", res == 0);
|
||||
// Verifies that the list is now empty
|
||||
ensure("LLImageDecodeThread: non threaded update() list emptying test failed", mThread->tut_size() == 0);
|
||||
}
|
||||
|
||||
template<> template<>
|
||||
void imagedecodethread_object_t::test<2>()
|
||||
{
|
||||
// Test a *threaded* instance of the class
|
||||
mThread = new LLImageDecodeThread(true);
|
||||
ensure("LLImageDecodeThread: threaded constructor failed", mThread != NULL);
|
||||
// Test that we start with an empty list right at creation
|
||||
ensure("LLImageDecodeThread: threaded init state incorrect", mThread->tut_size() == 0);
|
||||
// Insert something in the queue
|
||||
bool done = false;
|
||||
LLImageDecodeThread::handle_t decodeHandle = mThread->decodeImage(NULL, LLQueuedThread::PRIORITY_NORMAL, 0, FALSE, new responder_test(&done));
|
||||
LLImageDecodeThread::handle_t decodeHandle = mThread->decodeImage(NULL, 0, FALSE, new responder_test(&done));
|
||||
// Verifies we get back a valid handle
|
||||
ensure("LLImageDecodeThread: threaded decodeImage(), returned handle is null", decodeHandle != 0);
|
||||
// Wait a little so to simulate the main thread doing something on its main loop...
|
||||
ms_sleep(500); // 500 milliseconds
|
||||
// Verifies that the responder has *not* been called yet in the meantime
|
||||
ensure("LLImageDecodeThread: responder creation failed", done == false);
|
||||
// Ask the thread to update: that means tells the queue to check itself and creates work requests
|
||||
mThread->update(1);
|
||||
// Wait till the thread has time to handle the work order (though it doesn't do much per work order...)
|
||||
const U32 INCREMENT_TIME = 500; // 500 milliseconds
|
||||
const U32 MAX_TIME = 20 * INCREMENT_TIME; // Do the loop 20 times max, i.e. wait 10 seconds but no more
|
||||
|
|
@ -242,24 +165,4 @@ namespace tut
|
|||
// Verifies that the responder has now been called
|
||||
ensure("LLImageDecodeThread: threaded work unit not processed", done == true);
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------------------
|
||||
// Test the LLImageDecodeThread::ImageRequest interface
|
||||
// ---------------------------------------------------------------------------------------
|
||||
|
||||
template<> template<>
|
||||
void imagerequest_object_t::test<1>()
|
||||
{
|
||||
// Test that we start with a correct request at creation
|
||||
ensure("LLImageDecodeThread::ImageRequest::ImageRequest() constructor test failed", mRequest->tut_isOK());
|
||||
bool res = mRequest->processRequest();
|
||||
// Verifies that we processed the request successfully
|
||||
ensure("LLImageDecodeThread::ImageRequest::processRequest() processing request test failed", res == true);
|
||||
// Check that we can call the finishing call safely
|
||||
try {
|
||||
mRequest->finishRequest(false);
|
||||
} catch (...) {
|
||||
fail("LLImageDecodeThread::ImageRequest::finishRequest() test failed");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -118,6 +118,7 @@ bool LLImageJ2COJ::initEncode(LLImageJ2C &base, LLImageRaw &raw_image, int block
|
|||
|
||||
bool LLImageJ2COJ::decodeImpl(LLImageJ2C &base, LLImageRaw &raw_image, F32 decode_time, S32 first_channel, S32 max_channel_count)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
|
||||
//
|
||||
// FIXME: Get the comment field out of the texture
|
||||
//
|
||||
|
|
|
|||
|
|
@ -379,6 +379,7 @@ void LLImageJ2CKDU::setupCodeStream(LLImageJ2C &base, bool keep_codestream, ECod
|
|||
|
||||
void LLImageJ2CKDU::cleanupCodeStream()
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
|
||||
mInputp.reset();
|
||||
mDecodeState.reset();
|
||||
mCodeStreamp.reset();
|
||||
|
|
@ -426,6 +427,7 @@ bool LLImageJ2CKDU::initEncode(LLImageJ2C &base, LLImageRaw &raw_image, int bloc
|
|||
// decodeImpl() usage matters for production.
|
||||
bool LLImageJ2CKDU::initDecode(LLImageJ2C &base, LLImageRaw &raw_image, F32 decode_time, ECodeStreamMode mode, S32 first_channel, S32 max_channel_count, int discard_level, int* region)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
|
||||
base.resetLastError();
|
||||
|
||||
// *FIX: kdu calls our callback function if there's an error, and then bombs.
|
||||
|
|
@ -509,6 +511,7 @@ bool LLImageJ2CKDU::initDecode(LLImageJ2C &base, LLImageRaw &raw_image, F32 deco
|
|||
// Returns true to mean done, whether successful or not.
|
||||
bool LLImageJ2CKDU::decodeImpl(LLImageJ2C &base, LLImageRaw &raw_image, F32 decode_time, S32 first_channel, S32 max_channel_count)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
|
||||
ECodeStreamMode mode = MODE_FAST;
|
||||
|
||||
LLTimer decode_timer;
|
||||
|
|
@ -1332,6 +1335,7 @@ the `buf' pointer may actually point into a larger buffer representing
|
|||
multiple tiles. For this reason, `row_gap' is needed to identify the
|
||||
separation between consecutive rows in the real buffer. */
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
|
||||
S32 c;
|
||||
// Now walk through the lines of the buffer, recovering them from the
|
||||
// relevant tile-component processing engines.
|
||||
|
|
@ -1339,18 +1343,27 @@ separation between consecutive rows in the real buffer. */
|
|||
LLTimer decode_timer;
|
||||
while (mDims.size.y--)
|
||||
{
|
||||
for (c = 0; c < mNumComponents; c++)
|
||||
{
|
||||
mEngines[c].pull(mLines[c]);
|
||||
}
|
||||
{
|
||||
LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("kduptc - pull");
|
||||
for (c = 0; c < mNumComponents; c++)
|
||||
{
|
||||
mEngines[c].pull(mLines[c]);
|
||||
}
|
||||
}
|
||||
|
||||
if ((mNumComponents >= 3) && mUseYCC)
|
||||
{
|
||||
LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("kduptc - convert");
|
||||
kdu_convert_ycc_to_rgb(mLines[0],mLines[1],mLines[2]);
|
||||
}
|
||||
for (c = 0; c < mNumComponents; c++)
|
||||
{
|
||||
transfer_bytes(mBuf+c,mLines[c],mNumComponents,mBitDepths[c]);
|
||||
}
|
||||
|
||||
{
|
||||
LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("kduptc - transfer");
|
||||
for (c = 0; c < mNumComponents; c++)
|
||||
{
|
||||
transfer_bytes(mBuf + c, mLines[c], mNumComponents, mBitDepths[c]);
|
||||
}
|
||||
}
|
||||
mBuf += mRowGap;
|
||||
if (mDims.size.y % 10)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -64,7 +64,6 @@ LLCore::HttpRequest::ptr_t sHttpRequest;
|
|||
LLCore::HttpHeaders::ptr_t sHttpHeaders;
|
||||
LLCore::HttpOptions::ptr_t sHttpOptions;
|
||||
LLCore::HttpRequest::policy_t sHttpPolicy;
|
||||
LLCore::HttpRequest::priority_t sHttpPriority;
|
||||
|
||||
/* Sample response:
|
||||
<?xml version="1.0"?>
|
||||
|
|
@ -121,7 +120,6 @@ LLAvatarNameCache::LLAvatarNameCache()
|
|||
sHttpHeaders = LLCore::HttpHeaders::ptr_t(new LLCore::HttpHeaders());
|
||||
sHttpOptions = LLCore::HttpOptions::ptr_t(new LLCore::HttpOptions());
|
||||
sHttpPolicy = LLCore::HttpRequest::DEFAULT_POLICY_ID;
|
||||
sHttpPriority = 0;
|
||||
}
|
||||
|
||||
LLAvatarNameCache::~LLAvatarNameCache()
|
||||
|
|
|
|||
|
|
@ -131,7 +131,6 @@ bool responseToLLSD(HttpResponse * response, bool log, LLSD & out_llsd)
|
|||
|
||||
HttpHandle requestPostWithLLSD(HttpRequest * request,
|
||||
HttpRequest::policy_t policy_id,
|
||||
HttpRequest::priority_t priority,
|
||||
const std::string & url,
|
||||
const LLSD & body,
|
||||
const HttpOptions::ptr_t &options,
|
||||
|
|
@ -145,7 +144,6 @@ HttpHandle requestPostWithLLSD(HttpRequest * request,
|
|||
LLSDSerialize::toXML(body, bas);
|
||||
|
||||
handle = request->requestPost(policy_id,
|
||||
priority,
|
||||
url,
|
||||
ba,
|
||||
options,
|
||||
|
|
@ -158,7 +156,6 @@ HttpHandle requestPostWithLLSD(HttpRequest * request,
|
|||
|
||||
HttpHandle requestPutWithLLSD(HttpRequest * request,
|
||||
HttpRequest::policy_t policy_id,
|
||||
HttpRequest::priority_t priority,
|
||||
const std::string & url,
|
||||
const LLSD & body,
|
||||
const HttpOptions::ptr_t &options,
|
||||
|
|
@ -172,7 +169,6 @@ HttpHandle requestPutWithLLSD(HttpRequest * request,
|
|||
LLSDSerialize::toXML(body, bas);
|
||||
|
||||
handle = request->requestPut(policy_id,
|
||||
priority,
|
||||
url,
|
||||
ba,
|
||||
options,
|
||||
|
|
@ -184,7 +180,6 @@ HttpHandle requestPutWithLLSD(HttpRequest * request,
|
|||
|
||||
HttpHandle requestPatchWithLLSD(HttpRequest * request,
|
||||
HttpRequest::policy_t policy_id,
|
||||
HttpRequest::priority_t priority,
|
||||
const std::string & url,
|
||||
const LLSD & body,
|
||||
const HttpOptions::ptr_t &options,
|
||||
|
|
@ -198,7 +193,6 @@ HttpHandle requestPatchWithLLSD(HttpRequest * request,
|
|||
LLSDSerialize::toXML(body, bas);
|
||||
|
||||
handle = request->requestPatch(policy_id,
|
||||
priority,
|
||||
url,
|
||||
ba,
|
||||
options,
|
||||
|
|
@ -672,10 +666,9 @@ const std::string HttpCoroutineAdapter::HTTP_RESULTS_CONTENT("content");
|
|||
const std::string HttpCoroutineAdapter::HTTP_RESULTS_RAW("raw");
|
||||
|
||||
HttpCoroutineAdapter::HttpCoroutineAdapter(const std::string &name,
|
||||
LLCore::HttpRequest::policy_t policyId, LLCore::HttpRequest::priority_t priority) :
|
||||
LLCore::HttpRequest::policy_t policyId) :
|
||||
mAdapterName(name),
|
||||
mPolicyId(policyId),
|
||||
mPriority(priority),
|
||||
mYieldingHandle(LLCORE_HTTP_HANDLE_INVALID),
|
||||
mWeakRequest(),
|
||||
mWeakHandler()
|
||||
|
|
@ -709,7 +702,7 @@ LLSD HttpCoroutineAdapter::postAndSuspend_(LLCore::HttpRequest::ptr_t &request,
|
|||
// The HTTPCoroHandler does not self delete, so retrieval of a the contained
|
||||
// pointer from the smart pointer is safe in this case.
|
||||
LLCore::HttpHandle hhandle = requestPostWithLLSD(request,
|
||||
mPolicyId, mPriority, url, body, options, headers,
|
||||
mPolicyId, url, body, options, headers,
|
||||
handler);
|
||||
|
||||
if (hhandle == LLCORE_HTTP_HANDLE_INVALID)
|
||||
|
|
@ -832,7 +825,7 @@ LLSD HttpCoroutineAdapter::postAndSuspend_(LLCore::HttpRequest::ptr_t &request,
|
|||
|
||||
// The HTTPCoroHandler does not self delete, so retrieval of a the contained
|
||||
// pointer from the smart pointer is safe in this case.
|
||||
LLCore::HttpHandle hhandle = request->requestPost(mPolicyId, mPriority, url, rawbody.get(),
|
||||
LLCore::HttpHandle hhandle = request->requestPost(mPolicyId, url, rawbody.get(),
|
||||
options, headers, handler);
|
||||
|
||||
if (hhandle == LLCORE_HTTP_HANDLE_INVALID)
|
||||
|
|
@ -890,7 +883,7 @@ LLSD HttpCoroutineAdapter::putAndSuspend_(LLCore::HttpRequest::ptr_t &request,
|
|||
// The HTTPCoroHandler does not self delete, so retrieval of a the contained
|
||||
// pointer from the smart pointer is safe in this case.
|
||||
LLCore::HttpHandle hhandle = requestPutWithLLSD(request,
|
||||
mPolicyId, mPriority, url, body, options, headers,
|
||||
mPolicyId, url, body, options, headers,
|
||||
handler);
|
||||
|
||||
if (hhandle == LLCORE_HTTP_HANDLE_INVALID)
|
||||
|
|
@ -916,7 +909,7 @@ LLSD HttpCoroutineAdapter::putAndSuspend_(LLCore::HttpRequest::ptr_t &request,
|
|||
|
||||
// The HTTPCoroHandler does not self delete, so retrieval of a the contained
|
||||
// pointer from the smart pointer is safe in this case.
|
||||
LLCore::HttpHandle hhandle = request->requestPut(mPolicyId, mPriority,
|
||||
LLCore::HttpHandle hhandle = request->requestPut(mPolicyId,
|
||||
url, rawbody.get(), options, headers, handler);
|
||||
|
||||
if (hhandle == LLCORE_HTTP_HANDLE_INVALID)
|
||||
|
|
@ -972,7 +965,7 @@ LLSD HttpCoroutineAdapter::getAndSuspend_(LLCore::HttpRequest::ptr_t &request,
|
|||
|
||||
// The HTTPCoroHandler does not self delete, so retrieval of a the contained
|
||||
// pointer from the smart pointer is safe in this case.
|
||||
LLCore::HttpHandle hhandle = request->requestGet(mPolicyId, mPriority,
|
||||
LLCore::HttpHandle hhandle = request->requestGet(mPolicyId,
|
||||
url, options, headers, handler);
|
||||
|
||||
if (hhandle == LLCORE_HTTP_HANDLE_INVALID)
|
||||
|
|
@ -1018,7 +1011,7 @@ LLSD HttpCoroutineAdapter::deleteAndSuspend_(LLCore::HttpRequest::ptr_t &request
|
|||
checkDefaultHeaders(headers);
|
||||
// The HTTPCoroHandler does not self delete, so retrieval of a the contained
|
||||
// pointer from the smart pointer is safe in this case.
|
||||
LLCore::HttpHandle hhandle = request->requestDelete(mPolicyId, mPriority,
|
||||
LLCore::HttpHandle hhandle = request->requestDelete(mPolicyId,
|
||||
url, options, headers, handler);
|
||||
|
||||
if (hhandle == LLCORE_HTTP_HANDLE_INVALID)
|
||||
|
|
@ -1056,7 +1049,7 @@ LLSD HttpCoroutineAdapter::patchAndSuspend_(LLCore::HttpRequest::ptr_t &request,
|
|||
// The HTTPCoroHandler does not self delete, so retrieval of a the contained
|
||||
// pointer from the smart pointer is safe in this case.
|
||||
LLCore::HttpHandle hhandle = requestPatchWithLLSD(request,
|
||||
mPolicyId, mPriority, url, body, options, headers,
|
||||
mPolicyId, url, body, options, headers,
|
||||
handler);
|
||||
|
||||
if (hhandle == LLCORE_HTTP_HANDLE_INVALID)
|
||||
|
|
@ -1098,7 +1091,7 @@ LLSD HttpCoroutineAdapter::copyAndSuspend_(LLCore::HttpRequest::ptr_t &request,
|
|||
// The HTTPCoroHandler does not self delete, so retrieval of a the contained
|
||||
// pointer from the smart pointer is safe in this case.
|
||||
//
|
||||
LLCore::HttpHandle hhandle = request->requestCopy(mPolicyId, mPriority, url,
|
||||
LLCore::HttpHandle hhandle = request->requestCopy(mPolicyId, url,
|
||||
options, headers, handler);
|
||||
|
||||
if (hhandle == LLCORE_HTTP_HANDLE_INVALID)
|
||||
|
|
@ -1140,7 +1133,7 @@ LLSD HttpCoroutineAdapter::moveAndSuspend_(LLCore::HttpRequest::ptr_t &request,
|
|||
// The HTTPCoroHandler does not self delete, so retrieval of a the contained
|
||||
// pointer from the smart pointer is safe in this case.
|
||||
//
|
||||
LLCore::HttpHandle hhandle = request->requestMove(mPolicyId, mPriority, url,
|
||||
LLCore::HttpHandle hhandle = request->requestMove(mPolicyId, url,
|
||||
options, headers, handler);
|
||||
|
||||
if (hhandle == LLCORE_HTTP_HANDLE_INVALID)
|
||||
|
|
|
|||
|
|
@ -116,7 +116,6 @@ std::string responseToString(LLCore::HttpResponse * response);
|
|||
///
|
||||
LLCore::HttpHandle requestPostWithLLSD(LLCore::HttpRequest * request,
|
||||
LLCore::HttpRequest::policy_t policy_id,
|
||||
LLCore::HttpRequest::priority_t priority,
|
||||
const std::string & url,
|
||||
const LLSD & body,
|
||||
const LLCore::HttpOptions::ptr_t &options,
|
||||
|
|
@ -125,20 +124,18 @@ LLCore::HttpHandle requestPostWithLLSD(LLCore::HttpRequest * request,
|
|||
|
||||
inline LLCore::HttpHandle requestPostWithLLSD(LLCore::HttpRequest::ptr_t & request,
|
||||
LLCore::HttpRequest::policy_t policy_id,
|
||||
LLCore::HttpRequest::priority_t priority,
|
||||
const std::string & url,
|
||||
const LLSD & body,
|
||||
const LLCore::HttpOptions::ptr_t & options,
|
||||
const LLCore::HttpHeaders::ptr_t & headers,
|
||||
const LLCore::HttpHandler::ptr_t & handler)
|
||||
{
|
||||
return requestPostWithLLSD(request.get(), policy_id, priority,
|
||||
return requestPostWithLLSD(request.get(), policy_id,
|
||||
url, body, options, headers, handler);
|
||||
}
|
||||
|
||||
inline LLCore::HttpHandle requestPostWithLLSD(LLCore::HttpRequest::ptr_t & request,
|
||||
LLCore::HttpRequest::policy_t policy_id,
|
||||
LLCore::HttpRequest::priority_t priority,
|
||||
const std::string & url,
|
||||
const LLSD & body,
|
||||
const LLCore::HttpHandler::ptr_t &handler)
|
||||
|
|
@ -146,7 +143,7 @@ inline LLCore::HttpHandle requestPostWithLLSD(LLCore::HttpRequest::ptr_t & reque
|
|||
LLCore::HttpOptions::ptr_t options;
|
||||
LLCore::HttpHeaders::ptr_t headers;
|
||||
|
||||
return requestPostWithLLSD(request.get(), policy_id, priority,
|
||||
return requestPostWithLLSD(request.get(), policy_id,
|
||||
url, body, options, headers, handler);
|
||||
}
|
||||
|
||||
|
|
@ -169,7 +166,6 @@ inline LLCore::HttpHandle requestPostWithLLSD(LLCore::HttpRequest::ptr_t & reque
|
|||
///
|
||||
LLCore::HttpHandle requestPutWithLLSD(LLCore::HttpRequest * request,
|
||||
LLCore::HttpRequest::policy_t policy_id,
|
||||
LLCore::HttpRequest::priority_t priority,
|
||||
const std::string & url,
|
||||
const LLSD & body,
|
||||
const LLCore::HttpOptions::ptr_t &options,
|
||||
|
|
@ -178,20 +174,18 @@ LLCore::HttpHandle requestPutWithLLSD(LLCore::HttpRequest * request,
|
|||
|
||||
inline LLCore::HttpHandle requestPutWithLLSD(LLCore::HttpRequest::ptr_t & request,
|
||||
LLCore::HttpRequest::policy_t policy_id,
|
||||
LLCore::HttpRequest::priority_t priority,
|
||||
const std::string & url,
|
||||
const LLSD & body,
|
||||
const LLCore::HttpOptions::ptr_t & options,
|
||||
const LLCore::HttpHeaders::ptr_t & headers,
|
||||
LLCore::HttpHandler::ptr_t handler)
|
||||
{
|
||||
return requestPutWithLLSD(request.get(), policy_id, priority,
|
||||
return requestPutWithLLSD(request.get(), policy_id,
|
||||
url, body, options, headers, handler);
|
||||
}
|
||||
|
||||
inline LLCore::HttpHandle requestPutWithLLSD(LLCore::HttpRequest::ptr_t & request,
|
||||
LLCore::HttpRequest::policy_t policy_id,
|
||||
LLCore::HttpRequest::priority_t priority,
|
||||
const std::string & url,
|
||||
const LLSD & body,
|
||||
LLCore::HttpHandler::ptr_t handler)
|
||||
|
|
@ -199,7 +193,7 @@ inline LLCore::HttpHandle requestPutWithLLSD(LLCore::HttpRequest::ptr_t & reques
|
|||
LLCore::HttpOptions::ptr_t options;
|
||||
LLCore::HttpHeaders::ptr_t headers;
|
||||
|
||||
return requestPutWithLLSD(request.get(), policy_id, priority,
|
||||
return requestPutWithLLSD(request.get(), policy_id,
|
||||
url, body, options, headers, handler);
|
||||
}
|
||||
|
||||
|
|
@ -221,7 +215,6 @@ inline LLCore::HttpHandle requestPutWithLLSD(LLCore::HttpRequest::ptr_t & reques
|
|||
///
|
||||
LLCore::HttpHandle requestPatchWithLLSD(LLCore::HttpRequest * request,
|
||||
LLCore::HttpRequest::policy_t policy_id,
|
||||
LLCore::HttpRequest::priority_t priority,
|
||||
const std::string & url,
|
||||
const LLSD & body,
|
||||
const LLCore::HttpOptions::ptr_t &options,
|
||||
|
|
@ -230,20 +223,18 @@ LLCore::HttpHandle requestPatchWithLLSD(LLCore::HttpRequest * request,
|
|||
|
||||
inline LLCore::HttpHandle requestPatchWithLLSD(LLCore::HttpRequest::ptr_t & request,
|
||||
LLCore::HttpRequest::policy_t policy_id,
|
||||
LLCore::HttpRequest::priority_t priority,
|
||||
const std::string & url,
|
||||
const LLSD & body,
|
||||
const LLCore::HttpOptions::ptr_t & options,
|
||||
const LLCore::HttpHeaders::ptr_t & headers,
|
||||
const LLCore::HttpHandler::ptr_t & handler)
|
||||
{
|
||||
return requestPatchWithLLSD(request.get(), policy_id, priority,
|
||||
return requestPatchWithLLSD(request.get(), policy_id,
|
||||
url, body, options, headers, handler);
|
||||
}
|
||||
|
||||
inline LLCore::HttpHandle requestPatchWithLLSD(LLCore::HttpRequest::ptr_t & request,
|
||||
LLCore::HttpRequest::policy_t policy_id,
|
||||
LLCore::HttpRequest::priority_t priority,
|
||||
const std::string & url,
|
||||
const LLSD & body,
|
||||
const LLCore::HttpHandler::ptr_t &handler)
|
||||
|
|
@ -251,7 +242,7 @@ inline LLCore::HttpHandle requestPatchWithLLSD(LLCore::HttpRequest::ptr_t & requ
|
|||
LLCore::HttpOptions::ptr_t options;
|
||||
LLCore::HttpHeaders::ptr_t headers;
|
||||
|
||||
return requestPatchWithLLSD(request.get(), policy_id, priority,
|
||||
return requestPatchWithLLSD(request.get(), policy_id,
|
||||
url, body, options, headers, handler);
|
||||
}
|
||||
|
||||
|
|
@ -329,8 +320,7 @@ public:
|
|||
typedef boost::shared_ptr<HttpCoroutineAdapter> ptr_t;
|
||||
typedef boost::weak_ptr<HttpCoroutineAdapter> wptr_t;
|
||||
|
||||
HttpCoroutineAdapter(const std::string &name, LLCore::HttpRequest::policy_t policyId,
|
||||
LLCore::HttpRequest::priority_t priority = 0L);
|
||||
HttpCoroutineAdapter(const std::string &name, LLCore::HttpRequest::policy_t policyId);
|
||||
~HttpCoroutineAdapter();
|
||||
|
||||
/// Execute a Post transaction on the supplied URL and yield execution of
|
||||
|
|
@ -673,7 +663,6 @@ private:
|
|||
void checkDefaultHeaders(LLCore::HttpHeaders::ptr_t &headers);
|
||||
|
||||
std::string mAdapterName;
|
||||
LLCore::HttpRequest::priority_t mPriority;
|
||||
LLCore::HttpRequest::policy_t mPolicyId;
|
||||
|
||||
LLCore::HttpHandle mYieldingHandle;
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@
|
|||
#pragma warning(disable: 4702)
|
||||
#endif
|
||||
|
||||
LLCoreHttpUtil::HttpCoroutineAdapter::HttpCoroutineAdapter(std::string const&, unsigned int, unsigned int)
|
||||
LLCoreHttpUtil::HttpCoroutineAdapter::HttpCoroutineAdapter(std::string const&, unsigned int)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -53,13 +53,75 @@ const F32 MIN_TEXTURE_LIFETIME = 10.f;
|
|||
//assumes i is a power of 2 > 0
|
||||
U32 wpo2(U32 i);
|
||||
|
||||
|
||||
// texture memory accounting (for OS X)
|
||||
static LLMutex sTexMemMutex;
|
||||
static std::unordered_map<U32, U32> sTextureAllocs;
|
||||
static U64 sTextureBytes = 0;
|
||||
|
||||
// track a texture alloc on the currently bound texture.
|
||||
// asserts that no currently tracked alloc exists
|
||||
static void alloc_tex_image(U32 width, U32 height, U32 pixformat)
|
||||
{
|
||||
U32 texUnit = gGL.getCurrentTexUnitIndex();
|
||||
U32 texName = gGL.getTexUnit(texUnit)->getCurrTexture();
|
||||
S32 size = LLImageGL::dataFormatBytes(pixformat, width, height);
|
||||
|
||||
llassert(size >= 0);
|
||||
|
||||
sTexMemMutex.lock();
|
||||
llassert(sTextureAllocs.find(texName) == sTextureAllocs.end());
|
||||
|
||||
sTextureAllocs[texName] = size;
|
||||
sTextureBytes += size;
|
||||
|
||||
sTexMemMutex.unlock();
|
||||
}
|
||||
|
||||
// track texture free on given texName
|
||||
static void free_tex_image(U32 texName)
|
||||
{
|
||||
sTexMemMutex.lock();
|
||||
auto iter = sTextureAllocs.find(texName);
|
||||
if (iter != sTextureAllocs.end())
|
||||
{
|
||||
llassert(iter->second <= sTextureBytes); // sTextureBytes MUST NOT go below zero
|
||||
|
||||
sTextureBytes -= iter->second;
|
||||
|
||||
sTextureAllocs.erase(iter);
|
||||
}
|
||||
|
||||
sTexMemMutex.unlock();
|
||||
}
|
||||
|
||||
// track texture free on given texNames
|
||||
static void free_tex_images(U32 count, const U32* texNames)
|
||||
{
|
||||
for (int i = 0; i < count; ++i)
|
||||
{
|
||||
free_tex_image(texNames[i]);
|
||||
}
|
||||
}
|
||||
|
||||
// track texture free on currently bound texture
|
||||
static void free_cur_tex_image()
|
||||
{
|
||||
U32 texUnit = gGL.getCurrentTexUnitIndex();
|
||||
U32 texName = gGL.getTexUnit(texUnit)->getCurrTexture();
|
||||
free_tex_image(texName);
|
||||
}
|
||||
|
||||
// static
|
||||
U64 LLImageGL::getTextureBytesAllocated()
|
||||
{
|
||||
return sTextureBytes;
|
||||
}
|
||||
|
||||
//statics
|
||||
|
||||
U32 LLImageGL::sUniqueCount = 0;
|
||||
U32 LLImageGL::sBindCount = 0;
|
||||
S32Bytes LLImageGL::sGlobalTextureMemory(0);
|
||||
S32Bytes LLImageGL::sBoundTextureMemory(0);
|
||||
S32Bytes LLImageGL::sCurBoundTextureMemory(0);
|
||||
S32 LLImageGL::sCount = 0;
|
||||
|
||||
BOOL LLImageGL::sGlobalUseAnisotropic = FALSE;
|
||||
|
|
@ -220,6 +282,7 @@ S32 LLImageGL::dataFormatBits(S32 dataformat)
|
|||
case GL_RGBA: return 32;
|
||||
case GL_SRGB_ALPHA: return 32;
|
||||
case GL_BGRA: return 32; // Used for QuickTime media textures on the Mac
|
||||
case GL_DEPTH_COMPONENT: return 24;
|
||||
default:
|
||||
LL_ERRS() << "LLImageGL::Unknown format: " << dataformat << LL_ENDL;
|
||||
return 0;
|
||||
|
|
@ -282,15 +345,6 @@ void LLImageGL::updateStats(F32 current_time)
|
|||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
|
||||
sLastFrameTime = current_time;
|
||||
sBoundTextureMemory = sCurBoundTextureMemory;
|
||||
sCurBoundTextureMemory = S32Bytes(0);
|
||||
}
|
||||
|
||||
//static
|
||||
S32 LLImageGL::updateBoundTexMem(const S32Bytes mem, const S32 ncomponents, S32 category)
|
||||
{
|
||||
LLImageGL::sCurBoundTextureMemory += mem ;
|
||||
return LLImageGL::sCurBoundTextureMemory.value();
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
|
@ -623,7 +677,7 @@ void LLImageGL::forceUpdateBindStats(void) const
|
|||
mLastBindTime = sLastFrameTime;
|
||||
}
|
||||
|
||||
BOOL LLImageGL::updateBindStats(S32Bytes tex_mem) const
|
||||
BOOL LLImageGL::updateBindStats() const
|
||||
{
|
||||
if (mTexName != 0)
|
||||
{
|
||||
|
|
@ -635,7 +689,6 @@ BOOL LLImageGL::updateBindStats(S32Bytes tex_mem) const
|
|||
{
|
||||
// we haven't accounted for this texture yet this frame
|
||||
sUniqueCount++;
|
||||
updateBoundTexMem(tex_mem, mComponents, mCategory);
|
||||
mLastBindTime = sLastFrameTime;
|
||||
|
||||
return TRUE ;
|
||||
|
|
@ -1232,6 +1285,7 @@ void LLImageGL::deleteTextures(S32 numTextures, const U32 *textures)
|
|||
{
|
||||
if (gGLManager.mInited)
|
||||
{
|
||||
free_tex_images(numTextures, textures);
|
||||
glDeleteTextures(numTextures, textures);
|
||||
}
|
||||
}
|
||||
|
|
@ -1354,7 +1408,10 @@ void LLImageGL::setManualImage(U32 target, S32 miplevel, S32 intformat, S32 widt
|
|||
stop_glerror();
|
||||
{
|
||||
LL_PROFILE_ZONE_NAMED("glTexImage2D");
|
||||
|
||||
free_cur_tex_image();
|
||||
glTexImage2D(target, miplevel, intformat, width, height, 0, pixformat, pixtype, use_scratch ? scratch : pixels);
|
||||
alloc_tex_image(width, height, pixformat);
|
||||
}
|
||||
stop_glerror();
|
||||
|
||||
|
|
@ -1601,11 +1658,6 @@ BOOL LLImageGL::createGLTexture(S32 discard_level, const U8* data_in, BOOL data_
|
|||
// things will break if we don't unbind after creation
|
||||
gGL.getTexUnit(0)->unbind(mBindTarget);
|
||||
|
||||
if (old_texname != 0)
|
||||
{
|
||||
sGlobalTextureMemory -= mTextureMemory;
|
||||
}
|
||||
|
||||
//if we're on the image loading thread, be sure to delete old_texname and update mTexName on the main thread
|
||||
if (!defer_copy)
|
||||
{
|
||||
|
|
@ -1626,7 +1678,6 @@ BOOL LLImageGL::createGLTexture(S32 discard_level, const U8* data_in, BOOL data_
|
|||
|
||||
|
||||
mTextureMemory = (S32Bytes)getMipBytes(mCurrentDiscardLevel);
|
||||
sGlobalTextureMemory += mTextureMemory;
|
||||
mTexelsInGLTexture = getWidth() * getHeight();
|
||||
|
||||
// mark this as bound at this point, so we don't throw it out immediately
|
||||
|
|
@ -1636,51 +1687,6 @@ BOOL LLImageGL::createGLTexture(S32 discard_level, const U8* data_in, BOOL data_
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
void LLImageGLThread::updateClass()
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED;
|
||||
|
||||
// update available vram one per second
|
||||
static LLFrameTimer sTimer;
|
||||
|
||||
if (sTimer.getElapsedSeconds() < 1.f)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
sTimer.reset();
|
||||
|
||||
auto func = []()
|
||||
{
|
||||
if (gGLManager.mHasATIMemInfo)
|
||||
{
|
||||
S32 meminfo[4];
|
||||
glGetIntegerv(GL_TEXTURE_FREE_MEMORY_ATI, meminfo);
|
||||
LLImageGLThread::sFreeVRAMMegabytes = meminfo[0];
|
||||
|
||||
}
|
||||
else if (gGLManager.mHasNVXMemInfo)
|
||||
{
|
||||
S32 free_memory;
|
||||
glGetIntegerv(GL_GPU_MEMORY_INFO_CURRENT_AVAILABLE_VIDMEM_NVX, &free_memory);
|
||||
LLImageGLThread::sFreeVRAMMegabytes = free_memory / 1024;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// post update to background thread if available, otherwise execute immediately
|
||||
auto queue = LL::WorkQueue::getInstance("LLImageGL");
|
||||
if (sEnabled)
|
||||
{
|
||||
queue->post(func);
|
||||
}
|
||||
else
|
||||
{
|
||||
llassert(queue == nullptr);
|
||||
func();
|
||||
}
|
||||
}
|
||||
|
||||
void LLImageGL::syncToMainThread(LLGLuint new_tex_name)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED;
|
||||
|
|
@ -1874,7 +1880,6 @@ void LLImageGL::destroyGLTexture()
|
|||
{
|
||||
if(mTextureMemory != S32Bytes(0))
|
||||
{
|
||||
sGlobalTextureMemory -= mTextureMemory;
|
||||
mTextureMemory = (S32Bytes)0;
|
||||
}
|
||||
|
||||
|
|
@ -2426,13 +2431,9 @@ void LLImageGL::checkActiveThread()
|
|||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, nummips);
|
||||
*/
|
||||
|
||||
std::atomic<S32> LLImageGLThread::sFreeVRAMMegabytes(4096); //if free vram is unknown, default to 4GB
|
||||
|
||||
LLImageGLThread::LLImageGLThread(LLWindow* window)
|
||||
// We want exactly one thread, but a very large capacity: we never want
|
||||
// anyone, especially inner-loop render code, to have to block on post()
|
||||
// because we're full.
|
||||
: ThreadPool("LLImageGL", 1, 1024*1024)
|
||||
// We want exactly one thread.
|
||||
: ThreadPool("LLImageGL", 1)
|
||||
, mWindow(window)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
|
||||
|
|
@ -2455,8 +2456,3 @@ void LLImageGLThread::run()
|
|||
mWindow->destroySharedContext(mContext);
|
||||
}
|
||||
|
||||
S32 LLImageGLThread::getFreeVRAMMegabytes()
|
||||
{
|
||||
return sFreeVRAMMegabytes;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -52,6 +52,13 @@ class LLImageGL : public LLRefCount
|
|||
{
|
||||
friend class LLTexUnit;
|
||||
public:
|
||||
|
||||
// Get an estimate of how many bytes have been allocated in vram for textures.
|
||||
// Does not include mipmaps.
|
||||
// NOTE: multiplying this number by two gives a good estimate for total
|
||||
// video memory usage based on testing in lagland against an NVIDIA GPU.
|
||||
static U64 getTextureBytesAllocated();
|
||||
|
||||
// These 2 functions replace glGenTextures() and glDeleteTextures()
|
||||
static void generateTextures(S32 numTextures, U32 *textures);
|
||||
static void deleteTextures(S32 numTextures, const U32 *textures);
|
||||
|
|
@ -61,7 +68,7 @@ public:
|
|||
static S32 dataFormatBytes(S32 dataformat, S32 width, S32 height);
|
||||
static S32 dataFormatComponents(S32 dataformat);
|
||||
|
||||
BOOL updateBindStats(S32Bytes tex_mem) const ;
|
||||
BOOL updateBindStats() const ;
|
||||
F32 getTimePassedSinceLastBound();
|
||||
void forceUpdateBindStats(void) const;
|
||||
|
||||
|
|
@ -73,9 +80,6 @@ public:
|
|||
static void restoreGL();
|
||||
static void dirtyTexOptions();
|
||||
|
||||
// Sometimes called externally for textures not using LLImageGL (should go away...)
|
||||
static S32 updateBoundTexMem(const S32Bytes mem, const S32 ncomponents, S32 category) ;
|
||||
|
||||
static bool checkSize(S32 width, S32 height);
|
||||
|
||||
//for server side use only.
|
||||
|
|
@ -165,7 +169,7 @@ public:
|
|||
void updatePickMask(S32 width, S32 height, const U8* data_in);
|
||||
BOOL getMask(const LLVector2 &tc);
|
||||
|
||||
void checkTexSize(bool forced = false) const ;
|
||||
void checkTexSize(bool forced = false) const ;
|
||||
|
||||
// Sets the addressing mode used to sample the texture
|
||||
// (such as wrapping, mirrored wrapping, and clamp)
|
||||
|
|
@ -265,9 +269,6 @@ public:
|
|||
static F32 sLastFrameTime;
|
||||
|
||||
// Global memory statistics
|
||||
static S32Bytes sGlobalTextureMemory; // Tracks main memory texmem
|
||||
static S32Bytes sBoundTextureMemory; // Tracks bound texmem for last completed frame
|
||||
static S32Bytes sCurBoundTextureMemory; // Tracks bound texmem for current frame
|
||||
static U32 sBindCount; // Tracks number of texture binds for current frame
|
||||
static U32 sUniqueCount; // Tracks number of unique texture binds for current frame
|
||||
static BOOL sGlobalUseAnisotropic;
|
||||
|
|
@ -327,12 +328,6 @@ public:
|
|||
// follows gSavedSettings "RenderGLMultiThreaded"
|
||||
static bool sEnabled;
|
||||
|
||||
// app should call this function periodically
|
||||
static void updateClass();
|
||||
|
||||
// free video memory in megabytes
|
||||
static std::atomic<S32> sFreeVRAMMegabytes;
|
||||
|
||||
LLImageGLThread(LLWindow* window);
|
||||
|
||||
// post a function to be executed on the LLImageGL background thread
|
||||
|
|
@ -344,8 +339,6 @@ public:
|
|||
|
||||
void run() override;
|
||||
|
||||
static S32 getFreeVRAMMegabytes();
|
||||
|
||||
private:
|
||||
LLWindow* mWindow;
|
||||
void* mContext = nullptr;
|
||||
|
|
|
|||
|
|
@ -224,7 +224,7 @@ bool LLTexUnit::bind(LLTexture* texture, bool for_rendering, bool forceBind)
|
|||
enable(gl_tex->getTarget());
|
||||
mCurrTexture = gl_tex->getTexName();
|
||||
glBindTexture(sGLTextureType[gl_tex->getTarget()], mCurrTexture);
|
||||
if(gl_tex->updateBindStats(gl_tex->mTextureMemory))
|
||||
if(gl_tex->updateBindStats())
|
||||
{
|
||||
texture->setActive() ;
|
||||
texture->updateBindStatsForTester() ;
|
||||
|
|
@ -303,7 +303,7 @@ bool LLTexUnit::bind(LLImageGL* texture, bool for_rendering, bool forceBind, S32
|
|||
mCurrTexture = texname;
|
||||
glBindTexture(sGLTextureType[texture->getTarget()], mCurrTexture);
|
||||
stop_glerror();
|
||||
texture->updateBindStats(texture->mTextureMemory);
|
||||
texture->updateBindStats();
|
||||
mHasMipMaps = texture->mHasMipMaps;
|
||||
if (texture->mTexOptionsDirty)
|
||||
{
|
||||
|
|
@ -342,7 +342,7 @@ bool LLTexUnit::bind(LLCubeMap* cubeMap)
|
|||
mCurrTexture = cubeMap->mImages[0]->getTexName();
|
||||
glBindTexture(GL_TEXTURE_CUBE_MAP_ARB, mCurrTexture);
|
||||
mHasMipMaps = cubeMap->mImages[0]->mHasMipMaps;
|
||||
cubeMap->mImages[0]->updateBindStats(cubeMap->mImages[0]->mTextureMemory);
|
||||
cubeMap->mImages[0]->updateBindStats();
|
||||
if (cubeMap->mImages[0]->mTexOptionsDirty)
|
||||
{
|
||||
cubeMap->mImages[0]->mTexOptionsDirty = false;
|
||||
|
|
|
|||
|
|
@ -145,6 +145,8 @@ if (WINDOWS)
|
|||
list(APPEND llwindow_LINK_LIBRARIES
|
||||
comdlg32 # Common Dialogs for ChooseColor
|
||||
ole32
|
||||
dxgi
|
||||
d3d9
|
||||
)
|
||||
endif (WINDOWS)
|
||||
|
||||
|
|
|
|||
|
|
@ -141,7 +141,12 @@ attributedStringInfo getSegments(NSAttributedString *str)
|
|||
CGLError the_err = CGLQueryRendererInfo (CGDisplayIDToOpenGLDisplayMask(kCGDirectMainDisplay), &info, &num_renderers);
|
||||
if(0 == the_err)
|
||||
{
|
||||
CGLDescribeRenderer (info, 0, kCGLRPTextureMemoryMegabytes, &vram_megabytes);
|
||||
// The name, uses, and other platform definitions of gGLManager.mVRAM suggest that this is supposed to be total vram in MB,
|
||||
// rather than, say, just the texture memory. The two exceptions are:
|
||||
// 1. LLAppViewer::getViewerInfo() puts the value in a field labeled "TEXTURE_MEMORY"
|
||||
// 2. For years, this present function used kCGLRPTextureMemoryMegabytes
|
||||
// Now we use kCGLRPVideoMemoryMegabytes to bring it in line with everything else (except thatone label).
|
||||
CGLDescribeRenderer (info, 0, kCGLRPVideoMemoryMegabytes, &vram_megabytes);
|
||||
CGLDestroyRendererInfo (info);
|
||||
}
|
||||
else
|
||||
|
|
|
|||
|
|
@ -162,7 +162,10 @@ public:
|
|||
virtual F32 getNativeAspectRatio() = 0;
|
||||
virtual F32 getPixelAspectRatio() = 0;
|
||||
virtual void setNativeAspectRatio(F32 aspect) = 0;
|
||||
|
||||
|
||||
// query VRAM usage
|
||||
virtual U32 getAvailableVRAMMegabytes() = 0;
|
||||
|
||||
virtual void beforeDialog() {}; // prepare to put up an OS dialog (if special measures are required, such as in fullscreen mode)
|
||||
virtual void afterDialog() {}; // undo whatever was done in beforeDialog()
|
||||
|
||||
|
|
|
|||
|
|
@ -32,72 +32,79 @@
|
|||
class LLWindowHeadless : public LLWindow
|
||||
{
|
||||
public:
|
||||
/*virtual*/ void show() {};
|
||||
/*virtual*/ void hide() {};
|
||||
/*virtual*/ void close() {};
|
||||
/*virtual*/ BOOL getVisible() {return FALSE;};
|
||||
/*virtual*/ BOOL getMinimized() {return FALSE;};
|
||||
/*virtual*/ BOOL getMaximized() {return FALSE;};
|
||||
/*virtual*/ BOOL maximize() {return FALSE;};
|
||||
/*virtual*/ void minimize() {};
|
||||
/*virtual*/ void restore() {};
|
||||
/*virtual*/ BOOL getFullscreen() {return FALSE;};
|
||||
/*virtual*/ BOOL getPosition(LLCoordScreen *position) {return FALSE;};
|
||||
/*virtual*/ BOOL getSize(LLCoordScreen *size) {return FALSE;};
|
||||
/*virtual*/ BOOL getSize(LLCoordWindow *size) {return FALSE;};
|
||||
/*virtual*/ BOOL setPosition(LLCoordScreen position) {return FALSE;};
|
||||
/*virtual*/ BOOL setSizeImpl(LLCoordScreen size) {return FALSE;};
|
||||
/*virtual*/ BOOL setSizeImpl(LLCoordWindow size) {return FALSE;};
|
||||
/*virtual*/ BOOL switchContext(BOOL fullscreen, const LLCoordScreen &size, BOOL enable_vsync, const LLCoordScreen * const posp = NULL) {return FALSE;};
|
||||
void* createSharedContext() { return nullptr; }
|
||||
void makeContextCurrent(void*) {}
|
||||
void destroySharedContext(void*) {}
|
||||
/*virtual*/ void toggleVSync(bool enable_vsync) { }
|
||||
/*virtual*/ BOOL setCursorPosition(LLCoordWindow position) {return FALSE;};
|
||||
/*virtual*/ BOOL getCursorPosition(LLCoordWindow *position) {return FALSE;};
|
||||
/*virtual*/ void show() override {}
|
||||
/*virtual*/ void hide() override {}
|
||||
/*virtual*/ void close() override {}
|
||||
/*virtual*/ BOOL getVisible() override {return FALSE;}
|
||||
/*virtual*/ BOOL getMinimized() override {return FALSE;}
|
||||
/*virtual*/ BOOL getMaximized() override {return FALSE;}
|
||||
/*virtual*/ BOOL maximize() override {return FALSE;}
|
||||
/*virtual*/ void minimize() override {}
|
||||
/*virtual*/ void restore() override {}
|
||||
// TODO: LLWindow::getFullscreen() is (intentionally?) NOT virtual.
|
||||
// Apparently the coder of LLWindowHeadless didn't realize that. Is it a
|
||||
// mistake to shadow the base-class method with an LLWindowHeadless
|
||||
// override when called on the subclass, yet call the base-class method
|
||||
// when indirecting through a polymorphic pointer or reference?
|
||||
BOOL getFullscreen() {return FALSE;}
|
||||
/*virtual*/ BOOL getPosition(LLCoordScreen *position) override {return FALSE;}
|
||||
/*virtual*/ BOOL getSize(LLCoordScreen *size) override {return FALSE;}
|
||||
/*virtual*/ BOOL getSize(LLCoordWindow *size) override {return FALSE;}
|
||||
/*virtual*/ BOOL setPosition(LLCoordScreen position) override {return FALSE;}
|
||||
/*virtual*/ BOOL setSizeImpl(LLCoordScreen size) override {return FALSE;}
|
||||
/*virtual*/ BOOL setSizeImpl(LLCoordWindow size) override {return FALSE;}
|
||||
/*virtual*/ BOOL switchContext(BOOL fullscreen, const LLCoordScreen &size, BOOL enable_vsync, const LLCoordScreen * const posp = NULL) override {return FALSE;}
|
||||
void* createSharedContext() override { return nullptr; }
|
||||
void makeContextCurrent(void*) override {}
|
||||
void destroySharedContext(void*) override {}
|
||||
/*virtual*/ void toggleVSync(bool enable_vsync) override { }
|
||||
/*virtual*/ BOOL setCursorPosition(LLCoordWindow position) override {return FALSE;}
|
||||
/*virtual*/ BOOL getCursorPosition(LLCoordWindow *position) override {return FALSE;}
|
||||
#if LL_WINDOWS
|
||||
/*virtual*/ BOOL getCursorDelta(LLCoordCommon* delta) { return FALSE; }
|
||||
/*virtual*/ BOOL getCursorDelta(LLCoordCommon* delta) override { return FALSE; }
|
||||
#endif
|
||||
/*virtual*/ void showCursor() {};
|
||||
/*virtual*/ void hideCursor() {};
|
||||
/*virtual*/ void showCursorFromMouseMove() {};
|
||||
/*virtual*/ void hideCursorUntilMouseMove() {};
|
||||
/*virtual*/ BOOL isCursorHidden() {return FALSE;};
|
||||
/*virtual*/ void updateCursor() {};
|
||||
//virtual ECursorType getCursor() { return mCurrentCursor; };
|
||||
/*virtual*/ void captureMouse() {};
|
||||
/*virtual*/ void releaseMouse() {};
|
||||
/*virtual*/ void setMouseClipping( BOOL b ) {};
|
||||
/*virtual*/ BOOL isClipboardTextAvailable() {return FALSE; };
|
||||
/*virtual*/ BOOL pasteTextFromClipboard(LLWString &dst) {return FALSE; };
|
||||
/*virtual*/ BOOL copyTextToClipboard(const LLWString &src) {return FALSE; };
|
||||
/*virtual*/ void flashIcon(F32 seconds) {};
|
||||
/*virtual*/ F32 getGamma() {return 1.0f; };
|
||||
/*virtual*/ BOOL setGamma(const F32 gamma) {return FALSE; }; // Set the gamma
|
||||
/*virtual*/ void setFSAASamples(const U32 fsaa_samples) { }
|
||||
/*virtual*/ U32 getFSAASamples() { return 0; }
|
||||
/*virtual*/ BOOL restoreGamma() {return FALSE; }; // Restore original gamma table (before updating gamma)
|
||||
//virtual ESwapMethod getSwapMethod() { return mSwapMethod; }
|
||||
/*virtual*/ void gatherInput() {};
|
||||
/*virtual*/ void delayInputProcessing() {};
|
||||
/*virtual*/ void swapBuffers();
|
||||
/*virtual*/ void showCursor() override {}
|
||||
/*virtual*/ void hideCursor() override {}
|
||||
/*virtual*/ void showCursorFromMouseMove() override {}
|
||||
/*virtual*/ void hideCursorUntilMouseMove() override {}
|
||||
/*virtual*/ BOOL isCursorHidden() override {return FALSE;}
|
||||
/*virtual*/ void updateCursor() override {}
|
||||
//virtual ECursorType getCursor() override { return mCurrentCursor; }
|
||||
/*virtual*/ void captureMouse() override {}
|
||||
/*virtual*/ void releaseMouse() override {}
|
||||
/*virtual*/ void setMouseClipping( BOOL b ) override {}
|
||||
/*virtual*/ BOOL isClipboardTextAvailable() override {return FALSE; }
|
||||
/*virtual*/ BOOL pasteTextFromClipboard(LLWString &dst) override {return FALSE; }
|
||||
/*virtual*/ BOOL copyTextToClipboard(const LLWString &src) override {return FALSE; }
|
||||
/*virtual*/ void flashIcon(F32 seconds) override {}
|
||||
/*virtual*/ F32 getGamma() override {return 1.0f; }
|
||||
/*virtual*/ BOOL setGamma(const F32 gamma) override {return FALSE; } // Set the gamma
|
||||
/*virtual*/ void setFSAASamples(const U32 fsaa_samples) override { }
|
||||
/*virtual*/ U32 getFSAASamples() override { return 0; }
|
||||
/*virtual*/ BOOL restoreGamma() override {return FALSE; } // Restore original gamma table (before updating gamma)
|
||||
//virtual ESwapMethod getSwapMethod() override { return mSwapMethod; }
|
||||
/*virtual*/ void gatherInput() override {}
|
||||
/*virtual*/ void delayInputProcessing() override {}
|
||||
/*virtual*/ void swapBuffers() override;
|
||||
|
||||
|
||||
// handy coordinate space conversion routines
|
||||
/*virtual*/ BOOL convertCoords(LLCoordScreen from, LLCoordWindow *to) { return FALSE; };
|
||||
/*virtual*/ BOOL convertCoords(LLCoordWindow from, LLCoordScreen *to) { return FALSE; };
|
||||
/*virtual*/ BOOL convertCoords(LLCoordWindow from, LLCoordGL *to) { return FALSE; };
|
||||
/*virtual*/ BOOL convertCoords(LLCoordGL from, LLCoordWindow *to) { return FALSE; };
|
||||
/*virtual*/ BOOL convertCoords(LLCoordScreen from, LLCoordGL *to) { return FALSE; };
|
||||
/*virtual*/ BOOL convertCoords(LLCoordGL from, LLCoordScreen *to) { return FALSE; };
|
||||
/*virtual*/ BOOL convertCoords(LLCoordScreen from, LLCoordWindow *to) override { return FALSE; }
|
||||
/*virtual*/ BOOL convertCoords(LLCoordWindow from, LLCoordScreen *to) override { return FALSE; }
|
||||
/*virtual*/ BOOL convertCoords(LLCoordWindow from, LLCoordGL *to) override { return FALSE; }
|
||||
/*virtual*/ BOOL convertCoords(LLCoordGL from, LLCoordWindow *to) override { return FALSE; }
|
||||
/*virtual*/ BOOL convertCoords(LLCoordScreen from, LLCoordGL *to) override { return FALSE; }
|
||||
/*virtual*/ BOOL convertCoords(LLCoordGL from, LLCoordScreen *to) override { return FALSE; }
|
||||
|
||||
/*virtual*/ LLWindowResolution* getSupportedResolutions(S32 &num_resolutions) { return NULL; };
|
||||
/*virtual*/ F32 getNativeAspectRatio() { return 1.0f; };
|
||||
/*virtual*/ F32 getPixelAspectRatio() { return 1.0f; };
|
||||
/*virtual*/ void setNativeAspectRatio(F32 ratio) {}
|
||||
/*virtual*/ LLWindowResolution* getSupportedResolutions(S32 &num_resolutions) override { return NULL; }
|
||||
/*virtual*/ F32 getNativeAspectRatio() override { return 1.0f; }
|
||||
/*virtual*/ F32 getPixelAspectRatio() override { return 1.0f; }
|
||||
/*virtual*/ void setNativeAspectRatio(F32 ratio) override {}
|
||||
|
||||
/*virtual*/ void *getPlatformWindow() { return 0; };
|
||||
/*virtual*/ void bringToFront() {};
|
||||
U32 getAvailableVRAMMegabytes() override { return 4096; }
|
||||
|
||||
/*virtual*/ void *getPlatformWindow() override { return 0; }
|
||||
/*virtual*/ void bringToFront() override {}
|
||||
|
||||
LLWindowHeadless(LLWindowCallbacks* callbacks,
|
||||
const std::string& title, const std::string& name,
|
||||
|
|
@ -113,12 +120,12 @@ private:
|
|||
class LLSplashScreenHeadless : public LLSplashScreen
|
||||
{
|
||||
public:
|
||||
LLSplashScreenHeadless() {};
|
||||
virtual ~LLSplashScreenHeadless() {};
|
||||
LLSplashScreenHeadless() {}
|
||||
virtual ~LLSplashScreenHeadless() {}
|
||||
|
||||
/*virtual*/ void showImpl() {};
|
||||
/*virtual*/ void updateImpl(const std::string& mesg) {};
|
||||
/*virtual*/ void hideImpl() {};
|
||||
/*virtual*/ void showImpl() override {}
|
||||
/*virtual*/ void updateImpl(const std::string& mesg) override {}
|
||||
/*virtual*/ void hideImpl() override {}
|
||||
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -1222,6 +1222,16 @@ F32 LLWindowMacOSX::getPixelAspectRatio()
|
|||
return 1.f;
|
||||
}
|
||||
|
||||
U32 LLWindowMacOSX::getAvailableVRAMMegabytes() {
|
||||
// MTL (and MoltenVK) has some additional gpu data, such as recommendedMaxWorkingSetSize and currentAllocatedSize.
|
||||
// But these are not available for OpenGL and/or our current mimimum OS version.
|
||||
// So we will estimate.
|
||||
static const U32 mb = 1024*1024;
|
||||
// We're asked for total available gpu memory, but we only have allocation info on texture usage. So estimate by doubling that.
|
||||
static const U32 total_factor = 2; // estimated total/textures
|
||||
return gGLManager.mVRAM - (LLImageGL::getTextureBytesAllocated() * total_factor/mb);
|
||||
}
|
||||
|
||||
//static SInt32 oldWindowLevel;
|
||||
|
||||
// MBW -- XXX -- There's got to be a better way than this. Find it, please...
|
||||
|
|
|
|||
|
|
@ -100,6 +100,9 @@ public:
|
|||
F32 getPixelAspectRatio() override;
|
||||
void setNativeAspectRatio(F32 ratio) override { mOverrideAspectRatio = ratio; }
|
||||
|
||||
// query VRAM usage
|
||||
/*virtual*/ U32 getAvailableVRAMMegabytes() override;
|
||||
|
||||
void beforeDialog() override;
|
||||
void afterDialog() override;
|
||||
|
||||
|
|
|
|||
|
|
@ -47,6 +47,9 @@
|
|||
#include "llglslshader.h"
|
||||
#include "llthreadsafequeue.h"
|
||||
#include "stringize.h"
|
||||
#include "llframetimer.h"
|
||||
#include "commoncontrol.h" // TODO: Remove after testing
|
||||
#include "llsd.h" // TODO: Remove after testing
|
||||
|
||||
// System includes
|
||||
#include <commdlg.h>
|
||||
|
|
@ -61,6 +64,9 @@
|
|||
#include <sstream>
|
||||
#include <utility> // std::pair
|
||||
|
||||
#include <d3d9.h>
|
||||
#include <dxgi1_4.h>
|
||||
|
||||
// Require DirectInput version 8
|
||||
#define DIRECTINPUT_VERSION 0x0800
|
||||
|
||||
|
|
@ -347,6 +353,20 @@ struct LLWindowWin32::LLWindowWin32Thread : public LL::ThreadPool
|
|||
|
||||
void run() override;
|
||||
|
||||
// initialzie DXGI adapter (for querying available VRAM)
|
||||
void initDX();
|
||||
|
||||
// initialize D3D (if DXGI cannot be used)
|
||||
void initD3D();
|
||||
|
||||
// call periodically to update available VRAM
|
||||
void updateVRAMUsage();
|
||||
|
||||
U32 getAvailableVRAMMegabytes()
|
||||
{
|
||||
return mAvailableVRAM;
|
||||
}
|
||||
|
||||
/// called by main thread to post work to this window thread
|
||||
template <typename CALLABLE>
|
||||
void post(CALLABLE&& func)
|
||||
|
|
@ -395,6 +415,15 @@ struct LLWindowWin32::LLWindowWin32Thread : public LL::ThreadPool
|
|||
void gatherInput();
|
||||
HWND mWindowHandle = NULL;
|
||||
HDC mhDC = 0;
|
||||
|
||||
// best guess at available video memory in MB
|
||||
std::atomic<U32> mAvailableVRAM;
|
||||
|
||||
bool mTryUseDXGIAdapter; // TODO: Remove after testing
|
||||
IDXGIAdapter3* mDXGIAdapter = nullptr;
|
||||
bool mTryUseD3DDevice; // TODO: Remove after testing
|
||||
LPDIRECT3D9 mD3D = nullptr;
|
||||
LPDIRECT3DDEVICE9 mD3DDevice = nullptr;
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -4531,12 +4560,24 @@ std::vector<std::string> LLWindowWin32::getDynamicFallbackFontList()
|
|||
return std::vector<std::string>();
|
||||
}
|
||||
|
||||
U32 LLWindowWin32::getAvailableVRAMMegabytes()
|
||||
{
|
||||
return mWindowThread ? mWindowThread->getAvailableVRAMMegabytes() : 0;
|
||||
}
|
||||
|
||||
#endif // LL_WINDOWS
|
||||
|
||||
inline LLWindowWin32::LLWindowWin32Thread::LLWindowWin32Thread()
|
||||
: ThreadPool("Window Thread", 1, MAX_QUEUE_SIZE)
|
||||
{
|
||||
const LLSD skipDXGI{ LL::CommonControl::get("Global", "DisablePrimaryGraphicsMemoryAccounting") }; // TODO: Remove after testing
|
||||
LL_WARNS() << "DisablePrimaryGraphicsMemoryAccounting: " << skipDXGI << ", as boolean: " << skipDXGI.asBoolean() << LL_ENDL;
|
||||
mTryUseDXGIAdapter = !skipDXGI.asBoolean();
|
||||
LL_WARNS() << "mTryUseDXGIAdapter: " << mTryUseDXGIAdapter << LL_ENDL;
|
||||
const LLSD skipD3D{ LL::CommonControl::get("Global", "DisableSecondaryGraphicsMemoryAccounting") }; // TODO: Remove after testing
|
||||
LL_WARNS() << "DisableSecondaryGraphicsMemoryAccounting: " << skipD3D << ", as boolean: " << skipD3D.asBoolean() << LL_ENDL;
|
||||
mTryUseD3DDevice = !skipD3D.asBoolean();
|
||||
LL_WARNS() << "mTryUseD3DDevice: " << mTryUseD3DDevice << LL_ENDL;
|
||||
ThreadPool::start();
|
||||
}
|
||||
|
||||
|
|
@ -4586,17 +4627,216 @@ private:
|
|||
std::string mPrev;
|
||||
};
|
||||
|
||||
// Print hardware debug info about available graphics adapters in ordinal order
|
||||
void debugEnumerateGraphicsAdapters()
|
||||
{
|
||||
LL_INFOS("Window") << "Enumerating graphics adapters..." << LL_ENDL;
|
||||
|
||||
IDXGIFactory1* factory;
|
||||
HRESULT res = CreateDXGIFactory1(__uuidof(IDXGIFactory1), (void**)&factory);
|
||||
if (FAILED(res) || !factory)
|
||||
{
|
||||
LL_WARNS() << "CreateDXGIFactory1 failed: 0x" << std::hex << res << LL_ENDL;
|
||||
}
|
||||
else
|
||||
{
|
||||
UINT graphics_adapter_index = 0;
|
||||
IDXGIAdapter3* dxgi_adapter;
|
||||
while (true)
|
||||
{
|
||||
res = factory->EnumAdapters(graphics_adapter_index, reinterpret_cast<IDXGIAdapter**>(&dxgi_adapter));
|
||||
if (FAILED(res))
|
||||
{
|
||||
if (graphics_adapter_index == 0)
|
||||
{
|
||||
LL_WARNS() << "EnumAdapters failed: 0x" << std::hex << res << LL_ENDL;
|
||||
}
|
||||
else
|
||||
{
|
||||
LL_INFOS("Window") << "Done enumerating graphics adapters" << LL_ENDL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
DXGI_ADAPTER_DESC desc;
|
||||
dxgi_adapter->GetDesc(&desc);
|
||||
std::wstring description_w((wchar_t*)desc.Description);
|
||||
std::string description(description_w.begin(), description_w.end());
|
||||
LL_INFOS("Window") << "Graphics adapter index: " << graphics_adapter_index << ", "
|
||||
<< "Description: " << description << ", "
|
||||
<< "DeviceId: " << desc.DeviceId << ", "
|
||||
<< "SubSysId: " << desc.SubSysId << ", "
|
||||
<< "AdapterLuid: " << desc.AdapterLuid.HighPart << "_" << desc.AdapterLuid.LowPart << ", "
|
||||
<< "DedicatedVideoMemory: " << desc.DedicatedVideoMemory / 1024 / 1024 << ", "
|
||||
<< "DedicatedSystemMemory: " << desc.DedicatedSystemMemory / 1024 / 1024 << ", "
|
||||
<< "SharedSystemMemory: " << desc.SharedSystemMemory / 1024 / 1024 << LL_ENDL;
|
||||
}
|
||||
|
||||
if (dxgi_adapter)
|
||||
{
|
||||
dxgi_adapter->Release();
|
||||
dxgi_adapter = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
graphics_adapter_index++;
|
||||
}
|
||||
}
|
||||
|
||||
if (factory)
|
||||
{
|
||||
factory->Release();
|
||||
}
|
||||
}
|
||||
|
||||
void LLWindowWin32::LLWindowWin32Thread::initDX()
|
||||
{
|
||||
if (mDXGIAdapter == NULL && mTryUseDXGIAdapter)
|
||||
{
|
||||
debugEnumerateGraphicsAdapters();
|
||||
|
||||
IDXGIFactory4* pFactory = nullptr;
|
||||
|
||||
HRESULT res = CreateDXGIFactory1(__uuidof(IDXGIFactory4), (void**)&pFactory);
|
||||
|
||||
if (FAILED(res))
|
||||
{
|
||||
LL_WARNS() << "CreateDXGIFactory1 failed: 0x" << std::hex << res << LL_ENDL;
|
||||
}
|
||||
else
|
||||
{
|
||||
res = pFactory->EnumAdapters(0, reinterpret_cast<IDXGIAdapter**>(&mDXGIAdapter));
|
||||
if (FAILED(res))
|
||||
{
|
||||
LL_WARNS() << "EnumAdapters failed: 0x" << std::hex << res << LL_ENDL;
|
||||
}
|
||||
else
|
||||
{
|
||||
LL_INFOS() << "EnumAdapters success" << LL_ENDL;
|
||||
}
|
||||
}
|
||||
|
||||
if (pFactory)
|
||||
{
|
||||
pFactory->Release();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LLWindowWin32::LLWindowWin32Thread::initD3D()
|
||||
{
|
||||
if (mDXGIAdapter == NULL && mD3DDevice == NULL && mTryUseD3DDevice && mWindowHandle != 0)
|
||||
{
|
||||
mD3D = Direct3DCreate9(D3D_SDK_VERSION);
|
||||
|
||||
D3DPRESENT_PARAMETERS d3dpp;
|
||||
|
||||
ZeroMemory(&d3dpp, sizeof(d3dpp));
|
||||
d3dpp.Windowed = TRUE;
|
||||
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
|
||||
|
||||
HRESULT res = mD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, mWindowHandle, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &mD3DDevice);
|
||||
|
||||
if (FAILED(res))
|
||||
{
|
||||
LL_WARNS() << "(fallback) CreateDevice failed: 0x" << std::hex << res << LL_ENDL;
|
||||
}
|
||||
else
|
||||
{
|
||||
LL_INFOS() << "(fallback) CreateDevice success" << LL_ENDL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LLWindowWin32::LLWindowWin32Thread::updateVRAMUsage()
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED;
|
||||
if (mDXGIAdapter != nullptr)
|
||||
{
|
||||
// NOTE: what lies below is hand wavy math based on compatibility testing and observation against a variety of hardware
|
||||
// It doesn't make sense, but please don't refactor it to make sense. -- davep
|
||||
|
||||
DXGI_QUERY_VIDEO_MEMORY_INFO info;
|
||||
mDXGIAdapter->QueryVideoMemoryInfo(0, DXGI_MEMORY_SEGMENT_GROUP_LOCAL, &info);
|
||||
|
||||
#if 0 // debug 0 budget and 0 CU
|
||||
info.Budget = 0;
|
||||
info.CurrentUsage = 0;
|
||||
#endif
|
||||
|
||||
U32 budget_mb = info.Budget / 1024 / 1024;
|
||||
U32 afr_mb = info.AvailableForReservation / 1024 / 1024;
|
||||
// correct for systems that misreport budget
|
||||
if (budget_mb == 0)
|
||||
{
|
||||
// fall back to available for reservation clamped between 512MB and 2GB
|
||||
budget_mb = llclamp(afr_mb, (U32) 512, (U32) 2048);
|
||||
}
|
||||
|
||||
U32 cu_mb = info.CurrentUsage / 1024 / 1024;
|
||||
|
||||
// get an estimated usage based on texture bytes allocated
|
||||
U32 eu_mb = LLImageGL::getTextureBytesAllocated() * 2 / 1024 / 1024;
|
||||
|
||||
if (cu_mb == 0)
|
||||
{ // current usage is sometimes unreliable on Intel GPUs, fall back to estimated usage
|
||||
cu_mb = llmax((U32)1, eu_mb);
|
||||
}
|
||||
F32 eu_error = (F32)((S32)eu_mb - (S32)cu_mb) / (F32)cu_mb;
|
||||
|
||||
U32 target_mb = info.Budget / 1024 / 1024;
|
||||
|
||||
if (target_mb > 4096) // if 4GB are installed, try to leave 2GB free
|
||||
{
|
||||
target_mb -= 2048;
|
||||
}
|
||||
else // if less than 4GB are installed, try not to use more than half of it
|
||||
{
|
||||
target_mb /= 2;
|
||||
}
|
||||
|
||||
mAvailableVRAM = cu_mb < target_mb ? target_mb - cu_mb : 0;
|
||||
|
||||
LL_INFOS("Window") << "\nLocal\nAFR: " << info.AvailableForReservation / 1024 / 1024
|
||||
<< "\nBudget: " << info.Budget / 1024 / 1024
|
||||
<< "\nCR: " << info.CurrentReservation / 1024 / 1024
|
||||
<< "\nCU: " << info.CurrentUsage / 1024 / 1024
|
||||
<< "\nEU: " << eu_mb << llformat(" (%.2f)", eu_error)
|
||||
<< "\nTU: " << target_mb
|
||||
<< "\nAM: " << mAvailableVRAM << LL_ENDL;
|
||||
|
||||
/*mDXGIAdapter->QueryVideoMemoryInfo(0, DXGI_MEMORY_SEGMENT_GROUP_NON_LOCAL, &info);
|
||||
LL_INFOS("Window") << "\nNon-Local\nAFR: " << info.AvailableForReservation / 1024 / 1024
|
||||
<< "\nBudget: " << info.Budget / 1024 / 1024
|
||||
<< "\nCR: " << info.CurrentReservation / 1024 / 1024
|
||||
<< "\nCU: " << info.CurrentUsage / 1024 / 1024 << LL_ENDL;*/
|
||||
}
|
||||
else if (mD3DDevice != NULL)
|
||||
{ // fallback to D3D9
|
||||
mAvailableVRAM = mD3DDevice->GetAvailableTextureMem() / 1024 / 1024;
|
||||
}
|
||||
}
|
||||
|
||||
void LLWindowWin32::LLWindowWin32Thread::run()
|
||||
{
|
||||
sWindowThreadId = std::this_thread::get_id();
|
||||
LogChange logger("Window");
|
||||
|
||||
initDX();
|
||||
|
||||
while (! getQueue().done())
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_WIN32;
|
||||
|
||||
if (mWindowHandle != 0)
|
||||
{
|
||||
// lazily call initD3D inside this loop to catch when mWindowHandle has been set
|
||||
// *TODO: Shutdown if this fails when mWindowHandle exists
|
||||
initD3D();
|
||||
|
||||
MSG msg;
|
||||
BOOL status;
|
||||
if (mhDC == 0)
|
||||
|
|
@ -4629,6 +4869,13 @@ void LLWindowWin32::LLWindowWin32Thread::run()
|
|||
getQueue().runPending();
|
||||
}
|
||||
|
||||
// update available vram once every 3 seconds
|
||||
static LLFrameTimer vramTimer;
|
||||
if (vramTimer.getElapsedTimeF32() > 3.f)
|
||||
{
|
||||
updateVRAMUsage();
|
||||
vramTimer.reset();
|
||||
}
|
||||
#if 0
|
||||
{
|
||||
LL_PROFILE_ZONE_NAMED_CATEGORY_WIN32("w32t - Sleep");
|
||||
|
|
@ -4637,6 +4884,26 @@ void LLWindowWin32::LLWindowWin32Thread::run()
|
|||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
//clean up DXGI/D3D resources
|
||||
if (mDXGIAdapter)
|
||||
{
|
||||
mDXGIAdapter->Release();
|
||||
mDXGIAdapter = nullptr;
|
||||
}
|
||||
|
||||
if (mD3DDevice)
|
||||
{
|
||||
mD3DDevice->Release();
|
||||
mD3DDevice = nullptr;
|
||||
}
|
||||
|
||||
if (mD3D)
|
||||
{
|
||||
mD3D->Release();
|
||||
mD3D = nullptr;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void LLWindowWin32::post(const std::function<void()>& func)
|
||||
|
|
|
|||
|
|
@ -108,7 +108,9 @@ public:
|
|||
/*virtual*/ F32 getPixelAspectRatio();
|
||||
/*virtual*/ void setNativeAspectRatio(F32 ratio) { mOverrideAspectRatio = ratio; }
|
||||
|
||||
/*virtual*/ BOOL dialogColorPicker(F32 *r, F32 *g, F32 *b );
|
||||
U32 getAvailableVRAMMegabytes() override;
|
||||
|
||||
/*virtual*/ BOOL dialogColorPicker(F32 *r, F32 *g, F32 *b );
|
||||
|
||||
/*virtual*/ void *getPlatformWindow();
|
||||
/*virtual*/ void bringToFront();
|
||||
|
|
|
|||
|
|
@ -321,7 +321,6 @@ set(viewer_SOURCE_FILES
|
|||
llfloatertelehub.cpp
|
||||
llfloatertestinspectors.cpp
|
||||
llfloatertestlistview.cpp
|
||||
llfloatertexturefetchdebugger.cpp
|
||||
llfloatertools.cpp
|
||||
llfloatertopobjects.cpp
|
||||
llfloatertos.cpp
|
||||
|
|
@ -967,7 +966,6 @@ set(viewer_HEADER_FILES
|
|||
llfloatertelehub.h
|
||||
llfloatertestinspectors.h
|
||||
llfloatertestlistview.h
|
||||
llfloatertexturefetchdebugger.h
|
||||
llfloatertools.h
|
||||
llfloatertopobjects.h
|
||||
llfloatertos.h
|
||||
|
|
@ -2519,6 +2517,19 @@ if (LL_TESTS)
|
|||
"${test_libs}"
|
||||
)
|
||||
|
||||
set(llviewercontrollistener_test_sources
|
||||
llviewercontrollistener.cpp
|
||||
../llxml/llcontrol.cpp
|
||||
../llxml/llxmltree.cpp
|
||||
../llxml/llxmlparser.cpp
|
||||
../llcommon/commoncontrol.cpp
|
||||
)
|
||||
|
||||
LL_ADD_INTEGRATION_TEST(llviewercontrollistener
|
||||
"${llviewercontrollistener_test_sources}"
|
||||
"${test_libs}"
|
||||
)
|
||||
|
||||
LL_ADD_INTEGRATION_TEST(llviewernetwork
|
||||
llviewernetwork.cpp
|
||||
"${test_libs}"
|
||||
|
|
|
|||
|
|
@ -3398,6 +3398,29 @@
|
|||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
<!-- TODO: Remove settings keys DisablePrimaryGraphicsMemoryAccounting and DisableSecondaryGraphicsMemoryAccounting after testing, and code that references them -->
|
||||
<key>DisablePrimaryGraphicsMemoryAccounting</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Disable the first method used to detect GPU memory use</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
<key>DisableSecondaryGraphicsMemoryAccounting</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Disable the second method used to detect GPU memory use, used as a fallback when the first method fails</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
<key>DisableTextHyperlinkActions</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
|
|
@ -3924,7 +3947,7 @@
|
|||
<key>Type</key>
|
||||
<string>F32</string>
|
||||
<key>Value</key>
|
||||
<real>0.1</real>
|
||||
<real>1.0</real>
|
||||
</map>
|
||||
<key>QueueInventoryFetchTimeout</key>
|
||||
<map>
|
||||
|
|
@ -10458,17 +10481,6 @@
|
|||
<key>Value</key>
|
||||
<real>12.0</real>
|
||||
</map>
|
||||
<key>RenderTextureMemoryMultiple</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Multiple of texture memory value to use (should fit: 0 < value <= 1.0)</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>F32</string>
|
||||
<key>Value</key>
|
||||
<real>1.0</real>
|
||||
</map>
|
||||
<key>RenderTrackerBeacon</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
|
|
@ -12548,17 +12560,6 @@
|
|||
<key>Value</key>
|
||||
<real>20.0</real>
|
||||
</map>
|
||||
<key>TexelPixelRatio</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>texel pixel ratio = texel / pixel</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>F32</string>
|
||||
<key>Value</key>
|
||||
<real>1.0</real>
|
||||
</map>
|
||||
<key>TextureCameraMotionThreshold</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
|
|
@ -12658,17 +12659,6 @@
|
|||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
<key>TextureFetchDebuggerEnabled</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Enable the texture fetching debugger if set</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
<key>TextureFetchMinTimeToLog</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
|
|
@ -12691,21 +12681,10 @@
|
|||
<key>Value</key>
|
||||
<real>0.0</real>
|
||||
</map>
|
||||
<key>TextureFetchSource</key>
|
||||
<key>TextureFetchUpdateMinCount</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Debug use: Source to fetch textures</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>S32</string>
|
||||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
<key>TextureFetchUpdateHighPriority</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Number of high priority textures to update per frame</string>
|
||||
<string>Minimum number of textures to update per frame</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
|
|
@ -12713,91 +12692,14 @@
|
|||
<key>Value</key>
|
||||
<integer>32</integer>
|
||||
</map>
|
||||
<key>TextureFetchUpdateMaxMediumPriority</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Maximum number of medium priority textures to update per frame</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>S32</string>
|
||||
<key>Value</key>
|
||||
<integer>256</integer>
|
||||
</map>
|
||||
<key>TextureFetchUpdateMinMediumPriority</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Minimum number of medium priority textures to update per frame</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>S32</string>
|
||||
<key>Value</key>
|
||||
<integer>32</integer>
|
||||
</map>
|
||||
<key>TextureFetchUpdatePriorityThreshold</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Threshold under which textures will be considered too low priority and skipped for update</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>F32</string>
|
||||
<key>Value</key>
|
||||
<real>0.0</real>
|
||||
</map>
|
||||
<key>TextureFetchUpdateSkipLowPriority</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Flag indicating if we want to skip textures with too low of a priority</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
<key>TextureFetchUpdatePriorities</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Number of priority texture to update per frame</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>S32</string>
|
||||
<key>Value</key>
|
||||
<integer>32</integer>
|
||||
</map>
|
||||
<key>TextureListFetchingThreshold</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>If the ratio between fetched and all textures in the list is greater than this threshold, which we assume that almost all textures are fetched</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>F32</string>
|
||||
<key>Value</key>
|
||||
<real>0.97</real>
|
||||
</map>
|
||||
<key>TextureLoadFullRes</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>If TRUE, always load textures at full resolution (discard = 0)</string>
|
||||
<key>Persist</key>
|
||||
<integer>0</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
<key>TextureMemory</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Amount of memory to use for textures in MB (0 = autodetect)</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>S32</string>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
|
|
@ -12867,7 +12769,9 @@
|
|||
<key>Value</key>
|
||||
<map>
|
||||
<key>General</key>
|
||||
<integer>4</integer>
|
||||
<integer>1</integer>
|
||||
<key>ImageDecode</key>
|
||||
<integer>9</integer>
|
||||
</map>
|
||||
</map>
|
||||
<key>ThrottleBandwidthKBPS</key>
|
||||
|
|
|
|||
|
|
@ -60,7 +60,6 @@ WindLightUseAtmosShaders 1 1
|
|||
WLSkyDetail 1 128
|
||||
Disregard128DefaultDrawDistance 1 1
|
||||
Disregard96DefaultDrawDistance 1 1
|
||||
RenderTextureMemoryMultiple 1 1.0
|
||||
RenderCompressTextures 1 1
|
||||
RenderShaderLightingMaxLevel 1 3
|
||||
RenderPBR 1 1
|
||||
|
|
|
|||
|
|
@ -60,7 +60,6 @@ WindLightUseAtmosShaders 1 1
|
|||
WLSkyDetail 1 128
|
||||
Disregard128DefaultDrawDistance 1 1
|
||||
Disregard96DefaultDrawDistance 1 1
|
||||
RenderTextureMemoryMultiple 1 1.0
|
||||
RenderCompressTextures 1 1
|
||||
RenderShaderLightingMaxLevel 1 3
|
||||
RenderDeferred 1 1
|
||||
|
|
|
|||
|
|
@ -103,7 +103,6 @@
|
|||
#include "lldiskcache.h"
|
||||
#include "llvopartgroup.h"
|
||||
#include "llweb.h"
|
||||
#include "llfloatertexturefetchdebugger.h"
|
||||
#include "llspellcheck.h"
|
||||
#include "llscenemonitor.h"
|
||||
#include "llavatarrenderinfoaccountant.h"
|
||||
|
|
@ -1551,7 +1550,6 @@ bool LLAppViewer::doFrame()
|
|||
{
|
||||
S32 non_interactive_ms_sleep_time = 100;
|
||||
LLAppViewer::getTextureCache()->pause();
|
||||
LLAppViewer::getImageDecodeThread()->pause();
|
||||
ms_sleep(non_interactive_ms_sleep_time);
|
||||
}
|
||||
|
||||
|
|
@ -1571,7 +1569,6 @@ bool LLAppViewer::doFrame()
|
|||
ms_sleep(milliseconds_to_sleep);
|
||||
// also pause worker threads during this wait period
|
||||
LLAppViewer::getTextureCache()->pause();
|
||||
LLAppViewer::getImageDecodeThread()->pause();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1620,7 +1617,6 @@ bool LLAppViewer::doFrame()
|
|||
{
|
||||
LL_PROFILE_ZONE_NAMED_CATEGORY_APP( "df getTextureCache" )
|
||||
LLAppViewer::getTextureCache()->pause();
|
||||
LLAppViewer::getImageDecodeThread()->pause();
|
||||
LLAppViewer::getTextureFetch()->pause();
|
||||
}
|
||||
if(!total_io_pending) //pause file threads if nothing to process.
|
||||
|
|
@ -1629,21 +1625,9 @@ bool LLAppViewer::doFrame()
|
|||
LLLFSThread::sLocal->pause();
|
||||
}
|
||||
|
||||
//texture fetching debugger
|
||||
if(LLTextureFetchDebugger::isEnabled())
|
||||
{
|
||||
LL_PROFILE_ZONE_NAMED_CATEGORY_APP( "df tex_fetch_debugger_instance" )
|
||||
LLFloaterTextureFetchDebugger* tex_fetch_debugger_instance =
|
||||
LLFloaterReg::findTypedInstance<LLFloaterTextureFetchDebugger>("tex_fetch_debugger");
|
||||
if(tex_fetch_debugger_instance)
|
||||
{
|
||||
tex_fetch_debugger_instance->idle() ;
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
LL_PROFILE_ZONE_NAMED_CATEGORY_APP( "df resumeMainloopTimeout" )
|
||||
resumeMainloopTimeout();
|
||||
resumeMainloopTimeout();
|
||||
}
|
||||
pingMainloopTimeout("Main:End");
|
||||
}
|
||||
|
|
@ -1695,16 +1679,20 @@ S32 LLAppViewer::updateTextureThreads(F32 max_time)
|
|||
|
||||
void LLAppViewer::flushLFSIO()
|
||||
{
|
||||
while (1)
|
||||
{
|
||||
S32 pending = LLLFSThread::updateClass(0);
|
||||
if (!pending)
|
||||
{
|
||||
break;
|
||||
}
|
||||
LL_INFOS() << "Waiting for pending IO to finish: " << pending << LL_ENDL;
|
||||
ms_sleep(100);
|
||||
}
|
||||
S32 pending = LLLFSThread::updateClass(0);
|
||||
if (pending > 0)
|
||||
{
|
||||
LL_INFOS() << "Waiting for pending IO to finish: " << pending << LL_ENDL;
|
||||
while (1)
|
||||
{
|
||||
pending = LLLFSThread::updateClass(0);
|
||||
if (!pending)
|
||||
{
|
||||
break;
|
||||
}
|
||||
ms_sleep(100);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool LLAppViewer::cleanup()
|
||||
|
|
@ -1861,8 +1849,6 @@ bool LLAppViewer::cleanup()
|
|||
|
||||
LL_INFOS() << "Cache files removed" << LL_ENDL;
|
||||
|
||||
// Wait for any pending LFS IO
|
||||
flushLFSIO();
|
||||
LL_INFOS() << "Shutting down Views" << LL_ENDL;
|
||||
|
||||
// Destroy the UI
|
||||
|
|
@ -2062,13 +2048,13 @@ bool LLAppViewer::cleanup()
|
|||
sTextureCache->shutdown();
|
||||
sImageDecodeThread->shutdown();
|
||||
sPurgeDiskCacheThread->shutdown();
|
||||
if (mGeneralThreadPool)
|
||||
{
|
||||
mGeneralThreadPool->close();
|
||||
}
|
||||
if (mGeneralThreadPool)
|
||||
{
|
||||
mGeneralThreadPool->close();
|
||||
}
|
||||
|
||||
sTextureFetch->shutDownTextureCacheThread() ;
|
||||
sTextureFetch->shutDownImageDecodeThread() ;
|
||||
LLLFSThread::sLocal->shutdown();
|
||||
|
||||
LL_INFOS() << "Shutting down message system" << LL_ENDL;
|
||||
end_messaging_system();
|
||||
|
|
@ -2185,14 +2171,7 @@ void LLAppViewer::initGeneralThread()
|
|||
return;
|
||||
}
|
||||
|
||||
LLSD poolSizes{ gSavedSettings.getLLSD("ThreadPoolSizes") };
|
||||
LLSD sizeSpec{ poolSizes["General"] };
|
||||
LLSD::Integer poolSize{ sizeSpec.isInteger() ? sizeSpec.asInteger() : 3 };
|
||||
LL_DEBUGS("ThreadPool") << "Instantiating General pool with "
|
||||
<< poolSize << " threads" << LL_ENDL;
|
||||
// We don't want anyone, especially the main thread, to have to block
|
||||
// due to this ThreadPool being full.
|
||||
mGeneralThreadPool = new LL::ThreadPool("General", poolSize, 1024 * 1024);
|
||||
mGeneralThreadPool = new LL::ThreadPool("General", 3);
|
||||
mGeneralThreadPool->start();
|
||||
}
|
||||
|
||||
|
|
@ -2202,13 +2181,12 @@ bool LLAppViewer::initThreads()
|
|||
|
||||
LLImage::initClass(gSavedSettings.getBOOL("TextureNewByteRange"),gSavedSettings.getS32("TextureReverseByteRange"));
|
||||
|
||||
LLLFSThread::initClass(enable_threads && false);
|
||||
LLLFSThread::initClass(enable_threads && true); // TODO: fix crashes associated with this shutdo
|
||||
|
||||
// Image decoding
|
||||
LLAppViewer::sImageDecodeThread = new LLImageDecodeThread(enable_threads && true);
|
||||
LLAppViewer::sTextureCache = new LLTextureCache(enable_threads && true);
|
||||
LLAppViewer::sTextureFetch = new LLTextureFetch(LLAppViewer::getTextureCache(),
|
||||
sImageDecodeThread,
|
||||
enable_threads && true,
|
||||
app_metrics_qa_mode);
|
||||
LLAppViewer::sPurgeDiskCacheThread = new LLPurgeDiskCacheThread();
|
||||
|
|
@ -3279,7 +3257,7 @@ LLSD LLAppViewer::getViewerInfo() const
|
|||
info["LOD_FACTOR"] = gSavedSettings.getF32("RenderVolumeLODFactor");
|
||||
info["RENDER_QUALITY"] = (F32)gSavedSettings.getU32("RenderQualityPerformance");
|
||||
info["GPU_SHADERS"] = gSavedSettings.getBOOL("RenderDeferred") ? "Enabled" : "Disabled";
|
||||
info["TEXTURE_MEMORY"] = gSavedSettings.getS32("TextureMemory");
|
||||
info["TEXTURE_MEMORY"] = gGLManager.mVRAM;
|
||||
|
||||
#if LL_DARWIN
|
||||
info["HIDPI"] = gHiDPISupport;
|
||||
|
|
@ -4711,10 +4689,6 @@ void LLAppViewer::idle()
|
|||
//
|
||||
// Special case idle if still starting up
|
||||
//
|
||||
if (LLStartUp::getStartupState() >= STATE_WORLD_INIT)
|
||||
{
|
||||
update_texture_time();
|
||||
}
|
||||
if (LLStartUp::getStartupState() < STATE_STARTED)
|
||||
{
|
||||
// Skip rest if idle startup returns false (essentially, no world yet)
|
||||
|
|
|
|||
|
|
@ -148,7 +148,7 @@ void LLDrawPoolTerrain::boostTerrainDetailTextures()
|
|||
for (S32 i = 0; i < 4; i++)
|
||||
{
|
||||
compp->mDetailTextures[i]->setBoostLevel(LLGLTexture::BOOST_TERRAIN);
|
||||
compp->mDetailTextures[i]->addTextureStats(1024.f*1024.f); // assume large pixel area
|
||||
gPipeline.touchTexture(compp->mDetailTextures[i], 1024.f * 1024.f);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2321,6 +2321,7 @@ void LLFace::resetVirtualSize()
|
|||
|
||||
F32 LLFace::getTextureVirtualSize()
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
|
||||
F32 radius;
|
||||
F32 cos_angle_to_view_dir;
|
||||
BOOL in_frustum = calcPixelArea(cos_angle_to_view_dir, radius);
|
||||
|
|
|
|||
|
|
@ -179,7 +179,7 @@ void LLFloaterLagMeter::determineClient()
|
|||
{
|
||||
mClientCause->setText( getString("client_texture_loading_cause_msg", mStringArgs) );
|
||||
}
|
||||
else if(LLViewerTexture::sBoundTextureMemory > LLViewerTexture::sMaxBoundTextureMemory)
|
||||
else if(LLViewerTexture::isMemoryForTextureLow())
|
||||
{
|
||||
mClientCause->setText( getString("client_texture_memory_cause_msg", mStringArgs) );
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1225,12 +1225,7 @@ void LLFloaterPreferenceGraphicsAdvanced::refreshEnabledState()
|
|||
shadow_text->setEnabled(enabled);
|
||||
|
||||
// Hardware settings
|
||||
F32 mem_multiplier = gSavedSettings.getF32("RenderTextureMemoryMultiple");
|
||||
S32Megabytes min_tex_mem = LLViewerTextureList::getMinVideoRamSetting();
|
||||
S32Megabytes max_tex_mem = LLViewerTextureList::getMaxVideoRamSetting(false, mem_multiplier);
|
||||
getChild<LLSliderCtrl>("GraphicsCardTextureMemory")->setMinValue(min_tex_mem.value());
|
||||
getChild<LLSliderCtrl>("GraphicsCardTextureMemory")->setMaxValue(max_tex_mem.value());
|
||||
|
||||
|
||||
if (!LLFeatureManager::getInstance()->isFeatureAvailable("RenderVBOEnable") ||
|
||||
!gGLManager.mHasVertexBufferObject)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,480 +0,0 @@
|
|||
/**
|
||||
* @file llfloatertexturefetchdebugger.cpp
|
||||
* @brief LLFloaterTextureFetchDebugger class definition
|
||||
*
|
||||
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2012, Linden Research, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#include "llviewerprecompiledheaders.h"
|
||||
|
||||
#include "llfloatertexturefetchdebugger.h"
|
||||
|
||||
#include "lluictrlfactory.h"
|
||||
#include "llbutton.h"
|
||||
#include "llspinctrl.h"
|
||||
#include "llresmgr.h"
|
||||
|
||||
#include "llmath.h"
|
||||
#include "llviewerwindow.h"
|
||||
#include "llappviewer.h"
|
||||
#include "lltexturefetch.h"
|
||||
#include "llviewercontrol.h"
|
||||
#include "llviewerassetstats.h" //gTextureTimer
|
||||
|
||||
LLFloaterTextureFetchDebugger::LLFloaterTextureFetchDebugger(const LLSD& key)
|
||||
: LLFloater(key),
|
||||
mDebugger(NULL)
|
||||
{
|
||||
setTitle("Texture Fetching Debugger Floater");
|
||||
|
||||
mCommitCallbackRegistrar.add("TexFetchDebugger.ChangeTexelPixelRatio", boost::bind(&LLFloaterTextureFetchDebugger::onChangeTexelPixelRatio, this));
|
||||
|
||||
mCommitCallbackRegistrar.add("TexFetchDebugger.Start", boost::bind(&LLFloaterTextureFetchDebugger::onClickStart, this));
|
||||
mCommitCallbackRegistrar.add("TexFetchDebugger.Clear", boost::bind(&LLFloaterTextureFetchDebugger::onClickClear, this));
|
||||
mCommitCallbackRegistrar.add("TexFetchDebugger.Close", boost::bind(&LLFloaterTextureFetchDebugger::onClickClose, this));
|
||||
mCommitCallbackRegistrar.add("TexFetchDebugger.ResetFetchTime", boost::bind(&LLFloaterTextureFetchDebugger::onClickResetFetchTime, this));
|
||||
|
||||
mCommitCallbackRegistrar.add("TexFetchDebugger.CacheRead", boost::bind(&LLFloaterTextureFetchDebugger::onClickCacheRead, this));
|
||||
mCommitCallbackRegistrar.add("TexFetchDebugger.CacheWrite", boost::bind(&LLFloaterTextureFetchDebugger::onClickCacheWrite, this));
|
||||
mCommitCallbackRegistrar.add("TexFetchDebugger.HTTPLoad", boost::bind(&LLFloaterTextureFetchDebugger::onClickHTTPLoad, this));
|
||||
mCommitCallbackRegistrar.add("TexFetchDebugger.Decode", boost::bind(&LLFloaterTextureFetchDebugger::onClickDecode, this));
|
||||
mCommitCallbackRegistrar.add("TexFetchDebugger.GLTexture", boost::bind(&LLFloaterTextureFetchDebugger::onClickGLTexture, this));
|
||||
|
||||
mCommitCallbackRegistrar.add("TexFetchDebugger.RefetchVisCache", boost::bind(&LLFloaterTextureFetchDebugger::onClickRefetchVisCache, this));
|
||||
mCommitCallbackRegistrar.add("TexFetchDebugger.RefetchVisHTTP", boost::bind(&LLFloaterTextureFetchDebugger::onClickRefetchVisHTTP, this));
|
||||
mCommitCallbackRegistrar.add("TexFetchDebugger.RefetchAllCache", boost::bind(&LLFloaterTextureFetchDebugger::onClickRefetchAllCache, this));
|
||||
mCommitCallbackRegistrar.add("TexFetchDebugger.RefetchAllHTTP", boost::bind(&LLFloaterTextureFetchDebugger::onClickRefetchAllHTTP, this));
|
||||
}
|
||||
//----------------------------------------------
|
||||
|
||||
BOOL LLFloaterTextureFetchDebugger::postBuild(void)
|
||||
{
|
||||
mDebugger = LLAppViewer::getTextureFetch()->getFetchDebugger();
|
||||
mStartStatus = (S32)LLTextureFetchDebugger::IDLE;
|
||||
|
||||
//set states for buttons
|
||||
mButtonStateMap["start_btn"] = true;
|
||||
mButtonStateMap["close_btn"] = true;
|
||||
mButtonStateMap["clear_btn"] = true;
|
||||
mButtonStateMap["cacheread_btn"] = false;
|
||||
mButtonStateMap["cachewrite_btn"] = false;
|
||||
mButtonStateMap["http_btn"] = false;
|
||||
mButtonStateMap["decode_btn"] = false;
|
||||
mButtonStateMap["gl_btn"] = false;
|
||||
|
||||
mButtonStateMap["refetchviscache_btn"] = false;
|
||||
mButtonStateMap["refetchvishttp_btn"] = false;
|
||||
mButtonStateMap["refetchallcache_btn"] = false;
|
||||
mButtonStateMap["refetchallhttp_btn"] = false;
|
||||
|
||||
updateButtons();
|
||||
|
||||
getChild<LLUICtrl>("texel_pixel_ratio")->setValue(gSavedSettings.getF32("TexelPixelRatio"));
|
||||
|
||||
return TRUE ;
|
||||
}
|
||||
|
||||
LLFloaterTextureFetchDebugger::~LLFloaterTextureFetchDebugger()
|
||||
{
|
||||
//stop everything
|
||||
mDebugger->setStopDebug();
|
||||
}
|
||||
|
||||
void LLFloaterTextureFetchDebugger::updateButtons()
|
||||
{
|
||||
for(std::map<std::string, bool>::iterator iter = mButtonStateMap.begin(); iter != mButtonStateMap.end(); ++iter)
|
||||
{
|
||||
if(iter->second)
|
||||
{
|
||||
childEnable(iter->first.c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
childDisable(iter->first.c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LLFloaterTextureFetchDebugger::disableButtons()
|
||||
{
|
||||
childDisable("start_btn");
|
||||
childDisable("clear_btn");
|
||||
childDisable("cacheread_btn");
|
||||
childDisable("cachewrite_btn");
|
||||
childDisable("http_btn");
|
||||
childDisable("decode_btn");
|
||||
childDisable("gl_btn");
|
||||
childDisable("refetchviscache_btn");
|
||||
childDisable("refetchvishttp_btn");
|
||||
childDisable("refetchallcache_btn");
|
||||
childDisable("refetchallhttp_btn");
|
||||
}
|
||||
void LLFloaterTextureFetchDebugger::setStartStatus(S32 status)
|
||||
{
|
||||
llassert_always(LLTextureFetchDebugger::IDLE == (LLTextureFetchDebugger::e_debug_state)mStartStatus) ;
|
||||
mStartStatus = status;
|
||||
}
|
||||
|
||||
bool LLFloaterTextureFetchDebugger::idleStart()
|
||||
{
|
||||
if(mStartStatus != (S32)LLTextureFetchDebugger::IDLE)
|
||||
{
|
||||
mDebugger->startWork((LLTextureFetchDebugger::e_debug_state)mStartStatus);
|
||||
mStartStatus = (S32)LLTextureFetchDebugger::IDLE;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void LLFloaterTextureFetchDebugger::idle()
|
||||
{
|
||||
if(idleStart())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const F32 max_time = 0.005f; //5ms
|
||||
LLTextureFetchDebugger::e_debug_state state = mDebugger->getState();
|
||||
if(mDebugger->update(max_time))
|
||||
{
|
||||
switch(state)
|
||||
{
|
||||
case LLTextureFetchDebugger::IDLE:
|
||||
break;
|
||||
case LLTextureFetchDebugger::START_DEBUG:
|
||||
mButtonStateMap["cacheread_btn"] = true;
|
||||
mButtonStateMap["http_btn"] = true;
|
||||
mButtonStateMap["refetchviscache_btn"] = true;
|
||||
mButtonStateMap["refetchvishttp_btn"] = true;
|
||||
mButtonStateMap["refetchallcache_btn"] = true;
|
||||
mButtonStateMap["refetchallhttp_btn"] = true;
|
||||
break;
|
||||
case LLTextureFetchDebugger::READ_CACHE:
|
||||
mButtonStateMap["decode_btn"] = true;
|
||||
break;
|
||||
case LLTextureFetchDebugger::WRITE_CACHE:
|
||||
break;
|
||||
case LLTextureFetchDebugger::DECODING:
|
||||
mButtonStateMap["gl_btn"] = true;
|
||||
break;
|
||||
case LLTextureFetchDebugger::HTTP_FETCHING:
|
||||
mButtonStateMap["cacheread_btn"] = true;
|
||||
mButtonStateMap["cachewrite_btn"] = true;
|
||||
mButtonStateMap["decode_btn"] = true;
|
||||
break;
|
||||
case LLTextureFetchDebugger::GL_TEX:
|
||||
break;
|
||||
case LLTextureFetchDebugger::REFETCH_VIS_CACHE:
|
||||
break;
|
||||
case LLTextureFetchDebugger::REFETCH_VIS_HTTP:
|
||||
break;
|
||||
case LLTextureFetchDebugger::REFETCH_ALL_CACHE:
|
||||
break;
|
||||
case LLTextureFetchDebugger::REFETCH_ALL_HTTP:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if(state != LLTextureFetchDebugger::IDLE)
|
||||
{
|
||||
updateButtons();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------
|
||||
void LLFloaterTextureFetchDebugger::onChangeTexelPixelRatio()
|
||||
{
|
||||
gSavedSettings.setF32("TexelPixelRatio", getChild<LLUICtrl>("texel_pixel_ratio")->getValue().asReal());
|
||||
}
|
||||
|
||||
void LLFloaterTextureFetchDebugger::onClickStart()
|
||||
{
|
||||
disableButtons();
|
||||
|
||||
setStartStatus((S32)LLTextureFetchDebugger::START_DEBUG);
|
||||
|
||||
mButtonStateMap["start_btn"] = false;
|
||||
|
||||
updateButtons();
|
||||
}
|
||||
|
||||
void LLFloaterTextureFetchDebugger::onClickClose()
|
||||
{
|
||||
setVisible(FALSE);
|
||||
|
||||
//stop everything
|
||||
mDebugger->setStopDebug();
|
||||
|
||||
delete this;
|
||||
}
|
||||
|
||||
void LLFloaterTextureFetchDebugger::onClickResetFetchTime()
|
||||
{
|
||||
gTextureTimer.start();
|
||||
gTextureTimer.pause();
|
||||
}
|
||||
|
||||
void LLFloaterTextureFetchDebugger::onClickClear()
|
||||
{
|
||||
mButtonStateMap["start_btn"] = true;
|
||||
mButtonStateMap["close_btn"] = true;
|
||||
mButtonStateMap["clear_btn"] = true;
|
||||
mButtonStateMap["cacheread_btn"] = false;
|
||||
mButtonStateMap["cachewrite_btn"] = false;
|
||||
mButtonStateMap["http_btn"] = false;
|
||||
mButtonStateMap["decode_btn"] = false;
|
||||
mButtonStateMap["gl_btn"] = false;
|
||||
mButtonStateMap["refetchviscache_btn"] = true;
|
||||
mButtonStateMap["refetchvishttp_btn"] = true;
|
||||
updateButtons();
|
||||
|
||||
//stop everything
|
||||
mDebugger->setStopDebug();
|
||||
mDebugger->clearHistory();
|
||||
}
|
||||
|
||||
void LLFloaterTextureFetchDebugger::onClickCacheRead()
|
||||
{
|
||||
disableButtons();
|
||||
|
||||
setStartStatus((S32)LLTextureFetchDebugger::READ_CACHE);
|
||||
}
|
||||
|
||||
void LLFloaterTextureFetchDebugger::onClickCacheWrite()
|
||||
{
|
||||
disableButtons();
|
||||
|
||||
setStartStatus((S32)LLTextureFetchDebugger::WRITE_CACHE);
|
||||
}
|
||||
|
||||
void LLFloaterTextureFetchDebugger::onClickHTTPLoad()
|
||||
{
|
||||
disableButtons();
|
||||
|
||||
setStartStatus((S32)LLTextureFetchDebugger::HTTP_FETCHING);
|
||||
}
|
||||
|
||||
void LLFloaterTextureFetchDebugger::onClickDecode()
|
||||
{
|
||||
disableButtons();
|
||||
|
||||
setStartStatus((S32)LLTextureFetchDebugger::DECODING);
|
||||
}
|
||||
|
||||
void LLFloaterTextureFetchDebugger::onClickGLTexture()
|
||||
{
|
||||
disableButtons();
|
||||
|
||||
setStartStatus((S32)LLTextureFetchDebugger::GL_TEX);
|
||||
}
|
||||
|
||||
void LLFloaterTextureFetchDebugger::onClickRefetchVisCache()
|
||||
{
|
||||
disableButtons();
|
||||
|
||||
setStartStatus((S32)LLTextureFetchDebugger::REFETCH_VIS_CACHE);
|
||||
}
|
||||
|
||||
void LLFloaterTextureFetchDebugger::onClickRefetchVisHTTP()
|
||||
{
|
||||
disableButtons();
|
||||
|
||||
setStartStatus((S32)LLTextureFetchDebugger::REFETCH_VIS_HTTP);
|
||||
}
|
||||
|
||||
void LLFloaterTextureFetchDebugger::onClickRefetchAllCache()
|
||||
{
|
||||
disableButtons();
|
||||
|
||||
setStartStatus((S32)LLTextureFetchDebugger::REFETCH_ALL_CACHE);
|
||||
}
|
||||
|
||||
void LLFloaterTextureFetchDebugger::onClickRefetchAllHTTP()
|
||||
{
|
||||
disableButtons();
|
||||
|
||||
setStartStatus((S32)LLTextureFetchDebugger::REFETCH_ALL_HTTP);
|
||||
}
|
||||
|
||||
void LLFloaterTextureFetchDebugger::draw()
|
||||
{
|
||||
//total number of fetched textures
|
||||
{
|
||||
getChild<LLUICtrl>("total_num_fetched_label")->setTextArg("[NUM]", llformat("%d", mDebugger->getNumFetchedTextures()));
|
||||
}
|
||||
|
||||
//total number of fetching requests
|
||||
{
|
||||
getChild<LLUICtrl>("total_num_fetching_requests_label")->setTextArg("[NUM]", llformat("%d", mDebugger->getNumFetchingRequests()));
|
||||
}
|
||||
|
||||
//total number of cache hits
|
||||
{
|
||||
getChild<LLUICtrl>("total_num_cache_hits_label")->setTextArg("[NUM]", llformat("%d", mDebugger->getNumCacheHits()));
|
||||
}
|
||||
|
||||
//total number of visible textures
|
||||
{
|
||||
getChild<LLUICtrl>("total_num_visible_tex_label")->setTextArg("[NUM]", llformat("%d", mDebugger->getNumVisibleFetchedTextures()));
|
||||
}
|
||||
|
||||
//total number of visible texture fetching requests
|
||||
{
|
||||
getChild<LLUICtrl>("total_num_visible_tex_fetch_req_label")->setTextArg("[NUM]", llformat("%d", mDebugger->getNumVisibleFetchingRequests()));
|
||||
}
|
||||
|
||||
//total number of fetched data
|
||||
{
|
||||
getChild<LLUICtrl>("total_fetched_data_label")->setTextArg("[SIZE1]", llformat("%d", mDebugger->getFetchedData() >> 10));
|
||||
getChild<LLUICtrl>("total_fetched_data_label")->setTextArg("[SIZE2]", llformat("%d", mDebugger->getDecodedData() >> 10));
|
||||
getChild<LLUICtrl>("total_fetched_data_label")->setTextArg("[PIXEL]", llformat("%.3f", mDebugger->getFetchedPixels() / 1000000.f));
|
||||
}
|
||||
|
||||
//total number of visible fetched data
|
||||
{
|
||||
getChild<LLUICtrl>("total_fetched_vis_data_label")->setTextArg("[SIZE1]", llformat("%d", mDebugger->getVisibleFetchedData() >> 10));
|
||||
getChild<LLUICtrl>("total_fetched_vis_data_label")->setTextArg("[SIZE2]", llformat("%d", mDebugger->getVisibleDecodedData() >> 10));
|
||||
}
|
||||
|
||||
//total number of rendered fetched data
|
||||
{
|
||||
getChild<LLUICtrl>("total_fetched_rendered_data_label")->setTextArg("[SIZE1]", llformat("%d", mDebugger->getRenderedData() >> 10));
|
||||
getChild<LLUICtrl>("total_fetched_rendered_data_label")->setTextArg("[SIZE2]", llformat("%d", mDebugger->getRenderedDecodedData() >> 10));
|
||||
getChild<LLUICtrl>("total_fetched_rendered_data_label")->setTextArg("[PIXEL]", llformat("%.3f", mDebugger->getRenderedPixels() / 1000000.f));
|
||||
}
|
||||
|
||||
//total time on cache readings
|
||||
if(mDebugger->getCacheReadTime() < 0.f)
|
||||
{
|
||||
getChild<LLUICtrl>("total_time_cache_read_label")->setTextArg("[TIME]", std::string("----"));
|
||||
}
|
||||
else
|
||||
{
|
||||
getChild<LLUICtrl>("total_time_cache_read_label")->setTextArg("[TIME]", llformat("%.3f", mDebugger->getCacheReadTime()));
|
||||
}
|
||||
|
||||
//total time on cache writings
|
||||
if(mDebugger->getCacheWriteTime() < 0.f)
|
||||
{
|
||||
getChild<LLUICtrl>("total_time_cache_write_label")->setTextArg("[TIME]", std::string("----"));
|
||||
}
|
||||
else
|
||||
{
|
||||
getChild<LLUICtrl>("total_time_cache_write_label")->setTextArg("[TIME]", llformat("%.3f", mDebugger->getCacheWriteTime()));
|
||||
}
|
||||
|
||||
//total time on decoding
|
||||
if(mDebugger->getDecodeTime() < 0.f)
|
||||
{
|
||||
getChild<LLUICtrl>("total_time_decode_label")->setTextArg("[TIME]", std::string("----"));
|
||||
}
|
||||
else
|
||||
{
|
||||
getChild<LLUICtrl>("total_time_decode_label")->setTextArg("[TIME]", llformat("%.3f", mDebugger->getDecodeTime()));
|
||||
}
|
||||
|
||||
//total time on gl texture creation
|
||||
if(mDebugger->getGLCreationTime() < 0.f)
|
||||
{
|
||||
getChild<LLUICtrl>("total_time_gl_label")->setTextArg("[TIME]", std::string("----"));
|
||||
}
|
||||
else
|
||||
{
|
||||
getChild<LLUICtrl>("total_time_gl_label")->setTextArg("[TIME]", llformat("%.3f", mDebugger->getGLCreationTime()));
|
||||
}
|
||||
|
||||
//total time on HTTP fetching
|
||||
if(mDebugger->getHTTPTime() < 0.f)
|
||||
{
|
||||
getChild<LLUICtrl>("total_time_http_label")->setTextArg("[TIME]", std::string("----"));
|
||||
}
|
||||
else
|
||||
{
|
||||
getChild<LLUICtrl>("total_time_http_label")->setTextArg("[TIME]", llformat("%.3f", mDebugger->getHTTPTime()));
|
||||
}
|
||||
|
||||
//total time on entire fetching
|
||||
{
|
||||
getChild<LLUICtrl>("total_time_fetch_label")->setTextArg("[TIME]", llformat("%.3f", mDebugger->getTotalFetchingTime()));
|
||||
}
|
||||
|
||||
//total time on refetching visible textures from cache
|
||||
if(mDebugger->getRefetchVisCacheTime() < 0.f)
|
||||
{
|
||||
getChild<LLUICtrl>("total_time_refetch_vis_cache_label")->setTextArg("[TIME]", std::string("----"));
|
||||
getChild<LLUICtrl>("total_time_refetch_vis_cache_label")->setTextArg("[SIZE]", std::string("----"));
|
||||
getChild<LLUICtrl>("total_time_refetch_vis_cache_label")->setTextArg("[PIXEL]", std::string("----"));
|
||||
}
|
||||
else
|
||||
{
|
||||
getChild<LLUICtrl>("total_time_refetch_vis_cache_label")->setTextArg("[TIME]", llformat("%.3f", mDebugger->getRefetchVisCacheTime()));
|
||||
getChild<LLUICtrl>("total_time_refetch_vis_cache_label")->setTextArg("[SIZE]", llformat("%d", mDebugger->getRefetchedVisData() >> 10));
|
||||
getChild<LLUICtrl>("total_time_refetch_vis_cache_label")->setTextArg("[PIXEL]", llformat("%.3f", mDebugger->getRefetchedVisPixels() / 1000000.f));
|
||||
}
|
||||
|
||||
//total time on refetching all textures from cache
|
||||
if(mDebugger->getRefetchAllCacheTime() < 0.f)
|
||||
{
|
||||
getChild<LLUICtrl>("total_time_refetch_all_cache_label")->setTextArg("[TIME]", std::string("----"));
|
||||
getChild<LLUICtrl>("total_time_refetch_all_cache_label")->setTextArg("[SIZE]", std::string("----"));
|
||||
getChild<LLUICtrl>("total_time_refetch_all_cache_label")->setTextArg("[PIXEL]", std::string("----"));
|
||||
}
|
||||
else
|
||||
{
|
||||
getChild<LLUICtrl>("total_time_refetch_all_cache_label")->setTextArg("[TIME]", llformat("%.3f", mDebugger->getRefetchAllCacheTime()));
|
||||
getChild<LLUICtrl>("total_time_refetch_all_cache_label")->setTextArg("[SIZE]", llformat("%d", mDebugger->getRefetchedAllData() >> 10));
|
||||
getChild<LLUICtrl>("total_time_refetch_all_cache_label")->setTextArg("[PIXEL]", llformat("%.3f", mDebugger->getRefetchedAllPixels() / 1000000.f));
|
||||
}
|
||||
|
||||
//total time on refetching visible textures from http
|
||||
if(mDebugger->getRefetchVisHTTPTime() < 0.f)
|
||||
{
|
||||
getChild<LLUICtrl>("total_time_refetch_vis_http_label")->setTextArg("[TIME]", std::string("----"));
|
||||
getChild<LLUICtrl>("total_time_refetch_vis_http_label")->setTextArg("[SIZE]", std::string("----"));
|
||||
getChild<LLUICtrl>("total_time_refetch_vis_http_label")->setTextArg("[PIXEL]", std::string("----"));
|
||||
}
|
||||
else
|
||||
{
|
||||
getChild<LLUICtrl>("total_time_refetch_vis_http_label")->setTextArg("[TIME]", llformat("%.3f", mDebugger->getRefetchVisHTTPTime()));
|
||||
getChild<LLUICtrl>("total_time_refetch_vis_http_label")->setTextArg("[SIZE]", llformat("%d", mDebugger->getRefetchedVisData() >> 10));
|
||||
getChild<LLUICtrl>("total_time_refetch_vis_http_label")->setTextArg("[PIXEL]", llformat("%.3f", mDebugger->getRefetchedVisPixels() / 1000000.f));
|
||||
}
|
||||
|
||||
//total time on refetching all textures from http
|
||||
if(mDebugger->getRefetchAllHTTPTime() < 0.f)
|
||||
{
|
||||
getChild<LLUICtrl>("total_time_refetch_all_http_label")->setTextArg("[TIME]", std::string("----"));
|
||||
getChild<LLUICtrl>("total_time_refetch_all_http_label")->setTextArg("[SIZE]", std::string("----"));
|
||||
getChild<LLUICtrl>("total_time_refetch_all_http_label")->setTextArg("[PIXEL]", std::string("----"));
|
||||
}
|
||||
else
|
||||
{
|
||||
getChild<LLUICtrl>("total_time_refetch_all_http_label")->setTextArg("[TIME]", llformat("%.3f", mDebugger->getRefetchAllHTTPTime()));
|
||||
getChild<LLUICtrl>("total_time_refetch_all_http_label")->setTextArg("[SIZE]", llformat("%d", mDebugger->getRefetchedAllData() >> 10));
|
||||
getChild<LLUICtrl>("total_time_refetch_all_http_label")->setTextArg("[PIXEL]", llformat("%.3f", mDebugger->getRefetchedAllPixels() / 1000000.f));
|
||||
}
|
||||
|
||||
LLFloater::draw();
|
||||
}
|
||||
|
|
@ -1,77 +0,0 @@
|
|||
/**
|
||||
* @file llfloatertexturefetchdebugger.h
|
||||
* @brief texture fetching debugger window, debug use only
|
||||
*
|
||||
* $LicenseInfo:firstyear=2004&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2010, Linden Research, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#ifndef LL_FLOATER_TEXTURE_FETCH_DEBUGGER__H
|
||||
#define LL_FLOATER_TEXTURE_FETCH_DEBUGGER__H
|
||||
|
||||
#include "llfloater.h"
|
||||
class LLTextureFetchDebugger;
|
||||
|
||||
class LLFloaterTextureFetchDebugger : public LLFloater
|
||||
{
|
||||
friend class LLFloaterReg;
|
||||
public:
|
||||
/// initialize all the callbacks for the menu
|
||||
|
||||
virtual BOOL postBuild() ;
|
||||
virtual void draw() ;
|
||||
|
||||
void onChangeTexelPixelRatio();
|
||||
|
||||
void onClickStart();
|
||||
void onClickClear();
|
||||
void onClickClose();
|
||||
void onClickResetFetchTime();
|
||||
|
||||
void onClickCacheRead();
|
||||
void onClickCacheWrite();
|
||||
void onClickHTTPLoad();
|
||||
void onClickDecode();
|
||||
void onClickGLTexture();
|
||||
|
||||
void onClickRefetchVisCache();
|
||||
void onClickRefetchVisHTTP();
|
||||
void onClickRefetchAllCache();
|
||||
void onClickRefetchAllHTTP();
|
||||
public:
|
||||
void idle() ;
|
||||
|
||||
private:
|
||||
LLFloaterTextureFetchDebugger(const LLSD& key);
|
||||
virtual ~LLFloaterTextureFetchDebugger();
|
||||
|
||||
void updateButtons();
|
||||
void disableButtons();
|
||||
|
||||
void setStartStatus(S32 status);
|
||||
bool idleStart();
|
||||
private:
|
||||
LLTextureFetchDebugger* mDebugger;
|
||||
std::map<std::string, bool> mButtonStateMap;
|
||||
S32 mStartStatus;
|
||||
};
|
||||
|
||||
#endif // LL_FLOATER_TEXTURE_FETCH_DEBUGGER__H
|
||||
|
|
@ -222,8 +222,6 @@ LLInventoryModel::LLInventoryModel()
|
|||
mHttpOptions(),
|
||||
mHttpHeaders(),
|
||||
mHttpPolicyClass(LLCore::HttpRequest::DEFAULT_POLICY_ID),
|
||||
mHttpPriorityFG(0),
|
||||
mHttpPriorityBG(0),
|
||||
mCategoryLock(),
|
||||
mItemLock(),
|
||||
mValidationInfo(new LLInventoryValidationInfo)
|
||||
|
|
@ -2799,7 +2797,6 @@ LLCore::HttpHandle LLInventoryModel::requestPost(bool foreground,
|
|||
|
||||
handle = LLCoreHttpUtil::requestPostWithLLSD(request,
|
||||
mHttpPolicyClass,
|
||||
(foreground ? mHttpPriorityFG : mHttpPriorityBG),
|
||||
url,
|
||||
body,
|
||||
mHttpOptions,
|
||||
|
|
|
|||
|
|
@ -617,8 +617,6 @@ private:
|
|||
LLCore::HttpOptions::ptr_t mHttpOptions;
|
||||
LLCore::HttpHeaders::ptr_t mHttpHeaders;
|
||||
LLCore::HttpRequest::policy_t mHttpPolicyClass;
|
||||
LLCore::HttpRequest::priority_t mHttpPriorityFG;
|
||||
LLCore::HttpRequest::priority_t mHttpPriorityBG;
|
||||
|
||||
/** HTTP Transport
|
||||
** **
|
||||
|
|
|
|||
|
|
@ -133,8 +133,7 @@ LLMaterialMgr::LLMaterialMgr():
|
|||
mHttpRequest(),
|
||||
mHttpHeaders(),
|
||||
mHttpOptions(),
|
||||
mHttpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID),
|
||||
mHttpPriority(0)
|
||||
mHttpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID)
|
||||
{
|
||||
LLAppCoreHttp & app_core_http(LLAppViewer::instance()->getAppCoreHttp());
|
||||
|
||||
|
|
@ -699,7 +698,7 @@ void LLMaterialMgr::processGetQueue()
|
|||
<< "\ndata: " << ll_pretty_print_sd(materialsData) << LL_ENDL;
|
||||
|
||||
LLCore::HttpHandle handle = LLCoreHttpUtil::requestPostWithLLSD(mHttpRequest,
|
||||
mHttpPolicy, mHttpPriority, capURL,
|
||||
mHttpPolicy, capURL,
|
||||
postData, mHttpOptions, mHttpHeaders, handler);
|
||||
|
||||
if (handle == LLCORE_HTTP_HANDLE_INVALID)
|
||||
|
|
@ -985,7 +984,7 @@ void LLMaterialMgr::processPutQueue()
|
|||
));
|
||||
|
||||
LLCore::HttpHandle handle = LLCoreHttpUtil::requestPutWithLLSD(
|
||||
mHttpRequest, mHttpPolicy, mHttpPriority, capURL,
|
||||
mHttpRequest, mHttpPolicy, capURL,
|
||||
putData, mHttpOptions, mHttpHeaders, handler);
|
||||
|
||||
if (handle == LLCORE_HTTP_HANDLE_INVALID)
|
||||
|
|
|
|||
|
|
@ -141,7 +141,6 @@ private:
|
|||
LLCore::HttpHeaders::ptr_t mHttpHeaders;
|
||||
LLCore::HttpOptions::ptr_t mHttpOptions;
|
||||
LLCore::HttpRequest::policy_t mHttpPolicy;
|
||||
LLCore::HttpRequest::priority_t mHttpPriority;
|
||||
|
||||
U32 getMaxEntries(const LLViewerRegion* regionp);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -355,7 +355,7 @@ void LLMediaDataClient::serviceQueue()
|
|||
|
||||
// and make the post
|
||||
LLCore::HttpHandler::ptr_t handler = request->createHandler();
|
||||
LLCore::HttpHandle handle = LLCoreHttpUtil::requestPostWithLLSD(mHttpRequest, mHttpPolicy, 0,
|
||||
LLCore::HttpHandle handle = LLCoreHttpUtil::requestPostWithLLSD(mHttpRequest, mHttpPolicy,
|
||||
url, sd_payload, mHttpOpts, mHttpHeaders, handler);
|
||||
|
||||
if (handle == LLCORE_HTTP_HANDLE_INVALID)
|
||||
|
|
|
|||
|
|
@ -823,8 +823,7 @@ LLMeshRepoThread::LLMeshRepoThread()
|
|||
mHttpLargeOptions(),
|
||||
mHttpHeaders(),
|
||||
mHttpPolicyClass(LLCore::HttpRequest::DEFAULT_POLICY_ID),
|
||||
mHttpLargePolicyClass(LLCore::HttpRequest::DEFAULT_POLICY_ID),
|
||||
mHttpPriority(0)
|
||||
mHttpLargePolicyClass(LLCore::HttpRequest::DEFAULT_POLICY_ID)
|
||||
{
|
||||
LLAppCoreHttp & app_core_http(LLAppViewer::instance()->getAppCoreHttp());
|
||||
|
||||
|
|
@ -1268,7 +1267,6 @@ LLCore::HttpHandle LLMeshRepoThread::getByteRange(const std::string & url,
|
|||
if (len < LARGE_MESH_FETCH_THRESHOLD)
|
||||
{
|
||||
handle = mHttpRequest->requestGetByteRange( mHttpPolicyClass,
|
||||
mHttpPriority,
|
||||
url,
|
||||
(disable_range_req ? size_t(0) : offset),
|
||||
(disable_range_req ? size_t(0) : len),
|
||||
|
|
@ -1283,7 +1281,6 @@ LLCore::HttpHandle LLMeshRepoThread::getByteRange(const std::string & url,
|
|||
else
|
||||
{
|
||||
handle = mHttpRequest->requestGetByteRange(mHttpLargePolicyClass,
|
||||
mHttpPriority,
|
||||
url,
|
||||
(disable_range_req ? size_t(0) : offset),
|
||||
(disable_range_req ? size_t(0) : len),
|
||||
|
|
@ -2130,7 +2127,6 @@ LLMeshUploadThread::LLMeshUploadThread(LLMeshUploadThread::instance_list& data,
|
|||
mHttpHeaders = LLCore::HttpHeaders::ptr_t(new LLCore::HttpHeaders);
|
||||
mHttpHeaders->append(HTTP_OUT_HEADER_CONTENT_TYPE, HTTP_CONTENT_LLSD_XML);
|
||||
mHttpPolicyClass = LLAppViewer::instance()->getAppCoreHttp().getPolicy(LLAppCoreHttp::AP_UPLOADS);
|
||||
mHttpPriority = 0;
|
||||
}
|
||||
|
||||
LLMeshUploadThread::~LLMeshUploadThread()
|
||||
|
|
@ -2649,7 +2645,6 @@ void LLMeshUploadThread::doWholeModelUpload()
|
|||
|
||||
LLCore::HttpHandle handle = LLCoreHttpUtil::requestPostWithLLSD(mHttpRequest,
|
||||
mHttpPolicyClass,
|
||||
mHttpPriority,
|
||||
mWholeModelUploadURL,
|
||||
body,
|
||||
mHttpOptions,
|
||||
|
|
@ -2700,7 +2695,6 @@ void LLMeshUploadThread::requestWholeModelFee()
|
|||
dump_llsd_to_file(mModelData, make_dump_name("whole_model_fee_request_", dump_num));
|
||||
LLCore::HttpHandle handle = LLCoreHttpUtil::requestPostWithLLSD(mHttpRequest,
|
||||
mHttpPolicyClass,
|
||||
mHttpPriority,
|
||||
mWholeModelFeeCapability,
|
||||
mModelData,
|
||||
mHttpOptions,
|
||||
|
|
|
|||
|
|
@ -321,7 +321,6 @@ public:
|
|||
LLCore::HttpHeaders::ptr_t mHttpHeaders;
|
||||
LLCore::HttpRequest::policy_t mHttpPolicyClass;
|
||||
LLCore::HttpRequest::policy_t mHttpLargePolicyClass;
|
||||
LLCore::HttpRequest::priority_t mHttpPriority;
|
||||
|
||||
typedef std::set<LLCore::HttpHandler::ptr_t> http_request_set;
|
||||
http_request_set mHttpRequestSet; // Outstanding HTTP requests
|
||||
|
|
@ -489,7 +488,6 @@ private:
|
|||
LLCore::HttpOptions::ptr_t mHttpOptions;
|
||||
LLCore::HttpHeaders::ptr_t mHttpHeaders;
|
||||
LLCore::HttpRequest::policy_t mHttpPolicyClass;
|
||||
LLCore::HttpRequest::priority_t mHttpPriority;
|
||||
};
|
||||
|
||||
// Params related to streaming cost, render cost, and scene complexity tracking.
|
||||
|
|
|
|||
|
|
@ -3367,10 +3367,10 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
if (drawable->getVOVolume() && gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_TEXTURE_PRIORITY))
|
||||
/*if (drawable->getVOVolume() && gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_TEXTURE_PRIORITY))
|
||||
{
|
||||
renderTexturePriority(drawable);
|
||||
}
|
||||
}*/
|
||||
|
||||
if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_POINTS))
|
||||
{
|
||||
|
|
@ -3697,7 +3697,7 @@ void LLSpatialPartition::renderDebug()
|
|||
LLPipeline::RENDER_DEBUG_BBOXES |
|
||||
LLPipeline::RENDER_DEBUG_NORMALS |
|
||||
LLPipeline::RENDER_DEBUG_POINTS |
|
||||
LLPipeline::RENDER_DEBUG_TEXTURE_PRIORITY |
|
||||
//LLPipeline::RENDER_DEBUG_TEXTURE_PRIORITY |
|
||||
LLPipeline::RENDER_DEBUG_TEXTURE_ANIM |
|
||||
LLPipeline::RENDER_DEBUG_RAYCAST |
|
||||
LLPipeline::RENDER_DEBUG_AVATAR_VOLUME |
|
||||
|
|
|
|||
|
|
@ -95,14 +95,13 @@ private:
|
|||
};
|
||||
|
||||
public:
|
||||
LLTextureCacheWorker(LLTextureCache* cache, U32 priority, const LLUUID& id,
|
||||
LLTextureCacheWorker(LLTextureCache* cache, const LLUUID& id,
|
||||
U8* data, S32 datasize, S32 offset,
|
||||
S32 imagesize, // for writes
|
||||
LLTextureCache::Responder* responder)
|
||||
: LLWorkerClass(cache, "LLTextureCacheWorker"),
|
||||
mID(id),
|
||||
mCache(cache),
|
||||
mPriority(priority),
|
||||
mReadData(NULL),
|
||||
mWriteData(data),
|
||||
mDataSize(datasize),
|
||||
|
|
@ -115,7 +114,6 @@ public:
|
|||
mBytesToRead(0),
|
||||
mBytesRead(0)
|
||||
{
|
||||
mPriority &= LLWorkerThread::PRIORITY_LOWBITS;
|
||||
}
|
||||
~LLTextureCacheWorker()
|
||||
{
|
||||
|
|
@ -129,13 +127,12 @@ public:
|
|||
|
||||
virtual bool doWork(S32 param); // Called from LLWorkerThread::processRequest()
|
||||
|
||||
handle_t read() { addWork(0, LLWorkerThread::PRIORITY_HIGH | mPriority); return mRequestHandle; }
|
||||
handle_t write() { addWork(1, LLWorkerThread::PRIORITY_HIGH | mPriority); return mRequestHandle; }
|
||||
handle_t read() { addWork(0); return mRequestHandle; }
|
||||
handle_t write() { addWork(1); return mRequestHandle; }
|
||||
bool complete() { return checkWork(); }
|
||||
void ioComplete(S32 bytes)
|
||||
{
|
||||
mBytesRead = bytes;
|
||||
setPriority(LLWorkerThread::PRIORITY_HIGH | mPriority);
|
||||
}
|
||||
|
||||
private:
|
||||
|
|
@ -145,7 +142,6 @@ private:
|
|||
|
||||
protected:
|
||||
LLTextureCache* mCache;
|
||||
U32 mPriority;
|
||||
LLUUID mID;
|
||||
|
||||
U8* mReadData;
|
||||
|
|
@ -164,11 +160,11 @@ protected:
|
|||
class LLTextureCacheLocalFileWorker : public LLTextureCacheWorker
|
||||
{
|
||||
public:
|
||||
LLTextureCacheLocalFileWorker(LLTextureCache* cache, U32 priority, const std::string& filename, const LLUUID& id,
|
||||
LLTextureCacheLocalFileWorker(LLTextureCache* cache, const std::string& filename, const LLUUID& id,
|
||||
U8* data, S32 datasize, S32 offset,
|
||||
S32 imagesize, // for writes
|
||||
LLTextureCache::Responder* responder)
|
||||
: LLTextureCacheWorker(cache, priority, id, data, datasize, offset, imagesize, responder),
|
||||
: LLTextureCacheWorker(cache, id, data, datasize, offset, imagesize, responder),
|
||||
mFileName(filename)
|
||||
|
||||
{
|
||||
|
|
@ -183,6 +179,7 @@ private:
|
|||
|
||||
bool LLTextureCacheLocalFileWorker::doRead()
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
|
||||
S32 local_size = LLAPRFile::size(mFileName, mCache->getLocalAPRFilePool());
|
||||
|
||||
if (local_size > 0 && mFileName.size() > 4)
|
||||
|
|
@ -207,50 +204,6 @@ bool LLTextureCacheLocalFileWorker::doRead()
|
|||
return true;
|
||||
}
|
||||
|
||||
#if USE_LFS_READ
|
||||
if (mFileHandle == LLLFSThread::nullHandle())
|
||||
{
|
||||
mImageLocal = TRUE;
|
||||
mImageSize = local_size;
|
||||
if (!mDataSize || mDataSize + mOffset > local_size)
|
||||
{
|
||||
mDataSize = local_size - mOffset;
|
||||
}
|
||||
if (mDataSize <= 0)
|
||||
{
|
||||
// no more data to read
|
||||
mDataSize = 0;
|
||||
return true;
|
||||
}
|
||||
mReadData = (U8*)ALLOCATE_MEM(LLImageBase::getPrivatePool(), mDataSize);
|
||||
mBytesRead = -1;
|
||||
mBytesToRead = mDataSize;
|
||||
setPriority(LLWorkerThread::PRIORITY_LOW | mPriority);
|
||||
mFileHandle = LLLFSThread::sLocal->read(local_filename, mReadData, mOffset, mDataSize,
|
||||
new ReadResponder(mCache, mRequestHandle));
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (mBytesRead >= 0)
|
||||
{
|
||||
if (mBytesRead != mBytesToRead)
|
||||
{
|
||||
// LL_WARNS() << "Error reading file from local cache: " << local_filename
|
||||
// << " Bytes: " << mDataSize << " Offset: " << mOffset
|
||||
// << " / " << mDataSize << LL_ENDL;
|
||||
mDataSize = 0; // failed
|
||||
ll_aligned_free_16(mReadData);
|
||||
mReadData = NULL;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
#else
|
||||
if (!mDataSize || mDataSize > local_size)
|
||||
{
|
||||
mDataSize = local_size;
|
||||
|
|
@ -274,7 +227,6 @@ bool LLTextureCacheLocalFileWorker::doRead()
|
|||
mImageLocal = TRUE;
|
||||
}
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool LLTextureCacheLocalFileWorker::doWrite()
|
||||
|
|
@ -286,12 +238,12 @@ bool LLTextureCacheLocalFileWorker::doWrite()
|
|||
class LLTextureCacheRemoteWorker : public LLTextureCacheWorker
|
||||
{
|
||||
public:
|
||||
LLTextureCacheRemoteWorker(LLTextureCache* cache, U32 priority, const LLUUID& id,
|
||||
LLTextureCacheRemoteWorker(LLTextureCache* cache, const LLUUID& id,
|
||||
U8* data, S32 datasize, S32 offset,
|
||||
S32 imagesize, // for writes
|
||||
LLPointer<LLImageRaw> raw, S32 discardlevel,
|
||||
LLTextureCache::Responder* responder)
|
||||
: LLTextureCacheWorker(cache, priority, id, data, datasize, offset, imagesize, responder),
|
||||
: LLTextureCacheWorker(cache, id, data, datasize, offset, imagesize, responder),
|
||||
mState(INIT),
|
||||
mRawImage(raw),
|
||||
mRawDiscardLevel(discardlevel)
|
||||
|
|
@ -329,6 +281,7 @@ void LLTextureCacheWorker::startWork(S32 param)
|
|||
// - the code supports offset reading but this is actually never exercised in the viewer
|
||||
bool LLTextureCacheRemoteWorker::doRead()
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED;
|
||||
bool done = false;
|
||||
S32 idx = -1;
|
||||
|
||||
|
|
@ -580,6 +533,7 @@ bool LLTextureCacheRemoteWorker::doRead()
|
|||
// - the code *does not* support offset writing so there are no difference between buffer addresses and start of data
|
||||
bool LLTextureCacheRemoteWorker::doWrite()
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
|
||||
bool done = false;
|
||||
S32 idx = -1;
|
||||
|
||||
|
|
@ -756,6 +710,7 @@ bool LLTextureCacheRemoteWorker::doWrite()
|
|||
//virtual
|
||||
bool LLTextureCacheWorker::doWork(S32 param)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED;
|
||||
bool res = false;
|
||||
if (param == 0) // read
|
||||
{
|
||||
|
|
@ -775,11 +730,13 @@ bool LLTextureCacheWorker::doWork(S32 param)
|
|||
//virtual (WORKER THREAD)
|
||||
void LLTextureCacheWorker::finishWork(S32 param, bool completed)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
|
||||
if (mResponder.notNull())
|
||||
{
|
||||
bool success = (completed && mDataSize > 0);
|
||||
if (param == 0)
|
||||
{
|
||||
LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("tcwfw - read");
|
||||
// read
|
||||
if (success)
|
||||
{
|
||||
|
|
@ -789,12 +746,14 @@ void LLTextureCacheWorker::finishWork(S32 param, bool completed)
|
|||
}
|
||||
else
|
||||
{
|
||||
LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("tcwfw - read fail");
|
||||
ll_aligned_free_16(mReadData);
|
||||
mReadData = NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("tcwfw - write");
|
||||
// write
|
||||
mWriteData = NULL; // we never owned data
|
||||
mDataSize = 0;
|
||||
|
|
@ -806,6 +765,7 @@ void LLTextureCacheWorker::finishWork(S32 param, bool completed)
|
|||
//virtual (MAIN THREAD)
|
||||
void LLTextureCacheWorker::endWork(S32 param, bool aborted)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED;
|
||||
if (aborted)
|
||||
{
|
||||
// Let the destructor handle any cleanup
|
||||
|
|
@ -861,6 +821,7 @@ LLTextureCache::~LLTextureCache()
|
|||
//virtual
|
||||
S32 LLTextureCache::update(F32 max_time_ms)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
|
||||
static LLFrameTimer timer ;
|
||||
static const F32 MAX_TIME_INTERVAL = 300.f ; //seconds.
|
||||
|
||||
|
|
@ -874,22 +835,6 @@ S32 LLTextureCache::update(F32 max_time_ms)
|
|||
mCompletedList.clear();
|
||||
mListMutex.unlock();
|
||||
|
||||
lockWorkers();
|
||||
|
||||
for (handle_list_t::iterator iter1 = priorty_list.begin();
|
||||
iter1 != priorty_list.end(); ++iter1)
|
||||
{
|
||||
handle_t handle = *iter1;
|
||||
handle_map_t::iterator iter2 = mWriters.find(handle);
|
||||
if(iter2 != mWriters.end())
|
||||
{
|
||||
LLTextureCacheWorker* worker = iter2->second;
|
||||
worker->setPriority(LLWorkerThread::PRIORITY_HIGH | worker->mPriority);
|
||||
}
|
||||
}
|
||||
|
||||
unlockWorkers();
|
||||
|
||||
// call 'completed' with workers list unlocked (may call readComplete() or writeComplete()
|
||||
for (responder_list_t::iterator iter1 = completed_list.begin();
|
||||
iter1 != completed_list.end(); ++iter1)
|
||||
|
|
@ -1323,6 +1268,7 @@ void LLTextureCache::updateEntryTimeStamp(S32 idx, Entry& entry)
|
|||
//update an existing entry, write to header file immediately.
|
||||
bool LLTextureCache::updateEntry(S32& idx, Entry& entry, S32 new_image_size, S32 new_data_size)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
|
||||
S32 new_body_size = llmax(0, new_data_size - TEXTURE_CACHE_ENTRY_SIZE) ;
|
||||
|
||||
if(new_image_size == entry.mImageSize && new_body_size == entry.mBodySize)
|
||||
|
|
@ -1872,6 +1818,7 @@ void LLTextureCache::purgeTextures(bool validate)
|
|||
// call lockWorkers() first!
|
||||
LLTextureCacheWorker* LLTextureCache::getReader(handle_t handle)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
|
||||
LLTextureCacheWorker* res = NULL;
|
||||
handle_map_t::iterator iter = mReaders.find(handle);
|
||||
if (iter != mReaders.end())
|
||||
|
|
@ -1883,6 +1830,7 @@ LLTextureCacheWorker* LLTextureCache::getReader(handle_t handle)
|
|||
|
||||
LLTextureCacheWorker* LLTextureCache::getWriter(handle_t handle)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
|
||||
LLTextureCacheWorker* res = NULL;
|
||||
handle_map_t::iterator iter = mWriters.find(handle);
|
||||
if (iter != mWriters.end())
|
||||
|
|
@ -1898,6 +1846,7 @@ LLTextureCacheWorker* LLTextureCache::getWriter(handle_t handle)
|
|||
// Reads imagesize from the header, updates timestamp
|
||||
S32 LLTextureCache::getHeaderCacheEntry(const LLUUID& id, Entry& entry)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
|
||||
LLMutexLock lock(&mHeaderMutex);
|
||||
S32 idx = openAndReadEntry(id, entry, false);
|
||||
if (idx >= 0)
|
||||
|
|
@ -1910,6 +1859,7 @@ S32 LLTextureCache::getHeaderCacheEntry(const LLUUID& id, Entry& entry)
|
|||
// Writes imagesize to the header, updates timestamp
|
||||
S32 LLTextureCache::setHeaderCacheEntry(const LLUUID& id, Entry& entry, S32 imagesize, S32 datasize)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
|
||||
mHeaderMutex.lock();
|
||||
S32 idx = openAndReadEntry(id, entry, true); // read or create
|
||||
mHeaderMutex.unlock();
|
||||
|
|
@ -1942,13 +1892,14 @@ S32 LLTextureCache::setHeaderCacheEntry(const LLUUID& id, Entry& entry, S32 imag
|
|||
|
||||
// Calls from texture pipeline thread (i.e. LLTextureFetch)
|
||||
|
||||
LLTextureCache::handle_t LLTextureCache::readFromCache(const std::string& filename, const LLUUID& id, U32 priority,
|
||||
LLTextureCache::handle_t LLTextureCache::readFromCache(const std::string& filename, const LLUUID& id,
|
||||
S32 offset, S32 size, ReadResponder* responder)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
|
||||
// Note: checking to see if an entry exists can cause a stall,
|
||||
// so let the thread handle it
|
||||
LLMutexLock lock(&mWorkersMutex);
|
||||
LLTextureCacheWorker* worker = new LLTextureCacheLocalFileWorker(this, priority, filename, id,
|
||||
LLTextureCacheWorker* worker = new LLTextureCacheLocalFileWorker(this, filename, id,
|
||||
NULL, size, offset, 0,
|
||||
responder);
|
||||
handle_t handle = worker->read();
|
||||
|
|
@ -1956,13 +1907,14 @@ LLTextureCache::handle_t LLTextureCache::readFromCache(const std::string& filena
|
|||
return handle;
|
||||
}
|
||||
|
||||
LLTextureCache::handle_t LLTextureCache::readFromCache(const LLUUID& id, U32 priority,
|
||||
LLTextureCache::handle_t LLTextureCache::readFromCache(const LLUUID& id,
|
||||
S32 offset, S32 size, ReadResponder* responder)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
|
||||
// Note: checking to see if an entry exists can cause a stall,
|
||||
// so let the thread handle it
|
||||
LLMutexLock lock(&mWorkersMutex);
|
||||
LLTextureCacheWorker* worker = new LLTextureCacheRemoteWorker(this, priority, id,
|
||||
LLTextureCacheWorker* worker = new LLTextureCacheRemoteWorker(this, id,
|
||||
NULL, size, offset,
|
||||
0, NULL, 0, responder);
|
||||
handle_t handle = worker->read();
|
||||
|
|
@ -1973,6 +1925,7 @@ LLTextureCache::handle_t LLTextureCache::readFromCache(const LLUUID& id, U32 pri
|
|||
|
||||
bool LLTextureCache::readComplete(handle_t handle, bool abort)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
|
||||
lockWorkers();
|
||||
handle_map_t::iterator iter = mReaders.find(handle);
|
||||
LLTextureCacheWorker* worker = NULL;
|
||||
|
|
@ -2000,7 +1953,7 @@ bool LLTextureCache::readComplete(handle_t handle, bool abort)
|
|||
return (complete || abort);
|
||||
}
|
||||
|
||||
LLTextureCache::handle_t LLTextureCache::writeToCache(const LLUUID& id, U32 priority,
|
||||
LLTextureCache::handle_t LLTextureCache::writeToCache(const LLUUID& id,
|
||||
U8* data, S32 datasize, S32 imagesize,
|
||||
LLPointer<LLImageRaw> rawimage, S32 discardlevel,
|
||||
WriteResponder* responder)
|
||||
|
|
@ -2018,7 +1971,7 @@ LLTextureCache::handle_t LLTextureCache::writeToCache(const LLUUID& id, U32 prio
|
|||
mDoPurge = !mPurgeEntryList.empty();
|
||||
}
|
||||
LLMutexLock lock(&mWorkersMutex);
|
||||
LLTextureCacheWorker* worker = new LLTextureCacheRemoteWorker(this, priority, id,
|
||||
LLTextureCacheWorker* worker = new LLTextureCacheRemoteWorker(this, id,
|
||||
data, datasize, 0,
|
||||
imagesize, rawimage, discardlevel, responder);
|
||||
handle_t handle = worker->write();
|
||||
|
|
@ -2086,6 +2039,7 @@ LLPointer<LLImageRaw> LLTextureCache::readFromFastCache(const LLUUID& id, S32& d
|
|||
//return the fast cache location
|
||||
bool LLTextureCache::writeToFastCache(LLUUID image_id, S32 id, LLPointer<LLImageRaw> raw, S32 discardlevel)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
|
||||
//rescale image if needed
|
||||
if (raw.isNull() || raw->isBufferInvalid() || !raw->getData())
|
||||
{
|
||||
|
|
|
|||
|
|
@ -119,13 +119,13 @@ public:
|
|||
void setReadOnly(BOOL read_only) ;
|
||||
S64 initCache(ELLPath location, S64 maxsize, BOOL texture_cache_mismatch);
|
||||
|
||||
handle_t readFromCache(const std::string& local_filename, const LLUUID& id, U32 priority, S32 offset, S32 size,
|
||||
handle_t readFromCache(const std::string& local_filename, const LLUUID& id, S32 offset, S32 size,
|
||||
ReadResponder* responder);
|
||||
|
||||
handle_t readFromCache(const LLUUID& id, U32 priority, S32 offset, S32 size,
|
||||
handle_t readFromCache(const LLUUID& id, S32 offset, S32 size,
|
||||
ReadResponder* responder);
|
||||
bool readComplete(handle_t handle, bool abort);
|
||||
handle_t writeToCache(const LLUUID& id, U32 priority, U8* data, S32 datasize, S32 imagesize, LLPointer<LLImageRaw> rawimage, S32 discardlevel,
|
||||
handle_t writeToCache(const LLUUID& id, U8* data, S32 datasize, S32 imagesize, LLPointer<LLImageRaw> rawimage, S32 discardlevel,
|
||||
WriteResponder* responder);
|
||||
LLPointer<LLImageRaw> readFromFastCache(const LLUUID& id, S32& discardlevel);
|
||||
bool writeComplete(handle_t handle, bool abort = false);
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -48,7 +48,6 @@ class LLTextureFetchWorker;
|
|||
class LLImageDecodeThread;
|
||||
class LLHost;
|
||||
class LLViewerAssetStats;
|
||||
class LLTextureFetchDebugger;
|
||||
class LLTextureCache;
|
||||
class LLTextureFetchTester;
|
||||
|
||||
|
|
@ -59,7 +58,9 @@ class LLTextureFetch : public LLWorkerThread
|
|||
friend class LLTextureFetchWorker;
|
||||
|
||||
public:
|
||||
LLTextureFetch(LLTextureCache* cache, LLImageDecodeThread* imagedecodethread, bool threaded, bool qa_mode);
|
||||
static std::string getStateString(S32 state);
|
||||
|
||||
LLTextureFetch(LLTextureCache* cache, bool threaded, bool qa_mode);
|
||||
~LLTextureFetch();
|
||||
|
||||
class TFRequest;
|
||||
|
|
@ -116,10 +117,11 @@ public:
|
|||
// Threads: T*
|
||||
BOOL isFromLocalCache(const LLUUID& id);
|
||||
|
||||
// @return Magic number giving the internal state of the
|
||||
// request. We should make these codes public if we're
|
||||
// going to return them as a status value.
|
||||
//
|
||||
// get the current fetch state, if any, from the given UUID
|
||||
S32 getFetchState(const LLUUID& id);
|
||||
|
||||
// @return Fetch state of given image and associates statistics
|
||||
// See also getStateString
|
||||
// Threads: T*
|
||||
S32 getFetchState(const LLUUID& id, F32& decode_progress_p, F32& requested_priority_p,
|
||||
U32& fetch_priority_p, F32& fetch_dtime_p, F32& request_dtime_p, bool& can_use_http);
|
||||
|
|
@ -322,7 +324,6 @@ private:
|
|||
LLMutex mNetworkQueueMutex; //to protect mNetworkQueue, mHTTPTextureQueue and mCancelQueue.
|
||||
|
||||
LLTextureCache* mTextureCache;
|
||||
LLImageDecodeThread* mImageDecodeThread;
|
||||
|
||||
// Map of all requests by UUID
|
||||
typedef std::map<LLUUID,LLTextureFetchWorker*> map_t;
|
||||
|
|
@ -409,10 +410,6 @@ public:
|
|||
static LLTextureFetchTester* sTesterp;
|
||||
|
||||
private:
|
||||
//debug use
|
||||
LLTextureFetchDebugger* mFetchDebugger;
|
||||
bool mFetcherLocked;
|
||||
|
||||
e_tex_source mFetchSource;
|
||||
e_tex_source mOriginFetchSource;
|
||||
|
||||
|
|
@ -420,10 +417,6 @@ private:
|
|||
//LLAdaptiveRetryPolicy mFetchRetryPolicy;
|
||||
|
||||
public:
|
||||
//debug use
|
||||
LLTextureFetchDebugger* getFetchDebugger() { return mFetchDebugger;}
|
||||
void lockFetcher(bool lock) { mFetcherLocked = lock;}
|
||||
|
||||
void setLoadSource(e_tex_source source) {mFetchSource = source;}
|
||||
void resetLoadSource() {mFetchSource = mOriginFetchSource;}
|
||||
bool canLoadFromCache() { return mFetchSource != FROM_HTTP_ONLY;}
|
||||
|
|
@ -431,216 +424,6 @@ public:
|
|||
|
||||
//debug use
|
||||
class LLViewerFetchedTexture;
|
||||
class LLTextureFetchDebugger : public LLCore::HttpHandler
|
||||
{
|
||||
friend class LLTextureFetch;
|
||||
public:
|
||||
LLTextureFetchDebugger(LLTextureFetch* fetcher, LLTextureCache* cache, LLImageDecodeThread* imagedecodethread) ;
|
||||
~LLTextureFetchDebugger();
|
||||
|
||||
public:
|
||||
enum e_debug_state
|
||||
{
|
||||
IDLE = 0,
|
||||
START_DEBUG,
|
||||
READ_CACHE,
|
||||
WRITE_CACHE,
|
||||
DECODING,
|
||||
HTTP_FETCHING,
|
||||
GL_TEX,
|
||||
REFETCH_VIS_CACHE,
|
||||
REFETCH_VIS_HTTP,
|
||||
REFETCH_ALL_CACHE,
|
||||
REFETCH_ALL_HTTP,
|
||||
INVALID
|
||||
};
|
||||
|
||||
private:
|
||||
struct FetchEntry
|
||||
{
|
||||
enum e_curl_state
|
||||
{
|
||||
CURL_NOT_DONE = 0,
|
||||
CURL_IN_PROGRESS,
|
||||
CURL_DONE
|
||||
};
|
||||
LLUUID mID;
|
||||
S32 mRequestedSize;
|
||||
S32 mDecodedLevel;
|
||||
S32 mFetchedSize;
|
||||
S32 mDecodedSize;
|
||||
BOOL mNeedsAux;
|
||||
U32 mCacheHandle;
|
||||
LLPointer<LLImageFormatted> mFormattedImage;
|
||||
LLPointer<LLImageRaw> mRawImage;
|
||||
e_curl_state mCurlState;
|
||||
S32 mCurlReceivedSize;
|
||||
LLCore::HttpHandle mHttpHandle;
|
||||
|
||||
FetchEntry() :
|
||||
mDecodedLevel(-1),
|
||||
mFetchedSize(0),
|
||||
mDecodedSize(0),
|
||||
mHttpHandle(LLCORE_HTTP_HANDLE_INVALID)
|
||||
{}
|
||||
FetchEntry(LLUUID& id, S32 r_size, /*S32 f_discard, S32 c,*/ S32 level, S32 f_size, S32 d_size) :
|
||||
mID(id),
|
||||
mRequestedSize(r_size),
|
||||
mDecodedLevel(level),
|
||||
mFetchedSize(f_size),
|
||||
mDecodedSize(d_size),
|
||||
mNeedsAux(false),
|
||||
mHttpHandle(LLCORE_HTTP_HANDLE_INVALID)
|
||||
{}
|
||||
};
|
||||
typedef std::vector<FetchEntry> fetch_list_t;
|
||||
fetch_list_t mFetchingHistory;
|
||||
|
||||
typedef std::map<LLCore::HttpHandle, S32> handle_fetch_map_t;
|
||||
handle_fetch_map_t mHandleToFetchIndex;
|
||||
|
||||
void setDebuggerState(e_debug_state new_state) { mDebuggerState = new_state; }
|
||||
e_debug_state mDebuggerState;
|
||||
|
||||
F32 mCacheReadTime;
|
||||
F32 mCacheWriteTime;
|
||||
F32 mDecodingTime;
|
||||
F32 mHTTPTime;
|
||||
F32 mGLCreationTime;
|
||||
|
||||
F32 mTotalFetchingTime;
|
||||
F32 mRefetchVisCacheTime;
|
||||
F32 mRefetchVisHTTPTime;
|
||||
F32 mRefetchAllCacheTime;
|
||||
F32 mRefetchAllHTTPTime;
|
||||
|
||||
LLTimer mTimer;
|
||||
|
||||
LLTextureFetch* mFetcher;
|
||||
LLTextureCache* mTextureCache;
|
||||
LLImageDecodeThread* mImageDecodeThread;
|
||||
LLCore::HttpHeaders::ptr_t mHttpHeaders;
|
||||
LLCore::HttpRequest::policy_t mHttpPolicyClass;
|
||||
|
||||
S32 mNumFetchedTextures;
|
||||
S32 mNumCacheHits;
|
||||
S32 mNumVisibleFetchedTextures;
|
||||
S32 mNumVisibleFetchingRequests;
|
||||
U32 mFetchedData;
|
||||
U32 mDecodedData;
|
||||
U32 mVisibleFetchedData;
|
||||
U32 mVisibleDecodedData;
|
||||
U32 mRenderedData;
|
||||
U32 mRenderedDecodedData;
|
||||
U32 mFetchedPixels;
|
||||
U32 mRenderedPixels;
|
||||
U32 mRefetchedVisData;
|
||||
U32 mRefetchedVisPixels;
|
||||
U32 mRefetchedAllData;
|
||||
U32 mRefetchedAllPixels;
|
||||
|
||||
BOOL mFreezeHistory;
|
||||
BOOL mStopDebug;
|
||||
BOOL mClearHistory;
|
||||
BOOL mRefetchNonVis;
|
||||
|
||||
std::string mHTTPUrl;
|
||||
S32 mNbCurlRequests;
|
||||
S32 mNbCurlCompleted;
|
||||
|
||||
std::map< LLPointer<LLViewerFetchedTexture>, std::vector<S32> > mRefetchList; // treats UI textures as normal textures
|
||||
std::vector< LLPointer<LLViewerFetchedTexture> > mTempTexList;
|
||||
S32 mTempIndex;
|
||||
S32 mHistoryListIndex;
|
||||
|
||||
public:
|
||||
bool update(F32 max_time); //called in the main thread once per frame
|
||||
|
||||
//fetching history
|
||||
void clearHistory();
|
||||
void addHistoryEntry(LLTextureFetchWorker* worker);
|
||||
|
||||
// Inherited from LLCore::HttpHandler
|
||||
// Threads: Ttf
|
||||
virtual void onCompleted(LLCore::HttpHandle handle, LLCore::HttpResponse * response);
|
||||
|
||||
void startWork(e_debug_state state);
|
||||
void setStopDebug() {mStopDebug = TRUE;}
|
||||
void tryToStopDebug(); //stop everything
|
||||
void callbackCacheRead(S32 id, bool success, LLImageFormatted* image,
|
||||
S32 imagesize, BOOL islocal);
|
||||
void callbackCacheWrite(S32 id, bool success);
|
||||
void callbackDecoded(S32 id, bool success, LLImageRaw* raw, LLImageRaw* aux);
|
||||
void callbackHTTP(FetchEntry & fetch, LLCore::HttpResponse * response);
|
||||
|
||||
e_debug_state getState() {return mDebuggerState;}
|
||||
S32 getNumFetchedTextures() {return mNumFetchedTextures;}
|
||||
S32 getNumFetchingRequests() {return mFetchingHistory.size();}
|
||||
S32 getNumCacheHits() {return mNumCacheHits;}
|
||||
S32 getNumVisibleFetchedTextures() {return mNumVisibleFetchedTextures;}
|
||||
S32 getNumVisibleFetchingRequests() {return mNumVisibleFetchingRequests;}
|
||||
U32 getFetchedData() {return mFetchedData;}
|
||||
U32 getDecodedData() {return mDecodedData;}
|
||||
U32 getVisibleFetchedData() {return mVisibleFetchedData;}
|
||||
U32 getVisibleDecodedData() {return mVisibleDecodedData;}
|
||||
U32 getRenderedData() {return mRenderedData;}
|
||||
U32 getRenderedDecodedData() {return mRenderedDecodedData;}
|
||||
U32 getFetchedPixels() {return mFetchedPixels;}
|
||||
U32 getRenderedPixels() {return mRenderedPixels;}
|
||||
U32 getRefetchedVisData() {return mRefetchedVisData;}
|
||||
U32 getRefetchedVisPixels() {return mRefetchedVisPixels;}
|
||||
U32 getRefetchedAllData() {return mRefetchedAllData;}
|
||||
U32 getRefetchedAllPixels() {return mRefetchedAllPixels;}
|
||||
|
||||
F32 getCacheReadTime() {return mCacheReadTime;}
|
||||
F32 getCacheWriteTime() {return mCacheWriteTime;}
|
||||
F32 getDecodeTime() {return mDecodingTime;}
|
||||
F32 getGLCreationTime() {return mGLCreationTime;}
|
||||
F32 getHTTPTime() {return mHTTPTime;}
|
||||
F32 getTotalFetchingTime() {return mTotalFetchingTime;}
|
||||
F32 getRefetchVisCacheTime() {return mRefetchVisCacheTime;}
|
||||
F32 getRefetchVisHTTPTime() {return mRefetchVisHTTPTime;}
|
||||
F32 getRefetchAllCacheTime() {return mRefetchAllCacheTime;}
|
||||
F32 getRefetchAllHTTPTime() {return mRefetchAllHTTPTime;}
|
||||
|
||||
private:
|
||||
void init();
|
||||
void clearTextures();//clear fetching results of all textures.
|
||||
void clearCache();
|
||||
void makeRefetchList();
|
||||
void scanRefetchList();
|
||||
|
||||
void lockFetcher();
|
||||
void unlockFetcher();
|
||||
|
||||
void lockCache();
|
||||
void unlockCache();
|
||||
|
||||
void lockDecoder();
|
||||
void unlockDecoder();
|
||||
|
||||
S32 fillCurlQueue();
|
||||
|
||||
void startDebug();
|
||||
void debugCacheRead();
|
||||
void debugCacheWrite();
|
||||
void debugHTTP();
|
||||
void debugDecoder();
|
||||
void debugGLTextureCreation();
|
||||
void debugRefetchVisibleFromCache();
|
||||
void debugRefetchVisibleFromHTTP();
|
||||
void debugRefetchAllFromCache();
|
||||
void debugRefetchAllFromHTTP();
|
||||
|
||||
bool processStartDebug(F32 max_time);
|
||||
bool processGLCreation(F32 max_time);
|
||||
|
||||
private:
|
||||
static bool sDebuggerEnabled;
|
||||
public:
|
||||
static bool isEnabled() {return sDebuggerEnabled;}
|
||||
};
|
||||
|
||||
|
||||
class LLTextureFetchTester : public LLMetricPerformanceTesterBasic
|
||||
{
|
||||
|
|
|
|||
|
|
@ -49,6 +49,8 @@
|
|||
#include "llviewerobjectlist.h"
|
||||
#include "llviewertexture.h"
|
||||
#include "llviewertexturelist.h"
|
||||
#include "llviewerwindow.h"
|
||||
#include "llwindow.h"
|
||||
#include "llvovolume.h"
|
||||
#include "llviewerstats.h"
|
||||
#include "llworld.h"
|
||||
|
|
@ -117,8 +119,8 @@ public:
|
|||
LLTextureBar* bar2p = (LLTextureBar*)i2;
|
||||
LLViewerFetchedTexture *i1p = bar1p->mImagep;
|
||||
LLViewerFetchedTexture *i2p = bar2p->mImagep;
|
||||
F32 pri1 = i1p->getDecodePriority(); // i1p->mRequestedDownloadPriority
|
||||
F32 pri2 = i2p->getDecodePriority(); // i2p->mRequestedDownloadPriority
|
||||
F32 pri1 = i1p->getMaxVirtualSize();
|
||||
F32 pri2 = i2p->getMaxVirtualSize();
|
||||
if (pri1 > pri2)
|
||||
return true;
|
||||
else if (pri2 > pri1)
|
||||
|
|
@ -177,7 +179,7 @@ void LLTextureBar::draw()
|
|||
{
|
||||
color = LLColor4::magenta; // except none and alm
|
||||
}
|
||||
else if (mImagep->getDecodePriority() <= 0.0f)
|
||||
else if (mImagep->getMaxVirtualSize() <= 0.0f)
|
||||
{
|
||||
color = LLColor4::grey; color[VALPHA] = .7f;
|
||||
}
|
||||
|
|
@ -202,26 +204,13 @@ void LLTextureBar::draw()
|
|||
std::string uuid_str;
|
||||
mImagep->mID.toString(uuid_str);
|
||||
uuid_str = uuid_str.substr(0,7);
|
||||
if (mTextureView->mOrderFetch)
|
||||
{
|
||||
tex_str = llformat("%s %7.0f %d(%d) 0x%08x(%8.0f)",
|
||||
uuid_str.c_str(),
|
||||
mImagep->mMaxVirtualSize,
|
||||
mImagep->mDesiredDiscardLevel,
|
||||
mImagep->mRequestedDiscardLevel,
|
||||
mImagep->mFetchPriority,
|
||||
mImagep->getDecodePriority());
|
||||
}
|
||||
else
|
||||
{
|
||||
tex_str = llformat("%s %7.0f %d(%d) %8.0f(0x%08x)",
|
||||
uuid_str.c_str(),
|
||||
mImagep->mMaxVirtualSize,
|
||||
mImagep->mDesiredDiscardLevel,
|
||||
mImagep->mRequestedDiscardLevel,
|
||||
mImagep->getDecodePriority(),
|
||||
mImagep->mFetchPriority);
|
||||
}
|
||||
|
||||
tex_str = llformat("%s %7.0f %d(%d)",
|
||||
uuid_str.c_str(),
|
||||
mImagep->mMaxVirtualSize,
|
||||
mImagep->mDesiredDiscardLevel,
|
||||
mImagep->mRequestedDiscardLevel);
|
||||
|
||||
|
||||
LLFontGL::getFontMonospace()->renderUTF8(tex_str, 0, title_x1, getRect().getHeight(),
|
||||
color, LLFontGL::LEFT, LLFontGL::TOP);
|
||||
|
|
@ -500,10 +489,6 @@ private:
|
|||
|
||||
void LLGLTexMemBar::draw()
|
||||
{
|
||||
S32Megabytes bound_mem = LLViewerTexture::sBoundTextureMemory;
|
||||
S32Megabytes max_bound_mem = LLViewerTexture::sMaxBoundTextureMemory;
|
||||
S32Megabytes total_mem = LLViewerTexture::sTotalTextureMemory;
|
||||
S32Megabytes max_total_mem = LLViewerTexture::sMaxTotalTextureMem;
|
||||
F32 discard_bias = LLViewerTexture::sDesiredDiscardBias;
|
||||
F32 cache_usage = LLAppViewer::getTextureCache()->getUsage().valueInUnits<LLUnits::Megabytes>();
|
||||
F32 cache_max_usage = LLAppViewer::getTextureCache()->getMaxUsage().valueInUnits<LLUnits::Megabytes>();
|
||||
|
|
@ -549,15 +534,10 @@ void LLGLTexMemBar::draw()
|
|||
U32 texFetchLatMed = U32(recording.getMean(LLTextureFetch::sTexFetchLatency).value() * 1000.0f);
|
||||
U32 texFetchLatMax = U32(recording.getMax(LLTextureFetch::sTexFetchLatency).value() * 1000.0f);
|
||||
|
||||
text = llformat("GL Tot: %d/%d MB GL Free: %d Sys Free: %d MB Bound: %4d/%4d MB FBO: %d MB Raw Tot: %d MB Bias: %.2f Cache: %.1f/%.1f MB",
|
||||
total_mem.value(),
|
||||
max_total_mem.value(),
|
||||
LLImageGLThread::getFreeVRAMMegabytes(),
|
||||
text = llformat("GL Free: %d MB Sys Free: %d MB FBO: %d MB Bias: %.2f Cache: %.1f/%.1f MB",
|
||||
gViewerWindow->getWindow()->getAvailableVRAMMegabytes(),
|
||||
LLMemory::getAvailableMemKB()/1024,
|
||||
bound_mem.value(),
|
||||
max_bound_mem.value(),
|
||||
LLRenderTarget::sBytesAllocated/(1024*1024),
|
||||
LLImageRaw::sGlobalRawMemory >> 20,
|
||||
discard_bias,
|
||||
cache_usage,
|
||||
cache_max_usage);
|
||||
|
|
@ -837,7 +817,7 @@ void LLTextureView::draw()
|
|||
LL_INFOS() << imagep->getID()
|
||||
<< "\t" << tex_mem
|
||||
<< "\t" << imagep->getBoostLevel()
|
||||
<< "\t" << imagep->getDecodePriority()
|
||||
<< "\t" << imagep->getMaxVirtualSize()
|
||||
<< "\t" << imagep->getWidth()
|
||||
<< "\t" << imagep->getHeight()
|
||||
<< "\t" << cur_discard
|
||||
|
|
@ -857,7 +837,7 @@ void LLTextureView::draw()
|
|||
}
|
||||
else
|
||||
{
|
||||
pri = imagep->getDecodePriority();
|
||||
pri = imagep->getMaxVirtualSize();
|
||||
}
|
||||
pri = llclamp(pri, 0.0f, HIGH_PRIORITY-1.f);
|
||||
|
||||
|
|
|
|||
|
|
@ -341,12 +341,6 @@ static bool handleMaxPartCountChanged(const LLSD& newvalue)
|
|||
return true;
|
||||
}
|
||||
|
||||
static bool handleVideoMemoryChanged(const LLSD& newvalue)
|
||||
{
|
||||
gTextureList.updateMaxResidentTexMem(S32Megabytes(newvalue.asInteger()));
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool handleChatFontSizeChanged(const LLSD& newvalue)
|
||||
{
|
||||
if(gConsole)
|
||||
|
|
@ -706,7 +700,6 @@ void settings_setup_listeners()
|
|||
gSavedSettings.getControl("RenderShadowDetail")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _2));
|
||||
gSavedSettings.getControl("RenderDeferredSSAO")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _2));
|
||||
gSavedSettings.getControl("RenderPerformanceTest")->getSignal()->connect(boost::bind(&handleRenderPerfTestChanged, _2));
|
||||
gSavedSettings.getControl("TextureMemory")->getSignal()->connect(boost::bind(&handleVideoMemoryChanged, _2));
|
||||
gSavedSettings.getControl("ChatFontSize")->getSignal()->connect(boost::bind(&handleChatFontSizeChanged, _2));
|
||||
gSavedSettings.getControl("ChatPersistTime")->getSignal()->connect(boost::bind(&handleChatPersistTimeChanged, _2));
|
||||
gSavedSettings.getControl("ConsoleMaxLines")->getSignal()->connect(boost::bind(&handleConsoleMaxLinesChanged, _2));
|
||||
|
|
|
|||
|
|
@ -797,8 +797,6 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
|
|||
LLViewerTexture::updateClass();
|
||||
}
|
||||
|
||||
LLImageGLThread::updateClass();
|
||||
|
||||
{
|
||||
LL_RECORD_BLOCK_TIME(FTM_IMAGE_UPDATE_BUMP);
|
||||
gBumpImageList.updateImages(); // must be called before gTextureList version so that it's textures are thrown out first.
|
||||
|
|
|
|||
|
|
@ -132,7 +132,6 @@
|
|||
#include "llfloatertelehub.h"
|
||||
#include "llfloatertestinspectors.h"
|
||||
#include "llfloatertestlistview.h"
|
||||
#include "llfloatertexturefetchdebugger.h"
|
||||
#include "llfloatertools.h"
|
||||
#include "llfloatertopobjects.h"
|
||||
#include "llfloatertos.h"
|
||||
|
|
@ -284,10 +283,6 @@ void LLViewerFloaterReg::registerFloaters()
|
|||
|
||||
LLFloaterReg::add("mem_leaking", "floater_mem_leaking.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterMemLeak>);
|
||||
|
||||
if(gSavedSettings.getBOOL("TextureFetchDebuggerEnabled"))
|
||||
{
|
||||
LLFloaterReg::add("tex_fetch_debugger", "floater_texture_fetch_debugger.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterTextureFetchDebugger>);
|
||||
}
|
||||
LLFloaterReg::add("media_settings", "floater_media_settings.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterMediaSettings>);
|
||||
LLFloaterReg::add("marketplace_listings", "floater_marketplace_listings.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterMarketplaceListings>);
|
||||
LLFloaterReg::add("marketplace_validation", "floater_marketplace_validation.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterMarketplaceValidation>);
|
||||
|
|
|
|||
|
|
@ -2515,14 +2515,6 @@ class LLDevelopSetLoggingLevel : public view_listener_t
|
|||
}
|
||||
};
|
||||
|
||||
class LLDevelopTextureFetchDebugger : public view_listener_t
|
||||
{
|
||||
bool handleEvent(const LLSD& userdata)
|
||||
{
|
||||
return gSavedSettings.getBOOL("TextureFetchDebuggerEnabled");
|
||||
}
|
||||
};
|
||||
|
||||
//////////////////
|
||||
// ADMIN MENU //
|
||||
//////////////////
|
||||
|
|
@ -9471,8 +9463,6 @@ void initialize_menus()
|
|||
view_listener_t::addMenu(new LLDevelopCheckLoggingLevel(), "Develop.CheckLoggingLevel");
|
||||
view_listener_t::addMenu(new LLDevelopSetLoggingLevel(), "Develop.SetLoggingLevel");
|
||||
|
||||
//Develop (Texture Fetch Debug Console)
|
||||
view_listener_t::addMenu(new LLDevelopTextureFetchDebugger(), "Develop.SetTexFetchDebugger");
|
||||
//Develop (clear cache immediately)
|
||||
commit.add("Develop.ClearCache", boost::bind(&handle_cache_clear_immediately) );
|
||||
//Develop (override environment map)
|
||||
|
|
|
|||
|
|
@ -155,10 +155,7 @@ LLTrace::SampleStatHandle<LLUnit<F32, LLUnits::Percent> >
|
|||
static LLTrace::SampleStatHandle<bool>
|
||||
CHAT_BUBBLES("chatbubbles", "Chat Bubbles Enabled");
|
||||
|
||||
LLTrace::SampleStatHandle<F64Megabytes > GL_TEX_MEM("gltexmemstat"),
|
||||
GL_BOUND_MEM("glboundmemstat"),
|
||||
RAW_MEM("rawmemstat"),
|
||||
FORMATTED_MEM("formattedmemstat");
|
||||
LLTrace::SampleStatHandle<F64Megabytes > FORMATTED_MEM("formattedmemstat");
|
||||
LLTrace::SampleStatHandle<F64Kilobytes > DELTA_BANDWIDTH("deltabandwidth", "Increase/Decrease in bandwidth based on packet loss"),
|
||||
MAX_BANDWIDTH("maxbandwidth", "Max bandwidth setting");
|
||||
|
||||
|
|
@ -319,8 +316,6 @@ U32Bytes gTotalTextureBytesPerBoostLevel[LLViewerTexture::MAX_GL_IMAGE_CATEGOR
|
|||
extern U32 gVisCompared;
|
||||
extern U32 gVisTested;
|
||||
|
||||
LLFrameTimer gTextureTimer;
|
||||
|
||||
void update_statistics()
|
||||
{
|
||||
gTotalWorldData += gVLManager.getTotalBytes();
|
||||
|
|
@ -416,19 +411,6 @@ void update_statistics()
|
|||
}
|
||||
}
|
||||
|
||||
void update_texture_time()
|
||||
{
|
||||
if (gTextureList.isPrioRequestsFetched())
|
||||
{
|
||||
gTextureTimer.pause();
|
||||
}
|
||||
else
|
||||
{
|
||||
gTextureTimer.unpause();
|
||||
}
|
||||
|
||||
record(LLStatViewer::TEXTURE_FETCH_TIME, gTextureTimer.getElapsedTimeF32());
|
||||
}
|
||||
/*
|
||||
* The sim-side LLSD is in newsim/llagentinfo.cpp:forwardViewerStats.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -191,10 +191,8 @@ extern LLTrace::SampleStatHandle<> FPS_SAMPLE,
|
|||
|
||||
extern LLTrace::SampleStatHandle<LLUnit<F32, LLUnits::Percent> > PACKETS_LOST_PERCENT;
|
||||
|
||||
extern LLTrace::SampleStatHandle<F64Megabytes > GL_TEX_MEM,
|
||||
GL_BOUND_MEM,
|
||||
RAW_MEM,
|
||||
FORMATTED_MEM;
|
||||
extern LLTrace::SampleStatHandle<F64Megabytes > FORMATTED_MEM;
|
||||
|
||||
extern LLTrace::SampleStatHandle<F64Kilobytes > DELTA_BANDWIDTH,
|
||||
MAX_BANDWIDTH;
|
||||
extern SimMeasurement<F64Milliseconds > SIM_FRAME_TIME,
|
||||
|
|
@ -296,7 +294,6 @@ void update_statistics();
|
|||
void send_viewer_stats(bool include_preferences);
|
||||
void update_texture_time();
|
||||
|
||||
extern LLFrameTimer gTextureTimer;
|
||||
extern U32Bytes gTotalTextureData;
|
||||
extern U32Bytes gTotalObjectData;
|
||||
extern U32Bytes gTotalTextureBytesPerBoostLevel[] ;
|
||||
|
|
|
|||
|
|
@ -58,6 +58,8 @@
|
|||
#include "llvovolume.h"
|
||||
#include "llviewermedia.h"
|
||||
#include "lltexturecache.h"
|
||||
#include "llviewerwindow.h"
|
||||
#include "llwindow.h"
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// extern
|
||||
|
|
@ -76,6 +78,8 @@ LLPointer<LLViewerFetchedTexture> LLViewerFetchedTexture::sSmokeImagep = NULL;
|
|||
LLPointer<LLViewerFetchedTexture> LLViewerFetchedTexture::sFlatNormalImagep = NULL;
|
||||
LLViewerMediaTexture::media_map_t LLViewerMediaTexture::sMediaMap;
|
||||
LLTexturePipelineTester* LLViewerTextureManager::sTesterp = NULL;
|
||||
F32 LLViewerFetchedTexture::sMaxVirtualSize = F32_MAX/2.f;
|
||||
|
||||
const std::string sTesterName("TextureTester");
|
||||
|
||||
S32 LLViewerTexture::sImageCount = 0;
|
||||
|
|
@ -84,11 +88,6 @@ S32 LLViewerTexture::sAuxCount = 0;
|
|||
LLFrameTimer LLViewerTexture::sEvaluationTimer;
|
||||
F32 LLViewerTexture::sDesiredDiscardBias = 0.f;
|
||||
F32 LLViewerTexture::sDesiredDiscardScale = 1.1f;
|
||||
S32Bytes LLViewerTexture::sBoundTextureMemory;
|
||||
S32Bytes LLViewerTexture::sTotalTextureMemory;
|
||||
S32Megabytes LLViewerTexture::sMaxBoundTextureMemory;
|
||||
S32Megabytes LLViewerTexture::sMaxTotalTextureMem;
|
||||
S32Bytes LLViewerTexture::sMaxDesiredTextureMem;
|
||||
S8 LLViewerTexture::sCameraMovingDiscardBias = 0;
|
||||
F32 LLViewerTexture::sCameraMovingBias = 0.0f;
|
||||
S32 LLViewerTexture::sMaxSculptRez = 128; //max sculpt image size
|
||||
|
|
@ -471,11 +470,6 @@ void LLViewerTextureManager::cleanup()
|
|||
void LLViewerTexture::initClass()
|
||||
{
|
||||
LLImageGL::sDefaultGLTexture = LLViewerFetchedTexture::sDefaultImagep->getGLTexture();
|
||||
|
||||
if(gSavedSettings.getBOOL("TextureFetchDebuggerEnabled"))
|
||||
{
|
||||
sTexelPixelRatio = gSavedSettings.getF32("TexelPixelRatio");
|
||||
}
|
||||
}
|
||||
|
||||
// tuning params
|
||||
|
|
@ -500,7 +494,7 @@ bool LLViewerTexture::isMemoryForTextureLow()
|
|||
S32Megabytes physical;
|
||||
getGPUMemoryForTextures(gpu, physical);
|
||||
|
||||
return (gpu < MIN_FREE_TEXTURE_MEMORY) || (physical < MIN_FREE_MAIN_MEMORY);
|
||||
return (gpu < MIN_FREE_TEXTURE_MEMORY); // || (physical < MIN_FREE_MAIN_MEMORY);
|
||||
}
|
||||
|
||||
//static
|
||||
|
|
@ -514,7 +508,7 @@ bool LLViewerTexture::isMemoryForTextureSuficientlyFree()
|
|||
S32Megabytes physical;
|
||||
getGPUMemoryForTextures(gpu, physical);
|
||||
|
||||
return (gpu > DESIRED_FREE_TEXTURE_MEMORY) && (physical > DESIRED_FREE_MAIN_MEMORY);
|
||||
return (gpu > DESIRED_FREE_TEXTURE_MEMORY); // && (physical > DESIRED_FREE_MAIN_MEMORY);
|
||||
}
|
||||
|
||||
//static
|
||||
|
|
@ -535,9 +529,9 @@ void LLViewerTexture::getGPUMemoryForTextures(S32Megabytes &gpu, S32Megabytes &p
|
|||
timer.reset();
|
||||
|
||||
{
|
||||
gpu_res = (S32Megabytes) LLImageGLThread::getFreeVRAMMegabytes();
|
||||
gpu_res = (S32Megabytes)gViewerWindow->getWindow()->getAvailableVRAMMegabytes();
|
||||
|
||||
//check main memory, only works for windows.
|
||||
//check main memory, only works for windows and macos.
|
||||
LLMemory::updateMemoryInfo();
|
||||
physical_res = LLMemory::getAvailableMemKB();
|
||||
|
||||
|
|
@ -560,27 +554,7 @@ void LLViewerTexture::updateClass()
|
|||
|
||||
LLViewerMediaTexture::updateClass();
|
||||
|
||||
sBoundTextureMemory = LLImageGL::sBoundTextureMemory;
|
||||
sTotalTextureMemory = LLImageGL::sGlobalTextureMemory;
|
||||
sMaxBoundTextureMemory = gTextureList.getMaxResidentTexMem();
|
||||
sMaxTotalTextureMem = gTextureList.getMaxTotalTextureMem();
|
||||
sMaxDesiredTextureMem = sMaxTotalTextureMem; //in Bytes, by default and when total used texture memory is small.
|
||||
|
||||
if (sBoundTextureMemory >= sMaxBoundTextureMemory ||
|
||||
sTotalTextureMemory >= sMaxTotalTextureMem)
|
||||
{
|
||||
//when texture memory overflows, lower down the threshold to release the textures more aggressively.
|
||||
sMaxDesiredTextureMem = llmin(sMaxDesiredTextureMem * 0.75f, F32Bytes(gMaxVideoRam));
|
||||
|
||||
// If we are using more texture memory than we should,
|
||||
// scale up the desired discard level
|
||||
if (sEvaluationTimer.getElapsedTimeF32() > discard_delta_time)
|
||||
{
|
||||
sDesiredDiscardBias += discard_bias_delta;
|
||||
sEvaluationTimer.reset();
|
||||
}
|
||||
}
|
||||
else if(isMemoryForTextureLow())
|
||||
if(isMemoryForTextureLow())
|
||||
{
|
||||
// Note: isMemoryForTextureLow() uses 1s delay, make sure we waited enough for it to recheck
|
||||
if (sEvaluationTimer.getElapsedTimeF32() > GPU_MEMORY_CHECK_WAIT_TIME)
|
||||
|
|
@ -590,8 +564,6 @@ void LLViewerTexture::updateClass()
|
|||
}
|
||||
}
|
||||
else if (sDesiredDiscardBias > 0.0f
|
||||
&& sBoundTextureMemory < sMaxBoundTextureMemory * texmem_lower_bound_scale
|
||||
&& sTotalTextureMemory < sMaxTotalTextureMem * texmem_lower_bound_scale
|
||||
&& isMemoryForTextureSuficientlyFree())
|
||||
{
|
||||
// If we are using less texture memory than we should,
|
||||
|
|
@ -661,7 +633,6 @@ void LLViewerTexture::init(bool firstinit)
|
|||
mMaxVirtualSize = 0.f;
|
||||
mMaxVirtualSizeResetInterval = 1;
|
||||
mMaxVirtualSizeResetCounter = mMaxVirtualSizeResetInterval;
|
||||
mAdditionalDecodePriority = 0.f;
|
||||
mParcelMedia = NULL;
|
||||
|
||||
memset(&mNumVolumes, 0, sizeof(U32)* LLRender::NUM_VOLUME_TEXTURE_CHANNELS);
|
||||
|
|
@ -689,6 +660,11 @@ void LLViewerTexture::cleanup()
|
|||
{
|
||||
notifyAboutMissingAsset();
|
||||
|
||||
if (LLAppViewer::getTextureFetch())
|
||||
{
|
||||
LLAppViewer::getTextureFetch()->updateRequestPriority(mID, 0.f);
|
||||
}
|
||||
|
||||
mFaceList[LLRender::DIFFUSE_MAP].clear();
|
||||
mFaceList[LLRender::NORMAL_MAP].clear();
|
||||
mFaceList[LLRender::SPECULAR_MAP].clear();
|
||||
|
|
@ -745,6 +721,12 @@ void LLViewerTexture::setBoostLevel(S32 level)
|
|||
}
|
||||
}
|
||||
|
||||
// strongly encourage anything boosted to load at full res
|
||||
if (mBoostLevel >= LLViewerTexture::BOOST_HIGH)
|
||||
{
|
||||
mMaxVirtualSize = 2048.f * 2048.f;
|
||||
}
|
||||
|
||||
if (mBoostLevel == LLViewerTexture::BOOST_SELECTED)
|
||||
{
|
||||
mSelectedTime = gFrameTimeSeconds;
|
||||
|
|
@ -828,15 +810,8 @@ void LLViewerTexture::addTextureStats(F32 virtual_size, BOOL needs_gltexture) co
|
|||
}
|
||||
|
||||
virtual_size *= sTexelPixelRatio;
|
||||
if(!mMaxVirtualSizeResetCounter)
|
||||
{
|
||||
//flag to reset the values because the old values are used.
|
||||
resetMaxVirtualSizeResetCounter();
|
||||
mMaxVirtualSize = virtual_size;
|
||||
mAdditionalDecodePriority = 0.f;
|
||||
mNeedsGLTexture = needs_gltexture;
|
||||
}
|
||||
else if (virtual_size > mMaxVirtualSize)
|
||||
|
||||
if (virtual_size > mMaxVirtualSize)
|
||||
{
|
||||
mMaxVirtualSize = virtual_size;
|
||||
}
|
||||
|
|
@ -845,7 +820,6 @@ void LLViewerTexture::addTextureStats(F32 virtual_size, BOOL needs_gltexture) co
|
|||
void LLViewerTexture::resetTextureStats()
|
||||
{
|
||||
mMaxVirtualSize = 0.0f;
|
||||
mAdditionalDecodePriority = 0.f;
|
||||
mMaxVirtualSizeResetCounter = 0;
|
||||
}
|
||||
|
||||
|
|
@ -1114,7 +1088,6 @@ void LLViewerFetchedTexture::init(bool firstinit)
|
|||
|
||||
if (firstinit)
|
||||
{
|
||||
mDecodePriority = 0.f;
|
||||
mInImageList = 0;
|
||||
}
|
||||
|
||||
|
|
@ -1163,6 +1136,7 @@ void LLViewerFetchedTexture::init(bool firstinit)
|
|||
|
||||
LLViewerFetchedTexture::~LLViewerFetchedTexture()
|
||||
{
|
||||
assert_main_thread();
|
||||
//*NOTE getTextureFetch can return NULL when Viewer is shutting down.
|
||||
// This is due to LLWearableList is singleton and is destroyed after
|
||||
// LLAppViewer::cleanup() was called. (see ticket EXT-177)
|
||||
|
|
@ -1359,10 +1333,7 @@ void LLViewerFetchedTexture::dump()
|
|||
void LLViewerFetchedTexture::destroyTexture()
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
|
||||
if(LLImageGL::sGlobalTextureMemory < sMaxDesiredTextureMem * 0.95f)//not ready to release unused memory.
|
||||
{
|
||||
return ;
|
||||
}
|
||||
|
||||
if (mNeedsCreateTexture)//return if in the process of generating a new texture.
|
||||
{
|
||||
return;
|
||||
|
|
@ -1598,6 +1569,7 @@ BOOL LLViewerFetchedTexture::createTexture(S32 usename/*= 0*/)
|
|||
|
||||
void LLViewerFetchedTexture::postCreateTexture()
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
|
||||
if (!mNeedsCreateTexture)
|
||||
{
|
||||
return;
|
||||
|
|
@ -1621,6 +1593,8 @@ void LLViewerFetchedTexture::postCreateTexture()
|
|||
|
||||
void LLViewerFetchedTexture::scheduleCreateTexture()
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
|
||||
|
||||
if (!mNeedsCreateTexture)
|
||||
{
|
||||
mNeedsCreateTexture = TRUE;
|
||||
|
|
@ -1697,6 +1671,7 @@ void LLViewerFetchedTexture::scheduleCreateTexture()
|
|||
//virtual
|
||||
void LLViewerFetchedTexture::setKnownDrawSize(S32 width, S32 height)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
|
||||
if(mKnownDrawWidth < width || mKnownDrawHeight < height)
|
||||
{
|
||||
mKnownDrawWidth = llmax(mKnownDrawWidth, width);
|
||||
|
|
@ -1708,9 +1683,31 @@ void LLViewerFetchedTexture::setKnownDrawSize(S32 width, S32 height)
|
|||
addTextureStats((F32)(mKnownDrawWidth * mKnownDrawHeight));
|
||||
}
|
||||
|
||||
void LLViewerFetchedTexture::setDebugText(const std::string& text)
|
||||
{
|
||||
for (U32 ch = 0; ch < LLRender::NUM_TEXTURE_CHANNELS; ++ch)
|
||||
{
|
||||
llassert(mNumFaces[ch] <= mFaceList[ch].size());
|
||||
|
||||
for (U32 i = 0; i < mNumFaces[ch]; i++)
|
||||
{
|
||||
LLFace* facep = mFaceList[ch][i];
|
||||
if (facep)
|
||||
{
|
||||
LLDrawable* drawable = facep->getDrawable();
|
||||
if (drawable)
|
||||
{
|
||||
drawable->getVObj()->setDebugText(text);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//virtual
|
||||
void LLViewerFetchedTexture::processTextureStats()
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
|
||||
if(mFullyLoaded)
|
||||
{
|
||||
if(mDesiredDiscardLevel > mMinDesiredDiscardLevel)//need to load more
|
||||
|
|
@ -1718,6 +1715,7 @@ void LLViewerFetchedTexture::processTextureStats()
|
|||
mDesiredDiscardLevel = llmin(mDesiredDiscardLevel, mMinDesiredDiscardLevel);
|
||||
mFullyLoaded = FALSE;
|
||||
}
|
||||
//setDebugText("fully loaded");
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -1730,7 +1728,7 @@ void LLViewerFetchedTexture::processTextureStats()
|
|||
mDesiredDiscardLevel = 0;
|
||||
}
|
||||
else if (!LLPipeline::sRenderDeferred && mBoostLevel == LLGLTexture::BOOST_ALM)
|
||||
{
|
||||
{ // ??? don't load spec and normal maps when alm is disabled ???
|
||||
mDesiredDiscardLevel = MAX_DISCARD_LEVEL + 1;
|
||||
}
|
||||
else if (mDontDiscard && mBoostLevel == LLGLTexture::BOOST_ICON)
|
||||
|
|
@ -1788,198 +1786,8 @@ void LLViewerFetchedTexture::processTextureStats()
|
|||
}
|
||||
}
|
||||
|
||||
const F32 MAX_PRIORITY_PIXEL = 999.f; //pixel area
|
||||
const F32 PRIORITY_BOOST_LEVEL_FACTOR = 1000.f; //boost level
|
||||
const F32 PRIORITY_DELTA_DISCARD_LEVEL_FACTOR = 100000.f; //delta discard
|
||||
const S32 MAX_DELTA_DISCARD_LEVEL_FOR_PRIORITY = 4;
|
||||
const F32 PRIORITY_ADDITIONAL_FACTOR = 1000000.f; //additional
|
||||
const S32 MAX_ADDITIONAL_LEVEL_FOR_PRIORITY = 8;
|
||||
const F32 PRIORITY_BOOST_HIGH_FACTOR = 10000000.f;//boost high
|
||||
F32 LLViewerFetchedTexture::calcDecodePriority()
|
||||
{
|
||||
#ifndef LL_RELEASE_FOR_DOWNLOAD
|
||||
if (mID == LLAppViewer::getTextureFetch()->mDebugID)
|
||||
{
|
||||
LLAppViewer::getTextureFetch()->mDebugCount++; // for setting breakpoints
|
||||
}
|
||||
#endif
|
||||
|
||||
if (mNeedsCreateTexture)
|
||||
{
|
||||
return mDecodePriority; // no change while waiting to create
|
||||
}
|
||||
if(mFullyLoaded && !mForceToSaveRawImage)//already loaded for static texture
|
||||
{
|
||||
return -1.0f; //alreay fetched
|
||||
}
|
||||
|
||||
S32 cur_discard = getCurrentDiscardLevelForFetching();
|
||||
bool have_all_data = (cur_discard >= 0 && (cur_discard <= mDesiredDiscardLevel));
|
||||
F32 pixel_priority = (F32) sqrt(mMaxVirtualSize);
|
||||
|
||||
F32 priority = 0.f;
|
||||
|
||||
if (mIsMissingAsset)
|
||||
{
|
||||
priority = 0.0f;
|
||||
}
|
||||
else if(mDesiredDiscardLevel >= cur_discard && cur_discard > -1)
|
||||
{
|
||||
priority = -2.0f;
|
||||
}
|
||||
else if(mCachedRawDiscardLevel > -1 && mDesiredDiscardLevel >= mCachedRawDiscardLevel)
|
||||
{
|
||||
priority = -3.0f;
|
||||
}
|
||||
else if (mDesiredDiscardLevel > getMaxDiscardLevel())
|
||||
{
|
||||
// Don't decode anything we don't need
|
||||
priority = -4.0f;
|
||||
}
|
||||
else if ((mBoostLevel == LLGLTexture::BOOST_UI || mBoostLevel == LLGLTexture::BOOST_ICON) && !have_all_data)
|
||||
{
|
||||
priority = 1.f;
|
||||
}
|
||||
else if (pixel_priority < 0.001f && !have_all_data)
|
||||
{
|
||||
// Not on screen but we might want some data
|
||||
if (mBoostLevel > BOOST_SELECTED)
|
||||
{
|
||||
// Always want high boosted images
|
||||
priority = 1.f;
|
||||
}
|
||||
else
|
||||
{
|
||||
priority = -5.f; //stop fetching
|
||||
}
|
||||
}
|
||||
else if (cur_discard < 0)
|
||||
{
|
||||
//texture does not have any data, so we don't know the size of the image, treat it like 32 * 32.
|
||||
// priority range = 100,000 - 500,000
|
||||
static const F64 log_2 = log(2.0);
|
||||
F32 desired = (F32)(log(32.0/pixel_priority) / log_2);
|
||||
S32 ddiscard = MAX_DISCARD_LEVEL - (S32)desired;
|
||||
ddiscard = llclamp(ddiscard, 0, MAX_DELTA_DISCARD_LEVEL_FOR_PRIORITY);
|
||||
priority = (ddiscard + 1) * PRIORITY_DELTA_DISCARD_LEVEL_FACTOR;
|
||||
setAdditionalDecodePriority(0.1f);//boost the textures without any data so far.
|
||||
}
|
||||
else if ((mMinDiscardLevel > 0) && (cur_discard <= mMinDiscardLevel))
|
||||
{
|
||||
// larger mips are corrupted
|
||||
priority = -6.0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
// priority range = 100,000 - 500,000
|
||||
S32 desired_discard = mDesiredDiscardLevel;
|
||||
if (!isJustBound() && mCachedRawImageReady)
|
||||
{
|
||||
if(mBoostLevel < BOOST_HIGH)
|
||||
{
|
||||
// We haven't rendered this in a while, de-prioritize it
|
||||
desired_discard += 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
// We haven't rendered this in the last half second, and we have a cached raw image, leave the desired discard as-is
|
||||
desired_discard = cur_discard;
|
||||
}
|
||||
}
|
||||
|
||||
S32 ddiscard = cur_discard - desired_discard;
|
||||
ddiscard = llclamp(ddiscard, -1, MAX_DELTA_DISCARD_LEVEL_FOR_PRIORITY);
|
||||
priority = (ddiscard + 1) * PRIORITY_DELTA_DISCARD_LEVEL_FACTOR;
|
||||
}
|
||||
|
||||
// Priority Formula:
|
||||
// BOOST_HIGH + ADDITIONAL PRI + DELTA DISCARD + BOOST LEVEL + PIXELS
|
||||
// [10,000,000] + [1,000,000-9,000,000] + [100,000-500,000] + [1-20,000] + [0-999]
|
||||
if (priority > 0.0f)
|
||||
{
|
||||
bool large_enough = mCachedRawImageReady && ((S32)mTexelsPerImage > sMinLargeImageSize);
|
||||
if(large_enough)
|
||||
{
|
||||
//Note:
|
||||
//to give small, low-priority textures some chance to be fetched,
|
||||
//cut the priority in half if the texture size is larger than 256 * 256 and has a 64*64 ready.
|
||||
priority *= 0.5f;
|
||||
}
|
||||
|
||||
pixel_priority = llclamp(pixel_priority, 0.0f, MAX_PRIORITY_PIXEL);
|
||||
|
||||
priority += pixel_priority + PRIORITY_BOOST_LEVEL_FACTOR * mBoostLevel;
|
||||
|
||||
if ( mBoostLevel > BOOST_HIGH)
|
||||
{
|
||||
if(mBoostLevel > BOOST_SUPER_HIGH)
|
||||
{
|
||||
//for very important textures, always grant the highest priority.
|
||||
priority += PRIORITY_BOOST_HIGH_FACTOR;
|
||||
}
|
||||
else if(mCachedRawImageReady)
|
||||
{
|
||||
//Note:
|
||||
//to give small, low-priority textures some chance to be fetched,
|
||||
//if high priority texture has a 64*64 ready, lower its fetching priority.
|
||||
setAdditionalDecodePriority(0.5f);
|
||||
}
|
||||
else
|
||||
{
|
||||
priority += PRIORITY_BOOST_HIGH_FACTOR;
|
||||
}
|
||||
}
|
||||
|
||||
if(mAdditionalDecodePriority > 0.0f)
|
||||
{
|
||||
// priority range += 1,000,000.f-9,000,000.f
|
||||
F32 additional = PRIORITY_ADDITIONAL_FACTOR * (1.0 + mAdditionalDecodePriority * MAX_ADDITIONAL_LEVEL_FOR_PRIORITY);
|
||||
if(large_enough)
|
||||
{
|
||||
//Note:
|
||||
//to give small, low-priority textures some chance to be fetched,
|
||||
//cut the additional priority to a quarter if the texture size is larger than 256 * 256 and has a 64*64 ready.
|
||||
additional *= 0.25f;
|
||||
}
|
||||
priority += additional;
|
||||
}
|
||||
}
|
||||
return priority;
|
||||
}
|
||||
|
||||
//static
|
||||
F32 LLViewerFetchedTexture::maxDecodePriority()
|
||||
{
|
||||
static const F32 max_priority = PRIORITY_BOOST_HIGH_FACTOR + //boost_high
|
||||
PRIORITY_ADDITIONAL_FACTOR * (MAX_ADDITIONAL_LEVEL_FOR_PRIORITY + 1) + //additional (view dependent factors)
|
||||
PRIORITY_DELTA_DISCARD_LEVEL_FACTOR * (MAX_DELTA_DISCARD_LEVEL_FOR_PRIORITY + 1) + //delta discard
|
||||
PRIORITY_BOOST_LEVEL_FACTOR * (BOOST_MAX_LEVEL - 1) + //boost level
|
||||
MAX_PRIORITY_PIXEL + 1.0f; //pixel area.
|
||||
|
||||
return max_priority;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
|
||||
void LLViewerFetchedTexture::setDecodePriority(F32 priority)
|
||||
{
|
||||
mDecodePriority = priority;
|
||||
|
||||
if(mDecodePriority < F_ALMOST_ZERO)
|
||||
{
|
||||
mStopFetchingTimer.reset();
|
||||
}
|
||||
}
|
||||
|
||||
void LLViewerFetchedTexture::setAdditionalDecodePriority(F32 priority)
|
||||
{
|
||||
priority = llclamp(priority, 0.f, 1.f);
|
||||
if(mAdditionalDecodePriority < priority)
|
||||
{
|
||||
mAdditionalDecodePriority = priority;
|
||||
}
|
||||
}
|
||||
|
||||
void LLViewerFetchedTexture::updateVirtualSize()
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
|
||||
|
|
@ -1988,6 +1796,18 @@ void LLViewerFetchedTexture::updateVirtualSize()
|
|||
addTextureStats(0.f, FALSE);//reset
|
||||
}
|
||||
|
||||
if (getBoostLevel() >= LLViewerTexture::BOOST_HIGH)
|
||||
{ //always load boosted textures at highest priority full res
|
||||
addTextureStats(sMaxVirtualSize);
|
||||
return;
|
||||
}
|
||||
|
||||
if (sDesiredDiscardBias > 0.f)
|
||||
{
|
||||
// running out of video memory, don't hold onto high res textures in the background
|
||||
mMaxVirtualSize = 0.f;
|
||||
}
|
||||
|
||||
for (U32 ch = 0; ch < LLRender::NUM_TEXTURE_CHANNELS; ++ch)
|
||||
{
|
||||
llassert(mNumFaces[ch] <= mFaceList[ch].size());
|
||||
|
|
@ -2009,8 +1829,12 @@ void LLViewerFetchedTexture::updateVirtualSize()
|
|||
setBoostLevel(LLViewerTexture::BOOST_SELECTED);
|
||||
}
|
||||
addTextureStats(facep->getVirtualSize());
|
||||
setAdditionalDecodePriority(facep->getImportanceToCamera());
|
||||
//drawable->getVObj()->setDebugText(llformat("%d:%d", (S32)sqrtf(facep->getVirtualSize()), (S32)sqrtf(getMaxVirtualSize())));
|
||||
}
|
||||
else
|
||||
{
|
||||
//drawable->getVObj()->setDebugText("");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -2072,6 +1896,16 @@ bool LLViewerFetchedTexture::isActiveFetching()
|
|||
return mFetchState > 7 && mFetchState < 10 && monitor_enabled; //in state of WAIT_HTTP_REQ or DECODE_IMAGE.
|
||||
}
|
||||
|
||||
void LLViewerFetchedTexture::setBoostLevel(S32 level)
|
||||
{
|
||||
LLViewerTexture::setBoostLevel(level);
|
||||
|
||||
if (level >= LLViewerTexture::BOOST_HIGH)
|
||||
{
|
||||
mDesiredDiscardLevel = 0;
|
||||
}
|
||||
}
|
||||
|
||||
bool LLViewerFetchedTexture::updateFetch()
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
|
||||
|
|
@ -2098,31 +1932,40 @@ bool LLViewerFetchedTexture::updateFetch()
|
|||
|
||||
if (mNeedsCreateTexture)
|
||||
{
|
||||
LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("vftuf - needs create");
|
||||
// We may be fetching still (e.g. waiting on write)
|
||||
// but don't check until we've processed the raw data we have
|
||||
return false;
|
||||
}
|
||||
if (mIsMissingAsset)
|
||||
{
|
||||
LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("vftuf - missing asset");
|
||||
llassert_always(!mHasFetcher);
|
||||
return false; // skip
|
||||
}
|
||||
if (!mLoadedCallbackList.empty() && mRawImage.notNull())
|
||||
{
|
||||
LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("vftuf - callback pending");
|
||||
return false; // process any raw image data in callbacks before replacing
|
||||
}
|
||||
if(mInFastCacheList)
|
||||
{
|
||||
LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("vftuf - in fast cache");
|
||||
return false;
|
||||
}
|
||||
if (mGLTexturep.isNull())
|
||||
{ // fix for crash inside getCurrentDiscardLevelForFetching (shouldn't happen but appears to be happening)
|
||||
llassert(false);
|
||||
return false;
|
||||
}
|
||||
|
||||
S32 current_discard = getCurrentDiscardLevelForFetching();
|
||||
S32 desired_discard = getDesiredDiscardLevel();
|
||||
F32 decode_priority = getDecodePriority();
|
||||
decode_priority = llclamp(decode_priority, 0.0f, maxDecodePriority());
|
||||
F32 decode_priority = mMaxVirtualSize;
|
||||
|
||||
if (mIsFetching)
|
||||
{
|
||||
LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("vftuf - is fetching");
|
||||
// Sets mRawDiscardLevel, mRawImage, mAuxRawImage
|
||||
S32 fetch_discard = current_discard;
|
||||
|
||||
|
|
@ -2140,17 +1983,25 @@ bool LLViewerFetchedTexture::updateFetch()
|
|||
if (finished)
|
||||
{
|
||||
mIsFetching = FALSE;
|
||||
mLastFetchState = -1;
|
||||
setDebugText("");
|
||||
mLastPacketTimer.reset();
|
||||
}
|
||||
else
|
||||
{
|
||||
mFetchState = LLAppViewer::getTextureFetch()->getFetchState(mID, mDownloadProgress, mRequestedDownloadPriority,
|
||||
mFetchPriority, mFetchDeltaTime, mRequestDeltaTime, mCanUseHTTP);
|
||||
/*if (mFetchState != mLastFetchState)
|
||||
{
|
||||
setDebugText(LLTextureFetch::getStateString(mFetchState));
|
||||
mLastFetchState = mFetchState;
|
||||
}*/
|
||||
}
|
||||
|
||||
// We may have data ready regardless of whether or not we are finished (e.g. waiting on write)
|
||||
if (mRawImage.notNull())
|
||||
{
|
||||
LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("vftuf - has raw image");
|
||||
LLTexturePipelineTester* tester = (LLTexturePipelineTester*)LLMetricPerformanceTesterBasic::getTester(sTesterName);
|
||||
if (tester)
|
||||
{
|
||||
|
|
@ -2161,6 +2012,7 @@ bool LLViewerFetchedTexture::updateFetch()
|
|||
if ((mRawImage->getDataSize() > 0 && mRawDiscardLevel >= 0) &&
|
||||
(current_discard < 0 || mRawDiscardLevel < current_discard))
|
||||
{
|
||||
LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("vftuf - data good");
|
||||
mFullWidth = mRawImage->getWidth() << mRawDiscardLevel;
|
||||
mFullHeight = mRawImage->getHeight() << mRawDiscardLevel;
|
||||
setTexelsPerImage();
|
||||
|
|
@ -2197,6 +2049,7 @@ bool LLViewerFetchedTexture::updateFetch()
|
|||
}
|
||||
else
|
||||
{
|
||||
LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("vftuf - data not needed");
|
||||
// Data is ready but we don't need it
|
||||
// (received it already while fetcher was writing to disk)
|
||||
destroyRawImage();
|
||||
|
|
@ -2206,7 +2059,7 @@ bool LLViewerFetchedTexture::updateFetch()
|
|||
|
||||
if (!mIsFetching)
|
||||
{
|
||||
if ((decode_priority > 0) && (mRawDiscardLevel < 0 || mRawDiscardLevel == INVALID_DISCARD_LEVEL))
|
||||
if ((decode_priority > 0) && (mRawDiscardLevel < 0))
|
||||
{
|
||||
// We finished but received no data
|
||||
if (getDiscardLevel() < 0)
|
||||
|
|
@ -2229,13 +2082,13 @@ bool LLViewerFetchedTexture::updateFetch()
|
|||
if(current_discard >= 0)
|
||||
{
|
||||
mMinDiscardLevel = current_discard;
|
||||
desired_discard = current_discard;
|
||||
//desired_discard = current_discard;
|
||||
}
|
||||
else
|
||||
{
|
||||
S32 dis_level = getDiscardLevel();
|
||||
mMinDiscardLevel = dis_level;
|
||||
desired_discard = dis_level;
|
||||
//desired_discard = dis_level;
|
||||
}
|
||||
}
|
||||
destroyRawImage();
|
||||
|
|
@ -2249,12 +2102,6 @@ bool LLViewerFetchedTexture::updateFetch()
|
|||
}
|
||||
else
|
||||
{
|
||||
// // Useful debugging code for undesired deprioritization of textures.
|
||||
// if (decode_priority <= 0.0f && desired_discard >= 0 && desired_discard < current_discard)
|
||||
// {
|
||||
// LL_INFOS() << "Calling updateRequestPriority() with decode_priority = 0.0f" << LL_ENDL;
|
||||
// calcDecodePriority();
|
||||
// }
|
||||
static const F32 MAX_HOLD_TIME = 5.0f; //seconds to wait before canceling fecthing if decode_priority is 0.f.
|
||||
if(decode_priority > 0.0f || mStopFetchingTimer.getElapsedTimeF32() > MAX_HOLD_TIME)
|
||||
{
|
||||
|
|
@ -2264,21 +2111,27 @@ bool LLViewerFetchedTexture::updateFetch()
|
|||
}
|
||||
}
|
||||
|
||||
desired_discard = llmin(desired_discard, getMaxDiscardLevel());
|
||||
|
||||
bool make_request = true;
|
||||
if (decode_priority <= 0)
|
||||
/*if (decode_priority <= 0)
|
||||
{
|
||||
LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("vftuf - priority <= 0");
|
||||
make_request = false;
|
||||
}
|
||||
else if(mDesiredDiscardLevel > getMaxDiscardLevel())
|
||||
{
|
||||
LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("vftuf - desired > max");
|
||||
make_request = false;
|
||||
}
|
||||
else if (mNeedsCreateTexture || mIsMissingAsset)
|
||||
else */ if (mNeedsCreateTexture || mIsMissingAsset)
|
||||
{
|
||||
LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("vftuf - create or missing");
|
||||
make_request = false;
|
||||
}
|
||||
else if (current_discard >= 0 && current_discard <= mMinDiscardLevel)
|
||||
{
|
||||
LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("vftuf - current < min");
|
||||
make_request = false;
|
||||
}
|
||||
else if(mCachedRawImage.notNull() // can be empty
|
||||
|
|
@ -2295,6 +2148,7 @@ bool LLViewerFetchedTexture::updateFetch()
|
|||
|
||||
if (make_request)
|
||||
{
|
||||
#if 0
|
||||
// Load the texture progressively: we try not to rush to the desired discard too fast.
|
||||
// If the camera is not moving, we do not tweak the discard level notch by notch but go to the desired discard with larger boosted steps
|
||||
// This mitigates the "textures stay blurry" problem when loading while not killing the texture memory while moving around
|
||||
|
|
@ -2311,18 +2165,23 @@ bool LLViewerFetchedTexture::updateFetch()
|
|||
{
|
||||
desired_discard = llmax(desired_discard, current_discard - delta_level);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (mIsFetching)
|
||||
{
|
||||
// already requested a higher resolution mip
|
||||
if (mRequestedDiscardLevel <= desired_discard)
|
||||
{
|
||||
LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("vftuf - requested < desired");
|
||||
make_request = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// already at a higher resolution mip, don't discard
|
||||
if (current_discard >= 0 && current_discard <= desired_discard)
|
||||
{
|
||||
LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("vftuf - current <= desired");
|
||||
make_request = false;
|
||||
}
|
||||
}
|
||||
|
|
@ -2330,6 +2189,7 @@ bool LLViewerFetchedTexture::updateFetch()
|
|||
|
||||
if (make_request)
|
||||
{
|
||||
LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("vftuf - make request");
|
||||
S32 w=0, h=0, c=0;
|
||||
if (getDiscardLevel() >= 0)
|
||||
{
|
||||
|
|
@ -2351,6 +2211,7 @@ bool LLViewerFetchedTexture::updateFetch()
|
|||
|
||||
if (fetch_request_created)
|
||||
{
|
||||
LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("vftuf - request created");
|
||||
mHasFetcher = TRUE;
|
||||
mIsFetching = TRUE;
|
||||
mRequestedDiscardLevel = desired_discard;
|
||||
|
|
@ -2358,15 +2219,18 @@ bool LLViewerFetchedTexture::updateFetch()
|
|||
mFetchPriority, mFetchDeltaTime, mRequestDeltaTime, mCanUseHTTP);
|
||||
}
|
||||
|
||||
// if createRequest() failed, we're finishing up a request for this UUID,
|
||||
// wait for it to complete
|
||||
// If createRequest() failed, that means one of two things:
|
||||
// 1. We're finishing up a request for this UUID, so we
|
||||
// should wait for it to complete
|
||||
// 2. We've failed a request for this UUID, so there is
|
||||
// no need to create another request
|
||||
}
|
||||
else if (mHasFetcher && !mIsFetching)
|
||||
{
|
||||
// Only delete requests that haven't received any network data
|
||||
// for a while. Note - this is the normal mechanism for
|
||||
// deleting requests, not just a place to handle timeouts.
|
||||
const F32 FETCH_IDLE_TIME = 5.f;
|
||||
const F32 FETCH_IDLE_TIME = 0.1f;
|
||||
if (mLastPacketTimer.getElapsedTimeF32() > FETCH_IDLE_TIME)
|
||||
{
|
||||
LL_DEBUGS("Texture") << "exceeded idle time " << FETCH_IDLE_TIME << ", deleting request: " << getID() << LL_ENDL;
|
||||
|
|
@ -2676,7 +2540,7 @@ bool LLViewerFetchedTexture::doLoadedCallbacks()
|
|||
LL_INFOS() << "baked texture: " << mID << "clears all call backs due to inactivity." << LL_ENDL;
|
||||
LL_INFOS() << mUrl << LL_ENDL;
|
||||
LL_INFOS() << "current discard: " << getDiscardLevel() << " current discard for fetch: " << getCurrentDiscardLevelForFetching() <<
|
||||
" Desired discard: " << getDesiredDiscardLevel() << "decode Pri: " << getDecodePriority() << LL_ENDL;
|
||||
" Desired discard: " << getDesiredDiscardLevel() << "decode Pri: " << mMaxVirtualSize << LL_ENDL;
|
||||
}
|
||||
|
||||
clearCallbackEntryList() ; //remove all callbacks.
|
||||
|
|
@ -2907,7 +2771,7 @@ void LLViewerFetchedTexture::forceImmediateUpdate()
|
|||
return;
|
||||
}
|
||||
//if already called forceImmediateUpdate()
|
||||
if(mInImageList && mDecodePriority == LLViewerFetchedTexture::maxDecodePriority())
|
||||
if(mInImageList && mMaxVirtualSize == LLViewerFetchedTexture::sMaxVirtualSize)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
|
@ -2976,6 +2840,7 @@ bool LLViewerFetchedTexture::needsToSaveRawImage()
|
|||
|
||||
void LLViewerFetchedTexture::destroyRawImage()
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
|
||||
if (mAuxRawImage.notNull() && !needsToSaveRawImage())
|
||||
{
|
||||
sAuxCount--;
|
||||
|
|
@ -3059,6 +2924,7 @@ void LLViewerFetchedTexture::setCachedRawImage(S32 discard_level, LLImageRaw* im
|
|||
|
||||
void LLViewerFetchedTexture::setCachedRawImage()
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
|
||||
if(mRawImage == mCachedRawImage)
|
||||
{
|
||||
return;
|
||||
|
|
@ -3134,6 +3000,7 @@ void LLViewerFetchedTexture::checkCachedRawSculptImage()
|
|||
|
||||
void LLViewerFetchedTexture::saveRawImage()
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
|
||||
if(mRawImage.isNull() || mRawImage == mSavedRawImage || (mSavedRawDiscardLevel >= 0 && mSavedRawDiscardLevel <= mRawDiscardLevel))
|
||||
{
|
||||
return;
|
||||
|
|
@ -3349,25 +3216,10 @@ void LLViewerLODTexture::processTextureStats()
|
|||
}
|
||||
else
|
||||
{
|
||||
if(isLargeImage() && !isJustBound() && mAdditionalDecodePriority < 0.3f)
|
||||
{
|
||||
//if is a big image and not being used recently, nor close to the view point, do not load hi-res data.
|
||||
mMaxVirtualSize = llmin(mMaxVirtualSize, (F32)LLViewerTexture::sMinLargeImageSize);
|
||||
}
|
||||
|
||||
if ((mCalculatedDiscardLevel >= 0.f) &&
|
||||
(llabs(mMaxVirtualSize - mDiscardVirtualSize) < mMaxVirtualSize*.20f))
|
||||
{
|
||||
// < 20% change in virtual size = no change in desired discard
|
||||
discard_level = mCalculatedDiscardLevel;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Calculate the required scale factor of the image using pixels per texel
|
||||
discard_level = (F32)(log(mTexelsPerImage/mMaxVirtualSize) / log_4);
|
||||
mDiscardVirtualSize = mMaxVirtualSize;
|
||||
mCalculatedDiscardLevel = discard_level;
|
||||
}
|
||||
// Calculate the required scale factor of the image using pixels per texel
|
||||
discard_level = (F32)(log(mTexelsPerImage/mMaxVirtualSize) / log_4);
|
||||
mDiscardVirtualSize = mMaxVirtualSize;
|
||||
mCalculatedDiscardLevel = discard_level;
|
||||
}
|
||||
if (mBoostLevel < LLGLTexture::BOOST_SCULPTED)
|
||||
{
|
||||
|
|
@ -3407,18 +3259,6 @@ void LLViewerLODTexture::processTextureStats()
|
|||
//needs to release texture memory urgently
|
||||
scaleDown();
|
||||
}
|
||||
// Limit the amount of GL memory bound each frame
|
||||
else if ( sBoundTextureMemory > sMaxBoundTextureMemory * texmem_middle_bound_scale &&
|
||||
(!getBoundRecently() || mDesiredDiscardLevel >= mCachedRawDiscardLevel))
|
||||
{
|
||||
scaleDown();
|
||||
}
|
||||
// Only allow GL to have 2x the video card memory
|
||||
else if ( sTotalTextureMemory > sMaxTotalTextureMem * texmem_middle_bound_scale &&
|
||||
(!getBoundRecently() || mDesiredDiscardLevel >= mCachedRawDiscardLevel))
|
||||
{
|
||||
scaleDown();
|
||||
}
|
||||
}
|
||||
|
||||
if (isUpdateFrozen() // we are out of memory and nearing max allowed bias
|
||||
|
|
@ -4199,7 +4039,6 @@ void LLTexturePipelineTester::compareTestSessions(llofstream* os)
|
|||
*os << llformat("%s\n", getTesterName().c_str());
|
||||
*os << llformat("AggregateResults\n");
|
||||
|
||||
compareTestResults(os, "TotalFetchingTime", base_sessionp->mTotalFetchingTime, current_sessionp->mTotalFetchingTime);
|
||||
compareTestResults(os, "TotalGrayTime", base_sessionp->mTotalGrayTime, current_sessionp->mTotalGrayTime);
|
||||
compareTestResults(os, "TotalStablizingTime", base_sessionp->mTotalStablizingTime, current_sessionp->mTotalStablizingTime);
|
||||
compareTestResults(os, "StartTimeLoadingSculpties", base_sessionp->mStartTimeLoadingSculpties, current_sessionp->mStartTimeLoadingSculpties);
|
||||
|
|
@ -4259,7 +4098,6 @@ LLMetricPerformanceTesterWithSession::LLTestSession* LLTexturePipelineTester::lo
|
|||
return NULL;
|
||||
}
|
||||
|
||||
F32 total_fetching_time = 0.f;
|
||||
F32 total_gray_time = 0.f;
|
||||
F32 total_stablizing_time = 0.f;
|
||||
F32 total_loading_sculpties_time = 0.f;
|
||||
|
|
@ -4294,7 +4132,6 @@ LLMetricPerformanceTesterWithSession::LLTestSession* LLTexturePipelineTester::lo
|
|||
F32 cur_time = (*log)[label]["Time"].asReal();
|
||||
if(start_time - start_fetching_time > F_ALMOST_ZERO) //fetching has paused for a while
|
||||
{
|
||||
sessionp->mTotalFetchingTime += total_fetching_time;
|
||||
sessionp->mTotalGrayTime += total_gray_time;
|
||||
sessionp->mTotalStablizingTime += total_stablizing_time;
|
||||
|
||||
|
|
@ -4302,14 +4139,12 @@ LLMetricPerformanceTesterWithSession::LLTestSession* LLTexturePipelineTester::lo
|
|||
sessionp->mTotalTimeLoadingSculpties += total_loading_sculpties_time;
|
||||
|
||||
start_fetching_time = start_time;
|
||||
total_fetching_time = 0.0f;
|
||||
total_gray_time = 0.f;
|
||||
total_stablizing_time = 0.f;
|
||||
total_loading_sculpties_time = 0.f;
|
||||
}
|
||||
else
|
||||
{
|
||||
total_fetching_time = cur_time - start_time;
|
||||
total_gray_time = (*log)[label]["TotalGrayTime"].asReal();
|
||||
total_stablizing_time = (*log)[label]["TotalStablizingTime"].asReal();
|
||||
|
||||
|
|
@ -4355,7 +4190,6 @@ LLMetricPerformanceTesterWithSession::LLTestSession* LLTexturePipelineTester::lo
|
|||
in_log = (*log).has(currentLabel);
|
||||
}
|
||||
|
||||
sessionp->mTotalFetchingTime += total_fetching_time;
|
||||
sessionp->mTotalGrayTime += total_gray_time;
|
||||
sessionp->mTotalStablizingTime += total_stablizing_time;
|
||||
|
||||
|
|
@ -4377,8 +4211,6 @@ LLTexturePipelineTester::LLTextureTestSession::~LLTextureTestSession()
|
|||
}
|
||||
void LLTexturePipelineTester::LLTextureTestSession::reset()
|
||||
{
|
||||
mTotalFetchingTime = 0.0f;
|
||||
|
||||
mTotalGrayTime = 0.0f;
|
||||
mTotalStablizingTime = 0.0f;
|
||||
|
||||
|
|
|
|||
|
|
@ -134,7 +134,7 @@ public:
|
|||
/*virtual*/ bool isActiveFetching();
|
||||
|
||||
/*virtual*/ const LLUUID& getID() const { return mID; }
|
||||
void setBoostLevel(S32 level);
|
||||
virtual void setBoostLevel(S32 level);
|
||||
S32 getBoostLevel() { return mBoostLevel; }
|
||||
void setTextureListType(S32 tex_type) { mTextureListType = tex_type; }
|
||||
S32 getTextureListType() { return mTextureListType; }
|
||||
|
|
@ -188,19 +188,20 @@ private:
|
|||
|
||||
virtual void switchToCachedImage();
|
||||
|
||||
static bool isMemoryForTextureLow() ;
|
||||
static bool isMemoryForTextureSuficientlyFree();
|
||||
static void getGPUMemoryForTextures(S32Megabytes &gpu, S32Megabytes &physical);
|
||||
|
||||
public:
|
||||
static bool isMemoryForTextureLow();
|
||||
protected:
|
||||
friend class LLViewerTextureList;
|
||||
LLUUID mID;
|
||||
S32 mTextureListType; // along with mID identifies where to search for this texture in TextureList
|
||||
|
||||
F32 mSelectedTime; // time texture was last selected
|
||||
mutable F32 mMaxVirtualSize; // The largest virtual size of the image, in pixels - how much data to we need?
|
||||
mutable S32 mMaxVirtualSizeResetCounter ;
|
||||
mutable F32 mMaxVirtualSize = 0.f; // The largest virtual size of the image, in pixels - how much data to we need?
|
||||
mutable S32 mMaxVirtualSizeResetCounter;
|
||||
mutable S32 mMaxVirtualSizeResetInterval;
|
||||
mutable F32 mAdditionalDecodePriority; // priority add to mDecodePriority.
|
||||
LLFrameTimer mLastReferencedTimer;
|
||||
|
||||
ll_face_list_t mFaceList[LLRender::NUM_TEXTURE_CHANNELS]; //reverse pointer pointing to the faces using this image as texture
|
||||
|
|
@ -226,11 +227,6 @@ public:
|
|||
static LLFrameTimer sEvaluationTimer;
|
||||
static F32 sDesiredDiscardBias;
|
||||
static F32 sDesiredDiscardScale;
|
||||
static S32Bytes sBoundTextureMemory;
|
||||
static S32Bytes sTotalTextureMemory;
|
||||
static S32Megabytes sMaxBoundTextureMemory;
|
||||
static S32Megabytes sMaxTotalTextureMem;
|
||||
static S32Bytes sMaxDesiredTextureMem ;
|
||||
static S8 sCameraMovingDiscardBias;
|
||||
static F32 sCameraMovingBias;
|
||||
static S32 sMaxSculptRez ;
|
||||
|
|
@ -285,7 +281,6 @@ public:
|
|||
LLViewerFetchedTexture(const std::string& url, FTType f_type, const LLUUID& id, BOOL usemipmaps = TRUE);
|
||||
|
||||
public:
|
||||
static F32 maxDecodePriority();
|
||||
|
||||
struct Compare
|
||||
{
|
||||
|
|
@ -294,9 +289,10 @@ public:
|
|||
{
|
||||
const LLViewerFetchedTexture* lhsp = (const LLViewerFetchedTexture*)lhs;
|
||||
const LLViewerFetchedTexture* rhsp = (const LLViewerFetchedTexture*)rhs;
|
||||
|
||||
// greater priority is "less"
|
||||
const F32 lpriority = lhsp->getDecodePriority();
|
||||
const F32 rpriority = rhsp->getDecodePriority();
|
||||
const F32 lpriority = lhsp->mMaxVirtualSize;
|
||||
const F32 rpriority = rhsp->mMaxVirtualSize;
|
||||
if (lpriority > rpriority) // higher priority
|
||||
return true;
|
||||
if (lpriority < rpriority)
|
||||
|
|
@ -306,10 +302,10 @@ public:
|
|||
};
|
||||
|
||||
public:
|
||||
/*virtual*/ S8 getType() const ;
|
||||
/*virtual*/ S8 getType() const override;
|
||||
FTType getFTType() const;
|
||||
/*virtual*/ void forceImmediateUpdate() ;
|
||||
/*virtual*/ void dump() ;
|
||||
/*virtual*/ void forceImmediateUpdate() override;
|
||||
/*virtual*/ void dump() override;
|
||||
|
||||
// Set callbacks to get called when the image gets updated with higher
|
||||
// resolution versions.
|
||||
|
|
@ -335,7 +331,6 @@ public:
|
|||
void destroyTexture() ;
|
||||
|
||||
virtual void processTextureStats() ;
|
||||
F32 calcDecodePriority() ;
|
||||
|
||||
BOOL needsAux() const { return mNeedsAux; }
|
||||
|
||||
|
|
@ -343,20 +338,12 @@ public:
|
|||
void setTargetHost(LLHost host) { mTargetHost = host; }
|
||||
LLHost getTargetHost() const { return mTargetHost; }
|
||||
|
||||
// Set the decode priority for this image...
|
||||
// DON'T CALL THIS UNLESS YOU KNOW WHAT YOU'RE DOING, it can mess up
|
||||
// the priority list, and cause horrible things to happen.
|
||||
void setDecodePriority(F32 priority = -1.0f);
|
||||
F32 getDecodePriority() const { return mDecodePriority; };
|
||||
F32 getAdditionalDecodePriority() const { return mAdditionalDecodePriority; };
|
||||
|
||||
void setAdditionalDecodePriority(F32 priority) ;
|
||||
|
||||
void updateVirtualSize() ;
|
||||
|
||||
S32 getDesiredDiscardLevel() { return mDesiredDiscardLevel; }
|
||||
void setMinDiscardLevel(S32 discard) { mMinDesiredDiscardLevel = llmin(mMinDesiredDiscardLevel,(S8)discard); }
|
||||
|
||||
void setBoostLevel(S32 level) override;
|
||||
bool updateFetch();
|
||||
bool setDebugFetching(S32 debug_level);
|
||||
bool isInDebug() const { return mInDebug; }
|
||||
|
|
@ -369,10 +356,14 @@ public:
|
|||
// Override the computation of discard levels if we know the exact output
|
||||
// size of the image. Used for UI textures to not decode, even if we have
|
||||
// more data.
|
||||
/*virtual*/ void setKnownDrawSize(S32 width, S32 height);
|
||||
/*virtual*/ void setKnownDrawSize(S32 width, S32 height) override;
|
||||
|
||||
// Set the debug text of all Viewer Objects associated with this texture
|
||||
// to the specified text
|
||||
void setDebugText(const std::string& text);
|
||||
|
||||
void setIsMissingAsset(BOOL is_missing = true);
|
||||
/*virtual*/ BOOL isMissingAsset() const { return mIsMissingAsset; }
|
||||
/*virtual*/ BOOL isMissingAsset() const override { return mIsMissingAsset; }
|
||||
|
||||
// returns dimensions of original image for local files (before power of two scaling)
|
||||
// and returns 0 for all asset system images
|
||||
|
|
@ -415,7 +406,7 @@ public:
|
|||
BOOL isRawImageValid()const { return mIsRawImageValid ; }
|
||||
void forceToSaveRawImage(S32 desired_discard = 0, F32 kept_time = 0.f) ;
|
||||
void forceToRefetchTexture(S32 desired_discard = 0, F32 kept_time = 60.f);
|
||||
/*virtual*/ void setCachedRawImage(S32 discard_level, LLImageRaw* imageraw) ;
|
||||
/*virtual*/ void setCachedRawImage(S32 discard_level, LLImageRaw* imageraw) override;
|
||||
void destroySavedRawImage() ;
|
||||
LLImageRaw* getSavedRawImage() ;
|
||||
BOOL hasSavedRawImage() const ;
|
||||
|
|
@ -431,10 +422,10 @@ public:
|
|||
void setInFastCacheList(bool in_list) { mInFastCacheList = in_list; }
|
||||
bool isInFastCacheList() { return mInFastCacheList; }
|
||||
|
||||
/*virtual*/bool isActiveFetching(); //is actively in fetching by the fetching pipeline.
|
||||
/*virtual*/bool isActiveFetching() override; //is actively in fetching by the fetching pipeline.
|
||||
|
||||
protected:
|
||||
/*virtual*/ void switchToCachedImage();
|
||||
/*virtual*/ void switchToCachedImage() override;
|
||||
S32 getCurrentDiscardLevelForFetching() ;
|
||||
|
||||
private:
|
||||
|
|
@ -472,11 +463,11 @@ protected:
|
|||
S32 mRequestedDiscardLevel;
|
||||
F32 mRequestedDownloadPriority;
|
||||
S32 mFetchState;
|
||||
S32 mLastFetchState = -1; // DEBUG
|
||||
U32 mFetchPriority;
|
||||
F32 mDownloadProgress;
|
||||
F32 mFetchDeltaTime;
|
||||
F32 mRequestDeltaTime;
|
||||
F32 mDecodePriority; // The priority for decoding this image.
|
||||
S32 mMinDiscardLevel;
|
||||
S8 mDesiredDiscardLevel; // The discard level we'd LIKE to have - if we have it and there's space
|
||||
S8 mMinDesiredDiscardLevel; // The minimum discard level we'd like to have
|
||||
|
|
@ -500,7 +491,7 @@ protected:
|
|||
F32 mLastCallBackActiveTime;
|
||||
|
||||
LLPointer<LLImageRaw> mRawImage;
|
||||
S32 mRawDiscardLevel;
|
||||
S32 mRawDiscardLevel = -1;
|
||||
|
||||
// Used ONLY for cloth meshes right now. Make SURE you know what you're
|
||||
// doing if you use it for anything else! - djs
|
||||
|
|
@ -534,6 +525,7 @@ protected:
|
|||
BOOL mIsFetched ; //is loaded from remote or from cache, not generated locally.
|
||||
|
||||
public:
|
||||
static F32 sMaxVirtualSize; //maximum possible value of mMaxVirtualSize
|
||||
static LLPointer<LLViewerFetchedTexture> sMissingAssetImagep; // Texture to show for an image asset that is not in the database
|
||||
static LLPointer<LLViewerFetchedTexture> sWhiteImagep; // Texture to show NOTHING (whiteness)
|
||||
static LLPointer<LLViewerFetchedTexture> sDefaultImagep; // "Default" texture for error cases, the only case of fetched texture which is generated in local.
|
||||
|
|
@ -774,7 +766,6 @@ private:
|
|||
|
||||
void reset() ;
|
||||
|
||||
F32 mTotalFetchingTime ;
|
||||
F32 mTotalGrayTime ;
|
||||
F32 mTotalStablizingTime ;
|
||||
F32 mStartTimeLoadingSculpties ;
|
||||
|
|
|
|||
|
|
@ -89,8 +89,6 @@ LLTextureKey::LLTextureKey(LLUUID id, ETexListType tex_type)
|
|||
|
||||
LLViewerTextureList::LLViewerTextureList()
|
||||
: mForceResetTextureStats(FALSE),
|
||||
mMaxResidentTexMemInMegaBytes(0),
|
||||
mMaxTotalTextureMemInMegaBytes(0),
|
||||
mInitialized(FALSE)
|
||||
{
|
||||
}
|
||||
|
|
@ -99,12 +97,6 @@ void LLViewerTextureList::init()
|
|||
{
|
||||
mInitialized = TRUE ;
|
||||
sNumImages = 0;
|
||||
mMaxResidentTexMemInMegaBytes = (U32Bytes)0;
|
||||
mMaxTotalTextureMemInMegaBytes = (U32Bytes)0;
|
||||
|
||||
// Update how much texture RAM we're allowed to use.
|
||||
updateMaxResidentTexMem(S32Megabytes(0)); // 0 = use current
|
||||
|
||||
doPreloadImages();
|
||||
}
|
||||
|
||||
|
|
@ -204,10 +196,8 @@ static std::string get_texture_list_name()
|
|||
void LLViewerTextureList::doPrefetchImages()
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
|
||||
gTextureTimer.start();
|
||||
gTextureTimer.pause();
|
||||
|
||||
if (LLAppViewer::instance()->getPurgeCache())
|
||||
if (LLAppViewer::instance()->getPurgeCache())
|
||||
{
|
||||
// cache was purged, no point
|
||||
return;
|
||||
|
|
@ -342,7 +332,7 @@ void LLViewerTextureList::dump()
|
|||
{
|
||||
LLViewerFetchedTexture* image = *it;
|
||||
|
||||
LL_INFOS() << "priority " << image->getDecodePriority()
|
||||
LL_INFOS() << "priority " << image->getMaxVirtualSize()
|
||||
<< " boost " << image->getBoostLevel()
|
||||
<< " size " << image->getWidth() << "x" << image->getHeight()
|
||||
<< " discard " << image->getDiscardLevel()
|
||||
|
|
@ -667,13 +657,14 @@ void LLViewerTextureList::removeImageFromList(LLViewerFetchedTexture *image)
|
|||
assert_main_thread();
|
||||
llassert_always(mInitialized) ;
|
||||
llassert(image);
|
||||
image->validateRefCount();
|
||||
|
||||
S32 count = 0;
|
||||
if (image->isInImageList())
|
||||
{
|
||||
count = mImageList.erase(image) ;
|
||||
if(count != 1)
|
||||
{
|
||||
{
|
||||
LL_INFOS() << "Image " << image->getID()
|
||||
<< " had mInImageList set but mImageList.erase() returned " << count
|
||||
<< LL_ENDL;
|
||||
|
|
@ -699,6 +690,7 @@ void LLViewerTextureList::removeImageFromList(LLViewerFetchedTexture *image)
|
|||
LL_INFOS() << "Image " << image->getID() << " was in mUUIDMap with same pointer" << LL_ENDL ;
|
||||
}
|
||||
count = mImageList.erase(image) ;
|
||||
llassert(count != 0);
|
||||
if(count != 0)
|
||||
{ // it was in the list already?
|
||||
LL_WARNS() << "Image " << image->getID()
|
||||
|
|
@ -784,17 +776,12 @@ void LLViewerTextureList::updateImages(F32 max_time)
|
|||
using namespace LLStatViewer;
|
||||
sample(NUM_IMAGES, sNumImages);
|
||||
sample(NUM_RAW_IMAGES, LLImageRaw::sRawImageCount);
|
||||
sample(GL_TEX_MEM, LLImageGL::sGlobalTextureMemory);
|
||||
sample(GL_BOUND_MEM, LLImageGL::sBoundTextureMemory);
|
||||
sample(RAW_MEM, F64Bytes(LLImageRaw::sGlobalRawMemory));
|
||||
sample(FORMATTED_MEM, F64Bytes(LLImageFormatted::sGlobalFormattedMemory));
|
||||
}
|
||||
|
||||
//loading from fast cache
|
||||
max_time -= updateImagesLoadingFastCache(max_time);
|
||||
|
||||
updateImagesDecodePriorities();
|
||||
|
||||
F32 total_max_time = max_time;
|
||||
|
||||
max_time -= updateImagesFetchTextures(max_time);
|
||||
|
|
@ -825,7 +812,6 @@ void LLViewerTextureList::updateImages(F32 max_time)
|
|||
didone = image->doLoadedCallbacks();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
updateImagesUpdateStats();
|
||||
}
|
||||
|
|
@ -848,120 +834,78 @@ void LLViewerTextureList::clearFetchingRequests()
|
|||
}
|
||||
}
|
||||
|
||||
void LLViewerTextureList::updateImagesDecodePriorities()
|
||||
void LLViewerTextureList::updateImageDecodePriority(LLViewerFetchedTexture* imagep)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
|
||||
// Update the decode priority for N images each frame
|
||||
{
|
||||
F32 lazy_flush_timeout = 30.f; // stop decoding
|
||||
F32 max_inactive_time = 20.f; // actually delete
|
||||
S32 min_refs = 3; // 1 for mImageList, 1 for mUUIDMap, 1 for local reference
|
||||
if (imagep->isInDebug() || imagep->isUnremovable())
|
||||
{
|
||||
//update_counter--;
|
||||
return; //is in debug, ignore.
|
||||
}
|
||||
|
||||
//reset imagep->getLastReferencedTimer() when screen is showing the progress view to avoid removing pre-fetched textures too soon.
|
||||
bool reset_timer = gViewerWindow->getProgressView()->getVisible();
|
||||
|
||||
static const S32 MAX_PRIO_UPDATES = gSavedSettings.getS32("TextureFetchUpdatePriorities"); // default: 32
|
||||
const size_t max_update_count = llmin((S32) (MAX_PRIO_UPDATES*MAX_PRIO_UPDATES*gFrameIntervalSeconds.value()) + 1, MAX_PRIO_UPDATES);
|
||||
S32 update_counter = llmin(max_update_count, mUUIDMap.size());
|
||||
uuid_map_t::iterator iter = mUUIDMap.upper_bound(mLastUpdateKey);
|
||||
while ((update_counter-- > 0) && !mUUIDMap.empty())
|
||||
{
|
||||
if (iter == mUUIDMap.end())
|
||||
{
|
||||
iter = mUUIDMap.begin();
|
||||
F32 lazy_flush_timeout = 30.f; // stop decoding
|
||||
F32 max_inactive_time = 20.f; // actually delete
|
||||
S32 min_refs = 3; // 1 for mImageList, 1 for mUUIDMap, 1 for local reference
|
||||
|
||||
//
|
||||
// Flush formatted images using a lazy flush
|
||||
//
|
||||
S32 num_refs = imagep->getNumRefs();
|
||||
if (num_refs == min_refs)
|
||||
{
|
||||
if (imagep->getLastReferencedTimer()->getElapsedTimeF32() > lazy_flush_timeout)
|
||||
{
|
||||
// Remove the unused image from the image list
|
||||
deleteImage(imagep);
|
||||
imagep = NULL; // should destroy the image
|
||||
}
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (imagep->hasSavedRawImage())
|
||||
{
|
||||
if (imagep->getElapsedLastReferencedSavedRawImageTime() > max_inactive_time)
|
||||
{
|
||||
imagep->destroySavedRawImage();
|
||||
}
|
||||
mLastUpdateKey = iter->first;
|
||||
LLPointer<LLViewerFetchedTexture> imagep = iter->second;
|
||||
++iter; // safe to increment now
|
||||
}
|
||||
|
||||
if(imagep->isInDebug() || imagep->isUnremovable())
|
||||
{
|
||||
update_counter--;
|
||||
continue; //is in debug, ignore.
|
||||
}
|
||||
if (imagep->isDeleted())
|
||||
{
|
||||
return;
|
||||
}
|
||||
else if (imagep->isDeletionCandidate())
|
||||
{
|
||||
imagep->destroyTexture();
|
||||
return;
|
||||
}
|
||||
else if (imagep->isInactive())
|
||||
{
|
||||
if (imagep->getLastReferencedTimer()->getElapsedTimeF32() > max_inactive_time)
|
||||
{
|
||||
imagep->setDeletionCandidate();
|
||||
}
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
imagep->getLastReferencedTimer()->reset();
|
||||
|
||||
//
|
||||
// Flush formatted images using a lazy flush
|
||||
//
|
||||
S32 num_refs = imagep->getNumRefs();
|
||||
if (num_refs == min_refs)
|
||||
{
|
||||
if(reset_timer)
|
||||
{
|
||||
imagep->getLastReferencedTimer()->reset();
|
||||
}
|
||||
else if (imagep->getLastReferencedTimer()->getElapsedTimeF32() > lazy_flush_timeout)
|
||||
{
|
||||
// Remove the unused image from the image list
|
||||
deleteImage(imagep);
|
||||
imagep = NULL; // should destroy the image
|
||||
}
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(imagep->hasSavedRawImage())
|
||||
{
|
||||
if(imagep->getElapsedLastReferencedSavedRawImageTime() > max_inactive_time)
|
||||
{
|
||||
imagep->destroySavedRawImage() ;
|
||||
}
|
||||
}
|
||||
//reset texture state.
|
||||
imagep->setInactive();
|
||||
}
|
||||
}
|
||||
|
||||
if(imagep->isDeleted())
|
||||
{
|
||||
continue ;
|
||||
}
|
||||
else if(imagep->isDeletionCandidate())
|
||||
{
|
||||
imagep->destroyTexture() ;
|
||||
continue ;
|
||||
}
|
||||
else if(imagep->isInactive())
|
||||
{
|
||||
if(reset_timer)
|
||||
{
|
||||
imagep->getLastReferencedTimer()->reset();
|
||||
}
|
||||
else if (imagep->getLastReferencedTimer()->getElapsedTimeF32() > max_inactive_time)
|
||||
{
|
||||
imagep->setDeletionCandidate() ;
|
||||
}
|
||||
continue ;
|
||||
}
|
||||
else
|
||||
{
|
||||
imagep->getLastReferencedTimer()->reset();
|
||||
if (!imagep->isInImageList())
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (imagep->isInFastCacheList())
|
||||
{
|
||||
return; //wait for loading from the fast cache.
|
||||
}
|
||||
|
||||
//reset texture state.
|
||||
imagep->setInactive() ;
|
||||
}
|
||||
}
|
||||
|
||||
if (!imagep->isInImageList())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if(imagep->isInFastCacheList())
|
||||
{
|
||||
continue; //wait for loading from the fast cache.
|
||||
}
|
||||
|
||||
imagep->processTextureStats();
|
||||
F32 old_priority = imagep->getDecodePriority();
|
||||
F32 old_priority_test = llmax(old_priority, 0.0f);
|
||||
F32 decode_priority = imagep->calcDecodePriority();
|
||||
F32 decode_priority_test = llmax(decode_priority, 0.0f);
|
||||
// Ignore < 20% difference
|
||||
if ((decode_priority_test < old_priority_test * .8f) ||
|
||||
(decode_priority_test > old_priority_test * 1.25f))
|
||||
{
|
||||
mImageList.erase(imagep) ;
|
||||
imagep->setDecodePriority(decode_priority);
|
||||
mImageList.insert(imagep);
|
||||
}
|
||||
}
|
||||
}
|
||||
imagep->processTextureStats();
|
||||
}
|
||||
|
||||
void LLViewerTextureList::setDebugFetching(LLViewerFetchedTexture* tex, S32 debug_level)
|
||||
|
|
@ -973,17 +917,9 @@ void LLViewerTextureList::setDebugFetching(LLViewerFetchedTexture* tex, S32 debu
|
|||
}
|
||||
|
||||
const F32 DEBUG_PRIORITY = 100000.f;
|
||||
F32 old_priority_test = llmax(tex->getDecodePriority(), 0.0f);
|
||||
F32 decode_priority_test = DEBUG_PRIORITY;
|
||||
|
||||
// Ignore < 20% difference
|
||||
if ((decode_priority_test < old_priority_test * .8f) ||
|
||||
(decode_priority_test > old_priority_test * 1.25f))
|
||||
{
|
||||
removeImageFromList(tex);
|
||||
tex->setDecodePriority(decode_priority_test);
|
||||
addImageToList(tex);
|
||||
}
|
||||
removeImageFromList(tex);
|
||||
tex->mMaxVirtualSize = DEBUG_PRIORITY;
|
||||
addImageToList(tex);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -1033,10 +969,6 @@ F32 LLViewerTextureList::updateImagesCreateTextures(F32 max_time)
|
|||
LLViewerFetchedTexture *imagep = *curiter;
|
||||
imagep->createTexture();
|
||||
imagep->postCreateTexture();
|
||||
if (create_timer.getElapsedTimeF32() > max_time)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
mCreateTextureList.erase(mCreateTextureList.begin(), enditer);
|
||||
return create_timer.getElapsedTimeF32();
|
||||
|
|
@ -1064,10 +996,6 @@ F32 LLViewerTextureList::updateImagesLoadingFastCache(F32 max_time)
|
|||
enditer = iter;
|
||||
LLViewerFetchedTexture *imagep = *curiter;
|
||||
imagep->loadFromFastCache();
|
||||
if (timer.getElapsedTimeF32() > max_time)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
mFastCacheList.erase(mFastCacheList.begin(), enditer);
|
||||
return timer.getElapsedTimeF32();
|
||||
|
|
@ -1086,8 +1014,7 @@ void LLViewerTextureList::forceImmediateUpdate(LLViewerFetchedTexture* imagep)
|
|||
}
|
||||
|
||||
imagep->processTextureStats();
|
||||
F32 decode_priority = LLViewerFetchedTexture::maxDecodePriority() ;
|
||||
imagep->setDecodePriority(decode_priority);
|
||||
imagep->sMaxVirtualSize = LLViewerFetchedTexture::sMaxVirtualSize;
|
||||
addImageToList(imagep);
|
||||
|
||||
return ;
|
||||
|
|
@ -1096,76 +1023,55 @@ void LLViewerTextureList::forceImmediateUpdate(LLViewerFetchedTexture* imagep)
|
|||
F32 LLViewerTextureList::updateImagesFetchTextures(F32 max_time)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
|
||||
LLTimer image_op_timer;
|
||||
|
||||
// Update fetch for N images each frame
|
||||
static const S32 MAX_HIGH_PRIO_COUNT = gSavedSettings.getS32("TextureFetchUpdateHighPriority"); // default: 32
|
||||
static const S32 MAX_UPDATE_COUNT = gSavedSettings.getS32("TextureFetchUpdateMaxMediumPriority"); // default: 256
|
||||
static const S32 MIN_UPDATE_COUNT = gSavedSettings.getS32("TextureFetchUpdateMinMediumPriority"); // default: 32
|
||||
static const F32 MIN_PRIORITY_THRESHOLD = gSavedSettings.getF32("TextureFetchUpdatePriorityThreshold"); // default: 0.0
|
||||
static const bool SKIP_LOW_PRIO = gSavedSettings.getBOOL("TextureFetchUpdateSkipLowPriority"); // default: false
|
||||
LLTimer image_op_timer;
|
||||
|
||||
size_t max_priority_count = llmin((S32) (MAX_HIGH_PRIO_COUNT*MAX_HIGH_PRIO_COUNT*gFrameIntervalSeconds.value())+1, MAX_HIGH_PRIO_COUNT);
|
||||
max_priority_count = llmin(max_priority_count, mImageList.size());
|
||||
|
||||
size_t total_update_count = mUUIDMap.size();
|
||||
size_t max_update_count = llmin((S32) (MAX_UPDATE_COUNT*MAX_UPDATE_COUNT*gFrameIntervalSeconds.value())+1, MAX_UPDATE_COUNT);
|
||||
max_update_count = llmin(max_update_count, total_update_count);
|
||||
|
||||
// MAX_HIGH_PRIO_COUNT high priority entries
|
||||
typedef std::vector<LLViewerFetchedTexture*> entries_list_t;
|
||||
entries_list_t entries;
|
||||
size_t update_counter = max_priority_count;
|
||||
image_priority_list_t::iterator iter1 = mImageList.begin();
|
||||
while(update_counter > 0)
|
||||
{
|
||||
entries.push_back(*iter1);
|
||||
|
||||
++iter1;
|
||||
update_counter--;
|
||||
}
|
||||
|
||||
// MAX_UPDATE_COUNT cycled entries
|
||||
update_counter = max_update_count;
|
||||
if(update_counter > 0)
|
||||
{
|
||||
uuid_map_t::iterator iter2 = mUUIDMap.upper_bound(mLastFetchKey);
|
||||
while ((update_counter > 0) && (total_update_count > 0))
|
||||
{
|
||||
if (iter2 == mUUIDMap.end())
|
||||
{
|
||||
iter2 = mUUIDMap.begin();
|
||||
}
|
||||
LLViewerFetchedTexture* imagep = iter2->second;
|
||||
// Skip the textures where there's really nothing to do so to give some times to others. Also skip the texture if it's already in the high prio set.
|
||||
if (!SKIP_LOW_PRIO || (SKIP_LOW_PRIO && ((imagep->getDecodePriority() > MIN_PRIORITY_THRESHOLD) || imagep->hasFetcher())))
|
||||
typedef std::vector<LLPointer<LLViewerFetchedTexture> > entries_list_t;
|
||||
entries_list_t entries;
|
||||
|
||||
// update N textures at beginning of mImageList
|
||||
U32 update_count = 0;
|
||||
static const S32 MIN_UPDATE_COUNT = gSavedSettings.getS32("TextureFetchUpdateMinCount"); // default: 32
|
||||
// WIP -- dumb code here
|
||||
//update MIN_UPDATE_COUNT or 10% of other textures, whichever is greater
|
||||
update_count = llmax((U32) MIN_UPDATE_COUNT, (U32) mUUIDMap.size()/10);
|
||||
update_count = llmin(update_count, (U32) mUUIDMap.size());
|
||||
|
||||
{
|
||||
LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("vtluift - copy");
|
||||
|
||||
// copy entries out of UUID map for updating
|
||||
entries.reserve(update_count);
|
||||
uuid_map_t::iterator iter = mUUIDMap.upper_bound(mLastUpdateKey);
|
||||
while (update_count-- > 0)
|
||||
{
|
||||
if (iter == mUUIDMap.end())
|
||||
{
|
||||
entries.push_back(imagep);
|
||||
update_counter--;
|
||||
iter = mUUIDMap.begin();
|
||||
}
|
||||
|
||||
if (iter->second->getGLTexture())
|
||||
{
|
||||
entries.push_back(iter->second);
|
||||
}
|
||||
++iter;
|
||||
}
|
||||
}
|
||||
|
||||
for (auto& imagep : entries)
|
||||
{
|
||||
if (imagep->getNumRefs() > 1) // make sure this image hasn't been deleted before attempting to update (may happen as a side effect of some other image updating)
|
||||
{
|
||||
updateImageDecodePriority(imagep);
|
||||
imagep->updateFetch();
|
||||
}
|
||||
}
|
||||
|
||||
if (entries.size() > 0)
|
||||
{
|
||||
LLViewerFetchedTexture* imagep = *entries.rbegin();
|
||||
mLastUpdateKey = LLTextureKey(imagep->getID(), (ETexListType)imagep->getTextureListType());
|
||||
}
|
||||
|
||||
iter2++;
|
||||
total_update_count--;
|
||||
}
|
||||
}
|
||||
|
||||
S32 fetch_count = 0;
|
||||
size_t min_update_count = llmin(MIN_UPDATE_COUNT,(S32)(entries.size()-max_priority_count));
|
||||
S32 min_count = max_priority_count + min_update_count;
|
||||
for (entries_list_t::iterator iter3 = entries.begin();
|
||||
iter3 != entries.end(); )
|
||||
{
|
||||
LLViewerFetchedTexture* imagep = *iter3++;
|
||||
fetch_count += (imagep->updateFetch() ? 1 : 0);
|
||||
if (min_count <= min_update_count)
|
||||
{
|
||||
mLastFetchKey = LLTextureKey(imagep->getID(), (ETexListType)imagep->getTextureListType());
|
||||
}
|
||||
if ((min_count-- <= 0) && (image_op_timer.getElapsedTimeF32() > max_time))
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
return image_op_timer.getElapsedTimeF32();
|
||||
}
|
||||
|
||||
|
|
@ -1209,8 +1115,6 @@ void LLViewerTextureList::decodeAllImages(F32 max_time)
|
|||
{
|
||||
LLViewerFetchedTexture* imagep = *iter;
|
||||
imagep->processTextureStats();
|
||||
F32 decode_priority = imagep->calcDecodePriority();
|
||||
imagep->setDecodePriority(decode_priority);
|
||||
addImageToList(imagep);
|
||||
}
|
||||
image_list.clear();
|
||||
|
|
@ -1349,156 +1253,6 @@ LLPointer<LLImageJ2C> LLViewerTextureList::convertToUploadFile(LLPointer<LLImage
|
|||
return compressedImage;
|
||||
}
|
||||
|
||||
// Returns min setting for TextureMemory (in MB)
|
||||
S32Megabytes LLViewerTextureList::getMinVideoRamSetting()
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
|
||||
U32Megabytes system_ram = gSysMemory.getPhysicalMemoryKB();
|
||||
//min texture mem sets to 64M if total physical mem is more than 1.5GB
|
||||
return (system_ram > U32Megabytes(1500)) ? S32Megabytes(64) : gMinVideoRam ;
|
||||
}
|
||||
|
||||
//static
|
||||
// Returns max setting for TextureMemory (in MB)
|
||||
S32Megabytes LLViewerTextureList::getMaxVideoRamSetting(bool get_recommended, float mem_multiplier)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
|
||||
S32Megabytes max_texmem;
|
||||
if (gGLManager.mVRAM != 0)
|
||||
{
|
||||
// Treat any card with < 32 MB (shudder) as having 32 MB
|
||||
// - it's going to be swapping constantly regardless
|
||||
S32Megabytes max_vram(gGLManager.mVRAM);
|
||||
|
||||
if(gGLManager.mIsAMD)
|
||||
{
|
||||
//shrink the availabe vram for ATI cards because some of them do not handel texture swapping well.
|
||||
max_vram = max_vram * 0.75f;
|
||||
}
|
||||
|
||||
max_vram = llmax(max_vram, getMinVideoRamSetting());
|
||||
max_texmem = max_vram;
|
||||
if (!get_recommended)
|
||||
max_texmem *= 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!get_recommended)
|
||||
{
|
||||
max_texmem = (S32Megabytes)512;
|
||||
}
|
||||
else if (gSavedSettings.getBOOL("NoHardwareProbe")) //did not do hardware detection at startup
|
||||
{
|
||||
max_texmem = (S32Megabytes)512;
|
||||
}
|
||||
else
|
||||
{
|
||||
max_texmem = (S32Megabytes)128;
|
||||
}
|
||||
}
|
||||
|
||||
S32Megabytes system_ram = gSysMemory.getPhysicalMemoryKB(); // In MB
|
||||
//LL_INFOS() << "*** DETECTED " << system_ram << " MB of system memory." << LL_ENDL;
|
||||
if (get_recommended)
|
||||
max_texmem = llmin(max_texmem, system_ram/2);
|
||||
else
|
||||
max_texmem = llmin(max_texmem, system_ram);
|
||||
|
||||
// limit the texture memory to a multiple of the default if we've found some cards to behave poorly otherwise
|
||||
max_texmem = llmin(max_texmem, (S32Megabytes) (mem_multiplier * max_texmem));
|
||||
|
||||
max_texmem = llclamp(max_texmem, getMinVideoRamSetting(), gMaxVideoRam);
|
||||
|
||||
return max_texmem;
|
||||
}
|
||||
|
||||
bool LLViewerTextureList::isPrioRequestsFetched()
|
||||
{
|
||||
static LLCachedControl<F32> prio_threshold(gSavedSettings, "TextureFetchUpdatePriorityThreshold", 0.0f);
|
||||
static LLCachedControl<F32> fetching_textures_threshold(gSavedSettings, "TextureListFetchingThreshold", 0.97f);
|
||||
S32 fetching_tex_count = 0;
|
||||
S32 tex_count_threshold = gTextureList.mImageList.size() * (1 - fetching_textures_threshold);
|
||||
|
||||
for (LLViewerTextureList::image_priority_list_t::iterator iter = gTextureList.mImageList.begin();
|
||||
iter != gTextureList.mImageList.end(); )
|
||||
{
|
||||
LLPointer<LLViewerFetchedTexture> imagep = *iter++;
|
||||
if (imagep->getDecodePriority() > prio_threshold)
|
||||
{
|
||||
if (imagep->hasFetcher() || imagep->isFetching())
|
||||
{
|
||||
fetching_tex_count++;
|
||||
if (fetching_tex_count >= tex_count_threshold)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
const S32Megabytes VIDEO_CARD_FRAMEBUFFER_MEM(12);
|
||||
const S32Megabytes MIN_MEM_FOR_NON_TEXTURE(512);
|
||||
void LLViewerTextureList::updateMaxResidentTexMem(S32Megabytes mem)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
|
||||
// Initialize the image pipeline VRAM settings
|
||||
S32Megabytes cur_mem(gSavedSettings.getS32("TextureMemory"));
|
||||
F32 mem_multiplier = gSavedSettings.getF32("RenderTextureMemoryMultiple");
|
||||
S32Megabytes default_mem = getMaxVideoRamSetting(true, mem_multiplier); // recommended default
|
||||
if (mem == (S32Bytes)0)
|
||||
{
|
||||
mem = cur_mem > (S32Bytes)0 ? cur_mem : default_mem;
|
||||
}
|
||||
else if (mem < (S32Bytes)0)
|
||||
{
|
||||
mem = default_mem;
|
||||
}
|
||||
|
||||
mem = llclamp(mem, getMinVideoRamSetting(), getMaxVideoRamSetting(false, mem_multiplier));
|
||||
if (mem != cur_mem)
|
||||
{
|
||||
gSavedSettings.setS32("TextureMemory", mem.value());
|
||||
return; //listener will re-enter this function
|
||||
}
|
||||
|
||||
if (gGLManager.mVRAM == 0)
|
||||
{
|
||||
LL_WARNS() << "VRAM amount not detected, defaulting to " << mem << " MB" << LL_ENDL;
|
||||
}
|
||||
|
||||
// TODO: set available resident texture mem based on use by other subsystems
|
||||
// currently max(12MB, VRAM/4) assumed...
|
||||
|
||||
S32Megabytes vb_mem = mem;
|
||||
S32Megabytes fb_mem = llmax(VIDEO_CARD_FRAMEBUFFER_MEM, vb_mem/4);
|
||||
mMaxResidentTexMemInMegaBytes = (vb_mem - fb_mem) ; //in MB
|
||||
|
||||
mMaxTotalTextureMemInMegaBytes = mMaxResidentTexMemInMegaBytes * 2;
|
||||
if (mMaxResidentTexMemInMegaBytes > (S32Megabytes)640)
|
||||
{
|
||||
mMaxTotalTextureMemInMegaBytes -= (mMaxResidentTexMemInMegaBytes / 4);
|
||||
}
|
||||
|
||||
//system mem
|
||||
S32Megabytes system_ram = gSysMemory.getPhysicalMemoryKB();
|
||||
|
||||
//minimum memory reserved for non-texture use.
|
||||
//if system_raw >= 1GB, reserve at least 512MB for non-texture use;
|
||||
//otherwise reserve half of the system_ram for non-texture use.
|
||||
S32Megabytes min_non_texture_mem = llmin(system_ram / 2, MIN_MEM_FOR_NON_TEXTURE) ;
|
||||
|
||||
if (mMaxTotalTextureMemInMegaBytes > system_ram - min_non_texture_mem)
|
||||
{
|
||||
mMaxTotalTextureMemInMegaBytes = system_ram - min_non_texture_mem ;
|
||||
}
|
||||
|
||||
LL_INFOS() << "Total Video Memory set to: " << vb_mem << " MB" << LL_ENDL;
|
||||
LL_INFOS() << "Available Texture Memory set to: " << (vb_mem - fb_mem) << " MB" << LL_ENDL;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// static
|
||||
|
|
|
|||
|
|
@ -124,25 +124,20 @@ public:
|
|||
|
||||
void handleIRCallback(void **data, const S32 number);
|
||||
|
||||
S32Megabytes getMaxResidentTexMem() const { return mMaxResidentTexMemInMegaBytes; }
|
||||
S32Megabytes getMaxTotalTextureMem() const { return mMaxTotalTextureMemInMegaBytes;}
|
||||
S32 getNumImages() { return mImageList.size(); }
|
||||
|
||||
void updateMaxResidentTexMem(S32Megabytes mem);
|
||||
|
||||
void doPreloadImages();
|
||||
void doPrefetchImages();
|
||||
|
||||
void clearFetchingRequests();
|
||||
void setDebugFetching(LLViewerFetchedTexture* tex, S32 debug_level);
|
||||
|
||||
static S32Megabytes getMinVideoRamSetting();
|
||||
static S32Megabytes getMaxVideoRamSetting(bool get_recommended, float mem_multiplier);
|
||||
|
||||
static bool isPrioRequestsFetched();
|
||||
|
||||
private:
|
||||
void updateImagesDecodePriorities();
|
||||
// do some book keeping on the specified texture
|
||||
// - updates decode priority
|
||||
// - updates desired discard level
|
||||
// - cleans up textures that haven't been referenced in awhile
|
||||
void updateImageDecodePriority(LLViewerFetchedTexture* imagep);
|
||||
F32 updateImagesCreateTextures(F32 max_time);
|
||||
F32 updateImagesFetchTextures(F32 max_time);
|
||||
void updateImagesUpdateStats();
|
||||
|
|
@ -215,17 +210,14 @@ private:
|
|||
typedef std::map< LLTextureKey, LLPointer<LLViewerFetchedTexture> > uuid_map_t;
|
||||
uuid_map_t mUUIDMap;
|
||||
LLTextureKey mLastUpdateKey;
|
||||
LLTextureKey mLastFetchKey;
|
||||
|
||||
typedef std::set<LLPointer<LLViewerFetchedTexture>, LLViewerFetchedTexture::Compare> image_priority_list_t;
|
||||
typedef std::set < LLPointer<LLViewerFetchedTexture> > image_priority_list_t;
|
||||
image_priority_list_t mImageList;
|
||||
|
||||
// simply holds on to LLViewerFetchedTexture references to stop them from being purged too soon
|
||||
std::set<LLPointer<LLViewerFetchedTexture> > mImagePreloads;
|
||||
|
||||
BOOL mInitialized ;
|
||||
S32Megabytes mMaxResidentTexMemInMegaBytes;
|
||||
S32Megabytes mMaxTotalTextureMemInMegaBytes;
|
||||
LLFrameTimer mForceDecodeTimer;
|
||||
|
||||
private:
|
||||
|
|
|
|||
|
|
@ -493,24 +493,12 @@ public:
|
|||
|
||||
if (gSavedSettings.getBOOL("DebugShowTime"))
|
||||
{
|
||||
{
|
||||
const U32 y_inc2 = 15;
|
||||
LLFrameTimer& timer = gTextureTimer;
|
||||
F32 time = timer.getElapsedTimeF32();
|
||||
S32 hours = (S32)(time / (60*60));
|
||||
S32 mins = (S32)((time - hours*(60*60)) / 60);
|
||||
S32 secs = (S32)((time - hours*(60*60) - mins*60));
|
||||
addText(xpos, ypos, llformat("Texture: %d:%02d:%02d", hours,mins,secs)); ypos += y_inc2;
|
||||
}
|
||||
|
||||
{
|
||||
F32 time = gFrameTimeSeconds;
|
||||
S32 hours = (S32)(time / (60*60));
|
||||
S32 mins = (S32)((time - hours*(60*60)) / 60);
|
||||
S32 secs = (S32)((time - hours*(60*60) - mins*60));
|
||||
addText(xpos, ypos, llformat("Time: %d:%02d:%02d", hours,mins,secs)); ypos += y_inc;
|
||||
}
|
||||
}
|
||||
|
||||
if (gSavedSettings.getBOOL("DebugShowMemory"))
|
||||
{
|
||||
|
|
@ -5640,7 +5628,6 @@ void LLViewerWindow::stopGL(BOOL save_state)
|
|||
|
||||
// Pause texture decode threads (will get unpaused during main loop)
|
||||
LLAppViewer::getTextureCache()->pause();
|
||||
LLAppViewer::getImageDecodeThread()->pause();
|
||||
LLAppViewer::getTextureFetch()->pause();
|
||||
|
||||
gSky.destroyGL();
|
||||
|
|
@ -5687,8 +5674,6 @@ void LLViewerWindow::stopGL(BOOL save_state)
|
|||
LLGLSLShader* shader = *(LLGLSLShader::sInstances.begin());
|
||||
shader->unload();
|
||||
}
|
||||
|
||||
LL_INFOS() << "Remaining allocated texture memory: " << LLImageGL::sGlobalTextureMemory.value() << " bytes" << LL_ENDL;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -5707,7 +5707,6 @@ void LLVOAvatar::checkTextureLoading()
|
|||
}
|
||||
|
||||
const F32 SELF_ADDITIONAL_PRI = 0.75f ;
|
||||
const F32 ADDITIONAL_PRI = 0.5f;
|
||||
void LLVOAvatar::addBakedTextureStats( LLViewerFetchedTexture* imagep, F32 pixel_area, F32 texel_area_ratio, S32 boost_level)
|
||||
{
|
||||
//Note:
|
||||
|
|
@ -5722,15 +5721,6 @@ void LLVOAvatar::addBakedTextureStats( LLViewerFetchedTexture* imagep, F32 pixel
|
|||
mMinPixelArea = llmin(pixel_area, mMinPixelArea);
|
||||
imagep->addTextureStats(pixel_area / texel_area_ratio);
|
||||
imagep->setBoostLevel(boost_level);
|
||||
|
||||
if(boost_level != LLGLTexture::BOOST_AVATAR_BAKED_SELF)
|
||||
{
|
||||
imagep->setAdditionalDecodePriority(ADDITIONAL_PRI) ;
|
||||
}
|
||||
else
|
||||
{
|
||||
imagep->setAdditionalDecodePriority(SELF_ADDITIONAL_PRI) ;
|
||||
}
|
||||
}
|
||||
|
||||
//virtual
|
||||
|
|
|
|||
|
|
@ -1825,7 +1825,7 @@ void LLVOAvatarSelf::dumpLocalTextures() const
|
|||
}
|
||||
else
|
||||
{
|
||||
const LLViewerFetchedTexture* image = dynamic_cast<LLViewerFetchedTexture*>( local_tex_obj->getImage() );
|
||||
LLViewerFetchedTexture* image = dynamic_cast<LLViewerFetchedTexture*>( local_tex_obj->getImage() );
|
||||
|
||||
LL_INFOS() << "LocTex " << name << ": "
|
||||
<< "Discard " << image->getDiscardLevel() << ", "
|
||||
|
|
@ -1835,7 +1835,7 @@ void LLVOAvatarSelf::dumpLocalTextures() const
|
|||
// makes textures easier to steal
|
||||
<< image->getID() << " "
|
||||
#endif
|
||||
<< "Priority: " << image->getDecodePriority()
|
||||
<< "Priority: " << image->getMaxVirtualSize()
|
||||
<< LL_ENDL;
|
||||
}
|
||||
}
|
||||
|
|
@ -2074,8 +2074,7 @@ const std::string LLVOAvatarSelf::verboseDebugDumpLocalTextureDataInfo(const LLV
|
|||
<< " glocdisc: " << getLocalDiscardLevel(tex_index, wearable_index)
|
||||
<< " discard: " << image->getDiscardLevel()
|
||||
<< " desired: " << image->getDesiredDiscardLevel()
|
||||
<< " decode: " << image->getDecodePriority()
|
||||
<< " addl: " << image->getAdditionalDecodePriority()
|
||||
<< " vsize: " << image->getMaxVirtualSize()
|
||||
<< " ts: " << image->getTextureState()
|
||||
<< " bl: " << image->getBoostLevel()
|
||||
<< " fl: " << image->isFullyLoaded() // this is not an accessor for mFullyLoaded - see comment there.
|
||||
|
|
@ -2453,7 +2452,6 @@ void LLVOAvatarSelf::addLocalTextureStats( ETextureIndex type, LLViewerFetchedTe
|
|||
desired_pixels = llmin(mPixelArea, (F32)getTexImageArea());
|
||||
|
||||
imagep->setBoostLevel(getAvatarBoostLevel());
|
||||
imagep->setAdditionalDecodePriority(SELF_ADDITIONAL_PRI) ;
|
||||
imagep->resetTextureStats();
|
||||
imagep->setMaxVirtualSizeResetInterval(MAX_TEXTURE_VIRTUAL_SIZE_RESET_INTERVAL);
|
||||
imagep->addTextureStats( desired_pixels / texel_area_ratio );
|
||||
|
|
@ -2823,7 +2821,6 @@ void LLVOAvatarSelf::deleteScratchTextures()
|
|||
LL_DEBUGS() << "Clearing Scratch Textures " << (S32Kilobytes)sScratchTexBytes << LL_ENDL;
|
||||
|
||||
delete_and_clear(sScratchTexNames);
|
||||
LLImageGL::sGlobalTextureMemory -= sScratchTexBytes;
|
||||
sScratchTexBytes = S32Bytes(0);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -696,12 +696,13 @@ void LLVOVolume::animateTextures()
|
|||
|
||||
void LLVOVolume::updateTextures()
|
||||
{
|
||||
const F32 TEXTURE_AREA_REFRESH_TIME = 5.f; // seconds
|
||||
if (mTextureUpdateTimer.getElapsedTimeF32() > TEXTURE_AREA_REFRESH_TIME)
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
|
||||
//const F32 TEXTURE_AREA_REFRESH_TIME = 1.f; // seconds
|
||||
//if (mTextureUpdateTimer.getElapsedTimeF32() > TEXTURE_AREA_REFRESH_TIME)
|
||||
{
|
||||
updateTextureVirtualSize();
|
||||
|
||||
if (mDrawable.notNull() && !isVisible() && !mDrawable->isActive())
|
||||
/*if (mDrawable.notNull() && !isVisible() && !mDrawable->isActive())
|
||||
{ //delete vertex buffer to free up some VRAM
|
||||
LLSpatialGroup* group = mDrawable->getSpatialGroup();
|
||||
if (group && (group->mVertexBuffer.notNull() || !group->mBufferMap.empty() || !group->mDrawMap.empty()))
|
||||
|
|
@ -712,9 +713,7 @@ void LLVOVolume::updateTextures()
|
|||
//it becomes visible
|
||||
group->setState(LLSpatialGroup::GEOM_DIRTY | LLSpatialGroup::MESH_DIRTY | LLSpatialGroup::NEW_DRAWINFO);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}*/
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -788,6 +787,7 @@ void LLVOVolume::updateTextureVirtualSize(bool forced)
|
|||
const S32 num_faces = mDrawable->getNumFaces();
|
||||
F32 min_vsize=999999999.f, max_vsize=0.f;
|
||||
LLViewerCamera* camera = LLViewerCamera::getInstance();
|
||||
std::stringstream debug_text;
|
||||
for (S32 i = 0; i < num_faces; i++)
|
||||
{
|
||||
LLFace* face = mDrawable->getFace(i);
|
||||
|
|
@ -814,10 +814,14 @@ void LLVOVolume::updateTextureVirtualSize(bool forced)
|
|||
else
|
||||
{
|
||||
vsize = face->getTextureVirtualSize();
|
||||
imagep->addTextureStats(vsize);
|
||||
}
|
||||
|
||||
mPixelArea = llmax(mPixelArea, face->getPixelArea());
|
||||
mPixelArea = llmax(mPixelArea, face->getPixelArea());
|
||||
|
||||
// if the face has gotten small enough to turn off texture animation and texture
|
||||
// animation is running, rebuild the render batch for this face to turn off
|
||||
// texture animation
|
||||
if (face->mTextureMatrix != NULL)
|
||||
{
|
||||
if ((vsize < MIN_TEX_ANIM_SIZE && old_size > MIN_TEX_ANIM_SIZE) ||
|
||||
|
|
@ -837,10 +841,11 @@ void LLVOVolume::updateTextureVirtualSize(bool forced)
|
|||
LLViewerFetchedTexture* img = LLViewerTextureManager::staticCastToFetchedTexture(imagep) ;
|
||||
if(img)
|
||||
{
|
||||
F32 pri = img->getDecodePriority();
|
||||
debug_text << img->getDiscardLevel() << ":" << img->getDesiredDiscardLevel() << ":" << img->getWidth() << ":" << (S32) sqrtf(vsize) << ":" << (S32) sqrtf(img->getMaxVirtualSize()) << "\n";
|
||||
/*F32 pri = img->getDecodePriority();
|
||||
pri = llmax(pri, 0.0f);
|
||||
if (pri < min_vsize) min_vsize = pri;
|
||||
if (pri > max_vsize) max_vsize = pri;
|
||||
if (pri > max_vsize) max_vsize = pri;*/
|
||||
}
|
||||
}
|
||||
else if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_FACE_AREA))
|
||||
|
|
@ -872,14 +877,6 @@ void LLVOVolume::updateTextureVirtualSize(bool forced)
|
|||
F32 lodf = ((F32)(lod + 1.0f)/4.f);
|
||||
F32 tex_size = lodf * LLViewerTexture::sMaxSculptRez ;
|
||||
mSculptTexture->addTextureStats(2.f * tex_size * tex_size, FALSE);
|
||||
|
||||
//if the sculpty very close to the view point, load first
|
||||
{
|
||||
LLVector3 lookAt = getPositionAgent() - camera->getOrigin();
|
||||
F32 dist = lookAt.normVec() ;
|
||||
F32 cos_angle_to_view_dir = lookAt * camera->getXAxis() ;
|
||||
mSculptTexture->setAdditionalDecodePriority(0.8f * LLFace::calcImportanceToCamera(cos_angle_to_view_dir, dist)) ;
|
||||
}
|
||||
}
|
||||
|
||||
S32 texture_discard = mSculptTexture->getCachedRawImageLevel(); //try to match the texture
|
||||
|
|
@ -923,7 +920,8 @@ void LLVOVolume::updateTextureVirtualSize(bool forced)
|
|||
}
|
||||
else if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_TEXTURE_PRIORITY))
|
||||
{
|
||||
setDebugText(llformat("%.0f:%.0f", (F32) sqrt(min_vsize),(F32) sqrt(max_vsize)));
|
||||
//setDebugText(llformat("%.0f:%.0f", (F32) sqrt(min_vsize),(F32) sqrt(max_vsize)));
|
||||
setDebugText(debug_text.str());
|
||||
}
|
||||
else if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_FACE_AREA))
|
||||
{
|
||||
|
|
|
|||
|
|
@ -395,7 +395,7 @@ void LLXMLRPCTransaction::Impl::init(XMLRPC_REQUEST request, bool useGzip, const
|
|||
|
||||
mHandler = LLXMLRPCTransaction::Handler::ptr_t(new Handler( mHttpRequest, this ));
|
||||
|
||||
mPostH = mHttpRequest->requestPost(LLCore::HttpRequest::DEFAULT_POLICY_ID, 0,
|
||||
mPostH = mHttpRequest->requestPost(LLCore::HttpRequest::DEFAULT_POLICY_ID,
|
||||
mURI, body.get(), httpOpts, httpHeaders, mHandler);
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -442,6 +442,7 @@ void LLPipeline::connectRefreshCachedSettingsSafe(const std::string name)
|
|||
|
||||
void LLPipeline::init()
|
||||
{
|
||||
LL_WARNS() << "Begin pipeline initialization" << LL_ENDL; // TODO: Remove after testing
|
||||
refreshCachedSettings();
|
||||
|
||||
mRT = &mMainRT;
|
||||
|
|
@ -460,6 +461,7 @@ void LLPipeline::init()
|
|||
mInitialized = true;
|
||||
|
||||
stop_glerror();
|
||||
LL_WARNS() << "No GL errors yet. Pipeline initialization will continue." << LL_ENDL; // TODO: Remove after testing
|
||||
|
||||
//create render pass pools
|
||||
getPool(LLDrawPool::POOL_ALPHA);
|
||||
|
|
@ -521,7 +523,9 @@ void LLPipeline::init()
|
|||
|
||||
// Enable features
|
||||
|
||||
LL_WARNS() << "Shader initialization start" << LL_ENDL; // TODO: Remove after testing
|
||||
LLViewerShaderMgr::instance()->setShaders();
|
||||
LL_WARNS() << "Shader initialization end" << LL_ENDL; // TODO: Remove after testing
|
||||
|
||||
stop_glerror();
|
||||
|
||||
|
|
@ -3745,7 +3749,7 @@ void LLPipeline::touchTexture(LLViewerTexture* tex, F32 vsize)
|
|||
if (tex)
|
||||
{
|
||||
LLImageGL* gl_tex = tex->getGLTexture();
|
||||
if (gl_tex && gl_tex->updateBindStats(gl_tex->mTextureMemory))
|
||||
if (gl_tex && gl_tex->updateBindStats())
|
||||
{
|
||||
tex->setActive();
|
||||
tex->addTextureStats(vsize);
|
||||
|
|
@ -3815,25 +3819,47 @@ void LLPipeline::postSort(LLCamera& camera)
|
|||
group->rebuildGeom();
|
||||
}
|
||||
|
||||
for (LLSpatialGroup::draw_map_t::iterator j = group->mDrawMap.begin(); j != group->mDrawMap.end(); ++j)
|
||||
{
|
||||
LLSpatialGroup::drawmap_elem_t& src_vec = j->second;
|
||||
if (!hasRenderType(j->first))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
for (LLSpatialGroup::drawmap_elem_t::iterator k = src_vec.begin(); k != src_vec.end(); ++k)
|
||||
{
|
||||
for (LLSpatialGroup::draw_map_t::iterator j = group->mDrawMap.begin(); j != group->mDrawMap.end(); ++j)
|
||||
{
|
||||
LLSpatialGroup::drawmap_elem_t& src_vec = j->second;
|
||||
if (!hasRenderType(j->first))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// DEBUG -- force a texture virtual size update every frame
|
||||
/*if (group->getSpatialPartition()->mDrawableType == LLPipeline::RENDER_TYPE_VOLUME)
|
||||
{
|
||||
LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("plps - update vsize");
|
||||
auto& entries = group->getData();
|
||||
for (auto& entry : entries)
|
||||
{
|
||||
if (entry)
|
||||
{
|
||||
auto* data = entry->getDrawable();
|
||||
if (data)
|
||||
{
|
||||
LLVOVolume* volume = ((LLDrawable*)data)->getVOVolume();
|
||||
if (volume)
|
||||
{
|
||||
volume->updateTextureVirtualSize(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
for (LLSpatialGroup::drawmap_elem_t::iterator k = src_vec.begin(); k != src_vec.end(); ++k)
|
||||
{
|
||||
LLDrawInfo* info = *k;
|
||||
|
||||
sCull->pushDrawInfo(j->first, info);
|
||||
|
||||
sCull->pushDrawInfo(j->first, info);
|
||||
if (!sShadowRender && !sReflectionRender && !gCubeSnapshot)
|
||||
{
|
||||
touchTextures(info);
|
||||
addTrianglesDrawn(info->mCount, info->mDrawMode);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (hasRenderType(LLPipeline::RENDER_TYPE_PASS_ALPHA))
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue