From 3e80fa3dbc943de9b784fedc202ba38cf238f46d Mon Sep 17 00:00:00 2001
From: David Parks <davep@lindenlab.com>
Date: Mon, 2 Nov 2009 19:55:37 +0000
Subject: Sync up with render-pipeline-7 ignore-dead-branch

---
 indra/newview/pipeline.cpp | 241 ++++++++++++++++++++++++++++++++++++++++-----
 1 file changed, 214 insertions(+), 27 deletions(-)

(limited to 'indra/newview/pipeline.cpp')

diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index b50e71bf48..7cf5cf75ad 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -342,6 +342,8 @@ LLPipeline::LLPipeline() :
 	mGlowPool(NULL),
 	mBumpPool(NULL),
 	mWLSkyPool(NULL),
+	mMeshMutex(NULL),
+	mMeshThreadCount(0),
 	mLightMask(0),
 	mLightMovingMask(0),
 	mLightingDetail(0)
@@ -399,6 +401,7 @@ void LLPipeline::init()
 
 	stop_glerror();
 
+	mMeshMutex = new LLMutex(NULL);
 	for (U32 i = 0; i < 2; ++i)
 	{
 		mSpotLightFade[i] = 1.f;
@@ -473,6 +476,9 @@ void LLPipeline::cleanup()
 	//delete mWLSkyPool;
 	mWLSkyPool = NULL;
 
+	delete mMeshMutex;
+	mMeshMutex = NULL;
+
 	releaseGLBuffers();
 
 	mBloomImagep = NULL;
@@ -1783,6 +1789,8 @@ void LLPipeline::rebuildPriorityGroups()
 	
 	assertInitialized();
 
+	notifyLoadedMeshes();
+
 	// Iterate through all drawables on the priority build queue,
 	for (LLSpatialGroup::sg_list_t::iterator iter = mGroupQ1.begin();
 		 iter != mGroupQ1.end(); ++iter)
@@ -1793,6 +1801,7 @@ void LLPipeline::rebuildPriorityGroups()
 	}
 
 	mGroupQ1.clear();
+
 }
 		
 void LLPipeline::rebuildGroups()
@@ -3419,27 +3428,14 @@ void LLPipeline::renderGeomPostDeferred(LLCamera& camera)
 	gGLLastMatrix = NULL;
 	glLoadMatrixd(gGLModelView);
 
-	renderHighlights();
-	mHighlightFaces.clear();
-
-	renderDebug();
-
-	LLVertexBuffer::unbind();
-
-	if (gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI))
-	{
-		// Render debugging beacons.
-		gObjectList.renderObjectBeacons();
-		LLHUDObject::renderAll();
-		gObjectList.resetObjectBeacons();
-	}
-
 	if (occlude)
 	{
 		occlude = FALSE;
 		gGLLastMatrix = NULL;
 		glLoadMatrixd(gGLModelView);
 		doOcclusion(camera);
+		gGLLastMatrix = NULL;
+		glLoadMatrixd(gGLModelView);
 	}
 }
 
@@ -5836,6 +5832,12 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield)
 
 		gGL.getTexUnit(0)->activate();
 		gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT);
+
+		if (LLRenderTarget::sUseFBO)
+		{ //copy depth buffer from mScreen to framebuffer
+			LLRenderTarget::copyContentsToFramebuffer(mScreen, 0, 0, mScreen.getWidth(), mScreen.getHeight(), 
+				0, 0, mScreen.getWidth(), mScreen.getHeight(), GL_DEPTH_BUFFER_BIT, GL_NEAREST);
+		}
 	}
 	
 
@@ -6912,6 +6914,24 @@ void LLPipeline::renderDeferredLighting()
 		mRenderTypeMask = render_mask;
 	}
 
+	{
+		//render highlights, etc.
+		renderHighlights();
+		mHighlightFaces.clear();
+
+		renderDebug();
+
+		LLVertexBuffer::unbind();
+
+		if (gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI))
+		{
+			// Render debugging beacons.
+			gObjectList.renderObjectBeacons();
+			LLHUDObject::renderAll();
+			gObjectList.resetObjectBeacons();
+		}
+	}
+
 	mScreen.flush();
 						
 }
@@ -7241,18 +7261,12 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in)
 					LLGLDisable cull(GL_CULL_FACE);
 					updateCull(camera, ref_result, 1);
 					stateSort(camera, ref_result);
-					gGL.setColorMask(true, true);
-					mWaterRef.clear();
-					gGL.setColorMask(true, false);
-
-				}
-				else
-				{
-					gGL.setColorMask(true, true);
-					mWaterRef.clear();
-					gGL.setColorMask(true, false);
-				}
-
+				}	
+				
+				gGL.setColorMask(true, true);
+				mWaterRef.clear();
+				gGL.setColorMask(true, false);
+			
 				ref_mask = mRenderTypeMask;
 				mRenderTypeMask = mask;
 			}
@@ -7907,6 +7921,7 @@ void LLPipeline::generateHighlight(LLCamera& camera)
 
 		mHighlight.flush();
 		gGL.setColorMask(true, false);
+		gViewerWindow->setup3DViewport();
 	}
 }
 
@@ -8886,3 +8901,175 @@ LLCullResult::sg_list_t::iterator LLPipeline::endAlphaGroups()
 }
 
 
+void LLPipeline::loadMesh(LLVOVolume* volume, LLUUID mesh_id)
+{
+
+	{
+		LLMutexLock lock(mMeshMutex);
+		//add volume to list of loading meshes
+		mesh_load_map::iterator iter = mLoadingMeshes.find(mesh_id);
+		if (iter != mLoadingMeshes.end())
+		{ //request pending for this mesh, append volume id to list
+			iter->second.insert(volume->getID());
+			return;
+		}
+
+		//first request for this mesh
+		mLoadingMeshes[mesh_id].insert(volume->getID());
+	}
+
+	if (gAssetStorage->hasLocalAsset(mesh_id, LLAssetType::AT_MESH))
+	{ //already have asset, load desired LOD in background
+		mPendingMeshes.push_back(new LLMeshThread(mesh_id, volume->getVolume()));
+	}
+	else
+	{ //fetch asset and load when done
+		gAssetStorage->getAssetData(mesh_id, LLAssetType::AT_MESH,
+									getMeshAssetCallback, volume->getVolume(), TRUE);
+	}
+
+}
+
+//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)
+: LLThread("mesh_loading_thread")
+{
+	mMeshID = mesh_id;
+	mVolume = NULL;
+	mDetail = target->getDetail();
+	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);
+			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;
+		}
+
+		//get list of objects waiting to be notified this mesh is loaded
+		mesh_load_map::iterator obj_iter = mLoadingMeshes.find(mesh->mMeshID);
+
+		if (mesh->mVolume && obj_iter != mLoadingMeshes.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)
+			{
+				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.erase(mesh->mMeshID);
+		}
+
+		delete mesh;
+		--mMeshThreadCount;
+	}
+
+	mLoadedMeshes = stopping_threads;
+}
+
-- 
cgit v1.2.3


From 88292104d9a2332e6169f2add8f0b590bb22dbff Mon Sep 17 00:00:00 2001
From: David Parks <davep@lindenlab.com>
Date: Wed, 4 Nov 2009 14:19:05 +0000
Subject: Fix for crash when loading some meshes. Added button to auto-fill
 LODs.

---
 indra/newview/pipeline.cpp | 1 +
 1 file changed, 1 insertion(+)

(limited to 'indra/newview/pipeline.cpp')

diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index 7cf5cf75ad..4fc94c08bc 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -8988,6 +8988,7 @@ void LLPipeline::LLMeshThread::run()
 		{
 			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);
 		}
-- 
cgit v1.2.3


From 1c495c56c1011f4514d96b75cbcfb5a8256de78f Mon Sep 17 00:00:00 2001
From: Dave Parks <davep@lindenlab.com>
Date: Thu, 5 Nov 2009 17:12:18 -0600
Subject: Fix for crash on teleport to mesh enabled region. Fix for flashing
 meshes on LOD switch.

---
 indra/newview/pipeline.cpp | 47 ++++++++++++++++++++++++++++++++++++++++------
 1 file changed, 41 insertions(+), 6 deletions(-)

(limited to 'indra/newview/pipeline.cpp')

diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index 1a1d29ac32..4ac95fa939 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -8902,33 +8902,68 @@ LLCullResult::sg_list_t::iterator LLPipeline::endAlphaGroups()
 }
 
 
-void LLPipeline::loadMesh(LLVOVolume* volume, LLUUID mesh_id)
+void LLPipeline::loadMesh(LLVOVolume* vobj, LLUUID mesh_id, S32 detail)
 {
-
 	{
 		LLMutexLock lock(mMeshMutex);
 		//add volume to list of loading meshes
 		mesh_load_map::iterator iter = mLoadingMeshes.find(mesh_id);
 		if (iter != mLoadingMeshes.end())
 		{ //request pending for this mesh, append volume id to list
-			iter->second.insert(volume->getID());
+			iter->second.insert(vobj->getID());
 			return;
 		}
 
 		//first request for this mesh
-		mLoadingMeshes[mesh_id].insert(volume->getID());
+		mLoadingMeshes[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, volume->getVolume()));
+		mPendingMeshes.push_back(new LLMeshThread(mesh_id, vobj->getVolume()));
 	}
 	else
 	{ //fetch asset and load when done
 		gAssetStorage->getAssetData(mesh_id, LLAssetType::AT_MESH,
-									getMeshAssetCallback, volume->getVolume(), TRUE);
+									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->getNumVolumeFaces() > 0)
+				{
+					volume->copyVolumeFaces(lod);
+					group->derefLOD(lod);
+					return;
+				}
+			}
+
+			//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->getNumVolumeFaces() > 0)
+				{
+					volume->copyVolumeFaces(lod);
+					group->derefLOD(lod);
+					return;
+				}
+			}
+		}
+	}
 }
 
 //static
-- 
cgit v1.2.3


From 10069e0e13e3214ba9320fdce915440b2e12f938 Mon Sep 17 00:00:00 2001
From: Dave Parks <davep@lindenlab.com>
Date: Thu, 5 Nov 2009 19:58:10 -0600
Subject: Fix for prims all being 0 lod. Fix for dangling prim references.

---
 indra/newview/pipeline.cpp | 2 ++
 1 file changed, 2 insertions(+)

(limited to 'indra/newview/pipeline.cpp')

diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index 4ac95fa939..3554ceb7f0 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -8949,6 +8949,7 @@ void LLPipeline::loadMesh(LLVOVolume* vobj, LLUUID mesh_id, S32 detail)
 					group->derefLOD(lod);
 					return;
 				}
