Henri's HTTP pipeline, with SG twist

This commit is contained in:
Siana Gearz
2010-12-30 20:27:26 +01:00
parent e31c21fc54
commit 5fd5049e9b
15 changed files with 1102 additions and 584 deletions

View File

@@ -60,6 +60,27 @@ LLWorkerThread::~LLWorkerThread()
// ~LLQueuedThread() will be called here
}
//called only in destructor.
void LLWorkerThread::clearDeleteList()
{
// Delete any workers in the delete queue (should be safe - had better be!)
if (!mDeleteList.empty())
{
llwarns << "Worker Thread: " << mName << " destroyed with " << mDeleteList.size()
<< " entries in delete list." << llendl;
mDeleteMutex->lock();
for (delete_list_t::iterator iter = mDeleteList.begin(); iter != mDeleteList.end(); ++iter)
{
(*iter)->mRequestHandle = LLWorkerThread::nullHandle();
(*iter)->clearFlags(LLWorkerClass::WCF_HAVE_WORK);
delete *iter ;
}
mDeleteList.clear() ;
mDeleteMutex->unlock() ;
}
}
// virtual
S32 LLWorkerThread::update(U32 max_time_ms)
{
@@ -181,6 +202,7 @@ void LLWorkerThread::WorkRequest::finishRequest(bool completed)
LLWorkerClass::LLWorkerClass(LLWorkerThread* workerthread, const std::string& name)
: mWorkerThread(workerthread),
mRequestPriority(LLWorkerThread::PRIORITY_NORMAL),
mWorkerClassName(name),
mRequestHandle(LLWorkerThread::nullHandle()),
mMutex(NULL),
@@ -314,7 +336,20 @@ bool LLWorkerClass::checkWork(bool aborting)
if (mRequestHandle != LLWorkerThread::nullHandle())
{
LLWorkerThread::WorkRequest* workreq = (LLWorkerThread::WorkRequest*)mWorkerThread->getRequest(mRequestHandle);
if(!workreq)
{
if(mWorkerThread->isQuitting() || mWorkerThread->isStopped()) //the mWorkerThread is not running
{
mRequestHandle = LLWorkerThread::nullHandle();
clearFlags(WCF_HAVE_WORK);
}
else
{
llassert_always(workreq);
}
return true ;
}
LLQueuedThread::status_t status = workreq->getStatus();
if (status == LLWorkerThread::STATUS_ABORTED)
{
@@ -364,7 +399,7 @@ void LLWorkerClass::scheduleDelete()
void LLWorkerClass::setPriority(U32 priority)
{
mMutex.lock();
if (mRequestHandle != LLWorkerThread::nullHandle())
if (mRequestHandle != LLWorkerThread::nullHandle() && mRequestPriority != priority)
{
mRequestPriority = priority;
mWorkerThread->setPriority(mRequestHandle, priority);

View File

@@ -80,6 +80,9 @@ public:
S32 mParam;
};
protected:
void clearDeleteList();
private:
typedef std::list<LLWorkerClass*> delete_list_t;
delete_list_t mDeleteList;

View File

@@ -11236,7 +11236,7 @@
<key>Type</key>
<string>F32</string>
<key>Value</key>
<real>500.0</real>
<real>2000.0</real>
</map>
<key>ToolHelpRect</key>
<map>

View File

@@ -1428,6 +1428,8 @@ bool LLAppViewer::cleanup()
sTextureCache->shutdown();
sTextureFetch->shutdown();
sImageDecodeThread->shutdown();
sTextureFetch->shutDownTextureCacheThread();
sTextureFetch->shutDownImageDecodeThread();
delete sTextureCache;
sTextureCache = NULL;
delete sTextureFetch;
@@ -2853,6 +2855,22 @@ void LLAppViewer::migrateCacheDirectory()
bool LLAppViewer::initCache()
{
mPurgeCache = false;
BOOL read_only = mSecondInstance ? TRUE : FALSE;
LLAppViewer::getTextureCache()->setReadOnly(read_only);
BOOL texture_cache_mismatch = FALSE ;
static const S32 cache_version = 7;
if (gSavedSettings.getS32("LocalCacheVersion") != cache_version)
{
texture_cache_mismatch = TRUE ;
if (!read_only)
{
gSavedSettings.setS32("LocalCacheVersion", cache_version);
}
}
if (!read_only)
{
// Purge cache if user requested it
if (gSavedSettings.getBOOL("PurgeCacheOnStartup") ||
gSavedSettings.getBOOL("PurgeCacheOnNextStartup"))
@@ -2860,16 +2878,6 @@ bool LLAppViewer::initCache()
gSavedSettings.setBOOL("PurgeCacheOnNextStartup", false);
mPurgeCache = true;
}
// Purge cache if it belongs to an old version
else
{
static const S32 cache_version = 5;
if (gSavedSettings.getS32("LocalCacheVersion") != cache_version)
{
mPurgeCache = true;
gSavedSettings.setS32("LocalCacheVersion", cache_version);
}
}
// We have moved the location of the cache directory over time.
migrateCacheDirectory();
@@ -2883,6 +2891,7 @@ bool LLAppViewer::initCache()
purgeCache(); // purge old cache
gSavedSettings.setString("CacheLocation", new_cache_location);
}
}
if (!gDirUtilp->setCacheDir(gSavedSettings.getString("CacheLocation")))
{
@@ -2890,7 +2899,7 @@ bool LLAppViewer::initCache()
gSavedSettings.setString("CacheLocation", "");
}
if (mPurgeCache)
if (mPurgeCache && !read_only)
{
LLSplashScreen::update("Clearing cache...");
purgeCache();
@@ -2900,13 +2909,12 @@ bool LLAppViewer::initCache()
// Init the texture cache
// Allocate 80% of the cache size for textures
BOOL read_only = mSecondInstance ? TRUE : FALSE;
const S32 MB = 1024*1024;
S64 cache_size = (S64)(gSavedSettings.getU32("CacheSize")) * MB;
const S64 MAX_CACHE_SIZE = 1024*MB;
cache_size = llmin(cache_size, MAX_CACHE_SIZE);
S64 texture_cache_size = ((cache_size * 8)/10);
S64 extra = LLAppViewer::getTextureCache()->initCache(LL_PATH_CACHE, texture_cache_size, read_only);
S64 extra = LLAppViewer::getTextureCache()->initCache(LL_PATH_CACHE, texture_cache_size, texture_cache_mismatch);
texture_cache_size -= extra;
LLSplashScreen::update("Initializing VFS...");

View File

@@ -1252,16 +1252,17 @@ F32 LLFace::getTextureVirtualSize()
{
F32 radius;
F32 cos_angle_to_view_dir;
mPixelArea = calcPixelArea(cos_angle_to_view_dir, radius);
BOOL in_frustum = calcPixelArea(cos_angle_to_view_dir, radius);
if (mPixelArea <= 0)
if (mPixelArea < F_ALMOST_ZERO || !in_frustum)
{
setVirtualSize(0.f) ;
return 0.f;
}
//get area of circle in texture space
LLVector2 tdim = mTexExtents[1] - mTexExtents[0];
F32 texel_area = (tdim * 0.5f).lengthSquared()*3.14159f;
F32 texel_area = (tdim * 0.5f).lengthSquared() * 3.14159f;
if (texel_area <= 0)
{
// Probably animated, use default
@@ -1278,59 +1279,73 @@ F32 LLFace::getTextureVirtualSize()
{
//apply texel area to face area to get accurate ratio
//face_area /= llclamp(texel_area, 1.f/64.f, 16.f);
//face_area = mPixelArea / llclamp(texel_area, 0.015625f, 1024.f);
face_area = mPixelArea / llclamp(texel_area, 0.015625f, 128.f); // see SNOW-207
face_area = mPixelArea / llclamp(texel_area, 0.015625f, 128.f);
}
if(face_area > LLViewerImage::sMaxSmallImageSize)
face_area = LLFace::adjustPixelArea(mImportanceToCamera, face_area);
if (mImportanceToCamera < 1.0f && face_area > LLViewerImage::sMinLargeImageSize) //if is large image, shrink face_area by considering the partial overlapping.
{
if(mImportanceToCamera < LEAST_IMPORTANCE) //if the face is not important, do not load hi-res.
if (mImportanceToCamera > LEAST_IMPORTANCE_FOR_LARGE_IMAGE && mTexture.notNull() && mTexture->isLargeImage())
{
face_area = LLViewerImage::sMaxSmallImageSize ;
face_area *= adjustPartialOverlapPixelArea(cos_angle_to_view_dir, radius);
}
}
else if(face_area > LLViewerImage::sMinLargeImageSize) //if is large image, shrink face_area by considering the partial overlapping.
{
if(mImportanceToCamera < LEAST_IMPORTANCE_FOR_LARGE_IMAGE)//if the face is not important, do not load hi-res.
{
face_area = LLViewerImage::sMinLargeImageSize ;
}
else if(mTexture.notNull() && mTexture->isLargeImage())
{
face_area *= adjustPartialOverlapPixelArea(cos_angle_to_view_dir, radius );
}
}
}
setVirtualSize(face_area);
return face_area;
}
F32 LLFace::calcPixelArea(F32& cos_angle_to_view_dir, F32& radius)
//static
F32 LLFace::adjustPixelArea(F32 importance, F32 pixel_area)
{
if (pixel_area > LLViewerImage::sMaxSmallImageSize)
{
if (importance < LEAST_IMPORTANCE) //if the face is not important, do not load hi-res.
{
static const F32 MAX_LEAST_IMPORTANCE_IMAGE_SIZE = 128.0f * 128.0f;
pixel_area = llmin(pixel_area * 0.5f, MAX_LEAST_IMPORTANCE_IMAGE_SIZE);
}
else if (pixel_area > LLViewerImage::sMinLargeImageSize) //if is large image, shrink face_area by considering the partial overlapping.
{
if (importance < LEAST_IMPORTANCE_FOR_LARGE_IMAGE) //if the face is not important, do not load hi-res.
{
pixel_area = LLViewerImage::sMinLargeImageSize;
}
}
}
return pixel_area ;
}
BOOL LLFace::calcPixelArea(F32& cos_angle_to_view_dir, F32& radius)
{
//get area of circle around face
LLVector3 center = getPositionAgent();
LLVector3 size = (mExtents[1] - mExtents[0]) * 0.5f;
LLViewerCamera* camera = LLViewerCamera::getInstance();
LLVector3 lookAt = center - LLViewerCamera::getInstance()->getOrigin();
F32 size_squared = size.lengthSquared() ;
LLVector3 lookAt = center - camera->getOrigin();
F32 dist = lookAt.normVec() ;
//get area of circle around node
F32 app_angle = atanf(size.length()/dist);
F32 app_angle = atanf(fsqrtf(size_squared) / dist);
radius = app_angle*LLDrawable::sCurPixelAngle;
F32 face_area = radius*radius * 3.14159f;
mPixelArea = radius*radius * 3.14159f;
cos_angle_to_view_dir = lookAt * camera->getXAxis();
if(dist < mBoundingSphereRadius) //camera is very close
if (dist < mBoundingSphereRadius || dist < 10.0f) //camera is very close
{
cos_angle_to_view_dir = 1.0f ;
mImportanceToCamera = 1.0f ;
cos_angle_to_view_dir = 1.0f;
mImportanceToCamera = 1.0f;
}
else
{
cos_angle_to_view_dir = lookAt * LLViewerCamera::getInstance()->getXAxis() ;
mImportanceToCamera = LLFace::calcImportanceToCamera(cos_angle_to_view_dir, dist) ;
mImportanceToCamera = LLFace::calcImportanceToCamera(cos_angle_to_view_dir, dist);
}
return face_area ;
return true;
}
//the projection of the face partially overlaps with the screen

View File

@@ -194,9 +194,10 @@ public:
private:
F32 adjustPartialOverlapPixelArea(F32 cos_angle_to_view_dir, F32 radius );
F32 calcPixelArea(F32& cos_angle_to_view_dir, F32& radius) ;
BOOL calcPixelArea(F32& cos_angle_to_view_dir, F32& radius);
public:
static F32 calcImportanceToCamera(F32 to_view_dir, F32 dist);
static F32 adjustPixelArea(F32 importance, F32 pixel_area);
public:

File diff suppressed because it is too large Load Diff

View File

@@ -40,6 +40,7 @@
#include "llworkerthread.h"
class LLImageFormatted;
class LLTextureCacheWorker;
class LLTextureCache : public LLWorkerThread
@@ -58,10 +59,11 @@ private:
};
struct Entry
{
Entry() {}
Entry() : mBodySize(0), mImageSize(0), mTime(0) { }
Entry(const LLUUID& id, S32 imagesize, S32 bodysize, U32 time) :
mID(id), mImageSize(imagesize), mBodySize(bodysize), mTime(time) {}
void init(const LLUUID& id, U32 time) { mID = id, mImageSize = 0; mBodySize = 0; mTime = time; }
Entry& operator=(const Entry& entry) { mID = entry.mID, mImageSize = entry.mImageSize; mBodySize = entry.mBodySize; mTime = entry.mTime; return *this; }
LLUUID mID; // 16 bytes
S32 mImageSize; // total size of image if known
S32 mBodySize; // size of body file in body cache
@@ -103,7 +105,8 @@ public:
/*virtual*/ S32 update(U32 max_time_ms);
void purgeCache(ELLPath location);
S64 initCache(ELLPath location, S64 maxsize, BOOL read_only);
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,
ReadResponder* responder);
@@ -116,7 +119,7 @@ public:
bool writeComplete(handle_t handle, bool abort = false);
void prioritizeWrite(handle_t handle);
void removeFromCache(const LLUUID& id);
bool removeFromCache(const LLUUID& id);
// For LLTextureCacheWorker::Responder
LLTextureCacheWorker* getReader(handle_t handle);
@@ -131,10 +134,11 @@ public:
S64 getMaxUsage() { return sCacheMaxTexturesSize; }
U32 getEntries() { return mHeaderEntriesInfo.mEntries; }
U32 getMaxEntries() { return sCacheMaxEntries; };
BOOL isInCache(const LLUUID& id) ;
BOOL isInLocal(const LLUUID& id) ;
protected:
// Accessed by LLTextureCacheWorker
bool updateTextureEntryList(const LLUUID& id, S32 size);
std::string getLocalFileName(const LLUUID& id);
std::string getTextureFileName(const LLUUID& id);
void addCompleted(Responder* responder, bool success);
@@ -145,20 +149,29 @@ protected:
private:
void setDirNames(ELLPath location);
void readHeaderCache();
void clearCorruptedCache();
void purgeAllTextures(bool purge_directories);
void purgeTextures(bool validate);
void purgeTextures(bool validate, bool force = false);
void purgeTextureFilesTimeSliced(BOOL force_all = FALSE); // VWR-3878 - NB
LLAPRFile* openHeaderEntriesFile(bool readonly, S32 offset);
void closeHeaderEntriesFile();
void readEntriesHeader();
void writeEntriesHeader();
S32 openAndReadEntry(const LLUUID& id, Entry& entry, bool create);
void writeEntryAndClose(S32 idx, Entry& entry);
bool updateEntry(S32& idx, Entry& entry, S32 new_image_size, S32 new_body_size);
void updateEntryTimeStamp(S32 idx, Entry& entry) ;
U32 openAndReadEntries(std::vector<Entry>& entries);
void writeEntriesAndClose(const std::vector<Entry>& entries);
S32 getHeaderCacheEntry(const LLUUID& id, S32& imagesize);
S32 setHeaderCacheEntry(const LLUUID& id, S32 imagesize);
bool removeHeaderCacheEntry(const LLUUID& id);
void removeFromCacheLocked(const LLUUID& id);
void readEntryFromHeaderImmediately(S32& idx, Entry& entry) ;
void writeEntryToHeaderImmediately(S32& idx, Entry& entry, bool write_header = false) ;
void removeEntry(S32 idx, Entry& entry, std::string& filename);
void removeCachedTexture(const LLUUID& id) ;
S32 getHeaderCacheEntry(const LLUUID& id, Entry& entry);
S32 setHeaderCacheEntry(const LLUUID& id, Entry& entry, S32 imagesize, S32 datasize);
void writeUpdatedEntries() ;
void updatedHeaderEntriesFile() ;
void lockHeaders() { mHeaderMutex.lock(); }
void unlockHeaders() { mHeaderMutex.unlock(); }
private:
// Internal
@@ -177,6 +190,9 @@ private:
typedef std::vector<std::pair<LLPointer<Responder>, bool> > responder_list_t;
responder_list_t mCompletedList;
typedef std::list<std::string> filename_list_t;
filename_list_t mFilesToDelete;
LLTimer mTimeLastFileDelete;
BOOL mReadOnly;
// HEADERS (Include first mip)
@@ -195,6 +211,9 @@ private:
S64 mTexturesSizeTotal;
LLAtomic32<BOOL> mDoPurge;
typedef std::map<S32, Entry> idx_entry_map_t;
idx_entry_map_t mUpdatedEntryMap;
// Statics
static F32 sHeaderCacheVersion;
static U32 sCacheMaxEntries;

File diff suppressed because it is too large Load Diff

View File

@@ -58,9 +58,11 @@ public:
~LLTextureFetch();
/*virtual*/ S32 update(U32 max_time_ms);
void shutDownTextureCacheThread() ; //called in the main thread after the TextureCacheThread shuts down.
void shutDownImageDecodeThread() ; //called in the main thread after the ImageDecodeThread shuts down.
bool createRequest(const std::string& url, const LLUUID& id, const LLHost& host, F32 priority,
S32 w, S32 h, S32 c, S32 discard, bool needs_aux, bool use_http);
S32 w, S32 h, S32 c, S32 discard, bool needs_aux, bool can_use_http);
void deleteRequest(const LLUUID& id, bool cancel);
bool getRequestFinished(const LLUUID& id, S32& discard_level,
LLPointer<LLImageRaw>& raw, LLPointer<LLImageRaw>& aux);
@@ -73,24 +75,26 @@ public:
F32 getTextureBandwidth() { return mTextureBandwidth; }
// Debug
BOOL isFromLocalCache(const LLUUID& id);
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);
U32& fetch_priority_p, F32& fetch_dtime_p, F32& request_dtime_p, bool& can_use_http);
void dump();
S32 getNumRequests() const { LLMutexLock lock(&mQueueMutex); return mRequestMap.size(); }
S32 getNumHTTPRequests() const { LLMutexLock lock(&mNetworkQueueMutex); return mHTTPTextureQueue.size(); }
S32 getNumRequests();
S32 getNumHTTPRequests();
// Public for access by callbacks
void lockQueue() { mQueueMutex.lock(); }
void unlockQueue() { mQueueMutex.unlock(); }
LLTextureFetchWorker* getWorker(const LLUUID& id);
LLTextureFetchWorker* getWorkerAfterLock(const LLUUID& id);
LLTextureInfo* getTextureInfo() { return &mTextureInfo; }
protected:
void addToNetworkQueue(LLTextureFetchWorker* worker);
void removeFromNetworkQueue(LLTextureFetchWorker* worker, bool cancel);
void addToHTTPQueue(const LLUUID& id);
void removeFromHTTPQueue(const LLUUID& id);
void removeFromHTTPQueue(const LLUUID& id, S32 received_size = 0);
void removeRequest(LLTextureFetchWorker* worker, bool cancel);
// Called from worker thread (during doWork)
void processCurlRequests();
@@ -109,8 +113,8 @@ public:
S32 mBadPacketCount;
private:
mutable LLMutex mQueueMutex;
mutable LLMutex mNetworkQueueMutex;
LLMutex mQueueMutex; //to protect mRequestMap only
LLMutex mNetworkQueueMutex; //to protect mNetworkQueue, mHTTPTextureQueue and mCancelQueue.
LLTextureCache* mTextureCache;
LLImageDecodeThread* mImageDecodeThread;
@@ -129,6 +133,8 @@ private:
F32 mTextureBandwidth;
F32 mMaxBandwidth;
LLTextureInfo mTextureInfo;
U32 mHTTPTextureBits;
};
#endif // LL_LLTEXTUREFETCH_H

