diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp
index 2b1f4b138fc4749d8afe32c4ab557dac36291090..95f8785c90a1801e48e46ea797894b2848be0124 100644
--- a/indra/newview/llviewerdisplay.cpp
+++ b/indra/newview/llviewerdisplay.cpp
@@ -705,9 +705,6 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
 		LLGLState::checkTextureChannels();
 		LLGLState::checkClientArrays();
 
-		BOOL to_texture = gPipeline.canUseVertexShaders() &&
-						LLPipeline::sRenderGlow;
-
 		LLAppViewer::instance()->pingMainloopTimeout("Display:Swap");
 		
 		{ 
@@ -914,31 +911,28 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
 
 		stop_glerror();
 
-		if (to_texture)
-		{
-			gGL.setColorMask(true, true);
-					
-			if (LLPipeline::sRenderDeferred)
-			{
-				gPipeline.mDeferredScreen.bindTarget();
-				glClearColor(1,0,1,1);
-				gPipeline.mDeferredScreen.clear();
-			}
-			else
-			{
-				gPipeline.mScreen.bindTarget();
-				if (LLPipeline::sUnderWaterRender && !gPipeline.canUseWindLightShaders())
-				{
-					const LLColor4 &col = LLEnvironment::instance().getCurrentWater()->getWaterFogColor();
-					glClearColor(col.mV[0], col.mV[1], col.mV[2], 0.f);
-				}
-				gPipeline.mScreen.clear();
-			}
-			
-			gGL.setColorMask(true, false);
-		}
-		
-		LLAppViewer::instance()->pingMainloopTimeout("Display:RenderGeom");
+        gGL.setColorMask(true, true);
+
+        if (LLPipeline::sRenderDeferred)
+        {
+            gPipeline.mDeferredScreen.bindTarget();
+            glClearColor(1, 0, 1, 1);
+            gPipeline.mDeferredScreen.clear();
+        }
+        else
+        {
+            gPipeline.mScreen.bindTarget();
+            if (LLPipeline::sUnderWaterRender && !gPipeline.canUseWindLightShaders())
+            {
+                const LLColor4 &col = LLEnvironment::instance().getCurrentWater()->getWaterFogColor();
+                glClearColor(col.mV[0], col.mV[1], col.mV[2], 0.f);
+            }
+            gPipeline.mScreen.clear();
+        }
+
+        gGL.setColorMask(true, false);
+
+        LLAppViewer::instance()->pingMainloopTimeout("Display:RenderGeom");
 		
 		if (!(LLAppViewer::instance()->logoutRequestSent() && LLAppViewer::instance()->hasSavedFinalSnapshot())
 				&& !gRestoreGL)
@@ -1000,38 +994,20 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
 			}
 		}
 
-		LLAppViewer::instance()->pingMainloopTimeout("Display:RenderFlush");		
-		
-		if (to_texture)
-		{
-			if (LLPipeline::sRenderDeferred)
-			{
-				gPipeline.mDeferredScreen.flush();
-				if(LLRenderTarget::sUseFBO)
-				{
-					LLRenderTarget::copyContentsToFramebuffer(gPipeline.mDeferredScreen, 0, 0, gPipeline.mDeferredScreen.getWidth(), 
-															  gPipeline.mDeferredScreen.getHeight(), 0, 0, 
-															  gPipeline.mDeferredScreen.getWidth(), 
-															  gPipeline.mDeferredScreen.getHeight(), 
-															  GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, GL_NEAREST);
-				}
-			}
-			else
-			{
-				gPipeline.mScreen.flush();
-				if(LLRenderTarget::sUseFBO)
-				{				
-					LLRenderTarget::copyContentsToFramebuffer(gPipeline.mScreen, 0, 0, gPipeline.mScreen.getWidth(), 
-															  gPipeline.mScreen.getHeight(), 0, 0, 
-															  gPipeline.mScreen.getWidth(), 
-															  gPipeline.mScreen.getHeight(), 
-															  GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, GL_NEAREST);
-				}
-			}
-		}
+		LLAppViewer::instance()->pingMainloopTimeout("Display:RenderFlush");
 
-		if (LLPipeline::sRenderDeferred)
-		{
+        LLRenderTarget &rt = (gPipeline.sRenderDeferred ? gPipeline.mDeferredScreen : gPipeline.mScreen);
+        rt.flush();
+
+        if (rt.sUseFBO)
+        {
+            LLRenderTarget::copyContentsToFramebuffer(rt, 0, 0, rt.getWidth(), rt.getHeight(), 0, 0, rt.getWidth(),
+                                                      rt.getHeight(), GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT,
+                                                      GL_NEAREST);
+        }
+
+        if (LLPipeline::sRenderDeferred)
+        {
 			gPipeline.renderDeferredLighting(&gPipeline.mScreen);
 		}
 
@@ -1295,19 +1271,12 @@ void render_ui(F32 zoom_factor, int subfield)
 		gGL.popMatrix();
 	}
 
-	{
-		BOOL to_texture = gPipeline.canUseVertexShaders() &&
-							LLPipeline::sRenderGlow;
+    // Finalize scene
+    gPipeline.renderFinalize();
 
-		if (to_texture)
-		{
-			gPipeline.renderBloom(gSnapshot, zoom_factor, subfield);
-		}
-		
-		LL_RECORD_BLOCK_TIME(FTM_RENDER_HUD);
-		render_hud_elements();
-		render_hud_attachments();
-	}
+    LL_RECORD_BLOCK_TIME(FTM_RENDER_HUD);
+    render_hud_elements();
+	render_hud_attachments();
 
 	LLGLSDefault gls_default;
 	LLGLSUIDefault gls_ui;
diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index f3b8ad9008ca880bf0fe605bd7e324e8ce20e406..3f8f7b278f72b570964acca34fdc70db8a1e9c89 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -1049,25 +1049,19 @@ void LLPipeline::updateRenderBump()
 	sRenderBump = gSavedSettings.getBOOL("RenderObjectBump");
 }
 
-//static
+// static
 void LLPipeline::updateRenderDeferred()
 {
-	bool deferred = (bool(RenderDeferred && 
-					 LLRenderTarget::sUseFBO &&
-					 LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferred") &&	 
-					 LLPipeline::sRenderBump &&
-					 RenderAvatarVP &&
-					 WindLightUseAtmosShaders)) &&
-					!gUseWireframe;
-
-	sRenderDeferred = deferred;	
-	if (deferred)
-	{ //must render glow when rendering deferred since post effect pass is needed to present any lighting at all
-		sRenderGlow = true;
-	}
+    sRenderDeferred = !gUseWireframe &&
+                      RenderDeferred &&
+                      LLRenderTarget::sUseFBO &&
+                      LLPipeline::sRenderBump &&
+                      RenderAvatarVP &&
+                      WindLightUseAtmosShaders &&
+                      (bool) LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferred");
 }
 
