Merge viewer-development-shining up to REV 3bf724ecb7c6 (fix for SH-829: Viewer attempting to load precached images in file types that are not being used.)

master
Xiaohong Bao 2011-01-21 16:25:23 -07:00
commit 4af7e9eb64
28 changed files with 3465 additions and 3291 deletions

View File

@ -274,11 +274,11 @@ LLImageRaw::LLImageRaw(U8 *data, U16 width, U16 height, S8 components)
++sRawImageCount;
}
LLImageRaw::LLImageRaw(const std::string& filename, bool j2c_lowest_mip_only)
: LLImageBase()
{
createFromFile(filename, j2c_lowest_mip_only);
}
//LLImageRaw::LLImageRaw(const std::string& filename, bool j2c_lowest_mip_only)
// : LLImageBase()
//{
// createFromFile(filename, j2c_lowest_mip_only);
//}
LLImageRaw::~LLImageRaw()
{
@ -1178,7 +1178,7 @@ file_extensions[] =
{ "png", IMG_CODEC_PNG }
};
#define NUM_FILE_EXTENSIONS LL_ARRAY_SIZE(file_extensions)
#if 0
static std::string find_file(std::string &name, S8 *codec)
{
std::string tname;
@ -1196,7 +1196,7 @@ static std::string find_file(std::string &name, S8 *codec)
}
return std::string("");
}
#endif
EImageCodec LLImageBase::getCodecFromExtension(const std::string& exten)
{
for (int i=0; i<(int)(NUM_FILE_EXTENSIONS); i++)
@ -1206,7 +1206,7 @@ EImageCodec LLImageBase::getCodecFromExtension(const std::string& exten)
}
return IMG_CODEC_INVALID;
}
#if 0
bool LLImageRaw::createFromFile(const std::string &filename, bool j2c_lowest_mip_only)
{
std::string name = filename;
@ -1313,7 +1313,7 @@ bool LLImageRaw::createFromFile(const std::string &filename, bool j2c_lowest_mip
return true;
}
#endif
//---------------------------------------------------------------------------
// LLImageFormatted
//---------------------------------------------------------------------------

View File

@ -164,7 +164,7 @@ public:
LLImageRaw(U16 width, U16 height, S8 components);
LLImageRaw(U8 *data, U16 width, U16 height, S8 components);
// Construct using createFromFile (used by tools)
LLImageRaw(const std::string& filename, bool j2c_lowest_mip_only = false);
//LLImageRaw(const std::string& filename, bool j2c_lowest_mip_only = false);
/*virtual*/ void deleteData();
/*virtual*/ U8* allocateData(S32 size = -1);
@ -226,7 +226,7 @@ public:
protected:
// Create an image from a local file (generally used in tools)
bool createFromFile(const std::string& filename, bool j2c_lowest_mip_only = false);
//bool createFromFile(const std::string& filename, bool j2c_lowest_mip_only = false);
void copyLineScaled( U8* in, U8* out, S32 in_pixel_len, S32 out_pixel_len, S32 in_pixel_step, S32 out_pixel_step );
void compositeRowScaled4onto3( U8* in, U8* out, S32 in_pixel_len, S32 out_pixel_len );

View File

@ -4406,19 +4406,54 @@ std::ostream& operator<<(std::ostream &s, const LLVolume *volumep)
BOOL LLVolumeFace::create(LLVolume* volume, BOOL partial_build)
{
BOOL ret = FALSE ;
if (mTypeMask & CAP_MASK)
{
return createCap(volume, partial_build);
ret = createCap(volume, partial_build);
}
else if ((mTypeMask & END_MASK) || (mTypeMask & SIDE_MASK))
{
return createSide(volume, partial_build);
ret = createSide(volume, partial_build);
}
else
{
llerrs << "Unknown/uninitialized face type!" << llendl;
return FALSE;
}
//update the range of the texture coordinates
if(ret)
{
mTexCoordExtents[0].setVec(1.f, 1.f) ;
mTexCoordExtents[1].setVec(0.f, 0.f) ;
U32 end = mVertices.size() ;
for(U32 i = 0 ; i < end ; i++)
{
if(mTexCoordExtents[0].mV[0] > mVertices[i].mTexCoord.mV[0])
{
mTexCoordExtents[0].mV[0] = mVertices[i].mTexCoord.mV[0] ;
}
if(mTexCoordExtents[1].mV[0] < mVertices[i].mTexCoord.mV[0])
{
mTexCoordExtents[1].mV[0] = mVertices[i].mTexCoord.mV[0] ;
}
if(mTexCoordExtents[0].mV[1] > mVertices[i].mTexCoord.mV[1])
{
mTexCoordExtents[0].mV[1] = mVertices[i].mTexCoord.mV[1] ;
}
if(mTexCoordExtents[1].mV[1] < mVertices[i].mTexCoord.mV[1])
{
mTexCoordExtents[1].mV[1] = mVertices[i].mTexCoord.mV[1] ;
}
}
mTexCoordExtents[0].mV[0] = llmax(0.f, mTexCoordExtents[0].mV[0]) ;
mTexCoordExtents[0].mV[1] = llmax(0.f, mTexCoordExtents[0].mV[1]) ;
mTexCoordExtents[1].mV[0] = llmin(1.f, mTexCoordExtents[1].mV[0]) ;
mTexCoordExtents[1].mV[1] = llmin(1.f, mTexCoordExtents[1].mV[1]) ;
}
return ret ;
}
void LerpPlanarVertex(LLVolumeFace::VertexData& v0,

View File

@ -831,6 +831,7 @@ public:
S32 mNumT;
LLVector3 mExtents[2]; //minimum and maximum point of face
LLVector2 mTexCoordExtents[2]; //minimum and maximum of texture coordinates of the face.
std::vector<VertexData> mVertices;
std::vector<U16> mIndices;

View File

@ -403,7 +403,7 @@ S32 LLTextureEntry::setOffsetT(F32 t)
S32 LLTextureEntry::setRotation(F32 theta)
{
if (mRotation != theta)
if (mRotation != theta && llfinite(theta))
{
mRotation = theta;
return TEM_CHANGE_TEXTURE;

View File

@ -1063,16 +1063,6 @@ BOOL LLImageGL::setSubImageFromFrameBuffer(S32 fb_x, S32 fb_y, S32 x_pos, S32 y_
{
if (gGL.getTexUnit(0)->bind(this, false, true))
{
if(gGLManager.mDebugGPU)
{
llinfos << "Calling glCopyTexSubImage2D(...)" << llendl ;
checkTexSize(true) ;
llcallstacks << fb_x << " : " << fb_y << " : " << x_pos << " : " << y_pos << " : " << width << " : " << height <<
" : " << (S32)mComponents << llcallstacksendl ;
log_glerror() ;
}
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, fb_x, fb_y, x_pos, y_pos, width, height);
mGLTextureCreated = true;
stop_glerror();

View File

@ -101,10 +101,18 @@ S32 LLDir::deleteFilesInDir(const std::string &dirname, const std::string &mask)
{
if (0 != LLFile::remove(fullpath))
{
retry_count++;
result = errno;
llwarns << "Problem removing " << fullpath << " - errorcode: "
<< result << " attempt " << retry_count << llendl;
ms_sleep(1000);
if(retry_count >= 5)
{
llwarns << "Failed to remove " << fullpath << llendl ;
return count ;
}
ms_sleep(100);
}
else
{
@ -113,8 +121,7 @@ S32 LLDir::deleteFilesInDir(const std::string &dirname, const std::string &mask)
llwarns << "Successfully removed " << fullpath << llendl;
}
break;
}
retry_count++;
}
}
count++;
}

View File

@ -1918,10 +1918,21 @@
<key>Value</key>
<integer>0</integer>
</map>
<key>DebugShowTextureInfo</key>
<map>
<key>Comment</key>
<string>Show inertested texture info</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
<integer>0</integer>
</map>
<key>DebugShowTime</key>
<map>
<key>Comment</key>
<string>Show depth buffer contents</string>
<string>Show time info</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>

View File

@ -46,7 +46,7 @@ public:
/**
* Get host to which to send that capability request.
*/
virtual LLHost getHost() const = 0;
virtual const LLHost& getHost() const = 0;
/**
* Describe this LLCapabilityProvider for logging etc.
*/

View File

@ -177,10 +177,6 @@ void LLViewerDynamicTexture::postRender(BOOL success)
generateGLTexture() ;
}
if(gGLManager.mDebugGPU)
{
LLGLState::dumpStates() ;
}
success = mGLTexturep->setSubImageFromFrameBuffer(0, 0, mOrigin.mX, mOrigin.mY, mFullWidth, mFullHeight);
}
}
@ -220,12 +216,6 @@ BOOL LLViewerDynamicTexture::updateAllInstances()
LLViewerDynamicTexture *dynamicTexture = *iter;
if (dynamicTexture->needsRender())
{
if(gGLManager.mDebugGPU)
{
llinfos << "class type: " << (S32)dynamicTexture->getType() << llendl;
LLGLState::dumpStates() ;
}
glClear(GL_DEPTH_BUFFER_BIT);
gDepthDirty = TRUE;

View File

@ -1155,7 +1155,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
if (rebuild_tcoord)
{
LLVector2 tc = vf.mVertices[i].mTexCoord;
if (texgen != LLTextureEntry::TEX_GEN_DEFAULT)
{
LLVector3 vec = vf.mVertices[i].mPosition;
@ -1331,7 +1331,14 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
mTexExtents[0].setVec(0,0);
mTexExtents[1].setVec(1,1);
xform(mTexExtents[0], cos_ang, sin_ang, os, ot, ms, mt);
xform(mTexExtents[1], cos_ang, sin_ang, os, ot, ms, mt);
xform(mTexExtents[1], cos_ang, sin_ang, os, ot, ms, mt);
F32 es = vf.mTexCoordExtents[1].mV[0] - vf.mTexCoordExtents[0].mV[0] ;
F32 et = vf.mTexCoordExtents[1].mV[1] - vf.mTexCoordExtents[0].mV[1] ;
mTexExtents[0][0] *= es ;
mTexExtents[1][0] *= es ;
mTexExtents[0][1] *= et ;
mTexExtents[1][1] *= et ;
}
mLastVertexBuffer = mVertexBuffer;

View File

@ -273,6 +273,8 @@ void LLPreviewTexture::saveAs()
mSaveFileName = file_picker.getFirstFile();
mLoadingFullImage = TRUE;
getWindow()->incBusyCount();
mImage->forceToSaveRawImage(0) ;//re-fetch the raw image if the old one is removed.
mImage->setLoadedCallback( LLPreviewTexture::onFileLoadedForSave,
0, TRUE, FALSE, new LLUUID( mItemUUID ), &mCallbackTextureList );
}

View File

@ -326,6 +326,7 @@ bool LLTextureCacheRemoteWorker::doRead()
// First state / stage : find out if the file is local
if (mState == INIT)
{
#if 0
std::string filename = mCache->getLocalFileName(mID);
// Is it a JPEG2000 file?
{
@ -360,6 +361,11 @@ bool LLTextureCacheRemoteWorker::doRead()
}
// Determine the next stage: if we found a file, then LOCAL else CACHE
mState = (local_size > 0 ? LOCAL : CACHE);
llassert_always(mState == CACHE) ;
#else
mState = CACHE;
#endif
}
// Second state / stage : if the file is local, load it and leave

File diff suppressed because it is too large Load Diff

View File

@ -79,6 +79,7 @@ public:
void dump();
S32 getNumRequests() ;
S32 getNumHTTPRequests() ;
U32 getTotalNumHTTPRequests() ;
// Public for access by callbacks
S32 getPending();
@ -183,6 +184,9 @@ private:
U32 mHTTPTextureBits;
//debug use
U32 mTotalHTTPRequests ;
// Out-of-band cross-thread command queue. This command queue
// is logically tied to LLQueuedThread's list of
// QueuedRequest instances and so must be covered by the

View File

@ -516,6 +516,7 @@ void LLGLTexMemBar::draw()
S32 v_offset = (S32)((texture_bar_height + 2.2f) * mTextureView->mNumTextureBars + 2.0f);
F32 total_texture_downloaded = (F32)gTotalTextureBytes / (1024 * 1024);
F32 total_object_downloaded = (F32)gTotalObjectBytes / (1024 * 1024);
U32 total_http_requests = LLAppViewer::getTextureFetch()->getTotalNumHTTPRequests() ;
//----------------------------------------------------------------------------
LLGLSUIDefault gls_ui;
LLColor4 text_color(1.f, 1.f, 1.f, 0.75f);
@ -526,13 +527,13 @@ void LLGLTexMemBar::draw()
LLFontGL::getFontMonospace()->renderUTF8(text, 0, 0, v_offset + line_height*6,
text_color, LLFontGL::LEFT, LLFontGL::TOP);
text = llformat("GL Tot: %d/%d MB Bound: %d/%d MB Raw Tot: %d MB Bias: %.2f Cache: %.1f/%.1f MB Net Tot Tex: %.1f MB Tot Obj: %.1f MB",
text = llformat("GL Tot: %d/%d MB Bound: %d/%d MB Raw Tot: %d MB Bias: %.2f Cache: %.1f/%.1f MB Net Tot Tex: %.1f MB Tot Obj: %.1f MB Tot Htp: %d",
total_mem,
max_total_mem,
bound_mem,
max_bound_mem,
LLImageRaw::sGlobalRawMemory >> 20, discard_bias,
cache_usage, cache_max_usage, total_texture_downloaded, total_object_downloaded);
cache_usage, cache_max_usage, total_texture_downloaded, total_object_downloaded, total_http_requests);
//, cache_entries, cache_max_entries
LLFontGL::getFontMonospace()->renderUTF8(text, 0, 0, v_offset + line_height*3,

View File

@ -160,19 +160,13 @@ U64 LLViewerObjectList::getIndex(const U32 local_id,
return (((U64)index) << 32) | (U64)local_id;
}
BOOL LLViewerObjectList::removeFromLocalIDTable(const LLViewerObject &object)
BOOL LLViewerObjectList::removeFromLocalIDTable(const LLViewerObject* objectp)
{
if(object.getRegion())
if(objectp && objectp->getRegion())
{
U32 local_id = object.mLocalID;
LLHost region_host = object.getRegion()->getHost();
if(!region_host.isOk())
{
return FALSE ;
}
U32 ip = region_host.getAddress();
U32 port = region_host.getPort();
U32 local_id = objectp->mLocalID;
U32 ip = objectp->getRegion()->getHost().getAddress();
U32 port = objectp->getRegion()->getHost().getPort();
U64 ipport = (((U64)ip) << 32) | (U64)port;
U32 index = sIPAndPortToIndex[ipport];
@ -187,7 +181,7 @@ BOOL LLViewerObjectList::removeFromLocalIDTable(const LLViewerObject &object)
}
// Found existing entry
if (iter->second == object.getID())
if (iter->second == objectp->getID())
{ // Full UUIDs match, so remove the entry
sIndexAndLocalIDToUUID.erase(iter);
return TRUE;
@ -477,7 +471,7 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys,
// << ", regionp " << (U32) regionp << ", object region " << (U32) objectp->getRegion()
// << llendl;
//}
removeFromLocalIDTable(*objectp);
removeFromLocalIDTable(objectp);
setUUIDAndLocal(fullid,
local_id,
gMessageSystem->getSenderIP(),
@ -910,7 +904,7 @@ void LLViewerObjectList::cleanupReferences(LLViewerObject *objectp)
// << objectp->getRegion()->getHost().getPort() << llendl;
//}
removeFromLocalIDTable(*objectp);
removeFromLocalIDTable(objectp);
if (objectp->onActiveList())
{

View File

@ -160,7 +160,7 @@ public:
const U32 ip,
const U32 port); // Requires knowledge of message system info!
static BOOL removeFromLocalIDTable(const LLViewerObject &object);
static BOOL removeFromLocalIDTable(const LLViewerObject* objectp);
// Used ONLY by the orphaned object code.
static U64 getIndex(const U32 local_id, const U32 ip, const U32 port);

View File

@ -322,6 +322,12 @@ LLViewerRegion::~LLViewerRegion()
std::for_each(mObjectPartition.begin(), mObjectPartition.end(), DeletePointer());
}
/*virtual*/
const LLHost& LLViewerRegion::getHost() const
{
return mHost;
}
void LLViewerRegion::loadObjectCache()
{
if (mCacheLoaded)

View File

@ -245,7 +245,7 @@ public:
LLEventPump& getCapAPI() { return mCapabilityListener.getCapAPI(); }
/// implements LLCapabilityProvider
virtual LLHost getHost() const { return mHost; }
/*virtual*/ const LLHost& getHost() const;
const U64 &getHandle() const { return mHandle; }
LLSurface &getLand() const { return *mLandp; }

View File

@ -1214,12 +1214,15 @@ void LLViewerFetchedTexture::cleanup()
void LLViewerFetchedTexture::setForSculpt()
{
static const S32 MAX_INTERVAL = 8 ; //frames
mForSculpt = TRUE ;
if(isForSculptOnly() && !getBoundRecently())
{
destroyGLTexture() ; //sculpt image does not need gl texture.
}
checkCachedRawSculptImage() ;
setMaxVirtualSizeResetInterval(MAX_INTERVAL) ;
}
BOOL LLViewerFetchedTexture::isForSculptOnly() const

View File

@ -296,13 +296,15 @@ private:
line_list_t mLineList;
LLColor4 mTextColor;
public:
LLDebugText(LLViewerWindow* window) : mWindow(window) {}
void addText(S32 x, S32 y, const std::string &text)
{
mLineList.push_back(Line(text, x, y));
}
void clearText() { mLineList.clear(); }
public:
LLDebugText(LLViewerWindow* window) : mWindow(window) {}
void update()
{
@ -323,6 +325,8 @@ public:
U32 ypos = 64;
const U32 y_inc = 20;
clearText();
if (gSavedSettings.getBOOL("DebugShowTime"))
{
const U32 y_inc2 = 15;
@ -601,6 +605,50 @@ public:
ypos += y_inc;
}
}
if (gSavedSettings.getBOOL("DebugShowTextureInfo"))
{
LLViewerObject* objectp = NULL ;
//objectp = = gAgentCamera.getFocusObject();
LLSelectNode* nodep = LLSelectMgr::instance().getHoverNode();
if (nodep)
{
objectp = nodep->getObject();
}
if (objectp && !objectp->isDead())
{
S32 num_faces = objectp->mDrawable->getNumFaces() ;
for(S32 i = 0 ; i < num_faces; i++)
{
LLFace* facep = objectp->mDrawable->getFace(i) ;
if(facep)
{
//addText(xpos, ypos, llformat("ts_min: %.3f ts_max: %.3f tt_min: %.3f tt_max: %.3f", facep->mTexExtents[0].mV[0], facep->mTexExtents[1].mV[0],
// facep->mTexExtents[0].mV[1], facep->mTexExtents[1].mV[1]));
//ypos += y_inc;
addText(xpos, ypos, llformat("v_size: %.3f: p_size: %.3f", facep->getVirtualSize(), facep->getPixelArea()));
ypos += y_inc;
//const LLTextureEntry *tep = facep->getTextureEntry();
//if(tep)
//{
// addText(xpos, ypos, llformat("scale_s: %.3f: scale_t: %.3f", tep->mScaleS, tep->mScaleT)) ;
// ypos += y_inc;
//}
LLViewerTexture* tex = facep->getTexture() ;
if(tex)
{
addText(xpos, ypos, llformat("ID: %s v_size: %.3f", tex->getID().asString().c_str(), tex->getMaxVirtualSize()));
ypos += y_inc;
}
}
}
}
}
}
void draw()

View File

@ -225,8 +225,9 @@ BOOL LLVOCacheEntry::writeToFile(LLAPRFile* apr_file) const
// Format string used to construct filename for the object cache
static const char OBJECT_CACHE_FILENAME[] = "objects_%d_%d.slc";
// Throw out 1/20 (5%) of our cache entries if we run out of room.
const U32 ENTRIES_PURGE_FACTOR = 20;
const U32 MAX_NUM_OBJECT_ENTRIES = 128 ;
const U32 MIN_ENTRIES_TO_PURGE = 16 ;
const U32 INVALID_TIME = 0 ;
const char* object_cache_dirname = "objectcache";
const char* header_filename = "object.cache";
@ -261,6 +262,7 @@ void LLVOCache::destroyClass()
LLVOCache::LLVOCache():
mInitialized(FALSE),
mReadOnly(TRUE),
mNumEntries(0),
mCacheSize(1)
{
mEnabled = gSavedSettings.getBOOL("ObjectCacheEnabled");
@ -298,17 +300,16 @@ void LLVOCache::initCache(ELLPath location, U32 size, U32 cache_version)
llwarns << "Cache already initialized." << llendl;
return ;
}
mInitialized = TRUE ;
setDirNames(location);
if (!mReadOnly)
{
LLFile::mkdir(mObjectCacheDirName);
}
mCacheSize = size;
readCacheHeader();
mInitialized = TRUE ;
mCacheSize = llclamp(size, MIN_ENTRIES_TO_PURGE, MAX_NUM_OBJECT_ENTRIES);
mMetaInfo.mVersion = cache_version;
readCacheHeader();
if(mMetaInfo.mVersion != cache_version)
{
@ -332,6 +333,8 @@ void LLVOCache::removeCache(ELLPath location)
return ;
}
llinfos << "about to remove the object cache due to settings." << llendl ;
std::string delem = gDirUtilp->getDirDelimiter();
std::string mask = delem + "*";
std::string cache_dir = gDirUtilp->getExpandedFilename(location, object_cache_dirname);
@ -352,6 +355,8 @@ void LLVOCache::removeCache()
return ;
}
llinfos << "about to remove the object cache due to some error." << llendl ;
std::string delem = gDirUtilp->getDirDelimiter();
std::string mask = delem + "*";
llinfos << "Removing cache at " << mObjectCacheDirName << llendl;
@ -361,10 +366,54 @@ void LLVOCache::removeCache()
writeCacheHeader();
}
void LLVOCache::removeEntry(HeaderEntryInfo* entry)
{
llassert_always(mInitialized) ;
if(mReadOnly)
{
return ;
}
if(!entry)
{
return ;
}
header_entry_queue_t::iterator iter = mHeaderEntryQueue.find(entry) ;
if(iter != mHeaderEntryQueue.end())
{
mHandleEntryMap.erase(entry->mHandle) ;
mHeaderEntryQueue.erase(iter) ;
removeFromCache(entry) ;
delete entry ;
mNumEntries = mHandleEntryMap.size() ;
}
}
void LLVOCache::removeEntry(U64 handle)
{
handle_entry_map_t::iterator iter = mHandleEntryMap.find(handle) ;
if(iter == mHandleEntryMap.end()) //no cache
{
return ;
}
HeaderEntryInfo* entry = iter->second ;
removeEntry(entry) ;
}
void LLVOCache::clearCacheInMemory()
{
std::for_each(mHandleEntryMap.begin(), mHandleEntryMap.end(), DeletePairedPointer());
mHandleEntryMap.clear();
if(!mHeaderEntryQueue.empty())
{
for(header_entry_queue_t::iterator iter = mHeaderEntryQueue.begin(); iter != mHeaderEntryQueue.end(); ++iter)
{
delete *iter ;
}
mHeaderEntryQueue.clear();
mHandleEntryMap.clear();
mNumEntries = 0 ;
}
}
void LLVOCache::getObjectCacheFilename(U64 handle, std::string& filename)
@ -378,45 +427,19 @@ void LLVOCache::getObjectCacheFilename(U64 handle, std::string& filename)
return ;
}
void LLVOCache::removeFromCache(U64 handle)
void LLVOCache::removeFromCache(HeaderEntryInfo* entry)
{
if(mReadOnly)
{
llwarns << "Not removing cache for handle " << handle << ": Cache is currently in read-only mode." << llendl;
llwarns << "Not removing cache for handle " << entry->mHandle << ": Cache is currently in read-only mode." << llendl;
return ;
}
std::string filename;
getObjectCacheFilename(handle, filename);
LLAPRFile::remove(filename, mLocalAPRFilePoolp);
}
BOOL LLVOCache::checkRead(LLAPRFile* apr_file, void* src, S32 n_bytes, bool remove_cache_on_error)
{
if(!check_read(apr_file, src, n_bytes))
{
if (remove_cache_on_error)
{
removeCache() ;
}
return FALSE ;
}
return TRUE ;
}
BOOL LLVOCache::checkWrite(LLAPRFile* apr_file, void* src, S32 n_bytes, bool remove_cache_on_error)
{
if(!check_write(apr_file, src, n_bytes))
{
if (remove_cache_on_error)
{
removeCache() ;
}
return FALSE ;
}
return TRUE ;
getObjectCacheFilename(entry->mHandle, filename);
LLAPRFile::remove(filename, mLocalAPRFilePoolp);
entry->mTime = INVALID_TIME ;
updateEntry(entry) ; //update the head file.
}
void LLVOCache::readCacheHeader()
@ -430,45 +453,71 @@ void LLVOCache::readCacheHeader()
//clear stale info.
clearCacheInMemory();
bool success = true ;
if (LLAPRFile::isExist(mHeaderFileName, mLocalAPRFilePoolp))
{
LLAPRFile* apr_file = new LLAPRFile(mHeaderFileName, APR_FOPEN_READ|APR_FOPEN_BINARY, mLocalAPRFilePoolp);
LLAPRFile apr_file(mHeaderFileName, APR_READ|APR_BINARY, mLocalAPRFilePoolp);
//read the meta element
bool remove_cache_on_error = false;
if(!checkRead(apr_file, &mMetaInfo, sizeof(HeaderMetaInfo), remove_cache_on_error))
success = check_read(&apr_file, &mMetaInfo, sizeof(HeaderMetaInfo)) ;
if(success)
{
llwarns << "Error reading meta information from cache header." << llendl;
delete apr_file;
return;
}
HeaderEntryInfo* entry ;
for(U32 entry_index = 0; entry_index < mCacheSize; ++entry_index)
{
entry = new HeaderEntryInfo() ;
if(!checkRead(apr_file, entry, sizeof(HeaderEntryInfo), remove_cache_on_error))
HeaderEntryInfo* entry = NULL ;
mNumEntries = 0 ;
U32 num_read = 0 ;
while(num_read++ < MAX_NUM_OBJECT_ENTRIES)
{
llwarns << "Error reading cache header entry. (entry_index=" << entry_index << ")" << llendl;
delete entry ;
break;
if(!entry)
{
entry = new HeaderEntryInfo() ;
}
success = check_read(&apr_file, entry, sizeof(HeaderEntryInfo));
if(!success) //failed
{
llwarns << "Error reading cache header entry. (entry_index=" << mNumEntries << ")" << llendl;
delete entry ;
entry = NULL ;
break ;
}
else if(entry->mTime == INVALID_TIME)
{
continue ; //an empty entry
}
entry->mIndex = mNumEntries++ ;
mHeaderEntryQueue.insert(entry) ;
mHandleEntryMap[entry->mHandle] = entry ;
entry = NULL ;
}
else if(!entry->mTime) //end of the cache.
if(entry)
{
delete entry ;
break;
}
entry->mIndex = entry_index;
mHandleEntryMap[entry->mHandle] = entry;
}
delete apr_file ;
//---------
//debug code
//----------
//std::string name ;
//for(header_entry_queue_t::iterator iter = mHeaderEntryQueue.begin() ; success && iter != mHeaderEntryQueue.end(); ++iter)
//{
// getObjectCacheFilename((*iter)->mHandle, name) ;
// llinfos << name << llendl ;
//}
//-----------
}
else
{
writeCacheHeader() ;
}
if(!success)
{
removeCache() ; //failed to read header, clear the cache
}
return ;
}
void LLVOCache::writeCacheHeader()
@ -485,60 +534,50 @@ void LLVOCache::writeCacheHeader()
return;
}
LLAPRFile* apr_file = new LLAPRFile(mHeaderFileName, APR_FOPEN_CREATE|APR_FOPEN_WRITE|APR_FOPEN_BINARY|APR_FOPEN_TRUNCATE, mLocalAPRFilePoolp);
//write the meta element
if(!checkWrite(apr_file, &mMetaInfo, sizeof(HeaderMetaInfo)))
bool success = true ;
{
llwarns << "Error writing meta information to cache header." << llendl;
delete apr_file;
return;
}
LLAPRFile apr_file(mHeaderFileName, APR_CREATE|APR_WRITE|APR_BINARY, mLocalAPRFilePoolp);
U32 entry_index = 0;
handle_entry_map_t::iterator iter_end = mHandleEntryMap.end();
for(handle_entry_map_t::iterator iter = mHandleEntryMap.begin();
iter != iter_end;
++iter)
{
HeaderEntryInfo* entry = iter->second;
entry->mIndex = entry_index++;
if(!checkWrite(apr_file, (void*)entry, sizeof(HeaderEntryInfo)))
//write the meta element
success = check_write(&apr_file, &mMetaInfo, sizeof(HeaderMetaInfo)) ;
mNumEntries = 0 ;
for(header_entry_queue_t::iterator iter = mHeaderEntryQueue.begin() ; success && iter != mHeaderEntryQueue.end(); ++iter)
{
llwarns << "Failed to write cache header for entry " << entry->mHandle << " (entry_index = " << entry_index << ")" << llendl;
delete apr_file;
return;
(*iter)->mIndex = mNumEntries++ ;
success = check_write(&apr_file, (void*)*iter, sizeof(HeaderEntryInfo));
}
}
// Why do we need to fill the cache header with default entries? DK 2010-12-14
// It looks like we currently rely on the file being pre-allocated so we can seek during updateEntry().
if(entry_index < mCacheSize)
{
HeaderEntryInfo* entry = new HeaderEntryInfo() ;
for(; entry_index < mCacheSize; ++entry_index)
mNumEntries = mHeaderEntryQueue.size() ;
if(success && mNumEntries < MAX_NUM_OBJECT_ENTRIES)
{
//fill the cache with the default entry.
if(!checkWrite(apr_file, entry, sizeof(HeaderEntryInfo)))
HeaderEntryInfo* entry = new HeaderEntryInfo() ;
entry->mTime = INVALID_TIME ;
for(S32 i = mNumEntries ; success && i < MAX_NUM_OBJECT_ENTRIES ; i++)
{
llwarns << "Failed to fill cache header with default entries (entry_index = " << entry_index << "). Switching to read-only mode." << llendl;
mReadOnly = TRUE ; //disable the cache.
break;
//fill the cache with the default entry.
success = check_write(&apr_file, entry, sizeof(HeaderEntryInfo)) ;
}
delete entry ;
}
delete entry ;
}
delete apr_file ;
if(!success)
{
clearCacheInMemory() ;
mReadOnly = TRUE ; //disable the cache.
}
return ;
}
BOOL LLVOCache::updateEntry(const HeaderEntryInfo* entry)
{
LLAPRFile* apr_file = new LLAPRFile(mHeaderFileName, APR_FOPEN_WRITE|APR_FOPEN_BINARY, mLocalAPRFilePoolp);
apr_file->seek(APR_SET, entry->mIndex * sizeof(HeaderEntryInfo) + sizeof(HeaderMetaInfo)) ;
LLAPRFile apr_file(mHeaderFileName, APR_WRITE|APR_BINARY, mLocalAPRFilePoolp);
apr_file.seek(APR_SET, entry->mIndex * sizeof(HeaderEntryInfo) + sizeof(HeaderMetaInfo)) ;
BOOL result = checkWrite(apr_file, (void*)entry, sizeof(HeaderEntryInfo)) ;
delete apr_file;
return result;
return check_write(&apr_file, (void*)entry, sizeof(HeaderEntryInfo)) ;
}
void LLVOCache::readFromCache(U64 handle, const LLUUID& id, LLVOCacheEntry::vocache_entry_map_t& cache_entry_map)
@ -557,76 +596,66 @@ void LLVOCache::readFromCache(U64 handle, const LLUUID& id, LLVOCacheEntry::voca
return ;
}
std::string filename;
getObjectCacheFilename(handle, filename);
LLAPRFile* apr_file = new LLAPRFile(filename, APR_FOPEN_READ|APR_FOPEN_BINARY, mLocalAPRFilePoolp);
bool success = true ;
{
std::string filename;
getObjectCacheFilename(handle, filename);
LLAPRFile apr_file(filename, APR_READ|APR_BINARY, mLocalAPRFilePoolp);
LLUUID cache_id ;
success = check_read(&apr_file, cache_id.mData, UUID_BYTES) ;
if(success)
{
if(cache_id != id)
{
llinfos << "Cache ID doesn't match for this region, discarding"<< llendl;
success = false ;
}
LLUUID cache_id ;
if(!checkRead(apr_file, cache_id.mData, UUID_BYTES))
{
llwarns << "Error reading cache_id from " << filename << llendl;
delete apr_file;
return ;
}
if(cache_id != id)
{
llwarns << "Cache ID (" << cache_id << ") doesn't match id for this region (" << id << "), discarding. handle = " << handle << llendl;
delete apr_file ;
return ;
}
S32 num_entries;
if(!checkRead(apr_file, &num_entries, sizeof(S32)))
{
llwarns << "Error reading num_entries from " << filename << llendl;
delete apr_file;
return ;
if(success)
{
S32 num_entries;
success = check_read(&apr_file, &num_entries, sizeof(S32)) ;
for (S32 i = 0; success && i < num_entries; i++)
{
LLVOCacheEntry* entry = new LLVOCacheEntry(&apr_file);
if (!entry->getLocalID())
{
llwarns << "Aborting cache file load for " << filename << ", cache file corruption!" << llendl;
delete entry ;
success = false ;
}
cache_entry_map[entry->getLocalID()] = entry;
}
}
}
}
for (S32 i = 0; i < num_entries; i++)
if(!success)
{
LLVOCacheEntry* entry = new LLVOCacheEntry(apr_file);
if (!entry->getLocalID())
if(cache_entry_map.empty())
{
llwarns << "Aborting cache file load for " << filename << ", cache file corruption! (entry number = " << i << ")" << llendl;
delete entry ;
break;
removeEntry(iter->second) ;
}
cache_entry_map[entry->getLocalID()] = entry;
}
delete apr_file ;
return ;
}
void LLVOCache::purgeEntries()
{
U32 limit = mCacheSize - (mCacheSize / ENTRIES_PURGE_FACTOR);
limit = llclamp(limit, (U32)1, mCacheSize);
// Construct a vector of entries out of the map so we can sort by time.
std::vector<HeaderEntryInfo*> header_vector;
handle_entry_map_t::iterator iter_end = mHandleEntryMap.end();
for (handle_entry_map_t::iterator iter = mHandleEntryMap.begin();
iter != iter_end;
++iter)
while(mHeaderEntryQueue.size() >= mCacheSize)
{
header_vector.push_back(iter->second);
}
// Sort by time, oldest first.
std::sort(header_vector.begin(), header_vector.end(), header_entry_less());
while(header_vector.size() > limit)
{
HeaderEntryInfo* entry = header_vector.front();
removeFromCache(entry->mHandle);
header_entry_queue_t::iterator iter = mHeaderEntryQueue.begin() ;
HeaderEntryInfo* entry = *iter ;
mHandleEntryMap.erase(entry->mHandle);
header_vector.erase(header_vector.begin());
mHeaderEntryQueue.erase(iter) ;
removeFromCache(entry) ;
delete entry;
}
writeCacheHeader() ;
// *TODO: Verify that we can avoid re-reading the cache header. DK 2010-12-14
readCacheHeader() ;
mNumEntries = mHandleEntryMap.size() ;
}
void LLVOCache::writeToCache(U64 handle, const LLUUID& id, const LLVOCacheEntry::vocache_entry_map_t& cache_entry_map, BOOL dirty_cache)
@ -643,30 +672,32 @@ void LLVOCache::writeToCache(U64 handle, const LLUUID& id, const LLVOCacheEntry:
llwarns << "Not writing cache for handle " << handle << "): Cache is currently in read-only mode." << llendl;
return ;
}
if(mNumEntries >= mCacheSize)
{
purgeEntries() ;
}
U32 num_handle_entries = mHandleEntryMap.size();
HeaderEntryInfo* entry;
handle_entry_map_t::iterator iter = mHandleEntryMap.find(handle) ;
if(iter == mHandleEntryMap.end()) //new entry
{
if(num_handle_entries >= mCacheSize)
{
purgeEntries() ;
num_handle_entries = mHandleEntryMap.size();
}
{
entry = new HeaderEntryInfo();
entry->mHandle = handle ;
entry->mTime = time(NULL) ;
entry->mIndex = num_handle_entries++;
entry->mIndex = mNumEntries++;
mHeaderEntryQueue.insert(entry) ;
mHandleEntryMap[handle] = entry ;
}
else
{
// Update access time.
entry = iter->second ;
entry = iter->second ;
//resort
mHeaderEntryQueue.erase(entry) ;
entry->mTime = time(NULL) ;
mHeaderEntryQueue.insert(entry) ;
}
//update cache header
@ -683,37 +714,33 @@ void LLVOCache::writeToCache(U64 handle, const LLUUID& id, const LLVOCacheEntry:
}
//write to cache file
std::string filename;
getObjectCacheFilename(handle, filename);
LLAPRFile* apr_file = new LLAPRFile(filename, APR_FOPEN_CREATE|APR_FOPEN_WRITE|APR_FOPEN_BINARY|APR_FOPEN_TRUNCATE, mLocalAPRFilePoolp);
bool success = true ;
{
std::string filename;
getObjectCacheFilename(handle, filename);
LLAPRFile apr_file(filename, APR_CREATE|APR_WRITE|APR_BINARY, mLocalAPRFilePoolp);
if(!checkWrite(apr_file, (void*)id.mData, UUID_BYTES))
{
llwarns << "Error writing id to " << filename << llendl;
delete apr_file;
return ;
}
success = check_write(&apr_file, (void*)id.mData, UUID_BYTES) ;
S32 num_entries = cache_entry_map.size() ;
if(!checkWrite(apr_file, &num_entries, sizeof(S32)))
{
llwarns << "Error writing num_entries to " << filename << llendl;
delete apr_file;
return ;
}
for (LLVOCacheEntry::vocache_entry_map_t::const_iterator iter = cache_entry_map.begin(); iter != cache_entry_map.end(); ++iter)
{
if(!iter->second->writeToFile(apr_file))
if(success)
{
llwarns << "Aborting cache file write for " << filename << ", error writing to file!" << llendl;
//failed
removeCache() ;
break;
S32 num_entries = cache_entry_map.size() ;
success = check_write(&apr_file, &num_entries, sizeof(S32));
for (LLVOCacheEntry::vocache_entry_map_t::const_iterator iter = cache_entry_map.begin(); success && iter != cache_entry_map.end(); ++iter)
{
success = iter->second->writeToFile(&apr_file) ;
}
}
}
delete apr_file ;
if(!success)
{
removeEntry(entry) ;
}
return ;
}

View File

@ -95,13 +95,15 @@ private:
{
bool operator()(const HeaderEntryInfo* lhs, const HeaderEntryInfo* rhs) const
{
if (lhs->mTime == rhs->mTime)
if(lhs->mTime == rhs->mTime)
{
return lhs->mHandle < rhs->mHandle;
return lhs < rhs ;
}
return lhs->mTime < rhs->mTime; // older entry in front
return lhs->mTime < rhs->mTime ; // older entry in front of queue (set)
}
};
typedef std::set<HeaderEntryInfo*, header_entry_less> header_entry_queue_t;
typedef std::map<U64, HeaderEntryInfo*> handle_entry_map_t;
private:
LLVOCache() ;
@ -114,6 +116,7 @@ public:
void readFromCache(U64 handle, const LLUUID& id, LLVOCacheEntry::vocache_entry_map_t& cache_entry_map) ;
void writeToCache(U64 handle, const LLUUID& id, const LLVOCacheEntry::vocache_entry_map_t& cache_entry_map, BOOL dirty_cache) ;
void removeEntry(U64 handle) ;
void setReadOnly(BOOL read_only) {mReadOnly = read_only;}
@ -121,15 +124,14 @@ private:
void setDirNames(ELLPath location);
// determine the cache filename for the region from the region handle
void getObjectCacheFilename(U64 handle, std::string& filename);
void removeFromCache(U64 handle);
void removeFromCache(HeaderEntryInfo* entry);
void readCacheHeader();
void writeCacheHeader();
void clearCacheInMemory();
void removeCache() ;
void removeEntry(HeaderEntryInfo* entry) ;
void purgeEntries();
BOOL updateEntry(const HeaderEntryInfo* entry);
BOOL checkRead(LLAPRFile* apr_file, void* src, S32 n_bytes, bool remove_cache_on_error = true) ;
BOOL checkWrite(LLAPRFile* apr_file, void* src, S32 n_bytes, bool remove_cache_on_error = true) ;
private:
BOOL mEnabled;
@ -137,9 +139,11 @@ private:
BOOL mReadOnly ;
HeaderMetaInfo mMetaInfo;
U32 mCacheSize;
U32 mNumEntries;
std::string mHeaderFileName ;
std::string mObjectCacheDirName;
LLVolatileAPRPool* mLocalAPRFilePoolp ;
header_entry_queue_t mHeaderEntryQueue;
handle_entry_map_t mHandleEntryMap;
static LLVOCache* sInstance ;

View File

@ -388,10 +388,12 @@ U32 LLVOVolume::processUpdateMessage(LLMessageSystem *mesgsys,
// There's something bogus in the data that we're unpacking.
dp->dumpBufferToLog();
llwarns << "Flushing cache files" << llendl;
std::string mask;
mask = gDirUtilp->getDirDelimiter() + "*.slc";
gDirUtilp->deleteFilesInDir(gDirUtilp->getExpandedFilename(LL_PATH_CACHE,""), mask);
// llerrs << "Bogus TE data in " << getID() << ", crashing!" << llendl;
if(LLVOCache::hasInstance() && getRegion())
{
LLVOCache::getInstance()->removeEntry(getRegion()->getHandle()) ;
}
llwarns << "Bogus TE data in " << getID() << llendl;
}
else
@ -667,11 +669,32 @@ void LLVOVolume::updateTextures()
}
}
BOOL LLVOVolume::isVisible() const
{
if(mDrawable.notNull() && mDrawable->isVisible())
{
return TRUE ;
}
if(isAttachment())
{
LLViewerObject* objp = (LLViewerObject*)getParent() ;
while(objp && !objp->isAvatar())
{
objp = (LLViewerObject*)objp->getParent() ;
}
return objp && objp->mDrawable.notNull() && objp->mDrawable->isVisible() ;
}
return FALSE ;
}
void LLVOVolume::updateTextureVirtualSize()
{
// Update the pixel area of all faces
if(mDrawable.isNull() || !mDrawable->isVisible())
if(!isVisible())
{
return ;
}
@ -2738,14 +2761,7 @@ void LLVOVolume::updateRadius()
BOOL LLVOVolume::isAttachment() const
{
if (mState == 0)
{
return FALSE;
}
else
{
return TRUE;
}
return mState != 0 ;
}
BOOL LLVOVolume::isHUDAttachment() const

View File

@ -102,6 +102,7 @@ public:
void animateTextures();
/*virtual*/ BOOL idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time);
BOOL isVisible() const ;
/*virtual*/ BOOL isActive() const;
/*virtual*/ BOOL isAttachment() const;
/*virtual*/ BOOL isRootEdit() const; // overridden for sake of attachments treating themselves as a root object

