From 854e2eaf9a2ab150a820b28944363b6212ec7aae Mon Sep 17 00:00:00 2001
From: richard <none@none>
Date: Wed, 11 Nov 2009 12:01:17 -0800
Subject: [PATCH] added viewports to LLRenderTarget to speed up animation of
 sidetray

reviewed by Leyla
---
 indra/llrender/llrendertarget.cpp | 52 ++++++++++++++++++++++++++++---
 indra/llrender/llrendertarget.h   |  7 +++++
 indra/newview/pipeline.cpp        | 29 ++++++++++++-----
 indra/newview/pipeline.h          |  2 +-
 4 files changed, 78 insertions(+), 12 deletions(-)

diff --git a/indra/llrender/llrendertarget.cpp b/indra/llrender/llrendertarget.cpp
index d9520b3bf63..f0df3bcf90c 100644
--- a/indra/llrender/llrendertarget.cpp
+++ b/indra/llrender/llrendertarget.cpp
@@ -61,8 +61,11 @@ BOOL LLRenderTarget::sUseFBO = FALSE;
 LLRenderTarget::LLRenderTarget() :
 	mResX(0),
 	mResY(0),
+	mViewportWidth(0),
+	mViewportHeight(0),
 	mTex(0),
 	mFBO(0),
+	mColorFmt(0),
 	mDepth(0),
 	mStencil(0),
 	mUseDepth(FALSE),
@@ -86,13 +89,31 @@ void LLRenderTarget::setSampleBuffer(LLMultisampleBuffer* buffer)
 
 void LLRenderTarget::allocate(U32 resx, U32 resy, U32 color_fmt, BOOL depth, BOOL stencil, LLTexUnit::eTextureType usage, BOOL use_fbo)
 {
+	// only reallocate if something changed
+	if (mResX == resx
+		&& mResY == resy
+		&& mUseDepth == depth
+		&& mStencil == stencil
+		&& mUsage == usage
+		&& (mFBO != 0) == ((sUseFBO || use_fbo) && gGLManager.mHasFramebufferObject)
+		&& mColorFmt == color_fmt)
+	{
+		// nothing to do
+		return;
+	}
+		
 	stop_glerror();
 	mResX = resx;
 	mResY = resy;
+	// default viewport to entire texture
+	mViewportWidth = mResX;
+	mViewportHeight = mResY;
 
 	mStencil = stencil;
 	mUsage = usage;
 	mUseDepth = depth;
+	mFBO = 0;
+	mColorFmt = color_fmt;
 
 	release();
 
@@ -312,7 +333,7 @@ void LLRenderTarget::bindTarget()
 		}
 	}
 
-	glViewport(0, 0, mResX, mResY);
+	glViewport(0, 0, mViewportWidth, mViewportHeight);
 	sBoundTarget = this;
 }
 
@@ -515,12 +536,18 @@ BOOL LLRenderTarget::isComplete() const
 	return (!mTex.empty() || mDepth) ? TRUE : FALSE;
 }
 
+void LLRenderTarget::setViewport(U32 width, U32 height)
+{
+	mViewportWidth = llmin(width, mResX);
+	mViewportHeight = llmin(height, mResY);
+}
+
 void LLRenderTarget::getViewport(S32* viewport)
 {
 	viewport[0] = 0;
 	viewport[1] = 0;
-	viewport[2] = mResX;
-	viewport[3] = mResY;
+	viewport[2] = mViewportWidth;
+	viewport[3] = mViewportHeight;
 }
 
 //==================================================
@@ -581,7 +608,7 @@ void LLMultisampleBuffer::bindTarget(LLRenderTarget* ref)
 
 	check_framebuffer_status();
 
-	glViewport(0, 0, mResX, mResY);
+	glViewport(0, 0, mViewportWidth, mViewportHeight);
 
 	sBoundTarget = this;
 }