+				group->derefLOD(lod);
 			}
 
 			//no lower LOD is a available, is a higher lod available?
@@ -8961,6 +8962,7 @@ void LLPipeline::loadMesh(LLVOVolume* vobj, LLUUID mesh_id, S32 detail)
 					group->derefLOD(lod);
 					return;
 				}
+				group->derefLOD(lod);
 			}
 		}
 	}
-- 
cgit v1.2.3


From 4e420a36c67e611cd7d85652b43d9cd65315e563 Mon Sep 17 00:00:00 2001
From: Dave Parks <davep@lindenlab.com>
Date: Sat, 7 Nov 2009 08:22:39 -0600
Subject: Fix for missing LOD spam.

---
 indra/newview/pipeline.cpp | 2 ++
 1 file changed, 2 insertions(+)

(limited to 'indra/newview/pipeline.cpp')

diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index 3554ceb7f0..f13bb73acf 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -8949,6 +8949,7 @@ void LLPipeline::loadMesh(LLVOVolume* vobj, LLUUID mesh_id, S32 detail)
 					group->derefLOD(lod);
 					return;
 				}
+
 				group->derefLOD(lod);
 			}
 
@@ -8962,6 +8963,7 @@ void LLPipeline::loadMesh(LLVOVolume* vobj, LLUUID mesh_id, S32 detail)
 					group->derefLOD(lod);
 					return;
 				}
+
 				group->derefLOD(lod);
 			}
 		}
-- 
cgit v1.2.3


From 81bfdcbfae4f203e60f00794966383b01475995b Mon Sep 17 00:00:00 2001
From: Dave Parks <davep@lindenlab.com>
Date: Wed, 18 Nov 2009 18:10:48 -0600
Subject: Tetrahedron displays in place of unloaded mesh.  Still has some LOD
 issues.

---
 indra/newview/pipeline.cpp | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

(limited to 'indra/newview/pipeline.cpp')

diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index c262e94ff4..3410ad6559 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -8976,6 +8976,9 @@ void LLPipeline::loadMesh(LLVOVolume* vobj, LLUUID mesh_id, S32 detail)
 				group->derefLOD(lod);
 			}
 		}
+
+		//nothing found, so make a tetrahedron
+		volume->makeTetrahedron();
 	}
 }
 
