diff --git a/build.sh b/build.sh
index b5876738e67aa83a0963f1a58c3a03d7aae3e54d..2f4f440a9297fff6649bfa19acf2322dd56dd31f 100755
--- a/build.sh
+++ b/build.sh
@@ -292,12 +292,89 @@ then
   end_section WaitParallel
 fi
 
+# build debian package
+if [ "$arch" == "Linux" ]
+then
+  if $succeeded
+  then
+    if $build_viewer_deb && [ "$last_built_variant" == "Release" ]
+    then
+      begin_section "Build Debian Package"
+      # mangle the changelog
+      dch --force-bad-version \
+          --distribution unstable \
+          --newversion "${VIEWER_VERSION}" \
+          "Automated build #$build_id, repository $branch revision $revision." \
+          >> "$build_log" 2>&1
+
+      # build the debian package
+      $pkg_default_debuild_command  >>"$build_log" 2>&1 || record_failure "\"$pkg_default_debuild_command\" failed."
+
+      # Unmangle the changelog file
+      hg revert debian/changelog
+
+      end_section "Build Debian Package"
+
+      # upload debian package and create repository
+      begin_section "Upload Debian Repository"
+      for deb_file in ../*.deb; do
+        upload_item debian $deb_file binary/octet-stream
+      done
+      if [ -d "$build_log_dir/debian_repo" ]
+      then
+        pushd "$build_log_dir/debian_repo"
+        cat > Release <<EOF
+Archive: stable
+Component: main
+Origin: Teamcity
+Label: Teamcity built .debs
+Architecture: i386 amd64 any
+EOF
+        if dpkg-scanpackages . /dev/null | gzip -9c > Packages.gz \
+        && dpkg-scansources . /dev/null | gzip -9c > Sources.gz
+        then
+          begin_section Packages.gz
+          gunzip --stdout Packages.gz
+          for file in *.deb
+          do  
+            stat "$file" | sed 2q
+            md5sum "$file"
+          done
+          end_section Packages.gz
+
+          for file in *
+          do
+            upload_item debian_repo "$file" binary/octet-stream
+          done
+        else
+          record_failure 'Unable to generate Packages.gz or Sources.gz'
+        fi
+        popd
+
+        process_pending_uploads
+
+        # Rename the local debian_repo directory so that the master buildscript
+        # doesn't make a remote repo again.
+
+        mv $build_log_dir/debian_repo $build_log_dir/debian_repo_pushed
+      fi
+      end_section "Upload Debian Repository"
+      
+    else
+      echo skipping debian build
+    fi
+  else
+    echo skipping debian build due to failed build.
+  fi
+fi
+
+
 # check status and upload results to S3
 if $succeeded
 then
   if $build_viewer
   then
-    begin_section Upload
+    begin_section Upload Installer
     # Upload installer - note that ONLY THE FIRST ITEM uploaded as "installer"
     # will appear in the version manager.
     package=$(installer_$arch)
@@ -335,12 +412,12 @@ then
       # Upload stub installers
       upload_stub_installers "$build_dir_stubs"
     fi
-    end_section Upload
+    end_section Upload Installer
   else
-    echo skipping viewer
+    echo skipping upload of installer
   fi
 else
-  echo skipping upload of build results due to failed build.
+  echo skipping upload of installer due to failed build.
 fi
 
 # The branch independent build.sh script invoking this script will finish processing
diff --git a/debian/changelog b/debian/changelog
new file mode 100644
index 0000000000000000000000000000000000000000..ce54b54c6f107de19d88453456b9a243b6559ed4
--- /dev/null
+++ b/debian/changelog
@@ -0,0 +1,18 @@
+secondlife-viewer (0.3) unstable; urgency=low
+
+  * Initial debian configuration
+
+ -- Don Kjer <don@lindenlab.com>  Wed, 04 Jul 2012 00:43:03 +0000
+
+secondlife-viewer (0.2) unstable; urgency=low
+
+  * Adding default LSB headers for squeeze
+
+ -- Tyler Kohler <tyler@lindenlab.com>  Thu, 24 Mar 2011 09:43:36 -0700
+
+secondlife-viewer (0.1) unstable; urgency=low
+
+  * Cloned from debian package skeleton.
+
+ -- Lex Linden <lex@lindenlab.com>  Mon, 20 Sep 2010 08:01:59 -0700
+
diff --git a/debian/compat b/debian/compat
new file mode 100644
index 0000000000000000000000000000000000000000..7ed6ff82de6bcc2a78243fc9c54d3ef5ac14da69
--- /dev/null
+++ b/debian/compat
@@ -0,0 +1 @@
+5
diff --git a/debian/control b/debian/control
new file mode 100644
index 0000000000000000000000000000000000000000..50b9ed9a264abf7dbf48dc789484056635f36753
--- /dev/null
+++ b/debian/control
@@ -0,0 +1,16 @@
+Source: secondlife-viewer
+Section: unknown
+Priority: extra
+Maintainer: Don Linden <don@lindenlab.com>
+Build-Depends: debhelper (>= 5)
+Homepage: http://secondlife.com
+Standards-Version: 3.7.2
+
+Package: secondlife-viewer
+Architecture: any
+Depends: ${shlibs:Depends}, ${misc:Depends},
+ ia32-libs,
+ ia32-libs-gtk
+Description: Second Life Viewer
+ Second Life is an online virtual world developed by Linden Lab.
+ 
diff --git a/debian/copyright b/debian/copyright
new file mode 100644
index 0000000000000000000000000000000000000000..ecfceb392760e42352044cb24ff8f38d0af019c2
--- /dev/null
+++ b/debian/copyright
@@ -0,0 +1,7 @@
+Copyright: 2012 Linden Research, Inc.
+
+License:
+
+No license to distribute, copy, modify, or make derivitave works of this
+software is granted unless specifically granted in writing by Linden Research,
+Inc.
diff --git a/debian/postinst b/debian/postinst
new file mode 100644
index 0000000000000000000000000000000000000000..2c4f8ea8588b62b63d5ba8106d8e18964903307e
--- /dev/null
+++ b/debian/postinst
@@ -0,0 +1,43 @@
+#!/bin/sh
+# postinst script for secondlife-viewer
+#
+# Delete this file if you don't need it.
+#
+# see: dh_installdeb(1)
+
+set -e
+
+# summary of how this script can be called:
+#        * <postinst> `configure' <most-recently-configured-version>
+#        * <old-postinst> `abort-upgrade' <new version>
+#        * <conflictor's-postinst> `abort-remove' `in-favour' <package>
+#          <new-version>
+#        * <postinst> `abort-remove'
+#        * <deconfigured's-postinst> `abort-deconfigure' `in-favour'
+#          <failed-install-package> <version> `removing'
+#          <conflicting-package> <version>
+# for details, see http://www.debian.org/doc/debian-policy/ or
+# the debian-policy package
+
+
+case "$1" in
+    configure)
+    ;;
+
+    abort-upgrade|abort-remove|abort-deconfigure)
+    ;;
+
+    *)
+        echo "postinst called with unknown argument \`$1'" >&2
+        exit 1
+    ;;
+esac
+
+# dh_installdeb will replace this with shell code automatically
+# generated by other debhelper scripts.  Don't delete this!
+
+#DEBHELPER#
+
+exit 0
+
+
diff --git a/debian/postrm b/debian/postrm
new file mode 100644
index 0000000000000000000000000000000000000000..a575936ab04060765153060adf711ba28bb02890
--- /dev/null
+++ b/debian/postrm
@@ -0,0 +1,41 @@
+#!/bin/sh
+# postrm script for secondlife-viewer
+#
+# Delete this file if you don't need it.
+#
+# see: dh_installdeb(1)
+
+set -e
+
+# summary of how this script can be called:
+#        * <postrm> `remove'
+#        * <postrm> `purge'
+#        * <old-postrm> `upgrade' <new-version>
+#        * <new-postrm> `failed-upgrade' <old-version>
+#        * <new-postrm> `abort-install'
+#        * <new-postrm> `abort-install' <old-version>
+#        * <new-postrm> `abort-upgrade' <old-version>
+#        * <disappearer's-postrm> `disappear' <overwriter>
+#          <overwriter-version>
+# for details, see http://www.debian.org/doc/debian-policy/ or
+# the debian-policy package
+
+
+case "$1" in
+    purge|remove|upgrade|failed-upgrade|abort-install|abort-upgrade|disappear)
+    ;;
+
+    *)
+        echo "postrm called with unknown argument \`$1'" >&2
+        exit 1
+    ;;
+esac
+
+# dh_installdeb will replace this with shell code automatically
+# generated by other debhelper scripts.  Don't delete this!
+
+#DEBHELPER#
+
+exit 0
+
+
diff --git a/debian/preinst b/debian/preinst
new file mode 100644
index 0000000000000000000000000000000000000000..f62243440f6cf253026d0926576fa0c99535e524
--- /dev/null
+++ b/debian/preinst
@@ -0,0 +1,39 @@
+#!/bin/sh
+# preinst script for secondlife-viewer
+#
+# Delete this file if you don't need it.
+#
+# see: dh_installdeb(1)
+
+set -e
+
+# summary of how this script can be called:
+#        * <new-preinst> `install'
+#        * <new-preinst> `install' <old-version>
+#        * <new-preinst> `upgrade' <old-version>
+#        * <old-preinst> `abort-upgrade' <new-version>
+# for details, see http://www.debian.org/doc/debian-policy/ or
+# the debian-policy package
+
+
+case "$1" in
+    install|upgrade)
+    ;;
+
+    abort-upgrade)
+    ;;
+
+    *)
+        echo "preinst called with unknown argument \`$1'" >&2
+        exit 1
+    ;;
+esac
+
+# dh_installdeb will replace this with shell code automatically
+# generated by other debhelper scripts.  Don't delete this!
+
+#DEBHELPER#
+
+exit 0
+
+
diff --git a/debian/prerm b/debian/prerm
new file mode 100644
index 0000000000000000000000000000000000000000..405b8f9c87bcfe6e3bcca23b7eb192a9dd6ee0e2
--- /dev/null
+++ b/debian/prerm
@@ -0,0 +1,42 @@
+#!/bin/sh
+# prerm script for secondlife-viewer
+#
+# Delete this file if you don't need it.
+#
+# see: dh_installdeb(1)
+
+set -e
+
+# summary of how this script can be called:
+#        * <prerm> `remove'
+#        * <old-prerm> `upgrade' <new-version>
+#        * <new-prerm> `failed-upgrade' <old-version>
+#        * <conflictor's-prerm> `remove' `in-favour' <package> <new-version>
+#        * <deconfigured's-prerm> `deconfigure' `in-favour'
+#          <package-being-installed> <version> `removing'
+#          <conflicting-package> <version>
+# for details, see http://www.debian.org/doc/debian-policy/ or
+# the debian-policy package
+
+
+case "$1" in
+    remove|upgrade|deconfigure)
+    ;;
+
+    failed-upgrade)
+    ;;
+
+    *)
+        echo "prerm called with unknown argument \`$1'" >&2
+        exit 1
+    ;;
+esac
+
+# dh_installdeb will replace this with shell code automatically
+# generated by other debhelper scripts.  Don't delete this!
+
+#DEBHELPER#
+
+exit 0
+
+
diff --git a/debian/rules b/debian/rules
new file mode 100755
index 0000000000000000000000000000000000000000..c41f02d4fbd8a7c939766102ae96f8425ca4c5c6
--- /dev/null
+++ b/debian/rules
@@ -0,0 +1,116 @@
+#!/usr/bin/make -f
+# -*- makefile -*-
+# Sample debian/rules that uses debhelper.
+# This file was originally written by Joey Hess and Craig Small.
+# As a special exception, when this file is copied by dh-make into a
+# dh-make output file, you may use that output file without restriction.
+# This special exception was added by Craig Small in version 0.37 of dh-make.
+
+# Uncomment this to turn on verbose mode.
+#export DH_VERBOSE=1
+
+SRCDIR=build-linux-i686/newview/packaged
+DESTDIR=$(CURDIR)/debian/secondlife-viewer
+BASEDIR=opt/linden/viewer
+VIEWER_VERSION:=$(shell dpkg-parsechangelog | grep ^Version | sed 's/^Version: //')
+INSTALLDIR:=$(BASEDIR)/SecondLife-i686-$(VIEWER_VERSION)
+
+configure: configure-stamp
+configure-stamp:
+	dh_testdir
+	# Add here commands to configure the package.
+
+	touch configure-stamp
+
+build: build-stamp
+
+build-stamp: configure-stamp 
+	dh_testdir
+
+	# Add here commands to compile the package.
+	#$(MAKE)
+	#docbook-to-man debian/secondlife-viewer.sgml > secondlife-viewer.1
+
+	touch $@
+
+clean:
+	dh_testdir
+	dh_testroot
+	rm -f build-stamp configure-stamp
+
+	# Add here commands to clean up after the build process.
+	#-$(MAKE) clean
+
+	dh_clean 
+
+install: build
+	dh_testdir
+	dh_testroot
+	dh_clean -k 
+	dh_installdirs
+
+	# Add here commands to install the package into debian/secondlife-viewer.
+	for file in $$(find $(SRCDIR) -type f -o -type l | sed 's~$(SRCDIR)/~~'); do \
+		# create containing directory \
+		install -v -m 755 -o root -g root -d "$$(dirname "$(DESTDIR)/$(INSTALLDIR)/$$file")"; \
+		PERM=644; \
+		if [ -x "$(SRCDIR)/$$file" ]; then \
+			PERM=755; \
+		fi; \
+		if [ -L "$(SRCDIR)/$$file" ]; then \
+			REAL="$$( readlink -f $(SRCDIR)/$$file )"; \
+			RELATIVE="$$( echo $$REAL | sed 's~$(CURDIR)/$(SRCDIR)/~~' )"; \
+			echo dh_link "$(INSTALLDIR)/$$RELATIVE" "$(INSTALLDIR)/$$file" ; \
+			dh_link "$(INSTALLDIR)/$$RELATIVE" "$(INSTALLDIR)/$$file" ; \
+		else \
+			install -v -m $$PERM -o root -g root "$(SRCDIR)/$$file" "$(DESTDIR)/$(INSTALLDIR)/$$file"; \
+		fi; \
+	done
+	dh_link /$(INSTALLDIR)/secondlife /usr/bin/secondlife
+	dh_link $(BASEDIR)/SecondLife-i686-$(VIEWER_VERSION) $(BASEDIR)/SecondLife
+
+
+# Build architecture-independent files here.
+binary-indep: build install
+# We have nothing to do by default.
+
+# Build architecture-dependent files here.
+binary-arch: build install
+	dh_testdir
+	dh_testroot
+	dh_installchangelogs 
+	dh_installdocs
+	dh_installexamples
+#	dh_install
+#	dh_installmenu
+#	dh_installdebconf	
+#	dh_installlogrotate
+#	dh_installemacsen
+#	dh_installpam
+#	dh_installmime
+#	dh_python
+
+# To add an init script, uncomment this line and edit debian/init.d and 
+# customize debian/secondlife-viewer.default to suit your needs.
+#	dh_installinit
+
+# To add cron jobs, uncomment this line and make a crontab file named 
+# debian/cron.d, and it will be installed in /etc/cron.d/
+#	dh_installcron
+
+#	dh_installinfo
+	dh_installman
+	dh_link
+#	dh_strip
+	dh_compress
+#	dh_fixperms
+#	dh_perl
+#	dh_makeshlibs
+	dh_installdeb
+#	dh_shlibdeps
+	dh_gencontrol
+	dh_md5sums
+	dh_builddeb
+
+binary: binary-indep binary-arch
+.PHONY: build clean binary-indep binary-arch binary install configure
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index 753dbd7438643e283a6b0f05c0b9d6869cac8d87..2c9952cbc8e22af5df9bddac89d28dd25e8d7a2c 100755
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -437,6 +437,7 @@ set(viewer_SOURCE_FILES
     llpathfindingpathtool.cpp
     llphysicsmotion.cpp
     llphysicsshapebuilderutil.cpp
+    llpipelinelistener.cpp
     llplacesinventorybridge.cpp
     llplacesinventorypanel.cpp
     llpopupview.cpp
@@ -1002,6 +1003,7 @@ set(viewer_HEADER_FILES
     llpathfindingpathtool.h
     llphysicsmotion.h
     llphysicsshapebuilderutil.h
+    llpipelinelistener.h
     llplacesinventorybridge.h
     llplacesinventorypanel.h
     llpolymesh.h
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index 6914c3907593d56ece4e2b0a3318b561b0eb3b94..0e0707a589bdbb6a68f8dfb1a27423d3bb24b9f4 100755
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -8727,6 +8727,28 @@
       <key>Value</key>
       <integer>1</integer>
     </map>
+    <key>DisableAllRenderTypes</key>
+    <map>
+      <key>Comment</key>
+      <string>Disables all rendering types.</string>
+      <key>Persist</key>
+      <integer>0</integer>
+      <key>Type</key>
+      <string>Boolean</string>
+      <key>Value</key>
+      <integer>0</integer>
+    </map>
+    <key>DisableAllRenderFeatures</key>
+    <map>
+      <key>Comment</key>
+      <string>Disables all rendering features.</string>
+      <key>Persist</key>
+      <integer>0</integer>
+      <key>Type</key>
+      <string>Boolean</string>
+      <key>Value</key>
+      <integer>0</integer>
+    </map>
     <key>RenderHUDInSnapshot</key>
     <map>
       <key>Comment</key>
@@ -13120,6 +13142,28 @@
       <key>Value</key>
       <integer>-1</integer>
     </map>
+    <key>MaxFPS</key>
+    <map>
+      <key>Comment</key>
+      <string>Yield some time to the local host if we reach a threshold framerate.</string>
+      <key>Persist</key>
+      <integer>1</integer>
+      <key>Type</key>
+      <string>F32</string>
+      <key>Value</key>
+      <integer>-1.0</integer>
+    </map>
+    <key>ForcePeriodicRenderingTime</key>
+    <map>
+      <key>Comment</key>
+      <string>Periodically enable all rendering masks for a single frame.</string>
+      <key>Persist</key>
+      <integer>1</integer>
+      <key>Type</key>
+      <string>F32</string>
+      <key>Value</key>
+      <integer>-1.0</integer>
+    </map>
     <key>ZoomDirect</key>
     <map>
       <key>Comment</key>
diff --git a/indra/newview/linux_tools/wrapper.sh b/indra/newview/linux_tools/wrapper.sh
index 20936c6460bee17d344a1459ffde905572c114a4..fa9ce703a82a062cbe0bed86e1fe5662b124b21b 100755
--- a/indra/newview/linux_tools/wrapper.sh
+++ b/indra/newview/linux_tools/wrapper.sh
@@ -117,18 +117,32 @@ export LD_LIBRARY_PATH="$PWD/lib:${LD_LIBRARY_PATH}"
 # Simply embedding $(<etc/gridargs.dat) into a command line treats each of
 # Second, Life and Developer as separate args -- no good. We need bash to
 # process quotes using eval.
-# First read it without scanning, then scan that string. Break quoted words
+# First, check if we have been instructed to skip reading in gridargs.dat:
+skip_gridargs=false
+argnum=0
+for ARG in "$@"; do
+    if [ "--skip-gridargs" == "$ARG" ]; then
+        skip_gridargs=true
+    else
+        ARGS[$argnum]="$ARG"
+        argnum=$(($argnum+1))
+    fi
+done
+
+# Second, read it without scanning, then scan that string. Break quoted words
 # into a bash array. Note that if gridargs.dat is empty, or contains only
 # whitespace, the resulting gridargs array will be empty -- zero entries --
 # therefore "${gridargs[@]}" entirely vanishes from the command line below,
 # just as we want.
-eval gridargs=("$(<etc/gridargs.dat)")
+if ! $skip_gridargs ; then
+    eval gridargs=("$(<etc/gridargs.dat)")
+fi
 
 # Run the program.
 # Don't quote $LL_WRAPPER because, if empty, it should simply vanish from the
 # command line. But DO quote "$@": preserve separate args as individually
 # quoted. Similar remarks about the contents of gridargs.
-$LL_WRAPPER bin/do-not-directly-run-secondlife-bin "${gridargs[@]}" "$@"
+$LL_WRAPPER bin/do-not-directly-run-secondlife-bin "${gridargs[@]}" "${ARGS[@]}"
 LL_RUN_ERR=$?
 
 # Handle any resulting errors
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index 8594a13df05800201161894a5bab7f6399c398fe..5d5528cac78d5b84faa76c60f5b9961462c80f3b 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -633,7 +633,6 @@ LLAppViewer::LLAppViewer() :
 	mForceGraphicsDetail(false),
 	mQuitRequested(false),
 	mLogoutRequestSent(false),
-	mYieldTime(-1),
 	mMainloopTimeout(NULL),
 	mAgentRegionLastAlive(false),
 	mRandomizeFramerate(LLCachedControl<bool>(gSavedSettings,"Randomize Framerate", FALSE)),
@@ -1204,7 +1203,7 @@ bool LLAppViewer::mainLoop()
 	LLVoiceChannel::initClass();
 	LLVoiceClient::getInstance()->init(gServicePump);
 	LLVoiceChannel::setCurrentVoiceChannelChangedCallback(boost::bind(&LLCallFloater::sOnCurrentChannelChanged, _1), true);
-	LLTimer frameTimer,idleTimer;
+	LLTimer frameTimer,idleTimer,periodicRenderingTimer;
 	LLTimer debugTime;
 	LLViewerJoystick* joystick(LLViewerJoystick::getInstance());
 	joystick->setNeedsReset(true);
@@ -1216,6 +1215,8 @@ bool LLAppViewer::mainLoop()
     // point of posting.
     LLSD newFrame;
 
+	BOOL restore_rendering_masks = FALSE;
+
 	//LLPrivateMemoryPoolTester::getInstance()->run(false) ;
 	//LLPrivateMemoryPoolTester::getInstance()->run(true) ;
 	//LLPrivateMemoryPoolTester::destroy() ;
@@ -1233,6 +1234,28 @@ bool LLAppViewer::mainLoop()
 		
 		try
 		{
+			// Check if we need to restore rendering masks.
+			if (restore_rendering_masks)
+			{
+				gPipeline.popRenderDebugFeatureMask();
+				gPipeline.popRenderTypeMask();
+			}
+			// Check if we need to temporarily enable rendering.
+			F32 periodic_rendering = gSavedSettings.getF32("ForcePeriodicRenderingTime");
+			if (periodic_rendering > F_APPROXIMATELY_ZERO && periodicRenderingTimer.getElapsedTimeF64() > periodic_rendering)
+			{
+				periodicRenderingTimer.reset();
+				restore_rendering_masks = TRUE;
+				gPipeline.pushRenderTypeMask();
+				gPipeline.pushRenderDebugFeatureMask();
+				gPipeline.setAllRenderTypes();
+				gPipeline.setAllRenderDebugFeatures();
+			}
+			else
+			{
+				restore_rendering_masks = FALSE;
+			}
+
 			pingMainloopTimeout("Main:MiscNativeWindowEvents");
 
 			if (gViewerWindow)
@@ -1355,10 +1378,11 @@ bool LLAppViewer::mainLoop()
 				LLFastTimer t2(FTM_SLEEP);
 				
 				// yield some time to the os based on command line option
-				if(mYieldTime >= 0)
+				S32 yield_time = gSavedSettings.getS32("YieldTime");
+				if(yield_time >= 0)
 				{
 					LLFastTimer t(FTM_YIELD);
-					ms_sleep(mYieldTime);
+					ms_sleep(yield_time);
 				}
 
 				// yield cooperatively when not running as foreground window
@@ -1470,6 +1494,26 @@ bool LLAppViewer::mainLoop()
 				{
 					gFrameStalls++;
 				}
+
+				// Limit FPS
+				F32 max_fps = gSavedSettings.getF32("MaxFPS");
+				// Only limit FPS when we are actually rendering something.  Otherwise
+				// logins, logouts and teleports take much longer to complete.
+				if (max_fps > F_APPROXIMATELY_ZERO && 
+					LLStartUp::getStartupState() == STATE_STARTED &&
+					!gTeleportDisplay &&
+					!logoutRequestSent())
+				{
+					// Sleep a while to limit frame rate.
+					F32 min_frame_time = 1.f / max_fps;
+					S32 milliseconds_to_sleep = llclamp((S32)((min_frame_time - frameTimer.getElapsedTimeF64()) * 1000.f), 0, 1000);
+					if (milliseconds_to_sleep > 0)
+					{
+						LLFastTimer t(FTM_YIELD);
+						ms_sleep(milliseconds_to_sleep);
+					}
+				}
+
 				frameTimer.reset();
 
 				resumeMainloopTimeout();
@@ -2584,8 +2628,6 @@ bool LLAppViewer::initConfiguration()
 		}
 	}
 
-    mYieldTime = gSavedSettings.getS32("YieldTime");
-
 	// Read skin/branding settings if specified.
 	//if (! gDirUtilp->getSkinDir().empty() )
 	//{
diff --git a/indra/newview/llappviewer.h b/indra/newview/llappviewer.h
index ae3c795d1e2d9ced65bc77cfd79072a2b33adbab..043893020b13245f3ff5181822af24f79366aeac 100644
--- a/indra/newview/llappviewer.h
+++ b/indra/newview/llappviewer.h
@@ -253,7 +253,6 @@ class LLAppViewer : public LLApp
 
     bool mQuitRequested;				// User wants to quit, may have modified documents open.
     bool mLogoutRequestSent;			// Disconnect message sent to simulator, no longer safe to send messages to the sim.
-    S32 mYieldTime;
 	struct SettingsFiles* mSettingsLocationList;
 
 	LLWatchdogTimeout* mMainloopTimeout;
diff --git a/indra/newview/llpipelinelistener.cpp b/indra/newview/llpipelinelistener.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..20759239bf5f66663c8b77385d6bc56135b426da
--- /dev/null
+++ b/indra/newview/llpipelinelistener.cpp
@@ -0,0 +1,216 @@
+/**
+ * @file   llpipelinelistener.h
+ * @author Don Kjer
+ * @date   2012-07-09
+ * @brief  Implementation for LLPipelineListener
+ * 
+ * $LicenseInfo:firstyear=2012&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2012, 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$
+ */
+
+// Precompiled header
+#include "llviewerprecompiledheaders.h"
+
+#include "llpipelinelistener.h"
+
+#include "pipeline.h"
+#include "stringize.h"
+#include <sstream>
+#include "llviewermenu.h"
+
+
+namespace {
+	// Render Types
+	void toggle_render_types_wrapper(LLSD const& request)
+	{
+		for (LLSD::array_const_iterator iter = request["types"].beginArray();
+			iter != request["types"].endArray();
+			++iter)
+		{
+			U32 render_type = render_type_from_string( iter->asString() );
+			if ( render_type != 0 )
+			{
+				LLPipeline::toggleRenderTypeControl( (void*) render_type );
+			}
+		}
+	}
+
+	void has_render_type_wrapper(LLSD const& request)
+	{
+		LLEventAPI::Response response(LLSD(), request);
+		U32 render_type = render_type_from_string( request["type"].asString() );
+		if ( render_type != 0 )
+		{
+			response["value"] = LLPipeline::hasRenderTypeControl( (void*) render_type );
+		}
+		else
+		{
+			response.error(STRINGIZE("unknown type '" << request["type"].asString() << "'"));
+		}
+	}
+
+	void disable_all_render_types_wrapper(LLSD const& request)
+	{
+		gPipeline.clearAllRenderTypes();
+	}
+
+	void enable_all_render_types_wrapper(LLSD const& request)
+	{
+		gPipeline.setAllRenderTypes();
+	}
+
+	// Render Features
+	void toggle_render_features_wrapper(LLSD const& request)
+	{
+		for (LLSD::array_const_iterator iter = request["features"].beginArray();
+			iter != request["features"].endArray();
+			++iter)
+		{
+			U32 render_feature = feature_from_string( iter->asString() );
+			if ( render_feature != 0 )
+			{
+				LLPipeline::toggleRenderDebugControl( (void*) render_feature );
+			}
+		}
+	}
+
+	void has_render_feature_wrapper(LLSD const& request)
+	{
+		LLEventAPI::Response response(LLSD(), request);
+		U32 render_feature = feature_from_string( request["feature"].asString() );
+		if ( render_feature != 0 )
+		{
+			response["value"] = gPipeline.hasRenderDebugFeatureMask(render_feature);
+		}
+		else
+		{
+			response.error(STRINGIZE("unknown feature '" << request["feature"].asString() << "'"));
+		}
+	}
+
+	void disable_all_render_features_wrapper(LLSD const& request)
+	{
+		gPipeline.clearAllRenderDebugFeatures();
+	}
+
+	void enable_all_render_features_wrapper(LLSD const& request)
+	{
+		gPipeline.setAllRenderDebugFeatures();
+	}
+
+	// Render Info Displays
+	void toggle_info_displays_wrapper(LLSD const& request)
+	{
+		for (LLSD::array_const_iterator iter = request["displays"].beginArray();
+			iter != request["displays"].endArray();
+			++iter)
+		{
+			U32 info_display = info_display_from_string( iter->asString() );
+			if ( info_display != 0 )
+			{
+				LLPipeline::toggleRenderDebug( (void*) info_display );
+			}
+		}
+	}
+
+	void has_info_display_wrapper(LLSD const& request)
+	{
+		LLEventAPI::Response response(LLSD(), request);
+		U32 info_display = info_display_from_string( request["display"].asString() );
+		if ( info_display != 0 )
+		{
+			response["value"] = gPipeline.hasRenderDebugMask(info_display);
+		}
+		else
+		{
+			response.error(STRINGIZE("unknown display '" << request["display"].asString() << "'"));
+		}
+	}
+
+	void disable_all_info_displays_wrapper(LLSD const& request)
+	{
+		gPipeline.clearAllRenderDebugDisplays();
+	}
+
+	void enable_all_info_displays_wrapper(LLSD const& request)
+	{
+		gPipeline.setAllRenderDebugDisplays();
+	}
+
+}
+
+
+LLPipelineListener::LLPipelineListener():
+	LLEventAPI("LLPipeline",
+			   "API to te rendering pipeline.")
+{
+	// Render Types
+	add("toggleRenderTypes",
+		"Toggle rendering [\"types\"]:\n"
+		"See: llviewermenu.cpp:render_type_from_string for list of available types.",
+		&toggle_render_types_wrapper);
+	add("hasRenderType",
+		"Check if rendering [\"type\"] is enabled:\n"
+		"See: llviewermenu.cpp:render_type_from_string for list of available types.",
+		&has_render_type_wrapper,
+		LLSDMap("reply", LLSD()));
+	add("disableAllRenderTypes",
+		"Turn off all rendering types.",
+		&disable_all_render_types_wrapper);
+	add("enableAllRenderTypes",
+		"Turn on all rendering types.",
+		&enable_all_render_types_wrapper);
+
+	// Render Features
+	add("toggleRenderFeatures",
+		"Toggle rendering [\"features\"]:\n"
+		"See: llviewermenu.cpp:feature_from_string for list of available features.",
+		&toggle_render_features_wrapper);
+	add("hasRenderFeature",
+		"Check if rendering [\"feature\"] is enabled:\n"
+		"See: llviewermenu.cpp:render_feature_from_string for list of available features.",
+		&has_render_feature_wrapper,
+		LLSDMap("reply", LLSD()));
+	add("disableAllRenderFeatures",
+		"Turn off all rendering features.",
+		&disable_all_render_features_wrapper);
+	add("enableAllRenderFeatures",
+		"Turn on all rendering features.",
+		&enable_all_render_features_wrapper);
+
+	// Render Info Displays
+	add("toggleRenderInfoDisplays",
+		"Toggle info [\"displays\"]:\n"
+		"See: llviewermenu.cpp:info_display_from_string for list of available displays.",
+		&toggle_info_displays_wrapper);
+	add("hasRenderInfoDisplay",
+		"Check if info [\"display\"] is enabled:\n"
+		"See: llviewermenu.cpp:info_display_from_string for list of available displays.",
+		&has_info_display_wrapper,
+		LLSDMap("reply", LLSD()));
+	add("disableAllRenderInfoDisplays",
+		"Turn off all info displays.",
+		&disable_all_info_displays_wrapper);
+	add("enableAllRenderInfoDisplays",
+		"Turn on all info displays.",
+		&enable_all_info_displays_wrapper);
+}
+
diff --git a/indra/newview/llpipelinelistener.h b/indra/newview/llpipelinelistener.h
new file mode 100644
index 0000000000000000000000000000000000000000..da1898e57b62caed56c36d3268c19ce7fbd38fcd
--- /dev/null
+++ b/indra/newview/llpipelinelistener.h
@@ -0,0 +1,41 @@
+/**
+ * @file   llpipelinelistener.h
+ * @author Don Kjer
+ * @date   2012-07-09
+ * @brief  Wrap subset of LLPipeline API in event API
+ * 
+ * $LicenseInfo:firstyear=2012&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$
+ */
+
+#if ! defined(LL_LLPIPELINELISTENER_H)
+#define LL_LLPIPELINELISTENER_H
+
+#include "lleventapi.h"
+
+/// Listen on an LLEventPump with specified name for LLPipeline request events.
+class LLPipelineListener: public LLEventAPI
+{
+public:
+	LLPipelineListener();
+};
+
+#endif /* ! defined(LL_LLPIPELINELISTENER_H) */
diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp
index d58ee05fb6bb25d1bb9d938df9a33d40c79c1d17..3b486efd7e0fdf5284684826adca1121c264722c 100644
--- a/indra/newview/llviewerdisplay.cpp
+++ b/indra/newview/llviewerdisplay.cpp
@@ -1063,7 +1063,7 @@ void render_hud_attachments()
 		gPipeline.pushRenderTypeMask();
 		
 		// turn off everything