View File

@ -1967,12 +1967,12 @@ void LLPipeline::markVisible(LLDrawable *drawablep, LLCamera& camera)
if(drawablep && !drawablep->isDead())
{
if (drawablep->isSpatialBridge())
{
if (drawablep->isSpatialBridge())
{
const LLDrawable* root = ((LLSpatialBridge*) drawablep)->mDrawable;
llassert(root); // trying to catch a bad assumption
if (root && // // this test may not be needed, see above
root->getVObj()->isAttachment())
root->getVObj()->isAttachment())
{
LLDrawable* rootparent = root->getParent();
if (rootparent) // this IS sometimes NULL
@ -1980,24 +1980,24 @@ void LLPipeline::markVisible(LLDrawable *drawablep, LLCamera& camera)
LLViewerObject *vobj = rootparent->getVObj();
llassert(vobj); // trying to catch a bad assumption
if (vobj) // this test may not be needed, see above
{
{
const LLVOAvatar* av = vobj->asAvatar();
if (av && av->isImpostor())
{
return;
}
}
if (av && av->isImpostor())
{
return;
}
}
}
}
sCull->pushBridge((LLSpatialBridge*) drawablep);
}
else
{
sCull->pushDrawable(drawablep);
}
sCull->pushBridge((LLSpatialBridge*) drawablep);
}
else
{
sCull->pushDrawable(drawablep);
}
drawablep->setVisible(camera);
}
drawablep->setVisible(camera);
}
}
void LLPipeline::markMoved(LLDrawable *drawablep, BOOL damped_motion)

View File

@ -1959,6 +1959,16 @@
<menu_item_check.on_click
function="ToggleControl"
parameter="DebugShowRenderInfo" />
</menu_item_check>
<menu_item_check
label="Show Texture Info"
name="Show Texture Info">
<menu_item_check.on_check
function="CheckControl"
parameter="DebugShowTextureInfo" />
<menu_item_check.on_click
function="ToggleControl"
parameter="DebugShowTextureInfo" />
</menu_item_check>
<menu_item_check
label="Show Matrices"