summaryrefslogtreecommitdiff
path: root/indra/newview
diff options
context:
space:
mode:
authorDave Parks <davep@lindenlab.com>2009-12-15 17:45:10 -0600
committerDave Parks <davep@lindenlab.com>2009-12-15 17:45:10 -0600
commitb6af8aae5b0cccfb6653d84e2020557c2be945ce (patch)
tree8f495acf9360c95aca0c002bcf704ba169ab58ce /indra/newview
parentde38b58f37d6c7dadd4a5f15be519cb0bb230fc7 (diff)
parent081fa98a47d2b592ada0fbb049ff959ac2cd6294 (diff)
merge
Diffstat (limited to 'indra/newview')
-rw-r--r--indra/newview/CMakeLists.txt2
-rw-r--r--indra/newview/app_settings/settings.xml13
-rw-r--r--indra/newview/llappviewer.cpp8
-rw-r--r--indra/newview/llviewerregion.cpp1
-rw-r--r--indra/newview/llvovolume.cpp31
-rw-r--r--indra/newview/pipeline.cpp255
-rw-r--r--indra/newview/pipeline.h34
7 files changed, 59 insertions, 285 deletions
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index 3b3b624600..fac1dedb02 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -285,6 +285,7 @@ set(viewer_SOURCE_FILES
llmediaremotectrl.cpp
llmemoryview.cpp
llmenucommands.cpp
+ llmeshrepository.cpp
llmetricperformancetester.cpp
llmimetypes.cpp
llmorphview.cpp
@@ -797,6 +798,7 @@ set(viewer_HEADER_FILES
llmediaremotectrl.h
llmemoryview.h
llmenucommands.h
+ llmeshrepository.h
llmetricperformancetester.h
llmimetypes.h
llmorphview.h
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index cc19578386..d1ec04842e 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -7495,6 +7495,17 @@
<key>Value</key>
<integer>8</integer>
</map>
+ <key>MeshMaxConcurrentRequests</key>
+ <map>
+ <key>Comment</key>
+ <string>Number of threads to use for loading meshes.</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>U32</string>
+ <key>Value</key>
+ <integer>32</integer>
+ </map>
<key>SafeMode</key>
<map>
@@ -10063,7 +10074,7 @@
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
- <integer>1</integer>
+ <integer>0</integer>
</map>
<key>UseStartScreen</key>
<map>
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index 3250343b25..8dfc1657cf 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -48,6 +48,7 @@
#include "llwindow.h"
#include "llviewerstats.h"
#include "llmd5.h"
+#include "llmeshrepository.h"
#include "llpumpio.h"
#include "llmimetypes.h"
#include "llslurl.h"
@@ -1273,6 +1274,9 @@ bool LLAppViewer::cleanup()
llinfos << "Cleaning Up" << llendflush;
+ // shut down mesh streamer
+ gMeshRepo.shutdown();
+
// Must clean up texture references before viewer window is destroyed.
LLHUDManager::getInstance()->updateEffects();
LLHUDObject::updateAll();
@@ -1685,6 +1689,9 @@ bool LLAppViewer::initThreads()
mFastTimerLogThread->start();
}
+ // Mesh streaming and caching
+ gMeshRepo.init();
+
// *FIX: no error handling here!
return true;
}
@@ -2401,6 +2408,7 @@ bool LLAppViewer::initWindow()
gSavedSettings.saveToFile( gSavedSettings.getString("ClientSettingsFile"), TRUE );
gPipeline.init();
+
stop_glerror();
gViewerWindow->initGLDefaults();
diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp
index 8317837520..f173149bf4 100644
--- a/indra/newview/llviewerregion.cpp
+++ b/indra/newview/llviewerregion.cpp
@@ -1432,6 +1432,7 @@ void LLViewerRegion::setSeedCapability(const std::string& url)
capabilityNames.append("FetchLib");
capabilityNames.append("FetchLibDescendents");
capabilityNames.append("GetTexture");
+ capabilityNames.append("GetMesh");
capabilityNames.append("GroupProposalBallot");
capabilityNames.append("HomeLocation");
capabilityNames.append("MapLayer");
diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp
index 00b02035b5..60294ccb26 100644
--- a/indra/newview/llvovolume.cpp
+++ b/indra/newview/llvovolume.cpp
@@ -70,6 +70,7 @@
#include "llsdutil.h"
#include "llmediaentry.h"
#include "llmediadataclient.h"
+#include "llmeshrepository.h"
#include "llagent.h"
const S32 MIN_QUIET_FRAMES_COALESCE = 30;
@@ -880,6 +881,24 @@ BOOL LLVOVolume::setVolume(const LLVolumeParams &params, const S32 detail, bool
{
LLVolumeParams volume_params = params;
+ S32 lod = mLOD;
+
+ if (isSculpted())
+ {
+ // if it's a mesh
+ if ((volume_params.getSculptType() & LL_SCULPT_TYPE_MASK) == LL_SCULPT_TYPE_MESH)
+ { //meshes might not have all LODs, get the force detail to best existing LOD
+ LLUUID mesh_id = params.getSculptID();
+
+ //profile and path params don't matter for meshes
+ volume_params = LLVolumeParams();
+ volume_params.setType(LL_PCODE_PROFILE_SQUARE, LL_PCODE_PATH_LINE);
+ volume_params.setSculptID(mesh_id, LL_SCULPT_TYPE_MESH);
+
+ lod = gMeshRepo.getActualMeshLOD(mesh_id, lod);
+ }
+ }
+
// Check if we need to change implementations
bool is_flexible = (volume_params.getPathParams().getCurveType() == LL_PCODE_PATH_FLEXIBLE);
if (is_flexible)
@@ -907,13 +926,15 @@ BOOL LLVOVolume::setVolume(const LLVolumeParams &params, const S32 detail, bool
}
}
- if ((LLPrimitive::setVolume(volume_params, mLOD, (mVolumeImpl && mVolumeImpl->isVolumeUnique()))) || mSculptChanged)
+
+
+ if ((LLPrimitive::setVolume(volume_params, lod, (mVolumeImpl && mVolumeImpl->isVolumeUnique()))) || mSculptChanged)
{
mFaceMappingChanged = TRUE;
if (mVolumeImpl)
{
- mVolumeImpl->onSetVolume(volume_params, detail);
+ mVolumeImpl->onSetVolume(volume_params, mLOD);
}
if (isSculpted())
@@ -925,7 +946,11 @@ BOOL LLVOVolume::setVolume(const LLVolumeParams &params, const S32 detail, bool
{
//load request not yet issued, request pipeline load this mesh
LLUUID asset_id = volume_params.getSculptID();
- gPipeline.loadMesh(this, asset_id, LLVolumeLODGroup::getVolumeDetailFromScale(getVolume()->getDetail()));
+ S32 available_lod = gMeshRepo.loadMesh(this, asset_id, lod);
+ if (available_lod != lod)
+ {
+ LLPrimitive::setVolume(volume_params, available_lod);
+ }
}
}
else // otherwise is sculptie
diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index 610804c5eb..b37645d2de 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -70,6 +70,7 @@
#include "llgldbg.h"
#include "llhudmanager.h"
#include "lllightconstants.h"
+#include "llmeshrepository.h"
#include "llresmgr.h"
#include "llselectmgr.h"
#include "llsky.h"
@@ -103,6 +104,7 @@
#include "llspatialpartition.h"
#include "llmutelist.h"
#include "lltoolpie.h"
+#include "llcurl.h"
#ifdef _DEBUG
@@ -342,8 +344,6 @@ LLPipeline::LLPipeline() :
mGlowPool(NULL),
mBumpPool(NULL),
mWLSkyPool(NULL),
- mMeshMutex(NULL),
- mMeshThreadCount(0),
mLightMask(0),
mLightMovingMask(0),
mLightingDetail(0),
@@ -403,7 +403,6 @@ void LLPipeline::init()
stop_glerror();
- mMeshMutex = new LLMutex(NULL);
for (U32 i = 0; i < 2; ++i)
{
mSpotLightFade[i] = 1.f;
@@ -478,9 +477,6 @@ void LLPipeline::cleanup()
//delete mWLSkyPool;
mWLSkyPool = NULL;
- delete mMeshMutex;
- mMeshMutex = NULL;
-
releaseGLBuffers();
mBloomImagep = NULL;
@@ -1802,6 +1798,8 @@ void LLPipeline::rebuildPriorityGroups()
assertInitialized();
+ gMeshRepo.notifyLoadedMeshes();
+
// Iterate through all drawables on the priority build queue,
for (LLSpatialGroup::sg_list_t::iterator iter = mGroupQ1.begin();
iter != mGroupQ1.end(); ++iter)
@@ -1881,8 +1879,6 @@ void LLPipeline::updateGeom(F32 max_dtime)
// for now, only LLVOVolume does this to throttle LOD changes
LLVOVolume::preUpdateGeom();
- notifyLoadedMeshes();
-
// Iterate through all drawables on the priority build queue,
for (LLDrawable::drawable_list_t::iterator iter = mBuildQ1.begin();
iter != mBuildQ1.end();)
@@ -8912,246 +8908,3 @@ LLCullResult::sg_list_t::iterator LLPipeline::endAlphaGroups()
}
-void LLPipeline::loadMesh(LLVOVolume* vobj, LLUUID mesh_id, S32 detail)
-{
- if (detail < 0 || detail > 4)
- {
- return;
- }
-
- {
- LLMutexLock lock(mMeshMutex);
- //add volume to list of loading meshes
- mesh_load_map::iterator iter = mLoadingMeshes[detail].find(mesh_id);
- if (iter != mLoadingMeshes[detail].end())
- { //request pending for this mesh, append volume id to list
- iter->second.insert(vobj->getID());
- return;
- }
-
- //first request for this mesh
- mLoadingMeshes[detail][mesh_id].insert(vobj->getID());
- }
-
- if (gAssetStorage->hasLocalAsset(mesh_id, LLAssetType::AT_MESH))
- { //already have asset, load desired LOD in background
- mPendingMeshes.push_back(new LLMeshThread(mesh_id, vobj->getVolume(), detail));
- }
- else
- { //fetch asset and load when done
- gAssetStorage->getAssetData(mesh_id, LLAssetType::AT_MESH,
- getMeshAssetCallback, vobj->getVolume(), TRUE);
- }
-
- //do a quick search to see if we can't display something while we wait for this mesh to load
- LLVolume* volume = vobj->getVolume();
-
- if (volume)
- {
- LLVolumeParams params = volume->getParams();
-
- LLVolumeLODGroup* group = LLPrimitive::getVolumeManager()->getGroup(params);
-
- if (group)
- {
- //first see what the next lowest LOD available might be
- for (S32 i = detail-1; i >= 0; --i)
- {
- LLVolume* lod = group->refLOD(i);
- if (lod && !lod->isTetrahedron() && lod->getNumVolumeFaces() > 0)
- {
- volume->copyVolumeFaces(lod);
- group->derefLOD(lod);
- return;
- }
-
- group->derefLOD(lod);
- }
-
- //no lower LOD is a available, is a higher lod available?
- for (S32 i = detail+1; i < 4; ++i)
- {
- LLVolume* lod = group->refLOD(i);
- if (lod && !lod->isTetrahedron() && lod->getNumVolumeFaces() > 0)
- {
- volume->copyVolumeFaces(lod);
- group->derefLOD(lod);
- return;
- }
-
- group->derefLOD(lod);
- }
- }
- else
- {
- llerrs << "WTF?" << llendl;
- }
-
- //nothing found, so make a tetrahedron
- volume->makeTetrahedron();
- }
-}
-
-//static
-void LLPipeline::getMeshAssetCallback(LLVFS *vfs,
- const LLUUID& asset_uuid,
- LLAssetType::EType type,
- void* user_data, S32 status, LLExtStat ext_status)
-{
- gPipeline.mPendingMeshes.push_back(new LLMeshThread(asset_uuid, (LLVolume*) user_data));
-}
-
-
-LLPipeline::LLMeshThread::LLMeshThread(LLUUID mesh_id, LLVolume* target, S32 detail)
-: LLThread("mesh_loading_thread")
-{
- mMeshID = mesh_id;
- mVolume = NULL;
- mDetail = target->getDetail();
-
- if (detail == -1)
- {
- mDetailIndex = LLVolumeLODGroup::getVolumeDetailFromScale(target->getDetail());
- }
- else
- {
- mDetailIndex = detail;
- }
-
- mTargetVolume = target;
-}
-
-LLPipeline::LLMeshThread::~LLMeshThread()
-{
-
-}
-
-void LLPipeline::LLMeshThread::run()
-{
- if (!gAssetStorage || LLApp::instance()->isQuitting())
- {
- return;
- }
-
- char* buffer = NULL;
- S32 size = 0;
-
- LLVFS* vfs = gAssetStorage->mVFS;
-
- {
- LLVFile file(vfs, mMeshID, LLAssetType::AT_MESH, LLVFile::READ);
- file.waitForLock(VFSLOCK_READ);
- size = file.getSize();
-
- if (size == 0)
- {
- gPipeline.meshLoaded(this);
- return;
- }
-
- buffer = new char[size];
- file.read((U8*)&buffer[0], size);
- }
-
- {
- std::string buffer_string(buffer, size);
- std::istringstream buffer_stream(buffer_string);
-
- {
- LLVolumeParams volume_params;
- volume_params.setType(LL_PCODE_PROFILE_SQUARE, LL_PCODE_PATH_LINE);
- volume_params.setSculptID(mMeshID, LL_SCULPT_TYPE_MESH);
- mVolume = new LLVolume(volume_params, mDetail);
- mVolume->createVolumeFacesFromStream(buffer_stream);
- }
- }
- delete[] buffer;
-
- gPipeline.meshLoaded(this);
-}
-
-void LLPipeline::meshLoaded(LLPipeline::LLMeshThread* mesh_thread)
-{
- LLMutexLock lock(mMeshMutex);
- mLoadedMeshes.push_back(mesh_thread);
-}
-
-void LLPipeline::notifyLoadedMeshes()
-{ //called from main thread
-
- U32 max_thread_count = llmax(gSavedSettings.getU32("MeshThreadCount"), (U32) 1);
- while (mMeshThreadCount < max_thread_count && !mPendingMeshes.empty())
- {
- LLMeshThread* mesh_thread = mPendingMeshes.front();
- mesh_thread->start();
- ++mMeshThreadCount;
- mPendingMeshes.pop_front();
- }
-
- LLMutexLock lock(mMeshMutex);
- std::list<LLMeshThread*> stopping_threads;
-
- for (std::list<LLMeshThread*>::iterator iter = mLoadedMeshes.begin(); iter != mLoadedMeshes.end(); ++iter)
- { //for each mesh done loading
- LLMeshThread* mesh = *iter;
-
- if (!mesh->isStopped())
- { //don't process a LLMeshThread until it's stopped
- stopping_threads.push_back(mesh);
- continue;
- }
-
- S32 detail = mesh->mDetailIndex;
-
- //get list of objects waiting to be notified this mesh is loaded
- mesh_load_map::iterator obj_iter = mLoadingMeshes[detail].find(mesh->mMeshID);
-
- if (mesh->mVolume && obj_iter != mLoadingMeshes[detail].end())
- {
- //make sure target volume is still valid
- BOOL valid = FALSE;
-
- for (std::set<LLUUID>::iterator vobj_iter = obj_iter->second.begin(); vobj_iter != obj_iter->second.end(); ++vobj_iter)
- {
- LLVOVolume* vobj = (LLVOVolume*) gObjectList.findObject(*vobj_iter);
-
- if (vobj)
- {
- if (vobj->getVolume() == mesh->mTargetVolume)
- {
- valid = TRUE;
- }
- }
- }
-
-
- if (valid)
- {
- if (mesh->mVolume->getNumVolumeFaces() <= 0)
- {
- llwarns << "Mesh loading returned empty volume." << llendl;
- mesh->mVolume->makeTetrahedron();
- }
-
- mesh->mTargetVolume->copyVolumeFaces(mesh->mVolume);
-
- for (std::set<LLUUID>::iterator vobj_iter = obj_iter->second.begin(); vobj_iter != obj_iter->second.end(); ++vobj_iter)
- {
- LLVOVolume* vobj = (LLVOVolume*) gObjectList.findObject(*vobj_iter);
- if (vobj)
- {
- vobj->notifyMeshLoaded();
- }
- }
- }
-
- mLoadingMeshes[detail].erase(mesh->mMeshID);
- }
-
- delete mesh;
- --mMeshThreadCount;
- }
-
- mLoadedMeshes = stopping_threads;
-}
-
diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h
index f41f6173a9..0b040acf51 100644
--- a/indra/newview/pipeline.h
+++ b/indra/newview/pipeline.h
@@ -58,6 +58,8 @@ class LLCubeMap;
class LLCullResult;
class LLVOAvatar;
class LLGLSLShader;
+class LLCurlRequest;
+class LLMeshResponder;
typedef enum e_avatar_skinning_method
{
@@ -278,10 +280,6 @@ public:
LLCullResult::sg_list_t::iterator beginAlphaGroups();
LLCullResult::sg_list_t::iterator endAlphaGroups();
-
- //mesh management functions
- void loadMesh(LLVOVolume* volume, LLUUID mesh_id, S32 detail = 0);
-
void addTrianglesDrawn(S32 count);
BOOL hasRenderType(const U32 type) const { return (type && (mRenderTypeMask & (1<<type))) ? TRUE : FALSE; }
BOOL hasRenderDebugFeatureMask(const U32 mask) const { return (mRenderDebugFeatureMask & mask) ? TRUE : FALSE; }
@@ -683,32 +681,8 @@ protected:
typedef std::map<LLUUID, std::set<LLUUID> > mesh_load_map;
mesh_load_map mLoadingMeshes[4];
- LLMutex* mMeshMutex;
-
- class LLMeshThread : public LLThread
- {
- public:
- LLPointer<LLVolume> mVolume;
- LLVolume* mTargetVolume;
- LLUUID mMeshID;
- F32 mDetail;
- S32 mDetailIndex;
- LLMeshThread(LLUUID mesh_id, LLVolume* target, S32 detail = -1);
- ~LLMeshThread();
- void run();
- };
-
- static void getMeshAssetCallback(LLVFS *vfs,
- const LLUUID& asset_uuid,
- LLAssetType::EType type,
- void* user_data, S32 status, LLExtStat ext_status);
-
- std::list<LLMeshThread*> mLoadedMeshes;
- std::list<LLMeshThread*> mPendingMeshes;
- U32 mMeshThreadCount;
-
- void meshLoaded(LLMeshThread* mesh_thread);
- void notifyLoadedMeshes();
+ typedef std::list<LLMeshResponder*> mesh_response_list;
+ mesh_response_list mMeshResponseList;
LLPointer<LLViewerFetchedTexture> mFaceSelectImagep;
LLPointer<LLViewerTexture> mBloomImagep;