Pulled mesh header info parsing and VFS fetching into their own procedures to remove duplicate code.

This commit is contained in:
Shyotl
2014-08-18 17:16:45 -05:00
parent 47fcc70756
commit d1d68721ac
2 changed files with 125 additions and 244 deletions

View File

@@ -775,7 +775,7 @@ std::string LLMeshRepoThread::constructUrl(LLUUID mesh_id)
return http_url; return http_url;
} }
bool LLMeshRepoThread::fetchMeshSkinInfo(const LLUUID& mesh_id) bool LLMeshRepoThread::getMeshHeaderInfo(const LLUUID& mesh_id, const char* block_name, MeshHeaderInfo& info)
{ //protected by mMutex { //protected by mMutex
if (!mHeaderMutex) if (!mHeaderMutex)
@@ -783,229 +783,141 @@ bool LLMeshRepoThread::fetchMeshSkinInfo(const LLUUID& mesh_id)
return false; return false;
} }
mHeaderMutex->lock(); LLMutexLock lock(mHeaderMutex);
if (mMeshHeader.find(mesh_id) == mMeshHeader.end()) if (mMeshHeader.find(mesh_id) == mMeshHeader.end())
{ //we have no header info for this mesh, do nothing { //we have no header info for this mesh, do nothing
mHeaderMutex->unlock();
return false; return false;
} }
bool ret = true ; if ((info.mHeaderSize = mMeshHeaderSize[mesh_id]) > 0)
U32 header_size = mMeshHeaderSize[mesh_id];
if (header_size > 0)
{ {
S32 version = mMeshHeader[mesh_id]["version"].asInteger(); info.mVersion = mMeshHeader[mesh_id]["version"].asInteger();
S32 offset = header_size + mMeshHeader[mesh_id]["skin"]["offset"].asInteger(); info.mOffset = info.mHeaderSize + mMeshHeader[mesh_id][block_name]["offset"].asInteger();
S32 size = mMeshHeader[mesh_id]["skin"]["size"].asInteger(); info.mSize = mMeshHeader[mesh_id][block_name]["size"].asInteger();
}
return true;
}
mHeaderMutex->unlock(); bool LLMeshRepoThread::loadInfoFromVFS(const LLUUID& mesh_id, MeshHeaderInfo& info, boost::function<bool(const LLUUID&, U8*, S32)> fn)
{
//check VFS for mesh skin info
LLVFile file(gVFS, mesh_id, LLAssetType::AT_MESH);
if (file.getSize() >= info.mOffset + info.mSize)
{
LLMeshRepository::sCacheBytesRead += info.mSize;
if (version <= MAX_MESH_VERSION && offset >= 0 && size > 0) file.seek(info.mOffset);
U8* buffer = new U8[info.mSize];
file.read(buffer, info.mSize);
//make sure buffer isn't all 0's by checking the first 1KB (reserved block but not written)
bool zero = true;
for (S32 i = 0; i < llmin(info.mSize, S32(1024)) && zero; ++i)
{ {
//check VFS for mesh skin info zero = buffer[i] > 0 ? false : true;
LLVFile file(gVFS, mesh_id, LLAssetType::AT_MESH); }
if (file.getSize() >= offset+size)
if (!zero)
{ //attempt to parse
if (fn(mesh_id, buffer, info.mSize))
{ {
LLMeshRepository::sCacheBytesRead += size;
file.seek(offset);
U8* buffer = new U8[size];
file.read(buffer, size);
//make sure buffer isn't all 0's by checking the first 1KB (reserved block but not written)
bool zero = true;
for (S32 i = 0; i < llmin(size, 1024) && zero; ++i)
{
zero = buffer[i] > 0 ? false : true;
}
if (!zero)
{ //attempt to parse
if (skinInfoReceived(mesh_id, buffer, size))
{
delete[] buffer;
return true;
}
}
delete[] buffer; delete[] buffer;
} return true;
//reading from VFS failed for whatever reason, fetch from sim
AIHTTPHeaders headers("Accept", "application/octet-stream");
std::string http_url = constructUrl(mesh_id);
if (!http_url.empty())
{
ret = LLHTTPClient::getByteRange(http_url, headers, offset, size,
new LLMeshSkinInfoResponder(mesh_id, offset, size));
if (ret)
{
LLMeshRepository::sHTTPRequestCount++;
}
} }
} }
delete[] buffer;
} }
else return false;
{ }
mHeaderMutex->unlock();
bool LLMeshRepoThread::fetchMeshSkinInfo(const LLUUID& mesh_id)
{
MeshHeaderInfo info;
if (!getMeshHeaderInfo(mesh_id, "skin", info))
{
return false;
}
if (info.mHeaderSize > 0 && info.mVersion <= MAX_MESH_VERSION && info.mOffset >= 0 && info.mSize > 0)
{
//check VFS for mesh skin info
if (loadInfoFromVFS(mesh_id, info, boost::bind(&LLMeshRepoThread::skinInfoReceived, this, _1, _2, _3 )))
return true;
//reading from VFS failed for whatever reason, fetch from sim
AIHTTPHeaders headers("Accept", "application/octet-stream");
std::string http_url = constructUrl(mesh_id);
if (!http_url.empty())
{
if (!LLHTTPClient::getByteRange(http_url, headers, info.mOffset, info.mSize,
new LLMeshSkinInfoResponder(mesh_id, info.mOffset, info.mSize)))
return false;
LLMeshRepository::sHTTPRequestCount++;
}
} }
//early out was not hit, effectively fetched //early out was not hit, effectively fetched
return ret; return true;
} }
bool LLMeshRepoThread::fetchMeshDecomposition(const LLUUID& mesh_id) bool LLMeshRepoThread::fetchMeshDecomposition(const LLUUID& mesh_id)
{ //protected by mMutex {
if (!mHeaderMutex) MeshHeaderInfo info;
if (!getMeshHeaderInfo(mesh_id, "physics_convex", info))
{ {
return false; return false;
} }
mHeaderMutex->lock(); if (info.mHeaderSize > 0 && info.mVersion <= MAX_MESH_VERSION && info.mOffset >= 0 && info.mSize > 0)
if (mMeshHeader.find(mesh_id) == mMeshHeader.end())
{ //we have no header info for this mesh, do nothing
mHeaderMutex->unlock();
return false;
}
U32 header_size = mMeshHeaderSize[mesh_id];
bool ret = true ;
if (header_size > 0)
{ {
S32 version = mMeshHeader[mesh_id]["version"].asInteger(); if (loadInfoFromVFS(mesh_id, info, boost::bind(&LLMeshRepoThread::decompositionReceived, this, _1, _2, _3 )))
S32 offset = header_size + mMeshHeader[mesh_id]["physics_convex"]["offset"].asInteger(); return true;
S32 size = mMeshHeader[mesh_id]["physics_convex"]["size"].asInteger();
mHeaderMutex->unlock(); //reading from VFS failed for whatever reason, fetch from sim
AIHTTPHeaders headers("Accept", "application/octet-stream");
if (version <= MAX_MESH_VERSION && offset >= 0 && size > 0) std::string http_url = constructUrl(mesh_id);
{ if (!http_url.empty())
//check VFS for mesh skin info {
LLVFile file(gVFS, mesh_id, LLAssetType::AT_MESH); if (!LLHTTPClient::getByteRange(http_url, headers, info.mOffset, info.mSize,
if (file.getSize() >= offset+size) new LLMeshDecompositionResponder(mesh_id, info.mOffset, info.mSize)))
{ return false;
LLMeshRepository::sCacheBytesRead += size; LLMeshRepository::sHTTPRequestCount++;
file.seek(offset);
U8* buffer = new U8[size];
file.read(buffer, size);
//make sure buffer isn't all 0's by checking the first 1KB (reserved block but not written)
bool zero = true;
for (S32 i = 0; i < llmin(size, 1024) && zero; ++i)
{
zero = buffer[i] > 0 ? false : true;
}
if (!zero)
{ //attempt to parse
if (decompositionReceived(mesh_id, buffer, size))
{
delete[] buffer;
return true;
}
}
delete[] buffer;
}
//reading from VFS failed for whatever reason, fetch from sim
AIHTTPHeaders headers("Accept", "application/octet-stream");
std::string http_url = constructUrl(mesh_id);
if (!http_url.empty())
{
ret = LLHTTPClient::getByteRange(http_url, headers, offset, size,
new LLMeshDecompositionResponder(mesh_id, offset, size));
if(ret)
{
LLMeshRepository::sHTTPRequestCount++;
}
}
} }
} }
else
{
mHeaderMutex->unlock();
}
//early out was not hit, effectively fetched //early out was not hit, effectively fetched
return ret; return true;
} }
bool LLMeshRepoThread::fetchMeshPhysicsShape(const LLUUID& mesh_id) bool LLMeshRepoThread::fetchMeshPhysicsShape(const LLUUID& mesh_id)
{ //protected by mMutex {
if (!mHeaderMutex) MeshHeaderInfo info;
if (!getMeshHeaderInfo(mesh_id, "physics_mesh", info))
{ {
return false; return false;
} }
mHeaderMutex->lock(); if (info.mHeaderSize > 0)
if (mMeshHeader.find(mesh_id) == mMeshHeader.end())
{ //we have no header info for this mesh, do nothing
mHeaderMutex->unlock();
return false;
}
U32 header_size = mMeshHeaderSize[mesh_id];
bool ret = true ;
if (header_size > 0)
{ {
S32 version = mMeshHeader[mesh_id]["version"].asInteger(); if (info.mVersion <= MAX_MESH_VERSION && info.mOffset >= 0 && info.mSize > 0)
S32 offset = header_size + mMeshHeader[mesh_id]["physics_mesh"]["offset"].asInteger();
S32 size = mMeshHeader[mesh_id]["physics_mesh"]["size"].asInteger();
mHeaderMutex->unlock();
if (version <= MAX_MESH_VERSION && offset >= 0 && size > 0)
{ {
//check VFS for mesh physics shape info if (loadInfoFromVFS(mesh_id, info, boost::bind(&LLMeshRepoThread::physicsShapeReceived, this, _1, _2, _3 )))
LLVFile file(gVFS, mesh_id, LLAssetType::AT_MESH); return true;
if (file.getSize() >= offset+size)
{
LLMeshRepository::sCacheBytesRead += size;
file.seek(offset);
U8* buffer = new U8[size];
file.read(buffer, size);
//make sure buffer isn't all 0's by checking the first 1KB (reserved block but not written)
bool zero = true;
for (S32 i = 0; i < llmin(size, 1024) && zero; ++i)
{
zero = buffer[i] > 0 ? false : true;
}
if (!zero)
{ //attempt to parse
if (physicsShapeReceived(mesh_id, buffer, size))
{
delete[] buffer;
return true;
}
}
delete[] buffer;
}
//reading from VFS failed for whatever reason, fetch from sim //reading from VFS failed for whatever reason, fetch from sim
AIHTTPHeaders headers("Accept", "application/octet-stream"); AIHTTPHeaders headers("Accept", "application/octet-stream");
std::string http_url = constructUrl(mesh_id); std::string http_url = constructUrl(mesh_id);
if (!http_url.empty()) if (!http_url.empty())
{ {
ret = LLHTTPClient::getByteRange(http_url, headers, offset, size, if (!LLHTTPClient::getByteRange(http_url, headers, info.mOffset, info.mSize,
new LLMeshPhysicsShapeResponder(mesh_id, offset, size)); new LLMeshPhysicsShapeResponder(mesh_id, info.mOffset, info.mSize)))
return false;
if(ret) LLMeshRepository::sHTTPRequestCount++;
{
LLMeshRepository::sHTTPRequestCount++;
}
} }
} }
else else
@@ -1013,13 +925,9 @@ bool LLMeshRepoThread::fetchMeshPhysicsShape(const LLUUID& mesh_id)
physicsShapeReceived(mesh_id, NULL, 0); physicsShapeReceived(mesh_id, NULL, 0);
} }
} }
else
{
mHeaderMutex->unlock();
}
//early out was not hit, effectively fetched //early out was not hit, effectively fetched
return ret; return true;
} }
//static //static
@@ -1095,72 +1003,34 @@ bool LLMeshRepoThread::fetchMeshHeader(const LLVolumeParams& mesh_params, U32& c
//return false if failed to get mesh lod. //return false if failed to get mesh lod.
bool LLMeshRepoThread::fetchMeshLOD(const LLVolumeParams& mesh_params, S32 lod, U32& count) bool LLMeshRepoThread::fetchMeshLOD(const LLVolumeParams& mesh_params, S32 lod, U32& count)
{ //protected by mMutex {
if (!mHeaderMutex) LLUUID mesh_id = mesh_params.getSculptID();
MeshHeaderInfo info;
if (!getMeshHeaderInfo(mesh_id, header_lod[lod].c_str(), info))
{ {
return false; return false;
} }
mHeaderMutex->lock(); if (info.mHeaderSize > 0)
bool retval = true;
LLUUID mesh_id = mesh_params.getSculptID();
U32 header_size = mMeshHeaderSize[mesh_id];
if (header_size > 0)
{ {
S32 version = mMeshHeader[mesh_id]["version"].asInteger(); if(info.mVersion <= MAX_MESH_VERSION && info.mOffset >= 0 && info.mSize > 0)
S32 offset = header_size + mMeshHeader[mesh_id][header_lod[lod]]["offset"].asInteger();
S32 size = mMeshHeader[mesh_id][header_lod[lod]]["size"].asInteger();
mHeaderMutex->unlock();
if (version <= MAX_MESH_VERSION && offset >= 0 && size > 0)
{ {
if (loadInfoFromVFS(mesh_id, info, boost::bind(&LLMeshRepoThread::lodReceived, this, mesh_params, lod, _2, _3 )))
//check VFS for mesh asset return true;
LLVFile file(gVFS, mesh_id, LLAssetType::AT_MESH);
if (file.getSize() >= offset+size)
{
LLMeshRepository::sCacheBytesRead += size;
file.seek(offset);
U8* buffer = new U8[size];
file.read(buffer, size);
//make sure buffer isn't all 0's by checking the first 1KB (reserved block but not written)
bool zero = true;
for (S32 i = 0; i < llmin(size, 1024) && zero; ++i)
{
zero = buffer[i] > 0 ? false : true;
}
if (!zero)
{ //attempt to parse
if (lodReceived(mesh_params, lod, buffer, size))
{
delete[] buffer;
return true;
}
}
delete[] buffer;
}
//reading from VFS failed for whatever reason, fetch from sim //reading from VFS failed for whatever reason, fetch from sim
AIHTTPHeaders headers("Accept", "application/octet-stream"); AIHTTPHeaders headers("Accept", "application/octet-stream");
std::string http_url = constructUrl(mesh_id); std::string http_url = constructUrl(mesh_id);
if (!http_url.empty()) if (!http_url.empty())
{ {
retval = LLHTTPClient::getByteRange(constructUrl(mesh_id), headers, offset, size, count++;
new LLMeshLODResponder(mesh_params, lod, offset, size)); if (!LLHTTPClient::getByteRange(constructUrl(mesh_id), headers, info.mOffset, info.mSize,
new LLMeshLODResponder(mesh_params, lod, info.mOffset, info.mSize)))
if (retval) return false;
{ LLMeshRepository::sHTTPRequestCount++;
LLMeshRepository::sHTTPRequestCount++;
}
count++;
} }
else else
{ {
@@ -1172,12 +1042,8 @@ bool LLMeshRepoThread::fetchMeshLOD(const LLVolumeParams& mesh_params, S32 lod,
mUnavailableQ.push(LODRequest(mesh_params, lod)); mUnavailableQ.push(LODRequest(mesh_params, lod));
} }
} }
else
{ return true;
mHeaderMutex->unlock();
}
return retval;
} }
bool LLMeshRepoThread::headerReceived(const LLVolumeParams& mesh_params, U8* data, S32 data_size) bool LLMeshRepoThread::headerReceived(const LLVolumeParams& mesh_params, U8* data, S32 data_size)

View File

@@ -40,6 +40,8 @@
#include "lluploadfloaterobservers.h" #include "lluploadfloaterobservers.h"
#include "aistatemachinethread.h" #include "aistatemachinethread.h"
#include <boost/function.hpp>
class LLVOVolume; class LLVOVolume;
class LLMeshResponder; class LLMeshResponder;
class LLMutex; class LLMutex;
@@ -283,6 +285,16 @@ public:
}; };
struct MeshHeaderInfo
{
MeshHeaderInfo()
: mHeaderSize(0), mVersion(0), mOffset(-1), mSize(0) {}
U32 mHeaderSize;
U32 mVersion;
S32 mOffset;
S32 mSize;
};
//set of requested skin info //set of requested skin info
std::set<LLUUID> mSkinRequests; std::set<LLUUID> mSkinRequests;
@@ -332,6 +344,9 @@ public:
bool physicsShapeReceived(const LLUUID& mesh_id, U8* data, S32 data_size); bool physicsShapeReceived(const LLUUID& mesh_id, U8* data, S32 data_size);
LLSD& getMeshHeader(const LLUUID& mesh_id); LLSD& getMeshHeader(const LLUUID& mesh_id);
bool getMeshHeaderInfo(const LLUUID& mesh_id, const char* block_name, MeshHeaderInfo& info);
bool loadInfoFromVFS(const LLUUID& mesh_id, MeshHeaderInfo& info, boost::function<bool(const LLUUID&, U8*, S32)> fn);
void notifyLoadedMeshes(); void notifyLoadedMeshes();
S32 getActualMeshLOD(const LLVolumeParams& mesh_params, S32 lod); S32 getActualMeshLOD(const LLVolumeParams& mesh_params, S32 lod);