@@ -593,13 +620,30 @@ void LLMultisampleBuffer::allocate(U32 resx, U32 resy, U32 color_fmt, BOOL depth
 
 void LLMultisampleBuffer::allocate(U32 resx, U32 resy, U32 color_fmt, BOOL depth, BOOL stencil,  LLTexUnit::eTextureType usage, BOOL use_fbo, U32 samples )
 {
+	if (mResX == resx
+		&& mResY == resy
+		&& mUseDepth == depth
+		&& mStencil == stencil
+		&& mUsage == usage
+		&& (mFBO != 0) == ((sUseFBO || use_fbo) && gGLManager.mHasFramebufferObject)
+		&& mColorFmt == color_fmt
+		&& mSamples == samples)
+	{
+		// nothing to do
+		return;
+	}
+
 	stop_glerror();
 	mResX = resx;
 	mResY = resy;
+	mViewportWidth = mResX;
+	mViewportHeight = mResY;
 
 	mUsage = usage;
 	mUseDepth = depth;
 	mStencil = stencil;
+	mFBO = 0;
+	mColorFmt = color_fmt;
 
 	releaseSampleBuffer();
 
diff --git a/indra/llrender/llrendertarget.h b/indra/llrender/llrendertarget.h
index b7ebfc8f7f6..125747424c0 100644
--- a/indra/llrender/llrendertarget.h
+++ b/indra/llrender/llrendertarget.h
@@ -107,6 +107,9 @@ class LLRenderTarget
 	//uses scissor rect if in copy-to-texture mode
 	void clear(U32 mask = 0xFFFFFFFF);
 	
+	// override default viewport to a smaller size
+	void setViewport(U32 width, U32 height);
+
 	//get applied viewport
 	void getViewport(S32* viewport);
 
@@ -150,12 +153,16 @@ class LLRenderTarget
 	friend class LLMultisampleBuffer;
 	U32 mResX;
 	U32 mResY;
+	U32 mViewportWidth;
+	U32 mViewportHeight;
 	std::vector<U32> mTex;
 	U32 mFBO;
+	U32 mColorFmt;
 	U32 mDepth;
 	BOOL mStencil;
 	BOOL mUseDepth;
 	BOOL mRenderDepth;
+
 	LLTexUnit::eTextureType mUsage;
 	U32 mSamples;
 	LLMultisampleBuffer* mSampleBuffer;
diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index ba1732bc922..68410aca5d1 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -512,16 +512,18 @@ void LLPipeline::resizeScreenTexture()
 	LLFastTimer ft(FTM_RESIZE_SCREEN_TEXTURE);
 	if (gPipeline.canUseVertexShaders() && assertInitialized())
 	{
-		GLuint resX = gViewerWindow->getWorldViewWidth();
-		GLuint resY = gViewerWindow->getWorldViewHeight();
+		GLuint resX = gViewerWindow->getWindowDisplayWidth();
+		GLuint resY = gViewerWindow->getWindowDisplayHeight();
+		GLuint view_width = gViewerWindow->getWorldViewWidth();
+		GLuint view_height = gViewerWindow->getWorldViewHeight();
 	
-		allocateScreenBuffer(resX,resY);
+		allocateScreenBuffer(resX, resY, view_width, view_height);
 
 		llinfos << "RESIZED SCREEN TEXTURE: " << resX << "x" << resY << llendl;
 	}
 }
 
-void LLPipeline::allocateScreenBuffer(U32 resX, U32 resY)
+void LLPipeline::allocateScreenBuffer(U32 resX, U32 resY, U32 viewport_width, U32 viewport_height)
 {
 	U32 samples = gSavedSettings.getU32("RenderFSAASamples");
 
@@ -542,18 +544,24 @@ void LLPipeline::allocateScreenBuffer(U32 resX, U32 resY)
 		//allocate deferred rendering color buffers
 		mDeferredScreen.allocate(resX, resY, GL_RGBA, TRUE, TRUE, LLTexUnit::TT_RECT_TEXTURE, FALSE);
 		mDeferredDepth.allocate(resX, resY, 0, TRUE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE);
+		mDeferredScreen.setViewport(viewport_width, viewport_height);
+		mDeferredDepth.setViewport(viewport_width, viewport_height);
 		addDeferredAttachments(mDeferredScreen);
 		mScreen.allocate(resX, resY, GL_RGBA, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE);		
 		mEdgeMap.allocate(resX, resY, GL_ALPHA, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE);
+		mScreen.setViewport(viewport_width, viewport_height);
+		mEdgeMap.setViewport(viewport_width, viewport_height);
 
 		for (U32 i = 0; i < 3; i++)
 		{
 			mDeferredLight[i].allocate(resX, resY, GL_RGBA, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE);
+			mDeferredLight[i].setViewport(viewport_width, viewport_height);
 		}
 
 		for (U32 i = 0; i < 2; i++)
 		{
 			mGIMapPost[i].allocate(resX,resY, GL_RGB, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE);
+			mGIMapPost[i].setViewport(viewport_width, viewport_height);
 		}
 
 		F32 scale = gSavedSettings.getF32("RenderShadowResolutionScale");
@@ -561,6 +569,7 @@ void LLPipeline::allocateScreenBuffer(U32 resX, U32 resY)
 		for (U32 i = 0; i < 4; i++)
 		{
 			mShadow[i].allocate(U32(resX*scale),U32(resY*scale), 0, TRUE, FALSE, LLTexUnit::TT_RECT_TEXTURE);
+			mShadow[i].setViewport(viewport_width, viewport_height);
 		}
 
 
@@ -570,6 +579,7 @@ void LLPipeline::allocateScreenBuffer(U32 resX, U32 resY)
 		for (U32 i = 4; i < 6; i++)
 		{
 			mShadow[i].allocate(width, height, 0, TRUE, FALSE);
+			mShadow[i].setViewport(viewport_width, viewport_height);
 		}
 
 
@@ -577,16 +587,19 @@ void LLPipeline::allocateScreenBuffer(U32 resX, U32 resY)
 		width = nhpo2(resX)/2;
 		height = nhpo2(resY)/2;
 		mLuminanceMap.allocate(width,height, GL_RGBA, FALSE, FALSE);
+		mLuminanceMap.setViewport(viewport_width, viewport_height);
 	}
 	else
 	{
 		mScreen.allocate(resX, resY, GL_RGBA, TRUE, TRUE, LLTexUnit::TT_RECT_TEXTURE, FALSE);		
+		mScreen.setViewport(viewport_width, viewport_height);
 	}
 	
 
 	if (gGLManager.mHasFramebufferMultisample && samples > 1)
 	{
 		mSampleBuffer.allocate(resX,resY,GL_RGBA,TRUE,TRUE,LLTexUnit::TT_RECT_TEXTURE,FALSE,samples);
+		mSampleBuffer.setViewport(viewport_width, viewport_height);
 		mScreen.setSampleBuffer(&mSampleBuffer);
 
 		if (LLPipeline::sRenderDeferred)
@@ -698,8 +711,10 @@ void LLPipeline::createGLBuffers()
 
 	stop_glerror();
 
-	GLuint resX = gViewerWindow->getWorldViewWidth();
-	GLuint resY = gViewerWindow->getWorldViewHeight();
+	GLuint resX = gViewerWindow->getWindowDisplayWidth();
+	GLuint resY = gViewerWindow->getWindowDisplayHeight();
+	GLuint viewport_width = gViewerWindow->getWorldViewWidth();
+	GLuint viewport_height = gViewerWindow->getWorldViewHeight();
 	
 	if (LLPipeline::sRenderGlow)
 	{ //screen space glow buffers
@@ -711,7 +726,7 @@ void LLPipeline::createGLBuffers()
 			mGlow[i].allocate(512,glow_res,GL_RGBA,FALSE,FALSE);
 		}
 
-		allocateScreenBuffer(resX,resY);
+		allocateScreenBuffer(resX,resY, viewport_width, viewport_height);
 	}
 	
 	if (sRenderDeferred)
diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h
index ce50a374050..9193e19bb1a 100644
--- a/indra/newview/pipeline.h
+++ b/indra/newview/pipeline.h
@@ -111,7 +111,7 @@ class LLPipeline
 	void resizeScreenTexture();
 	void releaseGLBuffers();
 	void createGLBuffers();
-	void allocateScreenBuffer(U32 resX, U32 resY);
+	void allocateScreenBuffer(U32 resX, U32 resY, U32 viewport_width, U32 viewport_height);
 
 	void resetVertexBuffers(LLDrawable* drawable);
 	void setUseVBO(BOOL use_vbo);
-- 
GitLab