diff --git a/indra/llui/llui.cpp b/indra/llui/llui.cpp
index 87bf518aa17ca6c46b891627f344bc57eb9b7f7f..1dac622f32399f12c632f01ffb4bd6e4f2ea0bdc 100644
--- a/indra/llui/llui.cpp
+++ b/indra/llui/llui.cpp
@@ -724,9 +724,14 @@ void gl_draw_rotated_image(S32 x, S32 y, F32 degrees, LLTexture* image, const LL
 	gl_draw_scaled_rotated_image( x, y, image->getWidth(0), image->getHeight(0), degrees, image, color, uv_rect );
 }
 
-void gl_draw_scaled_rotated_image(S32 x, S32 y, S32 width, S32 height, F32 degrees, LLTexture* image, const LLColor4& color, const LLRectf& uv_rect)
+void gl_draw_scaled_target(S32 x, S32 y, S32 width, S32 height, LLRenderTarget* target, const LLColor4& color, const LLRectf& uv_rect)
 {
-	if (NULL == image)
+	gl_draw_scaled_rotated_image(x, y, width, height, 0.f, NULL, color, uv_rect, target);
+}
+
+void gl_draw_scaled_rotated_image(S32 x, S32 y, S32 width, S32 height, F32 degrees, LLTexture* image, const LLColor4& color, const LLRectf& uv_rect, LLRenderTarget* target)
+{
+	if (!image && !target)
 	{
 		llwarns << "image == NULL; aborting function" << llendl;
 		return;
@@ -734,8 +739,14 @@ void gl_draw_scaled_rotated_image(S32 x, S32 y, S32 width, S32 height, F32 degre
 
 	LLGLSUIDefault gls_ui;
 
-
-	gGL.getTexUnit(0)->bind(image, true);
+	if(image != NULL)
+	{
+		gGL.getTexUnit(0)->bind(image, true);
+	}
+	else
+	{
+		gGL.getTexUnit(0)->bind(target);
+	}
 
 	gGL.color4fv(color.mV);
 
@@ -788,7 +799,14 @@ void gl_draw_scaled_rotated_image(S32 x, S32 y, S32 width, S32 height, F32 degre
 
 		LLMatrix3 quat(0.f, 0.f, degrees*DEG_TO_RAD);
 		
-		gGL.getTexUnit(0)->bind(image, true);
+		if(image != NULL)
+		{
+			gGL.getTexUnit(0)->bind(image, true);
+		}
+		else
+		{
+			gGL.getTexUnit(0)->bind(target);
+		}
 
 		gGL.color4fv(color.mV);
 		
diff --git a/indra/llui/llui.h b/indra/llui/llui.h
index 28e84fa44410e55174ea478d1600f1786cc631c3..d3c88cfb5f87aa163e7a8d7f21d6ea6c6e9b268b 100644
--- a/indra/llui/llui.h
+++ b/indra/llui/llui.h
@@ -58,6 +58,7 @@ class LLUUID;
 class LLWindow;
 class LLView;
 class LLHelp;
+class LLRenderTarget;
 
 // UI colors
 extern const LLColor4 UI_VERTEX_COLOR;
@@ -93,8 +94,9 @@ void gl_washer_segment_2d(F32 outer_radius, F32 inner_radius, F32 start_radians,
 
 void gl_draw_image(S32 x, S32 y, LLTexture* image, const LLColor4& color = UI_VERTEX_COLOR, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f));
 void gl_draw_scaled_image(S32 x, S32 y, S32 width, S32 height, LLTexture* image, const LLColor4& color = UI_VERTEX_COLOR, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f));
+void gl_draw_scaled_target(S32 x, S32 y, S32 width, S32 height, LLRenderTarget* target, const LLColor4& color = UI_VERTEX_COLOR, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f));
 void gl_draw_rotated_image(S32 x, S32 y, F32 degrees, LLTexture* image, const LLColor4& color = UI_VERTEX_COLOR, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f));
-void gl_draw_scaled_rotated_image(S32 x, S32 y, S32 width, S32 height, F32 degrees,LLTexture* image, const LLColor4& color = UI_VERTEX_COLOR, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f));
+void gl_draw_scaled_rotated_image(S32 x, S32 y, S32 width, S32 height, F32 degrees,LLTexture* image, const LLColor4& color = UI_VERTEX_COLOR, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f), LLRenderTarget* target = NULL);
 void gl_draw_scaled_image_with_border(S32 x, S32 y, S32 border_width, S32 border_height, S32 width, S32 height, LLTexture* image, const LLColor4 &color, BOOL solid_color = FALSE, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f));
 void gl_draw_scaled_image_with_border(S32 x, S32 y, S32 width, S32 height, LLTexture* image, const LLColor4 &color, BOOL solid_color = FALSE, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f), const LLRectf& scale_rect = LLRectf(0.f, 1.f, 1.f, 0.f));
 
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index c81ade6937383a1845963caab7a53428b93636e9..377075ffd591a00205f7f21d4c2941120f53daf4 100755
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -459,6 +459,7 @@ set(viewer_SOURCE_FILES
     llremoteparcelrequest.cpp
     llsavedsettingsglue.cpp
     llsaveoutfitcombobtn.cpp
+	llscenemonitor.cpp
     llsceneview.cpp
     llscreenchannel.cpp
     llscriptfloater.cpp
@@ -1025,6 +1026,7 @@ set(viewer_HEADER_FILES
     llrootview.h
     llsavedsettingsglue.h
     llsaveoutfitcombobtn.h
+	llscenemonitor.h
     llsceneview.h
     llscreenchannel.h
     llscriptfloater.h
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index 13c95c23819b09442a2ebc8d92fddb23da727593..c6cfe3b616a0d50c30482d15ea3fe12c990f3d77 100755
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -9469,6 +9469,17 @@
       <key>Value</key>
       <integer>0</integer>
     </map>
+    <key>SceneLoadingMonitorEnabled</key>
+    <map>
+      <key>Comment</key>
+      <string>Enabled scene loading monitor if set</string>
+      <key>Persist</key>
+      <integer>0</integer>
+      <key>Type</key>
+      <string>Boolean</string>
+      <key>Value</key>
+      <integer>0</integer>
+    </map>
     <key>ScriptHelpFollowsCursor</key>
     <map>
       <key>Comment</key>
@@ -10864,7 +10875,7 @@
       <key>Type</key>
       <string>F32</string>
       <key>Value</key>
-      <integer>0.0</integer>
+      <real>0.0</real>
     </map>
     <key>TextureFetchUpdateSkipLowPriority</key>
     <map>
@@ -12492,6 +12503,7 @@
       <key>Type</key>
       <string>LLSD</string>
       <key>Value</key>
+      <array />
     </map>
     <key>VFSOldSize</key>
     <map>
diff --git a/indra/newview/lldebugview.cpp b/indra/newview/lldebugview.cpp
index aeecf054b8ba5245c1f0cf800bd39057a355e90f..86f0213282b33fdcadf4eeb0f5d40c6bec3296d6 100644
--- a/indra/newview/lldebugview.cpp
+++ b/indra/newview/lldebugview.cpp
@@ -40,7 +40,7 @@
 #include "llsceneview.h"
 #include "llviewertexture.h"
 #include "llfloaterreg.h"
-
+#include "llscenemonitor.h"
 //
 // Globals
 //
@@ -66,6 +66,7 @@ LLDebugView::~LLDebugView()
 	gDebugView = NULL;
 	gTextureView = NULL;
 	gSceneView = NULL;
+	gSceneMonitorView = NULL;
 }
 
 void LLDebugView::init()
@@ -98,6 +99,13 @@ void LLDebugView::init()
 	gSceneView->setVisible(FALSE);
 	addChild(gSceneView);
 	gSceneView->setRect(rect);
+
+	gSceneMonitorView = new LLSceneMonitorView(r);
+	gSceneMonitorView->setFollowsTop();
+	gSceneMonitorView->setFollowsLeft();
+	gSceneMonitorView->setVisible(FALSE);
+	addChild(gSceneMonitorView);
+	gSceneMonitorView->setRect(rect);
 	
 	r.setLeftTopAndSize(25, rect.getHeight() - 50, (S32) (gViewerWindow->getWindowRectScaled().getWidth() * 0.75f), 
 									 (S32) (gViewerWindow->getWindowRectScaled().getHeight() * 0.75f));
diff --git a/indra/newview/llscenemonitor.cpp b/indra/newview/llscenemonitor.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..8597767c61af02e18bcb993cba1f0a3c3dd1e8a2
--- /dev/null
+++ b/indra/newview/llscenemonitor.cpp
@@ -0,0 +1,358 @@
+/** 
+ * @file llscenemonitor.cpp
+ * @brief monitor the scene loading process.
+ *
+ * $LicenseInfo:firstyear=2003&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+#include "llrendertarget.h"
+#include "llscenemonitor.h"
+#include "llviewerwindow.h"
+#include "llviewerdisplay.h"
+#include "llviewercontrol.h"
+#include "llviewershadermgr.h"
+#include "llui.h"
+#include "llstartup.h"
+#include "llappviewer.h"
+#include "llwindow.h"
+#include "llpointer.h"
+
+LLSceneMonitorView* gSceneMonitorView = NULL;
+
+LLSceneMonitor::LLSceneMonitor() : mEnabled(false), mDiff(NULL), mNeedsUpdateDiff(FALSE)
+{
+	mFrames[0] = NULL;
+	mFrames[1] = NULL;
+}
+
+LLSceneMonitor::~LLSceneMonitor()
+{
+	destroyClass();
+}
+
+void LLSceneMonitor::destroyClass()
+{
+	reset();
+}
+
+void LLSceneMonitor::reset()
+{
+	delete mFrames[0];
+	delete mFrames[1];
+	delete mDiff;
+
+	mFrames[0] = NULL;
+	mFrames[1] = NULL;
+	mDiff = NULL;
+}
+
+void LLSceneMonitor::setEnabled(bool enabled)
+{
+	if(enabled == (bool)gSavedSettings.getBOOL("SceneLoadingMonitorEnabled"))
+	{
+		return;
+	}
+	gSavedSettings.setBOOL("SceneLoadingMonitorEnabled", enabled);
+}
+
+bool LLSceneMonitor::preCapture()
+{
+	static LLCachedControl<bool> enabled(gSavedSettings,"SceneLoadingMonitorEnabled");
+	static LLFrameTimer timer;	
+
+	mCurTarget = NULL;
+	if (!LLGLSLShader::sNoFixedFunction)
+	{
+		return false;
+	}
+	if(mEnabled != (BOOL)enabled)
+	{
+		if(mEnabled)
+		{
+			reset();
+			unfreezeScene();
+		}
+		else
+		{
+			freezeScene();
+		}
+
+		mEnabled = (BOOL)enabled;
+	}
+
+	if(!mEnabled)
+	{
+		return false;
+	}
+
+	if (LLStartUp::getStartupState() < STATE_STARTED)
+	{
+		return false;
+	}
+
+	if(LLAppViewer::instance()->logoutRequestSent())
+	{
+		return false;
+	}
+
+	if(gWindowResized || gHeadlessClient || gTeleportDisplay || gRestoreGL || gDisconnected)
+	{
+		return false;
+	}
+
+	if (   !gViewerWindow->getActive()
+		|| !gViewerWindow->getWindow()->getVisible() 
+		|| gViewerWindow->getWindow()->getMinimized() )
+	{
+		return false;
+	}
+
+	if(timer.getElapsedTimeF32() < 1.0f)
+	{
+		return false;
+	}
+	timer.reset();
+	
+	S32 width = gViewerWindow->getWorldViewWidthRaw();
+	S32 height = gViewerWindow->getWorldViewHeightRaw();
+	
+	if(!mFrames[0])
+	{
+		mFrames[0] = new LLRenderTarget();
+		mFrames[0]->allocate(width, height, GL_RGB, false, false, LLTexUnit::TT_TEXTURE, true);
+		gGL.getTexUnit(0)->bind(mFrames[0]);
+		gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_POINT);
+		gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+
+		mCurTarget = mFrames[0];
+	}
+	else if(!mFrames[1])
+	{
+		mFrames[1] = new LLRenderTarget();
+		mFrames[1]->allocate(width, height, GL_RGB, false, false, LLTexUnit::TT_TEXTURE, true);
+		gGL.getTexUnit(0)->bind(mFrames[1]);
+		gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_POINT);
+		gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+
+		mCurTarget = mFrames[1];
+	}
+	else //swap
+	{
+		mCurTarget = mFrames[0];
+		mFrames[0] = mFrames[1];
+		mFrames[1] = mCurTarget;
+	}
+	
+	if(mCurTarget->getWidth() != width || mCurTarget->getHeight() != height) //size changed
+	{
+		mCurTarget->resize(width, height, GL_RGB);
+	}
+
+	return true;
+}
+
+void LLSceneMonitor::postCapture()
+{
+	mCurTarget = NULL;
+	mNeedsUpdateDiff = TRUE;
+}
+
+void LLSceneMonitor::freezeAvatar(LLCharacter* avatarp)
+{
+	mAvatarPauseHandles.push_back(avatarp->requestPause());
+}
+
+void LLSceneMonitor::freezeScene()
+{
+	//freeze all avatars
+	for (std::vector<LLCharacter*>::iterator iter = LLCharacter::sInstances.begin();
+		iter != LLCharacter::sInstances.end(); ++iter)
+	{
+		freezeAvatar((LLCharacter*)(*iter));
+	}
+
+	// freeze everything else
+	gSavedSettings.setBOOL("FreezeTime", TRUE);
+}
+
+void LLSceneMonitor::unfreezeScene()
+{
+	//thaw all avatars
+	mAvatarPauseHandles.clear();
+
+	// thaw everything else
+	gSavedSettings.setBOOL("FreezeTime", FALSE);
+}
+
+LLRenderTarget* LLSceneMonitor::getDiffTarget() const 
+{
+	return mDiff;
+}
+
+void LLSceneMonitor::capture()
+{
+	static U32 count = 0;
+	if(count == gFrameCount)
+	{
+		return;
+	}
+	count = gFrameCount;
+
+	preCapture();
+
+	if(!mCurTarget)
+	{
+		return;
+	}
+	
+	U32 old_FBO = LLRenderTarget::sCurFBO;
+
+	gGL.getTexUnit(0)->bind(mCurTarget);
+	glBindFramebuffer(GL_READ_FRAMEBUFFER, 0); //point to the main frame buffer.
+		
+	glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, mCurTarget->getWidth(), mCurTarget->getHeight()); //copy the content
+	
+	glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
+	glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);		
+	glBindFramebuffer(GL_FRAMEBUFFER, old_FBO);
+
+	postCapture();
+}
+
+void LLSceneMonitor::compare()
+{
+	if(!mNeedsUpdateDiff)
+	{
+		return;
+	}
+
+	if(!mFrames[0] || !mFrames[1])
+	{
+		return;
+	}
+	if(mFrames[0]->getWidth() != mFrames[1]->getWidth() || mFrames[0]->getHeight() != mFrames[1]->getHeight())
+	{
+		return; //size does not match
+	}
+
+	if (!LLGLSLShader::sNoFixedFunction)
+	{
+		return;
+	}
+
+	S32 width = mFrames[0]->getWidth();
+	S32 height = mFrames[0]->getHeight();
+	if(!mDiff)
+	{
+		mDiff = new LLRenderTarget();
+		mDiff->allocate(width, height, GL_RGBA, false, false, LLTexUnit::TT_TEXTURE, true);
+	}
+	else if(mDiff->getWidth() != width || mDiff->getHeight() != height)
+	{
+		mDiff->resize(width, height, GL_RGBA);
+	}
+	mDiff->bindTarget();
+	mDiff->clear();
+
+	gTwoTextureCompareProgram.bind();
+	
+	gGL.getTexUnit(0)->activate();
+	gGL.getTexUnit(0)->enable(LLTexUnit::TT_TEXTURE);
+	gGL.getTexUnit(0)->bind(mFrames[0]);
+	gGL.getTexUnit(0)->activate();
+
+	gGL.getTexUnit(1)->activate();
+	gGL.getTexUnit(1)->enable(LLTexUnit::TT_TEXTURE);
+	gGL.getTexUnit(1)->bind(mFrames[1]);
+	gGL.getTexUnit(1)->activate();	
+			
+	gl_rect_2d_simple_tex(width, height);
+	
+	gGL.flush();
+	mDiff->flush();
+
+	gTwoTextureCompareProgram.unbind();
+	
+	gGL.getTexUnit(0)->disable();
+	gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+	gGL.getTexUnit(1)->disable();
+	gGL.getTexUnit(1)->unbind(LLTexUnit::TT_TEXTURE);
+
+	mNeedsUpdateDiff = FALSE;
+}
+
+//-------------------------------------------------------------------------------------------------------------
+//definition of class LLSceneMonitorView
+//-------------------------------------------------------------------------------------------------------------
+LLSceneMonitorView::LLSceneMonitorView(const LLRect& rect)
+	:	LLFloater(LLSD())
+{
+	setRect(rect);
+	setVisible(FALSE);
+	
+	setCanMinimize(false);
+	setCanClose(true);
+}
+
+void LLSceneMonitorView::onClickCloseBtn()
+{
+	setVisible(false);	
+}
+
+void LLSceneMonitorView::setVisible(BOOL visible)
+{
+	if(visible != (BOOL)LLSceneMonitor::getInstance()->isEnabled())
+	{
+		LLSceneMonitor::getInstance()->setEnabled(visible);
+	}
+
+	LLView::setVisible(visible);
+}
+
+void LLSceneMonitorView::draw()
+{
+	if (!LLGLSLShader::sNoFixedFunction)
+	{
+		return;
+	}
+	LLRenderTarget* target = LLSceneMonitor::getInstance()->getDiffTarget();
+	if(!target)
+	{
+		return;
+	}
+
+	S32 height = (S32) (gViewerWindow->getWindowRectScaled().getHeight()*0.75f);
+	S32 width = (S32) (gViewerWindow->getWindowRectScaled().getWidth() * 0.75f);
+	
+	LLRect new_rect;
+	new_rect.setLeftTopAndSize(getRect().mLeft, getRect().mTop, width, height);
+	setRect(new_rect);
+
+	gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+	gl_rect_2d(0, getRect().getHeight(), getRect().getWidth(), 0, LLColor4(0.f, 0.f, 0.f, 0.25f));
+	
+	gl_draw_scaled_target(0, 0, getRect().getWidth(), getRect().getHeight(), target);//, LLColor4(0.f, 0.f, 0.f, 0.25f));
+
+	LLView::draw();
+}
+
diff --git a/indra/newview/llscenemonitor.h b/indra/newview/llscenemonitor.h
new file mode 100644
index 0000000000000000000000000000000000000000..941039cefd1c163e25ee9c5f8d346faf9c9d665d
--- /dev/null
+++ b/indra/newview/llscenemonitor.h
@@ -0,0 +1,87 @@
+/** 
+ * @file llscenemonitor.h
+ * @brief monitor the process of scene loading
+ *
+ * $LicenseInfo:firstyear=2003&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLSCENE_MONITOR_H
+#define LL_LLSCENE_MONITOR_H
+
+#include "llsingleton.h"
+#include "llmath.h"
+#include "llfloater.h"
+#include "llcharacter.h"
+
+class LLCharacter;
+class LLRenderTarget;
+
+class LLSceneMonitor :  public LLSingleton<LLSceneMonitor>
+{
+public:
+	LLSceneMonitor();
+	~LLSceneMonitor();
+
+	void destroyClass();
+	
+	void freezeAvatar(LLCharacter* avatarp);
+	void setEnabled(bool enabled);
+
+	void capture(); //capture the main frame buffer
+	void compare(); //compare the stored two buffers.	
+
+	LLRenderTarget* getDiffTarget() const;
+	bool isEnabled()const {return mEnabled;}
+	
+private:
+	void freezeScene();
+	void unfreezeScene();
+	void reset();
+	bool preCapture();
+	void postCapture();
+	
+private:
+	BOOL mEnabled;
+	BOOL mNeedsUpdateDiff;
+	LLRenderTarget* mFrames[2];
+	LLRenderTarget* mDiff;
+	LLRenderTarget* mCurTarget;
+
+	std::vector<LLAnimPauseRequest> mAvatarPauseHandles;
+};
+
+class LLSceneMonitorView : public LLFloater
+{
+public:
+	LLSceneMonitorView(const LLRect& rect);
+
+	virtual void draw();
+	virtual void setVisible(BOOL visible);
+
+protected:
+	virtual void onClickCloseBtn();
+};
+
+extern LLSceneMonitorView* gSceneMonitorView;
+
+#endif
+
diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp
index ffeea2f4df936aa827557f97016c393394a18b69..c12144df6fbbcd4b945a862b2fcd940cced24051 100644
--- a/indra/newview/llviewerdisplay.cpp
+++ b/indra/newview/llviewerdisplay.cpp
@@ -77,6 +77,7 @@
 #include "llwlparammanager.h"
 #include "llwaterparammanager.h"
 #include "llpostprocess.h"
+#include "llscenemonitor.h"
 
 extern LLPointer<LLViewerTexture> gStartTexture;
 extern bool gShiftFrame;
@@ -989,6 +990,11 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
 
 		LLPipeline::sUnderWaterRender = FALSE;
 
+		{
+			//capture the frame buffer.
+			LLSceneMonitor::getInstance()->capture();
+		}
+
 		LLAppViewer::instance()->pingMainloopTimeout("Display:RenderUI");
 		if (!for_snapshot)
 		{
@@ -1403,6 +1409,8 @@ void render_ui_2d()
 	//  Menu overlays, HUD, etc
 	gViewerWindow->setup2DRender();
 
+	LLSceneMonitor::getInstance()->compare();
+
 	F32 zoom_factor = LLViewerCamera::getInstance()->getZoomFactor();
 	S16 sub_region = LLViewerCamera::getInstance()->getZoomSubRegion();
 
diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp
index 4ec498dc338a55f8adb3f980e9c5d0078f8e812a..4dfcf1efce022f366e9174a908776291f3e9ed39 100644
--- a/indra/newview/llviewermenu.cpp
+++ b/indra/newview/llviewermenu.cpp
@@ -121,6 +121,7 @@
 #include "llwindow.h"
 #include "llpathfindingmanager.h"
 #include "boost/unordered_map.hpp"
+#include "llscenemonitor.h"
 
 using namespace LLVOAvatarDefines;
 
@@ -528,7 +529,10 @@ class LLAdvancedToggleConsole : public view_listener_t
 		{
 			toggle_visibility( (void*)gSceneView);
 		}
-
+		else if ("scene monitor" == console_type)
+		{
+			toggle_visibility( (void*)gSceneMonitorView);
+		}
 #if MEM_TRACK_MEM
 		else if ("memory view" == console_type)
 		{
@@ -556,9 +560,9 @@ class LLAdvancedCheckConsole : public view_listener_t
 		{
 			new_value = LLFloaterReg::instanceVisible("fast_timers");
 		}
-		else if ("scene view" == console_type)
+		else if ("scene monitor" == console_type)
 		{
-			new_value = get_visibility( (void*) gSceneView);
+			new_value = get_visibility( (void*) gSceneMonitorView);
 		}
 #if MEM_TRACK_MEM
 		else if ("memory view" == console_type)
diff --git a/indra/newview/llviewertexture.cpp b/indra/newview/llviewertexture.cpp
index b0f8f60d1ec744a3305776b3173e8451478ccafd..45b6bf2828f08863340349ac4594265a5c1300e2 100644
--- a/indra/newview/llviewertexture.cpp
+++ b/indra/newview/llviewertexture.cpp
@@ -953,6 +953,12 @@ void LLViewerTexture::setCachedRawImage(S32 discard_level, LLImageRaw* imageraw)
 	//nothing here.
 }
 
+BOOL LLViewerTexture::setSubImageFromFrameBuffer(S32 fb_x, S32 fb_y, S32 x_pos, S32 y_pos, S32 width, S32 height)
+{
+	llassert(mGLTexturep.notNull()) ;
+	return mGLTexturep->setSubImageFromFrameBuffer(fb_x, fb_y, x_pos, y_pos, width, height);
+}
+
 void LLViewerTexture::setExplicitFormat(LLGLint internal_format, LLGLenum primary_format, LLGLenum type_format, BOOL swap_bytes)
 {
 	llassert(mGLTexturep.notNull()) ;
diff --git a/indra/newview/llviewertexture.h b/indra/newview/llviewertexture.h
index 2ea9a07e9a1acff51c8d7406d6294859ad5bf021..7095e97b39d4018f01887bd6e071bcfb158de725 100755
--- a/indra/newview/llviewertexture.h
+++ b/indra/newview/llviewertexture.h
@@ -211,6 +211,7 @@ class LLViewerTexture : public LLTexture
 	BOOL       createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S32 usename = 0, BOOL to_create = TRUE, S32 category = LLViewerTexture::OTHER);
 	virtual void setCachedRawImage(S32 discard_level, LLImageRaw* imageraw) ;
 
+	BOOL       setSubImageFromFrameBuffer(S32 fb_x, S32 fb_y, S32 x_pos, S32 y_pos, S32 width, S32 height);
 	void       setFilteringOption(LLTexUnit::eTextureFilterOptions option);
 	void       setExplicitFormat(LLGLint internal_format, LLGLenum primary_format, LLGLenum type_format = 0, BOOL swap_bytes = FALSE);
 	void       setAddressMode(LLTexUnit::eTextureAddressMode mode);
diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp
index d366455a62d2a0dcd77fbc0ad4ea24b49dd5d1d4..1fab3b68d5ec1b5ecb8c4ef24d379e2c7ab26f1b 100755
--- a/indra/newview/llvoavatar.cpp
+++ b/indra/newview/llvoavatar.cpp
@@ -102,6 +102,7 @@
 
 #include "lldebugmessagebox.h"
 #include "llsdutil.h"
+#include "llscenemonitor.h"
 
 extern F32 SPEED_ADJUST_MAX;
 extern F32 SPEED_ADJUST_MAX_SEC;
@@ -771,6 +772,11 @@ LLVOAvatar::LLVOAvatar(const LLUUID& id,
 	mLastPelvisToFoot = 0.0f;
 	mPelvisFixup = 0.0f;
 	mLastPelvisFixup = 0.0f;
+
+	if(LLSceneMonitor::getInstance()->isEnabled())
+	{
+		LLSceneMonitor::getInstance()->freezeAvatar((LLCharacter*)this);
+	}
 }
 
 std::string LLVOAvatar::avString() const
diff --git a/indra/newview/llworld.cpp b/indra/newview/llworld.cpp
index 0a622997f7eea9f011b82d938a8a1cf32c19c2ca..aed2835e4a3d4febe105d00f2c187b00d3a9f3de 100644
--- a/indra/newview/llworld.cpp
+++ b/indra/newview/llworld.cpp
@@ -55,7 +55,7 @@
 #include "message.h"
 #include "pipeline.h"
 #include "llappviewer.h"		// for do_disconnect()
-
+#include "llscenemonitor.h"
 #include <deque>
 #include <queue>
 #include <map>
@@ -136,6 +136,8 @@ void LLWorld::destroyClass()
 
 	//make all visible drawbles invisible.
 	LLDrawable::incrementVisible();
+
+	LLSceneMonitor::getInstance()->destroyClass();
 }
 
 
diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml
index c6d9f9ef8f3812b476c1a90a6981aa3d2bd859e2..7923cc9f62054eb509a3236e9410118c55cf292a 100644
--- a/indra/newview/skins/default/xui/en/menu_viewer.xml
+++ b/indra/newview/skins/default/xui/en/menu_viewer.xml
@@ -1981,6 +1981,16 @@
                function="Advanced.ToggleConsole"
                parameter="scene view" />
             </menu_item_check>
+            <menu_item_check
+                 label="Scene Loading Monitor"
+                 name="Scene Loading Monitor">
+              <menu_item_check.on_check
+               function="Advanced.CheckConsole"
+               parameter="scene monitor" />
+              <menu_item_check.on_click
+               function="Advanced.ToggleConsole"
+               parameter="scene monitor" />
+            </menu_item_check>
             <menu_item_call
               enabled="false"
               visible="false"