-//static
+// static
 void LLPipeline::refreshCachedSettings()
 {
 	LLPipeline::sAutoMaskAlphaDeferred = gSavedSettings.getBOOL("RenderAutoMaskAlphaDeferred");
@@ -1259,24 +1253,20 @@ void LLPipeline::createGLBuffers()
 
 	GLuint resX = gViewerWindow->getWorldViewWidthRaw();
 	GLuint resY = gViewerWindow->getWorldViewHeightRaw();
-	
-	if (LLPipeline::sRenderGlow)
-	{ //screen space glow buffers
-		const U32 glow_res = llmax(1, 
-			llmin(512, 1 << gSavedSettings.getS32("RenderGlowResolutionPow")));
 
-		for (U32 i = 0; i < 3; i++)
-		{
-			mGlow[i].allocate(512,glow_res,GL_RGBA,FALSE,FALSE);
-		}
+    // allocate screen space glow buffers
+    const U32 glow_res = llmax(1, llmin(512, 1 << gSavedSettings.getS32("RenderGlowResolutionPow")));
+    for (U32 i = 0; i < 3; i++)
+    {
+        mGlow[i].allocate(512, glow_res, GL_RGBA, FALSE, FALSE);
+    }
 
-		allocateScreenBuffer(resX,resY);
-		mScreenWidth = 0;
-		mScreenHeight = 0;
-	}
-	
-	if (sRenderDeferred)
-	{
+    allocateScreenBuffer(resX, resY);
+    mScreenWidth = 0;
+    mScreenHeight = 0;
+
+    if (sRenderDeferred)
+    {
 		if (!mNoiseMap)
 		{
 			const U32 noiseRes = 128;
@@ -7544,641 +7534,630 @@ void LLPipeline::bindScreenToTexture()
 
 static LLTrace::BlockTimerStatHandle FTM_RENDER_BLOOM("Bloom");
 
-void LLPipeline::renderBloom(bool for_snapshot, F32 zoom_factor, int subfield)
+void LLPipeline::renderFinalize()
 {
-	if (!(gPipeline.canUseVertexShaders() &&
-		sRenderGlow))
-	{
-		return;
-	}
+    LLVertexBuffer::unbind();
+    LLGLState::checkStates();
+    LLGLState::checkTextureChannels();
 
-	LLVertexBuffer::unbind();
-	LLGLState::checkStates();
-	LLGLState::checkTextureChannels();
+    assertInitialized();
 
-	assertInitialized();
+    if (gUseWireframe)
+    {
+        glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
+    }
 
-	if (gUseWireframe)
-	{
-		glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
-	}
+    LLVector2 tc1(0, 0);
+    LLVector2 tc2((F32) mScreen.getWidth() * 2, (F32) mScreen.getHeight() * 2);
 
-	LLVector2 tc1(0,0);
-	LLVector2 tc2((F32) mScreen.getWidth()*2,
-				  (F32) mScreen.getHeight()*2);
+    LL_RECORD_BLOCK_TIME(FTM_RENDER_BLOOM);
+    gGL.color4f(1, 1, 1, 1);
+    LLGLDepthTest depth(GL_FALSE);
+    LLGLDisable blend(GL_BLEND);
+    LLGLDisable cull(GL_CULL_FACE);
 
-	LL_RECORD_BLOCK_TIME(FTM_RENDER_BLOOM);
-	gGL.color4f(1,1,1,1);
-	LLGLDepthTest depth(GL_FALSE);
-	LLGLDisable blend(GL_BLEND);
-	LLGLDisable cull(GL_CULL_FACE);
-	
-	enableLightsFullbright();
+    enableLightsFullbright();
 
-	gGL.matrixMode(LLRender::MM_PROJECTION);
-	gGL.pushMatrix();
-	gGL.loadIdentity();
-	gGL.matrixMode(LLRender::MM_MODELVIEW);
-	gGL.pushMatrix();
-	gGL.loadIdentity();
+    gGL.matrixMode(LLRender::MM_PROJECTION);
+    gGL.pushMatrix();
+    gGL.loadIdentity();
+    gGL.matrixMode(LLRender::MM_MODELVIEW);
+    gGL.pushMatrix();
+    gGL.loadIdentity();
 
-	LLGLDisable test(GL_ALPHA_TEST);
+    LLGLDisable test(GL_ALPHA_TEST);
 
-	gGL.setColorMask(true, true);
-	glClearColor(0,0,0,0);
-		
-	{
-		{
-			LL_RECORD_BLOCK_TIME(FTM_RENDER_BLOOM_FBO);
-			mGlow[2].bindTarget();
-			mGlow[2].clear();
-		}
-		
-		gGlowExtractProgram.bind();
-		F32 minLum = llmax((F32) RenderGlowMinLuminance, 0.0f);
-		F32 maxAlpha = RenderGlowMaxExtractAlpha;		
-		F32 warmthAmount = RenderGlowWarmthAmount;	
-		LLVector3 lumWeights = RenderGlowLumWeights;
-		LLVector3 warmthWeights = RenderGlowWarmthWeights;
-
-
-		gGlowExtractProgram.uniform1f(LLShaderMgr::GLOW_MIN_LUMINANCE, minLum);
-		gGlowExtractProgram.uniform1f(LLShaderMgr::GLOW_MAX_EXTRACT_ALPHA, maxAlpha);
-		gGlowExtractProgram.uniform3f(LLShaderMgr::GLOW_LUM_WEIGHTS, lumWeights.mV[0], lumWeights.mV[1], lumWeights.mV[2]);
-		gGlowExtractProgram.uniform3f(LLShaderMgr::GLOW_WARMTH_WEIGHTS, warmthWeights.mV[0], warmthWeights.mV[1], warmthWeights.mV[2]);
-		gGlowExtractProgram.uniform1f(LLShaderMgr::GLOW_WARMTH_AMOUNT, warmthAmount);
-		LLGLEnable blend_on(GL_BLEND);
-		LLGLEnable test(GL_ALPHA_TEST);
-		
-		gGL.setSceneBlendType(LLRender::BT_ADD_WITH_ALPHA);
-		
-		mScreen.bindTexture(0, 0, LLTexUnit::TFO_POINT);
-		
-		gGL.color4f(1,1,1,1);
-		gPipeline.enableLightsFullbright();
-		gGL.begin(LLRender::TRIANGLE_STRIP);
-		gGL.texCoord2f(tc1.mV[0], tc1.mV[1]);
-		gGL.vertex2f(-1,-1);
-		
-		gGL.texCoord2f(tc1.mV[0], tc2.mV[1]);
-		gGL.vertex2f(-1,3);
-		
-		gGL.texCoord2f(tc2.mV[0], tc1.mV[1]);
-		gGL.vertex2f(3,-1);
-		
-		gGL.end();
-		
-		gGL.getTexUnit(0)->unbind(mScreen.getUsage());
+    gGL.setColorMask(true, true);
+    glClearColor(0, 0, 0, 0);
 
-		mGlow[2].flush();
-	}
+    if (sRenderGlow)
+    {
+        {
+            LL_RECORD_BLOCK_TIME(FTM_RENDER_BLOOM_FBO);
+            mGlow[2].bindTarget();
+            mGlow[2].clear();
+        }
 
-	tc1.setVec(0,0);
-	tc2.setVec(2,2);
+        gGlowExtractProgram.bind();
+        F32 minLum = llmax((F32) RenderGlowMinLuminance, 0.0f);
+        F32 maxAlpha = RenderGlowMaxExtractAlpha;
+        F32 warmthAmount = RenderGlowWarmthAmount;
+        LLVector3 lumWeights = RenderGlowLumWeights;
+        LLVector3 warmthWeights = RenderGlowWarmthWeights;
 
-	// power of two between 1 and 1024
-	U32 glowResPow = RenderGlowResolutionPow;
-	const U32 glow_res = llmax(1, 
-		llmin(1024, 1 << glowResPow));
+        gGlowExtractProgram.uniform1f(LLShaderMgr::GLOW_MIN_LUMINANCE, minLum);
+        gGlowExtractProgram.uniform1f(LLShaderMgr::GLOW_MAX_EXTRACT_ALPHA, maxAlpha);
+        gGlowExtractProgram.uniform3f(LLShaderMgr::GLOW_LUM_WEIGHTS, lumWeights.mV[0], lumWeights.mV[1],
+                                      lumWeights.mV[2]);
+        gGlowExtractProgram.uniform3f(LLShaderMgr::GLOW_WARMTH_WEIGHTS, warmthWeights.mV[0], warmthWeights.mV[1],
+                                      warmthWeights.mV[2]);
+        gGlowExtractProgram.uniform1f(LLShaderMgr::GLOW_WARMTH_AMOUNT, warmthAmount);
+        LLGLEnable blend_on(GL_BLEND);
+        LLGLEnable test(GL_ALPHA_TEST);
 
-	S32 kernel = RenderGlowIterations*2;
-	F32 delta = RenderGlowWidth / glow_res;
-	// Use half the glow width if we have the res set to less than 9 so that it looks
-	// almost the same in either case.
-	if (glowResPow < 9)
-	{
-		delta *= 0.5f;
-	}
-	F32 strength = RenderGlowStrength;
+        gGL.setSceneBlendType(LLRender::BT_ADD_WITH_ALPHA);
 
-	gGlowProgram.bind();
-	gGlowProgram.uniform1f(LLShaderMgr::GLOW_STRENGTH, strength);
+        mScreen.bindTexture(0, 0, LLTexUnit::TFO_POINT);
 
-	for (S32 i = 0; i < kernel; i++)
-	{
-		{
-			LL_RECORD_BLOCK_TIME(FTM_RENDER_BLOOM_FBO);
-			mGlow[i%2].bindTarget();
-			mGlow[i%2].clear();
-		}
-			
-		if (i == 0)
-		{
-			gGL.getTexUnit(0)->bind(&mGlow[2]);
-		}
-		else
-		{
-			gGL.getTexUnit(0)->bind(&mGlow[(i-1)%2]);
-		}
+        gGL.color4f(1, 1, 1, 1);
+        gPipeline.enableLightsFullbright();
+        gGL.begin(LLRender::TRIANGLE_STRIP);
+        gGL.texCoord2f(tc1.mV[0], tc1.mV[1]);
+        gGL.vertex2f(-1, -1);
 
-		if (i%2 == 0)
-		{
-			gGlowProgram.uniform2f(LLShaderMgr::GLOW_DELTA, delta, 0);
-		}
-		else
-		{
-			gGlowProgram.uniform2f(LLShaderMgr::GLOW_DELTA, 0, delta);
-		}
+        gGL.texCoord2f(tc1.mV[0], tc2.mV[1]);
+        gGL.vertex2f(-1, 3);
 
-		gGL.begin(LLRender::TRIANGLE_STRIP);
-		gGL.texCoord2f(tc1.mV[0], tc1.mV[1]);
-		gGL.vertex2f(-1,-1);
-		
-		gGL.texCoord2f(tc1.mV[0], tc2.mV[1]);
-		gGL.vertex2f(-1,3);
-		
-		gGL.texCoord2f(tc2.mV[0], tc1.mV[1]);
-		gGL.vertex2f(3,-1);
-		
-		gGL.end();
-		
-		mGlow[i%2].flush();
-	}
+        gGL.texCoord2f(tc2.mV[0], tc1.mV[1]);
+        gGL.vertex2f(3, -1);
 
-	gGlowProgram.unbind();
+        gGL.end();
 
-	/*if (LLRenderTarget::sUseFBO)
-	{
-		LL_RECORD_BLOCK_TIME(FTM_RENDER_BLOOM_FBO);
-		glBindFramebuffer(GL_FRAMEBUFFER, 0);
-	}*/
+        gGL.getTexUnit(0)->unbind(mScreen.getUsage());
 
-	gGLViewport[0] = gViewerWindow->getWorldViewRectRaw().mLeft;
-	gGLViewport[1] = gViewerWindow->getWorldViewRectRaw().mBottom;
-	gGLViewport[2] = gViewerWindow->getWorldViewRectRaw().getWidth();
-	gGLViewport[3] = gViewerWindow->getWorldViewRectRaw().getHeight();
-	glViewport(gGLViewport[0], gGLViewport[1], gGLViewport[2], gGLViewport[3]);
+        mGlow[2].flush();
 
-	tc2.setVec((F32) mScreen.getWidth(),
-			(F32) mScreen.getHeight());
+        tc1.setVec(0, 0);
+        tc2.setVec(2, 2);
 
-	gGL.flush();
-	
-	LLVertexBuffer::unbind();
+        // power of two between 1 and 1024
+        U32 glowResPow = RenderGlowResolutionPow;
+        const U32 glow_res = llmax(1, llmin(1024, 1 << glowResPow));
 
-	if (LLPipeline::sRenderDeferred)
-	{
+        S32 kernel = RenderGlowIterations * 2;
+        F32 delta = RenderGlowWidth / glow_res;
+        // Use half the glow width if we have the res set to less than 9 so that it looks
+        // almost the same in either case.
+        if (glowResPow < 9)
+        {
+            delta *= 0.5f;
+        }
+        F32 strength = RenderGlowStrength;
 
-		bool dof_enabled = !LLViewerCamera::getInstance()->cameraUnderWater() &&
-			(RenderDepthOfFieldInEditMode || !LLToolMgr::getInstance()->inBuildMode()) &&
-							RenderDepthOfField;
+        gGlowProgram.bind();
+        gGlowProgram.uniform1f(LLShaderMgr::GLOW_STRENGTH, strength);
 
+        for (S32 i = 0; i < kernel; i++)
+        {
+            {
+                LL_RECORD_BLOCK_TIME(FTM_RENDER_BLOOM_FBO);
+                mGlow[i % 2].bindTarget();
+                mGlow[i % 2].clear();
+            }
 
-		bool multisample = RenderFSAASamples > 1 && mFXAABuffer.isComplete();
+            if (i == 0)
+            {
+                gGL.getTexUnit(0)->bind(&mGlow[2]);
+            }
+            else
+            {
+                gGL.getTexUnit(0)->bind(&mGlow[(i - 1) % 2]);
+            }
 
-		gViewerWindow->setup3DViewport();
-				
-		if (dof_enabled)
-		{
-			LLGLSLShader* shader = &gDeferredPostProgram;
-			LLGLDisable blend(GL_BLEND);
+            if (i % 2 == 0)
+            {
+                gGlowProgram.uniform2f(LLShaderMgr::GLOW_DELTA, delta, 0);
+            }
+            else
+            {
+                gGlowProgram.uniform2f(LLShaderMgr::GLOW_DELTA, 0, delta);
+            }
 
-			//depth of field focal plane calculations
-			static F32 current_distance = 16.f;
-			static F32 start_distance = 16.f;
-			static F32 transition_time = 1.f;
+            gGL.begin(LLRender::TRIANGLE_STRIP);
+            gGL.texCoord2f(tc1.mV[0], tc1.mV[1]);
+            gGL.vertex2f(-1, -1);
 
-			LLVector3 focus_point;
+            gGL.texCoord2f(tc1.mV[0], tc2.mV[1]);
+            gGL.vertex2f(-1, 3);
 
-			LLViewerObject* obj = LLViewerMediaFocus::getInstance()->getFocusedObject();
-			if (obj && obj->mDrawable && obj->isSelected())
-			{ //focus on selected media object
-				S32 face_idx = LLViewerMediaFocus::getInstance()->getFocusedFace();
-				if (obj && obj->mDrawable)
-				{
-					LLFace* face = obj->mDrawable->getFace(face_idx);
-					if (face)
-					{
-						focus_point = face->getPositionAgent();
-					}
-				}
-			}
-		
-			if (focus_point.isExactlyZero())
-			{
-				if (LLViewerJoystick::getInstance()->getOverrideCamera())
-				{ //focus on point under cursor
-					focus_point.set(gDebugRaycastIntersection.getF32ptr());
-				}
-				else if (gAgentCamera.cameraMouselook())
-				{ //focus on point under mouselook crosshairs
-					LLVector4a result;
-					result.clear();
+            gGL.texCoord2f(tc2.mV[0], tc1.mV[1]);
+            gGL.vertex2f(3, -1);
 
-					gViewerWindow->cursorIntersect(-1, -1, 512.f, NULL, -1, FALSE, FALSE,
-													NULL,
-													&result);
+            gGL.end();
 
-					focus_point.set(result.getF32ptr());
-				}
-				else
-				{
-					//focus on alt-zoom target
-					LLViewerRegion* region = gAgent.getRegion();
-					if (region)
-					{
-						focus_point = LLVector3(gAgentCamera.getFocusGlobal()-region->getOriginGlobal());
-					}
-				}
-			}
+            mGlow[i % 2].flush();
+        }
 
-			LLVector3 eye = LLViewerCamera::getInstance()->getOrigin();
-			F32 target_distance = 16.f;
-			if (!focus_point.isExactlyZero())
-			{
-				target_distance = LLViewerCamera::getInstance()->getAtAxis() * (focus_point-eye);
-			}
+        gGlowProgram.unbind();
+    }
+    else // !sRenderGlow, skip the glow ping-pong and just clear the result target
+    {
+        mGlow[1].bindTarget();
+        mGlow[1].clear();
+        mGlow[1].flush();
+    }
 
-			if (transition_time >= 1.f &&
-				fabsf(current_distance-target_distance)/current_distance > 0.01f)
-			{ //large shift happened, interpolate smoothly to new target distance
-				transition_time = 0.f;
-				start_distance = current_distance;
-			}
-			else if (transition_time < 1.f)
-			{ //currently in a transition, continue interpolating
-				transition_time += 1.f/CameraFocusTransitionTime*gFrameIntervalSeconds.value();
-				transition_time = llmin(transition_time, 1.f);
+    gGLViewport[0] = gViewerWindow->getWorldViewRectRaw().mLeft;
+    gGLViewport[1] = gViewerWindow->getWorldViewRectRaw().mBottom;
+    gGLViewport[2] = gViewerWindow->getWorldViewRectRaw().getWidth();
+    gGLViewport[3] = gViewerWindow->getWorldViewRectRaw().getHeight();
+    glViewport(gGLViewport[0], gGLViewport[1], gGLViewport[2], gGLViewport[3]);
 
-				F32 t = cosf(transition_time*F_PI+F_PI)*0.5f+0.5f;
-				current_distance = start_distance + (target_distance-start_distance)*t;
-			}
-			else
-			{ //small or no change, just snap to target distance
-				current_distance = target_distance;
-			}
+    tc2.setVec((F32) mScreen.getWidth(), (F32) mScreen.getHeight());
 
-			//convert to mm
-			F32 subject_distance = current_distance*1000.f;
-			F32 fnumber = CameraFNumber;
-			F32 default_focal_length = CameraFocalLength;
+    gGL.flush();
 
-			F32 fov = LLViewerCamera::getInstance()->getView();
-		
-			const F32 default_fov = CameraFieldOfView * F_PI/180.f;
-		
-			//F32 aspect_ratio = (F32) mScreen.getWidth()/(F32)mScreen.getHeight();
-		
-			F32 dv = 2.f*default_focal_length * tanf(default_fov/2.f);
+    LLVertexBuffer::unbind();
 
-			F32 focal_length = dv/(2*tanf(fov/2.f));
-		 
-			//F32 tan_pixel_angle = tanf(LLDrawable::sCurPixelAngle);
-	
-			// from wikipedia -- c = |s2-s1|/s2 * f^2/(N(S1-f))
-			// where	 N = fnumber
-			//			 s2 = dot distance
-			//			 s1 = subject distance
-			//			 f = focal length
-			//	
+    if (LLPipeline::sRenderDeferred)
+    {
 
-			F32 blur_constant = focal_length*focal_length/(fnumber*(subject_distance-focal_length));
-			blur_constant /= 1000.f; //convert to meters for shader
-			F32 magnification = focal_length/(subject_distance-focal_length);
+        bool dof_enabled = !LLViewerCamera::getInstance()->cameraUnderWater() &&
+                           (RenderDepthOfFieldInEditMode || !LLToolMgr::getInstance()->inBuildMode()) &&
+                           RenderDepthOfField;
 
-			{ //build diffuse+bloom+CoF
-				mDeferredLight.bindTarget();
-				shader = &gDeferredCoFProgram;
+        bool multisample = RenderFSAASamples > 1 && mFXAABuffer.isComplete();
 
-				bindDeferredShader(*shader);
+        gViewerWindow->setup3DViewport();
 
-				S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mScreen.getUsage());
-				if (channel > -1)
-				{
-					mScreen.bindTexture(0, channel);
-				}
+        if (dof_enabled)
+        {
+            LLGLSLShader *shader = &gDeferredPostProgram;
+            LLGLDisable blend(GL_BLEND);
 
-				shader->uniform1f(LLShaderMgr::DOF_FOCAL_DISTANCE, -subject_distance/1000.f);
-				shader->uniform1f(LLShaderMgr::DOF_BLUR_CONSTANT, blur_constant);
-				shader->uniform1f(LLShaderMgr::DOF_TAN_PIXEL_ANGLE, tanf(1.f/LLDrawable::sCurPixelAngle));
-				shader->uniform1f(LLShaderMgr::DOF_MAGNIFICATION, magnification);
-				shader->uniform1f(LLShaderMgr::DOF_MAX_COF, CameraMaxCoF);
-				shader->uniform1f(LLShaderMgr::DOF_RES_SCALE, CameraDoFResScale);
+            // depth of field focal plane calculations
+            static F32 current_distance = 16.f;
+            static F32 start_distance = 16.f;
+            static F32 transition_time = 1.f;
 
-				gGL.begin(LLRender::TRIANGLE_STRIP);
-				gGL.texCoord2f(tc1.mV[0], tc1.mV[1]);
-				gGL.vertex2f(-1,-1);
-		
-				gGL.texCoord2f(tc1.mV[0], tc2.mV[1]);
-				gGL.vertex2f(-1,3);
-		
-				gGL.texCoord2f(tc2.mV[0], tc1.mV[1]);
-				gGL.vertex2f(3,-1);
-		
-				gGL.end();
+            LLVector3 focus_point;
 
-				unbindDeferredShader(*shader);
-				mDeferredLight.flush();
-			}
+            LLViewerObject *obj = LLViewerMediaFocus::getInstance()->getFocusedObject();
+            if (obj && obj->mDrawable && obj->isSelected())
+            { // focus on selected media object
+                S32 face_idx = LLViewerMediaFocus::getInstance()->getFocusedFace();
+                if (obj && obj->mDrawable)
+                {
+                    LLFace *face = obj->mDrawable->getFace(face_idx);
+                    if (face)
+                    {
+                        focus_point = face->getPositionAgent();
+                    }
+                }
+            }
 
-			U32 dof_width = (U32) (mScreen.getWidth()*CameraDoFResScale);
-			U32 dof_height = (U32) (mScreen.getHeight()*CameraDoFResScale);
-			
-			{ //perform DoF sampling at half-res (preserve alpha channel)
-				mScreen.bindTarget();
-				glViewport(0,0, dof_width, dof_height);
-				gGL.setColorMask(true, false);
+            if (focus_point.isExactlyZero())
+            {
+                if (LLViewerJoystick::getInstance()->getOverrideCamera())
+                { // focus on point under cursor
+                    focus_point.set(gDebugRaycastIntersection.getF32ptr());
+                }
+                else if (gAgentCamera.cameraMouselook())
+                { // focus on point under mouselook crosshairs
+                    LLVector4a result;
+                    result.clear();
 
-				shader = &gDeferredPostProgram;
-				bindDeferredShader(*shader);
-				S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mDeferredLight.getUsage());
-				if (channel > -1)
-				{
-					mDeferredLight.bindTexture(0, channel);
-				}
+                    gViewerWindow->cursorIntersect(-1, -1, 512.f, NULL, -1, FALSE, FALSE, NULL, &result);
 
-				shader->uniform1f(LLShaderMgr::DOF_MAX_COF, CameraMaxCoF);
-				shader->uniform1f(LLShaderMgr::DOF_RES_SCALE, CameraDoFResScale);
-				
-				gGL.begin(LLRender::TRIANGLE_STRIP);
-				gGL.texCoord2f(tc1.mV[0], tc1.mV[1]);
-				gGL.vertex2f(-1,-1);
-		
-				gGL.texCoord2f(tc1.mV[0], tc2.mV[1]);
-				gGL.vertex2f(-1,3);
-		
-				gGL.texCoord2f(tc2.mV[0], tc1.mV[1]);
-				gGL.vertex2f(3,-1);
-		
-				gGL.end();
+                    focus_point.set(result.getF32ptr());
+                }
+                else
+                {
+                    // focus on alt-zoom target
+                    LLViewerRegion *region = gAgent.getRegion();
+                    if (region)
+                    {
+                        focus_point = LLVector3(gAgentCamera.getFocusGlobal() - region->getOriginGlobal());
+                    }
+                }
+            }
 
-				unbindDeferredShader(*shader);
-				mScreen.flush();
-				gGL.setColorMask(true, true);
-			}
-	
-			{ //combine result based on alpha
-				if (multisample)
-				{
-					mDeferredLight.bindTarget();
-					glViewport(0, 0, mDeferredScreen.getWidth(), mDeferredScreen.getHeight());
-				}
-				else
-				{
-					gGLViewport[0] = gViewerWindow->getWorldViewRectRaw().mLeft;
-					gGLViewport[1] = gViewerWindow->getWorldViewRectRaw().mBottom;
-					gGLViewport[2] = gViewerWindow->getWorldViewRectRaw().getWidth();
-					gGLViewport[3] = gViewerWindow->getWorldViewRectRaw().getHeight();
-					glViewport(gGLViewport[0], gGLViewport[1], gGLViewport[2], gGLViewport[3]);
-				}
+            LLVector3 eye = LLViewerCamera::getInstance()->getOrigin();
+            F32 target_distance = 16.f;
+            if (!focus_point.isExactlyZero())
+            {
+                target_distance = LLViewerCamera::getInstance()->getAtAxis() * (focus_point - eye);
+            }
 
-				shader = &gDeferredDoFCombineProgram;
-				bindDeferredShader(*shader);
-				
-				S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mScreen.getUsage());
-				if (channel > -1)
-				{
-					mScreen.bindTexture(0, channel);
-				}
+            if (transition_time >= 1.f && fabsf(current_distance - target_distance) / current_distance > 0.01f)
+            { // large shift happened, interpolate smoothly to new target distance
+                transition_time = 0.f;
+                start_distance = current_distance;
+            }
+            else if (transition_time < 1.f)
+            { // currently in a transition, continue interpolating
+                transition_time += 1.f / CameraFocusTransitionTime * gFrameIntervalSeconds.value();
+                transition_time = llmin(transition_time, 1.f);
 
-				shader->uniform1f(LLShaderMgr::DOF_MAX_COF, CameraMaxCoF);
-				shader->uniform1f(LLShaderMgr::DOF_RES_SCALE, CameraDoFResScale);
-				shader->uniform1f(LLShaderMgr::DOF_WIDTH, dof_width-1);
-				shader->uniform1f(LLShaderMgr::DOF_HEIGHT, dof_height-1);
+                F32 t = cosf(transition_time * F_PI + F_PI) * 0.5f + 0.5f;
+                current_distance = start_distance + (target_distance - start_distance) * t;
+            }
+            else
+            { // small or no change, just snap to target distance
+                current_distance = target_distance;
+            }
 
-				gGL.begin(LLRender::TRIANGLE_STRIP);
-				gGL.texCoord2f(tc1.mV[0], tc1.mV[1]);
-				gGL.vertex2f(-1,-1);
-		
-				gGL.texCoord2f(tc1.mV[0], tc2.mV[1]);
-				gGL.vertex2f(-1,3);
-		
-				gGL.texCoord2f(tc2.mV[0], tc1.mV[1]);
-				gGL.vertex2f(3,-1);
-		
-				gGL.end();
+            // convert to mm
+            F32 subject_distance = current_distance * 1000.f;
+            F32 fnumber = CameraFNumber;
+            F32 default_focal_length = CameraFocalLength;
 
-				unbindDeferredShader(*shader);
+            F32 fov = LLViewerCamera::getInstance()->getView();
 
-				if (multisample)
-				{
-					mDeferredLight.flush();
-				}
-			}
-		}
-		else
-		{
-			if (multisample)
-			{
-				mDeferredLight.bindTarget();
-			}
-			LLGLSLShader* shader = &gDeferredPostNoDoFProgram;
-			
-			bindDeferredShader(*shader);
-							
-			S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mScreen.getUsage());
-			if (channel > -1)
-			{
-				mScreen.bindTexture(0, channel);
-			}
+            const F32 default_fov = CameraFieldOfView * F_PI / 180.f;
 
-			gGL.begin(LLRender::TRIANGLE_STRIP);
-			gGL.texCoord2f(tc1.mV[0], tc1.mV[1]);
-			gGL.vertex2f(-1,-1);
-		
-			gGL.texCoord2f(tc1.mV[0], tc2.mV[1]);
-			gGL.vertex2f(-1,3);
-		
-			gGL.texCoord2f(tc2.mV[0], tc1.mV[1]);
-			gGL.vertex2f(3,-1);
-		
-			gGL.end();
+            // F32 aspect_ratio = (F32) mScreen.getWidth()/(F32)mScreen.getHeight();
 
-			unbindDeferredShader(*shader);
+            F32 dv = 2.f * default_focal_length * tanf(default_fov / 2.f);
 
-			if (multisample)
-			{
-				mDeferredLight.flush();
-			}
-		}
+            F32 focal_length = dv / (2 * tanf(fov / 2.f));
 
-		if (multisample)
-		{
-			//bake out texture2D with RGBL for FXAA shader
-			mFXAABuffer.bindTarget();
-			
-			S32 width = mScreen.getWidth();
-			S32 height = mScreen.getHeight();
-			glViewport(0, 0, width, height);
+            // F32 tan_pixel_angle = tanf(LLDrawable::sCurPixelAngle);
 
-			LLGLSLShader* shader = &gGlowCombineFXAAProgram;
+            // from wikipedia -- c = |s2-s1|/s2 * f^2/(N(S1-f))
+            // where	 N = fnumber
+            //			 s2 = dot distance
+            //			 s1 = subject distance
+            //			 f = focal length
+            //
 
-			shader->bind();
-			shader->uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, width, height);
+            F32 blur_constant = focal_length * focal_length / (fnumber * (subject_distance - focal_length));
+            blur_constant /= 1000.f; // convert to meters for shader
+            F32 magnification = focal_length / (subject_distance - focal_length);
 
-			S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mDeferredLight.getUsage());
-			if (channel > -1)
-			{
-				mDeferredLight.bindTexture(0, channel);
-			}
-						
-			gGL.begin(LLRender::TRIANGLE_STRIP);
-			gGL.vertex2f(-1,-1);
-			gGL.vertex2f(-1,3);
-			gGL.vertex2f(3,-1);
-			gGL.end();
+            { // build diffuse+bloom+CoF
+                mDeferredLight.bindTarget();
+                shader = &gDeferredCoFProgram;
 
-			gGL.flush();
+                bindDeferredShader(*shader);
 
-			shader->disableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mDeferredLight.getUsage());
-			shader->unbind();
-			
-			mFXAABuffer.flush();
+                S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mScreen.getUsage());
+                if (channel > -1)
+                {
+                    mScreen.bindTexture(0, channel);
+                }
 
-			shader = &gFXAAProgram;
-			shader->bind();
+                shader->uniform1f(LLShaderMgr::DOF_FOCAL_DISTANCE, -subject_distance / 1000.f);
+                shader->uniform1f(LLShaderMgr::DOF_BLUR_CONSTANT, blur_constant);
+                shader->uniform1f(LLShaderMgr::DOF_TAN_PIXEL_ANGLE, tanf(1.f / LLDrawable::sCurPixelAngle));
+                shader->uniform1f(LLShaderMgr::DOF_MAGNIFICATION, magnification);
+                shader->uniform1f(LLShaderMgr::DOF_MAX_COF, CameraMaxCoF);
+                shader->uniform1f(LLShaderMgr::DOF_RES_SCALE, CameraDoFResScale);
 
-			channel = shader->enableTexture(LLShaderMgr::DIFFUSE_MAP, mFXAABuffer.getUsage());
-			if (channel > -1)
-			{
-				mFXAABuffer.bindTexture(0, channel, LLTexUnit::TFO_BILINEAR);
-			}
-			
-			gGLViewport[0] = gViewerWindow->getWorldViewRectRaw().mLeft;
-			gGLViewport[1] = gViewerWindow->getWorldViewRectRaw().mBottom;
-			gGLViewport[2] = gViewerWindow->getWorldViewRectRaw().getWidth();
-			gGLViewport[3] = gViewerWindow->getWorldViewRectRaw().getHeight();
-			glViewport(gGLViewport[0], gGLViewport[1], gGLViewport[2], gGLViewport[3]);
-
-			F32 scale_x = (F32) width/mFXAABuffer.getWidth();
-			F32 scale_y = (F32) height/mFXAABuffer.getHeight();
-			shader->uniform2f(LLShaderMgr::FXAA_TC_SCALE, scale_x, scale_y);
-			shader->uniform2f(LLShaderMgr::FXAA_RCP_SCREEN_RES, 1.f/width*scale_x, 1.f/height*scale_y);
-			shader->uniform4f(LLShaderMgr::FXAA_RCP_FRAME_OPT, -0.5f/width*scale_x, -0.5f/height*scale_y, 0.5f/width*scale_x, 0.5f/height*scale_y);
-			shader->uniform4f(LLShaderMgr::FXAA_RCP_FRAME_OPT2, -2.f/width*scale_x, -2.f/height*scale_y, 2.f/width*scale_x, 2.f/height*scale_y);
-			
-			gGL.begin(LLRender::TRIANGLE_STRIP);
-			gGL.vertex2f(-1,-1);
-			gGL.vertex2f(-1,3);
-			gGL.vertex2f(3,-1);
-			gGL.end();
+                gGL.begin(LLRender::TRIANGLE_STRIP);
+                gGL.texCoord2f(tc1.mV[0], tc1.mV[1]);
+                gGL.vertex2f(-1, -1);
 
-			gGL.flush();
-			shader->unbind();
-		}
-	}
-	else
-	{
-		U32 mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_TEXCOORD1;
-		LLPointer<LLVertexBuffer> buff = new LLVertexBuffer(mask, 0);
-		buff->allocateBuffer(3,0,TRUE);
+                gGL.texCoord2f(tc1.mV[0], tc2.mV[1]);
+                gGL.vertex2f(-1, 3);
 
-		LLStrider<LLVector3> v;
-		LLStrider<LLVector2> uv1;
-		LLStrider<LLVector2> uv2;
+                gGL.texCoord2f(tc2.mV[0], tc1.mV[1]);
+                gGL.vertex2f(3, -1);
 
-		buff->getVertexStrider(v);
-		buff->getTexCoord0Strider(uv1);
-		buff->getTexCoord1Strider(uv2);
-		
-		uv1[0] = LLVector2(0, 0);
-		uv1[1] = LLVector2(0, 2);
-		uv1[2] = LLVector2(2, 0);
-		
-		uv2[0] = LLVector2(0, 0);
-		uv2[1] = LLVector2(0, tc2.mV[1]*2.f);
-		uv2[2] = LLVector2(tc2.mV[0]*2.f, 0);
-		
-		v[0] = LLVector3(-1,-1,0);
-		v[1] = LLVector3(-1,3,0);
-		v[2] = LLVector3(3,-1,0);
-				
-		buff->flush();
+                gGL.end();
 
-		LLGLDisable blend(GL_BLEND);
+                unbindDeferredShader(*shader);
+                mDeferredLight.flush();
+            }
 