-		gPipeline.andRenderTypeMask(LLPipeline::END_RENDER_TYPES);
+		gPipeline.clearAllRenderTypes();
 		// turn on HUD
 		gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_HUD);
 		// turn on HUD particles
diff --git a/indra/newview/llviewermenu.h b/indra/newview/llviewermenu.h
index 3515aa4302cfe614340fae22d1134ba8781f6935..885a0721c0bda48a748cc9f46af05b26cb901a38 100644
--- a/indra/newview/llviewermenu.h
+++ b/indra/newview/llviewermenu.h
@@ -139,6 +139,11 @@ bool handle_go_to();
 // Export to XML or Collada
 void handle_export_selected( void * );
 
+// Convert strings to internal types
+U32 render_type_from_string(std::string render_type);
+U32 feature_from_string(std::string feature);
+U32 info_display_from_string(std::string info_display);
+
 class LLViewerMenuHolderGL : public LLMenuHolderGL
 {
 public:
diff --git a/indra/newview/llviewerobjectlist.cpp b/indra/newview/llviewerobjectlist.cpp
index ea20950b36f1801505e535e4034ea10e1bbb0868..3cd749fb4681a1bac1b96342f604ec21337754ea 100644
--- a/indra/newview/llviewerobjectlist.cpp
+++ b/indra/newview/llviewerobjectlist.cpp
@@ -1526,6 +1526,7 @@ static LLFastTimer::DeclareTimer FTM_REGION_SHIFT("Region Shift");
 
 void LLViewerObjectList::shiftObjects(const LLVector3 &offset)
 {
+	if (gHeadlessClient) return;
 	// This is called when we shift our origin when we cross region boundaries...
 	// We need to update many object caches, I'll document this more as I dig through the code
 	// cleaning things out...
diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp
index af2eec9ba8961b43c122cf261081d85d04a67e60..62bdb870229f20d4aaba2bdcd1d2d57bf0392159 100644
--- a/indra/newview/llviewerwindow.cpp
+++ b/indra/newview/llviewerwindow.cpp
@@ -1713,6 +1713,7 @@ LLViewerWindow::LLViewerWindow(const Params& p)
 
 void LLViewerWindow::initGLDefaults()
 {
+	if (gHeadlessClient) return;
 	gGL.setSceneBlendType(LLRender::BT_ALPHA);
 
 	if (!LLGLSLShader::sNoFixedFunction)
diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index c20292a76e0c5133e05409e2681b36aa11b62259..1447316558dab3820d2c18adef77e8ec58896e8e 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -72,6 +72,7 @@
 #include "llhudtext.h"
 #include "lllightconstants.h"
 #include "llmeshrepository.h"
+#include "llpipelinelistener.h"
 #include "llresmgr.h"
 #include "llselectmgr.h"
 #include "llsky.h"
@@ -378,6 +379,8 @@ BOOL    LLPipeline::sMemAllocationThrottled = FALSE;
 S32		LLPipeline::sVisibleLightCount = 0;
 F32		LLPipeline::sMinRenderSize = 0.f;
 
+// EventHost API LLPipeline listener.
+static LLPipelineListener sPipelineListener;
 
 static LLCullResult* sCull = NULL;
 
@@ -481,19 +484,29 @@ void LLPipeline::init()
 	LLViewerStats::getInstance()->mTrianglesDrawnStat.reset();
 	resetFrameStats();
 
-	for (U32 i = 0; i < NUM_RENDER_TYPES; ++i)
+	if (gSavedSettings.getBOOL("DisableAllRenderFeatures"))
 	{
-		mRenderTypeEnabled[i] = TRUE; //all rendering types start enabled
+		clearAllRenderDebugFeatures();
 	}
+	else
+	{
+		setAllRenderDebugFeatures(); // By default, all debugging features on
+	}
+	clearAllRenderDebugDisplays(); // All debug displays off
 
-	mRenderDebugFeatureMask = 0xffffffff; // All debugging features on
-	mRenderDebugMask = 0;	// All debug starts off
-
-	// Don't turn on ground when this is set
-	// Mac Books with intel 950s need this
-	if(!gSavedSettings.getBOOL("RenderGround"))
+	if (gSavedSettings.getBOOL("DisableAllRenderTypes"))
+	{
+		clearAllRenderTypes();
+	}
+	else
 	{
-		toggleRenderType(RENDER_TYPE_GROUND);
+		setAllRenderTypes(); // By default, all rendering types start enabled
+		// Don't turn on ground when this is set
+		// Mac Books with intel 950s need this
+		if(!gSavedSettings.getBOOL("RenderGround"))
+		{
+			toggleRenderType(RENDER_TYPE_GROUND);
+		}
 	}
 
 	// make sure RenderPerformanceTest persists (hackity hack hack)
@@ -1115,6 +1128,7 @@ void LLPipeline::releaseScreenBuffers()
 
 void LLPipeline::createGLBuffers()
 {
+	if (gHeadlessClient) return;
 	stop_glerror();
 	LLMemType mt_cb(LLMemType::MTYPE_PIPELINE_CREATE_BUFFERS);
 	assertInitialized();
@@ -6397,6 +6411,22 @@ void LLPipeline::setRenderDebugFeatureControl(U32 bit, bool value)
 	}
 }
 
+void LLPipeline::pushRenderDebugFeatureMask()
+{
+	mRenderDebugFeatureStack.push(mRenderDebugFeatureMask);
+}
+
+void LLPipeline::popRenderDebugFeatureMask()
+{
+	if (mRenderDebugFeatureStack.empty())
+	{
+		llerrs << "Depleted render feature stack." << llendl;
+	}
+
+	mRenderDebugFeatureMask = mRenderDebugFeatureStack.top();
+	mRenderDebugFeatureStack.pop();
+}
+
 // static
 void LLPipeline::setRenderScriptedBeacons(BOOL val)
 {
@@ -10376,6 +10406,22 @@ void LLPipeline::clearRenderTypeMask(U32 type, ...)
 	}
 }
 
+void LLPipeline::setAllRenderTypes()
+{
+	for (U32 i = 0; i < NUM_RENDER_TYPES; ++i)
+	{
+		mRenderTypeEnabled[i] = TRUE;
+	}
+}
+
+void LLPipeline::clearAllRenderTypes()
+{
+	for (U32 i = 0; i < NUM_RENDER_TYPES; ++i)
+	{
+		mRenderTypeEnabled[i] = FALSE;
+	}
+}
+
 void LLPipeline::addDebugBlip(const LLVector3& position, const LLColor4& color)
 {
 	DebugBlip blip(position, color);
diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h
index d1baf17d0dd504870ae9c477fb5fa9bb3a311978..6abdfe11d023939dd45d6e5a7b8b31c9404fd0f3 100644
--- a/indra/newview/pipeline.h
+++ b/indra/newview/pipeline.h
@@ -305,20 +305,28 @@ class LLPipeline
 
 	BOOL hasRenderDebugFeatureMask(const U32 mask) const	{ return (mRenderDebugFeatureMask & mask) ? TRUE : FALSE; }
 	BOOL hasRenderDebugMask(const U32 mask) const			{ return (mRenderDebugMask & mask) ? TRUE : FALSE; }
-	
-
+	void setAllRenderDebugFeatures() { mRenderDebugFeatureMask = 0xffffffff; }
+	void clearAllRenderDebugFeatures() { mRenderDebugFeatureMask = 0x0; }
+	void setAllRenderDebugDisplays() { mRenderDebugMask = 0xffffffff; }
+	void clearAllRenderDebugDisplays() { mRenderDebugMask = 0x0; }
 
 	BOOL hasRenderType(const U32 type) const;
 	BOOL hasAnyRenderType(const U32 type, ...) const;
 
 	void setRenderTypeMask(U32 type, ...);
-	void orRenderTypeMask(U32 type, ...);
+	// This is equivalent to 'setRenderTypeMask'
+	//void orRenderTypeMask(U32 type, ...);
 	void andRenderTypeMask(U32 type, ...);
 	void clearRenderTypeMask(U32 type, ...);
+	void setAllRenderTypes();
+	void clearAllRenderTypes();
 	
 	void pushRenderTypeMask();
 	void popRenderTypeMask();
 
+	void pushRenderDebugFeatureMask();
+	void popRenderDebugFeatureMask();
+
 	static void toggleRenderType(U32 type);
 
 	// For UI control of render features
@@ -614,6 +622,7 @@ class LLPipeline
 
 	U32						mRenderDebugFeatureMask;
 	U32						mRenderDebugMask;
+	std::stack<U32>			mRenderDebugFeatureStack;
 
 	U32						mOldRenderDebugMask;