View File

@@ -1026,8 +1026,7 @@ bool LLViewerImage::updateFetch()
S32 current_discard = getDiscardLevel();
S32 desired_discard = getDesiredDiscardLevel();
F32 decode_priority = getDecodePriority();
decode_priority = llmax(decode_priority, 0.0f);
decode_priority = llmin(decode_priority, maxDecodePriority());
decode_priority = llclamp(decode_priority, 0.0f, maxDecodePriority());
if (mIsFetching)
{
@@ -1053,7 +1052,7 @@ bool LLViewerImage::updateFetch()
else
{
mFetchState = LLAppViewer::getTextureFetch()->getFetchState(mID, mDownloadProgress, mRequestedDownloadPriority,
mFetchPriority, mFetchDeltaTime, mRequestDeltaTime);
mFetchPriority, mFetchDeltaTime, mRequestDeltaTime, mCanUseHTTP);
}
// We may have data ready regardless of whether or not we are finished (e.g. waiting on write)
@@ -1200,7 +1199,7 @@ bool LLViewerImage::updateFetch()
mRequestedDiscardLevel = desired_discard;
mFetchState = LLAppViewer::getTextureFetch()->getFetchState(mID, mDownloadProgress, mRequestedDownloadPriority,
mFetchPriority, mFetchDeltaTime, mRequestDeltaTime);
mFetchPriority, mFetchDeltaTime, mRequestDeltaTime, mCanUseHTTP);
}
// if createRequest() failed, we're finishing up a request for this UUID,
@@ -1282,7 +1281,7 @@ BOOL LLViewerImage::forceFetch()
mRequestedDiscardLevel = desired_discard ;
mFetchState = LLAppViewer::getTextureFetch()->getFetchState(mID, mDownloadProgress, mRequestedDownloadPriority,
mFetchPriority, mFetchDeltaTime, mRequestDeltaTime);
mFetchPriority, mFetchDeltaTime, mRequestDeltaTime, mCanUseHTTP);
}
return mIsFetching ? true : false;

