PageRenderTime 120ms CodeModel.GetById 13ms app.highlight 93ms RepoModel.GetById 0ms app.codeStats 1ms

/indra/newview/pipeline.cpp

https://bitbucket.org/lindenlab/viewer-beta/
C++ | 2147 lines | 1734 code | 308 blank | 105 comment | 242 complexity | a626ac3162a100298701681638d51672 MD5 | raw file
Possible License(s): LGPL-2.1
   1/** 
   2 * @file pipeline.cpp
   3 * @brief Rendering pipeline.
   4 *
   5 * $LicenseInfo:firstyear=2005&license=viewerlgpl$
   6 * Second Life Viewer Source Code
   7 * Copyright (C) 2010, Linden Research, Inc.
   8 * 
   9 * This library is free software; you can redistribute it and/or
  10 * modify it under the terms of the GNU Lesser General Public
  11 * License as published by the Free Software Foundation;
  12 * version 2.1 of the License only.
  13 * 
  14 * This library is distributed in the hope that it will be useful,
  15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  17 * Lesser General Public License for more details.
  18 * 
  19 * You should have received a copy of the GNU Lesser General Public
  20 * License along with this library; if not, write to the Free Software
  21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
  22 * 
  23 * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
  24 * $/LicenseInfo$
  25 */
  26
  27#include "llviewerprecompiledheaders.h"
  28
  29#include "pipeline.h"
  30
  31// library includes
  32#include "llaudioengine.h" // For debugging.
  33#include "imageids.h"
  34#include "llerror.h"
  35#include "llviewercontrol.h"
  36#include "llfasttimer.h"
  37#include "llfontgl.h"
  38#include "llmemtype.h"
  39#include "llnamevalue.h"
  40#include "llpointer.h"
  41#include "llprimitive.h"
  42#include "llvolume.h"
  43#include "material_codes.h"
  44#include "timing.h"
  45#include "v3color.h"
  46#include "llui.h" 
  47#include "llglheaders.h"
  48#include "llrender.h"
  49#include "llwindow.h"	// swapBuffers()
  50
  51// newview includes
  52#include "llagent.h"
  53#include "llagentcamera.h"
  54#include "lldrawable.h"
  55#include "lldrawpoolalpha.h"
  56#include "lldrawpoolavatar.h"
  57#include "lldrawpoolground.h"
  58#include "lldrawpoolbump.h"
  59#include "lldrawpooltree.h"
  60#include "lldrawpoolwater.h"
  61#include "llface.h"
  62#include "llfeaturemanager.h"
  63#include "llfloatertelehub.h"
  64#include "llfloaterreg.h"
  65#include "llgldbg.h"
  66#include "llhudmanager.h"
  67#include "llhudnametag.h"
  68#include "llhudtext.h"
  69#include "lllightconstants.h"
  70#include "llmeshrepository.h"
  71#include "llresmgr.h"
  72#include "llselectmgr.h"
  73#include "llsky.h"
  74#include "lltracker.h"
  75#include "lltool.h"
  76#include "lltoolmgr.h"
  77#include "llviewercamera.h"
  78#include "llviewermediafocus.h"
  79#include "llviewertexturelist.h"
  80#include "llviewerobject.h"
  81#include "llviewerobjectlist.h"
  82#include "llviewerparcelmgr.h"
  83#include "llviewerregion.h" // for audio debugging.
  84#include "llviewerwindow.h" // For getSpinAxis
  85#include "llvoavatarself.h"
  86#include "llvoground.h"
  87#include "llvosky.h"
  88#include "llvotree.h"
  89#include "llvovolume.h"
  90#include "llvosurfacepatch.h"
  91#include "llvowater.h"
  92#include "llvotree.h"
  93#include "llvopartgroup.h"
  94#include "llworld.h"
  95#include "llcubemap.h"
  96#include "llviewershadermgr.h"
  97#include "llviewerstats.h"
  98#include "llviewerjoystick.h"
  99#include "llviewerdisplay.h"
 100#include "llwlparammanager.h"
 101#include "llwaterparammanager.h"
 102#include "llspatialpartition.h"
 103#include "llmutelist.h"
 104#include "lltoolpie.h"
 105#include "llcurl.h"
 106#include "llnotifications.h"
 107
 108
 109#ifdef _DEBUG
 110// Debug indices is disabled for now for debug performance - djs 4/24/02
 111//#define DEBUG_INDICES
 112#else
 113//#define DEBUG_INDICES
 114#endif
 115
 116//cached settings
 117BOOL LLPipeline::RenderAvatarVP;
 118BOOL LLPipeline::VertexShaderEnable;
 119BOOL LLPipeline::WindLightUseAtmosShaders;
 120BOOL LLPipeline::RenderDeferred;
 121F32 LLPipeline::RenderDeferredSunWash;
 122U32 LLPipeline::RenderFSAASamples;
 123U32 LLPipeline::RenderResolutionDivisor;
 124BOOL LLPipeline::RenderUIBuffer;
 125S32 LLPipeline::RenderShadowDetail;
 126BOOL LLPipeline::RenderDeferredSSAO;
 127F32 LLPipeline::RenderShadowResolutionScale;
 128BOOL LLPipeline::RenderLocalLights;
 129BOOL LLPipeline::RenderDelayCreation;
 130BOOL LLPipeline::RenderAnimateRes;
 131BOOL LLPipeline::FreezeTime;
 132S32 LLPipeline::DebugBeaconLineWidth;
 133F32 LLPipeline::RenderHighlightBrightness;
 134LLColor4 LLPipeline::RenderHighlightColor;
 135F32 LLPipeline::RenderHighlightThickness;
 136BOOL LLPipeline::RenderSpotLightsInNondeferred;
 137LLColor4 LLPipeline::PreviewAmbientColor;
 138LLColor4 LLPipeline::PreviewDiffuse0;
 139LLColor4 LLPipeline::PreviewSpecular0;
 140LLColor4 LLPipeline::PreviewDiffuse1;
 141LLColor4 LLPipeline::PreviewSpecular1;
 142LLColor4 LLPipeline::PreviewDiffuse2;
 143LLColor4 LLPipeline::PreviewSpecular2;
 144LLVector3 LLPipeline::PreviewDirection0;
 145LLVector3 LLPipeline::PreviewDirection1;
 146LLVector3 LLPipeline::PreviewDirection2;
 147F32 LLPipeline::RenderGlowMinLuminance;
 148F32 LLPipeline::RenderGlowMaxExtractAlpha;
 149F32 LLPipeline::RenderGlowWarmthAmount;
 150LLVector3 LLPipeline::RenderGlowLumWeights;
 151LLVector3 LLPipeline::RenderGlowWarmthWeights;
 152S32 LLPipeline::RenderGlowResolutionPow;
 153S32 LLPipeline::RenderGlowIterations;
 154F32 LLPipeline::RenderGlowWidth;
 155F32 LLPipeline::RenderGlowStrength;
 156BOOL LLPipeline::RenderDepthOfField;
 157F32 LLPipeline::CameraFocusTransitionTime;
 158F32 LLPipeline::CameraFNumber;
 159F32 LLPipeline::CameraFocalLength;
 160F32 LLPipeline::CameraFieldOfView;
 161F32 LLPipeline::RenderShadowNoise;
 162F32 LLPipeline::RenderShadowBlurSize;
 163F32 LLPipeline::RenderSSAOScale;
 164U32 LLPipeline::RenderSSAOMaxScale;
 165F32 LLPipeline::RenderSSAOFactor;
 166LLVector3 LLPipeline::RenderSSAOEffect;
 167F32 LLPipeline::RenderShadowOffsetError;
 168F32 LLPipeline::RenderShadowBiasError;
 169F32 LLPipeline::RenderShadowOffset;
 170F32 LLPipeline::RenderShadowBias;
 171F32 LLPipeline::RenderSpotShadowOffset;
 172F32 LLPipeline::RenderSpotShadowBias;
 173F32 LLPipeline::RenderEdgeDepthCutoff;
 174F32 LLPipeline::RenderEdgeNormCutoff;
 175LLVector3 LLPipeline::RenderShadowGaussian;
 176F32 LLPipeline::RenderShadowBlurDistFactor;
 177BOOL LLPipeline::RenderDeferredAtmospheric;
 178S32 LLPipeline::RenderReflectionDetail;
 179F32 LLPipeline::RenderHighlightFadeTime;
 180LLVector3 LLPipeline::RenderShadowClipPlanes;
 181LLVector3 LLPipeline::RenderShadowOrthoClipPlanes;
 182LLVector3 LLPipeline::RenderShadowNearDist;
 183F32 LLPipeline::RenderFarClip;
 184LLVector3 LLPipeline::RenderShadowSplitExponent;
 185F32 LLPipeline::RenderShadowErrorCutoff;
 186F32 LLPipeline::RenderShadowFOVCutoff;
 187BOOL LLPipeline::CameraOffset;
 188F32 LLPipeline::CameraMaxCoF;
 189F32 LLPipeline::CameraDoFResScale;
 190
 191const F32 BACKLIGHT_DAY_MAGNITUDE_AVATAR = 0.2f;
 192const F32 BACKLIGHT_NIGHT_MAGNITUDE_AVATAR = 0.1f;
 193const F32 BACKLIGHT_DAY_MAGNITUDE_OBJECT = 0.1f;
 194const F32 BACKLIGHT_NIGHT_MAGNITUDE_OBJECT = 0.08f;
 195const S32 MAX_OFFSCREEN_GEOMETRY_CHANGES_PER_FRAME = 10;
 196const U32 REFLECTION_MAP_RES = 128;
 197const U32 DEFERRED_VB_MASK = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_TEXCOORD1;
 198// Max number of occluders to search for. JC
 199const S32 MAX_OCCLUDER_COUNT = 2;
 200
 201extern S32 gBoxFrame;
 202//extern BOOL gHideSelectedObjects;
 203extern BOOL gDisplaySwapBuffers;
 204extern BOOL gDebugGL;
 205
 206// hack counter for rendering a fixed number of frames after toggling
 207// fullscreen to work around DEV-5361
 208static S32 sDelayedVBOEnable = 0;
 209
 210BOOL	gAvatarBacklight = FALSE;
 211
 212BOOL	gDebugPipeline = FALSE;
 213LLPipeline gPipeline;
 214const LLMatrix4* gGLLastMatrix = NULL;
 215
 216LLFastTimer::DeclareTimer FTM_RENDER_GEOMETRY("Geometry");
 217LLFastTimer::DeclareTimer FTM_RENDER_GRASS("Grass");
 218LLFastTimer::DeclareTimer FTM_RENDER_INVISIBLE("Invisible");
 219LLFastTimer::DeclareTimer FTM_RENDER_OCCLUSION("Occlusion");
 220LLFastTimer::DeclareTimer FTM_RENDER_SHINY("Shiny");
 221LLFastTimer::DeclareTimer FTM_RENDER_SIMPLE("Simple");
 222LLFastTimer::DeclareTimer FTM_RENDER_TERRAIN("Terrain");
 223LLFastTimer::DeclareTimer FTM_RENDER_TREES("Trees");
 224LLFastTimer::DeclareTimer FTM_RENDER_UI("UI");
 225LLFastTimer::DeclareTimer FTM_RENDER_WATER("Water");
 226LLFastTimer::DeclareTimer FTM_RENDER_WL_SKY("Windlight Sky");
 227LLFastTimer::DeclareTimer FTM_RENDER_ALPHA("Alpha Objects");
 228LLFastTimer::DeclareTimer FTM_RENDER_CHARACTERS("Avatars");
 229LLFastTimer::DeclareTimer FTM_RENDER_BUMP("Bump");
 230LLFastTimer::DeclareTimer FTM_RENDER_FULLBRIGHT("Fullbright");
 231LLFastTimer::DeclareTimer FTM_RENDER_GLOW("Glow");
 232LLFastTimer::DeclareTimer FTM_GEO_UPDATE("Geo Update");
 233LLFastTimer::DeclareTimer FTM_POOLRENDER("RenderPool");
 234LLFastTimer::DeclareTimer FTM_POOLS("Pools");
 235LLFastTimer::DeclareTimer FTM_RENDER_BLOOM_FBO("First FBO");
 236LLFastTimer::DeclareTimer FTM_STATESORT("Sort Draw State");
 237LLFastTimer::DeclareTimer FTM_PIPELINE("Pipeline");
 238LLFastTimer::DeclareTimer FTM_CLIENT_COPY("Client Copy");
 239LLFastTimer::DeclareTimer FTM_RENDER_DEFERRED("Deferred Shading");
 240
 241
 242static LLFastTimer::DeclareTimer FTM_STATESORT_DRAWABLE("Sort Drawables");
 243static LLFastTimer::DeclareTimer FTM_STATESORT_POSTSORT("Post Sort");
 244
 245//----------------------------------------
 246std::string gPoolNames[] = 
 247{
 248	// Correspond to LLDrawpool enum render type
 249	"NONE",
 250	"POOL_SIMPLE",
 251	"POOL_GROUND",
 252	"POOL_FULLBRIGHT",
 253	"POOL_BUMP",
 254	"POOL_TERRAIN,"	
 255	"POOL_SKY",
 256	"POOL_WL_SKY",
 257	"POOL_TREE",
 258	"POOL_GRASS",
 259	"POOL_INVISIBLE",
 260	"POOL_AVATAR",
 261	"POOL_VOIDWATER",
 262	"POOL_WATER",
 263	"POOL_GLOW",
 264	"POOL_ALPHA"
 265};
 266
 267void drawBox(const LLVector3& c, const LLVector3& r);
 268void drawBoxOutline(const LLVector3& pos, const LLVector3& size);
 269U32 nhpo2(U32 v);
 270
 271glh::matrix4f glh_copy_matrix(F32* src)
 272{
 273	glh::matrix4f ret;
 274	ret.set_value(src);
 275	return ret;
 276}
 277
 278glh::matrix4f glh_get_current_modelview()
 279{
 280	return glh_copy_matrix(gGLModelView);
 281}
 282
 283glh::matrix4f glh_get_current_projection()
 284{
 285	return glh_copy_matrix(gGLProjection);
 286}
 287
 288glh::matrix4f glh_get_last_modelview()
 289{
 290	return glh_copy_matrix(gGLLastModelView);
 291}
 292
 293glh::matrix4f glh_get_last_projection()
 294{
 295	return glh_copy_matrix(gGLLastProjection);
 296}
 297
 298void glh_copy_matrix(const glh::matrix4f& src, F32* dst)
 299{
 300	for (U32 i = 0; i < 16; i++)
 301	{
 302		dst[i] = src.m[i];
 303	}
 304}
 305
 306void glh_set_current_modelview(const glh::matrix4f& mat)
 307{
 308	glh_copy_matrix(mat, gGLModelView);
 309}
 310
 311void glh_set_current_projection(glh::matrix4f& mat)
 312{
 313	glh_copy_matrix(mat, gGLProjection);
 314}
 315
 316glh::matrix4f gl_ortho(GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat znear, GLfloat zfar)
 317{
 318	glh::matrix4f ret(
 319		2.f/(right-left), 0.f, 0.f, -(right+left)/(right-left),
 320		0.f, 2.f/(top-bottom), 0.f, -(top+bottom)/(top-bottom),
 321		0.f, 0.f, -2.f/(zfar-znear),  -(zfar+znear)/(zfar-znear),
 322		0.f, 0.f, 0.f, 1.f);
 323
 324	return ret;
 325}
 326
 327void display_update_camera();
 328//----------------------------------------
 329
 330S32		LLPipeline::sCompiles = 0;
 331
 332BOOL	LLPipeline::sPickAvatar = TRUE;
 333BOOL	LLPipeline::sDynamicLOD = TRUE;
 334BOOL	LLPipeline::sShowHUDAttachments = TRUE;
 335BOOL	LLPipeline::sRenderMOAPBeacons = FALSE;
 336BOOL	LLPipeline::sRenderPhysicalBeacons = TRUE;
 337BOOL	LLPipeline::sRenderScriptedBeacons = FALSE;
 338BOOL	LLPipeline::sRenderScriptedTouchBeacons = TRUE;
 339BOOL	LLPipeline::sRenderParticleBeacons = FALSE;
 340BOOL	LLPipeline::sRenderSoundBeacons = FALSE;
 341BOOL	LLPipeline::sRenderBeacons = FALSE;
 342BOOL	LLPipeline::sRenderHighlight = TRUE;
 343BOOL	LLPipeline::sForceOldBakedUpload = FALSE;
 344S32		LLPipeline::sUseOcclusion = 0;
 345BOOL	LLPipeline::sDelayVBUpdate = TRUE;
 346BOOL	LLPipeline::sAutoMaskAlphaDeferred = TRUE;
 347BOOL	LLPipeline::sAutoMaskAlphaNonDeferred = FALSE;
 348BOOL	LLPipeline::sDisableShaders = FALSE;
 349BOOL	LLPipeline::sRenderBump = TRUE;
 350BOOL	LLPipeline::sBakeSunlight = FALSE;
 351BOOL	LLPipeline::sNoAlpha = FALSE;
 352BOOL	LLPipeline::sUseTriStrips = TRUE;
 353BOOL	LLPipeline::sUseFarClip = TRUE;
 354BOOL	LLPipeline::sShadowRender = FALSE;
 355BOOL	LLPipeline::sWaterReflections = FALSE;
 356BOOL	LLPipeline::sRenderGlow = FALSE;
 357BOOL	LLPipeline::sReflectionRender = FALSE;
 358BOOL	LLPipeline::sImpostorRender = FALSE;
 359BOOL	LLPipeline::sUnderWaterRender = FALSE;
 360BOOL	LLPipeline::sTextureBindTest = FALSE;
 361BOOL	LLPipeline::sRenderFrameTest = FALSE;
 362BOOL	LLPipeline::sRenderAttachedLights = TRUE;
 363BOOL	LLPipeline::sRenderAttachedParticles = TRUE;
 364BOOL	LLPipeline::sRenderDeferred = FALSE;
 365BOOL    LLPipeline::sMemAllocationThrottled = FALSE;
 366S32		LLPipeline::sVisibleLightCount = 0;
 367F32		LLPipeline::sMinRenderSize = 0.f;
 368
 369
 370static LLCullResult* sCull = NULL;
 371
 372static const U32 gl_cube_face[] = 
 373{
 374	GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB,
 375	GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB,
 376	GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB,
 377	GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB,
 378	GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB,
 379	GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB,
 380};
 381
 382void validate_framebuffer_object();
 383
 384
 385bool addDeferredAttachments(LLRenderTarget& target)
 386{
 387	return target.addColorAttachment(GL_RGBA) && //specular
 388			target.addColorAttachment(GL_RGBA); //normal+z	
 389}
 390
 391LLPipeline::LLPipeline() :
 392	mBackfaceCull(FALSE),
 393	mBatchCount(0),
 394	mMatrixOpCount(0),
 395	mTextureMatrixOps(0),
 396	mMaxBatchSize(0),
 397	mMinBatchSize(0),
 398	mMeanBatchSize(0),
 399	mTrianglesDrawn(0),
 400	mNumVisibleNodes(0),
 401	mVerticesRelit(0),
 402	mLightingChanges(0),
 403	mGeometryChanges(0),
 404	mNumVisibleFaces(0),
 405
 406	mInitialized(FALSE),
 407	mVertexShadersEnabled(FALSE),
 408	mVertexShadersLoaded(0),
 409	mRenderDebugFeatureMask(0),
 410	mRenderDebugMask(0),
 411	mOldRenderDebugMask(0),
 412	mGroupQ1Locked(false),
 413	mGroupQ2Locked(false),
 414	mLastRebuildPool(NULL),
 415	mAlphaPool(NULL),
 416	mSkyPool(NULL),
 417	mTerrainPool(NULL),
 418	mWaterPool(NULL),
 419	mGroundPool(NULL),
 420	mSimplePool(NULL),
 421	mFullbrightPool(NULL),
 422	mInvisiblePool(NULL),
 423	mGlowPool(NULL),
 424	mBumpPool(NULL),
 425	mWLSkyPool(NULL),
 426	mLightMask(0),
 427	mLightMovingMask(0),
 428	mLightingDetail(0),
 429	mScreenWidth(0),
 430	mScreenHeight(0)
 431{
 432	mNoiseMap = 0;
 433	mTrueNoiseMap = 0;
 434	mLightFunc = 0;
 435}
 436
 437void LLPipeline::init()
 438{
 439	LLMemType mt(LLMemType::MTYPE_PIPELINE_INIT);
 440
 441	refreshCachedSettings();
 442
 443	gOctreeMaxCapacity = gSavedSettings.getU32("OctreeMaxNodeCapacity");
 444	sDynamicLOD = gSavedSettings.getBOOL("RenderDynamicLOD");
 445	sRenderBump = gSavedSettings.getBOOL("RenderObjectBump");
 446	sUseTriStrips = gSavedSettings.getBOOL("RenderUseTriStrips");
 447	LLVertexBuffer::sUseStreamDraw = gSavedSettings.getBOOL("RenderUseStreamVBO");
 448	LLVertexBuffer::sUseVAO = gSavedSettings.getBOOL("RenderUseVAO");
 449	LLVertexBuffer::sPreferStreamDraw = gSavedSettings.getBOOL("RenderPreferStreamDraw");
 450	sRenderAttachedLights = gSavedSettings.getBOOL("RenderAttachedLights");
 451	sRenderAttachedParticles = gSavedSettings.getBOOL("RenderAttachedParticles");
 452
 453	mInitialized = TRUE;
 454	
 455	stop_glerror();
 456
 457	//create render pass pools
 458	getPool(LLDrawPool::POOL_ALPHA);
 459	getPool(LLDrawPool::POOL_SIMPLE);
 460	getPool(LLDrawPool::POOL_GRASS);
 461	getPool(LLDrawPool::POOL_FULLBRIGHT);
 462	getPool(LLDrawPool::POOL_INVISIBLE);
 463	getPool(LLDrawPool::POOL_BUMP);
 464	getPool(LLDrawPool::POOL_GLOW);
 465
 466	LLViewerStats::getInstance()->mTrianglesDrawnStat.reset();
 467	resetFrameStats();
 468
 469	for (U32 i = 0; i < NUM_RENDER_TYPES; ++i)
 470	{
 471		mRenderTypeEnabled[i] = TRUE; //all rendering types start enabled
 472	}
 473
 474	mRenderDebugFeatureMask = 0xffffffff; // All debugging features on
 475	mRenderDebugMask = 0;	// All debug starts off
 476
 477	// Don't turn on ground when this is set
 478	// Mac Books with intel 950s need this
 479	if(!gSavedSettings.getBOOL("RenderGround"))
 480	{
 481		toggleRenderType(RENDER_TYPE_GROUND);
 482	}
 483
 484	// make sure RenderPerformanceTest persists (hackity hack hack)
 485	// disables non-object rendering (UI, sky, water, etc)
 486	if (gSavedSettings.getBOOL("RenderPerformanceTest"))
 487	{
 488		gSavedSettings.setBOOL("RenderPerformanceTest", FALSE);
 489		gSavedSettings.setBOOL("RenderPerformanceTest", TRUE);
 490	}
 491
 492	mOldRenderDebugMask = mRenderDebugMask;
 493
 494	mBackfaceCull = TRUE;
 495
 496	stop_glerror();
 497	
 498	// Enable features
 499		
 500	LLViewerShaderMgr::instance()->setShaders();
 501
 502	stop_glerror();
 503
 504	for (U32 i = 0; i < 2; ++i)
 505	{
 506		mSpotLightFade[i] = 1.f;
 507	}
 508
 509	mDeferredVB = new LLVertexBuffer(DEFERRED_VB_MASK, 0);
 510	mDeferredVB->allocateBuffer(8, 0, true);
 511	setLightingDetail(-1);
 512	
 513	//
 514	// Update all settings to trigger a cached settings refresh
 515	//
 516
 517	gSavedSettings.getControl("RenderAutoMaskAlphaDeferred")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings));
 518	gSavedSettings.getControl("RenderAutoMaskAlphaNonDeferred")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings));
 519	gSavedSettings.getControl("RenderUseFarClip")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings));
 520	gSavedSettings.getControl("RenderAvatarMaxVisible")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings));
 521	gSavedSettings.getControl("RenderDelayVBUpdate")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings));
 522	
 523	gSavedSettings.getControl("UseOcclusion")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings));
 524	
 525	gSavedSettings.getControl("VertexShaderEnable")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings));
 526	gSavedSettings.getControl("RenderAvatarVP")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings));
 527	gSavedSettings.getControl("WindLightUseAtmosShaders")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings));
 528	gSavedSettings.getControl("RenderDeferred")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings));
 529	gSavedSettings.getControl("RenderDeferredSunWash")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings));
 530	gSavedSettings.getControl("RenderFSAASamples")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings));
 531	gSavedSettings.getControl("RenderResolutionDivisor")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings));
 532	gSavedSettings.getControl("RenderUIBuffer")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings));
 533	gSavedSettings.getControl("RenderShadowDetail")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings));
 534	gSavedSettings.getControl("RenderDeferredSSAO")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings));
 535	gSavedSettings.getControl("RenderShadowResolutionScale")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings));
 536	gSavedSettings.getControl("RenderLocalLights")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings));
 537	gSavedSettings.getControl("RenderDelayCreation")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings));
 538	gSavedSettings.getControl("RenderAnimateRes")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings));
 539	gSavedSettings.getControl("FreezeTime")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings));
 540	gSavedSettings.getControl("DebugBeaconLineWidth")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings));
 541	gSavedSettings.getControl("RenderHighlightBrightness")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings));
 542	gSavedSettings.getControl("RenderHighlightColor")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings));
 543	gSavedSettings.getControl("RenderHighlightThickness")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings));
 544	gSavedSettings.getControl("RenderSpotLightsInNondeferred")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings));
 545	gSavedSettings.getControl("PreviewAmbientColor")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings));
 546	gSavedSettings.getControl("PreviewDiffuse0")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings));
 547	gSavedSettings.getControl("PreviewSpecular0")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings));
 548	gSavedSettings.getControl("PreviewDiffuse1")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings));
 549	gSavedSettings.getControl("PreviewSpecular1")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings));
 550	gSavedSettings.getControl("PreviewDiffuse2")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings));
 551	gSavedSettings.getControl("PreviewSpecular2")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings));
 552	gSavedSettings.getControl("PreviewDirection0")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings));
 553	gSavedSettings.getControl("PreviewDirection1")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings));
 554	gSavedSettings.getControl("PreviewDirection2")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings));
 555	gSavedSettings.getControl("RenderGlowMinLuminance")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings));
 556	gSavedSettings.getControl("RenderGlowMaxExtractAlpha")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings));
 557	gSavedSettings.getControl("RenderGlowWarmthAmount")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings));
 558	gSavedSettings.getControl("RenderGlowLumWeights")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings));
 559	gSavedSettings.getControl("RenderGlowWarmthWeights")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings));
 560	gSavedSettings.getControl("RenderGlowResolutionPow")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings));
 561	gSavedSettings.getControl("RenderGlowIterations")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings));
 562	gSavedSettings.getControl("RenderGlowWidth")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings));
 563	gSavedSettings.getControl("RenderGlowStrength")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings));
 564	gSavedSettings.getControl("RenderDepthOfField")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings));
 565	gSavedSettings.getControl("CameraFocusTransitionTime")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings));
 566	gSavedSettings.getControl("CameraFNumber")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings));
 567	gSavedSettings.getControl("CameraFocalLength")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings));
 568	gSavedSettings.getControl("CameraFieldOfView")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings));
 569	gSavedSettings.getControl("RenderShadowNoise")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings));
 570	gSavedSettings.getControl("RenderShadowBlurSize")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings));
 571	gSavedSettings.getControl("RenderSSAOScale")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings));
 572	gSavedSettings.getControl("RenderSSAOMaxScale")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings));
 573	gSavedSettings.getControl("RenderSSAOFactor")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings));
 574	gSavedSettings.getControl("RenderSSAOEffect")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings));
 575	gSavedSettings.getControl("RenderShadowOffsetError")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings));
 576	gSavedSettings.getControl("RenderShadowBiasError")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings));
 577	gSavedSettings.getControl("RenderShadowOffset")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings));
 578	gSavedSettings.getControl("RenderShadowBias")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings));
 579	gSavedSettings.getControl("RenderSpotShadowOffset")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings));
 580	gSavedSettings.getControl("RenderSpotShadowBias")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings));
 581	gSavedSettings.getControl("RenderEdgeDepthCutoff")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings));
 582	gSavedSettings.getControl("RenderEdgeNormCutoff")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings));
 583	gSavedSettings.getControl("RenderShadowGaussian")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings));
 584	gSavedSettings.getControl("RenderShadowBlurDistFactor")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings));
 585	gSavedSettings.getControl("RenderDeferredAtmospheric")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings));
 586	gSavedSettings.getControl("RenderReflectionDetail")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings));
 587	gSavedSettings.getControl("RenderHighlightFadeTime")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings));
 588	gSavedSettings.getControl("RenderShadowClipPlanes")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings));
 589	gSavedSettings.getControl("RenderShadowOrthoClipPlanes")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings));
 590	gSavedSettings.getControl("RenderShadowNearDist")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings));
 591	gSavedSettings.getControl("RenderFarClip")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings));
 592	gSavedSettings.getControl("RenderShadowSplitExponent")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings));
 593	gSavedSettings.getControl("RenderShadowErrorCutoff")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings));
 594	gSavedSettings.getControl("RenderShadowFOVCutoff")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings));
 595	gSavedSettings.getControl("CameraOffset")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings));
 596	gSavedSettings.getControl("CameraMaxCoF")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings));
 597	gSavedSettings.getControl("CameraDoFResScale")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings));
 598}
 599
 600LLPipeline::~LLPipeline()
 601{
 602
 603}
 604
 605void LLPipeline::cleanup()
 606{
 607	assertInitialized();
 608
 609	mGroupQ1.clear() ;
 610	mGroupQ2.clear() ;
 611
 612	for(pool_set_t::iterator iter = mPools.begin();
 613		iter != mPools.end(); )
 614	{
 615		pool_set_t::iterator curiter = iter++;
 616		LLDrawPool* poolp = *curiter;
 617		if (poolp->isFacePool())
 618		{
 619			LLFacePool* face_pool = (LLFacePool*) poolp;
 620			if (face_pool->mReferences.empty())
 621			{
 622				mPools.erase(curiter);
 623				removeFromQuickLookup( poolp );
 624				delete poolp;
 625			}
 626		}
 627		else
 628		{
 629			mPools.erase(curiter);
 630			removeFromQuickLookup( poolp );
 631			delete poolp;
 632		}
 633	}
 634	
 635	if (!mTerrainPools.empty())
 636	{
 637		llwarns << "Terrain Pools not cleaned up" << llendl;
 638	}
 639	if (!mTreePools.empty())
 640	{
 641		llwarns << "Tree Pools not cleaned up" << llendl;
 642	}
 643		
 644	delete mAlphaPool;
 645	mAlphaPool = NULL;
 646	delete mSkyPool;
 647	mSkyPool = NULL;
 648	delete mTerrainPool;
 649	mTerrainPool = NULL;
 650	delete mWaterPool;
 651	mWaterPool = NULL;
 652	delete mGroundPool;
 653	mGroundPool = NULL;
 654	delete mSimplePool;
 655	mSimplePool = NULL;
 656	delete mFullbrightPool;
 657	mFullbrightPool = NULL;
 658	delete mInvisiblePool;
 659	mInvisiblePool = NULL;
 660	delete mGlowPool;
 661	mGlowPool = NULL;
 662	delete mBumpPool;
 663	mBumpPool = NULL;
 664	// don't delete wl sky pool it was handled above in the for loop
 665	//delete mWLSkyPool;
 666	mWLSkyPool = NULL;
 667
 668	releaseGLBuffers();
 669
 670	mFaceSelectImagep = NULL;
 671
 672	mMovedBridge.clear();
 673
 674	mInitialized = FALSE;
 675
 676	mDeferredVB = NULL;
 677}
 678
 679//============================================================================
 680
 681void LLPipeline::destroyGL() 
 682{
 683	stop_glerror();
 684	unloadShaders();
 685	mHighlightFaces.clear();
 686	
 687	resetDrawOrders();
 688
 689	resetVertexBuffers();
 690
 691	releaseGLBuffers();
 692
 693	if (LLVertexBuffer::sEnableVBOs)
 694	{
 695		// render 30 frames after switching to work around DEV-5361
 696		sDelayedVBOEnable = 30;
 697		LLVertexBuffer::sEnableVBOs = FALSE;
 698	}
 699}
 700
 701static LLFastTimer::DeclareTimer FTM_RESIZE_SCREEN_TEXTURE("Resize Screen Texture");
 702
 703//static
 704void LLPipeline::throttleNewMemoryAllocation(BOOL disable)
 705{
 706	if(sMemAllocationThrottled != disable)
 707	{
 708		sMemAllocationThrottled = disable ;
 709
 710		if(sMemAllocationThrottled)
 711		{
 712			//send out notification
 713			LLNotification::Params params("LowMemory");
 714			LLNotifications::instance().add(params);
 715
 716			//release some memory.
 717		}
 718	}
 719}
 720
 721void LLPipeline::resizeScreenTexture()
 722{
 723	LLFastTimer ft(FTM_RESIZE_SCREEN_TEXTURE);
 724	if (gPipeline.canUseVertexShaders() && assertInitialized())
 725	{
 726		GLuint resX = gViewerWindow->getWorldViewWidthRaw();
 727		GLuint resY = gViewerWindow->getWorldViewHeightRaw();
 728	
 729		allocateScreenBuffer(resX,resY);
 730	}
 731}
 732
 733void LLPipeline::allocatePhysicsBuffer()
 734{
 735	GLuint resX = gViewerWindow->getWorldViewWidthRaw();
 736	GLuint resY = gViewerWindow->getWorldViewHeightRaw();
 737
 738	if (mPhysicsDisplay.getWidth() != resX || mPhysicsDisplay.getHeight() != resY)
 739	{
 740		mPhysicsDisplay.allocate(resX, resY, GL_RGBA, TRUE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE);
 741	}
 742}
 743
 744void LLPipeline::allocateScreenBuffer(U32 resX, U32 resY)
 745{
 746	refreshCachedSettings();
 747	U32 samples = RenderFSAASamples;
 748
 749	//try to allocate screen buffers at requested resolution and samples
 750	// - on failure, shrink number of samples and try again
 751	// - if not multisampled, shrink resolution and try again (favor X resolution over Y)
 752	// Make sure to call "releaseScreenBuffers" after each failure to cleanup the partially loaded state
 753
 754	if (!allocateScreenBuffer(resX, resY, samples))
 755	{
 756		releaseScreenBuffers();
 757		//reduce number of samples 
 758		while (samples > 0)
 759		{
 760			samples /= 2;
 761			if (allocateScreenBuffer(resX, resY, samples))
 762			{ //success
 763				return;
 764			}
 765			releaseScreenBuffers();
 766		}
 767
 768		samples = 0;
 769
 770		//reduce resolution
 771		while (resY > 0 && resX > 0)
 772		{
 773			resY /= 2;
 774			if (allocateScreenBuffer(resX, resY, samples))
 775			{
 776				return;
 777			}
 778			releaseScreenBuffers();
 779
 780			resX /= 2;
 781			if (allocateScreenBuffer(resX, resY, samples))
 782			{
 783				return;
 784			}
 785			releaseScreenBuffers();
 786		}
 787
 788		llwarns << "Unable to allocate screen buffer at any resolution!" << llendl;
 789	}
 790}
 791
 792
 793bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY, U32 samples)
 794{
 795	refreshCachedSettings();
 796
 797	// remember these dimensions
 798	mScreenWidth = resX;
 799	mScreenHeight = resY;
 800	
 801	U32 res_mod = RenderResolutionDivisor;
 802
 803	if (res_mod > 1 && res_mod < resX && res_mod < resY)
 804	{
 805		resX /= res_mod;
 806		resY /= res_mod;
 807	}
 808
 809	if (RenderUIBuffer)
 810	{
 811		if (!mUIScreen.allocate(resX,resY, GL_RGBA, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE))
 812		{
 813			return false;
 814		}
 815	}	
 816
 817	if (LLPipeline::sRenderDeferred)
 818	{
 819		S32 shadow_detail = RenderShadowDetail;
 820		BOOL ssao = RenderDeferredSSAO;
 821		
 822		//allocate deferred rendering color buffers
 823		if (!mDeferredScreen.allocate(resX, resY, GL_RGBA, TRUE, TRUE, LLTexUnit::TT_RECT_TEXTURE, FALSE, samples)) return false;
 824		if (!mDeferredDepth.allocate(resX, resY, 0, TRUE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE, samples)) return false;
 825		if (!addDeferredAttachments(mDeferredScreen)) return false;
 826	
 827		if (!mScreen.allocate(resX, resY, GL_RGBA, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE, samples)) return false;
 828		if (samples > 0)
 829		{
 830			if (!mFXAABuffer.allocate(nhpo2(resX), nhpo2(resY), GL_RGBA, FALSE, FALSE, LLTexUnit::TT_TEXTURE, FALSE, samples)) return false;
 831		}
 832		else
 833		{
 834			mFXAABuffer.release();
 835		}
 836		
 837		if (shadow_detail > 0 || ssao || RenderDepthOfField || samples > 0)
 838		{ //only need mDeferredLight for shadows OR ssao OR dof OR fxaa
 839			if (!mDeferredLight.allocate(resX, resY, GL_RGBA, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE)) return false;
 840		}
 841		else
 842		{
 843			mDeferredLight.release();
 844		}
 845
 846		F32 scale = RenderShadowResolutionScale;
 847
 848		if (shadow_detail > 0)
 849		{ //allocate 4 sun shadow maps
 850			for (U32 i = 0; i < 4; i++)
 851			{
 852				if (!mShadow[i].allocate(U32(resX*scale),U32(resY*scale), 0, TRUE, FALSE, LLTexUnit::TT_RECT_TEXTURE)) return false;
 853			}
 854		}
 855		else
 856		{
 857			for (U32 i = 0; i < 4; i++)
 858			{
 859				mShadow[i].release();
 860			}
 861		}
 862
 863		U32 width = nhpo2(U32(resX*scale))/2;
 864		U32 height = width;
 865
 866		if (shadow_detail > 1)
 867		{ //allocate two spot shadow maps
 868			for (U32 i = 4; i < 6; i++)
 869			{
 870				if (!mShadow[i].allocate(width, height, 0, TRUE, FALSE)) return false;
 871			}
 872		}
 873		else
 874		{
 875			for (U32 i = 4; i < 6; i++)
 876			{
 877				mShadow[i].release();
 878			}
 879		}
 880	}
 881	else
 882	{
 883		mDeferredLight.release();
 884				
 885		for (U32 i = 0; i < 6; i++)
 886		{
 887			mShadow[i].release();
 888		}
 889		mFXAABuffer.release();
 890		mScreen.release();
 891		mDeferredScreen.release(); //make sure to release any render targets that share a depth buffer with mDeferredScreen first
 892		mDeferredDepth.release();
 893						
 894		if (!mScreen.allocate(resX, resY, GL_RGBA, TRUE, TRUE, LLTexUnit::TT_RECT_TEXTURE, FALSE)) return false;		
 895	}
 896	
 897	if (LLPipeline::sRenderDeferred)
 898	{ //share depth buffer between deferred targets
 899		mDeferredScreen.shareDepthBuffer(mScreen);
 900	}
 901
 902	gGL.getTexUnit(0)->disable();
 903
 904	stop_glerror();
 905
 906	return true;
 907}
 908
 909//static
 910void LLPipeline::updateRenderDeferred()
 911{
 912	BOOL deferred = ((RenderDeferred && 
 913					 LLRenderTarget::sUseFBO &&
 914					 LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferred") &&	 
 915					 VertexShaderEnable && 
 916					 RenderAvatarVP &&
 917					 WindLightUseAtmosShaders) ? TRUE : FALSE) &&
 918					!gUseWireframe;
 919
 920	sRenderDeferred = deferred;	
 921	if (deferred)
 922	{ //must render glow when rendering deferred since post effect pass is needed to present any lighting at all
 923		sRenderGlow = TRUE;
 924	}
 925}
 926
 927//static
 928void LLPipeline::refreshCachedSettings()
 929{
 930	LLPipeline::sAutoMaskAlphaDeferred = gSavedSettings.getBOOL("RenderAutoMaskAlphaDeferred");
 931	LLPipeline::sAutoMaskAlphaNonDeferred = gSavedSettings.getBOOL("RenderAutoMaskAlphaNonDeferred");
 932	LLPipeline::sUseFarClip = gSavedSettings.getBOOL("RenderUseFarClip");
 933	LLVOAvatar::sMaxVisible = (U32)gSavedSettings.getS32("RenderAvatarMaxVisible");
 934	LLPipeline::sDelayVBUpdate = gSavedSettings.getBOOL("RenderDelayVBUpdate");
 935
 936	LLPipeline::sUseOcclusion = 
 937			(!gUseWireframe
 938			&& LLFeatureManager::getInstance()->isFeatureAvailable("UseOcclusion") 
 939			&& gSavedSettings.getBOOL("UseOcclusion") 
 940			&& gGLManager.mHasOcclusionQuery) ? 2 : 0;
 941	
 942	VertexShaderEnable = gSavedSettings.getBOOL("VertexShaderEnable");
 943	RenderAvatarVP = gSavedSettings.getBOOL("RenderAvatarVP");
 944	WindLightUseAtmosShaders = gSavedSettings.getBOOL("WindLightUseAtmosShaders");
 945	RenderDeferred = gSavedSettings.getBOOL("RenderDeferred");
 946	RenderDeferredSunWash = gSavedSettings.getF32("RenderDeferredSunWash");
 947	RenderFSAASamples = gSavedSettings.getU32("RenderFSAASamples");
 948	RenderResolutionDivisor = gSavedSettings.getU32("RenderResolutionDivisor");
 949	RenderUIBuffer = gSavedSettings.getBOOL("RenderUIBuffer");
 950	RenderShadowDetail = gSavedSettings.getS32("RenderShadowDetail");
 951	RenderDeferredSSAO = gSavedSettings.getBOOL("RenderDeferredSSAO");
 952	RenderShadowResolutionScale = gSavedSettings.getF32("RenderShadowResolutionScale");
 953	RenderLocalLights = gSavedSettings.getBOOL("RenderLocalLights");
 954	RenderDelayCreation = gSavedSettings.getBOOL("RenderDelayCreation");
 955	RenderAnimateRes = gSavedSettings.getBOOL("RenderAnimateRes");
 956	FreezeTime = gSavedSettings.getBOOL("FreezeTime");
 957	DebugBeaconLineWidth = gSavedSettings.getS32("DebugBeaconLineWidth");
 958	RenderHighlightBrightness = gSavedSettings.getF32("RenderHighlightBrightness");
 959	RenderHighlightColor = gSavedSettings.getColor4("RenderHighlightColor");
 960	RenderHighlightThickness = gSavedSettings.getF32("RenderHighlightThickness");
 961	RenderSpotLightsInNondeferred = gSavedSettings.getBOOL("RenderSpotLightsInNondeferred");
 962	PreviewAmbientColor = gSavedSettings.getColor4("PreviewAmbientColor");
 963	PreviewDiffuse0 = gSavedSettings.getColor4("PreviewDiffuse0");
 964	PreviewSpecular0 = gSavedSettings.getColor4("PreviewSpecular0");
 965	PreviewDiffuse1 = gSavedSettings.getColor4("PreviewDiffuse1");
 966	PreviewSpecular1 = gSavedSettings.getColor4("PreviewSpecular1");
 967	PreviewDiffuse2 = gSavedSettings.getColor4("PreviewDiffuse2");
 968	PreviewSpecular2 = gSavedSettings.getColor4("PreviewSpecular2");
 969	PreviewDirection0 = gSavedSettings.getVector3("PreviewDirection0");
 970	PreviewDirection1 = gSavedSettings.getVector3("PreviewDirection1");
 971	PreviewDirection2 = gSavedSettings.getVector3("PreviewDirection2");
 972	RenderGlowMinLuminance = gSavedSettings.getF32("RenderGlowMinLuminance");
 973	RenderGlowMaxExtractAlpha = gSavedSettings.getF32("RenderGlowMaxExtractAlpha");
 974	RenderGlowWarmthAmount = gSavedSettings.getF32("RenderGlowWarmthAmount");
 975	RenderGlowLumWeights = gSavedSettings.getVector3("RenderGlowLumWeights");
 976	RenderGlowWarmthWeights = gSavedSettings.getVector3("RenderGlowWarmthWeights");
 977	RenderGlowResolutionPow = gSavedSettings.getS32("RenderGlowResolutionPow");
 978	RenderGlowIterations = gSavedSettings.getS32("RenderGlowIterations");
 979	RenderGlowWidth = gSavedSettings.getF32("RenderGlowWidth");
 980	RenderGlowStrength = gSavedSettings.getF32("RenderGlowStrength");
 981	RenderDepthOfField = gSavedSettings.getBOOL("RenderDepthOfField");
 982	CameraFocusTransitionTime = gSavedSettings.getF32("CameraFocusTransitionTime");
 983	CameraFNumber = gSavedSettings.getF32("CameraFNumber");
 984	CameraFocalLength = gSavedSettings.getF32("CameraFocalLength");
 985	CameraFieldOfView = gSavedSettings.getF32("CameraFieldOfView");
 986	RenderShadowNoise = gSavedSettings.getF32("RenderShadowNoise");
 987	RenderShadowBlurSize = gSavedSettings.getF32("RenderShadowBlurSize");
 988	RenderSSAOScale = gSavedSettings.getF32("RenderSSAOScale");
 989	RenderSSAOMaxScale = gSavedSettings.getU32("RenderSSAOMaxScale");
 990	RenderSSAOFactor = gSavedSettings.getF32("RenderSSAOFactor");
 991	RenderSSAOEffect = gSavedSettings.getVector3("RenderSSAOEffect");
 992	RenderShadowOffsetError = gSavedSettings.getF32("RenderShadowOffsetError");
 993	RenderShadowBiasError = gSavedSettings.getF32("RenderShadowBiasError");
 994	RenderShadowOffset = gSavedSettings.getF32("RenderShadowOffset");
 995	RenderShadowBias = gSavedSettings.getF32("RenderShadowBias");
 996	RenderSpotShadowOffset = gSavedSettings.getF32("RenderSpotShadowOffset");
 997	RenderSpotShadowBias = gSavedSettings.getF32("RenderSpotShadowBias");
 998	RenderEdgeDepthCutoff = gSavedSettings.getF32("RenderEdgeDepthCutoff");
 999	RenderEdgeNormCutoff = gSavedSettings.getF32("RenderEdgeNormCutoff");
1000	RenderShadowGaussian = gSavedSettings.getVector3("RenderShadowGaussian");
1001	RenderShadowBlurDistFactor = gSavedSettings.getF32("RenderShadowBlurDistFactor");
1002	RenderDeferredAtmospheric = gSavedSettings.getBOOL("RenderDeferredAtmospheric");
1003	RenderReflectionDetail = gSavedSettings.getS32("RenderReflectionDetail");
1004	RenderHighlightFadeTime = gSavedSettings.getF32("RenderHighlightFadeTime");
1005	RenderShadowClipPlanes = gSavedSettings.getVector3("RenderShadowClipPlanes");
1006	RenderShadowOrthoClipPlanes = gSavedSettings.getVector3("RenderShadowOrthoClipPlanes");
1007	RenderShadowNearDist = gSavedSettings.getVector3("RenderShadowNearDist");
1008	RenderFarClip = gSavedSettings.getF32("RenderFarClip");
1009	RenderShadowSplitExponent = gSavedSettings.getVector3("RenderShadowSplitExponent");
1010	RenderShadowErrorCutoff = gSavedSettings.getF32("RenderShadowErrorCutoff");
1011	RenderShadowFOVCutoff = gSavedSettings.getF32("RenderShadowFOVCutoff");
1012	CameraOffset = gSavedSettings.getBOOL("CameraOffset");
1013	CameraMaxCoF = gSavedSettings.getF32("CameraMaxCoF");
1014	CameraDoFResScale = gSavedSettings.getF32("CameraDoFResScale");
1015	
1016	updateRenderDeferred();
1017}
1018
1019void LLPipeline::releaseGLBuffers()
1020{
1021	assertInitialized();
1022	
1023	if (mNoiseMap)
1024	{
1025		LLImageGL::deleteTextures(1, &mNoiseMap);
1026		mNoiseMap = 0;
1027	}
1028
1029	if (mTrueNoiseMap)
1030	{
1031		LLImageGL::deleteTextures(1, &mTrueNoiseMap);
1032		mTrueNoiseMap = 0;
1033	}
1034
1035	if (mLightFunc)
1036	{
1037		LLImageGL::deleteTextures(1, &mLightFunc);
1038		mLightFunc = 0;
1039	}
1040
1041	mWaterRef.release();
1042	mWaterDis.release();
1043	
1044	for (U32 i = 0; i < 3; i++)
1045	{
1046		mGlow[i].release();
1047	}
1048
1049	releaseScreenBuffers();
1050
1051	gBumpImageList.destroyGL();
1052	LLVOAvatar::resetImpostors();
1053}
1054
1055void LLPipeline::releaseScreenBuffers()
1056{
1057	mUIScreen.release();
1058	mScreen.release();
1059	mFXAABuffer.release();
1060	mPhysicsDisplay.release();
1061	mDeferredScreen.release();
1062	mDeferredDepth.release();
1063	mDeferredLight.release();
1064	
1065	mHighlight.release();
1066		
1067	for (U32 i = 0; i < 6; i++)
1068	{
1069		mShadow[i].release();
1070	}
1071}
1072
1073
1074void LLPipeline::createGLBuffers()
1075{
1076	stop_glerror();
1077	LLMemType mt_cb(LLMemType::MTYPE_PIPELINE_CREATE_BUFFERS);
1078	assertInitialized();
1079
1080	updateRenderDeferred();
1081
1082	if (LLPipeline::sWaterReflections)
1083	{ //water reflection texture
1084		U32 res = (U32) gSavedSettings.getS32("RenderWaterRefResolution");
1085			
1086		mWaterRef.allocate(res,res,GL_RGBA,TRUE,FALSE);
1087		mWaterDis.allocate(res,res,GL_RGBA,TRUE,FALSE);
1088	}
1089
1090	mHighlight.allocate(256,256,GL_RGBA, FALSE, FALSE);
1091
1092	stop_glerror();
1093
1094	GLuint resX = gViewerWindow->getWorldViewWidthRaw();
1095	GLuint resY = gViewerWindow->getWorldViewHeightRaw();
1096	
1097	if (LLPipeline::sRenderGlow)
1098	{ //screen space glow buffers
1099		const U32 glow_res = llmax(1, 
1100			llmin(512, 1 << gSavedSettings.getS32("RenderGlowResolutionPow")));
1101
1102		for (U32 i = 0; i < 3; i++)
1103		{
1104			mGlow[i].allocate(512,glow_res,GL_RGBA,FALSE,FALSE);
1105		}
1106
1107		allocateScreenBuffer(resX,resY);
1108		mScreenWidth = 0;
1109		mScreenHeight = 0;
1110	}
1111	
1112	if (sRenderDeferred)
1113	{
1114		if (!mNoiseMap)
1115		{
1116			const U32 noiseRes = 128;
1117			LLVector3 noise[noiseRes*noiseRes];
1118
1119			F32 scaler = gSavedSettings.getF32("RenderDeferredNoise")/100.f;
1120			for (U32 i = 0; i < noiseRes*noiseRes; ++i)
1121			{
1122				noise[i] = LLVector3(ll_frand()-0.5f, ll_frand()-0.5f, 0.f);
1123				noise[i].normVec();
1124				noise[i].mV[2] = ll_frand()*scaler+1.f-scaler/2.f;
1125			}
1126
1127			LLImageGL::generateTextures(1, &mNoiseMap);
1128			
1129			gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, mNoiseMap);
1130			LLImageGL::setManualImage(LLTexUnit::getInternalType(LLTexUnit::TT_TEXTURE), 0, GL_RGB16F_ARB, noiseRes, noiseRes, GL_RGB, GL_FLOAT, noise);
1131			gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_POINT);
1132		}
1133
1134		if (!mTrueNoiseMap)
1135		{
1136			const U32 noiseRes = 128;
1137			F32 noise[noiseRes*noiseRes*3];
1138			for (U32 i = 0; i < noiseRes*noiseRes*3; i++)
1139			{
1140				noise[i] = ll_frand()*2.0-1.0;
1141			}
1142
1143			LLImageGL::generateTextures(1, &mTrueNoiseMap);
1144			gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, mTrueNoiseMap);
1145			LLImageGL::setManualImage(LLTexUnit::getInternalType(LLTexUnit::TT_TEXTURE), 0, GL_RGB16F_ARB, noiseRes, noiseRes, GL_RGB,GL_FLOAT, noise);
1146			gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_POINT);
1147		}
1148
1149		if (!mLightFunc)
1150		{
1151			U32 lightResX = gSavedSettings.getU32("RenderSpecularResX");
1152			U32 lightResY = gSavedSettings.getU32("RenderSpecularResY");
1153			U8* lg = new U8[lightResX*lightResY];
1154
1155			for (U32 y = 0; y < lightResY; ++y)
1156			{
1157				for (U32 x = 0; x < lightResX; ++x)
1158				{
1159					//spec func
1160					F32 sa = (F32) x/(lightResX-1);
1161					F32 spec = (F32) y/(lightResY-1);
1162					//lg[y*lightResX+x] = (U8) (powf(sa, 128.f*spec*spec)*255);
1163
1164					//F32 sp = acosf(sa)/(1.f-spec);
1165
1166					sa = powf(sa, gSavedSettings.getF32("RenderSpecularExponent"));
1167					F32 a = acosf(sa*0.25f+0.75f);
1168					F32 m = llmax(0.5f-spec*0.5f, 0.001f);
1169					F32 t2 = tanf(a)/m;
1170					t2 *= t2;
1171
1172					F32 c4a = (3.f+4.f*cosf(2.f*a)+cosf(4.f*a))/8.f;
1173					F32 bd = 1.f/(4.f*m*m*c4a)*powf(F_E, -t2);
1174
1175					lg[y*lightResX+x] = (U8) (llclamp(bd, 0.f, 1.f)*255);
1176				}
1177			}
1178
1179			LLImageGL::generateTextures(1, &mLightFunc);
1180			gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, mLightFunc);
1181			LLImageGL::setManualImage(LLTexUnit::getInternalType(LLTexUnit::TT_TEXTURE), 0, GL_R8, lightResX, lightResY, GL_RED, GL_UNSIGNED_BYTE, lg);
1182			gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_CLAMP);
1183			gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_TRILINEAR);
1184
1185			delete [] lg;
1186		}
1187	}
1188
1189	gBumpImageList.restoreGL();
1190}
1191
1192void LLPipeline::restoreGL() 
1193{
1194	LLMemType mt_cb(LLMemType::MTYPE_PIPELINE_RESTORE_GL);
1195	assertInitialized();
1196
1197	if (mVertexShadersEnabled)
1198	{
1199		LLViewerShaderMgr::instance()->setShaders();
1200	}
1201
1202	for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); 
1203			iter != LLWorld::getInstance()->getRegionList().end(); ++iter)
1204	{
1205		LLViewerRegion* region = *iter;
1206		for (U32 i = 0; i < LLViewerRegion::NUM_PARTITIONS; i++)
1207		{
1208			LLSpatialPartition* part = region->getSpatialPartition(i);
1209			if (part)
1210			{
1211				part->restoreGL();
1212			}
1213		}
1214	}
1215}
1216
1217
1218BOOL LLPipeline::canUseVertexShaders()
1219{
1220	if (sDisableShaders ||
1221		!gGLManager.mHasVertexShader ||
1222		!gGLManager.mHasFragmentShader ||
1223		!LLFeatureManager::getInstance()->isFeatureAvailable("VertexShaderEnable") ||
1224		(assertInitialized() && mVertexShadersLoaded != 1) )
1225	{
1226		return FALSE;
1227	}
1228	else
1229	{
1230		return TRUE;
1231	}
1232}
1233
1234BOOL LLPipeline::canUseWindLightShaders() const
1235{
1236	return (!LLPipeline::sDisableShaders &&
1237			gWLSkyProgram.mProgramObject != 0 &&
1238			LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_WINDLIGHT) > 1);
1239}
1240
1241BOOL LLPipeline::canUseWindLightShadersOnObjects() const
1242{
1243	return (canUseWindLightShaders() 
1244		&& LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_OBJECT) > 0);
1245}
1246
1247BOOL LLPipeline::canUseAntiAliasing() const
1248{
1249	return TRUE;
1250}
1251
1252void LLPipeline::unloadShaders()
1253{
1254	LLMemType mt_us(LLMemType::MTYPE_PIPELINE_UNLOAD_SHADERS);
1255	LLViewerShaderMgr::instance()->unloadShaders();
1256
1257	mVertexShadersLoaded = 0;
1258}
1259
1260void LLPipeline::assertInitializedDoError()
1261{
1262	llerrs << "LLPipeline used when uninitialized." << llendl;
1263}
1264
1265//============================================================================
1266
1267void LLPipeline::enableShadows(const BOOL enable_shadows)
1268{
1269	//should probably do something here to wrangle shadows....	
1270}
1271
1272S32 LLPipeline::getMaxLightingDetail() const
1273{
1274	/*if (mVertexShaderLevel[SHADER_OBJECT] >= LLDrawPoolSimple::SHADER_LEVEL_LOCAL_LIGHTS)
1275	{
1276		return 3;
1277	}
1278	else*/
1279	{
1280		return 1;
1281	}
1282}
1283
1284S32 LLPipeline::setLightingDetail(S32 level)
1285{
1286	LLMemType mt_ld(LLMemType::MTYPE_PIPELINE_LIGHTING_DETAIL);
1287	refreshCachedSettings();
1288
1289	if (level < 0)
1290	{
1291		if (RenderLocalLights)
1292		{
1293			level = 1;
1294		}
1295		else
1296		{
1297			level = 0;
1298		}
1299	}
1300	level = llclamp(level, 0, getMaxLightingDetail());
1301	mLightingDetail = level;
1302	
1303	return mLightingDetail;
1304}
1305
1306class LLOctreeDirtyTexture : public LLOctreeTraveler<LLDrawable>
1307{
1308public:
1309	const std::set<LLViewerFetchedTexture*>& mTextures;
1310
1311	LLOctreeDirtyTexture(const std::set<LLViewerFetchedTexture*>& textures) : mTextures(textures) { }
1312
1313	virtual void visit(const LLOctreeNode<LLDrawable>* node)
1314	{
1315		LLSpatialGroup* group = (LLSpatialGroup*) node->getListener(0);
1316
1317		if (!group->isState(LLSpatialGroup::GEOM_DIRTY) && !group->getData().empty())
1318		{
1319			for (LLSpatialGroup::draw_map_t::iterator i = group->mDrawMap.begin(); i != group->mDrawMap.end(); ++i)
1320			{
1321				for (LLSpatialGroup::drawmap_elem_t::iterator j = i->second.begin(); j != i->second.end(); ++j) 
1322				{
1323					LLDrawInfo* params = *j;
1324					LLViewerFetchedTexture* tex = LLViewerTextureManager::staticCastToFetchedTexture(params->mTexture);
1325					if (tex && mTextures.find(tex) != mTextures.end())
1326					{ 
1327						group->setState(LLSpatialGroup::GEOM_DIRTY);
1328					}
1329				}
1330			}
1331		}
1332
1333		for (LLSpatialGroup::bridge_list_t::iterator i = group->mBridgeList.begin(); i != group->mBridgeList.end(); ++i)
1334		{
1335			LLSpatialBridge* bridge = *i;
1336			traverse(bridge->mOctree);
1337		}
1338	}
1339};
1340
1341// Called when a texture changes # of channels (causes faces to move to alpha pool)
1342void LLPipeline::dirtyPoolObjectTextures(const std::set<LLViewerFetchedTexture*>& textures)
1343{
1344	assertInitialized();
1345
1346	// *TODO: This is inefficient and causes frame spikes; need a better way to do this
1347	//        Most of the time is spent in dirty.traverse.
1348
1349	for (pool_set_t::iterator iter = mPools.begin(); iter != mPools.end(); ++iter)
1350	{
1351		LLDrawPool *poolp = *iter;
1352		if (poolp->isFacePool())
1353		{
1354			((LLFacePool*) poolp)->dirtyTextures(textures);
1355		}
1356	}
1357	
1358	LLOctreeDirtyTexture dirty(textures);
1359	for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); 
1360			iter != LLWorld::getInstance()->getRegionList().end(); ++iter)
1361	{
1362		LLViewerRegion* region = *iter;
1363		for (U32 i = 0; i < LLViewerRegion::NUM_PARTITIONS; i++)
1364		{
1365			LLSpatialPartition* part = region->getSpatialPartition(i);
1366			if (part)
1367			{
1368				dirty.traverse(part->mOctree);
1369			}
1370		}
1371	}
1372}
1373
1374LLDrawPool *LLPipeline::findPool(const U32 type, LLViewerTexture *tex0)
1375{
1376	assertInitialized();
1377
1378	LLDrawPool *poolp = NULL;
1379	switch( type )
1380	{
1381	case LLDrawPool::POOL_SIMPLE:
1382		poolp = mSimplePool;
1383		break;
1384
1385	case LLDrawPool::POOL_GRASS:
1386		poolp = mGrassPool;
1387		break;
1388
1389	case LLDrawPool::POOL_FULLBRIGHT:
1390		poolp = mFullbrightPool;
1391		break;
1392
1393	case LLDrawPool::POOL_INVISIBLE:
1394		poolp = mInvisiblePool;
1395		break;
1396
1397	case LLDrawPool::POOL_GLOW:
1398		poolp = mGlowPool;
1399		break;
1400
1401	case LLDrawPool::POOL_TREE:
1402		poolp = get_if_there(mTreePools, (uintptr_t)tex0, (LLDrawPool*)0 );
1403		break;
1404
1405	case LLDrawPool::POOL_TERRAIN:
1406		poolp = get_if_there(mTerrainPools, (uintptr_t)tex0, (LLDrawPool*)0 );
1407		break;
1408
1409	case LLDrawPool::POOL_BUMP:
1410		poolp = mBumpPool;
1411		break;
1412
1413	case LLDrawPool::POOL_ALPHA:
1414		poolp = mAlphaPool;
1415		break;
1416
1417	case LLDrawPool::POOL_AVATAR:
1418		break; // Do nothing
1419
1420	case LLDrawPool::POOL_SKY:
1421		poolp = mSkyPool;
1422		break;
1423
1424	case LLDrawPool::POOL_WATER:
1425		poolp = mWaterPool;
1426		break;
1427
1428	case LLDrawPool::POOL_GROUND:
1429		poolp = mGroundPool;
1430		break;
1431
1432	case LLDrawPool::POOL_WL_SKY:
1433		poolp = mWLSkyPool;
1434		break;
1435
1436	default:
1437		llassert(0);
1438		llerrs << "Invalid Pool Type in  LLPipeline::findPool() type=" << type << llendl;
1439		break;
1440	}
1441
1442	return poolp;
1443}
1444
1445
1446LLDrawPool *LLPipeline::getPool(const U32 type,	LLViewerTexture *tex0)
1447{
1448	LLMemType mt(LLMemType::MTYPE_PIPELINE);
1449	LLDrawPool *poolp = findPool(type, tex0);
1450	if (poolp)
1451	{
1452		return poolp;
1453	}
1454
1455	LLDrawPool *new_poolp = LLDrawPool::createPool(type, tex0);
1456	addPool( new_poolp );
1457
1458	return new_poolp;
1459}
1460
1461
1462// static
1463LLDrawPool* LLPipeline::getPoolFromTE(const LLTextureEntry* te, LLViewerTexture* imagep)
1464{
1465	LLMemType mt(LLMemType::MTYPE_PIPELINE);
1466	U32 type = getPoolTypeFromTE(te, imagep);
1467	return gPipeline.getPool(type, imagep);
1468}
1469
1470//static 
1471U32 LLPipeline::getPoolTypeFromTE(const LLTextureEntry* te, LLViewerTexture* imagep)
1472{
1473	LLMemType mt_gpt(LLMemType::MTYPE_PIPELINE_GET_POOL_TYPE);
1474	
1475	if (!te || !imagep)
1476	{
1477		return 0;
1478	}
1479		
1480	bool alpha = te->getColor().mV[3] < 0.999f;
1481	if (imagep)
1482	{
1483		alpha = alpha || (imagep->getComponents() == 4 && imagep->getType() != LLViewerTexture::MEDIA_TEXTURE) || (imagep->getComponents() == 2);
1484	}
1485
1486	if (alpha)
1487	{
1488		return LLDrawPool::POOL_ALPHA;
1489	}
1490	else if ((te->getBumpmap() || te->getShiny()))
1491	{
1492		return LLDrawPool::POOL_BUMP;
1493	}
1494	else
1495	{
1496		return LLDrawPool::POOL_SIMPLE;
1497	}
1498}
1499
1500
1501void LLPipeline::addPool(LLDrawPool *new_poolp)
1502{
1503	LLMemType mt_a(LLMemType::MTYPE_PIPELINE_ADD_POOL);
1504	assertInitialized();
1505	mPools.insert(new_poolp);
1506	addToQuickLookup( new_poolp );
1507}
1508
1509void LLPipeline::allocDrawable(LLViewerObject *vobj)
1510{
1511	LLMemType mt_ad(LLMemType::MTYPE_PIPELINE_ALLOCATE_DRAWABLE);
1512	LLDrawable *drawable = new LLDrawable();
1513	vobj->mDrawable = drawable;
1514	
1515	drawable->mVObjp     = vobj;
1516	
1517	//encompass completely sheared objects by taking 
1518	//the most extreme point possible (<1,1,0.5>)
1519	drawable->setRadius(LLVector3(1,1,0.5f).scaleVec(vobj->getScale()).length());
1520	if (vobj->isOrphaned())
1521	{
1522		drawable->setState(LLDrawable::FORCE_INVISIBLE);
1523	}
1524	drawable->updateXform(TRUE);
1525}
1526
1527
1528static LLFastTimer::DeclareTimer FTM_UNLINK("Unlink");
1529static LLFastTimer::DeclareTimer FTM_REMOVE_FROM_MOVE_LIST("Movelist");
1530static LLFastTimer::DeclareTimer FTM_REMOVE_FROM_SPATIAL_PARTITION("Spatial Partition");
1531static LLFastTimer::DeclareTimer FTM_REMOVE_FROM_LIGHT_SET("Light Set");
1532static LLFastTimer::DeclareTimer FTM_REMOVE_FROM_HIGHLIGHT_SET("Highlight Set");
1533
1534void LLPipeline::unlinkDrawable(LLDrawable *drawable)
1535{
1536	LLFastTimer t(FTM_UNLINK);
1537
1538	assertInitialized();
1539
1540	LLPointer<LLDrawable> drawablep = drawable; // make sure this doesn't get deleted before we are done
1541	
1542	// Based on flags, remove the drawable from the queues that it's on.
1543	if (drawablep->isState(LLDrawable::ON_MOVE_LIST))
1544	{
1545		LLFastTimer t(FTM_REMOVE_FROM_MOVE_LIST);
1546		LLDrawable::drawable_vector_t::iterator iter = std::find(mMovedList.begin(), mMovedList.end(), drawablep);
1547		if (iter != mMovedList.end())
1548		{
1549			mMovedList.erase(iter);
1550		}
1551	}
1552
1553	if (drawablep->getSpatialGroup())
1554	{
1555		LLFastTimer t(FTM_REMOVE_FROM_SPATIAL_PARTITION);
1556		if (!drawablep->getSpatialGroup()->mSpatialPartition->remove(drawablep, drawablep->getSpatialGroup()))
1557		{
1558#ifdef LL_RELEASE_FOR_DOWNLOAD
1559			llwarns << "Couldn't remove object from spatial group!" << llendl;
1560#else
1561			llerrs << "Couldn't remove object from spatial group!" << llendl;
1562#endif
1563		}
1564	}
1565
1566	{
1567		LLFastTimer t(FTM_REMOVE_FROM_LIGHT_SET);
1568		mLights.erase(drawablep);
1569
1570		for (light_set_t::iterator iter = mNearbyLights.begin();
1571					iter != mNearbyLights.end(); iter++)
1572		{
1573			if (iter->drawable == drawablep)
1574			{
1575				mNearbyLights.erase(iter);
1576				break;
1577			}
1578		}
1579	}
1580
1581	{
1582		LLFastTimer t(FTM_REMOVE_FROM_HIGHLIGHT_SET);
1583		HighlightItem item(drawablep);
1584		mHighlightSet.erase(item);
1585
1586		if (mHighlightObject == drawablep)
1587		{
1588			mHighlightObject = NULL;
1589		}
1590	}
1591
1592	for (U32 i = 0; i < 2; ++i)
1593	{
1594		if (mShadowSpotLight[i] == drawablep)
1595		{
1596			mShadowSpotLight[i] = NULL;
1597		}
1598
1599		if (mTargetShadowSpotLight[i] == drawablep)
1600		{
1601			mTargetShadowSpotLight[i] = NULL;
1602		}
1603	}
1604
1605
1606}
1607
1608U32 LLPipeline::addObject(LLViewerObject *vobj)
1609{
1610	LLMemType mt_ao(LLMemType::MTYPE_PIPELINE_ADD_OBJECT);
1611
1612	if (RenderDelayCreation)
1613	{
1614		mCreateQ.push_back(vobj);
1615	}
1616	else
1617	{
1618		createObject(vobj);
1619	}
1620
1621	return 1;
1622}
1623
1624void LLPipeline::createObjects(F32 max_dtime)
1625{
1626	LLFastTimer ftm(FTM_GEO_UPDATE);
1627	LLMemType mt(LLMemType::MTYPE_PIPELINE_CREATE_OBJECTS);
1628
1629	LLTimer update_timer;
1630
1631	while (!mCreateQ.empty() && update_timer.getElapsedTimeF32() < max_dtime)
1632	{
1633		LLViewerObject* vobj = mCreateQ.front();
1634		if (!vobj->isDead())
1635		{
1636			createObject(vobj);
1637		}
1638		mCreateQ.pop_front();
1639	}
1640	
1641	//for (LLViewerObject::vobj_list_t::iterator iter = mCreateQ.begin(); iter != mCreateQ.end(); ++iter)
1642	//{
1643	//	createObject(*iter);
1644	//}
1645
1646	//mCreateQ.clear();
1647}
1648
1649void LLPipeline::createObject(LLViewerObject* vobj)
1650{
1651	LLDrawable* drawablep = vobj->mDrawable;
1652
1653	if (!drawablep)
1654	{
1655		drawablep = vobj->createDrawable(this);
1656	}
1657	else
1658	{
1659		llerrs << "Redundant drawable creation!" << llendl;
1660	}
1661		
1662	llassert(drawablep);
1663
1664	if (vobj->getParent())
1665	{
1666		vobj->setDrawableParent(((LLViewerObject*)vobj->getParent())->mDrawable); // LLPipeline::addObject 1
1667	}
1668	else
1669	{
1670		vobj->setDrawableParent(NULL); // LLPipeline::addObject 2
1671	}
1672
1673	markRebuild(drawablep, LLDrawable::REBUILD_ALL, TRUE);
1674
1675	if (drawablep->getVOVolume() && RenderAnimateRes)
1676	{
1677		// fun animated res
1678		drawablep->updateXform(TRUE);
1679		drawablep->clearState(LLDrawable::MOVE_UNDAMPED);
1680		drawablep->setScale(LLVector3(0,0,0));
1681		drawablep->makeActive();
1682	}
1683}
1684
1685
1686void LLPipeline::resetFrameStats()
1687{
1688	assertInitialized();
1689
1690	LLViewerStats::getInstance()->mTrianglesDrawnStat.addValue(mTrianglesDrawn/1000.f);
1691
1692	if (mBatchCount > 0)
1693	{
1694		mMeanBatchSize = gPipeline.mTrianglesDrawn/gPipeline.mBatchCount;
1695	}
1696	mTrianglesDrawn = 0;
1697	sCompiles        = 0;
1698	mVerticesRelit   = 0;
1699	mLightingChanges = 0;
1700	mGeometryChanges = 0;
1701	mNumVisibleFaces = 0;
1702
1703	if (mOldRenderDebugMask != mRenderDebugMask)
1704	{
1705		gObjectList.clearDebugText();
1706		mOldRenderDebugMask = mRenderDebugMask;
1707	}
1708		
1709}
1710
1711//external functions for asynchronous updating
1712void LLPipeline::updateMoveDampedAsync(LLDrawable* drawablep)
1713{
1714	if (FreezeTime)
1715	{
1716		return;
1717	}
1718	if (!drawablep)
1719	{
1720		llerrs << "updateMove called with NULL drawablep" << llendl;
1721		return;
1722	}
1723	if (drawablep->isState(LLDrawable::EARLY_MOVE))
1724	{
1725		return;
1726	}
1727
1728	assertInitialized();
1729
1730	// update drawable now
1731	drawablep->clearState(LLDrawable::MOVE_UNDAMPED); // force to DAMPED
1732	drawablep->updateMove(); // returns done
1733	drawablep->setState(LLDrawable::EARLY_MOVE); // flag says we already did an undamped move this frame
1734	// Put on move list so that EARLY_MOVE gets cleared
1735	if (!drawablep->isState(LLDrawable::ON_MOVE_LIST))
1736	{
1737		mMovedList.push_back(drawablep);
1738		drawablep->setState(LLDrawable::ON_MOVE_LIST);
1739	}
1740}
1741
1742void LLPipeline::updateMoveNormalAsync(LLDrawable* drawablep)
1743{
1744	if (FreezeTime)
1745	{
1746		return;
1747	}
1748	if (!drawablep)
1749	{
1750		llerrs << "updateMove called with NULL drawablep" << llendl;
1751		return;
1752	}
1753	if (drawablep->isState(LLDrawable::EARLY_MOVE))
1754	{
1755		return;
1756	}
1757
1758	assertInitialized();
1759
1760	// update drawable now
1761	drawablep->setState(LLDrawable::MOVE_UNDAMPED); // force to UNDAMPED
1762	drawablep->updateMove();
1763	drawablep->setState(LLDrawable::EARLY_MOVE); // flag says we already did an undamped move this frame
1764	// Put on move list so that EARLY_MOVE gets cleared
1765	if (!drawablep->isState(LLDrawable::ON_MOVE_LIST))
1766	{
1767		mMovedList.push_back(drawablep);
1768		drawablep->setState(LLDrawable::ON_MOVE_LIST);
1769	}
1770}
1771
1772void LLPipeline::updateMovedList(LLDrawable::drawable_vector_t& moved_list)
1773{
1774	for (LLDrawable::drawable_vector_t::iterator iter = moved_list.begin();
1775		 iter != moved_list.end(); )
1776	{
1777		LLDrawable::drawable_vector_t::iterator curiter = iter++;
1778		LLDrawable *drawablep = *curiter;
1779		BOOL done = TRUE;
1780		if (!drawablep->isDead() && (!drawablep->isState(LLDrawable::EARLY_MOVE)))
1781		{
1782			done = drawablep->updateMove();
1783		}
1784		drawablep->clearState(LLDrawable::EARLY_MOVE | LLDrawable::MOVE_UNDAMPED);
1785		if (done)
1786		{
1787			drawablep->clearState(LLDrawable::ON_MOVE_LIST);
1788			iter = moved_list.erase(curiter);
1789		}
1790	}
1791}
1792
1793static LLFastTimer::DeclareTimer FTM_OCTREE_BALANCE("Balance Octree");
1794static LLFastTimer::DeclareTimer FTM_UPDATE_MOVE("Update Move");
1795
1796void LLPipeline::updateMove()
1797{
1798	LLFastTimer t(FTM_UPDATE_MOVE);
1799	LLMemType mt_um(LLMemType::MTYPE_PIPELINE_UPDATE_MOVE);
1800
1801	if (FreezeTime)
1802	{
1803		return;
1804	}
1805
1806	assertInitialized();
1807
1808	{
1809		static LLFastTimer::DeclareTimer ftm("Retexture");
1810		LLFastTimer t(ftm);
1811
1812		for (LLDrawable::drawable_set_t::iterator iter = mRetexturedList.begin();
1813			 iter != mRetexturedList.end(); ++iter)
1814		{
1815			LLDrawable* drawablep = *iter;
1816			if (drawablep && !drawablep->isDead())
1817			{
1818				drawablep->updateTexture();
1819			}
1820		}
1821		mRetexturedList.clear();
1822	}
1823
1824	{
1825		static LLFastTimer::DeclareTimer ftm("Moved List");
1826		LLFastTimer t(ftm);
1827		updateMovedList(mMovedList);
1828	}
1829
1830	//balance octrees
1831	{
1832 		LLFastTimer ot(FTM_OCTREE_BALANCE);
1833
1834		for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); 
1835			iter != LLWorld::getInstance()->getRegionList().end(); ++iter)
1836		{
1837			LLViewerRegion* region = *iter;
1838			for (U32 i = 0; i < LLViewerRegion::NUM_PARTITIONS; i++)
1839			{
1840				LLSpatialPartition* part = region->getSpatialPartition(i);
1841				if (part)
1842				{
1843					part->mOctree->balance();
1844				}
1845			}
1846		}
1847	}
1848}
1849
1850/////////////////////////////////////////////////////////////////////////////
1851// Culling and occlusion testing
1852/////////////////////////////////////////////////////////////////////////////
1853
1854//static
1855F32 LLPipeline::calcPixelArea(LLVector3 center, LLVector3 size, LLCamera &camera)
1856{
1857	LLVector3 lookAt = center - camera.getOrigin();
1858	F32 dist = lookAt.length();
1859
1860	//ramp down distance for nearby objects
1861	//shrink dist by dist/16.
1862	if (dist < 16.f)
1863	{
1864		dist /= 16.f;
1865		dist *= dist;
1866		dist *= 16.f;
1867	}
1868
1869	//get area of circle around node
1870	F32 app_angle = atanf(size.length()/dist);
1871	F32 radius = app_angle*LLDrawable::sCurPixelAngle;
1872	return radius*radius * F_PI;
1873}
1874
1875//static
1876F32 LLPipeline::calcPixelArea(const LLVector4a& center, const LLVector4a& size, LLCamera &camera)
1877{
1878	LLVector4a origin;
1879	origin.load3(camera.getOrigin().mV);
1880
1881	LLVector4a lookAt;
1882	lookAt.setSub(center, origin);
1883	F32 dist = lookAt.getLength3().getF32();
1884
1885	//ramp down distance for nearby objects
1886	//shrink dist by dist/16.
1887	if (dist < 16.f)
1888	{
1889		dist /= 16.f;
1890		dist *= dist;
1891		dist *= 16.f;
1892	}
1893
1894	//get area of circle around node
1895	F32 app_angle = atanf(size.getLength3().getF32()/dist);
1896	F32 radius = app_angle*LLDrawable::sCurPixelAngle;
1897	return radius*radius * F_PI;
1898}
1899
1900void LLPipeline::grabReferences(LLCullResult& result)
1901{
1902	sCull = &result;
1903}
1904
1905void LLPipeline::clearReferences()
1906{
1907	sCull = NULL;
1908}
1909
1910void check_references(LLSpatialGroup* group, LLDrawable* drawable)
1911{
1912	for (LLSpatialGroup::element_iter i = group->getData().begin(); i != group->getData().end(); ++i)
1913	{
1914		if (drawable == *i)
1915		{
1916			llerrs << "LLDrawable deleted while actively reference by LLPipeline." << llendl;
1917		}
1918	}			
1919}
1920
1921void check_references(LLDrawable* drawable, LLFace* face)
1922{
1923	for (S32 i = 0; i < drawable->getNumFaces(); ++i)
1924	{
1925		if (drawable->getFace(i) == face)
1926		{
1927			llerrs << "LLFace deleted while actively referenced by LLPipeline." << llendl;
1928		}
1929	}
1930}
1931
1932void check_references(LLSpatialGroup* group, LLFace* face)
1933{
1934	for (LLSpatialGroup::element_iter i = group->getData().begin(); i != group->getData().end(); ++i)
1935	{
1936		LLDrawable* drawable = *i;
1937		check_references(drawable, face);
1938	}			
1939}
1940
1941void LLPipeline::checkReferences(LLFace* face)
1942{
1943#if 0
1944	if (sCull)
1945	{
1946		for (LLCullResult::sg_list_t::iterator iter = sCull->beginVisibleGroups(); iter != sCull->endVisibleGroups(); ++iter)
1947		{
1948			LLSpatialGroup* group = *iter;
1949			check_references(group, face);
1950		}
1951
1952		for (LLCullResult::sg_list_t::iterator iter = sCull->beginAlphaGroups(); iter != sCull->endAlphaGroups(); ++iter)
1953		{
1954			LLSpatialGroup* group = *iter;
1955			check_references(group, face);
1956		}
1957
1958		for (LLCullResult::sg_list_t::iterator iter = sCull->beginDrawableGroups(); iter != sCull->endDrawableGroups(); ++iter)
1959		{
1960			LLSpatialGroup* group = *iter;
1961			check_references(group, face);
1962		}
1963
1964		for (LLCullResult::drawable_list_t::iterator iter = sCull->beginVisibleList(); iter != sCull->endVisibleList(); ++iter)
1965		{
1966			LLDrawable* drawable = *iter;
1967			check_references(drawable, face);	
1968		}
1969	}
1970#endif
1971}
1972
1973void LLPipeline::checkReferences(LLDrawable* drawable)
1974{
1975#if 0
1976	if (sCull)
1977	{
1978		for (LLCullResult::sg_list_t::iterator iter = sCull->beginVisibleGroups(); iter != sCull->endVisibleGroups(); ++iter)
1979		{
1980			LLSpatialGroup* group = *iter;
1981			check_references(group, drawable);
1982		}
1983
1984		for (LLCullResult::sg_list_t::iterator iter = sCull->beginAlphaGroups(); iter != sCull->endAlphaGroups(); ++iter)
1985		{
1986			LLSpatialGroup* group = *iter;
1987			check_references(group, drawable);
1988		}
1989
1990		for (LLCullResult::sg_list_t::iterator iter = sCull->beginDrawableGroups(); iter != sCull->endDrawableGroups(); ++iter)
1991		{
1992			LLSpatialGroup* group = *iter;
1993			check_references(group, drawable);
1994		}
1995
1996		for (LLCullResult::drawable_list_t::iterator iter = sCull->beginVisibleList(); iter != sCull->endVisibleList(); ++iter)
1997		{
1998			if (drawable == *iter)
1999			{
2000				llerrs << "LLDrawable deleted while actively referenced by LLPipeline." << llendl;
2001			}
2002		}
2003	}
2004#endif
2005}
2006
2007void check_references(LLSpatialGroup* group, LLDrawInfo* draw_info)
2008{
2009	for (LLSpatialGroup::draw_map_t::iterator i = group->mDrawMap.begin(); i != group->mDrawMap.end(); ++i)
2010	{
2011		LLSpatialGroup::drawmap_elem_t& draw_vec = i->second;
2012		for (LLSpatialGroup::drawmap_elem_t::iterator j = draw_vec.begin(); j != draw_vec.end(); ++j)
2013		{
2014			LLDrawInfo* params = *j;
2015			if (params == draw_info)
2016			{
2017				llerrs << "LLDrawInfo deleted while actively referenced by LLPipeline." << llendl;
2018			}
2019		}
2020	}
2021}
2022
2023
2024void LLPipeline::checkReferences(LLDrawInfo* draw_info)
2025{
2026#if 0
2027	if (sCull)
2028	{
2029		for (LLCullResult::sg_list_t::iterator iter = sCull->beginVisibleGroups(); iter != sCull->endVisibleGroups(); ++iter)
2030		{
2031			LLSpatialGroup* group = *iter;
2032			check_references(group, draw_info);
2033		}
2034
2035		for (LLCullResult::sg_list_t::iterator iter = sCull->beginAlphaGroups(); iter != sCull->endAlphaGroups(); ++iter)
2036		{
2037			LLSpatialGroup* group = *iter;
2038			check_references(group, draw_info);
2039		}
2040
2041		for (LLCullResult::sg_list_t::iterator iter = sCull->beginDrawableGroups(); iter != sCull->endDrawableGroups(); ++iter)
2042		{
2043			LLSpatialGroup* group = *iter;
2044			check_references(group, draw_info);
2045		}
2046	}
2047#endif
2048}
2049
2050void LLPipeline::checkReferences(LLSpatialGroup* group)
2051{
2052#if 0
2053	if (sCull)
2054	{
2055		for (LLCullResult::sg_list_t::iterator iter = sCull->beginVisibleGroups(); iter != sCull->endVisibleGroups(); ++iter)
2056		{
2057			if (group == *iter)
2058			{
2059				llerrs << "LLSpatialGroup deleted while actively referenced by LLPipeline." << llendl;
2060			}
2061		}
2062
2063		for (LLCullResult::sg_list_t::iterator iter = sCull->beginAlphaGroups(); iter != sCull->endAlphaGroups(); ++iter)
2064		{
2065			if (group == *iter)
2066			{
2067				llerrs << "LLSpatialGroup deleted while actively referenced by LLPipeline." << llendl;
2068			}
2069		}
2070
2071		for (LLCullResult::sg_list_t::iterator iter = sCull->beginDrawableGroups(); iter != sCull->endDrawableGroups(); ++iter)
2072		{
2073			if (group == *iter)
2074			{
2075				llerrs << "LLSpatialGroup deleted while actively referenced by LLPipeline." << llendl;
2076			}
2077		}
2078	}
2079#endif
2080}
2081
2082
2083BOOL LLPipeline::visibleObjectsInFrustum(LLCamera& camera)
2084{
2085	for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); 
2086			iter != LLWorld::getInstance()->getRegionList().end(); ++iter)
2087	{
2088		LLViewerRegion* region = *iter;
2089
2090		for (U32 i = 0; i < LLViewerRegion::NUM_PARTITIONS; i++)
2091		{
2092			LLSpatialPartition* part = region->getSpatialPartition(i);
2093			if (part)
2094			{
2095				if (hasRenderType(part->mDrawableType))
2096				{
2097					if (part->visibleObjectsInFrustum(camera))
2098					{
2099						return TRUE;
2100					}
2101				}
2102			}
2103		}
2104	}
2105
2106	return FALSE;
2107}
2108
2109BOOL LLPipeline::getVisibleExtents(LLCamera& camera, LLVector3& min, LLVector3& max)
2110{
2111	const F32 X = 65536.f;
2112
2113	min = LLVector3(X,X,X);
2114	max = LLVector3(-X,-X,-X);
2115
2116	U32 saved_camera_id = LLViewerCamera::sCurCameraID;
2117	LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WORLD;
2118
2119	BOOL res = TRUE;
2120
2121	for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); 
2122			iter != LLWorld::getInstance()->getRegionList().end(); ++iter)
2123	{
2124		LLViewerRegion* region = *iter;
2125
2126		for (U32 i = 0; i < LLViewerRegion::NUM_PARTITIONS; i++)
2127		{
2128			LLSpatialPartition* part = region->getSpatialPartition(i);
2129			if (part)
2130			{
2131				if (hasRenderType(part->mDrawableType))
2132				{
2133					if (!part->getVisibleExtents(camera, min, max))
2134					{
2135						res = FALSE;
2136					}
2137				}
2138			}
2139		}
2140	}
2141
2142	LLViewerCamera::sCurCameraID = saved_camera_id;
2143
2144	return res;
2145}
2146
2147static LLFastTimer::DeclareTimer FTM_CU