-		if (LLGLSLShader::sNoFixedFunction)
-		{
-			gGlowCombineProgram.bind();
-		}
-		else
-		{
-			//tex unit 0
-			gGL.getTexUnit(0)->setTextureColorBlend(LLTexUnit::TBO_REPLACE, LLTexUnit::TBS_TEX_COLOR);
-			//tex unit 1
-			gGL.getTexUnit(1)->setTextureColorBlend(LLTexUnit::TBO_ADD, LLTexUnit::TBS_TEX_COLOR, LLTexUnit::TBS_PREV_COLOR);
-		}
-		
-		gGL.getTexUnit(0)->bind(&mGlow[1]);
-		gGL.getTexUnit(1)->bind(&mScreen);
-		
-		LLGLEnable multisample(RenderFSAASamples > 0 ? GL_MULTISAMPLE_ARB : 0);
-		
-		buff->setBuffer(mask);
-		buff->drawArrays(LLRender::TRIANGLE_STRIP, 0, 3);
-		
-		if (LLGLSLShader::sNoFixedFunction)
-		{
-			gGlowCombineProgram.unbind();
-		}
-		else
-		{
-			gGL.getTexUnit(1)->disable();
-			gGL.getTexUnit(1)->setTextureBlendType(LLTexUnit::TB_MULT);
+            U32 dof_width = (U32)(mScreen.getWidth() * CameraDoFResScale);
+            U32 dof_height = (U32)(mScreen.getHeight() * CameraDoFResScale);
 
-			gGL.getTexUnit(0)->activate();
-			gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT);
-		}
-		
-	}
+            { // perform DoF sampling at half-res (preserve alpha channel)
+                mScreen.bindTarget();
+                glViewport(0, 0, dof_width, dof_height);
+                gGL.setColorMask(true, false);
 
-	gGL.setSceneBlendType(LLRender::BT_ALPHA);
+                shader = &gDeferredPostProgram;
+                bindDeferredShader(*shader);
+                S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mDeferredLight.getUsage());
+                if (channel > -1)
+                {
+                    mDeferredLight.bindTexture(0, channel);
+                }
 
