From 8c15a7e17fceeba9e55e254d7654c1a4f8c3b871 Mon Sep 17 00:00:00 2001
From: Dave Parks <davep@lindenlab.com>
Date: Tue, 7 Feb 2012 14:51:30 -0600
Subject: [PATCH] SH-2902 Fix for avatar bakes etc. getting garbage data
 sometimes.

---
 indra/newview/lldynamictexture.cpp | 28 ++++++++++++++++++++++++----
 indra/newview/pipeline.cpp         |  5 +++--
 2 files changed, 27 insertions(+), 6 deletions(-)

diff --git a/indra/newview/lldynamictexture.cpp b/indra/newview/lldynamictexture.cpp
index 5d6081a35cf..a93b2b71de3 100644
--- a/indra/newview/lldynamictexture.cpp
+++ b/indra/newview/lldynamictexture.cpp
@@ -125,8 +125,16 @@ BOOL LLViewerDynamicTexture::render()
 //-----------------------------------------------------------------------------
 void LLViewerDynamicTexture::preRender(BOOL clear_depth)
 {
-	{
-		// force rendering to on-screen portion of frame buffer
+	//only images up to 512x512 are supported
+	llassert(mFullHeight <= 512);
+	llassert(mFullWidth <= 512);
+
+	if (gGLManager.mHasFramebufferObject && gPipeline.mWaterDis.isComplete())
+	{ //using offscreen render target, just use the bottom left corner
+		mOrigin.set(0, 0);
+	}
+	else
+	{ // force rendering to on-screen portion of frame buffer
 		LLCoordScreen window_pos;
 		gViewerWindow->getWindow()->getPosition( &window_pos );
 		mOrigin.set(0, gViewerWindow->getWindowHeightRaw() - mFullHeight);  // top left corner
@@ -140,9 +148,9 @@ void LLViewerDynamicTexture::preRender(BOOL clear_depth)
 			mOrigin.mY += window_pos.mY;
 			mOrigin.mY = llmax(mOrigin.mY, 0) ;
 		}
-
-		gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
 	}
+
+	gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
 	// Set up camera
 	LLViewerCamera* camera = LLViewerCamera::getInstance();
 	mCamera.setOrigin(*camera);
@@ -208,6 +216,13 @@ BOOL LLViewerDynamicTexture::updateAllInstances()
 		return TRUE;
 	}
 
+	bool use_fbo = gGLManager.mHasFramebufferObject && gPipeline.mWaterDis.isComplete();
+
+	if (use_fbo)
+	{
+		gPipeline.mWaterDis.bindTarget();
+	}
+
 	LLGLSLShader::bindNoShader();
 	LLVertexBuffer::unbind();
 	
@@ -241,6 +256,11 @@ BOOL LLViewerDynamicTexture::updateAllInstances()
 		}
 	}
 
+	if (use_fbo)
+	{
+		gPipeline.mWaterDis.flush();
+	}
+
 	return ret;
 }
 
diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index dffc541001b..c8a8b910ea5 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -1076,10 +1076,11 @@ void LLPipeline::createGLBuffers()
 
 	if (LLPipeline::sWaterReflections)
 	{ //water reflection texture
-		U32 res = (U32) gSavedSettings.getS32("RenderWaterRefResolution");
+		U32 res = (U32) llmax(gSavedSettings.getS32("RenderWaterRefResolution"), 512);
 			
 		mWaterRef.allocate(res,res,GL_RGBA,TRUE,FALSE);
-		mWaterDis.allocate(res,res,GL_RGBA,TRUE,FALSE);
+		//always use FBO for mWaterDis so it can be used for avatar texture bakes
+		mWaterDis.allocate(res,res,GL_RGBA,TRUE,FALSE,LLTexUnit::TT_TEXTURE, true);
 	}
 
 	mHighlight.allocate(256,256,GL_RGBA, FALSE, FALSE);
-- 
GitLab