From c0ba626c8009b22310b3923e8170e5db2a021253 Mon Sep 17 00:00:00 2001 From: Xiaohong Bao Date: Mon, 15 Oct 2012 21:34:29 -0600 Subject: For SH-3333: Design and implement a new object cache system on viewer side --- indra/newview/llviewerobjectlist.cpp | 145 +++++++++++++++++++++++++++++++---- 1 file changed, 131 insertions(+), 14 deletions(-) (limited to 'indra/newview/llviewerobjectlist.cpp') diff --git a/indra/newview/llviewerobjectlist.cpp b/indra/newview/llviewerobjectlist.cpp index 88bb087742..a1db1f7237 100644 --- a/indra/newview/llviewerobjectlist.cpp +++ b/indra/newview/llviewerobjectlist.cpp @@ -76,6 +76,7 @@ #include "object_flags.h" #include "llappviewer.h" +#include "llvocache.h" extern F32 gMinObjectDistance; extern BOOL gAnimateTextures; @@ -228,9 +229,15 @@ void LLViewerObjectList::processUpdateCore(LLViewerObject* objectp, U32 i, const EObjectUpdateType update_type, LLDataPacker* dpp, - BOOL just_created) + bool just_created, + bool from_cache) { - LLMessageSystem* msg = gMessageSystem; + LLMessageSystem* msg = NULL; + + if(!from_cache) + { + msg = gMessageSystem; + } // ignore returned flags objectp->processUpdateMessage(msg, user_data, i, update_type, dpp); @@ -254,7 +261,18 @@ void LLViewerObjectList::processUpdateCore(LLViewerObject* objectp, // RN: this must be called after we have a drawable // (from gPipeline.addObject) // so that the drawable parent is set properly - findOrphans(objectp, msg->getSenderIP(), msg->getSenderPort()); + if(msg != NULL) + { + findOrphans(objectp, msg->getSenderIP(), msg->getSenderPort()); + } + else + { + LLViewerRegion* regionp = objectp->getRegion(); + if(regionp != NULL) + { + findOrphans(objectp, regionp->getHost().getAddress(), regionp->getHost().getPort()); + } + } // If we're just wandering around, don't create new objects selected. if (just_created @@ -277,6 +295,82 @@ void LLViewerObjectList::processUpdateCore(LLViewerObject* objectp, static LLFastTimer::DeclareTimer FTM_PROCESS_OBJECTS("Process Objects"); +LLViewerObject* LLViewerObjectList::processObjectUpdateFromCache(LLVOCacheEntry* entry, LLViewerRegion* regionp) +{ + LLDataPacker *cached_dpp = entry->getDP(); + + if (!cached_dpp) + { + return NULL; //nothing cached. + } + + LLViewerObject *objectp; + U32 local_id; + LLPCode pcode = 0; + LLUUID fullid; + LLViewerStatsRecorder& recorder = LLViewerStatsRecorder::instance(); + + // Cache Hit. + cached_dpp->reset(); + cached_dpp->unpackUUID(fullid, "ID"); + cached_dpp->unpackU32(local_id, "LocalID"); + cached_dpp->unpackU8(pcode, "PCode"); + + objectp = findObject(fullid); + + if (objectp) + { + if(!objectp->isDead() && (objectp->mLocalID != entry->getLocalID() || + objectp->getRegion() != regionp)) + { + removeFromLocalIDTable(objectp); + setUUIDAndLocal(fullid, entry->getLocalID(), + regionp->getHost().getAddress(), + regionp->getHost().getPort()); + + if (objectp->mLocalID != entry->getLocalID()) + { // Update local ID in object with the one sent from the region + objectp->mLocalID = entry->getLocalID(); + } + + if (objectp->getRegion() != regionp) + { // Object changed region, so update it + objectp->updateRegion(regionp); // for LLVOAvatar + } + } + + //return TRUE; //already loaded. + } + + bool justCreated = false; + if (!objectp) + { + objectp = createObjectFromCache(pcode, regionp, fullid, entry->getLocalID()); + + if (!objectp) + { + llinfos << "createObject failure for object: " << fullid << llendl; + recorder.objectUpdateFailure(entry->getLocalID(), OUT_FULL_CACHED, 0); + return NULL; + } + justCreated = true; + mNumNewObjects++; + sCacheHitRate.addValue(100.f); + } + + if (objectp->isDead()) + { + llwarns << "Dead object " << objectp->mID << " in UUID map 1!" << llendl; + } + + processUpdateCore(objectp, NULL, 0, OUT_FULL_CACHED, cached_dpp, justCreated, true); + + recorder.log(0.2f); + LLVOAvatar::cullAvatarsByPixelArea(); + + return objectp; +} + void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys, void **user_data, const EObjectUpdateType update_type, @@ -382,14 +476,8 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys, } else if (compressed) { - S32 uncompressed_length = 2048; - compressed_dp.reset(); - - U32 flags = 0; - if (update_type != OUT_TERSE_IMPROVED) // OUT_FULL_COMPRESSED only? - { - mesgsys->getU32Fast(_PREHASH_ObjectData, _PREHASH_UpdateFlags, flags, i); - } + S32 uncompressed_length = 2048; + compressed_dp.reset(); uncompressed_length = mesgsys->getSizeFast(_PREHASH_ObjectData, i, _PREHASH_Data); mesgsys->getBinaryDataFast(_PREHASH_ObjectData, _PREHASH_Data, compressed_dpbuffer, 0, i); @@ -540,9 +628,15 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys, processUpdateCore(objectp, user_data, i, update_type, &compressed_dp, justCreated); if (update_type != OUT_TERSE_IMPROVED) // OUT_FULL_COMPRESSED only? { - bCached = true; - LLViewerRegion::eCacheUpdateResult result = objectp->mRegionp->cacheFullUpdate(objectp, compressed_dp); - recorder.cacheFullUpdate(local_id, update_type, result, objectp, msg_size); + U32 flags = 0; + mesgsys->getU32Fast(_PREHASH_ObjectData, _PREHASH_UpdateFlags, flags, i); + + if(!(flags & FLAGS_TEMPORARY_ON_REZ)) + { + bCached = true; + LLViewerRegion::eCacheUpdateResult result = objectp->mRegionp->cacheFullUpdate(objectp, compressed_dp); + recorder.cacheFullUpdate(local_id, update_type, result, objectp, msg_size); + } } } else if (cached) // Cache hit only? @@ -1887,7 +1981,30 @@ LLViewerObject *LLViewerObjectList::createObjectViewer(const LLPCode pcode, LLVi return objectp; } +LLViewerObject *LLViewerObjectList::createObjectFromCache(const LLPCode pcode, LLViewerRegion *regionp, const LLUUID &uuid, const U32 local_id) +{ + llassert_always(uuid.notNull()); + LLViewerObject *objectp = LLViewerObject::createObject(uuid, pcode, regionp); + if (!objectp) + { +// llwarns << "Couldn't create object of type " << LLPrimitive::pCodeToString(pcode) << " id:" << fullid << llendl; + return NULL; + } + + objectp->mLocalID = local_id; + mUUIDObjectMap[uuid] = objectp; + setUUIDAndLocal(uuid, + local_id, + regionp->getHost().getAddress(), + regionp->getHost().getPort()); + mObjects.push_back(objectp); + + updateActive(objectp); + + return objectp; +} + LLViewerObject *LLViewerObjectList::createObject(const LLPCode pcode, LLViewerRegion *regionp, const LLUUID &uuid, const U32 local_id, const LLHost &sender) { -- cgit v1.2.3 From 09591242f90fa9b24a0be2aad02e91041ac0fcc7 Mon Sep 17 00:00:00 2001 From: Xiaohong Bao Date: Thu, 25 Oct 2012 18:20:36 -0600 Subject: avoid redundant object creation. --- indra/newview/llviewerobjectlist.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'indra/newview/llviewerobjectlist.cpp') diff --git a/indra/newview/llviewerobjectlist.cpp b/indra/newview/llviewerobjectlist.cpp index a1db1f7237..d41eee5926 100644 --- a/indra/newview/llviewerobjectlist.cpp +++ b/indra/newview/llviewerobjectlist.cpp @@ -338,8 +338,10 @@ LLViewerObject* LLViewerObjectList::processObjectUpdateFromCache(LLVOCacheEntry* objectp->updateRegion(regionp); // for LLVOAvatar } } - - //return TRUE; //already loaded. + else + { + return objectp; //already loaded. + } } bool justCreated = false; -- cgit v1.2.3 From c2859e4663c405950b6f433270ae558852330c76 Mon Sep 17 00:00:00 2001 From: Xiaohong Bao Date: Thu, 8 Nov 2012 21:36:47 -0700 Subject: for SH-3472: prioritize object loading --- indra/newview/llviewerobjectlist.cpp | 85 ++++++++++++++++++------------------ 1 file changed, 43 insertions(+), 42 deletions(-) (limited to 'indra/newview/llviewerobjectlist.cpp') diff --git a/indra/newview/llviewerobjectlist.cpp b/indra/newview/llviewerobjectlist.cpp index d41eee5926..f3552e2c2b 100644 --- a/indra/newview/llviewerobjectlist.cpp +++ b/indra/newview/llviewerobjectlist.cpp @@ -376,7 +376,7 @@ LLViewerObject* LLViewerObjectList::processObjectUpdateFromCache(LLVOCacheEntry* void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys, void **user_data, const EObjectUpdateType update_type, - bool cached, bool compressed) + bool compressed) { LLFastTimer t(FTM_PROCESS_OBJECTS); @@ -395,7 +395,7 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys, num_objects = mesgsys->getNumberOfBlocksFast(_PREHASH_ObjectData); // I don't think this case is ever hit. TODO* Test this. - if (!cached && !compressed && update_type != OUT_FULL) + if (!compressed && update_type != OUT_FULL) { //llinfos << "TEST: !cached && !compressed && update_type != OUT_FULL" << llendl; gTerseObjectUpdates += num_objects; @@ -439,7 +439,6 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys, U8 compressed_dpbuffer[2048]; LLDataPackerBinaryBuffer compressed_dp(compressed_dpbuffer, 2048); - LLDataPacker *cached_dpp = NULL; LLViewerStatsRecorder& recorder = LLViewerStatsRecorder::instance(); for (i = 0; i < num_objects; i++) @@ -449,34 +448,7 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys, BOOL justCreated = FALSE; S32 msg_size = 0; - if (cached) - { - U32 id; - U32 crc; - mesgsys->getU32Fast(_PREHASH_ObjectData, _PREHASH_ID, id, i); - mesgsys->getU32Fast(_PREHASH_ObjectData, _PREHASH_CRC, crc, i); - msg_size += sizeof(U32) * 2; - - // Lookup data packer and add this id to cache miss lists if necessary. - U8 cache_miss_type = LLViewerRegion::CACHE_MISS_TYPE_NONE; - cached_dpp = regionp->getDP(id, crc, cache_miss_type); - if (cached_dpp) - { - // Cache Hit. - cached_dpp->reset(); - cached_dpp->unpackUUID(fullid, "ID"); - cached_dpp->unpackU32(local_id, "LocalID"); - cached_dpp->unpackU8(pcode, "PCode"); - } - else - { - // Cache Miss. - recorder.cacheMissEvent(id, update_type, cache_miss_type, msg_size); - - continue; // no data packer, skip this object - } - } - else if (compressed) + if (compressed) { S32 uncompressed_length = 2048; compressed_dp.reset(); @@ -575,9 +547,6 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys, continue; } } - else if (cached) // Cache hit only? - { - } else { if (update_type != OUT_FULL) @@ -610,7 +579,7 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys, } justCreated = TRUE; mNumNewObjects++; - sCacheHitRate.addValue(cached ? 100.f : 0.f); + sCacheHitRate.addValue(0.f); } @@ -641,11 +610,6 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys, } } } - else if (cached) // Cache hit only? - { - objectp->mLocalID = local_id; - processUpdateCore(objectp, user_data, i, update_type, cached_dpp, justCreated); - } else { if (update_type == OUT_FULL) @@ -668,14 +632,51 @@ void LLViewerObjectList::processCompressedObjectUpdate(LLMessageSystem *mesgsys, void **user_data, const EObjectUpdateType update_type) { - processObjectUpdate(mesgsys, user_data, update_type, false, true); + processObjectUpdate(mesgsys, user_data, update_type, true); } void LLViewerObjectList::processCachedObjectUpdate(LLMessageSystem *mesgsys, void **user_data, const EObjectUpdateType update_type) { - processObjectUpdate(mesgsys, user_data, update_type, true, false); + //processObjectUpdate(mesgsys, user_data, update_type, true, false); + + S32 num_objects = mesgsys->getNumberOfBlocksFast(_PREHASH_ObjectData); + gFullObjectUpdates += num_objects; + + U64 region_handle; + mesgsys->getU64Fast(_PREHASH_RegionData, _PREHASH_RegionHandle, region_handle); + LLViewerRegion *regionp = LLWorld::getInstance()->getRegionFromHandle(region_handle); + if (!regionp) + { + llwarns << "Object update from unknown region! " << region_handle << llendl; + return; + } + + LLViewerStatsRecorder& recorder = LLViewerStatsRecorder::instance(); + + for (S32 i = 0; i < num_objects; i++) + { + S32 msg_size = 0; + U32 id; + U32 crc; + mesgsys->getU32Fast(_PREHASH_ObjectData, _PREHASH_ID, id, i); + mesgsys->getU32Fast(_PREHASH_ObjectData, _PREHASH_CRC, crc, i); + msg_size += sizeof(U32) * 2; + + // Lookup data packer and add this id to cache miss lists if necessary. + U8 cache_miss_type = LLViewerRegion::CACHE_MISS_TYPE_NONE; + if(!regionp->probeCache(id, crc, cache_miss_type)) + { + // Cache Miss. + recorder.cacheMissEvent(id, update_type, cache_miss_type, msg_size); + + continue; // no data packer, skip this object + } + sCacheHitRate.addValue(100.f); + } + + return; } void LLViewerObjectList::dirtyAllObjectInventory() -- cgit v1.2.3 From 834a956a70bb49f1a242681bd611df4bbb7e4cc8 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Thu, 13 Dec 2012 15:43:10 -0800 Subject: We now handle local_id=0 in KillObject as a prefix to deleted local_id's. This is the real viewer-side work that was the motivation for MAINT-2123. Reviewed with Bao. --- indra/newview/llviewerobjectlist.cpp | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) (limited to 'indra/newview/llviewerobjectlist.cpp') diff --git a/indra/newview/llviewerobjectlist.cpp b/indra/newview/llviewerobjectlist.cpp index f3552e2c2b..5b2214f3b3 100644 --- a/indra/newview/llviewerobjectlist.cpp +++ b/indra/newview/llviewerobjectlist.cpp @@ -107,7 +107,6 @@ LLViewerObjectList::LLViewerObjectList() mNumNewObjects = 0; mWasPaused = FALSE; mNumDeadObjectUpdates = 0; - mNumUnknownKills = 0; mNumUnknownUpdates = 0; } @@ -1342,16 +1341,7 @@ BOOL LLViewerObjectList::killObject(LLViewerObject *objectp) if (objectp) { - if (objectp->isDead()) - { - // This object is already dead. Don't need to do more. - return TRUE; - } - else - { - objectp->markDead(); - } - + objectp->markDead(); // does the right thing if object already dead return TRUE; } -- cgit v1.2.3 From 4e22f3e3ef15e24d7e9e0ad156e60d4cd1b2d5c9 Mon Sep 17 00:00:00 2001 From: Xiaohong Bao Date: Tue, 18 Dec 2012 23:16:50 -0700 Subject: fix for SH-3624: Object deletion does not work --- indra/newview/llviewerobjectlist.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'indra/newview/llviewerobjectlist.cpp') diff --git a/indra/newview/llviewerobjectlist.cpp b/indra/newview/llviewerobjectlist.cpp index 5b2214f3b3..6e7ce103b5 100644 --- a/indra/newview/llviewerobjectlist.cpp +++ b/indra/newview/llviewerobjectlist.cpp @@ -1326,7 +1326,7 @@ void LLViewerObjectList::removeDrawable(LLDrawable* drawablep) } } -BOOL LLViewerObjectList::killObject(LLViewerObject *objectp) +BOOL LLViewerObjectList::killObject(LLViewerObject *objectp, bool cache_enabled) { // Don't ever kill gAgentAvatarp, just force it to the agent's region // unless region is NULL which is assumed to mean you are logging out. @@ -1341,6 +1341,7 @@ BOOL LLViewerObjectList::killObject(LLViewerObject *objectp) if (objectp) { + objectp->EnableToCacheTree(cache_enabled); //enable to add to VO cache tree if set. objectp->markDead(); // does the right thing if object already dead return TRUE; } -- cgit v1.2.3 From 7cc37d949e9319a5b60641ff8453a0fed763d817 Mon Sep 17 00:00:00 2001 From: Xiaohong Bao Date: Wed, 9 Jan 2013 22:43:10 -0700 Subject: fix the merge errors from the changeset 3eadda9666cf --- indra/newview/llviewerobjectlist.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'indra/newview/llviewerobjectlist.cpp') diff --git a/indra/newview/llviewerobjectlist.cpp b/indra/newview/llviewerobjectlist.cpp index 0543d11644..0335cd769b 100644 --- a/indra/newview/llviewerobjectlist.cpp +++ b/indra/newview/llviewerobjectlist.cpp @@ -356,7 +356,7 @@ LLViewerObject* LLViewerObjectList::processObjectUpdateFromCache(LLVOCacheEntry* } justCreated = true; mNumNewObjects++; - sCacheHitRate.addValue(100.f); + sCacheHitRate.sample(100.f); } if (objectp->isDead()) @@ -578,8 +578,6 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys, } justCreated = TRUE; mNumNewObjects++; - sCacheHitRate.sample(cached ? 100.f : 0.f); - } @@ -672,7 +670,7 @@ void LLViewerObjectList::processCachedObjectUpdate(LLMessageSystem *mesgsys, continue; // no data packer, skip this object } - sCacheHitRate.addValue(100.f); + sCacheHitRate.sample(100.f); } return; -- cgit v1.2.3