-	if (hasRenderDebugMask(LLPipeline::RENDER_DEBUG_PHYSICS_SHAPES))
-	{
-		if (LLGLSLShader::sNoFixedFunction)
-		{
-			gSplatTextureRectProgram.bind();
-		}
+                shader->uniform1f(LLShaderMgr::DOF_MAX_COF, CameraMaxCoF);
+                shader->uniform1f(LLShaderMgr::DOF_RES_SCALE, CameraDoFResScale);
 
-		gGL.setColorMask(true, false);
+                gGL.begin(LLRender::TRIANGLE_STRIP);
+                gGL.texCoord2f(tc1.mV[0], tc1.mV[1]);
+                gGL.vertex2f(-1, -1);
 
-		LLVector2 tc1(0,0);
-		LLVector2 tc2((F32) gViewerWindow->getWorldViewWidthRaw()*2,
-				  (F32) gViewerWindow->getWorldViewHeightRaw()*2);
+                gGL.texCoord2f(tc1.mV[0], tc2.mV[1]);
+                gGL.vertex2f(-1, 3);
 
-		LLGLEnable blend(GL_BLEND);
-		gGL.color4f(1,1,1,0.75f);
+                gGL.texCoord2f(tc2.mV[0], tc1.mV[1]);
+                gGL.vertex2f(3, -1);
 
-		gGL.getTexUnit(0)->bind(&mPhysicsDisplay);
+                gGL.end();
 
-		gGL.begin(LLRender::TRIANGLES);
-		gGL.texCoord2f(tc1.mV[0], tc1.mV[1]);
-		gGL.vertex2f(-1,-1);
-		
-		gGL.texCoord2f(tc1.mV[0], tc2.mV[1]);
-		gGL.vertex2f(-1,3);
-		
-		gGL.texCoord2f(tc2.mV[0], tc1.mV[1]);
-		gGL.vertex2f(3,-1);
-		
-		gGL.end();
-		gGL.flush();
+                unbindDeferredShader(*shader);
+                mScreen.flush();
+                gGL.setColorMask(true, true);
+            }
 
