summaryrefslogtreecommitdiff
path: root/indra/newview/llvocache.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'indra/newview/llvocache.cpp')
-rw-r--r--indra/newview/llvocache.cpp236
1 files changed, 229 insertions, 7 deletions
diff --git a/indra/newview/llvocache.cpp b/indra/newview/llvocache.cpp
index 55fc663496..0fbcf9c624 100644
--- a/indra/newview/llvocache.cpp
+++ b/indra/newview/llvocache.cpp
@@ -26,15 +26,13 @@
#include "llviewerprecompiledheaders.h"
#include "llvocache.h"
-#include "llerror.h"
#include "llregionhandle.h"
#include "llviewercontrol.h"
#include "llviewerobjectlist.h"
#include "lldrawable.h"
#include "llviewerregion.h"
-#include "pipeline.h"
#include "llagentcamera.h"
-#include "llmemory.h"
+#include "llsdserialize.h"
//static variables
U32 LLVOCacheEntry::sMinFrameRange = 0;
@@ -57,6 +55,77 @@ BOOL check_write(LLAPRFile* apr_file, void* src, S32 n_bytes)
return apr_file->write(src, n_bytes) == n_bytes ;
}
+bool LLGLTFOverrideCacheEntry::fromLLSD(const LLSD& data)
+{
+ if (!data.has("object_id"))
+ {
+ mObjectId.setNull();
+ return false;
+ }
+
+ if (data.has("region_handle_x") && data.has("region_handle_y"))
+ {
+ // TODO start requiring this once server sends this for all messages
+ U32 region_handle_y = data["region_handle_y"].asInteger();
+ U32 region_handle_x = data["region_handle_x"].asInteger();
+ mRegionHandle = to_region_handle(region_handle_x, region_handle_y);
+ mHasRegionHandle = true;
+ }
+ else
+ {
+ mHasRegionHandle = false;
+ }
+
+ mObjectId = data["object_id"];
+
+ // message should be interpreted thusly:
+ /// sides is a list of face indices
+ // gltf_json is a list of corresponding json
+ // any side not represented in "sides" has no override
+ if (data.has("sides") && data.has("gltf_json"))
+ {
+ LLSD const& sides = data.get("sides");
+ LLSD const& gltf_json = data.get("gltf_json");
+
+ if (sides.isArray() && gltf_json.isArray() &&
+ sides.size() != 0 &&
+ sides.size() == gltf_json.size())
+ {
+ for (int i = 0; i < sides.size(); ++i)
+ {
+ S32 side_idx = sides[i].asInteger();
+ mSides[side_idx] = gltf_json[i].asString();
+ }
+ }
+ else
+ {
+ LL_WARNS_IF(sides.size() != 0, "GLTF") << "broken override cache entry" << LL_ENDL;
+ }
+ }
+ return true;
+}
+
+LLSD LLGLTFOverrideCacheEntry::toLLSD() const
+{
+ LLSD data;
+ if (mHasRegionHandle)
+ {
+ U32 region_handle_x, region_handle_y;
+ from_region_handle(mRegionHandle, &region_handle_x, &region_handle_y);
+ data["region_handle_y"] = LLSD::Integer(region_handle_y);
+ data["region_handle_x"] = LLSD::Integer(region_handle_x);
+ }
+
+ data["object_id"] = mObjectId;
+
+ for (auto const & side : mSides)
+ {
+ data["sides"].append(LLSD::Integer(side.first));
+ data["gltf_json"].append(side.second);
+ }
+
+ return data;
+}
//---------------------------------------------------------------------------
// LLVOCacheEntry
@@ -170,7 +239,7 @@ LLVOCacheEntry::~LLVOCacheEntry()
}
void LLVOCacheEntry::updateEntry(U32 crc, LLDataPackerBinaryBuffer &dp)
-{
+{
if(mCRC != crc)
{
mCRC = crc;
@@ -356,6 +425,7 @@ S32 LLVOCacheEntry::writeToBuffer(U8 *data_buffer) const
return ENTRY_HEADER_SIZE + size;
}
+#ifndef LL_TEST
//static
void LLVOCacheEntry::updateDebugSettings()
{
@@ -408,6 +478,7 @@ void LLVOCacheEntry::updateDebugSettings()
const U32 clamped_frames = inv_obj_time ? llclamp((U32) inv_obj_time, MIN_FRAMES, MAX_FRAMES) : MAX_FRAMES; // [10, 64], with zero => 64
sMinFrameRange = MIN_FRAMES + ((clamped_frames - MIN_FRAMES) * adjust_factor);
}
+#endif // LL_TEST
//static
F32 LLVOCacheEntry::getSquaredPixelThreshold(bool is_front)
@@ -879,6 +950,7 @@ void LLVOCachePartition::selectBackObjects(LLCamera &camera, F32 pixel_threshold
return;
}
+#ifndef LL_TEST
S32 LLVOCachePartition::cull(LLCamera &camera, bool do_occlusion)
{
static LLCachedControl<bool> use_object_cache_occlusion(gSavedSettings,"UseObjectCacheOcclusion");
@@ -945,6 +1017,7 @@ S32 LLVOCachePartition::cull(LLCamera &camera, bool do_occlusion)
}
return 1;
}
+#endif // LL_TEST
void LLVOCachePartition::setCullHistory(BOOL has_new_object)
{
@@ -1018,8 +1091,9 @@ void LLVOCachePartition::removeOccluder(LLVOCacheGroup* group)
//-------------------------------------------------------------------
//LLVOCache
//-------------------------------------------------------------------
-// Format string used to construct filename for the object cache
+// Format strings used to construct filename for the object cache
static const char OBJECT_CACHE_FILENAME[] = "objects_%d_%d.slc";
+static const char OBJECT_CACHE_EXTRAS_FILENAME[] = "objects_%d_%d_extras.slec";
const U32 MAX_NUM_OBJECT_ENTRIES = 128 ;
const U32 MIN_ENTRIES_TO_PURGE = 16 ;
@@ -1032,9 +1106,12 @@ LLVOCache::LLVOCache(bool read_only) :
mInitialized(false),
mReadOnly(read_only),
mNumEntries(0),
- mCacheSize(1)
+ mCacheSize(1),
+ mEnabled(true)
{
+#ifndef LL_TEST
mEnabled = gSavedSettings.getBOOL("ObjectCacheEnabled");
+#endif
mLocalAPRFilePoolp = new LLVolatileAPRPool() ;
}
@@ -1211,6 +1288,15 @@ void LLVOCache::getObjectCacheFilename(U64 handle, std::string& filename)
return ;
}
+std::string LLVOCache::getObjectCacheExtrasFilename(U64 handle)
+{
+ U32 region_x, region_y;
+
+ grid_from_region_handle(handle, &region_x, &region_y);
+ return gDirUtilp->getExpandedFilename(LL_PATH_CACHE, object_cache_dirname,
+ llformat(OBJECT_CACHE_EXTRAS_FILENAME, region_x, region_y));
+}
+
void LLVOCache::removeFromCache(HeaderEntryInfo* entry)
{
if(mReadOnly)
@@ -1435,7 +1521,83 @@ void LLVOCache::readFromCache(U64 handle, const LLUUID& id, LLVOCacheEntry::voca
return ;
}
-
+
+void LLVOCache::readGenericExtrasFromCache(U64 handle, const LLUUID& id, LLVOCacheEntry::vocache_gltf_overrides_map_t& cache_extras_entry_map)
+{
+ if(!mEnabled)
+ {
+ LL_WARNS() << "Not reading cache for handle " << handle << "): Cache is currently disabled." << LL_ENDL;
+ return ;
+ }
+ llassert_always(mInitialized);
+
+ handle_entry_map_t::iterator iter = mHandleEntryMap.find(handle) ;
+ if(iter == mHandleEntryMap.end()) //no cache
+ {
+ LL_WARNS() << "No handle map entry for " << handle << LL_ENDL;
+ return;
+ }
+
+ std::string filename(getObjectCacheExtrasFilename(handle));
+ llifstream in(filename, std::ios::in | std::ios::binary);
+
+ std::string line;
+ std::getline(in, line);
+ if(!in.good()) {
+ LL_WARNS() << "Failed reading extras cache for handle " << handle << LL_ENDL;
+ return;
+ }
+
+ if(!LLUUID::validate(line))
+ {
+ LL_WARNS() << "Failed reading extras cache for handle" << handle << ". invalid uuid line: '" << line << "'" << LL_ENDL;
+ return;
+ }
+
+ LLUUID cache_id(line);
+ if(cache_id != id)
+ {
+ LL_INFOS() << "Cache ID doesn't match for this region, discarding" << LL_ENDL;
+ return;
+ }
+
+ U32 num_entries; // if removal was enabled during write num_entries might be wrong
+ std::getline(in, line);
+ if(!in.good()) {
+ LL_WARNS() << "Failed reading extras cache for handle " << handle << LL_ENDL;
+ return;
+ }
+ try {
+ num_entries = std::stol(line);
+ }
+ catch(std::logic_error&) // either invalid_argument or out_of_range
+ {
+ LL_WARNS() << "Failed reading extras cache for handle " << handle << ". unreadable num_entries" << LL_ENDL;
+ return;
+ }
+
+ LL_DEBUGS("GLTF") << "Beginning reading extras cache for handle " << handle << ", " << num_entries << " entries" << LL_ENDL;
+
+ LLSD entry_llsd;
+ for (U32 i = 0; i < num_entries && !in.eof(); i++)
+ {
+ static const U32 max_size = 4096;
+ bool success = LLSDSerialize::deserialize(entry_llsd, in, max_size);
+ // check bool(in) this time since eof is not a failure condition here
+ if(!success || !in) {
+ LL_WARNS() << "Failed reading extras cache for handle " << handle << ", entry number " << i << LL_ENDL;
+ return;
+ }
+
+ LLGLTFOverrideCacheEntry entry;
+ entry.fromLLSD(entry_llsd);
+ U32 local_id = entry_llsd["local_id"].asInteger();
+ cache_extras_entry_map[local_id] = entry;
+ }
+
+ LL_DEBUGS("GLTF") << "Completed reading extras cache for handle " << handle << ", " << num_entries << " entries" << LL_ENDL;
+}
+
void LLVOCache::purgeEntries(U32 size)
{
while(mHeaderEntryQueue.size() > size)
@@ -1446,6 +1608,7 @@ void LLVOCache::purgeEntries(U32 size)
mHeaderEntryQueue.erase(iter) ;
removeFromCache(entry) ;
delete entry;
+ // TODO also delete extras
}
mNumEntries = mHandleEntryMap.size() ;
}
@@ -1572,3 +1735,62 @@ void LLVOCache::writeToCache(U64 handle, const LLUUID& id, const LLVOCacheEntry:
return ;
}
+
+void LLVOCache::writeGenericExtrasToCache(U64 handle, const LLUUID& id, const LLVOCacheEntry::vocache_gltf_overrides_map_t& cache_extras_entry_map, BOOL dirty_cache, bool removal_enabled)
+{
+ if(!mEnabled)
+ {
+ LL_WARNS() << "Not writing extras cache for handle " << handle << "): Cache is currently disabled." << LL_ENDL;
+ return;
+ }
+ llassert_always(mInitialized);
+
+ if(mReadOnly)
+ {
+ LL_WARNS() << "Not writing extras cache for handle " << handle << "): Cache is currently in read-only mode." << LL_ENDL;
+ return;
+ }
+
+ std::string filename(getObjectCacheExtrasFilename(handle));
+ llofstream out(filename, std::ios::out | std::ios::binary);
+ if(!out.good())
+ {
+ LL_WARNS() << "Failed writing extras cache for handle " << handle << LL_ENDL;
+ return;
+ // TODO - clean up broken cache file
+ }
+
+ out << id << '\n';
+ if(!out.good())
+ {
+ LL_WARNS() << "Failed writing extras cache for handle " << handle << LL_ENDL;
+ return;
+ // TODO - clean up broken cache file
+ }
+
+ U32 num_entries = cache_extras_entry_map.size();
+ out << num_entries << '\n';
+ if(!out.good())
+ {
+ LL_WARNS() << "Failed writing extras cache for handle " << handle << LL_ENDL;
+ return;
+ // TODO - clean up broken cache file
+ }
+
+ for (auto const & entry : cache_extras_entry_map)
+ {
+ S32 local_id = entry.first;
+ LLSD entry_llsd = entry.second.toLLSD();
+ entry_llsd["local_id"] = local_id;
+ LLSDSerialize::serialize(entry_llsd, out, LLSDSerialize::LLSD_XML);
+ out << '\n';
+ if(!out.good())
+ {
+ LL_WARNS() << "Failed writing extras cache for handle " << handle << LL_ENDL;
+ return;
+ // TODO - clean up broken cache file
+ }
+ }
+
+ LL_DEBUGS("GLTF") << "Completed writing extras cache for handle " << handle << ", " << num_entries << " entries" << LL_ENDL;
+}