View File

@@ -1492,10 +1492,8 @@ void init_debug_rendering_menu(LLMenuGL* menu)
item = new LLMenuItemCheckGL("Disable Textures", menu_toggle_variable, NULL, menu_check_variable, (void*)&LLViewerImage::sDontLoadVolumeTextures);
menu->append(item);
#if 1 //ndef LL_RELEASE_FOR_DOWNLOAD
item = new LLMenuItemCheckGL("HTTP Get Textures", menu_toggle_control, NULL, menu_check_control, (void*)"ImagePipelineUseHTTP");
menu->append(item);
#endif
item = new LLMenuItemCheckGL("Run Multiple Threads", menu_toggle_control, NULL, menu_check_control, (void*)"RunMultipleThreads");
menu->append(item);

View File

@@ -4358,7 +4358,14 @@ BOOL LLViewerWindow::rawSnapshot(LLImageRaw *raw, S32 image_width, S32 image_hei
image_buffer_x = llfloor(snapshot_width*scale_factor) ;
image_buffer_y = llfloor(snapshot_height *scale_factor) ;
}
if (image_buffer_x > 0 && image_buffer_y > 0)
{
raw->resize(image_buffer_x, image_buffer_y, 3);
}
else
{
return FALSE ;
}
if(raw->isBufferInvalid())
{
return FALSE ;

View File

@@ -446,23 +446,36 @@ void LLVOTree::render(LLAgent &agent)
void LLVOTree::setPixelAreaAndAngle(LLAgent &agent)
{
// First calculate values as for any other object (for mAppAngle)
LLViewerObject::setPixelAreaAndAngle(agent);
// Re-calculate mPixelArea accurately
LLVector3 center = getPositionAgent();//center of tree.
LLVector3 viewer_pos_agent = gAgent.getCameraPositionAgent();
LLVector3 lookAt = center - viewer_pos_agent;
F32 dist = lookAt.normVec() ;
F32 cos_angle_to_view_dir = lookAt * LLViewerCamera::getInstance()->getXAxis() ;
// This should be the camera's center, as soon as we move to all region-local.
LLVector3 relative_position = getPositionAgent() - agent.getCameraPositionAgent();
F32 range = relative_position.length(); // ugh, square root
F32 range = dist - getMinScale()/2;
if (range < F_ALMOST_ZERO) // range == zero
{
range = 0;
mAppAngle = 180.f;
}
else
{
mAppAngle = (F32) atan2( getMaxScale(), range) * RAD_TO_DEG;
}
F32 max_scale = mBillboardScale * getMaxScale();
F32 area = max_scale * (max_scale*mBillboardRatio);
// Compute pixels per meter at the given range
F32 pixels_per_meter = LLViewerCamera::getInstance()->getViewHeightInPixels() /
(tan(LLViewerCamera::getInstance()->getView()) * range);
F32 pixels_per_meter = LLViewerCamera::getInstance()->getViewHeightInPixels() / (tan(LLViewerCamera::getInstance()->getView()) * dist);
mPixelArea = pixels_per_meter * pixels_per_meter * area ;
F32 importance = LLFace::calcImportanceToCamera(cos_angle_to_view_dir, dist) ;
mPixelArea = LLFace::adjustPixelArea(importance, mPixelArea) ;
if (mPixelArea > LLViewerCamera::getInstance()->getScreenPixelArea())
{
mAppAngle = 180.f;
}
mPixelArea = (pixels_per_meter) * (pixels_per_meter) * area;
#if 0
// mAppAngle is a bit of voodoo;
// use the one calculated LLViewerObject::setPixelAreaAndAngle above

View File

@@ -465,6 +465,27 @@ void LLVOVolume::updateTextureVirtualSize()
else
{
vsize = face->getTextureVirtualSize();
if (isAttachment())
{
// Rez attachments faster and at full details !
if (permYouOwner())
{
// Our attachments must really rez fast and fully:
// we shouldn't have to zoom on them to get the textures
// fully loaded !
imagep->setBoostLevel(LLViewerImageBoostLevel::BOOST_HUD);
imagep->dontDiscard();
}
else
{
// Others' can get their texture discarded to avoid
// filling up the video buffers in crowded areas...
imagep->setBoostLevel(LLViewerImageBoostLevel::BOOST_SELECTED);
imagep->setAdditionalDecodePriority(1.5f);
vsize = (F32) LLViewerCamera::getInstance()->getScreenPixelArea();
face->setPixelArea(vsize); // treat as full screen
}
}
}
mPixelArea = llmax(mPixelArea, face->getPixelArea());