-		if (LLGLSLShader::sNoFixedFunction)
-		{
-			gSplatTextureRectProgram.unbind();
-		}
-	}
+            { // combine result based on alpha
+                if (multisample)
+                {
+                    mDeferredLight.bindTarget();
+                    glViewport(0, 0, mDeferredScreen.getWidth(), mDeferredScreen.getHeight());
+                }
+                else
+                {
+                    gGLViewport[0] = gViewerWindow->getWorldViewRectRaw().mLeft;
+                    gGLViewport[1] = gViewerWindow->getWorldViewRectRaw().mBottom;
+                    gGLViewport[2] = gViewerWindow->getWorldViewRectRaw().getWidth();
+                    gGLViewport[3] = gViewerWindow->getWorldViewRectRaw().getHeight();
+                    glViewport(gGLViewport[0], gGLViewport[1], gGLViewport[2], gGLViewport[3]);
+                }
 
-	
-	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_STENCIL_BUFFER_BIT, GL_NEAREST);
-	}
-	
+                shader = &gDeferredDoFCombineProgram;
+                bindDeferredShader(*shader);
 
-	gGL.matrixMode(LLRender::MM_PROJECTION);
-	gGL.popMatrix();
-	gGL.matrixMode(LLRender::MM_MODELVIEW);
-	gGL.popMatrix();
+                S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mScreen.getUsage());
+                if (channel > -1)
+                {
+                    mScreen.bindTexture(0, channel);
+                }
 