@@ -9102,7 +9105,11 @@ void LLPipeline::notifyLoadedMeshes()
 
 			if (valid)
 			{
-				mesh->mTargetVolume->copyVolumeFaces(mesh->mVolume);
+				if (mesh->mVolume->getNumVolumeFaces() > 0)
+				{
+					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);
-- 
cgit v1.2.3


From 62233f22469cdc66042fc7bbbbd367dbb7212fde Mon Sep 17 00:00:00 2001
From: Dave Parks <davep@lindenlab.com>
Date: Tue, 24 Nov 2009 07:38:04 -0600
Subject: Fix for copying of tetrahedrons in place of mesh LODs. Fix for bad
 tetrahedron bounding box. Bad fix for simultaneous loading of multiple LODs.

---
 indra/newview/pipeline.cpp | 50 ++++++++++++++++++++++++++++++++++++----------
 1 file changed, 40 insertions(+), 10 deletions(-)

(limited to 'indra/newview/pipeline.cpp')

diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index 3410ad6559..0ee619244b 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -8913,23 +8913,29 @@ 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.find(mesh_id);
-		if (iter != mLoadingMeshes.end())
+		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[mesh_id].insert(vobj->getID());
+		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()));
+		mPendingMeshes.push_back(new LLMeshThread(mesh_id, vobj->getVolume(), detail));
 	}
 	else
 	{ //fetch asset and load when done
@@ -8952,7 +8958,7 @@ void LLPipeline::loadMesh(LLVOVolume* vobj, LLUUID mesh_id, S32 detail)
 			for (S32 i = detail-1; i >= 0; --i)
 			{
 				LLVolume* lod = group->refLOD(i);
-				if (lod && lod->getNumVolumeFaces() > 0)
+				if (lod && !lod->isTetrahedron() && lod->getNumVolumeFaces() > 0)
 				{
 					volume->copyVolumeFaces(lod);
 					group->derefLOD(lod);
@@ -8966,7 +8972,7 @@ void LLPipeline::loadMesh(LLVOVolume* vobj, LLUUID mesh_id, S32 detail)
 			for (S32 i = detail+1; i < 4; ++i)
 			{
 				LLVolume* lod = group->refLOD(i);
-				if (lod && lod->getNumVolumeFaces() > 0)
+				if (lod && !lod->isTetrahedron() && lod->getNumVolumeFaces() > 0)
 				{
 					volume->copyVolumeFaces(lod);
 					group->derefLOD(lod);
@@ -8976,6 +8982,10 @@ void LLPipeline::loadMesh(LLVOVolume* vobj, LLUUID mesh_id, S32 detail)
 				group->derefLOD(lod);
 			}
 		}
+		else
+		{
+			llerrs << "WTF?" << llendl;
+		}
 
 		//nothing found, so make a tetrahedron
 		volume->makeTetrahedron();
@@ -8992,12 +9002,22 @@ void LLPipeline::getMeshAssetCallback(LLVFS *vfs,
 }
 
 
-LLPipeline::LLMeshThread::LLMeshThread(LLUUID mesh_id, LLVolume* target)
+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;
 }
 
@@ -9073,6 +9093,10 @@ void LLPipeline::notifyLoadedMeshes()
 
 	for (std::list<LLMeshThread*>::iterator iter = mLoadedMeshes.begin(); iter != mLoadedMeshes.end(); ++iter)
 	{ //for each mesh done loading
+
+
+
+
 		LLMeshThread* mesh = *iter;
 		
 		if (!mesh->isStopped())
@@ -9081,10 +9105,12 @@ void LLPipeline::notifyLoadedMeshes()
 			continue;
 		}
 
+		S32 detail = mesh->mDetailIndex;
+
 		//get list of objects waiting to be notified this mesh is loaded
-		mesh_load_map::iterator obj_iter = mLoadingMeshes.find(mesh->mMeshID);
+		mesh_load_map::iterator obj_iter = mLoadingMeshes[detail].find(mesh->mMeshID);
 
-		if (mesh->mVolume && obj_iter != mLoadingMeshes.end())
+		if (mesh->mVolume && obj_iter != mLoadingMeshes[detail].end())
 		{
 			//make sure target volume is still valid
 			BOOL valid = FALSE;
@@ -9109,6 +9135,10 @@ void LLPipeline::notifyLoadedMeshes()
 				{
 					mesh->mTargetVolume->copyVolumeFaces(mesh->mVolume);
 				}
+				else
+				{
+					llwarns << "Mesh loading returned empty volume." << llendl;
+				}
 
 				for (std::set<LLUUID>::iterator vobj_iter = obj_iter->second.begin(); vobj_iter != obj_iter->second.end(); ++vobj_iter)
 				{
@@ -9120,7 +9150,7 @@ void LLPipeline::notifyLoadedMeshes()
 				}
 			}
 
-			mLoadingMeshes.erase(mesh->mMeshID);
+			mLoadingMeshes[detail].erase(mesh->mMeshID);
 		}
 
 		delete mesh;
-- 
cgit v1.2.3


From 6d66910c6e2fbb25bf8b5c7b90e795f350342104 Mon Sep 17 00:00:00 2001
From: Dave Parks <davep@lindenlab.com>
Date: Wed, 25 Nov 2009 11:35:41 -0600
Subject: Fix for spam on invalid mesh asset. Fix for index buffer overflow
 spam and crash in llvertexbuffer.

---
 indra/newview/pipeline.cpp | 18 ++++++------------
 1 file changed, 6 insertions(+), 12 deletions(-)

(limited to 'indra/newview/pipeline.cpp')

diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index 0ee619244b..af3a35615c 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -1807,8 +1807,6 @@ void LLPipeline::rebuildPriorityGroups()
 	
 	assertInitialized();
 
-	notifyLoadedMeshes();
-
 	// Iterate through all drawables on the priority build queue,
 	for (LLSpatialGroup::sg_list_t::iterator iter = mGroupQ1.begin();
 		 iter != mGroupQ1.end(); ++iter)
@@ -1888,6 +1886,8 @@ 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();)
@@ -8913,7 +8913,6 @@ LLCullResult::sg_list_t::iterator LLPipeline::endAlphaGroups()
 
 void LLPipeline::loadMesh(LLVOVolume* vobj, LLUUID mesh_id, S32 detail)
 {
-
 	if (detail < 0 || detail > 4)
 	{
 		return;
@@ -9093,10 +9092,6 @@ void LLPipeline::notifyLoadedMeshes()
 
 	for (std::list<LLMeshThread*>::iterator iter = mLoadedMeshes.begin(); iter != mLoadedMeshes.end(); ++iter)
 	{ //for each mesh done loading
-
-
-
-
 		LLMeshThread* mesh = *iter;
 		
 		if (!mesh->isStopped())
@@ -9131,14 +9126,13 @@ void LLPipeline::notifyLoadedMeshes()
 
 			if (valid)
 			{
-				if (mesh->mVolume->getNumVolumeFaces() > 0)
-				{
-					mesh->mTargetVolume->copyVolumeFaces(mesh->mVolume);
-				}
-				else
+				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)
 				{
-- 
cgit v1.2.3


From 695969c77066de5032bdc9caefecf9b32b076b2f Mon Sep 17 00:00:00 2001
From: Dave Parks <davep@lindenlab.com>
Date: Fri, 11 Dec 2009 14:47:11 -0600
Subject: HTTP Mesh fetch FTW.. still busted

---
 indra/newview/pipeline.cpp | 255 +--------------------------------------------
 1 file changed, 4 insertions(+), 251 deletions(-)

(limited to 'indra/newview/pipeline.cpp')

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;
-}
-
-- 
cgit v1.2.3


From c6aaf115ade4b335df9ca479992b08e028ffd910 Mon Sep 17 00:00:00 2001
From: Dave Parks <davep@lindenlab.com>
Date: Wed, 16 Dec 2009 09:26:53 -0600
Subject: Quick 'n dirty prioritization scheme for mesh loading. Sprinkling of
 fast timers in areas that are likely to stall.

---
 indra/newview/pipeline.cpp | 27 ++++++++++++++++++++-------
 1 file changed, 20 insertions(+), 7 deletions(-)

(limited to 'indra/newview/pipeline.cpp')

diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index b37645d2de..cac266a683 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -1143,9 +1143,15 @@ void LLPipeline::allocDrawable(LLViewerObject *vobj)
 }
 
 
+static LLFastTimer::DeclareTimer FTM_UNLINK("Unlink");
+static LLFastTimer::DeclareTimer FTM_REMOVE_FROM_MOVE_LIST("Movelist");
+static LLFastTimer::DeclareTimer FTM_REMOVE_FROM_SPATIAL_PARTITION("Spatial Partition");
+static LLFastTimer::DeclareTimer FTM_REMOVE_FROM_LIGHT_SET("Light Set");
+static LLFastTimer::DeclareTimer FTM_REMOVE_FROM_HIGHLIGHT_SET("Highlight Set");
+
 void LLPipeline::unlinkDrawable(LLDrawable *drawable)
 {
-	LLFastTimer t(FTM_PIPELINE);
+	LLFastTimer t(FTM_UNLINK);
 
 	assertInitialized();
 
@@ -1154,6 +1160,7 @@ void LLPipeline::unlinkDrawable(LLDrawable *drawable)
 	// Based on flags, remove the drawable from the queues that it's on.
 	if (drawablep->isState(LLDrawable::ON_MOVE_LIST))
 	{
+		LLFastTimer t(FTM_REMOVE_FROM_MOVE_LIST);
 		LLDrawable::drawable_vector_t::iterator iter = std::find(mMovedList.begin(), mMovedList.end(), drawablep);
 		if (iter != mMovedList.end())
 		{
@@ -1163,6 +1170,7 @@ void LLPipeline::unlinkDrawable(LLDrawable *drawable)
 
 	if (drawablep->getSpatialGroup())
 	{
+		LLFastTimer t(FTM_REMOVE_FROM_SPATIAL_PARTITION);
 		if (!drawablep->getSpatialGroup()->mSpatialPartition->remove(drawablep, drawablep->getSpatialGroup()))
 		{
 #ifdef LL_RELEASE_FOR_DOWNLOAD
@@ -1173,18 +1181,23 @@ void LLPipeline::unlinkDrawable(LLDrawable *drawable)
 		}
 	}
 
-	mLights.erase(drawablep);
-	for (light_set_t::iterator iter = mNearbyLights.begin();
-				iter != mNearbyLights.end(); iter++)
 	{
-		if (iter->drawable == drawablep)
+		LLFastTimer t(FTM_REMOVE_FROM_LIGHT_SET);
+		mLights.erase(drawablep);
+
+		for (light_set_t::iterator iter = mNearbyLights.begin();
+					iter != mNearbyLights.end(); iter++)
 		{
-			mNearbyLights.erase(iter);
-			break;
+			if (iter->drawable == drawablep)
+			{
+				mNearbyLights.erase(iter);
+				break;
+			}
 		}
 	}
 
 	{
+		LLFastTimer t(FTM_REMOVE_FROM_HIGHLIGHT_SET);
 		HighlightItem item(drawablep);
 		mHighlightSet.erase(item);
 
-- 
cgit v1.2.3


From c3b37faba3cba425d749345a978ddec16bbd1338 Mon Sep 17 00:00:00 2001
From: Tofu Linden <tofu.linden@lindenlab.com>
Date: Thu, 28 Jan 2010 16:20:06 -0800
Subject: first dribble of directional lights for shaderless path.

---
 indra/newview/pipeline.cpp | 19 ++++++++++++++++---
 1 file changed, 16 insertions(+), 3 deletions(-)

(limited to 'indra/newview/pipeline.cpp')

diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index d66662ed49..bced8a8e07 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -4596,8 +4596,22 @@ void LLPipeline::setupHWLights(LLDrawPool* pool)
 			glLightf (gllight, GL_CONSTANT_ATTENUATION,   0.0f);
 			glLightf (gllight, GL_LINEAR_ATTENUATION,     atten);
 			glLightf (gllight, GL_QUADRATIC_ATTENUATION,  quad);
-			glLightf (gllight, GL_SPOT_EXPONENT,          0.0f);
-			glLightf (gllight, GL_SPOT_CUTOFF,            180.0f);
+			if (light->getLightTexture()) // directional (spot-)light
+			{
+				LLVector3 spotparams = light->getSpotLightParams();
+				LLQuaternion quat = light->getRenderRotation();
+				LLVector3 at_axis(0,0,-1); // todo: verify against deferred
+				at_axis *= quat;
+				llinfos << "SPOT!!!!!!! fov: " << spotparams.mV[0] << " focus: " << spotparams.mV[1] << " dir: " << at_axis << llendl;
+				glLightfv(gllight, GL_SPOT_DIRECTION, at_axis.mV);
+				glLightf (gllight, GL_SPOT_EXPONENT,  0.0f); // fixme - focus
+				glLightf (gllight, GL_SPOT_CUTOFF,    22.0f); // fixme - fov
+			}
+			else // omnidirectional (point) light
+			{
+				glLightf (gllight, GL_SPOT_EXPONENT, 0.0f);
+				glLightf (gllight, GL_SPOT_CUTOFF,   180.0f);
+			}
 			cur_light++;
 			if (cur_light >= 8)
 			{
@@ -4613,7 +4627,6 @@ void LLPipeline::setupHWLights(LLDrawPool* pool)
 		glLightfv(gllight, GL_AMBIENT,  LLColor4::black.mV);
 		glLightfv(gllight, GL_SPECULAR, LLColor4::black.mV);
 	}
-
 	if (gAgent.getAvatarObject() &&
 		gAgent.getAvatarObject()->mSpecialRenderMode == 3)
 	{
-- 
cgit v1.2.3


From cf3df7968ef654ba7cafeafd463e7107b80ca07f Mon Sep 17 00:00:00 2001
From: Tofu Linden <tofu.linden@lindenlab.com>
Date: Thu, 28 Jan 2010 18:21:33 -0800
Subject: woo, dumb GL lights now match up to our dumb shader model pretty
 well.

next: shader model needs to grok point vs directional, shader model needs to resurrect ambient which I seem to have broken
---
 indra/newview/pipeline.cpp | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

(limited to 'indra/newview/pipeline.cpp')

diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index bced8a8e07..71f9ce7eb2 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -4284,7 +4284,7 @@ void LLPipeline::setupAvatarLights(BOOL for_edit)
 		glLightf (GL_LIGHT1, GL_LINEAR_ATTENUATION, 	 0.0f);
 		glLightf (GL_LIGHT1, GL_QUADRATIC_ATTENUATION, 0.0f);
 		glLightf (GL_LIGHT1, GL_SPOT_EXPONENT, 		 0.0f);
-		glLightf (GL_LIGHT1, GL_SPOT_CUTOFF, 			 180.0f);
+		glLightf (GL_LIGHT1, GL_SPOT_CUTOFF,		 180.0f);
 	}
 	else if (gAvatarBacklight) // Always true (unless overridden in a devs .ini)
 	{
@@ -4600,12 +4600,12 @@ void LLPipeline::setupHWLights(LLDrawPool* pool)
 			{
 				LLVector3 spotparams = light->getSpotLightParams();
 				LLQuaternion quat = light->getRenderRotation();
-				LLVector3 at_axis(0,0,-1); // todo: verify against deferred
+				LLVector3 at_axis(0,0,-1); // this matches deferred rendering's object light direction
 				at_axis *= quat;
 				llinfos << "SPOT!!!!!!! fov: " << spotparams.mV[0] << " focus: " << spotparams.mV[1] << " dir: " << at_axis << llendl;
 				glLightfv(gllight, GL_SPOT_DIRECTION, at_axis.mV);
-				glLightf (gllight, GL_SPOT_EXPONENT,  0.0f); // fixme - focus
-				glLightf (gllight, GL_SPOT_CUTOFF,    22.0f); // fixme - fov
+				glLightf (gllight, GL_SPOT_EXPONENT,  1.0f); // 1.0 = good old dot product
+				glLightf (gllight, GL_SPOT_CUTOFF,    90.0f); // hemisphere
 			}
 			else // omnidirectional (point) light
 			{
-- 
cgit v1.2.3


From f773b6ef9669bab6765678f8b07831144dd44a5e Mon Sep 17 00:00:00 2001
From: Tofu Linden <tofu.linden@lindenlab.com>
Date: Thu, 28 Jan 2010 18:50:10 -0800
Subject: cheaply resurrect the difference between spotlight and
 omnidirectional, as far as the shader is concerned.

not complete.
---
 indra/newview/pipeline.cpp | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

(limited to 'indra/newview/pipeline.cpp')

diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index 71f9ce7eb2..6cd8b94405 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -4592,7 +4592,6 @@ void LLPipeline::setupHWLights(LLDrawPool* pool)
 			glLightfv(gllight, GL_POSITION, light_pos_gl.mV);
 			glLightfv(gllight, GL_DIFFUSE,  light_color.mV);
 			glLightfv(gllight, GL_AMBIENT,  LLColor4::black.mV);
-			glLightfv(gllight, GL_SPECULAR, LLColor4::black.mV);
 			glLightf (gllight, GL_CONSTANT_ATTENUATION,   0.0f);
 			glLightf (gllight, GL_LINEAR_ATTENUATION,     atten);
 			glLightf (gllight, GL_QUADRATIC_ATTENUATION,  quad);
@@ -4606,11 +4605,16 @@ void LLPipeline::setupHWLights(LLDrawPool* pool)
 				glLightfv(gllight, GL_SPOT_DIRECTION, at_axis.mV);
 				glLightf (gllight, GL_SPOT_EXPONENT,  1.0f); // 1.0 = good old dot product
 				glLightf (gllight, GL_SPOT_CUTOFF,    90.0f); // hemisphere
+				glLightfv(gllight, GL_SPECULAR, LLColor4::black.mV);
 			}
 			else // omnidirectional (point) light
 			{
 				glLightf (gllight, GL_SPOT_EXPONENT, 0.0f);
 				glLightf (gllight, GL_SPOT_CUTOFF,   180.0f);
+
+				// we use specular.w = 1.0 as a cheap hack for the shaders to know that this is omnidirectional rather than a spotlight
+				const float specular = {0.f, 0.f, 0.f, 1.f},
+				glLightfv(gllight, GL_SPECULAR, LLColor4::black.mV);
 			}
 			cur_light++;
 			if (cur_light >= 8)
-- 
cgit v1.2.3


From bc0a9fd5fe0675d7327ee182ff4ac20c39e76305 Mon Sep 17 00:00:00 2001
From: Tofu Linden <tofu.linden@lindenlab.com>
Date: Thu, 28 Jan 2010 21:48:22 -0800
Subject: getting closer to point/spot interchangability

---
 indra/newview/pipeline.cpp | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

(limited to 'indra/newview/pipeline.cpp')

diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index 6cd8b94405..e12412c58c 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -4613,8 +4613,8 @@ void LLPipeline::setupHWLights(LLDrawPool* pool)
 				glLightf (gllight, GL_SPOT_CUTOFF,   180.0f);
 
 				// we use specular.w = 1.0 as a cheap hack for the shaders to know that this is omnidirectional rather than a spotlight
-				const float specular = {0.f, 0.f, 0.f, 1.f},
-				glLightfv(gllight, GL_SPECULAR, LLColor4::black.mV);
+				const float specular[] = {0.f, 0.f, 0.f, 1.f};
+				glLightfv(gllight, GL_SPECULAR, specular);
 			}
 			cur_light++;
 			if (cur_light >= 8)
-- 
cgit v1.2.3


From fcaca49a9496154419a8f44c17cba16b028d3518 Mon Sep 17 00:00:00 2001
From: Tofu Linden <tofu.linden@lindenlab.com>
Date: Thu, 28 Jan 2010 23:58:50 -0800
Subject: cheap no-branch goodness for rendering both spotlights and
 pointlights with the same shader code.

kill already-nerfed quadratic attenuation which it seems we won't be supporting any decade soon.
---
 indra/newview/pipeline.cpp | 42 +++++++++++++++---------------------------
 1 file changed, 15 insertions(+), 27 deletions(-)

(limited to 'indra/newview/pipeline.cpp')

diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index e12412c58c..2ad0bad11f 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -4572,40 +4572,30 @@ void LLPipeline::setupHWLights(LLDrawPool* pool)
 			LLVector4 light_pos_gl(light_pos, 1.0f);
 	
 			F32 light_radius = llmax(light->getLightRadius(), 0.001f);
-			F32 atten, quad;
 
-#if 0 //1.9.1
-			if (pool->getVertexShaderLevel() > 0)
-			{
-				atten = light_radius;
-				quad = llmax(light->getLightFalloff(), 0.0001f);
-			}
-			else
-#endif
-			{
-				F32 x = (3.f * (1.f + light->getLightFalloff()));
-				atten = x / (light_radius); // % of brightness at radius
-				quad = 0.0f;
-			}
+			F32 x = (3.f * (1.f + light->getLightFalloff()));
+			float linatten = x / (light_radius); // % of brightness at radius
+
 			mHWLightColors[cur_light] = light_color;
 			S32 gllight = GL_LIGHT0+cur_light;
 			glLightfv(gllight, GL_POSITION, light_pos_gl.mV);
 			glLightfv(gllight, GL_DIFFUSE,  light_color.mV);
 			glLightfv(gllight, GL_AMBIENT,  LLColor4::black.mV);
 			glLightf (gllight, GL_CONSTANT_ATTENUATION,   0.0f);
-			glLightf (gllight, GL_LINEAR_ATTENUATION,     atten);
-			glLightf (gllight, GL_QUADRATIC_ATTENUATION,  quad);
+			glLightf (gllight, GL_LINEAR_ATTENUATION,     linatten);
+			glLightf (gllight, GL_QUADRATIC_ATTENUATION,  0.0f);
 			if (light->getLightTexture()) // directional (spot-)light
 			{
 				LLVector3 spotparams = light->getSpotLightParams();
 				LLQuaternion quat = light->getRenderRotation();
 				LLVector3 at_axis(0,0,-1); // this matches deferred rendering's object light direction
 				at_axis *= quat;
-				llinfos << "SPOT!!!!!!! fov: " << spotparams.mV[0] << " focus: " << spotparams.mV[1] << " dir: " << at_axis << llendl;
+				//llinfos << "SPOT!!!!!!! fov: " << spotparams.mV[0] << " focus: " << spotparams.mV[1] << " dir: " << at_axis << llendl;
 				glLightfv(gllight, GL_SPOT_DIRECTION, at_axis.mV);
-				glLightf (gllight, GL_SPOT_EXPONENT,  1.0f); // 1.0 = good old dot product
+				glLightf (gllight, GL_SPOT_EXPONENT,  2.0f); // 2.0 = good old dot product ^ 2
 				glLightf (gllight, GL_SPOT_CUTOFF,    90.0f); // hemisphere
-				glLightfv(gllight, GL_SPECULAR, LLColor4::black.mV);
+				const float specular[] = {0.f, 0.f, 0.f, 0.f};
+				glLightfv(gllight, GL_SPECULAR, specular);
 			}
 			else // omnidirectional (point) light
 			{
@@ -4615,6 +4605,7 @@ void LLPipeline::setupHWLights(LLDrawPool* pool)
 				// we use specular.w = 1.0 as a cheap hack for the shaders to know that this is omnidirectional rather than a spotlight
 				const float specular[] = {0.f, 0.f, 0.f, 1.f};
 				glLightfv(gllight, GL_SPECULAR, specular);
+				//llinfos << "boring light" << llendl;
 			}
 			cur_light++;
 			if (cur_light >= 8)
@@ -4641,13 +4632,10 @@ void LLPipeline::setupHWLights(LLDrawPool* pool)
 		LLVector4 light_pos_gl(light_pos, 1.0f);
 
 		F32 light_radius = 16.f;
-		F32 atten, quad;
 
-		{
-			F32 x = 3.f;
-			atten = x / (light_radius); // % of brightness at radius
-			quad = 0.0f;
-		}
+		F32 x = 3.f;
+		float linatten = x / (light_radius); // % of brightness at radius
+
 		mHWLightColors[2] = light_color;
 		S32 gllight = GL_LIGHT2;
 		glLightfv(gllight, GL_POSITION, light_pos_gl.mV);
@@ -4655,8 +4643,8 @@ void LLPipeline::setupHWLights(LLDrawPool* pool)
 		glLightfv(gllight, GL_AMBIENT,  LLColor4::black.mV);
 		glLightfv(gllight, GL_SPECULAR, LLColor4::black.mV);
 		glLightf (gllight, GL_CONSTANT_ATTENUATION,   0.0f);
-		glLightf (gllight, GL_LINEAR_ATTENUATION,     atten);
-		glLightf (gllight, GL_QUADRATIC_ATTENUATION,  quad);
+		glLightf (gllight, GL_LINEAR_ATTENUATION,     linatten);
+		glLightf (gllight, GL_QUADRATIC_ATTENUATION,  0.0f);
 		glLightf (gllight, GL_SPOT_EXPONENT,          0.0f);
 		glLightf (gllight, GL_SPOT_CUTOFF,            180.0f);
 	}
-- 
cgit v1.2.3


From e8899c4f4c2ae95f108b9bbf543e401debc9c588 Mon Sep 17 00:00:00 2001
From: Tofu Linden <tofu.linden@lindenlab.com>
Date: Mon, 1 Feb 2010 17:29:08 +0000
Subject: start to abstract-out the 'is a spotlight' question so one day we can
 perhaps make the UI hurt less.

---
 indra/newview/pipeline.cpp | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

(limited to 'indra/newview/pipeline.cpp')

diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index 2ad0bad11f..cb0baf77f1 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -4584,7 +4584,7 @@ void LLPipeline::setupHWLights(LLDrawPool* pool)
 			glLightf (gllight, GL_CONSTANT_ATTENUATION,   0.0f);
 			glLightf (gllight, GL_LINEAR_ATTENUATION,     linatten);
 			glLightf (gllight, GL_QUADRATIC_ATTENUATION,  0.0f);
-			if (light->getLightTexture()) // directional (spot-)light
+			if (light->isLightSpotlight()) // directional (spot-)light
 			{
 				LLVector3 spotparams = light->getSpotLightParams();
 				LLQuaternion quat = light->getRenderRotation();
@@ -6693,7 +6693,7 @@ void LLPipeline::renderDeferredLighting()
 					{ //draw box if camera is outside box
 						if (render_local)
 						{
-							if (volume->getLightTexture())
+							if (volume->isLightSpotlight())
 							{
 								drawablep->getVOVolume()->updateSpotLightPriority();
 								spot_lights.push_back(drawablep);
@@ -6710,7 +6710,7 @@ void LLPipeline::renderDeferredLighting()
 					}
 					else if (render_fullscreen)
 					{	
-						if (volume->getLightTexture())
+						if (volume->isLightSpotlight())
 						{
 							drawablep->getVOVolume()->updateSpotLightPriority();
 							fullscreen_spot_lights.push_back(drawablep);
-- 
cgit v1.2.3


From 3dc32880ae0f2f0f5499a7f271df666759fc220a Mon Sep 17 00:00:00 2001
From: Tofu Linden <tofu.linden@lindenlab.com>
Date: Mon, 1 Feb 2010 17:50:55 +0000
Subject: const fix.

---
 indra/newview/pipeline.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'indra/newview/pipeline.cpp')

diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index cb0baf77f1..b25c7c9212 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -4573,7 +4573,7 @@ void LLPipeline::setupHWLights(LLDrawPool* pool)
 	
 			F32 light_radius = llmax(light->getLightRadius(), 0.001f);
 
-			F32 x = (3.f * (1.f + light->getLightFalloff()));
+			F32 x = (3.f * (1.f + light->getLightFalloff())); // why this magic?  probably trying to match a historic behavior.
 			float linatten = x / (light_radius); // % of brightness at radius
 
 			mHWLightColors[cur_light] = light_color;
-- 
cgit v1.2.3


From 095a5e84408b47ef3c5610e111aefe51d77633ca Mon Sep 17 00:00:00 2001
From: Dave Parks <davep@lindenlab.com>
Date: Sat, 6 Feb 2010 17:33:12 -0600
Subject: Draw prims using triangle strips instead of triangle lists.

---
 indra/newview/pipeline.cpp | 15 ++++++++++++++-
 1 file changed, 14 insertions(+), 1 deletion(-)

(limited to 'indra/newview/pipeline.cpp')

diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index d5f87b73fe..91da9e39e0 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -270,6 +270,7 @@ BOOL	LLPipeline::sDelayVBUpdate = TRUE;
 BOOL	LLPipeline::sFastAlpha = TRUE;
 BOOL	LLPipeline::sDisableShaders = FALSE;
 BOOL	LLPipeline::sRenderBump = TRUE;
+BOOL	LLPipeline::sUseTriStrips = TRUE;
 BOOL	LLPipeline::sUseFarClip = TRUE;
 BOOL	LLPipeline::sShadowRender = FALSE;
 BOOL	LLPipeline::sWaterReflections = FALSE;
@@ -358,6 +359,7 @@ void LLPipeline::init()
 
 	sDynamicLOD = gSavedSettings.getBOOL("RenderDynamicLOD");
 	sRenderBump = gSavedSettings.getBOOL("RenderObjectBump");
+	sUseTriStrips = gSavedSettings.getBOOL("RenderUseTriStrips");
 	sRenderAttachedLights = gSavedSettings.getBOOL("RenderAttachedLights");
 	sRenderAttachedParticles = gSavedSettings.getBOOL("RenderAttachedParticles");
 
@@ -3495,9 +3497,19 @@ void LLPipeline::renderGeomShadow(LLCamera& camera)
 }
 
 
-void LLPipeline::addTrianglesDrawn(S32 count)
+void LLPipeline::addTrianglesDrawn(S32 index_count, U32 render_type)
 {
 	assertInitialized();
+	S32 count = 0;
+	if (render_type == LLRender::TRIANGLE_STRIP)
+	{
+		count = index_count-2;
+	}
+	else
+	{
+		count = index_count/3;
+	}
+
 	mTrianglesDrawn += count;
 	mBatchCount++;
 	mMaxBatchSize = llmax(mMaxBatchSize, count);
@@ -5349,6 +5361,7 @@ void LLPipeline::resetVertexBuffers(LLDrawable* drawable)
 void LLPipeline::resetVertexBuffers()
 {
 	sRenderBump = gSavedSettings.getBOOL("RenderObjectBump");
+	sUseTriStrips = gSavedSettings.getBOOL("RenderUseTriStrips");
 
 	for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); 
 			iter != LLWorld::getInstance()->getRegionList().end(); ++iter)
-- 
cgit v1.2.3


From e09822153e135e8fc89f6fdb3338bb9e8e5b6132 Mon Sep 17 00:00:00 2001
From: Tofu Linden <tofu.linden@lindenlab.com>
Date: Thu, 18 Feb 2010 15:52:49 +0000
Subject: EXT-5389 Unreadable resident names with glow.

An alternative fix just for render-pipeline.
This is here instead of the trunk because it's cosmetically less good, and codewise a little weirder, and slightly (unmeasurably?) less performant.

But its advantage over the trunk fix is, it's still Z-buffered when FBOs are turned on.  Which we really care about on render-pipeline.
---
 indra/newview/pipeline.cpp | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

(limited to 'indra/newview/pipeline.cpp')

diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index 559ae83182..3a37ce8fbb 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -2794,9 +2794,6 @@ void render_hud_elements()
 		LLWorld::getInstance()->renderPropertyLines();
 		LLViewerParcelMgr::getInstance()->render();
 		LLViewerParcelMgr::getInstance()->renderParcelCollision();
-	
-		// Render name tags.
-		LLHUDObject::renderAll();
 	}
 	else if (gForceRenderLandFence)
 	{
@@ -3200,8 +3197,10 @@ void LLPipeline::renderGeom(LLCamera& camera, BOOL forceVBOUpdate)
 	if (!LLPipeline::sReflectionRender && !LLPipeline::sRenderDeferred && gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI))
 	{
 		// Render debugging beacons.
-		gObjectList.renderObjectBeacons();
+		gObjectList.renderObjectBeacons();	
 		gObjectList.resetObjectBeacons();
+		// Render name tags
+		LLHUDObject::renderAll();
 	}
 
 	LLAppViewer::instance()->pingMainloopTimeout("Pipeline:RenderGeomEnd");
@@ -6923,6 +6922,8 @@ void LLPipeline::renderDeferredLighting()
 			// Render debugging beacons.
 			gObjectList.renderObjectBeacons();
 			gObjectList.resetObjectBeacons();
+			// Render name tags
+			LLHUDObject::renderAll();
 		}
 	}
 
-- 
cgit v1.2.3


From dc7db357ac4e50f2d1e0d47fd50fd712f67dffe6 Mon Sep 17 00:00:00 2001
From: Tofu Linden <tofu.linden@lindenlab.com>
Date: Thu, 18 Feb 2010 16:49:45 +0000
Subject: Backed out changeset 83d7019fda75

backing-out render-pipeline-specific version of EXT-5389 fix because it just doesn't reliably work right.
---
 indra/newview/pipeline.cpp | 9 ++++-----
 1 file changed, 4 insertions(+), 5 deletions(-)

(limited to 'indra/newview/pipeline.cpp')

diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index 3a37ce8fbb..559ae83182 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -2794,6 +2794,9 @@ void render_hud_elements()
 		LLWorld::getInstance()->renderPropertyLines();
 		LLViewerParcelMgr::getInstance()->render();
 		LLViewerParcelMgr::getInstance()->renderParcelCollision();
+	
+		// Render name tags.
+		LLHUDObject::renderAll();
 	}
 	else if (gForceRenderLandFence)
 	{
@@ -3197,10 +3200,8 @@ void LLPipeline::renderGeom(LLCamera& camera, BOOL forceVBOUpdate)
 	if (!LLPipeline::sReflectionRender && !LLPipeline::sRenderDeferred && gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI))
 	{
 		// Render debugging beacons.
-		gObjectList.renderObjectBeacons();	
+		gObjectList.renderObjectBeacons();
 		gObjectList.resetObjectBeacons();
-		// Render name tags
-		LLHUDObject::renderAll();
 	}
 
 	LLAppViewer::instance()->pingMainloopTimeout("Pipeline:RenderGeomEnd");
@@ -6922,8 +6923,6 @@ void LLPipeline::renderDeferredLighting()
 			// Render debugging beacons.
 			gObjectList.renderObjectBeacons();
 			gObjectList.resetObjectBeacons();
-			// Render name tags
-			LLHUDObject::renderAll();
 		}
 	}
 
-- 
cgit v1.2.3


From b414b5067e3e47da7d9baf490d94534b4c65a8eb Mon Sep 17 00:00:00 2001
From: Dave Parks <davep@lindenlab.com>
Date: Sun, 28 Feb 2010 16:40:30 -0600
Subject: Remove some dead code. Add LH transform to LLVector3 Add
 DebugShowUploadCost Make LOD generation on model preview less finnicky.
 Remove error level based LOD generation. Better framing of model before
 upload. Better error handling for model uploader. Remove [COST] argument from
 model upload menu item. Remove L$ check from model upload menu item being
 enabled.

---
 indra/newview/pipeline.cpp | 57 ++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 57 insertions(+)

(limited to 'indra/newview/pipeline.cpp')

diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index 559ae83182..43b2104135 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -3553,6 +3553,63 @@ void LLPipeline::renderDebug()
 		}
 	}
 
