From a589bc99701d6258d3dd467a5d36fb989348a758 Mon Sep 17 00:00:00 2001
From: Don Kjer <don@lindenlab.com>
Date: Wed, 11 Jul 2012 00:30:04 +0000
Subject: Added LLPipeline eventhost API.  Added ForcePeriodicRenderingTime
 setting.

---
 indra/newview/CMakeLists.txt            |   2 +
 indra/newview/app_settings/settings.xml |  11 ++
 indra/newview/llappviewer.cpp           |  47 ++++---
 indra/newview/llappviewer.h             |   2 -
 indra/newview/llpipelinelistener.cpp    | 216 ++++++++++++++++++++++++++++++++
 indra/newview/llpipelinelistener.h      |  41 ++++++
 indra/newview/llviewermenu.h            |   5 +
 indra/newview/pipeline.cpp              |  25 +++-
 indra/newview/pipeline.h                |  10 +-
 9 files changed, 337 insertions(+), 22 deletions(-)
 create mode 100644 indra/newview/llpipelinelistener.cpp
 create mode 100644 indra/newview/llpipelinelistener.h

(limited to 'indra/newview')

diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index 9783601696..5a1055319a 100755
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -418,6 +418,7 @@ set(viewer_SOURCE_FILES
     llpatchvertexarray.cpp
     llphysicsmotion.cpp
     llphysicsshapebuilderutil.cpp
+    llpipelinelistener.cpp
     llplacesinventorybridge.cpp
     llplacesinventorypanel.cpp
     llpopupview.cpp
@@ -967,6 +968,7 @@ set(viewer_HEADER_FILES
     llpatchvertexarray.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 dde423f86c..8c82b761bb 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -13043,6 +13043,17 @@
       <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/llappviewer.cpp b/indra/newview/llappviewer.cpp
index f01f62c798..f5dce58758 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -631,8 +631,6 @@ LLAppViewer::LLAppViewer() :
 	mForceGraphicsDetail(false),
 	mQuitRequested(false),
 	mLogoutRequestSent(false),
-	mYieldTime(-1),
-	mMinFrameTime(-1.0),
 	mMainloopTimeout(NULL),
 	mAgentRegionLastAlive(false),
 	mRandomizeFramerate(LLCachedControl<bool>(gSavedSettings,"Randomize Framerate", FALSE)),
@@ -1200,7 +1198,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);
@@ -1212,6 +1210,8 @@ bool LLAppViewer::mainLoop()
     // point of posting.
     LLSD newFrame;
 
+	BOOL restore_rendering_masks = FALSE;
+
 	//LLPrivateMemoryPoolTester::getInstance()->run(false) ;
 	//LLPrivateMemoryPoolTester::getInstance()->run(true) ;
 	//LLPrivateMemoryPoolTester::destroy() ;
@@ -1229,6 +1229,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)
@@ -1351,10 +1373,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
@@ -1468,10 +1491,12 @@ bool LLAppViewer::mainLoop()
 				}
 
 				// Limit FPS
-				if (mMinFrameTime > F_APPROXIMATELY_ZERO)
+				F32 max_fps = gSavedSettings.getF32("MaxFPS");
+				if (max_fps > F_APPROXIMATELY_ZERO)
 				{
 					// Sleep a while to limit frame rate.
-					S32 milliseconds_to_sleep = llclamp((S32)((mMinFrameTime - frameTimer.getElapsedTimeF64()) * 1000.f), 0, 1000);
+					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);
@@ -2590,14 +2615,6 @@ bool LLAppViewer::initConfiguration()
 		}
 	}
 
-    mYieldTime = gSavedSettings.getS32("YieldTime");
-	mMinFrameTime = -1.0f;
-	F32 max_fps = gSavedSettings.getF32("MaxFPS");
-	if (max_fps > F_APPROXIMATELY_ZERO)
-	{
-		mMinFrameTime = 1.0f / max_fps;
-	}
-
 	// Read skin/branding settings if specified.
 	//if (! gDirUtilp->getSkinDir().empty() )
 	//{
diff --git a/indra/newview/llappviewer.h b/indra/newview/llappviewer.h
index f55954234f..043893020b 100644
--- a/indra/newview/llappviewer.h
+++ b/indra/newview/llappviewer.h
@@ -253,8 +253,6 @@ private:
 
     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;
-	F32 mMinFrameTime;
 	struct SettingsFiles* mSettingsLocationList;
 
 	LLWatchdogTimeout* mMainloopTimeout;
diff --git a/indra/newview/llpipelinelistener.cpp b/indra/newview/llpipelinelistener.cpp
new file mode 100644
index 0000000000..20759239bf
--- /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 0000000000..da1898e57b
--- /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/llviewermenu.h b/indra/newview/llviewermenu.h
index 8c40762865..c809ebde43 100644
--- a/indra/newview/llviewermenu.h
+++ b/indra/newview/llviewermenu.h
@@ -130,6 +130,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/pipeline.cpp b/indra/newview/pipeline.cpp
index cd4c7289a7..72cc6bfcd4 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"
@@ -368,6 +369,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;
 
@@ -473,13 +476,13 @@ void LLPipeline::init()
 
 	if (gSavedSettings.getBOOL("DisableAllRenderFeatures"))
 	{
-		mRenderDebugFeatureMask = 0x0;
+		clearAllRenderDebugFeatures();
 	}
 	else
 	{
-		mRenderDebugFeatureMask = 0xffffffff; // By default, all debugging features on
+		setAllRenderDebugFeatures(); // By default, all debugging features on
 	}
-	mRenderDebugMask = 0;	// All debug starts off
+	clearAllRenderDebugDisplays(); // All debug displays off
 
 	if (gSavedSettings.getBOOL("DisableAllRenderTypes"))
 	{
@@ -6008,6 +6011,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)
 {
diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h
index 3536746eb1..16610b8c68 100644
--- a/indra/newview/pipeline.h
+++ b/indra/newview/pipeline.h
@@ -304,8 +304,10 @@ public:
 
 	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;
@@ -321,6 +323,9 @@ public:
 	void pushRenderTypeMask();
 	void popRenderTypeMask();
 
+	void pushRenderDebugFeatureMask();
+	void popRenderDebugFeatureMask();
+
 	static void toggleRenderType(U32 type);
 
 	// For UI control of render features
@@ -609,6 +614,7 @@ protected:
 
 	U32						mRenderDebugFeatureMask;
 	U32						mRenderDebugMask;
+	std::stack<U32>			mRenderDebugFeatureStack;
 
 	U32						mOldRenderDebugMask;
 	
-- 
cgit v1.2.3