-	LLVertexBuffer::unbind();
+                shader->uniform1f(LLShaderMgr::DOF_MAX_COF, CameraMaxCoF);
+                shader->uniform1f(LLShaderMgr::DOF_RES_SCALE, CameraDoFResScale);
+                shader->uniform1f(LLShaderMgr::DOF_WIDTH, dof_width - 1);
+                shader->uniform1f(LLShaderMgr::DOF_HEIGHT, dof_height - 1);
 
-	LLGLState::checkStates();
-	LLGLState::checkTextureChannels();
+                gGL.begin(LLRender::TRIANGLE_STRIP);
+                gGL.texCoord2f(tc1.mV[0], tc1.mV[1]);
+                gGL.vertex2f(-1, -1);
+
+                gGL.texCoord2f(tc1.mV[0], tc2.mV[1]);
+                gGL.vertex2f(-1, 3);
+
+                gGL.texCoord2f(tc2.mV[0], tc1.mV[1]);
+                gGL.vertex2f(3, -1);
+
+                gGL.end();
+
+                unbindDeferredShader(*shader);
+
+                if (multisample)
+                {
+                    mDeferredLight.flush();
+                }
+            }
+        }
+        else
+        {
+            if (multisample)
+            {
+                mDeferredLight.bindTarget();
+            }
+            LLGLSLShader *shader = &gDeferredPostNoDoFProgram;
+
+            bindDeferredShader(*shader);
+
+            S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mScreen.getUsage());
+            if (channel > -1)
+            {
+                mScreen.bindTexture(0, channel);
+            }
+
+            gGL.begin(LLRender::TRIANGLE_STRIP);
+            gGL.texCoord2f(tc1.mV[0], tc1.mV[1]);
+            gGL.vertex2f(-1, -1);
+
+            gGL.texCoord2f(tc1.mV[0], tc2.mV[1]);
+            gGL.vertex2f(-1, 3);
+
+            gGL.texCoord2f(tc2.mV[0], tc1.mV[1]);
+            gGL.vertex2f(3, -1);
+
+            gGL.end();
+
+            unbindDeferredShader(*shader);
+
+            if (multisample)
+            {
+                mDeferredLight.flush();
+            }
+        }
+
+        if (multisample)
+        {
+            // bake out texture2D with RGBL for FXAA shader
+            mFXAABuffer.bindTarget();
+
+            S32 width = mScreen.getWidth();
+            S32 height = mScreen.getHeight();
+            glViewport(0, 0, width, height);
+
+            LLGLSLShader *shader = &gGlowCombineFXAAProgram;
+
+            shader->bind();
+            shader->uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, width, height);
+
+            S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mDeferredLight.getUsage());
+            if (channel > -1)
+            {
+                mDeferredLight.bindTexture(0, channel);
+            }
+
+            gGL.begin(LLRender::TRIANGLE_STRIP);
+            gGL.vertex2f(-1, -1);
+            gGL.vertex2f(-1, 3);
+            gGL.vertex2f(3, -1);
+            gGL.end();
+
+            gGL.flush();
+
+            shader->disableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mDeferredLight.getUsage());
+            shader->unbind();
+
+            mFXAABuffer.flush();
+
+            shader = &gFXAAProgram;
+            shader->bind();
+
+            channel = shader->enableTexture(LLShaderMgr::DIFFUSE_MAP, mFXAABuffer.getUsage());
+            if (channel > -1)
+            {
+                mFXAABuffer.bindTexture(0, channel, LLTexUnit::TFO_BILINEAR);
+            }
+
+            gGLViewport[0] = gViewerWindow->getWorldViewRectRaw().mLeft;
+            gGLViewport[1] = gViewerWindow->getWorldViewRectRaw().mBottom;
+            gGLViewport[2] = gViewerWindow->getWorldViewRectRaw().getWidth();
+            gGLViewport[3] = gViewerWindow->getWorldViewRectRaw().getHeight();
+            glViewport(gGLViewport[0], gGLViewport[1], gGLViewport[2], gGLViewport[3]);
+
+            F32 scale_x = (F32) width / mFXAABuffer.getWidth();
+            F32 scale_y = (F32) height / mFXAABuffer.getHeight();
+            shader->uniform2f(LLShaderMgr::FXAA_TC_SCALE, scale_x, scale_y);
+            shader->uniform2f(LLShaderMgr::FXAA_RCP_SCREEN_RES, 1.f / width * scale_x, 1.f / height * scale_y);
+            shader->uniform4f(LLShaderMgr::FXAA_RCP_FRAME_OPT, -0.5f / width * scale_x, -0.5f / height * scale_y,
+                              0.5f / width * scale_x, 0.5f / height * scale_y);
+            shader->uniform4f(LLShaderMgr::FXAA_RCP_FRAME_OPT2, -2.f / width * scale_x, -2.f / height * scale_y,
+                              2.f / width * scale_x, 2.f / height * scale_y);
+
+            gGL.begin(LLRender::TRIANGLE_STRIP);
+            gGL.vertex2f(-1, -1);
+            gGL.vertex2f(-1, 3);
+            gGL.vertex2f(3, -1);
+            gGL.end();
+
+            gGL.flush();
+            shader->unbind();
+        }
+    }
+    else // not deferred
+    {
+        U32 mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_TEXCOORD1;
+        LLPointer<LLVertexBuffer> buff = new LLVertexBuffer(mask, 0);
+        buff->allocateBuffer(3, 0, TRUE);
+
+        LLStrider<LLVector3> v;
+        LLStrider<LLVector2> uv1;
+        LLStrider<LLVector2> uv2;
+
+        buff->getVertexStrider(v);
+        buff->getTexCoord0Strider(uv1);
+        buff->getTexCoord1Strider(uv2);
+
+        uv1[0] = LLVector2(0, 0);
+        uv1[1] = LLVector2(0, 2);
+        uv1[2] = LLVector2(2, 0);
+
+        uv2[0] = LLVector2(0, 0);
+        uv2[1] = LLVector2(0, tc2.mV[1] * 2.f);
+        uv2[2] = LLVector2(tc2.mV[0] * 2.f, 0);
+
+        v[0] = LLVector3(-1, -1, 0);
+        v[1] = LLVector3(-1, 3, 0);
+        v[2] = LLVector3(3, -1, 0);
+
+        buff->flush();
+
+        LLGLDisable blend(GL_BLEND);
+
+        if (LLGLSLShader::sNoFixedFunction)
+        {
+            gGlowCombineProgram.bind();
+        }
+        else
+        {
+            // tex unit 0
+            gGL.getTexUnit(0)->setTextureColorBlend(LLTexUnit::TBO_REPLACE, LLTexUnit::TBS_TEX_COLOR);
+            // tex unit 1
+            gGL.getTexUnit(1)->setTextureColorBlend(LLTexUnit::TBO_ADD, LLTexUnit::TBS_TEX_COLOR,
+                                                    LLTexUnit::TBS_PREV_COLOR);
+        }
+
+        gGL.getTexUnit(0)->bind(&mGlow[1]);
+        gGL.getTexUnit(1)->bind(&mScreen);
+
+        LLGLEnable multisample(RenderFSAASamples > 0 ? GL_MULTISAMPLE_ARB : 0);
+
+        buff->setBuffer(mask);
+        buff->drawArrays(LLRender::TRIANGLE_STRIP, 0, 3);
+
+        if (LLGLSLShader::sNoFixedFunction)
+        {
+            gGlowCombineProgram.unbind();
+        }
+        else
+        {
+            gGL.getTexUnit(1)->disable();
+            gGL.getTexUnit(1)->setTextureBlendType(LLTexUnit::TB_MULT);
+
+            gGL.getTexUnit(0)->activate();
+            gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT);
+        }
+    }
+
+    gGL.setSceneBlendType(LLRender::BT_ALPHA);
+
+    if (hasRenderDebugMask(LLPipeline::RENDER_DEBUG_PHYSICS_SHAPES))
+    {
+        if (LLGLSLShader::sNoFixedFunction)
+        {
+            gSplatTextureRectProgram.bind();
+        }
+
+        gGL.setColorMask(true, false);
+
+        LLVector2 tc1(0, 0);
+        LLVector2 tc2((F32) gViewerWindow->getWorldViewWidthRaw() * 2,
+                      (F32) gViewerWindow->getWorldViewHeightRaw() * 2);
+
+        LLGLEnable blend(GL_BLEND);
+        gGL.color4f(1, 1, 1, 0.75f);
+
+        gGL.getTexUnit(0)->bind(&mPhysicsDisplay);
+
+        gGL.begin(LLRender::TRIANGLES);
+        gGL.texCoord2f(tc1.mV[0], tc1.mV[1]);
+        gGL.vertex2f(-1, -1);
+
+        gGL.texCoord2f(tc1.mV[0], tc2.mV[1]);
+        gGL.vertex2f(-1, 3);
+
+        gGL.texCoord2f(tc2.mV[0], tc1.mV[1]);
+        gGL.vertex2f(3, -1);
+
+        gGL.end();
+        gGL.flush();
+
+        if (LLGLSLShader::sNoFixedFunction)
+        {
+            gSplatTextureRectProgram.unbind();
+        }
+    }
+
+    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_STENCIL_BUFFER_BIT, GL_NEAREST);
+    }
+
+    gGL.matrixMode(LLRender::MM_PROJECTION);
+    gGL.popMatrix();
+    gGL.matrixMode(LLRender::MM_MODELVIEW);
+    gGL.popMatrix();
+
+    LLVertexBuffer::unbind();
 
+    LLGLState::checkStates();
+    LLGLState::checkTextureChannels();
 }
 
 static LLTrace::BlockTimerStatHandle FTM_BIND_DEFERRED("Bind Deferred");
diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h
index 5a07bdebe3362e2435e5387a1541eec035c3160a..600bdd9d06dc1aba6baba86a462f9fca789267ea 100644
--- a/indra/newview/pipeline.h
+++ b/indra/newview/pipeline.h
@@ -139,7 +139,7 @@ class LLPipeline
 	void resetVertexBuffers(LLDrawable* drawable);
 	void generateImpostor(LLVOAvatar* avatar);
 	void bindScreenToTexture();
-	void renderBloom(bool for_snapshot, F32 zoom_factor = 1.f, int subfield = 0);
+	void renderFinalize();
 
 	void init();
 	void cleanup();