+	if (gSavedSettings.getBOOL("DebugShowUploadCost"))
+	{
+		std::set<LLUUID> textures;
+		std::set<LLUUID> sculpts;
+		std::set<LLUUID> meshes;
+		
+		BOOL selected = TRUE;
+		if (LLSelectMgr::getInstance()->getSelection()->isEmpty())
+		{
+			selected = FALSE;
+		}
+			
+		for (LLCullResult::sg_list_t::iterator iter = sCull->beginVisibleGroups(); iter != sCull->endVisibleGroups(); ++iter)
+		{
+			LLSpatialGroup* group = *iter;
+			LLSpatialGroup::OctreeNode* node = group->mOctreeNode;
+			for (LLSpatialGroup::OctreeNode::element_iter elem = node->getData().begin(); elem != node->getData().end(); ++elem)
+			{
+				LLDrawable* drawable = *elem;
+				LLVOVolume* volume = drawable->getVOVolume();
+				if (volume && volume->isSelected() == selected)
+				{
+					for (U32 i = 0; i < volume->getNumTEs(); ++i)
+					{
+						LLTextureEntry* te = volume->getTE(i);
+						textures.insert(te->getID());
+					}
+
+					if (volume->isSculpted())
+					{
+						LLUUID sculpt_id = volume->getVolume()->getParams().getSculptID();
+						if (volume->isMesh())
+						{
+							meshes.insert(sculpt_id);
+						}
+						else
+						{
+							sculpts.insert(sculpt_id);
+						}
+					}
+				}
+			}
+		}
+
+		gPipeline.mDebugTextureUploadCost = textures.size() * 10;
+		gPipeline.mDebugSculptUploadCost = sculpts.size()*10;
+		
+		U32 mesh_cost = 0;
+
+		for (std::set<LLUUID>::iterator iter = meshes.begin(); iter != meshes.end(); ++iter)
+		{
+			mesh_cost += gMeshRepo.getResourceCost(*iter)*10;
+		}
+
+		gPipeline.mDebugMeshUploadCost = mesh_cost;
+	}
+
 	for (LLCullResult::bridge_list_t::const_iterator i = sCull->beginVisibleBridge(); i != sCull->endVisibleBridge(); ++i)
 	{
 		LLSpatialBridge* bridge = *i;
-- 
cgit v1.2.3


From ea6397fe4990b73e190391d61781c609fbd1f8c1 Mon Sep 17 00:00:00 2001
From: Dave Parks <davep@lindenlab.com>
Date: Thu, 4 Mar 2010 15:30:15 -0600
Subject: Optimiziation pass. Added RenderUseStreamVBO to enable/disable usage
 of VBO's for streaming buffers. Faster traversal of LLCullResult members.
 Removal of llpushcallstacks from inner loops. Sprinkling in fast timers.

---
 indra/newview/pipeline.cpp | 21 +++++++++++++++++----
 1 file changed, 17 insertions(+), 4 deletions(-)

(limited to 'indra/newview/pipeline.cpp')

diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index 43b2104135..eb3ad95586 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -362,6 +362,7 @@ void LLPipeline::init()
 	sDynamicLOD = gSavedSettings.getBOOL("RenderDynamicLOD");
 	sRenderBump = gSavedSettings.getBOOL("RenderObjectBump");
 	sUseTriStrips = gSavedSettings.getBOOL("RenderUseTriStrips");
+	LLVertexBuffer::sUseStreamDraw = gSavedSettings.getBOOL("RenderUseStreamVBO");
 	sRenderAttachedLights = gSavedSettings.getBOOL("RenderAttachedLights");
 	sRenderAttachedParticles = gSavedSettings.getBOOL("RenderAttachedParticles");
 
@@ -1739,8 +1740,12 @@ void LLPipeline::markOccluder(LLSpatialGroup* group)
 	}
 }
 
+static LLFastTimer::DeclareTimer FTM_DO_OCCLUSION("Do Occlusion");
+
 void LLPipeline::doOcclusion(LLCamera& camera)
 {
+	LLFastTimer t(FTM_DO_OCCLUSION);
+
 	LLVertexBuffer::unbind();
 
 	if (hasRenderDebugMask(LLPipeline::RENDER_DEBUG_OCCLUSION))
@@ -1816,7 +1821,6 @@ void LLPipeline::rebuildPriorityGroups()
 		
 void LLPipeline::rebuildGroups()
 {
-	llpushcallstacks ;
 	// Iterate through some drawables on the non-priority build queue
 	S32 size = (S32) mGroupQ2.size();
 	S32 min_count = llclamp((S32) ((F32) (size * size)/4096*0.25f), 1, size);
@@ -1961,9 +1965,13 @@ void LLPipeline::updateGeom(F32 max_dtime)
 	updateMovedList(mMovedBridge);
 }
 
+static LLFastTimer::DeclareTimer FTM_MARK_VISIBLE("Mark Visible");
+
 void LLPipeline::markVisible(LLDrawable *drawablep, LLCamera& camera)
 {
 	LLMemType mt(LLMemType::MTYPE_PIPELINE_MARK_VISIBLE);
+	LLFastTimer t(FTM_MARK_VISIBLE);
+
 	if(!drawablep || drawablep->isDead())
 	{
 		return;
@@ -4704,8 +4712,12 @@ void LLPipeline::setupHWLights(LLDrawPool* pool)
 	mLightMask = 0;
 }
 
+static LLFastTimer::DeclareTimer FTM_ENABLE_LIGHTS("Enable Lights");
+
 void LLPipeline::enableLights(U32 mask)
 {
+	LLFastTimer ftm(FTM_ENABLE_LIGHTS);
+
 	assertInitialized();
 
 	if (mLightingDetail == 0)
@@ -4813,16 +4825,16 @@ void LLPipeline::enableLightsFullbright(const LLColor4& color)
 	enableLights(mask);
 
 	glLightModelfv(GL_LIGHT_MODEL_AMBIENT,color.mV);
-	if (mLightingDetail >= 2)
+	/*if (mLightingDetail >= 2)
 	{
 		glColor4f(0.f, 0.f, 0.f, 1.f); // no local lighting by default
-	}
+	}*/
 }
 
 void LLPipeline::disableLights()
 {
 	enableLights(0); // no lighting (full bright)
-	glColor4f(1.f, 1.f, 1.f, 1.f); // lighting color = white by default
+	//glColor4f(1.f, 1.f, 1.f, 1.f); // lighting color = white by default
 }
 
 //============================================================================
@@ -5425,6 +5437,7 @@ void LLPipeline::resetVertexBuffers()
 {
 	sRenderBump = gSavedSettings.getBOOL("RenderObjectBump");
 	sUseTriStrips = gSavedSettings.getBOOL("RenderUseTriStrips");
+	LLVertexBuffer::sUseStreamDraw = gSavedSettings.getBOOL("RenderUseStreamVBO");
 
 	for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); 
 			iter != LLWorld::getInstance()->getRegionList().end(); ++iter)
-- 
cgit v1.2.3


From 3ea01fb66e75ec6da1cee994da37ef461af66a48 Mon Sep 17 00:00:00 2001
From: Dave Parks <davep@lindenlab.com>
Date: Fri, 5 Mar 2010 10:49:05 -0600
Subject: Remove some fast timers that were being futzy.

---
 indra/newview/pipeline.cpp | 13 ++-----------
 1 file changed, 2 insertions(+), 11 deletions(-)

(limited to 'indra/newview/pipeline.cpp')

diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index eb3ad95586..e65c8b9af8 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -511,6 +511,7 @@ void LLPipeline::destroyGL()
 }
 
 static LLFastTimer::DeclareTimer FTM_RESIZE_SCREEN_TEXTURE("Resize Screen Texture");
+
 void LLPipeline::resizeScreenTexture()
 {
 	LLFastTimer ft(FTM_RESIZE_SCREEN_TEXTURE);
@@ -1740,12 +1741,8 @@ void LLPipeline::markOccluder(LLSpatialGroup* group)
 	}
 }
 
-static LLFastTimer::DeclareTimer FTM_DO_OCCLUSION("Do Occlusion");
-
 void LLPipeline::doOcclusion(LLCamera& camera)
 {
-	LLFastTimer t(FTM_DO_OCCLUSION);
-
 	LLVertexBuffer::unbind();
 
 	if (hasRenderDebugMask(LLPipeline::RENDER_DEBUG_OCCLUSION))
@@ -1965,12 +1962,9 @@ void LLPipeline::updateGeom(F32 max_dtime)
 	updateMovedList(mMovedBridge);
 }
 
-static LLFastTimer::DeclareTimer FTM_MARK_VISIBLE("Mark Visible");
-
 void LLPipeline::markVisible(LLDrawable *drawablep, LLCamera& camera)
 {
 	LLMemType mt(LLMemType::MTYPE_PIPELINE_MARK_VISIBLE);
-	LLFastTimer t(FTM_MARK_VISIBLE);
 
 	if(!drawablep || drawablep->isDead())
 	{
@@ -4712,12 +4706,8 @@ void LLPipeline::setupHWLights(LLDrawPool* pool)
 	mLightMask = 0;
 }
 
-static LLFastTimer::DeclareTimer FTM_ENABLE_LIGHTS("Enable Lights");
-
 void LLPipeline::enableLights(U32 mask)
 {
-	LLFastTimer ftm(FTM_ENABLE_LIGHTS);
-
 	assertInitialized();
 
 	if (mLightingDetail == 0)
@@ -5573,6 +5563,7 @@ void LLPipeline::bindScreenToTexture()
 }
 
 static LLFastTimer::DeclareTimer FTM_RENDER_BLOOM("Bloom");
+
 void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield)
 {
 	LLMemType mt_ru(LLMemType::MTYPE_PIPELINE_RENDER_BLOOM);
-- 
cgit v1.2.3


From 0afe2491ab6a05bf62a2fce438dfdbbaf0b191df Mon Sep 17 00:00:00 2001
From: Dave Parks <davep@lindenlab.com>
Date: Wed, 17 Mar 2010 22:22:02 -0500
Subject: CTS-110 Remove soft alpha in deferred pipeline (breaks some content).
  Will revisit soft alpha in materials project.

---
 indra/newview/pipeline.cpp | 1 -
 1 file changed, 1 deletion(-)

(limited to 'indra/newview/pipeline.cpp')

diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index e65c8b9af8..ee5ed32a83 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -6249,7 +6249,6 @@ void LLPipeline::bindDeferredShader(LLGLSLShader& shader, U32 light_index, LLRen
 
 	shader.uniform2f("screen_res", mDeferredScreen.getWidth(), mDeferredScreen.getHeight());
 	shader.uniform1f("near_clip", LLViewerCamera::getInstance()->getNear()*2.f);
-	shader.uniform1f("alpha_soften", gSavedSettings.getF32("RenderDeferredAlphaSoften"));
 	shader.uniform1f ("shadow_offset", gSavedSettings.getF32("RenderShadowOffset"));
 	shader.uniform1f("shadow_bias", gSavedSettings.getF32("RenderShadowBias"));
 	shader.uniform1f("lum_scale", gSavedSettings.getF32("RenderLuminanceScale"));
-- 
cgit v1.2.3


From 16b5db66419fdad8a8f958fd4e542c96429965ae Mon Sep 17 00:00:00 2001
From: Dave Parks <davep@lindenlab.com>
Date: Fri, 19 Mar 2010 14:34:49 -0500
Subject: Replace usage of RenderWaterReflections with RenderReflectionDetail.

---
 indra/newview/pipeline.cpp | 13 ++++++-------
 1 file changed, 6 insertions(+), 7 deletions(-)

(limited to 'indra/newview/pipeline.cpp')

diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index ee5ed32a83..e61dff139e 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -7313,17 +7313,16 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in)
 									  (1<<LLPipeline::RENDER_TYPE_SKY) |
 									  (1<<LLPipeline::RENDER_TYPE_CLOUDS));	
 
-				if (gSavedSettings.getBOOL("RenderWaterReflections"))
+				S32 detail = gSavedSettings.getS32("RenderReflectionDetail");
+				if (detail > 0)
 				{ //mask out selected geometry based on reflection detail
-
-					S32 detail = gSavedSettings.getS32("RenderReflectionDetail");
-					if (detail < 3)
+					if (detail < 4)
 					{
 						mRenderTypeMask &= ~(1 << LLPipeline::RENDER_TYPE_PARTICLES);
-						if (detail < 2)
+						if (detail < 3)
 						{
 							mRenderTypeMask &= ~(1 << LLPipeline::RENDER_TYPE_AVATAR);
-							if (detail < 1)
+							if (detail < 2)
 							{
 								mRenderTypeMask &= ~(1 << LLPipeline::RENDER_TYPE_VOLUME);
 							}
@@ -7343,7 +7342,7 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in)
 			if (LLDrawPoolWater::sNeedsDistortionUpdate)
 			{
 				mRenderTypeMask = ref_mask;
-				if (gSavedSettings.getBOOL("RenderWaterReflections"))
+				if (gSavedSettings.getS32("RenderReflectionDetail") > 0)
 				{
 					gPipeline.grabReferences(ref_result);
 					LLGLUserClipPlane clip_plane(plane, mat, projection);
-- 
cgit v1.2.3


From d4699a1b0e922258682d9b6e164a5bcc6bbd7238 Mon Sep 17 00:00:00 2001
From: Dave Parks <davep@lindenlab.com>
Date: Fri, 19 Mar 2010 15:25:35 -0500
Subject: Replace RenderDeferredShadow/RenderDeferredSunShadow with
 RenderShadowDetail

---
 indra/newview/pipeline.cpp | 237 +++++++++++++++++++++++----------------------
 1 file changed, 119 insertions(+), 118 deletions(-)

(limited to 'indra/newview/pipeline.cpp')

diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index e61dff139e..04118ad767 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -6344,7 +6344,7 @@ void LLPipeline::renderDeferredLighting()
 			glTexCoord4f(tc.v[0], tc.v[1], tc.v[2], 0);
 		}
 
-		if (gSavedSettings.getBOOL("RenderDeferredShadow"))
+		if (gSavedSettings.getS32("RenderShadowDetail") > 0)
 		{
 			glPushMatrix();
 			glLoadIdentity();
@@ -7980,30 +7980,11 @@ void LLPipeline::generateHighlight(LLCamera& camera)
 
 void LLPipeline::generateSunShadow(LLCamera& camera)
 {
-	if (!sRenderDeferred || !gSavedSettings.getBOOL("RenderDeferredShadow"))
+	if (!sRenderDeferred || gSavedSettings.getS32("RenderShadowDetail") <= 0)
 	{
 		return;
 	}
 
-	//temporary hack to disable shadows but keep local lights
-	static BOOL clear = TRUE;
-	BOOL gen_shadow = gSavedSettings.getBOOL("RenderDeferredSunShadow");
-	if (!gen_shadow)
-	{
-		if (clear)
-		{
-			clear = FALSE;
-			for (U32 i = 0; i < 6; i++)
-			{
-				mShadow[i].bindTarget();
-				mShadow[i].clear();
-				mShadow[i].flush();
-			}
-		}
-		return;
-	}
-	clear = TRUE;
-
 	F64 last_modelview[16];
 	F64 last_projection[16];
 	for (U32 i = 0; i < 16; i++)
@@ -8519,135 +8500,155 @@ void LLPipeline::generateSunShadow(LLCamera& camera)
 		}
 	}
 
-	
-
-	F32 fade_amt = gFrameIntervalSeconds * llmax(LLViewerCamera::getInstance()->getVelocityStat()->getCurrentPerSec(), 1.f);
 
-	//update shadow targets
-	for (U32 i = 0; i < 2; i++)
-	{ //for each current shadow
-		LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_SHADOW4+i;
+	//hack to disable projector shadows 
+	static bool clear = true;
+	bool gen_shadow = gSavedSettings.getS32("RenderShadowDetail") > 1;
+	
+	if (gen_shadow)
+	{
+		clear = true;
+		F32 fade_amt = gFrameIntervalSeconds * llmax(LLViewerCamera::getInstance()->getVelocityStat()->getCurrentPerSec(), 1.f);
 
-		if (mShadowSpotLight[i].notNull() && 
-			(mShadowSpotLight[i] == mTargetShadowSpotLight[0] ||
-			mShadowSpotLight[i] == mTargetShadowSpotLight[1]))
-		{ //keep this spotlight
-			mSpotLightFade[i] = llmin(mSpotLightFade[i]+fade_amt, 1.f);
-		}
-		else
-		{ //fade out this light
-			mSpotLightFade[i] = llmax(mSpotLightFade[i]-fade_amt, 0.f);
-			
-			if (mSpotLightFade[i] == 0.f || mShadowSpotLight[i].isNull())
-			{ //faded out, grab one of the pending spots (whichever one isn't already taken)
-				if (mTargetShadowSpotLight[0] != mShadowSpotLight[(i+1)%2])
-				{
-					mShadowSpotLight[i] = mTargetShadowSpotLight[0];
-				}
-				else
-				{
-					mShadowSpotLight[i] = mTargetShadowSpotLight[1];
+		//update shadow targets
+		for (U32 i = 0; i < 2; i++)
+		{ //for each current shadow
+			LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_SHADOW4+i;
+
+			if (mShadowSpotLight[i].notNull() && 
+				(mShadowSpotLight[i] == mTargetShadowSpotLight[0] ||
+				mShadowSpotLight[i] == mTargetShadowSpotLight[1]))
+			{ //keep this spotlight
+				mSpotLightFade[i] = llmin(mSpotLightFade[i]+fade_amt, 1.f);
+			}
+			else
+			{ //fade out this light
+				mSpotLightFade[i] = llmax(mSpotLightFade[i]-fade_amt, 0.f);
+				
+				if (mSpotLightFade[i] == 0.f || mShadowSpotLight[i].isNull())
+				{ //faded out, grab one of the pending spots (whichever one isn't already taken)
+					if (mTargetShadowSpotLight[0] != mShadowSpotLight[(i+1)%2])
+					{
+						mShadowSpotLight[i] = mTargetShadowSpotLight[0];
+					}
+					else
+					{
+						mShadowSpotLight[i] = mTargetShadowSpotLight[1];
+					}
 				}
 			}
 		}
-	}
-
-	for (S32 i = 0; i < 2; i++)
-	{
-		glh_set_current_modelview(saved_view);
-		glh_set_current_projection(saved_proj);
-
-		if (mShadowSpotLight[i].isNull())
+		
+		for (S32 i = 0; i < 2; i++)
 		{
-			continue;
-		}
+			glh_set_current_modelview(saved_view);
+			glh_set_current_projection(saved_proj);
 
-		LLVOVolume* volume = mShadowSpotLight[i]->getVOVolume();
+			if (mShadowSpotLight[i].isNull())
+			{
+				continue;
+			}
 
-		if (!volume)
-		{
-			mShadowSpotLight[i] = NULL;
-			continue;
-		}
+			LLVOVolume* volume = mShadowSpotLight[i]->getVOVolume();
 
-		LLDrawable* drawable = mShadowSpotLight[i];
+			if (!volume)
+			{
+				mShadowSpotLight[i] = NULL;
+				continue;
+			}
 
-		LLVector3 params = volume->getSpotLightParams();
-		F32 fov = params.mV[0];
+			LLDrawable* drawable = mShadowSpotLight[i];
 
-		//get agent->light space matrix (modelview)
-		LLVector3 center = drawable->getPositionAgent();
-		LLQuaternion quat = volume->getRenderRotation();
+			LLVector3 params = volume->getSpotLightParams();
+			F32 fov = params.mV[0];
 
-		//get near clip plane
-		LLVector3 scale = volume->getScale();
-		LLVector3 at_axis(0,0,-scale.mV[2]*0.5f);
-		at_axis *= quat;
+			//get agent->light space matrix (modelview)
+			LLVector3 center = drawable->getPositionAgent();
+			LLQuaternion quat = volume->getRenderRotation();
 
-		LLVector3 np = center+at_axis;
-		at_axis.normVec();
+			//get near clip plane
+			LLVector3 scale = volume->getScale();
+			LLVector3 at_axis(0,0,-scale.mV[2]*0.5f);
+			at_axis *= quat;
 
-		//get origin that has given fov for plane np, at_axis, and given scale
-		F32 dist = (scale.mV[1]*0.5f)/tanf(fov*0.5f);
+			LLVector3 np = center+at_axis;
+			at_axis.normVec();
 
-		LLVector3 origin = np - at_axis*dist;
+			//get origin that has given fov for plane np, at_axis, and given scale
+			F32 dist = (scale.mV[1]*0.5f)/tanf(fov*0.5f);
 
-		LLMatrix4 mat(quat, LLVector4(origin, 1.f));
+			LLVector3 origin = np - at_axis*dist;
 
-		view[i+4] = glh::matrix4f((F32*) mat.mMatrix);
+			LLMatrix4 mat(quat, LLVector4(origin, 1.f));
 
-		view[i+4] = view[i+4].inverse();
+			view[i+4] = glh::matrix4f((F32*) mat.mMatrix);
 
-		//get perspective matrix
-		F32 near_clip = dist+0.01f;
-		F32 width = scale.mV[VX];
-		F32 height = scale.mV[VY];
-		F32 far_clip = dist+volume->getLightRadius()*1.5f;
+			view[i+4] = view[i+4].inverse();
 
-		F32 fovy = fov * RAD_TO_DEG;
-		F32 aspect = width/height;
-		
-		proj[i+4] = gl_perspective(fovy, aspect, near_clip, far_clip);
+			//get perspective matrix
+			F32 near_clip = dist+0.01f;
+			F32 width = scale.mV[VX];
+			F32 height = scale.mV[VY];
+			F32 far_clip = dist+volume->getLightRadius()*1.5f;
 
-		//translate and scale to from [-1, 1] to [0, 1]
-		glh::matrix4f trans(0.5f, 0.f, 0.f, 0.5f,
-						0.f, 0.5f, 0.f, 0.5f,
-						0.f, 0.f, 0.5f, 0.5f,
-						0.f, 0.f, 0.f, 1.f);
+			F32 fovy = fov * RAD_TO_DEG;
+			F32 aspect = width/height;
+			
+			proj[i+4] = gl_perspective(fovy, aspect, near_clip, far_clip);
 
-		glh_set_current_modelview(view[i+4]);
-		glh_set_current_projection(proj[i+4]);
+			//translate and scale to from [-1, 1] to [0, 1]
+			glh::matrix4f trans(0.5f, 0.f, 0.f, 0.5f,
+							0.f, 0.5f, 0.f, 0.5f,
+							0.f, 0.f, 0.5f, 0.5f,
+							0.f, 0.f, 0.f, 1.f);
 
-		mSunShadowMatrix[i+4] = trans*proj[i+4]*view[i+4]*inv_view;
-		
-		for (U32 j = 0; j < 16; j++)
-		{
-			gGLLastModelView[j] = mShadowModelview[i+4].m[j];
-			gGLLastProjection[j] = mShadowProjection[i+4].m[j];
-		}
+			glh_set_current_modelview(view[i+4]);
+			glh_set_current_projection(proj[i+4]);
 
-		mShadowModelview[i+4] = view[i+4];
-		mShadowProjection[i+4] = proj[i+4];
+			mSunShadowMatrix[i+4] = trans*proj[i+4]*view[i+4]*inv_view;
+			
+			for (U32 j = 0; j < 16; j++)
+			{
+				gGLLastModelView[j] = mShadowModelview[i+4].m[j];
+				gGLLastProjection[j] = mShadowProjection[i+4].m[j];
+			}
 
-		LLCamera shadow_cam = camera;
-		shadow_cam.setFar(far_clip);
-		shadow_cam.setOrigin(origin);
+			mShadowModelview[i+4] = view[i+4];
+			mShadowProjection[i+4] = proj[i+4];
 
-		LLViewerCamera::updateFrustumPlanes(shadow_cam, FALSE, FALSE, TRUE);
+			LLCamera shadow_cam = camera;
+			shadow_cam.setFar(far_clip);
+			shadow_cam.setOrigin(origin);
 
-		stop_glerror();
+			LLViewerCamera::updateFrustumPlanes(shadow_cam, FALSE, FALSE, TRUE);
+
+			stop_glerror();
 
-		mShadow[i+4].bindTarget();
-		mShadow[i+4].getViewport(gGLViewport);
+			mShadow[i+4].bindTarget();
+			mShadow[i+4].getViewport(gGLViewport);
 
-		static LLCullResult result[2];
+			static LLCullResult result[2];
 
-		LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_SHADOW0+i+4;
+			LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_SHADOW0+i+4;
 
-		renderShadow(view[i+4], proj[i+4], shadow_cam, result[i], FALSE, FALSE);
+			renderShadow(view[i+4], proj[i+4], shadow_cam, result[i], FALSE, FALSE);
 
-		mShadow[i+4].flush();
- 	}
+			mShadow[i+4].flush();
+ 		}
+	}
+	else
+	{
+		if (clear)
+		{
+			clear = false;
+			for (U32 i = 4; i < 6; i++)
+			{
+				mShadow[i].bindTarget();
+				mShadow[i].clear();
+				mShadow[i].flush();
+			}
+		}
+	}
 
 	if (!gSavedSettings.getBOOL("CameraOffset"))
 	{
-- 
cgit v1.2.3


From bbfacbd50d6e8beac36fd8de1dc51ceb109a4a7d Mon Sep 17 00:00:00 2001
From: Dave Parks <davep@lindenlab.com>
Date: Fri, 19 Mar 2010 18:14:17 -0500
Subject: RenderDeferredSSAO works as an independent setting -- decoupled
 shadows from SSAO.

---
 indra/newview/pipeline.cpp | 156 +++++++++++++++++++++++----------------------
 1 file changed, 80 insertions(+), 76 deletions(-)

(limited to 'indra/newview/pipeline.cpp')

diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index 04118ad767..5cfd6c3d38 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -6344,16 +6344,16 @@ void LLPipeline::renderDeferredLighting()
 			glTexCoord4f(tc.v[0], tc.v[1], tc.v[2], 0);
 		}
 
-		if (gSavedSettings.getS32("RenderShadowDetail") > 0)
-		{
-			glPushMatrix();
-			glLoadIdentity();
-			glMatrixMode(GL_PROJECTION);
-			glPushMatrix();
-			glLoadIdentity();
+		glPushMatrix();
+		glLoadIdentity();
+		glMatrixMode(GL_PROJECTION);
+		glPushMatrix();
+		glLoadIdentity();
 
-			mDeferredLight[0].bindTarget();
-			if (gSavedSettings.getBOOL("RenderDeferredSun"))
+		mDeferredLight[0].bindTarget();
+
+		if (gSavedSettings.getBOOL("RenderDeferredSSAO") || gSavedSettings.getS32("RenderShadowDetail") > 0)
+		{
 			{ //paint shadow/SSAO light map (direct lighting lightmap)
 				LLFastTimer ftm(FTM_SUN_SHADOW);
 				bindDeferredShader(gDeferredSunProgram, 0);
@@ -6394,18 +6394,22 @@ void LLPipeline::renderDeferredLighting()
 				
 				unbindDeferredShader(gDeferredSunProgram);
 			}
-			else
-			{
-				mDeferredLight[0].clear(GL_COLOR_BUFFER_BIT);
-			}
+		}
+		else
+		{
+			glClearColor(1,1,1,1);
+			mDeferredLight[0].clear(GL_COLOR_BUFFER_BIT);
+			glClearColor(0,0,0,0);
+		}
 
-			mDeferredLight[0].flush();
+		mDeferredLight[0].flush();
 
+		{ //global illumination specific block (still experimental)
 			if (gSavedSettings.getBOOL("RenderDeferredBlurLight") &&
-			    gSavedSettings.getBOOL("RenderDeferredGI"))
-			{
+				gSavedSettings.getBOOL("RenderDeferredGI"))
+			{ 
 				LLFastTimer ftm(FTM_EDGE_DETECTION);
-				//get edge map
+				//generate edge map
 				LLGLDisable blend(GL_BLEND);
 				LLGLDisable test(GL_ALPHA_TEST);
 				LLGLDepthTest depth(GL_FALSE);
@@ -6502,79 +6506,79 @@ void LLPipeline::renderDeferredLighting()
 					unbindDeferredShader(gDeferredPostGIProgram);
 				}
 			}
+		}
 
-			if (gSavedSettings.getBOOL("RenderDeferredBlurLight"))
-			{ //soften direct lighting lightmap
-				LLFastTimer ftm(FTM_SOFTEN_SHADOW);
-				//blur lightmap
-				mDeferredLight[1].bindTarget();
+		if (gSavedSettings.getBOOL("RenderDeferredSSAO"))
+		{ //soften direct lighting lightmap
+			LLFastTimer ftm(FTM_SOFTEN_SHADOW);
+			//blur lightmap
+			mDeferredLight[1].bindTarget();
 
-				glClearColor(1,1,1,1);
-				mDeferredLight[1].clear(GL_COLOR_BUFFER_BIT);
-				glClearColor(0,0,0,0);
-				
-				bindDeferredShader(gDeferredBlurLightProgram);
+			glClearColor(1,1,1,1);
+			mDeferredLight[1].clear(GL_COLOR_BUFFER_BIT);
+			glClearColor(0,0,0,0);
+			
+			bindDeferredShader(gDeferredBlurLightProgram);
 
-				LLVector3 go = gSavedSettings.getVector3("RenderShadowGaussian");
-				const U32 kern_length = 4;
-				F32 blur_size = gSavedSettings.getF32("RenderShadowBlurSize");
-				F32 dist_factor = gSavedSettings.getF32("RenderShadowBlurDistFactor");
+			LLVector3 go = gSavedSettings.getVector3("RenderShadowGaussian");
+			const U32 kern_length = 4;
+			F32 blur_size = gSavedSettings.getF32("RenderShadowBlurSize");
+			F32 dist_factor = gSavedSettings.getF32("RenderShadowBlurDistFactor");
 
-				// sample symmetrically with the middle sample falling exactly on 0.0
-				F32 x = 0.f;
+			// sample symmetrically with the middle sample falling exactly on 0.0
+			F32 x = 0.f;
 
-				LLVector3 gauss[32]; // xweight, yweight, offset
+			LLVector3 gauss[32]; // xweight, yweight, offset
 
-				for (U32 i = 0; i < kern_length; i++)
-				{
-					gauss[i].mV[0] = llgaussian(x, go.mV[0]);
-					gauss[i].mV[1] = llgaussian(x, go.mV[1]);
-					gauss[i].mV[2] = x;
-					x += 1.f;
-				}
+			for (U32 i = 0; i < kern_length; i++)
+			{
+				gauss[i].mV[0] = llgaussian(x, go.mV[0]);
+				gauss[i].mV[1] = llgaussian(x, go.mV[1]);
+				gauss[i].mV[2] = x;
+				x += 1.f;
+			}
 
-				gDeferredBlurLightProgram.uniform2f("delta", 1.f, 0.f);
-				gDeferredBlurLightProgram.uniform1f("dist_factor", dist_factor);
-				gDeferredBlurLightProgram.uniform3fv("kern[0]", kern_length, gauss[0].mV);
-				gDeferredBlurLightProgram.uniform3fv("kern", kern_length, gauss[0].mV);
-				gDeferredBlurLightProgram.uniform1f("kern_scale", blur_size * (kern_length/2.f - 0.5f));
+			gDeferredBlurLightProgram.uniform2f("delta", 1.f, 0.f);
+			gDeferredBlurLightProgram.uniform1f("dist_factor", dist_factor);
+			gDeferredBlurLightProgram.uniform3fv("kern[0]", kern_length, gauss[0].mV);
+			gDeferredBlurLightProgram.uniform3fv("kern", kern_length, gauss[0].mV);
+			gDeferredBlurLightProgram.uniform1f("kern_scale", blur_size * (kern_length/2.f - 0.5f));
+		
+			{
+				LLGLDisable blend(GL_BLEND);
+				LLGLDepthTest depth(GL_TRUE, GL_FALSE, GL_ALWAYS);
+				stop_glerror();
+				glDrawArrays(GL_TRIANGLE_STRIP, 0, 3);
+				stop_glerror();
+			}
 			
-				{
-					LLGLDisable blend(GL_BLEND);
-					LLGLDepthTest depth(GL_TRUE, GL_FALSE, GL_ALWAYS);
-					stop_glerror();
-					glDrawArrays(GL_TRIANGLE_STRIP, 0, 3);
-					stop_glerror();
-				}
-				
-				mDeferredLight[1].flush();
-				unbindDeferredShader(gDeferredBlurLightProgram);
+			mDeferredLight[1].flush();
+			unbindDeferredShader(gDeferredBlurLightProgram);
 
-				bindDeferredShader(gDeferredBlurLightProgram, 1);
-				mDeferredLight[0].bindTarget();
+			bindDeferredShader(gDeferredBlurLightProgram, 1);
+			mDeferredLight[0].bindTarget();
 
-				gDeferredBlurLightProgram.uniform2f("delta", 0.f, 1.f);
+			gDeferredBlurLightProgram.uniform2f("delta", 0.f, 1.f);
 
-				{
-					LLGLDisable blend(GL_BLEND);
-					LLGLDepthTest depth(GL_TRUE, GL_FALSE, GL_ALWAYS);
-					stop_glerror();
-					glDrawArrays(GL_TRIANGLE_STRIP, 0, 3);
-					stop_glerror();
-				}
-				mDeferredLight[0].flush();
-				unbindDeferredShader(gDeferredBlurLightProgram);
+			{
+				LLGLDisable blend(GL_BLEND);
+				LLGLDepthTest depth(GL_TRUE, GL_FALSE, GL_ALWAYS);
+				stop_glerror();
+				glDrawArrays(GL_TRIANGLE_STRIP, 0, 3);
+				stop_glerror();
 			}
-
-			stop_glerror();
-			glPopMatrix();
-			stop_glerror();
-			glMatrixMode(GL_MODELVIEW);
-			stop_glerror();
-			glPopMatrix();
-			stop_glerror();
+			mDeferredLight[0].flush();
+			unbindDeferredShader(gDeferredBlurLightProgram);
 		}
 
+		stop_glerror();
+		glPopMatrix();
+		stop_glerror();
+		glMatrixMode(GL_MODELVIEW);
+		stop_glerror();
+		glPopMatrix();
+		stop_glerror();
+
 		//copy depth and stencil from deferred screen
 		//mScreen.copyContents(mDeferredScreen, 0, 0, mDeferredScreen.getWidth(), mDeferredScreen.getHeight(),
 		//					0, 0, mScreen.getWidth(), mScreen.getHeight(), GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, GL_NEAREST);
-- 
cgit v1.2.3


From 06e3d288e40e46204d84aed9c548a6ca529e78d8 Mon Sep 17 00:00:00 2001
From: Dave Parks <davep@lindenlab.com>
Date: Sat, 20 Mar 2010 16:56:36 -0500
Subject: Tweak detail settings and make graphics preferences widget enabling
 respect requirements.

---
 indra/newview/pipeline.cpp | 13 ++++++++++---
 1 file changed, 10 insertions(+), 3 deletions(-)

(limited to 'indra/newview/pipeline.cpp')

diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index 5cfd6c3d38..26670351c6 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -409,6 +409,8 @@ void LLPipeline::init()
 	{
 		mSpotLightFade[i] = 1.f;
 	}
+
+	setLightingDetail(-1);
 }
 
 LLPipeline::~LLPipeline()
@@ -905,13 +907,18 @@ S32 LLPipeline::setLightingDetail(S32 level)
 
 	if (level < 0)
 	{
-		level = gSavedSettings.getS32("RenderLightingDetail");
+		if (gSavedSettings.getBOOL("VertexShaderEnable"))
+		{
+			level = 1;
+		}
+		else
+		{
+			level = 0;
+		}
 	}
 	level = llclamp(level, 0, getMaxLightingDetail());
 	if (level != mLightingDetail)
 	{
-		gSavedSettings.setS32("RenderLightingDetail", level);
-		
 		mLightingDetail = level;
 
 		if (mVertexShadersLoaded == 1)
-- 
cgit v1.2.3