diff --git a/indra/appearance_utility/CMakeLists.txt b/indra/appearance_utility/CMakeLists.txt
index c38f811b44ad6947cc2993887dce07a2f6d1d339..d860dae4df86006ec44933f846ea2965a72a079e 100644
--- a/indra/appearance_utility/CMakeLists.txt
+++ b/indra/appearance_utility/CMakeLists.txt
@@ -9,6 +9,7 @@ include(OpenSSL)
 include(UI)
 include(LLAppearance)
 include(LLCommon)
+include(LLInventory)
 include(LLVFS)
 include(LLXML)
 include(LLUI)
@@ -19,6 +20,7 @@ include_directories(
     ${LLVFS_INCLUDE_DIRS}
     ${LLXML_INCLUDE_DIRS}
     ${LLUI_INCLUDE_DIRS}
+    ${LLINVENTORY_INCLUDE_DIRS}
     ${CURL_INCLUDE_DIRS}
     ${CARES_INCLUDE_DIRS}
     ${OPENSSL_INCLUDE_DIRS}
@@ -44,6 +46,7 @@ target_link_libraries(appearance-utility-bin
     ${CRYPTO_LIBRARIES}
     ${UI_LIBRARIES}
     ${LLAPPEARANCE_LIBRARIES}
+    ${LLINVENTORY_LIBRARIES}
     ${LLXML_LIBRARIES}
     ${LLUI_LIBRARIES}
     ${LLVFS_LIBRARIES}
diff --git a/indra/appearance_utility/appearance_utility.cpp b/indra/appearance_utility/appearance_utility.cpp
index 130bca84a89b265d93f4e0b731092e5385e3209d..c7f8703e286a91d665450d5d41318ae246653f9c 100644
--- a/indra/appearance_utility/appearance_utility.cpp
+++ b/indra/appearance_utility/appearance_utility.cpp
@@ -38,6 +38,8 @@
 #include "llsdserialize.h"
 #include "llsdutil.h"
 
+//#include "llwearabledata.h"
+
 enum EResult
 {
 	RV_SUCCESS = 0,
@@ -150,6 +152,8 @@ EResult process_tbd(LLSD& input, std::ostream& output, LLSD& error_llsd)
 {
 	EResult rv = RV_SUCCESS;
 
+	//LLWearableData wearable_data;
+
 	LLSD result;
 	result["success"] = true;
 	result["input"] = input;
diff --git a/indra/llappearance/CMakeLists.txt b/indra/llappearance/CMakeLists.txt
index 41da898457905f3ee9305031cba29c2551d54e44..717efb2f8b04fb525f263aae00bca2f7e370a72e 100644
--- a/indra/llappearance/CMakeLists.txt
+++ b/indra/llappearance/CMakeLists.txt
@@ -43,7 +43,6 @@ include_directories(
 set(llappearance_SOURCE_FILES
     llavatarappearance.cpp
     lldriverparam.cpp
-    llinventoryicon.cpp
     lllocaltextureobject.cpp
     lltexglobalcolor.cpp
     lltexlayer.cpp
@@ -61,7 +60,6 @@ set(llappearance_HEADER_FILES
 
     llavatarappearance.h
     lldriverparam.h
-    llinventoryicon.h
     lljointpickname.h
     lllocaltextureobject.h
     lltexglobalcolor.h
diff --git a/indra/llappearance/lltexlayer.cpp b/indra/llappearance/lltexlayer.cpp
index 9b70f737a086b43c0953f5c7fc0333e45afaa79d..1325267dc236ce2500f899f6ca916f6e9c500de4 100644
--- a/indra/llappearance/lltexlayer.cpp
+++ b/indra/llappearance/lltexlayer.cpp
@@ -38,7 +38,7 @@
 #include "llvfs.h"
 #include "lltexlayerparams.h"
 #include "lltexturemanagerbridge.h"
-#include "llui.h"
+#include "llrender2dutils.h"
 #include "llwearable.h"
 #include "llwearabledata.h"
 #include "llvertexbuffer.h"
diff --git a/indra/llappearance/lltexlayer.h b/indra/llappearance/lltexlayer.h
index e6c2ece64aed8f86878de91394cbfbab2a8c8267..0d7fad349cbb409c6bdd98293a4f035eb8cb26f8 100644
--- a/indra/llappearance/lltexlayer.h
+++ b/indra/llappearance/lltexlayer.h
@@ -28,8 +28,8 @@
 #define LL_LLTEXLAYER_H
 
 #include <deque>
+#include "llglslshader.h"
 #include "llgltexture.h"
-//#include "llframetimer.h"
 #include "llavatarappearancedefines.h"
 #include "lltexlayerparams.h"
 
diff --git a/indra/llappearance/lltexlayerparams.cpp b/indra/llappearance/lltexlayerparams.cpp
index 06001c6b15feb988f1107c2b2ee9fa45581b14c2..82c92b5a5ea1975bb9eb47317ed51bf30e2af219 100644
--- a/indra/llappearance/lltexlayerparams.cpp
+++ b/indra/llappearance/lltexlayerparams.cpp
@@ -33,8 +33,8 @@
 #include "llquantize.h"
 #include "lltexlayer.h"
 #include "lltexturemanagerbridge.h"
+#include "llrender2dutils.h"
 #include "llwearable.h"
-#include "llui.h"
 
 //-----------------------------------------------------------------------------
 // LLTexLayerParam
diff --git a/indra/llappearance/llviewervisualparam.cpp b/indra/llappearance/llviewervisualparam.cpp
index a6792d09747525cddc76a82a6c5d8c61af45f3fd..cc81bcf118a2a964d9a40feb556c400eed2cdf99 100644
--- a/indra/llappearance/llviewervisualparam.cpp
+++ b/indra/llappearance/llviewervisualparam.cpp
@@ -31,7 +31,6 @@
 
 #include "llviewervisualparam.h"
 #include "llxmltree.h"
-#include "llui.h"
 #include "llwearable.h"
 
 //-----------------------------------------------------------------------------
diff --git a/indra/llappearance/llwearabletype.cpp b/indra/llappearance/llwearabletype.cpp
index c72a0965fe7ad64bdee3d786bdd10c3d029328af..3a8e1b8be3f0ef8c818eadb9038341a62ac357f8 100644
--- a/indra/llappearance/llwearabletype.cpp
+++ b/indra/llappearance/llwearabletype.cpp
@@ -26,15 +26,15 @@
 
 #include "linden_common.h"
 #include "llwearabletype.h"
-#include "llinventoryicon.h"
-#include "lltrans.h"
+#include "llinventorytype.h"
+#include "llui/lltrans.h"
 
 struct WearableEntry : public LLDictionaryEntry
 {
 	WearableEntry(const std::string &name,
 				  const std::string& default_new_name,
 				  LLAssetType::EType assetType,
-				  LLInventoryIcon::EIconName iconName,
+				  LLInventoryType::EIconName iconName,
 				  BOOL disable_camera_switch = FALSE,
 				  BOOL allow_multiwear = TRUE) :
 		LLDictionaryEntry(name),
@@ -50,7 +50,7 @@ struct WearableEntry : public LLDictionaryEntry
 	const LLAssetType::EType mAssetType;
 	const std::string mLabel;
 	const std::string mDefaultNewName; //keep mLabel for backward compatibility
-	LLInventoryIcon::EIconName mIconName;
+	LLInventoryType::EIconName mIconName;
 	BOOL mDisableCameraSwitch;
 	BOOL mAllowMultiwear;
 };
@@ -64,26 +64,26 @@ public:
 
 LLWearableDictionary::LLWearableDictionary()
 {
-	addEntry(LLWearableType::WT_SHAPE,        new WearableEntry("shape",       "New Shape",			LLAssetType::AT_BODYPART, 	LLInventoryIcon::ICONNAME_BODYPART_SHAPE, FALSE, FALSE));
-	addEntry(LLWearableType::WT_SKIN,         new WearableEntry("skin",        "New Skin",			LLAssetType::AT_BODYPART, 	LLInventoryIcon::ICONNAME_BODYPART_SKIN, FALSE, FALSE));
-	addEntry(LLWearableType::WT_HAIR,         new WearableEntry("hair",        "New Hair",			LLAssetType::AT_BODYPART, 	LLInventoryIcon::ICONNAME_BODYPART_HAIR, FALSE, FALSE));
-	addEntry(LLWearableType::WT_EYES,         new WearableEntry("eyes",        "New Eyes",			LLAssetType::AT_BODYPART, 	LLInventoryIcon::ICONNAME_BODYPART_EYES, FALSE, FALSE));
-	addEntry(LLWearableType::WT_SHIRT,        new WearableEntry("shirt",       "New Shirt",			LLAssetType::AT_CLOTHING, 	LLInventoryIcon::ICONNAME_CLOTHING_SHIRT, FALSE, TRUE));
-	addEntry(LLWearableType::WT_PANTS,        new WearableEntry("pants",       "New Pants",			LLAssetType::AT_CLOTHING, 	LLInventoryIcon::ICONNAME_CLOTHING_PANTS, FALSE, TRUE));
-	addEntry(LLWearableType::WT_SHOES,        new WearableEntry("shoes",       "New Shoes",			LLAssetType::AT_CLOTHING, 	LLInventoryIcon::ICONNAME_CLOTHING_SHOES, FALSE, TRUE));
-	addEntry(LLWearableType::WT_SOCKS,        new WearableEntry("socks",       "New Socks",			LLAssetType::AT_CLOTHING, 	LLInventoryIcon::ICONNAME_CLOTHING_SOCKS, FALSE, TRUE));
-	addEntry(LLWearableType::WT_JACKET,       new WearableEntry("jacket",      "New Jacket",		LLAssetType::AT_CLOTHING, 	LLInventoryIcon::ICONNAME_CLOTHING_JACKET, FALSE, TRUE));
-	addEntry(LLWearableType::WT_GLOVES,       new WearableEntry("gloves",      "New Gloves",		LLAssetType::AT_CLOTHING, 	LLInventoryIcon::ICONNAME_CLOTHING_GLOVES, FALSE, TRUE));
-	addEntry(LLWearableType::WT_UNDERSHIRT,   new WearableEntry("undershirt",  "New Undershirt",	LLAssetType::AT_CLOTHING, 	LLInventoryIcon::ICONNAME_CLOTHING_UNDERSHIRT, FALSE, TRUE));
-	addEntry(LLWearableType::WT_UNDERPANTS,   new WearableEntry("underpants",  "New Underpants",	LLAssetType::AT_CLOTHING, 	LLInventoryIcon::ICONNAME_CLOTHING_UNDERPANTS, FALSE, TRUE));
-	addEntry(LLWearableType::WT_SKIRT,        new WearableEntry("skirt",       "New Skirt",			LLAssetType::AT_CLOTHING, 	LLInventoryIcon::ICONNAME_CLOTHING_SKIRT, FALSE, TRUE));
-	addEntry(LLWearableType::WT_ALPHA,        new WearableEntry("alpha",       "New Alpha",			LLAssetType::AT_CLOTHING, 	LLInventoryIcon::ICONNAME_CLOTHING_ALPHA, FALSE, TRUE));
-	addEntry(LLWearableType::WT_TATTOO,       new WearableEntry("tattoo",      "New Tattoo",		LLAssetType::AT_CLOTHING, 	LLInventoryIcon::ICONNAME_CLOTHING_TATTOO, FALSE, TRUE));
+	addEntry(LLWearableType::WT_SHAPE,        new WearableEntry("shape",       "New Shape",			LLAssetType::AT_BODYPART, 	LLInventoryType::ICONNAME_BODYPART_SHAPE, FALSE, FALSE));
+	addEntry(LLWearableType::WT_SKIN,         new WearableEntry("skin",        "New Skin",			LLAssetType::AT_BODYPART, 	LLInventoryType::ICONNAME_BODYPART_SKIN, FALSE, FALSE));
+	addEntry(LLWearableType::WT_HAIR,         new WearableEntry("hair",        "New Hair",			LLAssetType::AT_BODYPART, 	LLInventoryType::ICONNAME_BODYPART_HAIR, FALSE, FALSE));
+	addEntry(LLWearableType::WT_EYES,         new WearableEntry("eyes",        "New Eyes",			LLAssetType::AT_BODYPART, 	LLInventoryType::ICONNAME_BODYPART_EYES, FALSE, FALSE));
+	addEntry(LLWearableType::WT_SHIRT,        new WearableEntry("shirt",       "New Shirt",			LLAssetType::AT_CLOTHING, 	LLInventoryType::ICONNAME_CLOTHING_SHIRT, FALSE, TRUE));
+	addEntry(LLWearableType::WT_PANTS,        new WearableEntry("pants",       "New Pants",			LLAssetType::AT_CLOTHING, 	LLInventoryType::ICONNAME_CLOTHING_PANTS, FALSE, TRUE));
+	addEntry(LLWearableType::WT_SHOES,        new WearableEntry("shoes",       "New Shoes",			LLAssetType::AT_CLOTHING, 	LLInventoryType::ICONNAME_CLOTHING_SHOES, FALSE, TRUE));
+	addEntry(LLWearableType::WT_SOCKS,        new WearableEntry("socks",       "New Socks",			LLAssetType::AT_CLOTHING, 	LLInventoryType::ICONNAME_CLOTHING_SOCKS, FALSE, TRUE));
+	addEntry(LLWearableType::WT_JACKET,       new WearableEntry("jacket",      "New Jacket",		LLAssetType::AT_CLOTHING, 	LLInventoryType::ICONNAME_CLOTHING_JACKET, FALSE, TRUE));
+	addEntry(LLWearableType::WT_GLOVES,       new WearableEntry("gloves",      "New Gloves",		LLAssetType::AT_CLOTHING, 	LLInventoryType::ICONNAME_CLOTHING_GLOVES, FALSE, TRUE));
+	addEntry(LLWearableType::WT_UNDERSHIRT,   new WearableEntry("undershirt",  "New Undershirt",	LLAssetType::AT_CLOTHING, 	LLInventoryType::ICONNAME_CLOTHING_UNDERSHIRT, FALSE, TRUE));
+	addEntry(LLWearableType::WT_UNDERPANTS,   new WearableEntry("underpants",  "New Underpants",	LLAssetType::AT_CLOTHING, 	LLInventoryType::ICONNAME_CLOTHING_UNDERPANTS, FALSE, TRUE));
+	addEntry(LLWearableType::WT_SKIRT,        new WearableEntry("skirt",       "New Skirt",			LLAssetType::AT_CLOTHING, 	LLInventoryType::ICONNAME_CLOTHING_SKIRT, FALSE, TRUE));
+	addEntry(LLWearableType::WT_ALPHA,        new WearableEntry("alpha",       "New Alpha",			LLAssetType::AT_CLOTHING, 	LLInventoryType::ICONNAME_CLOTHING_ALPHA, FALSE, TRUE));
+	addEntry(LLWearableType::WT_TATTOO,       new WearableEntry("tattoo",      "New Tattoo",		LLAssetType::AT_CLOTHING, 	LLInventoryType::ICONNAME_CLOTHING_TATTOO, FALSE, TRUE));
 
-	addEntry(LLWearableType::WT_PHYSICS,      new WearableEntry("physics",     "New Physics",		LLAssetType::AT_CLOTHING, 	LLInventoryIcon::ICONNAME_CLOTHING_PHYSICS, TRUE, TRUE));
+	addEntry(LLWearableType::WT_PHYSICS,      new WearableEntry("physics",     "New Physics",		LLAssetType::AT_CLOTHING, 	LLInventoryType::ICONNAME_CLOTHING_PHYSICS, TRUE, TRUE));
 
-	addEntry(LLWearableType::WT_INVALID,      new WearableEntry("invalid",     "Invalid Wearable", 	LLAssetType::AT_NONE, 		LLInventoryIcon::ICONNAME_NONE, FALSE, FALSE));
-	addEntry(LLWearableType::WT_NONE,      	  new WearableEntry("none",        "Invalid Wearable", 	LLAssetType::AT_NONE, 		LLInventoryIcon::ICONNAME_NONE, FALSE, FALSE));
+	addEntry(LLWearableType::WT_INVALID,      new WearableEntry("invalid",     "Invalid Wearable", 	LLAssetType::AT_NONE, 		LLInventoryType::ICONNAME_NONE, FALSE, FALSE));
+	addEntry(LLWearableType::WT_NONE,      	  new WearableEntry("none",        "Invalid Wearable", 	LLAssetType::AT_NONE, 		LLInventoryType::ICONNAME_NONE, FALSE, FALSE));
 }
 
 // static
@@ -131,7 +131,7 @@ LLAssetType::EType LLWearableType::getAssetType(LLWearableType::EType type)
 }
 
 // static 
-LLInventoryIcon::EIconName LLWearableType::getIconName(LLWearableType::EType type)
+LLInventoryType::EIconName LLWearableType::getIconName(LLWearableType::EType type)
 {
 	const LLWearableDictionary *dict = LLWearableDictionary::getInstance();
 	const WearableEntry *entry = dict->lookup(type);
diff --git a/indra/llappearance/llwearabletype.h b/indra/llappearance/llwearabletype.h
index d633b4807ece113c630fca0250318a5d86a338fe..78008c27ea2bb86331b34b3e2b7ac7db5b94e1a6 100644
--- a/indra/llappearance/llwearabletype.h
+++ b/indra/llappearance/llwearabletype.h
@@ -29,7 +29,7 @@
 
 #include "llassettype.h"
 #include "lldictionary.h"
-#include "llinventoryicon.h"
+#include "llinventorytype.h"
 #include "llsingleton.h"
 
 class LLWearableType
@@ -64,7 +64,7 @@ public:
 	static const std::string& 			getTypeLabel(EType type);
 	static LLAssetType::EType 			getAssetType(EType type);
 	static EType 						typeNameToType(const std::string& type_name);
-	static LLInventoryIcon::EIconName 	getIconName(EType type);
+	static LLInventoryType::EIconName 	getIconName(EType type);
 	static BOOL 						getDisableCameraSwitch(EType type);
 	static BOOL 						getAllowMultiwear(EType type);
 
diff --git a/indra/llinventory/llinventorytype.h b/indra/llinventory/llinventorytype.h
index 4d1e0db04016126a4fc70df3b1f738bf78031c4e..078b7739328f1ed5ae4238da8f6b85c2887efaf3 100644
--- a/indra/llinventory/llinventorytype.h
+++ b/indra/llinventory/llinventorytype.h
@@ -68,6 +68,53 @@ public:
 		IT_NONE = -1
 	};
 
+	enum EIconName
+	{
+		ICONNAME_TEXTURE,
+		ICONNAME_SOUND,
+		ICONNAME_CALLINGCARD_ONLINE,
+		ICONNAME_CALLINGCARD_OFFLINE,
+		ICONNAME_LANDMARK,
+		ICONNAME_LANDMARK_VISITED,
+		ICONNAME_SCRIPT,
+		ICONNAME_CLOTHING,
+		ICONNAME_OBJECT,
+		ICONNAME_OBJECT_MULTI,
+		ICONNAME_NOTECARD,
+		ICONNAME_BODYPART,
+		ICONNAME_SNAPSHOT,
+		
+		ICONNAME_BODYPART_SHAPE,
+		ICONNAME_BODYPART_SKIN,
+		ICONNAME_BODYPART_HAIR,
+		ICONNAME_BODYPART_EYES,
+		ICONNAME_CLOTHING_SHIRT,
+		ICONNAME_CLOTHING_PANTS,
+		ICONNAME_CLOTHING_SHOES,
+		ICONNAME_CLOTHING_SOCKS,
+		ICONNAME_CLOTHING_JACKET,
+		ICONNAME_CLOTHING_GLOVES,
+		ICONNAME_CLOTHING_UNDERSHIRT,
+		ICONNAME_CLOTHING_UNDERPANTS,
+		ICONNAME_CLOTHING_SKIRT,
+		ICONNAME_CLOTHING_ALPHA,
+		ICONNAME_CLOTHING_TATTOO,
+
+		ICONNAME_ANIMATION,
+		ICONNAME_GESTURE,
+
+		ICONNAME_CLOTHING_PHYSICS,
+		
+		ICONNAME_LINKITEM,
+		ICONNAME_LINKFOLDER,
+		ICONNAME_MESH,
+
+		ICONNAME_INVALID,
+		ICONNAME_COUNT,
+		ICONNAME_NONE = -1
+	};
+
+
 	// machine transation between type and strings
 	static EType lookup(const std::string& name);
 	static const std::string &lookup(EType type);
diff --git a/indra/llrender/CMakeLists.txt b/indra/llrender/CMakeLists.txt
index 4609401ccf020340748808dc9f19515d1a5dc367..3418ce2dfa7d7dffe46b595baf5f28b7760e86ce 100644
--- a/indra/llrender/CMakeLists.txt
+++ b/indra/llrender/CMakeLists.txt
@@ -37,10 +37,12 @@ set(llrender_SOURCE_FILES
     llgltexture.cpp
     llimagegl.cpp
     llpostprocess.cpp
+    llrender2dutils.cpp
     llrendernavprim.cpp
     llrendersphere.cpp
     llshadermgr.cpp
     lltexture.cpp
+    lluiimage.cpp
     llvertexbuffer.cpp
     )
     
@@ -62,10 +64,12 @@ set(llrender_HEADER_FILES
     llimagegl.h
     llpostprocess.h
     llrender.h
+    llrender2dutils.h
     llrendernavprim.h
     llrendersphere.h
     llshadermgr.h
     lltexture.h
+    lluiimage.h
     llvertexbuffer.h
     )
 
diff --git a/indra/llrender/llrender2dutils.cpp b/indra/llrender/llrender2dutils.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..b2679176bea3152d0b2125bffd124126ea09b12d
--- /dev/null
+++ b/indra/llrender/llrender2dutils.cpp
@@ -0,0 +1,1621 @@
+/** 
+ * @file llrender2dutils.cpp
+ * @brief GL function implementations for immediate-mode gl drawing.
+ *
+ * $LicenseInfo:firstyear=2001&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 "linden_common.h"
+
+// Linden library includes
+#include "v2math.h"
+#include "m3math.h"
+#include "v4color.h"
+#include "llfontgl.h"
+#include "llrender.h"
+#include "llrect.h"
+#include "llgl.h"
+#include "lltexture.h"
+
+// Project includes
+#include "llrender2dutils.h"
+#include "lluiimage.h"
+
+
+//
+// Globals
+//
+const LLColor4 UI_VERTEX_COLOR(1.f, 1.f, 1.f, 1.f);
+/*static*/ LLVector2		LLRender2D::sGLScaleFactor(1.f, 1.f);
+/*static*/ LLImageProviderInterface* LLRender2D::sImageProvider = NULL;
+
+//
+// Functions
+//
+
+BOOL ui_point_in_rect(S32 x, S32 y, S32 left, S32 top, S32 right, S32 bottom)
+{
+	if (x < left || right < x) return FALSE;
+	if (y < bottom || top < y) return FALSE;
+	return TRUE;
+}
+
+
+// Puts GL into 2D drawing mode by turning off lighting, setting to an
+// orthographic projection, etc.
+void gl_state_for_2d(S32 width, S32 height)
+{
+	stop_glerror();
+	F32 window_width = (F32) width;//gViewerWindow->getWindowWidth();
+	F32 window_height = (F32) height;//gViewerWindow->getWindowHeight();
+
+	gGL.matrixMode(LLRender::MM_PROJECTION);
+	gGL.loadIdentity();
+	gGL.ortho(0.0f, llmax(window_width, 1.f), 0.0f, llmax(window_height,1.f), -1.0f, 1.0f);
+	gGL.matrixMode(LLRender::MM_MODELVIEW);
+	gGL.loadIdentity();
+	stop_glerror();
+}
+
+
+void gl_draw_x(const LLRect& rect, const LLColor4& color)
+{
+	gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+
+	gGL.color4fv( color.mV );
+
+	gGL.begin( LLRender::LINES );
+		gGL.vertex2i( rect.mLeft,		rect.mTop );
+		gGL.vertex2i( rect.mRight,	rect.mBottom );
+		gGL.vertex2i( rect.mLeft,		rect.mBottom );
+		gGL.vertex2i( rect.mRight,	rect.mTop );
+	gGL.end();
+}
+
+
+void gl_rect_2d_offset_local( S32 left, S32 top, S32 right, S32 bottom, const LLColor4 &color, S32 pixel_offset, BOOL filled)
+{
+	gGL.color4fv(color.mV);
+	gl_rect_2d_offset_local(left, top, right, bottom, pixel_offset, filled);
+}
+
+void gl_rect_2d_offset_local( S32 left, S32 top, S32 right, S32 bottom, S32 pixel_offset, BOOL filled)
+{
+	gGL.pushUIMatrix();
+	left += LLFontGL::sCurOrigin.mX;
+	right += LLFontGL::sCurOrigin.mX;
+	bottom += LLFontGL::sCurOrigin.mY;
+	top += LLFontGL::sCurOrigin.mY;
+
+	gGL.loadUIIdentity();
+	gl_rect_2d(llfloor((F32)left * LLRender2D::sGLScaleFactor.mV[VX]) - pixel_offset,
+				llfloor((F32)top * LLRender2D::sGLScaleFactor.mV[VY]) + pixel_offset,
+				llfloor((F32)right * LLRender2D::sGLScaleFactor.mV[VX]) + pixel_offset,
+				llfloor((F32)bottom * LLRender2D::sGLScaleFactor.mV[VY]) - pixel_offset,
+				filled);
+	gGL.popUIMatrix();
+}
+
+
+void gl_rect_2d(S32 left, S32 top, S32 right, S32 bottom, BOOL filled )
+{
+	stop_glerror();
+	gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+
+	// Counterclockwise quad will face the viewer
+	if( filled )
+	{ 
+		gGL.begin( LLRender::QUADS );
+			gGL.vertex2i(left, top);
+			gGL.vertex2i(left, bottom);
+			gGL.vertex2i(right, bottom);
+			gGL.vertex2i(right, top);
+		gGL.end();
+	}
+	else
+	{
+		if( gGLManager.mATIOffsetVerticalLines )
+		{
+			// Work around bug in ATI driver: vertical lines are offset by (-1,-1)
+			gGL.begin( LLRender::LINES );
+
+				// Verticals 
+				gGL.vertex2i(left + 1, top);
+				gGL.vertex2i(left + 1, bottom);
+
+				gGL.vertex2i(right, bottom);
+				gGL.vertex2i(right, top);
+
+				// Horizontals
+				top--;
+				right--;
+				gGL.vertex2i(left, bottom);
+				gGL.vertex2i(right, bottom);
+
+				gGL.vertex2i(left, top);
+				gGL.vertex2i(right, top);
+			gGL.end();
+		}
+		else
+		{
+			top--;
+			right--;
+			gGL.begin( LLRender::LINE_STRIP );
+				gGL.vertex2i(left, top);
+				gGL.vertex2i(left, bottom);
+				gGL.vertex2i(right, bottom);
+				gGL.vertex2i(right, top);
+				gGL.vertex2i(left, top);
+			gGL.end();
+		}
+	}
+	stop_glerror();
+}
+
+void gl_rect_2d(S32 left, S32 top, S32 right, S32 bottom, const LLColor4 &color, BOOL filled )
+{
+	gGL.color4fv( color.mV );
+	gl_rect_2d( left, top, right, bottom, filled );
+}
+
+
+void gl_rect_2d( const LLRect& rect, const LLColor4& color, BOOL filled )
+{
+	gGL.color4fv( color.mV );
+	gl_rect_2d( rect.mLeft, rect.mTop, rect.mRight, rect.mBottom, filled );
+}
+
+// Given a rectangle on the screen, draws a drop shadow _outside_
+// the right and bottom edges of it.  Along the right it has width "lines"
+// and along the bottom it has height "lines".
+void gl_drop_shadow(S32 left, S32 top, S32 right, S32 bottom, const LLColor4 &start_color, S32 lines)
+{
+	stop_glerror();
+	gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+	
+	// HACK: Overlap with the rectangle by a single pixel.
+	right--;
+	bottom++;
+	lines++;
+
+	LLColor4 end_color = start_color;
+	end_color.mV[VALPHA] = 0.f;
+
+	gGL.begin(LLRender::QUADS);
+
+	// Right edge, CCW faces screen
+	gGL.color4fv(start_color.mV);
+	gGL.vertex2i(right,		top-lines);
+	gGL.vertex2i(right,		bottom);
+	gGL.color4fv(end_color.mV);
+	gGL.vertex2i(right+lines, bottom);
+	gGL.vertex2i(right+lines, top-lines);
+
+	// Bottom edge, CCW faces screen
+	gGL.color4fv(start_color.mV);
+	gGL.vertex2i(right,		bottom);
+	gGL.vertex2i(left+lines,	bottom);
+	gGL.color4fv(end_color.mV);
+	gGL.vertex2i(left+lines,	bottom-lines);
+	gGL.vertex2i(right,		bottom-lines);
+
+	// bottom left Corner
+	gGL.color4fv(start_color.mV);
+	gGL.vertex2i(left+lines,	bottom);
+	gGL.color4fv(end_color.mV);
+	gGL.vertex2i(left,		bottom);
+	// make the bottom left corner not sharp
+	gGL.vertex2i(left+1,		bottom-lines+1);
+	gGL.vertex2i(left+lines,	bottom-lines);
+
+	// bottom right corner
+	gGL.color4fv(start_color.mV);
+	gGL.vertex2i(right,		bottom);
+	gGL.color4fv(end_color.mV);
+	gGL.vertex2i(right,		bottom-lines);
+	// make the rightmost corner not sharp
+	gGL.vertex2i(right+lines-1,	bottom-lines+1);
+	gGL.vertex2i(right+lines,	bottom);
+
+	// top right corner
+	gGL.color4fv(start_color.mV);
+	gGL.vertex2i( right,			top-lines );
+	gGL.color4fv(end_color.mV);
+	gGL.vertex2i( right+lines,	top-lines );
+	// make the corner not sharp
+	gGL.vertex2i( right+lines-1,	top-1 );
+	gGL.vertex2i( right,			top );
+
+	gGL.end();
+	stop_glerror();
+}
+
+void gl_line_2d(S32 x1, S32 y1, S32 x2, S32 y2 )
+{
+	// Work around bug in ATI driver: vertical lines are offset by (-1,-1)
+	if( (x1 == x2) && gGLManager.mATIOffsetVerticalLines )
+	{
+		x1++;
+		x2++;
+		y1++;
+		y2++;
+	}
+
+	gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+	
+	gGL.begin(LLRender::LINES);
+		gGL.vertex2i(x1, y1);
+		gGL.vertex2i(x2, y2);
+	gGL.end();
+}
+
+void gl_line_2d(S32 x1, S32 y1, S32 x2, S32 y2, const LLColor4 &color )
+{
+	// Work around bug in ATI driver: vertical lines are offset by (-1,-1)
+	if( (x1 == x2) && gGLManager.mATIOffsetVerticalLines )
+	{
+		x1++;
+		x2++;
+		y1++;
+		y2++;
+	}
+
+	gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+
+	gGL.color4fv( color.mV );
+
+	gGL.begin(LLRender::LINES);
+		gGL.vertex2i(x1, y1);
+		gGL.vertex2i(x2, y2);
+	gGL.end();
+}
+
+void gl_triangle_2d(S32 x1, S32 y1, S32 x2, S32 y2, S32 x3, S32 y3, const LLColor4& color, BOOL filled)
+{
+	gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+
+	gGL.color4fv(color.mV);
+
+	if (filled)
+	{
+		gGL.begin(LLRender::TRIANGLES);
+	}
+	else
+	{
+		gGL.begin(LLRender::LINE_LOOP);
+	}
+	gGL.vertex2i(x1, y1);
+	gGL.vertex2i(x2, y2);
+	gGL.vertex2i(x3, y3);
+	gGL.end();
+}
+
+void gl_corners_2d(S32 left, S32 top, S32 right, S32 bottom, S32 length, F32 max_frac)
+{
+	gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+
+	length = llmin((S32)(max_frac*(right - left)), length);
+	length = llmin((S32)(max_frac*(top - bottom)), length);
+	gGL.begin(LLRender::LINES);
+	gGL.vertex2i(left, top);
+	gGL.vertex2i(left + length, top);
+	
+	gGL.vertex2i(left, top);
+	gGL.vertex2i(left, top - length);
+
+	gGL.vertex2i(left, bottom);
+	gGL.vertex2i(left + length, bottom);
+	
+	gGL.vertex2i(left, bottom);
+	gGL.vertex2i(left, bottom + length);
+
+	gGL.vertex2i(right, top);
+	gGL.vertex2i(right - length, top);
+
+	gGL.vertex2i(right, top);
+	gGL.vertex2i(right, top - length);
+
+	gGL.vertex2i(right, bottom);
+	gGL.vertex2i(right - length, bottom);
+
+	gGL.vertex2i(right, bottom);
+	gGL.vertex2i(right, bottom + length);
+	gGL.end();
+}
+
+
+void gl_draw_image( S32 x, S32 y, LLTexture* image, const LLColor4& color, const LLRectf& uv_rect )
+{
+	if (NULL == image)
+	{
+		llwarns << "image == NULL; aborting function" << llendl;
+		return;
+	}
+	gl_draw_scaled_rotated_image( x, y, image->getWidth(0), image->getHeight(0), 0.f, image, color, uv_rect );
+}
+
+void gl_draw_scaled_image(S32 x, S32 y, S32 width, S32 height, LLTexture* image, const LLColor4& color, const LLRectf& uv_rect)
+{
+	if (NULL == image)
+	{
+		llwarns << "image == NULL; aborting function" << llendl;
+		return;
+	}
+	gl_draw_scaled_rotated_image( x, y, width, height, 0.f, image, color, uv_rect );
+}
+
+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, const LLRectf& uv_rect)
+{
+	if (NULL == image)
+	{
+		llwarns << "image == NULL; aborting function" << llendl;
+		return;
+	}
+
+	// scale screen size of borders down
+	F32 border_width_fraction = (F32)border_width / (F32)image->getWidth(0);
+	F32 border_height_fraction = (F32)border_height / (F32)image->getHeight(0);
+
+	LLRectf scale_rect(border_width_fraction, 1.f - border_height_fraction, 1.f - border_width_fraction, border_height_fraction);
+	gl_draw_scaled_image_with_border(x, y, width, height, image, color, solid_color, uv_rect, scale_rect);
+}
+
+void gl_draw_scaled_image_with_border(S32 x, S32 y, S32 width, S32 height, LLTexture* image, const LLColor4& color, BOOL solid_color, const LLRectf& uv_outer_rect, const LLRectf& center_rect)
+{
+	stop_glerror();
+
+	if (NULL == image)
+	{
+		llwarns << "image == NULL; aborting function" << llendl;
+		return;
+	}
+
+	// add in offset of current image to current UI translation
+	const LLVector3 ui_scale = gGL.getUIScale();
+	const LLVector3 ui_translation = (gGL.getUITranslation() + LLVector3(x, y, 0.f)).scaledVec(ui_scale);
+
+	F32 uv_width = uv_outer_rect.getWidth();
+	F32 uv_height = uv_outer_rect.getHeight();
+
+	// shrink scaling region to be proportional to clipped image region
+	LLRectf uv_center_rect(
+		uv_outer_rect.mLeft + (center_rect.mLeft * uv_width),
+		uv_outer_rect.mBottom + (center_rect.mTop * uv_height),
+		uv_outer_rect.mLeft + (center_rect.mRight * uv_width),
+		uv_outer_rect.mBottom + (center_rect.mBottom * uv_height));
+
+	F32 image_width = image->getWidth(0);
+	F32 image_height = image->getHeight(0);
+
+	S32 image_natural_width = llround(image_width * uv_width);
+	S32 image_natural_height = llround(image_height * uv_height);
+
+	LLRectf draw_center_rect(	uv_center_rect.mLeft * image_width,
+								uv_center_rect.mTop * image_height,
+								uv_center_rect.mRight * image_width,
+								uv_center_rect.mBottom * image_height);
+
+	{	// scale fixed region of image to drawn region
+		draw_center_rect.mRight += width - image_natural_width;
+		draw_center_rect.mTop += height - image_natural_height;
+
+		F32 border_shrink_width = llmax(0.f, draw_center_rect.mLeft - draw_center_rect.mRight);
+		F32 border_shrink_height = llmax(0.f, draw_center_rect.mBottom - draw_center_rect.mTop);
+
+		F32 shrink_width_ratio = center_rect.getWidth() == 1.f ? 0.f : border_shrink_width / ((F32)image_natural_width * (1.f - center_rect.getWidth()));
+		F32 shrink_height_ratio = center_rect.getHeight() == 1.f ? 0.f : border_shrink_height / ((F32)image_natural_height * (1.f - center_rect.getHeight()));
+
+		F32 shrink_scale = 1.f - llmax(shrink_width_ratio, shrink_height_ratio);
+
+		draw_center_rect.mLeft = llround(ui_translation.mV[VX] + (F32)draw_center_rect.mLeft * shrink_scale * ui_scale.mV[VX]);
+		draw_center_rect.mTop = llround(ui_translation.mV[VY] + lerp((F32)height, (F32)draw_center_rect.mTop, shrink_scale) * ui_scale.mV[VY]);
+		draw_center_rect.mRight = llround(ui_translation.mV[VX] + lerp((F32)width, (F32)draw_center_rect.mRight, shrink_scale) * ui_scale.mV[VX]);
+		draw_center_rect.mBottom = llround(ui_translation.mV[VY] + (F32)draw_center_rect.mBottom * shrink_scale * ui_scale.mV[VY]);
+	}
+
+	LLRectf draw_outer_rect(ui_translation.mV[VX], 
+							ui_translation.mV[VY] + height * ui_scale.mV[VY], 
+							ui_translation.mV[VX] + width * ui_scale.mV[VX], 
+							ui_translation.mV[VY]);
+
+	LLGLSUIDefault gls_ui;
+	
+	if (solid_color)
+	{
+		if (LLGLSLShader::sNoFixedFunction)
+		{
+			gSolidColorProgram.bind();
+		}
+		else
+		{
+			gGL.getTexUnit(0)->setTextureColorBlend(LLTexUnit::TBO_REPLACE, LLTexUnit::TBS_PREV_COLOR);
+			gGL.getTexUnit(0)->setTextureAlphaBlend(LLTexUnit::TBO_MULT, LLTexUnit::TBS_TEX_ALPHA, LLTexUnit::TBS_VERT_ALPHA);
+		}
+	}
+
+	gGL.getTexUnit(0)->bind(image, true);
+
+	gGL.color4fv(color.mV);
+	
+	const S32 NUM_VERTICES = 9 * 4; // 9 quads
+	LLVector2 uv[NUM_VERTICES];
+	LLVector3 pos[NUM_VERTICES];
+
+	S32 index = 0;
+
+	gGL.begin(LLRender::QUADS);
+	{
+		// draw bottom left
+		uv[index] = LLVector2(uv_outer_rect.mLeft, uv_outer_rect.mBottom);
+		pos[index] = LLVector3(draw_outer_rect.mLeft, draw_outer_rect.mBottom, 0.f);
+		index++;
+
+		uv[index] = LLVector2(uv_center_rect.mLeft, uv_outer_rect.mBottom);
+		pos[index] = LLVector3(draw_center_rect.mLeft, draw_outer_rect.mBottom, 0.f);
+		index++;
+
+		uv[index] = LLVector2(uv_center_rect.mLeft, uv_center_rect.mBottom);
+		pos[index] = LLVector3(draw_center_rect.mLeft, draw_center_rect.mBottom, 0.f);
+		index++;
+
+		uv[index] = LLVector2(uv_outer_rect.mLeft, uv_center_rect.mBottom);
+		pos[index] = LLVector3(draw_outer_rect.mLeft, draw_center_rect.mBottom, 0.f);
+		index++;
+
+		// draw bottom middle
+		uv[index] = LLVector2(uv_center_rect.mLeft, uv_outer_rect.mBottom);
+		pos[index] = LLVector3(draw_center_rect.mLeft, draw_outer_rect.mBottom, 0.f);
+		index++;
+
+		uv[index] = LLVector2(uv_center_rect.mRight, uv_outer_rect.mBottom);
+		pos[index] = LLVector3(draw_center_rect.mRight, draw_outer_rect.mBottom, 0.f);
+		index++;
+
+		uv[index] = LLVector2(uv_center_rect.mRight, uv_center_rect.mBottom);
+		pos[index] = LLVector3(draw_center_rect.mRight, draw_center_rect.mBottom, 0.f);
+		index++;
+
+		uv[index] = LLVector2(uv_center_rect.mLeft, uv_center_rect.mBottom);
+		pos[index] = LLVector3(draw_center_rect.mLeft, draw_center_rect.mBottom, 0.f);
+		index++;
+
+		// draw bottom right
+		uv[index] = LLVector2(uv_center_rect.mRight, uv_outer_rect.mBottom);
+		pos[index] = LLVector3(draw_center_rect.mRight, draw_outer_rect.mBottom, 0.f);
+		index++;
+
+		uv[index] = LLVector2(uv_outer_rect.mRight, uv_outer_rect.mBottom);
+		pos[index] = LLVector3(draw_outer_rect.mRight, draw_outer_rect.mBottom, 0.f);
+		index++;
+
+		uv[index] = LLVector2(uv_outer_rect.mRight, uv_center_rect.mBottom);
+		pos[index] = LLVector3(draw_outer_rect.mRight, draw_center_rect.mBottom, 0.f);
+		index++;
+
+		uv[index] = LLVector2(uv_center_rect.mRight, uv_center_rect.mBottom);
+		pos[index] = LLVector3(draw_center_rect.mRight, draw_center_rect.mBottom, 0.f);
+		index++;
+
+		// draw left 
+		uv[index] = LLVector2(uv_outer_rect.mLeft, uv_center_rect.mBottom);
+		pos[index] = LLVector3(draw_outer_rect.mLeft, draw_center_rect.mBottom, 0.f);
+		index++;
+
+		uv[index] = LLVector2(uv_center_rect.mLeft, uv_center_rect.mBottom);
+		pos[index] = LLVector3(draw_center_rect.mLeft, draw_center_rect.mBottom, 0.f);
+		index++;
+
+		uv[index] = LLVector2(uv_center_rect.mLeft, uv_center_rect.mTop);
+		pos[index] = LLVector3(draw_center_rect.mLeft, draw_center_rect.mTop, 0.f);
+		index++;
+
+		uv[index] = LLVector2(uv_outer_rect.mLeft, uv_center_rect.mTop);
+		pos[index] = LLVector3(draw_outer_rect.mLeft, draw_center_rect.mTop, 0.f);
+		index++;
+
+		// draw middle
+		uv[index] = LLVector2(uv_center_rect.mLeft, uv_center_rect.mBottom);
+		pos[index] = LLVector3(draw_center_rect.mLeft, draw_center_rect.mBottom, 0.f);
+		index++;
+
+		uv[index] = LLVector2(uv_center_rect.mRight, uv_center_rect.mBottom);
+		pos[index] = LLVector3(draw_center_rect.mRight, draw_center_rect.mBottom, 0.f);
+		index++;
+
+		uv[index] = LLVector2(uv_center_rect.mRight, uv_center_rect.mTop);
+		pos[index] = LLVector3(draw_center_rect.mRight, draw_center_rect.mTop, 0.f);
+		index++;
+
+		uv[index] = LLVector2(uv_center_rect.mLeft, uv_center_rect.mTop);
+		pos[index] = LLVector3(draw_center_rect.mLeft, draw_center_rect.mTop, 0.f);
+		index++;
+
+		// draw right 
+		uv[index] = LLVector2(uv_center_rect.mRight, uv_center_rect.mBottom);
+		pos[index] = LLVector3(draw_center_rect.mRight, draw_center_rect.mBottom, 0.f);
+		index++;
+
+		uv[index] = LLVector2(uv_outer_rect.mRight, uv_center_rect.mBottom);
+		pos[index] = LLVector3(draw_outer_rect.mRight, draw_center_rect.mBottom, 0.f);
+		index++;
+
+		uv[index] = LLVector2(uv_outer_rect.mRight, uv_center_rect.mTop);
+		pos[index] = LLVector3(draw_outer_rect.mRight, draw_center_rect.mTop, 0.f);
+		index++;
+
+		uv[index] = LLVector2(uv_center_rect.mRight, uv_center_rect.mTop);
+		pos[index] = LLVector3(draw_center_rect.mRight, draw_center_rect.mTop, 0.f);
+		index++;
+
+		// draw top left
+		uv[index] = LLVector2(uv_outer_rect.mLeft, uv_center_rect.mTop);
+		pos[index] = LLVector3(draw_outer_rect.mLeft, draw_center_rect.mTop, 0.f);
+		index++;
+
+		uv[index] = LLVector2(uv_center_rect.mLeft, uv_center_rect.mTop);
+		pos[index] = LLVector3(draw_center_rect.mLeft, draw_center_rect.mTop, 0.f);
+		index++;
+
+		uv[index] = LLVector2(uv_center_rect.mLeft, uv_outer_rect.mTop);
+		pos[index] = LLVector3(draw_center_rect.mLeft, draw_outer_rect.mTop, 0.f);
+		index++;
+
+		uv[index] = LLVector2(uv_outer_rect.mLeft, uv_outer_rect.mTop);
+		pos[index] = LLVector3(draw_outer_rect.mLeft, draw_outer_rect.mTop, 0.f);
+		index++;
+
+		// draw top middle
+		uv[index] = LLVector2(uv_center_rect.mLeft, uv_center_rect.mTop);
+		pos[index] = LLVector3(draw_center_rect.mLeft, draw_center_rect.mTop, 0.f);
+		index++;
+
+		uv[index] = LLVector2(uv_center_rect.mRight, uv_center_rect.mTop);
+		pos[index] = LLVector3(draw_center_rect.mRight, draw_center_rect.mTop, 0.f);
+		index++;
+
+		uv[index] = LLVector2(uv_center_rect.mRight, uv_outer_rect.mTop);
+		pos[index] = LLVector3(draw_center_rect.mRight, draw_outer_rect.mTop, 0.f);
+		index++;
+
+		uv[index] = LLVector2(uv_center_rect.mLeft, uv_outer_rect.mTop);
+		pos[index] = LLVector3(draw_center_rect.mLeft, draw_outer_rect.mTop, 0.f);
+		index++;
+
+		// draw top right
+		uv[index] = LLVector2(uv_center_rect.mRight, uv_center_rect.mTop);
+		pos[index] = LLVector3(draw_center_rect.mRight, draw_center_rect.mTop, 0.f);
+		index++;
+
+		uv[index] = LLVector2(uv_outer_rect.mRight, uv_center_rect.mTop);
+		pos[index] = LLVector3(draw_outer_rect.mRight, draw_center_rect.mTop, 0.f);
+		index++;
+
+		uv[index] = LLVector2(uv_outer_rect.mRight, uv_outer_rect.mTop);
+		pos[index] = LLVector3(draw_outer_rect.mRight, draw_outer_rect.mTop, 0.f);
+		index++;
+
+		uv[index] = LLVector2(uv_center_rect.mRight, uv_outer_rect.mTop);
+		pos[index] = LLVector3(draw_center_rect.mRight, draw_outer_rect.mTop, 0.f);
+		index++;
+
+		gGL.vertexBatchPreTransformed(pos, uv, NUM_VERTICES);
+	}
+	gGL.end();
+
+	if (solid_color)
+	{
+		if (LLGLSLShader::sNoFixedFunction)
+		{
+			gUIProgram.bind();
+		}
+		else
+		{
+			gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT);
+		}
+	}
+}
+
+void gl_draw_rotated_image(S32 x, S32 y, F32 degrees, LLTexture* image, const LLColor4& color, const LLRectf& uv_rect)
+{
+	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)
+{
+	if (NULL == image)
+	{
+		llwarns << "image == NULL; aborting function" << llendl;
+		return;
+	}
+
+	LLGLSUIDefault gls_ui;
+
+
+	gGL.getTexUnit(0)->bind(image, true);
+
+	gGL.color4fv(color.mV);
+
+	if (degrees == 0.f)
+	{
+		const S32 NUM_VERTICES = 4; // 9 quads
+		LLVector2 uv[NUM_VERTICES];
+		LLVector3 pos[NUM_VERTICES];
+
+		gGL.begin(LLRender::QUADS);
+		{
+			LLVector3 ui_scale = gGL.getUIScale();
+			LLVector3 ui_translation = gGL.getUITranslation();
+			ui_translation.mV[VX] += x;
+			ui_translation.mV[VY] += y;
+			ui_translation.scaleVec(ui_scale);
+			S32 index = 0;
+			S32 scaled_width = llround(width * ui_scale.mV[VX]);
+			S32 scaled_height = llround(height * ui_scale.mV[VY]);
+
+			uv[index] = LLVector2(uv_rect.mRight, uv_rect.mTop);
+			pos[index] = LLVector3(ui_translation.mV[VX] + scaled_width, ui_translation.mV[VY] + scaled_height, 0.f);
+			index++;
+
+			uv[index] = LLVector2(uv_rect.mLeft, uv_rect.mTop);
+			pos[index] = LLVector3(ui_translation.mV[VX], ui_translation.mV[VY] + scaled_height, 0.f);
+			index++;
+
+			uv[index] = LLVector2(uv_rect.mLeft, uv_rect.mBottom);
+			pos[index] = LLVector3(ui_translation.mV[VX], ui_translation.mV[VY], 0.f);
+			index++;
+
+			uv[index] = LLVector2(uv_rect.mRight, uv_rect.mBottom);
+			pos[index] = LLVector3(ui_translation.mV[VX] + scaled_width, ui_translation.mV[VY], 0.f);
+			index++;
+
+			gGL.vertexBatchPreTransformed(pos, uv, NUM_VERTICES);
+		}
+		gGL.end();
+	}
+	else
+	{
+		gGL.pushUIMatrix();
+		gGL.translateUI((F32)x, (F32)y, 0.f);
+	
+		F32 offset_x = F32(width/2);
+		F32 offset_y = F32(height/2);
+
+		gGL.translateUI(offset_x, offset_y, 0.f);
+
+		LLMatrix3 quat(0.f, 0.f, degrees*DEG_TO_RAD);
+		
+		gGL.getTexUnit(0)->bind(image, true);
+
+		gGL.color4fv(color.mV);
+		
+		gGL.begin(LLRender::QUADS);
+		{
+			LLVector3 v;
+
+			v = LLVector3(offset_x, offset_y, 0.f) * quat;
+			gGL.texCoord2f(uv_rect.mRight, uv_rect.mTop);
+			gGL.vertex2f(v.mV[0], v.mV[1] );
+
+			v = LLVector3(-offset_x, offset_y, 0.f) * quat;
+			gGL.texCoord2f(uv_rect.mLeft, uv_rect.mTop);
+			gGL.vertex2f(v.mV[0], v.mV[1] );
+
+			v = LLVector3(-offset_x, -offset_y, 0.f) * quat;
+			gGL.texCoord2f(uv_rect.mLeft, uv_rect.mBottom);
+			gGL.vertex2f(v.mV[0], v.mV[1] );
+
+			v = LLVector3(offset_x, -offset_y, 0.f) * quat;
+			gGL.texCoord2f(uv_rect.mRight, uv_rect.mBottom);
+			gGL.vertex2f(v.mV[0], v.mV[1] );
+		}
+		gGL.end();
+		gGL.popUIMatrix();
+	}
+}
+
+
+void gl_stippled_line_3d( const LLVector3& start, const LLVector3& end, const LLColor4& color, F32 phase )
+{
+	phase = fmod(phase, 1.f);
+
+	S32 shift = S32(phase * 4.f) % 4;
+
+	// Stippled line
+	LLGLEnable stipple(GL_LINE_STIPPLE);
+	
+	gGL.color4f(color.mV[VRED], color.mV[VGREEN], color.mV[VBLUE], color.mV[VALPHA]);
+
+	gGL.flush();
+	glLineWidth(2.5f);
+
+	if (!LLGLSLShader::sNoFixedFunction)
+	{
+		glLineStipple(2, 0x3333 << shift);
+	}
+
+	gGL.begin(LLRender::LINES);
+	{
+		gGL.vertex3fv( start.mV );
+		gGL.vertex3fv( end.mV );
+	}
+	gGL.end();
+
+	LLRender2D::setLineWidth(1.f);
+}
+
+void gl_arc_2d(F32 center_x, F32 center_y, F32 radius, S32 steps, BOOL filled, F32 start_angle, F32 end_angle)
+{
+	if (end_angle < start_angle)
+	{
+		end_angle += F_TWO_PI;
+	}
+
+	gGL.pushUIMatrix();
+	{
+		gGL.translateUI(center_x, center_y, 0.f);
+
+		// Inexact, but reasonably fast.
+		F32 delta = (end_angle - start_angle) / steps;
+		F32 sin_delta = sin( delta );
+		F32 cos_delta = cos( delta );
+		F32 x = cosf(start_angle) * radius;
+		F32 y = sinf(start_angle) * radius;
+
+		if (filled)
+		{
+			gGL.begin(LLRender::TRIANGLE_FAN);
+			gGL.vertex2f(0.f, 0.f);
+			// make sure circle is complete
+			steps += 1;
+		}
+		else
+		{
+			gGL.begin(LLRender::LINE_STRIP);
+		}
+
+		while( steps-- )
+		{
+			// Successive rotations
+			gGL.vertex2f( x, y );
+			F32 x_new = x * cos_delta - y * sin_delta;
+			y = x * sin_delta +  y * cos_delta;
+			x = x_new;
+		}
+		gGL.end();
+	}
+	gGL.popUIMatrix();
+}
+
+void gl_circle_2d(F32 center_x, F32 center_y, F32 radius, S32 steps, BOOL filled)
+{
+	gGL.pushUIMatrix();
+	{
+		gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+		gGL.translateUI(center_x, center_y, 0.f);
+
+		// Inexact, but reasonably fast.
+		F32 delta = F_TWO_PI / steps;
+		F32 sin_delta = sin( delta );
+		F32 cos_delta = cos( delta );
+		F32 x = radius;
+		F32 y = 0.f;
+
+		if (filled)
+		{
+			gGL.begin(LLRender::TRIANGLE_FAN);
+			gGL.vertex2f(0.f, 0.f);
+			// make sure circle is complete
+			steps += 1;
+		}
+		else
+		{
+			gGL.begin(LLRender::LINE_LOOP);
+		}
+
+		while( steps-- )
+		{
+			// Successive rotations
+			gGL.vertex2f( x, y );
+			F32 x_new = x * cos_delta - y * sin_delta;
+			y = x * sin_delta +  y * cos_delta;
+			x = x_new;
+		}
+		gGL.end();
+	}
+	gGL.popUIMatrix();
+}
+
+// Renders a ring with sides (tube shape)
+void gl_deep_circle( F32 radius, F32 depth, S32 steps )
+{
+	F32 x = radius;
+	F32 y = 0.f;
+	F32 angle_delta = F_TWO_PI / (F32)steps;
+	gGL.begin( LLRender::TRIANGLE_STRIP  );
+	{
+		S32 step = steps + 1; // An extra step to close the circle.
+		while( step-- )
+		{
+			gGL.vertex3f( x, y, depth );
+			gGL.vertex3f( x, y, 0.f );
+
+			F32 x_new = x * cosf(angle_delta) - y * sinf(angle_delta);
+			y = x * sinf(angle_delta) +  y * cosf(angle_delta);
+			x = x_new;
+		}
+	}
+	gGL.end();
+}
+
+void gl_ring( F32 radius, F32 width, const LLColor4& center_color, const LLColor4& side_color, S32 steps, BOOL render_center )
+{
+	gGL.pushUIMatrix();
+	{
+		gGL.translateUI(0.f, 0.f, -width / 2);
+		if( render_center )
+		{
+			gGL.color4fv(center_color.mV);
+			gGL.diffuseColor4fv(center_color.mV);
+			gl_deep_circle( radius, width, steps );
+		}
+		else
+		{
+			gGL.diffuseColor4fv(side_color.mV);
+			gl_washer_2d(radius, radius - width, steps, side_color, side_color);
+			gGL.translateUI(0.f, 0.f, width);
+			gl_washer_2d(radius - width, radius, steps, side_color, side_color);
+		}
+	}
+	gGL.popUIMatrix();
+}
+
+// Draw gray and white checkerboard with black border
+void gl_rect_2d_checkerboard(const LLRect& rect, GLfloat alpha)
+{
+	if (!LLGLSLShader::sNoFixedFunction)
+	{ 
+		// Initialize the first time this is called.
+		const S32 PIXELS = 32;
+		static GLubyte checkerboard[PIXELS * PIXELS];
+		static BOOL first = TRUE;
+		if( first )
+		{
+			for( S32 i = 0; i < PIXELS; i++ )
+			{
+				for( S32 j = 0; j < PIXELS; j++ )
+				{
+					checkerboard[i * PIXELS + j] = ((i & 1) ^ (j & 1)) * 0xFF;
+				}
+			}
+			first = FALSE;
+		}
+	
+		gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+
+		// ...white squares
+		gGL.color4f( 1.f, 1.f, 1.f, alpha );
+		gl_rect_2d(rect);
+
+		// ...gray squares
+		gGL.color4f( .7f, .7f, .7f, alpha );
+		gGL.flush();
+
+		glPolygonStipple( checkerboard );
+
+		LLGLEnable polygon_stipple(GL_POLYGON_STIPPLE);
+		gl_rect_2d(rect);
+	}
+	else
+	{ //polygon stipple is deprecated, use "Checker" texture
+		LLPointer<LLUIImage> img = LLRender2D::getUIImage("Checker");
+		gGL.getTexUnit(0)->bind(img->getImage());
+		gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_WRAP);
+		gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_POINT);
+
+		LLColor4 color(1.f, 1.f, 1.f, alpha);
+		LLRectf uv_rect(0, 0, rect.getWidth()/32.f, rect.getHeight()/32.f);
+
+		gl_draw_scaled_image(rect.mLeft, rect.mBottom, rect.getWidth(), rect.getHeight(),
+			img->getImage(), color, uv_rect);
+	}
+	
+	gGL.flush();
+}
+
+
+// Draws the area between two concentric circles, like
+// a doughnut or washer.
+void gl_washer_2d(F32 outer_radius, F32 inner_radius, S32 steps, const LLColor4& inner_color, const LLColor4& outer_color)
+{
+	const F32 DELTA = F_TWO_PI / steps;
+	const F32 SIN_DELTA = sin( DELTA );
+	const F32 COS_DELTA = cos( DELTA );
+
+	F32 x1 = outer_radius;
+	F32 y1 = 0.f;
+	F32 x2 = inner_radius;
+	F32 y2 = 0.f;
+
+	gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+
+	gGL.begin( LLRender::TRIANGLE_STRIP  );
+	{
+		steps += 1; // An extra step to close the circle.
+		while( steps-- )
+		{
+			gGL.color4fv(outer_color.mV);
+			gGL.vertex2f( x1, y1 );
+			gGL.color4fv(inner_color.mV);
+			gGL.vertex2f( x2, y2 );
+
+			F32 x1_new = x1 * COS_DELTA - y1 * SIN_DELTA;
+			y1 = x1 * SIN_DELTA +  y1 * COS_DELTA;
+			x1 = x1_new;
+
+			F32 x2_new = x2 * COS_DELTA - y2 * SIN_DELTA;
+			y2 = x2 * SIN_DELTA +  y2 * COS_DELTA;
+			x2 = x2_new;
+		}
+	}
+	gGL.end();
+}
+
+// Draws the area between two concentric circles, like
+// a doughnut or washer.
+void gl_washer_segment_2d(F32 outer_radius, F32 inner_radius, F32 start_radians, F32 end_radians, S32 steps, const LLColor4& inner_color, const LLColor4& outer_color)
+{
+	const F32 DELTA = (end_radians - start_radians) / steps;
+	const F32 SIN_DELTA = sin( DELTA );
+	const F32 COS_DELTA = cos( DELTA );
+
+	F32 x1 = outer_radius * cos( start_radians );
+	F32 y1 = outer_radius * sin( start_radians );
+	F32 x2 = inner_radius * cos( start_radians );
+	F32 y2 = inner_radius * sin( start_radians );
+
+	gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+	gGL.begin( LLRender::TRIANGLE_STRIP  );
+	{
+		steps += 1; // An extra step to close the circle.
+		while( steps-- )
+		{
+			gGL.color4fv(outer_color.mV);
+			gGL.vertex2f( x1, y1 );
+			gGL.color4fv(inner_color.mV);
+			gGL.vertex2f( x2, y2 );
+
+			F32 x1_new = x1 * COS_DELTA - y1 * SIN_DELTA;
+			y1 = x1 * SIN_DELTA +  y1 * COS_DELTA;
+			x1 = x1_new;
+
+			F32 x2_new = x2 * COS_DELTA - y2 * SIN_DELTA;
+			y2 = x2 * SIN_DELTA +  y2 * COS_DELTA;
+			x2 = x2_new;
+		}
+	}
+	gGL.end();
+}
+
+void gl_rect_2d_simple_tex( S32 width, S32 height )
+{
+	gGL.begin( LLRender::QUADS );
+
+		gGL.texCoord2f(1.f, 1.f);
+		gGL.vertex2i(width, height);
+
+		gGL.texCoord2f(0.f, 1.f);
+		gGL.vertex2i(0, height);
+
+		gGL.texCoord2f(0.f, 0.f);
+		gGL.vertex2i(0, 0);
+
+		gGL.texCoord2f(1.f, 0.f);
+		gGL.vertex2i(width, 0);
+	
+	gGL.end();
+}
+
+void gl_rect_2d_simple( S32 width, S32 height )
+{
+	gGL.begin( LLRender::QUADS );
+		gGL.vertex2i(width, height);
+		gGL.vertex2i(0, height);
+		gGL.vertex2i(0, 0);
+		gGL.vertex2i(width, 0);
+	gGL.end();
+}
+
+void gl_segmented_rect_2d_tex(const S32 left, 
+							  const S32 top, 
+							  const S32 right, 
+							  const S32 bottom, 
+							  const S32 texture_width, 
+							  const S32 texture_height, 
+							  const S32 border_size, 
+							  const U32 edges)
+{
+	S32 width = llabs(right - left);
+	S32 height = llabs(top - bottom);
+
+	gGL.pushUIMatrix();
+
+	gGL.translateUI((F32)left, (F32)bottom, 0.f);
+	LLVector2 border_uv_scale((F32)border_size / (F32)texture_width, (F32)border_size / (F32)texture_height);
+
+	if (border_uv_scale.mV[VX] > 0.5f)
+	{
+		border_uv_scale *= 0.5f / border_uv_scale.mV[VX];
+	}
+	if (border_uv_scale.mV[VY] > 0.5f)
+	{
+		border_uv_scale *= 0.5f / border_uv_scale.mV[VY];
+	}
+
+	F32 border_scale = llmin((F32)border_size, (F32)width * 0.5f, (F32)height * 0.5f);
+	LLVector2 border_width_left = ((edges & (~(U32)ROUNDED_RECT_RIGHT)) != 0) ? LLVector2(border_scale, 0.f) : LLVector2::zero;
+	LLVector2 border_width_right = ((edges & (~(U32)ROUNDED_RECT_LEFT)) != 0) ? LLVector2(border_scale, 0.f) : LLVector2::zero;
+	LLVector2 border_height_bottom = ((edges & (~(U32)ROUNDED_RECT_TOP)) != 0) ? LLVector2(0.f, border_scale) : LLVector2::zero;
+	LLVector2 border_height_top = ((edges & (~(U32)ROUNDED_RECT_BOTTOM)) != 0) ? LLVector2(0.f, border_scale) : LLVector2::zero;
+	LLVector2 width_vec((F32)width, 0.f);
+	LLVector2 height_vec(0.f, (F32)height);
+
+	gGL.begin(LLRender::QUADS);
+	{
+		// draw bottom left
+		gGL.texCoord2f(0.f, 0.f);
+		gGL.vertex2f(0.f, 0.f);
+
+		gGL.texCoord2f(border_uv_scale.mV[VX], 0.f);
+		gGL.vertex2fv(border_width_left.mV);
+
+		gGL.texCoord2f(border_uv_scale.mV[VX], border_uv_scale.mV[VY]);
+		gGL.vertex2fv((border_width_left + border_height_bottom).mV);
+
+		gGL.texCoord2f(0.f, border_uv_scale.mV[VY]);
+		gGL.vertex2fv(border_height_bottom.mV);
+
+		// draw bottom middle
+		gGL.texCoord2f(border_uv_scale.mV[VX], 0.f);
+		gGL.vertex2fv(border_width_left.mV);
+
+		gGL.texCoord2f(1.f - border_uv_scale.mV[VX], 0.f);
+		gGL.vertex2fv((width_vec - border_width_right).mV);
+
+		gGL.texCoord2f(1.f - border_uv_scale.mV[VX], border_uv_scale.mV[VY]);
+		gGL.vertex2fv((width_vec - border_width_right + border_height_bottom).mV);
+
+		gGL.texCoord2f(border_uv_scale.mV[VX], border_uv_scale.mV[VY]);
+		gGL.vertex2fv((border_width_left + border_height_bottom).mV);
+
+		// draw bottom right
+		gGL.texCoord2f(1.f - border_uv_scale.mV[VX], 0.f);
+		gGL.vertex2fv((width_vec - border_width_right).mV);
+
+		gGL.texCoord2f(1.f, 0.f);
+		gGL.vertex2fv(width_vec.mV);
+
+		gGL.texCoord2f(1.f, border_uv_scale.mV[VY]);
+		gGL.vertex2fv((width_vec + border_height_bottom).mV);
+
+		gGL.texCoord2f(1.f - border_uv_scale.mV[VX], border_uv_scale.mV[VY]);
+		gGL.vertex2fv((width_vec - border_width_right + border_height_bottom).mV);
+
+		// draw left 
+		gGL.texCoord2f(0.f, border_uv_scale.mV[VY]);
+		gGL.vertex2fv(border_height_bottom.mV);
+
+		gGL.texCoord2f(border_uv_scale.mV[VX], border_uv_scale.mV[VY]);
+		gGL.vertex2fv((border_width_left + border_height_bottom).mV);
+
+		gGL.texCoord2f(border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]);
+		gGL.vertex2fv((border_width_left + height_vec - border_height_top).mV);
+
+		gGL.texCoord2f(0.f, 1.f - border_uv_scale.mV[VY]);
+		gGL.vertex2fv((height_vec - border_height_top).mV);
+
+		// draw middle
+		gGL.texCoord2f(border_uv_scale.mV[VX], border_uv_scale.mV[VY]);
+		gGL.vertex2fv((border_width_left + border_height_bottom).mV);
+
+		gGL.texCoord2f(1.f - border_uv_scale.mV[VX], border_uv_scale.mV[VY]);
+		gGL.vertex2fv((width_vec - border_width_right + border_height_bottom).mV);
+
+		gGL.texCoord2f(1.f - border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]);
+		gGL.vertex2fv((width_vec - border_width_right + height_vec - border_height_top).mV);
+
+		gGL.texCoord2f(border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]);
+		gGL.vertex2fv((border_width_left + height_vec - border_height_top).mV);
+
+		// draw right 
+		gGL.texCoord2f(1.f - border_uv_scale.mV[VX], border_uv_scale.mV[VY]);
+		gGL.vertex2fv((width_vec - border_width_right + border_height_bottom).mV);
+
+		gGL.texCoord2f(1.f, border_uv_scale.mV[VY]);
+		gGL.vertex2fv((width_vec + border_height_bottom).mV);
+
+		gGL.texCoord2f(1.f, 1.f - border_uv_scale.mV[VY]);
+		gGL.vertex2fv((width_vec + height_vec - border_height_top).mV);
+
+		gGL.texCoord2f(1.f - border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]);
+		gGL.vertex2fv((width_vec - border_width_right + height_vec - border_height_top).mV);
+
+		// draw top left
+		gGL.texCoord2f(0.f, 1.f - border_uv_scale.mV[VY]);
+		gGL.vertex2fv((height_vec - border_height_top).mV);
+
+		gGL.texCoord2f(border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]);
+		gGL.vertex2fv((border_width_left + height_vec - border_height_top).mV);
+
+		gGL.texCoord2f(border_uv_scale.mV[VX], 1.f);
+		gGL.vertex2fv((border_width_left + height_vec).mV);
+
+		gGL.texCoord2f(0.f, 1.f);
+		gGL.vertex2fv((height_vec).mV);
+
+		// draw top middle
+		gGL.texCoord2f(border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]);
+		gGL.vertex2fv((border_width_left + height_vec - border_height_top).mV);
+
+		gGL.texCoord2f(1.f - border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]);
+		gGL.vertex2fv((width_vec - border_width_right + height_vec - border_height_top).mV);
+
+		gGL.texCoord2f(1.f - border_uv_scale.mV[VX], 1.f);
+		gGL.vertex2fv((width_vec - border_width_right + height_vec).mV);
+
+		gGL.texCoord2f(border_uv_scale.mV[VX], 1.f);
+		gGL.vertex2fv((border_width_left + height_vec).mV);
+
+		// draw top right
+		gGL.texCoord2f(1.f - border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]);
+		gGL.vertex2fv((width_vec - border_width_right + height_vec - border_height_top).mV);
+
+		gGL.texCoord2f(1.f, 1.f - border_uv_scale.mV[VY]);
+		gGL.vertex2fv((width_vec + height_vec - border_height_top).mV);
+
+		gGL.texCoord2f(1.f, 1.f);
+		gGL.vertex2fv((width_vec + height_vec).mV);
+
+		gGL.texCoord2f(1.f - border_uv_scale.mV[VX], 1.f);
+		gGL.vertex2fv((width_vec - border_width_right + height_vec).mV);
+	}
+	gGL.end();
+
+	gGL.popUIMatrix();
+}
+
+//FIXME: rewrite to use scissor?
+void gl_segmented_rect_2d_fragment_tex(const S32 left, 
+									   const S32 top, 
+									   const S32 right, 
+									   const S32 bottom, 
+									   const S32 texture_width, 
+									   const S32 texture_height, 
+									   const S32 border_size, 
+									   const F32 start_fragment, 
+									   const F32 end_fragment, 
+									   const U32 edges)
+{
+	S32 width = llabs(right - left);
+	S32 height = llabs(top - bottom);
+
+	gGL.pushUIMatrix();
+
+	gGL.translateUI((F32)left, (F32)bottom, 0.f);
+	LLVector2 border_uv_scale((F32)border_size / (F32)texture_width, (F32)border_size / (F32)texture_height);
+
+	if (border_uv_scale.mV[VX] > 0.5f)
+	{
+		border_uv_scale *= 0.5f / border_uv_scale.mV[VX];
+	}
+	if (border_uv_scale.mV[VY] > 0.5f)
+	{
+		border_uv_scale *= 0.5f / border_uv_scale.mV[VY];
+	}
+
+	F32 border_scale = llmin((F32)border_size, (F32)width * 0.5f, (F32)height * 0.5f);
+	LLVector2 border_width_left = ((edges & (~(U32)ROUNDED_RECT_RIGHT)) != 0) ? LLVector2(border_scale, 0.f) : LLVector2::zero;
+	LLVector2 border_width_right = ((edges & (~(U32)ROUNDED_RECT_LEFT)) != 0) ? LLVector2(border_scale, 0.f) : LLVector2::zero;
+	LLVector2 border_height_bottom = ((edges & (~(U32)ROUNDED_RECT_TOP)) != 0) ? LLVector2(0.f, border_scale) : LLVector2::zero;
+	LLVector2 border_height_top = ((edges & (~(U32)ROUNDED_RECT_BOTTOM)) != 0) ? LLVector2(0.f, border_scale) : LLVector2::zero;
+	LLVector2 width_vec((F32)width, 0.f);
+	LLVector2 height_vec(0.f, (F32)height);
+
+	F32 middle_start = border_scale / (F32)width;
+	F32 middle_end = 1.f - middle_start;
+
+	F32 u_min;
+	F32 u_max;
+	LLVector2 x_min;
+	LLVector2 x_max;
+
+	gGL.begin(LLRender::QUADS);
+	{
+		if (start_fragment < middle_start)
+		{
+			u_min = (start_fragment / middle_start) * border_uv_scale.mV[VX];
+			u_max = llmin(end_fragment / middle_start, 1.f) * border_uv_scale.mV[VX];
+			x_min = (start_fragment / middle_start) * border_width_left;
+			x_max = llmin(end_fragment / middle_start, 1.f) * border_width_left;
+
+			// draw bottom left
+			gGL.texCoord2f(u_min, 0.f);
+			gGL.vertex2fv(x_min.mV);
+
+			gGL.texCoord2f(border_uv_scale.mV[VX], 0.f);
+			gGL.vertex2fv(x_max.mV);
+
+			gGL.texCoord2f(u_max, border_uv_scale.mV[VY]);
+			gGL.vertex2fv((x_max + border_height_bottom).mV);
+
+			gGL.texCoord2f(u_min, border_uv_scale.mV[VY]);
+			gGL.vertex2fv((x_min + border_height_bottom).mV);
+
+			// draw left 
+			gGL.texCoord2f(u_min, border_uv_scale.mV[VY]);
+			gGL.vertex2fv((x_min + border_height_bottom).mV);
+
+			gGL.texCoord2f(u_max, border_uv_scale.mV[VY]);
+			gGL.vertex2fv((x_max + border_height_bottom).mV);
+
+			gGL.texCoord2f(u_max, 1.f - border_uv_scale.mV[VY]);
+			gGL.vertex2fv((x_max + height_vec - border_height_top).mV);
+
+			gGL.texCoord2f(u_min, 1.f - border_uv_scale.mV[VY]);
+			gGL.vertex2fv((x_min + height_vec - border_height_top).mV);
+			
+			// draw top left
+			gGL.texCoord2f(u_min, 1.f - border_uv_scale.mV[VY]);
+			gGL.vertex2fv((x_min + height_vec - border_height_top).mV);
+
+			gGL.texCoord2f(u_max, 1.f - border_uv_scale.mV[VY]);
+			gGL.vertex2fv((x_max + height_vec - border_height_top).mV);
+
+			gGL.texCoord2f(u_max, 1.f);
+			gGL.vertex2fv((x_max + height_vec).mV);
+
+			gGL.texCoord2f(u_min, 1.f);
+			gGL.vertex2fv((x_min + height_vec).mV);
+		}
+
+		if (end_fragment > middle_start || start_fragment < middle_end)
+		{
+			x_min = border_width_left + ((llclamp(start_fragment, middle_start, middle_end) - middle_start)) * width_vec;
+			x_max = border_width_left + ((llclamp(end_fragment, middle_start, middle_end) - middle_start)) * width_vec;
+
+			// draw bottom middle
+			gGL.texCoord2f(border_uv_scale.mV[VX], 0.f);
+			gGL.vertex2fv(x_min.mV);
+
+			gGL.texCoord2f(1.f - border_uv_scale.mV[VX], 0.f);
+			gGL.vertex2fv((x_max).mV);
+
+			gGL.texCoord2f(1.f - border_uv_scale.mV[VX], border_uv_scale.mV[VY]);
+			gGL.vertex2fv((x_max + border_height_bottom).mV);
+
+			gGL.texCoord2f(border_uv_scale.mV[VX], border_uv_scale.mV[VY]);
+			gGL.vertex2fv((x_min + border_height_bottom).mV);
+
+			// draw middle
+			gGL.texCoord2f(border_uv_scale.mV[VX], border_uv_scale.mV[VY]);
+			gGL.vertex2fv((x_min + border_height_bottom).mV);
+
+			gGL.texCoord2f(1.f - border_uv_scale.mV[VX], border_uv_scale.mV[VY]);
+			gGL.vertex2fv((x_max + border_height_bottom).mV);
+
+			gGL.texCoord2f(1.f - border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]);
+			gGL.vertex2fv((x_max + height_vec - border_height_top).mV);
+
+			gGL.texCoord2f(border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]);
+			gGL.vertex2fv((x_min + height_vec - border_height_top).mV);
+
+			// draw top middle
+			gGL.texCoord2f(border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]);
+			gGL.vertex2fv((x_min + height_vec - border_height_top).mV);
+
+			gGL.texCoord2f(1.f - border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]);
+			gGL.vertex2fv((x_max + height_vec - border_height_top).mV);
+
+			gGL.texCoord2f(1.f - border_uv_scale.mV[VX], 1.f);
+			gGL.vertex2fv((x_max + height_vec).mV);
+
+			gGL.texCoord2f(border_uv_scale.mV[VX], 1.f);
+			gGL.vertex2fv((x_min + height_vec).mV);
+		}
+
+		if (end_fragment > middle_end)
+		{
+			u_min = (1.f - llmax(0.f, ((start_fragment - middle_end) / middle_start))) * border_uv_scale.mV[VX];
+			u_max = (1.f - ((end_fragment - middle_end) / middle_start)) * border_uv_scale.mV[VX];
+			x_min = width_vec - ((1.f - llmax(0.f, ((start_fragment - middle_end) / middle_start))) * border_width_right);
+			x_max = width_vec - ((1.f - ((end_fragment - middle_end) / middle_start)) * border_width_right);
+
+			// draw bottom right
+			gGL.texCoord2f(u_min, 0.f);
+			gGL.vertex2fv((x_min).mV);
+
+			gGL.texCoord2f(u_max, 0.f);
+			gGL.vertex2fv(x_max.mV);
+
+			gGL.texCoord2f(u_max, border_uv_scale.mV[VY]);
+			gGL.vertex2fv((x_max + border_height_bottom).mV);
+
+			gGL.texCoord2f(u_min, border_uv_scale.mV[VY]);
+			gGL.vertex2fv((x_min + border_height_bottom).mV);
+
+			// draw right 
+			gGL.texCoord2f(u_min, border_uv_scale.mV[VY]);
+			gGL.vertex2fv((x_min + border_height_bottom).mV);
+
+			gGL.texCoord2f(u_max, border_uv_scale.mV[VY]);
+			gGL.vertex2fv((x_max + border_height_bottom).mV);
+
+			gGL.texCoord2f(u_max, 1.f - border_uv_scale.mV[VY]);
+			gGL.vertex2fv((x_max + height_vec - border_height_top).mV);
+
+			gGL.texCoord2f(u_min, 1.f - border_uv_scale.mV[VY]);
+			gGL.vertex2fv((x_min + height_vec - border_height_top).mV);
+
+			// draw top right
+			gGL.texCoord2f(u_min, 1.f - border_uv_scale.mV[VY]);
+			gGL.vertex2fv((x_min + height_vec - border_height_top).mV);
+
+			gGL.texCoord2f(u_max, 1.f - border_uv_scale.mV[VY]);
+			gGL.vertex2fv((x_max + height_vec - border_height_top).mV);
+
+			gGL.texCoord2f(u_max, 1.f);
+			gGL.vertex2fv((x_max + height_vec).mV);
+
+			gGL.texCoord2f(u_min, 1.f);
+			gGL.vertex2fv((x_min + height_vec).mV);
+		}
+	}
+	gGL.end();
+
+	gGL.popUIMatrix();
+}
+
+void gl_segmented_rect_3d_tex(const LLVector2& border_scale, const LLVector3& border_width, 
+							  const LLVector3& border_height, const LLVector3& width_vec, const LLVector3& height_vec,
+							  const U32 edges)
+{
+	LLVector3 left_border_width = ((edges & (~(U32)ROUNDED_RECT_RIGHT)) != 0) ? border_width : LLVector3::zero;
+	LLVector3 right_border_width = ((edges & (~(U32)ROUNDED_RECT_LEFT)) != 0) ? border_width : LLVector3::zero;
+
+	LLVector3 top_border_height = ((edges & (~(U32)ROUNDED_RECT_BOTTOM)) != 0) ? border_height : LLVector3::zero;
+	LLVector3 bottom_border_height = ((edges & (~(U32)ROUNDED_RECT_TOP)) != 0) ? border_height : LLVector3::zero;
+
+
+	gGL.begin(LLRender::QUADS);
+	{
+		// draw bottom left
+		gGL.texCoord2f(0.f, 0.f);
+		gGL.vertex3f(0.f, 0.f, 0.f);
+
+		gGL.texCoord2f(border_scale.mV[VX], 0.f);
+		gGL.vertex3fv(left_border_width.mV);
+
+		gGL.texCoord2f(border_scale.mV[VX], border_scale.mV[VY]);
+		gGL.vertex3fv((left_border_width + bottom_border_height).mV);
+
+		gGL.texCoord2f(0.f, border_scale.mV[VY]);
+		gGL.vertex3fv(bottom_border_height.mV);
+
+		// draw bottom middle
+		gGL.texCoord2f(border_scale.mV[VX], 0.f);
+		gGL.vertex3fv(left_border_width.mV);
+
+		gGL.texCoord2f(1.f - border_scale.mV[VX], 0.f);
+		gGL.vertex3fv((width_vec - right_border_width).mV);
+
+		gGL.texCoord2f(1.f - border_scale.mV[VX], border_scale.mV[VY]);
+		gGL.vertex3fv((width_vec - right_border_width + bottom_border_height).mV);
+
+		gGL.texCoord2f(border_scale.mV[VX], border_scale.mV[VY]);
+		gGL.vertex3fv((left_border_width + bottom_border_height).mV);
+
+		// draw bottom right
+		gGL.texCoord2f(1.f - border_scale.mV[VX], 0.f);
+		gGL.vertex3fv((width_vec - right_border_width).mV);
+
+		gGL.texCoord2f(1.f, 0.f);
+		gGL.vertex3fv(width_vec.mV);
+
+		gGL.texCoord2f(1.f, border_scale.mV[VY]);
+		gGL.vertex3fv((width_vec + bottom_border_height).mV);
+
+		gGL.texCoord2f(1.f - border_scale.mV[VX], border_scale.mV[VY]);
+		gGL.vertex3fv((width_vec - right_border_width + bottom_border_height).mV);
+
+		// draw left 
+		gGL.texCoord2f(0.f, border_scale.mV[VY]);
+		gGL.vertex3fv(bottom_border_height.mV);
+
+		gGL.texCoord2f(border_scale.mV[VX], border_scale.mV[VY]);
+		gGL.vertex3fv((left_border_width + bottom_border_height).mV);
+
+		gGL.texCoord2f(border_scale.mV[VX], 1.f - border_scale.mV[VY]);
+		gGL.vertex3fv((left_border_width + height_vec - top_border_height).mV);
+
+		gGL.texCoord2f(0.f, 1.f - border_scale.mV[VY]);
+		gGL.vertex3fv((height_vec - top_border_height).mV);
+
+		// draw middle
+		gGL.texCoord2f(border_scale.mV[VX], border_scale.mV[VY]);
+		gGL.vertex3fv((left_border_width + bottom_border_height).mV);
+
+		gGL.texCoord2f(1.f - border_scale.mV[VX], border_scale.mV[VY]);
+		gGL.vertex3fv((width_vec - right_border_width + bottom_border_height).mV);
+
+		gGL.texCoord2f(1.f - border_scale.mV[VX], 1.f - border_scale.mV[VY]);
+		gGL.vertex3fv((width_vec - right_border_width + height_vec - top_border_height).mV);
+
+		gGL.texCoord2f(border_scale.mV[VX], 1.f - border_scale.mV[VY]);
+		gGL.vertex3fv((left_border_width + height_vec - top_border_height).mV);
+
+		// draw right 
+		gGL.texCoord2f(1.f - border_scale.mV[VX], border_scale.mV[VY]);
+		gGL.vertex3fv((width_vec - right_border_width + bottom_border_height).mV);
+
+		gGL.texCoord2f(1.f, border_scale.mV[VY]);
+		gGL.vertex3fv((width_vec + bottom_border_height).mV);
+
+		gGL.texCoord2f(1.f, 1.f - border_scale.mV[VY]);
+		gGL.vertex3fv((width_vec + height_vec - top_border_height).mV);
+
+		gGL.texCoord2f(1.f - border_scale.mV[VX], 1.f - border_scale.mV[VY]);
+		gGL.vertex3fv((width_vec - right_border_width + height_vec - top_border_height).mV);
+
+		// draw top left
+		gGL.texCoord2f(0.f, 1.f - border_scale.mV[VY]);
+		gGL.vertex3fv((height_vec - top_border_height).mV);
+
+		gGL.texCoord2f(border_scale.mV[VX], 1.f - border_scale.mV[VY]);
+		gGL.vertex3fv((left_border_width + height_vec - top_border_height).mV);
+
+		gGL.texCoord2f(border_scale.mV[VX], 1.f);
+		gGL.vertex3fv((left_border_width + height_vec).mV);
+
+		gGL.texCoord2f(0.f, 1.f);
+		gGL.vertex3fv((height_vec).mV);
+
+		// draw top middle
+		gGL.texCoord2f(border_scale.mV[VX], 1.f - border_scale.mV[VY]);
+		gGL.vertex3fv((left_border_width + height_vec - top_border_height).mV);
+
+		gGL.texCoord2f(1.f - border_scale.mV[VX], 1.f - border_scale.mV[VY]);
+		gGL.vertex3fv((width_vec - right_border_width + height_vec - top_border_height).mV);
+
+		gGL.texCoord2f(1.f - border_scale.mV[VX], 1.f);
+		gGL.vertex3fv((width_vec - right_border_width + height_vec).mV);
+
+		gGL.texCoord2f(border_scale.mV[VX], 1.f);
+		gGL.vertex3fv((left_border_width + height_vec).mV);
+
+		// draw top right
+		gGL.texCoord2f(1.f - border_scale.mV[VX], 1.f - border_scale.mV[VY]);
+		gGL.vertex3fv((width_vec - right_border_width + height_vec - top_border_height).mV);
+
+		gGL.texCoord2f(1.f, 1.f - border_scale.mV[VY]);
+		gGL.vertex3fv((width_vec + height_vec - top_border_height).mV);
+
+		gGL.texCoord2f(1.f, 1.f);
+		gGL.vertex3fv((width_vec + height_vec).mV);
+
+		gGL.texCoord2f(1.f - border_scale.mV[VX], 1.f);
+		gGL.vertex3fv((width_vec - right_border_width + height_vec).mV);
+	}
+	gGL.end();
+
+}
+
+void gl_segmented_rect_3d_tex_top(const LLVector2& border_scale, const LLVector3& border_width, const LLVector3& border_height, const LLVector3& width_vec, const LLVector3& height_vec)
+{
+	gl_segmented_rect_3d_tex(border_scale, border_width, border_height, width_vec, height_vec, ROUNDED_RECT_TOP);
+}
+
+// static
+void LLRender2D::initClass(LLImageProviderInterface* image_provider,
+						   const LLVector2* scale_factor)
+{
+	sGLScaleFactor = (scale_factor == NULL) ? LLVector2(1.f, 1.f) : *scale_factor;
+	sImageProvider = image_provider;
+}
+
+// static
+void LLRender2D::cleanupClass()
+{
+	if(sImageProvider)
+	{
+		sImageProvider->cleanUp();
+	}
+}
+
+
+//static
+void LLRender2D::translate(F32 x, F32 y, F32 z)
+{
+	gGL.translateUI(x,y,z);
+	LLFontGL::sCurOrigin.mX += (S32) x;
+	LLFontGL::sCurOrigin.mY += (S32) y;
+	LLFontGL::sCurDepth += z;
+}
+
+//static
+void LLRender2D::pushMatrix()
+{
+	gGL.pushUIMatrix();
+	LLFontGL::sOriginStack.push_back(std::make_pair(LLFontGL::sCurOrigin, LLFontGL::sCurDepth));
+}
+
+//static
+void LLRender2D::popMatrix()
+{
+	gGL.popUIMatrix();
+	LLFontGL::sCurOrigin = LLFontGL::sOriginStack.back().first;
+	LLFontGL::sCurDepth = LLFontGL::sOriginStack.back().second;
+	LLFontGL::sOriginStack.pop_back();
+}
+
+//static 
+void LLRender2D::loadIdentity()
+{
+	gGL.loadUIIdentity(); 
+	LLFontGL::sCurOrigin.mX = 0;
+	LLFontGL::sCurOrigin.mY = 0;
+	LLFontGL::sCurDepth = 0.f;
+}
+
+//static
+void LLRender2D::setScaleFactor(const LLVector2 &scale_factor)
+{
+	sGLScaleFactor = scale_factor;
+}
+
+//static
+void LLRender2D::setLineWidth(F32 width)
+{
+	gGL.flush();
+	glLineWidth(width * lerp(sGLScaleFactor.mV[VX], sGLScaleFactor.mV[VY], 0.5f));
+}
+
+//static
+LLPointer<LLUIImage> LLRender2D::getUIImageByID(const LLUUID& image_id, S32 priority)
+{
+	if (sImageProvider)
+	{
+		return sImageProvider->getUIImageByID(image_id, priority);
+	}
+	else
+	{
+		return NULL;
+	}
+}
+
+//static 
+LLPointer<LLUIImage> LLRender2D::getUIImage(const std::string& name, S32 priority)
+{
+	if (!name.empty() && sImageProvider)
+		return sImageProvider->getUIImage(name, priority);
+	else
+		return NULL;
+}
+
diff --git a/indra/llrender/llrender2dutils.h b/indra/llrender/llrender2dutils.h
new file mode 100644
index 0000000000000000000000000000000000000000..4ea2d06d99d7c78c98bf639f7d5bd997571a9d37
--- /dev/null
+++ b/indra/llrender/llrender2dutils.h
@@ -0,0 +1,164 @@
+/** 
+ * @file llrender2dutils.h
+ * @brief GL function declarations for immediate-mode gl drawing.
+ *
+ * $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$
+ */
+
+// All immediate-mode gl drawing should happen here.
+
+
+#ifndef LL_RENDER2DUTILS_H
+#define LL_RENDER2DUTILS_H
+
+#include "llpointer.h"		// LLPointer<>
+#include "llrect.h"
+#include "llglslshader.h"
+
+class LLColor4; 
+class LLVector3;
+class LLVector2;
+class LLUIImage;
+class LLUUID;
+
+extern const LLColor4 UI_VERTEX_COLOR;
+
+BOOL ui_point_in_rect(S32 x, S32 y, S32 left, S32 top, S32 right, S32 bottom);
+void gl_state_for_2d(S32 width, S32 height);
+
+void gl_line_2d(S32 x1, S32 y1, S32 x2, S32 y2);
+void gl_line_2d(S32 x1, S32 y1, S32 x2, S32 y2, const LLColor4 &color );
+void gl_triangle_2d(S32 x1, S32 y1, S32 x2, S32 y2, S32 x3, S32 y3, const LLColor4& color, BOOL filled);
+void gl_rect_2d_simple( S32 width, S32 height );
+
+void gl_draw_x(const LLRect& rect, const LLColor4& color);
+
+void gl_rect_2d(S32 left, S32 top, S32 right, S32 bottom, BOOL filled = TRUE );
+void gl_rect_2d(S32 left, S32 top, S32 right, S32 bottom, const LLColor4 &color, BOOL filled = TRUE );
+void gl_rect_2d_offset_local( S32 left, S32 top, S32 right, S32 bottom, const LLColor4 &color, S32 pixel_offset = 0, BOOL filled = TRUE );
+void gl_rect_2d_offset_local( S32 left, S32 top, S32 right, S32 bottom, S32 pixel_offset = 0, BOOL filled = TRUE );
+void gl_rect_2d(const LLRect& rect, BOOL filled = TRUE );
+void gl_rect_2d(const LLRect& rect, const LLColor4& color, BOOL filled = TRUE );
+void gl_rect_2d_checkerboard(const LLRect& rect, GLfloat alpha = 1.0f);
+
+void gl_drop_shadow(S32 left, S32 top, S32 right, S32 bottom, const LLColor4 &start_color, S32 lines);
+
+void gl_circle_2d(F32 x, F32 y, F32 radius, S32 steps, BOOL filled);
+void gl_arc_2d(F32 center_x, F32 center_y, F32 radius, S32 steps, BOOL filled, F32 start_angle, F32 end_angle);
+void gl_deep_circle( F32 radius, F32 depth );
+void gl_ring( F32 radius, F32 width, const LLColor4& center_color, const LLColor4& side_color, S32 steps, BOOL render_center );
+void gl_corners_2d(S32 left, S32 top, S32 right, S32 bottom, S32 length, F32 max_frac);
+void gl_washer_2d(F32 outer_radius, F32 inner_radius, S32 steps, const LLColor4& inner_color, const LLColor4& outer_color);
+void gl_washer_segment_2d(F32 outer_radius, F32 inner_radius, F32 start_radians, F32 end_radians, S32 steps, const LLColor4& inner_color, const LLColor4& outer_color);
+
+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_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_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));
+
+void gl_stippled_line_3d( const LLVector3& start, const LLVector3& end, const LLColor4& color, F32 phase = 0.f ); 
+
+void gl_rect_2d_simple_tex( S32 width, S32 height );
+
+// segmented rectangles
+
+/*
+   TL |______TOP_________| TR 
+     /|                  |\  
+   _/_|__________________|_\_
+   L| |    MIDDLE        | |R
+   _|_|__________________|_|_
+    \ |    BOTTOM        | /  
+   BL\|__________________|/ BR
+      |                  |    
+*/
+
+typedef enum e_rounded_edge
+{
+	ROUNDED_RECT_LEFT	= 0x1, 
+	ROUNDED_RECT_TOP	= 0x2, 
+	ROUNDED_RECT_RIGHT	= 0x4, 
+	ROUNDED_RECT_BOTTOM	= 0x8,
+	ROUNDED_RECT_ALL	= 0xf
+}ERoundedEdge;
+
+
+void gl_segmented_rect_2d_tex(const S32 left, const S32 top, const S32 right, const S32 bottom, const S32 texture_width, const S32 texture_height, const S32 border_size, const U32 edges = ROUNDED_RECT_ALL);
+void gl_segmented_rect_2d_fragment_tex(const S32 left, const S32 top, const S32 right, const S32 bottom, const S32 texture_width, const S32 texture_height, const S32 border_size, const F32 start_fragment, const F32 end_fragment, const U32 edges = ROUNDED_RECT_ALL);
+void gl_segmented_rect_3d_tex(const LLVector2& border_scale, const LLVector3& border_width, const LLVector3& border_height, const LLVector3& width_vec, const LLVector3& height_vec, U32 edges = ROUNDED_RECT_ALL);
+void gl_segmented_rect_3d_tex_top(const LLVector2& border_scale, const LLVector3& border_width, const LLVector3& border_height, const LLVector3& width_vec, const LLVector3& height_vec);
+
+inline void gl_rect_2d( const LLRect& rect, BOOL filled )
+{
+	gl_rect_2d( rect.mLeft, rect.mTop, rect.mRight, rect.mBottom, filled );
+}
+
+inline void gl_rect_2d_offset_local( const LLRect& rect, S32 pixel_offset, BOOL filled)
+{
+	gl_rect_2d_offset_local( rect.mLeft, rect.mTop, rect.mRight, rect.mBottom, pixel_offset, filled );
+}
+
+class LLImageProviderInterface;
+
+class LLRender2D
+{
+	LOG_CLASS(LLRender2D);
+public:
+	static void initClass(LLImageProviderInterface* image_provider,
+						  const LLVector2* scale_factor);
+	static void cleanupClass();
+
+	static void pushMatrix();
+	static void popMatrix();
+	static void loadIdentity();
+	static void translate(F32 x, F32 y, F32 z = 0.0f);
+
+	static void setLineWidth(F32 width);
+	static void setScaleFactor(const LLVector2& scale_factor);
+
+	static LLPointer<LLUIImage> getUIImageByID(const LLUUID& image_id, S32 priority = 0);
+	static LLPointer<LLUIImage> getUIImage(const std::string& name, S32 priority = 0);
+
+	static LLVector2		sGLScaleFactor;
+private:
+	static LLImageProviderInterface* sImageProvider;
+};
+
+class LLImageProviderInterface
+{
+protected:
+	LLImageProviderInterface() {};
+	virtual ~LLImageProviderInterface() {};
+public:
+	virtual LLPointer<LLUIImage> getUIImage(const std::string& name, S32 priority) = 0;
+	virtual LLPointer<LLUIImage> getUIImageByID(const LLUUID& id, S32 priority) = 0;
+	virtual void cleanUp() = 0;
+};
+
+
+extern LLGLSLShader gSolidColorProgram;
+extern LLGLSLShader gUIProgram;
+
+#endif // LL_RENDER2DUTILS_H
+
diff --git a/indra/llui/lluiimage.cpp b/indra/llrender/lluiimage.cpp
similarity index 98%
rename from indra/llui/lluiimage.cpp
rename to indra/llrender/lluiimage.cpp
index 1d9ce29ba98acd5ee95438c7f7d6b134ad454170..a632e7ed2fada3e2b5ae743c6e8f8ff80d55e84c 100644
--- a/indra/llui/lluiimage.cpp
+++ b/indra/llrender/lluiimage.cpp
@@ -31,7 +31,7 @@
 
 // Project includes
 #include "lluiimage.h"
-#include "llui.h"
+#include "llrender2dutils.h"
 
 LLUIImage::LLUIImage(const std::string& name, LLPointer<LLTexture> image)
 :	mName(name),
@@ -165,7 +165,7 @@ namespace LLInitParam
 			return;
 		}
 
-		LLUIImage* imagep =  LLUI::getUIImage(name());
+		LLUIImage* imagep =  LLRender2D::getUIImage(name());
 		if (imagep)
 		{
 			updateValue(imagep);
diff --git a/indra/llui/lluiimage.h b/indra/llrender/lluiimage.h
similarity index 100%
rename from indra/llui/lluiimage.h
rename to indra/llrender/lluiimage.h
diff --git a/indra/llui/CMakeLists.txt b/indra/llui/CMakeLists.txt
index d92b6aa1c07f66806f89ce0992ff6cda7e5fedf7..4d4b8edc37dc32463678eb99dfdb5a34e009a8cc 100644
--- a/indra/llui/CMakeLists.txt
+++ b/indra/llui/CMakeLists.txt
@@ -109,7 +109,6 @@ set(llui_SOURCE_FILES
     lluicolortable.cpp
     lluictrl.cpp
     lluictrlfactory.cpp
-    lluiimage.cpp
     lluistring.cpp
     llundo.cpp
     llurlaction.cpp
@@ -219,7 +218,6 @@ set(llui_HEADER_FILES
     lluifwd.h
     llui.h
     lluicolor.h
-    lluiimage.h
     lluistring.h
     llundo.h
     llurlaction.h
diff --git a/indra/llui/llcombobox.cpp b/indra/llui/llcombobox.cpp
index 806d2ef3f65d6b1e0aa6993e537fc2e42eaa8414..16e79b211d2968116a3ec4f099fbd25522dce699 100644
--- a/indra/llui/llcombobox.cpp
+++ b/indra/llui/llcombobox.cpp
@@ -551,7 +551,7 @@ void LLComboBox::showList()
 	LLCoordWindow window_size;
 	getWindow()->getSize(&window_size);
 	//HACK: shouldn't have to know about scale here
-	mList->fitContents( 192, llfloor((F32)window_size.mY / LLUI::sGLScaleFactor.mV[VY]) - 50 );
+	mList->fitContents( 192, llfloor((F32)window_size.mY / LLUI::getScaleFactor().mV[VY]) - 50 );
 
 	// Make sure that we can see the whole list
 	LLRect root_view_local;
diff --git a/indra/llui/lllineeditor.cpp b/indra/llui/lllineeditor.cpp
index 48d49af58810e4e4eccc3a73072ddd2821a431ae..d1e67a7d6baa6a9a055e59d9a69c782f5dfe47ad 100644
--- a/indra/llui/lllineeditor.cpp
+++ b/indra/llui/lllineeditor.cpp
@@ -2022,8 +2022,8 @@ void LLLineEditor::draw()
 				LLRect screen_pos = calcScreenRect();
 				LLCoordGL ime_pos( screen_pos.mLeft + pixels_after_scroll, screen_pos.mTop - lineeditor_v_pad );
 
-				ime_pos.mX = (S32) (ime_pos.mX * LLUI::sGLScaleFactor.mV[VX]);
-				ime_pos.mY = (S32) (ime_pos.mY * LLUI::sGLScaleFactor.mV[VY]);
+				ime_pos.mX = (S32) (ime_pos.mX * LLUI::getScaleFactor().mV[VX]);
+				ime_pos.mY = (S32) (ime_pos.mY * LLUI::getScaleFactor().mV[VY]);
 				getWindow()->setLanguageTextInput( ime_pos );
 			}
 		}
@@ -2570,7 +2570,7 @@ void LLLineEditor::markAsPreedit(S32 position, S32 length)
 
 S32 LLLineEditor::getPreeditFontSize() const
 {
-	return llround(mGLFont->getLineHeight() * LLUI::sGLScaleFactor.mV[VY]);
+	return llround(mGLFont->getLineHeight() * LLUI::getScaleFactor().mV[VY]);
 }
 
 void LLLineEditor::setReplaceNewlinesWithSpaces(BOOL replace)
diff --git a/indra/llui/lllocalcliprect.cpp b/indra/llui/lllocalcliprect.cpp
index 6841301219427752c66f74675a2f5201d15a7fae..f3a526faeb33ca0aee3f64bdb2ae7a656795d640 100644
--- a/indra/llui/lllocalcliprect.cpp
+++ b/indra/llui/lllocalcliprect.cpp
@@ -88,10 +88,10 @@ void LLScreenClipRect::updateScissorRegion()
 	LLRect rect = sClipRectStack.top();
 	stop_glerror();
 	S32 x,y,w,h;
-	x = llfloor(rect.mLeft * LLUI::sGLScaleFactor.mV[VX]);
-	y = llfloor(rect.mBottom * LLUI::sGLScaleFactor.mV[VY]);
-	w = llmax(0, llceil(rect.getWidth() * LLUI::sGLScaleFactor.mV[VX])) + 1;
-	h = llmax(0, llceil(rect.getHeight() * LLUI::sGLScaleFactor.mV[VY])) + 1;
+	x = llfloor(rect.mLeft * LLUI::getScaleFactor().mV[VX]);
+	y = llfloor(rect.mBottom * LLUI::getScaleFactor().mV[VY]);
+	w = llmax(0, llceil(rect.getWidth() * LLUI::getScaleFactor().mV[VX])) + 1;
+	h = llmax(0, llceil(rect.getHeight() * LLUI::getScaleFactor().mV[VY])) + 1;
 	glScissor( x,y,w,h );
 	stop_glerror();
 }
diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp
index 3815eec447e73908208ff8680bd03bc9aa983466..abe74c3f203badee2138b2438aedd042531fe28d 100644
--- a/indra/llui/lltextbase.cpp
+++ b/indra/llui/lltextbase.cpp
@@ -513,8 +513,8 @@ void LLTextBase::drawCursor()
 			LLRect screen_pos = calcScreenRect();
 			LLCoordGL ime_pos( screen_pos.mLeft + llfloor(cursor_rect.mLeft), screen_pos.mBottom + llfloor(cursor_rect.mTop) );
 
-			ime_pos.mX = (S32) (ime_pos.mX * LLUI::sGLScaleFactor.mV[VX]);
-			ime_pos.mY = (S32) (ime_pos.mY * LLUI::sGLScaleFactor.mV[VY]);
+			ime_pos.mX = (S32) (ime_pos.mX * LLUI::getScaleFactor().mV[VX]);
+			ime_pos.mY = (S32) (ime_pos.mY * LLUI::getScaleFactor().mV[VY]);
 			getWindow()->setLanguageTextInput( ime_pos );
 		}
 	}
diff --git a/indra/llui/lltexteditor.cpp b/indra/llui/lltexteditor.cpp
index 144b6960a1b03cf090f599207e7c02a5b5410097..1b22f87823dd3658f5c3534051e805df72ff238a 100644
--- a/indra/llui/lltexteditor.cpp
+++ b/indra/llui/lltexteditor.cpp
@@ -2843,7 +2843,7 @@ void LLTextEditor::markAsPreedit(S32 position, S32 length)
 
 S32 LLTextEditor::getPreeditFontSize() const
 {
-	return llround((F32)mDefaultFont->getLineHeight() * LLUI::sGLScaleFactor.mV[VY]);
+	return llround((F32)mDefaultFont->getLineHeight() * LLUI::getScaleFactor().mV[VY]);
 }
 
 BOOL LLTextEditor::isDirty() const
diff --git a/indra/llui/llui.cpp b/indra/llui/llui.cpp
index 87bf518aa17ca6c46b891627f344bc57eb9b7f7f..d5fdd1d064204ca413ed4881480bc833c9e07f94 100644
--- a/indra/llui/llui.cpp
+++ b/indra/llui/llui.cpp
@@ -39,6 +39,7 @@
 #include "llrect.h"
 #include "lldir.h"
 #include "llgl.h"
+#include "llsd.h"
 
 // Project includes
 #include "llcommandmanager.h"
@@ -69,15 +70,12 @@
 //
 // Globals
 //
-const LLColor4 UI_VERTEX_COLOR(1.f, 1.f, 1.f, 1.f);
 
 // Language for UI construction
 std::map<std::string, std::string> gTranslation;
 std::list<std::string> gUntranslated;
 /*static*/ LLUI::settings_map_t LLUI::sSettingGroups;
-/*static*/ LLImageProviderInterface* LLUI::sImageProvider = NULL;
 /*static*/ LLUIAudioCallback LLUI::sAudioCallback = NULL;
-/*static*/ LLVector2		LLUI::sGLScaleFactor(1.f, 1.f);
 /*static*/ LLWindow*		LLUI::sWindow = NULL;
 /*static*/ LLView*			LLUI::sRootView = NULL;
 /*static*/ BOOL                         LLUI::sDirty = FALSE;
@@ -137,1492 +135,13 @@ void make_ui_sound(const char* namep)
 	}
 }
 
-BOOL ui_point_in_rect(S32 x, S32 y, S32 left, S32 top, S32 right, S32 bottom)
-{
-	if (x < left || right < x) return FALSE;
-	if (y < bottom || top < y) return FALSE;
-	return TRUE;
-}
-
-
-// Puts GL into 2D drawing mode by turning off lighting, setting to an
-// orthographic projection, etc.
-void gl_state_for_2d(S32 width, S32 height)
-{
-	stop_glerror();
-	F32 window_width = (F32) width;//gViewerWindow->getWindowWidth();
-	F32 window_height = (F32) height;//gViewerWindow->getWindowHeight();
-
-	gGL.matrixMode(LLRender::MM_PROJECTION);
-	gGL.loadIdentity();
-	gGL.ortho(0.0f, llmax(window_width, 1.f), 0.0f, llmax(window_height,1.f), -1.0f, 1.0f);
-	gGL.matrixMode(LLRender::MM_MODELVIEW);
-	gGL.loadIdentity();
-	stop_glerror();
-}
-
-
-void gl_draw_x(const LLRect& rect, const LLColor4& color)
-{
-	gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
-
-	gGL.color4fv( color.mV );
-
-	gGL.begin( LLRender::LINES );
-		gGL.vertex2i( rect.mLeft,		rect.mTop );
-		gGL.vertex2i( rect.mRight,	rect.mBottom );
-		gGL.vertex2i( rect.mLeft,		rect.mBottom );
-		gGL.vertex2i( rect.mRight,	rect.mTop );
-	gGL.end();
-}
-
-
-void gl_rect_2d_offset_local( S32 left, S32 top, S32 right, S32 bottom, const LLColor4 &color, S32 pixel_offset, BOOL filled)
-{
-	gGL.color4fv(color.mV);
-	gl_rect_2d_offset_local(left, top, right, bottom, pixel_offset, filled);
-}
-
-void gl_rect_2d_offset_local( S32 left, S32 top, S32 right, S32 bottom, S32 pixel_offset, BOOL filled)
-{
-	gGL.pushUIMatrix();
-	left += LLFontGL::sCurOrigin.mX;
-	right += LLFontGL::sCurOrigin.mX;
-	bottom += LLFontGL::sCurOrigin.mY;
-	top += LLFontGL::sCurOrigin.mY;
-
-	gGL.loadUIIdentity();
-	gl_rect_2d(llfloor((F32)left * LLUI::sGLScaleFactor.mV[VX]) - pixel_offset,
-				llfloor((F32)top * LLUI::sGLScaleFactor.mV[VY]) + pixel_offset,
-				llfloor((F32)right * LLUI::sGLScaleFactor.mV[VX]) + pixel_offset,
-				llfloor((F32)bottom * LLUI::sGLScaleFactor.mV[VY]) - pixel_offset,
-				filled);
-	gGL.popUIMatrix();
-}
-
-
-void gl_rect_2d(S32 left, S32 top, S32 right, S32 bottom, BOOL filled )
-{
-	stop_glerror();
-	gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
-
-	// Counterclockwise quad will face the viewer
-	if( filled )
-	{ 
-		gGL.begin( LLRender::QUADS );
-			gGL.vertex2i(left, top);
-			gGL.vertex2i(left, bottom);
-			gGL.vertex2i(right, bottom);
-			gGL.vertex2i(right, top);
-		gGL.end();
-	}
-	else
-	{
-		if( gGLManager.mATIOffsetVerticalLines )
-		{
-			// Work around bug in ATI driver: vertical lines are offset by (-1,-1)
-			gGL.begin( LLRender::LINES );
-
-				// Verticals 
-				gGL.vertex2i(left + 1, top);
-				gGL.vertex2i(left + 1, bottom);
-
-				gGL.vertex2i(right, bottom);
-				gGL.vertex2i(right, top);
-
-				// Horizontals
-				top--;
-				right--;
-				gGL.vertex2i(left, bottom);
-				gGL.vertex2i(right, bottom);
-
-				gGL.vertex2i(left, top);
-				gGL.vertex2i(right, top);
-			gGL.end();
-		}
-		else
-		{
-			top--;
-			right--;
-			gGL.begin( LLRender::LINE_STRIP );
-				gGL.vertex2i(left, top);
-				gGL.vertex2i(left, bottom);
-				gGL.vertex2i(right, bottom);
-				gGL.vertex2i(right, top);
-				gGL.vertex2i(left, top);
-			gGL.end();
-		}
-	}
-	stop_glerror();
-}
-
-void gl_rect_2d(S32 left, S32 top, S32 right, S32 bottom, const LLColor4 &color, BOOL filled )
-{
-	gGL.color4fv( color.mV );
-	gl_rect_2d( left, top, right, bottom, filled );
-}
-
-
-void gl_rect_2d( const LLRect& rect, const LLColor4& color, BOOL filled )
-{
-	gGL.color4fv( color.mV );
-	gl_rect_2d( rect.mLeft, rect.mTop, rect.mRight, rect.mBottom, filled );
-}
-
-// Given a rectangle on the screen, draws a drop shadow _outside_
-// the right and bottom edges of it.  Along the right it has width "lines"
-// and along the bottom it has height "lines".
-void gl_drop_shadow(S32 left, S32 top, S32 right, S32 bottom, const LLColor4 &start_color, S32 lines)
-{
-	stop_glerror();
-	gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
-	
-	// HACK: Overlap with the rectangle by a single pixel.
-	right--;
-	bottom++;
-	lines++;
-
-	LLColor4 end_color = start_color;
-	end_color.mV[VALPHA] = 0.f;
-
-	gGL.begin(LLRender::QUADS);
-
-	// Right edge, CCW faces screen
-	gGL.color4fv(start_color.mV);
-	gGL.vertex2i(right,		top-lines);
-	gGL.vertex2i(right,		bottom);
-	gGL.color4fv(end_color.mV);
-	gGL.vertex2i(right+lines, bottom);
-	gGL.vertex2i(right+lines, top-lines);
-
-	// Bottom edge, CCW faces screen
-	gGL.color4fv(start_color.mV);
-	gGL.vertex2i(right,		bottom);
-	gGL.vertex2i(left+lines,	bottom);
-	gGL.color4fv(end_color.mV);
-	gGL.vertex2i(left+lines,	bottom-lines);
-	gGL.vertex2i(right,		bottom-lines);
-
-	// bottom left Corner
-	gGL.color4fv(start_color.mV);
-	gGL.vertex2i(left+lines,	bottom);
-	gGL.color4fv(end_color.mV);
-	gGL.vertex2i(left,		bottom);
-	// make the bottom left corner not sharp
-	gGL.vertex2i(left+1,		bottom-lines+1);
-	gGL.vertex2i(left+lines,	bottom-lines);
-
-	// bottom right corner
-	gGL.color4fv(start_color.mV);
-	gGL.vertex2i(right,		bottom);
-	gGL.color4fv(end_color.mV);
-	gGL.vertex2i(right,		bottom-lines);
-	// make the rightmost corner not sharp
-	gGL.vertex2i(right+lines-1,	bottom-lines+1);
-	gGL.vertex2i(right+lines,	bottom);
-
-	// top right corner
-	gGL.color4fv(start_color.mV);
-	gGL.vertex2i( right,			top-lines );
-	gGL.color4fv(end_color.mV);
-	gGL.vertex2i( right+lines,	top-lines );
-	// make the corner not sharp
-	gGL.vertex2i( right+lines-1,	top-1 );
-	gGL.vertex2i( right,			top );
-
-	gGL.end();
-	stop_glerror();
-}
-
-void gl_line_2d(S32 x1, S32 y1, S32 x2, S32 y2 )
-{
-	// Work around bug in ATI driver: vertical lines are offset by (-1,-1)
-	if( (x1 == x2) && gGLManager.mATIOffsetVerticalLines )
-	{
-		x1++;
-		x2++;
-		y1++;
-		y2++;
-	}
-
-	gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
-	
-	gGL.begin(LLRender::LINES);
-		gGL.vertex2i(x1, y1);
-		gGL.vertex2i(x2, y2);
-	gGL.end();
-}
-
-void gl_line_2d(S32 x1, S32 y1, S32 x2, S32 y2, const LLColor4 &color )
-{
-	// Work around bug in ATI driver: vertical lines are offset by (-1,-1)
-	if( (x1 == x2) && gGLManager.mATIOffsetVerticalLines )
-	{
-		x1++;
-		x2++;
-		y1++;
-		y2++;
-	}
-
-	gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
-
-	gGL.color4fv( color.mV );
-
-	gGL.begin(LLRender::LINES);
-		gGL.vertex2i(x1, y1);
-		gGL.vertex2i(x2, y2);
-	gGL.end();
-}
-
-void gl_triangle_2d(S32 x1, S32 y1, S32 x2, S32 y2, S32 x3, S32 y3, const LLColor4& color, BOOL filled)
-{
-	gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
-
-	gGL.color4fv(color.mV);
-
-	if (filled)
-	{
-		gGL.begin(LLRender::TRIANGLES);
-	}
-	else
-	{
-		gGL.begin(LLRender::LINE_LOOP);
-	}
-	gGL.vertex2i(x1, y1);
-	gGL.vertex2i(x2, y2);
-	gGL.vertex2i(x3, y3);
-	gGL.end();
-}
-
-void gl_corners_2d(S32 left, S32 top, S32 right, S32 bottom, S32 length, F32 max_frac)
-{
-	gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
-
-	length = llmin((S32)(max_frac*(right - left)), length);
-	length = llmin((S32)(max_frac*(top - bottom)), length);
-	gGL.begin(LLRender::LINES);
-	gGL.vertex2i(left, top);
-	gGL.vertex2i(left + length, top);
-	
-	gGL.vertex2i(left, top);
-	gGL.vertex2i(left, top - length);
-
-	gGL.vertex2i(left, bottom);
-	gGL.vertex2i(left + length, bottom);
-	
-	gGL.vertex2i(left, bottom);
-	gGL.vertex2i(left, bottom + length);
-
-	gGL.vertex2i(right, top);
-	gGL.vertex2i(right - length, top);
-
-	gGL.vertex2i(right, top);
-	gGL.vertex2i(right, top - length);
-
-	gGL.vertex2i(right, bottom);
-	gGL.vertex2i(right - length, bottom);
-
-	gGL.vertex2i(right, bottom);
-	gGL.vertex2i(right, bottom + length);
-	gGL.end();
-}
-
-
-void gl_draw_image( S32 x, S32 y, LLTexture* image, const LLColor4& color, const LLRectf& uv_rect )
-{
-	if (NULL == image)
-	{
-		llwarns << "image == NULL; aborting function" << llendl;
-		return;
-	}
-	gl_draw_scaled_rotated_image( x, y, image->getWidth(0), image->getHeight(0), 0.f, image, color, uv_rect );
-}
-
-void gl_draw_scaled_image(S32 x, S32 y, S32 width, S32 height, LLTexture* image, const LLColor4& color, const LLRectf& uv_rect)
-{
-	if (NULL == image)
-	{
-		llwarns << "image == NULL; aborting function" << llendl;
-		return;
-	}
-	gl_draw_scaled_rotated_image( x, y, width, height, 0.f, image, color, uv_rect );
-}
-
-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, const LLRectf& uv_rect)
-{
-	if (NULL == image)
-	{
-		llwarns << "image == NULL; aborting function" << llendl;
-		return;
-	}
-
-	// scale screen size of borders down
-	F32 border_width_fraction = (F32)border_width / (F32)image->getWidth(0);
-	F32 border_height_fraction = (F32)border_height / (F32)image->getHeight(0);
-
-	LLRectf scale_rect(border_width_fraction, 1.f - border_height_fraction, 1.f - border_width_fraction, border_height_fraction);
-	gl_draw_scaled_image_with_border(x, y, width, height, image, color, solid_color, uv_rect, scale_rect);
-}
-
-void gl_draw_scaled_image_with_border(S32 x, S32 y, S32 width, S32 height, LLTexture* image, const LLColor4& color, BOOL solid_color, const LLRectf& uv_outer_rect, const LLRectf& center_rect)
-{
-	stop_glerror();
-
-	if (NULL == image)
-	{
-		llwarns << "image == NULL; aborting function" << llendl;
-		return;
-	}
-
-	// add in offset of current image to current UI translation
-	const LLVector3 ui_scale = gGL.getUIScale();
-	const LLVector3 ui_translation = (gGL.getUITranslation() + LLVector3(x, y, 0.f)).scaledVec(ui_scale);
-
-	F32 uv_width = uv_outer_rect.getWidth();
-	F32 uv_height = uv_outer_rect.getHeight();
-
-	// shrink scaling region to be proportional to clipped image region
-	LLRectf uv_center_rect(
-		uv_outer_rect.mLeft + (center_rect.mLeft * uv_width),
-		uv_outer_rect.mBottom + (center_rect.mTop * uv_height),
-		uv_outer_rect.mLeft + (center_rect.mRight * uv_width),
-		uv_outer_rect.mBottom + (center_rect.mBottom * uv_height));
-
-	F32 image_width = image->getWidth(0);
-	F32 image_height = image->getHeight(0);
-
-	S32 image_natural_width = llround(image_width * uv_width);
-	S32 image_natural_height = llround(image_height * uv_height);
-
-	LLRectf draw_center_rect(	uv_center_rect.mLeft * image_width,
-								uv_center_rect.mTop * image_height,
-								uv_center_rect.mRight * image_width,
-								uv_center_rect.mBottom * image_height);
-
-	{	// scale fixed region of image to drawn region
-		draw_center_rect.mRight += width - image_natural_width;
-		draw_center_rect.mTop += height - image_natural_height;
-
-		F32 border_shrink_width = llmax(0.f, draw_center_rect.mLeft - draw_center_rect.mRight);
-		F32 border_shrink_height = llmax(0.f, draw_center_rect.mBottom - draw_center_rect.mTop);
-
-		F32 shrink_width_ratio = center_rect.getWidth() == 1.f ? 0.f : border_shrink_width / ((F32)image_natural_width * (1.f - center_rect.getWidth()));
-		F32 shrink_height_ratio = center_rect.getHeight() == 1.f ? 0.f : border_shrink_height / ((F32)image_natural_height * (1.f - center_rect.getHeight()));
-
-		F32 shrink_scale = 1.f - llmax(shrink_width_ratio, shrink_height_ratio);
-
-		draw_center_rect.mLeft = llround(ui_translation.mV[VX] + (F32)draw_center_rect.mLeft * shrink_scale * ui_scale.mV[VX]);
-		draw_center_rect.mTop = llround(ui_translation.mV[VY] + lerp((F32)height, (F32)draw_center_rect.mTop, shrink_scale) * ui_scale.mV[VY]);
-		draw_center_rect.mRight = llround(ui_translation.mV[VX] + lerp((F32)width, (F32)draw_center_rect.mRight, shrink_scale) * ui_scale.mV[VX]);
-		draw_center_rect.mBottom = llround(ui_translation.mV[VY] + (F32)draw_center_rect.mBottom * shrink_scale * ui_scale.mV[VY]);
-	}
-
-	LLRectf draw_outer_rect(ui_translation.mV[VX], 
-							ui_translation.mV[VY] + height * ui_scale.mV[VY], 
-							ui_translation.mV[VX] + width * ui_scale.mV[VX], 
-							ui_translation.mV[VY]);
-
-	LLGLSUIDefault gls_ui;
-	
-	if (solid_color)
-	{
-		if (LLGLSLShader::sNoFixedFunction)
-		{
-			gSolidColorProgram.bind();
-		}
-		else
-		{
-			gGL.getTexUnit(0)->setTextureColorBlend(LLTexUnit::TBO_REPLACE, LLTexUnit::TBS_PREV_COLOR);
-			gGL.getTexUnit(0)->setTextureAlphaBlend(LLTexUnit::TBO_MULT, LLTexUnit::TBS_TEX_ALPHA, LLTexUnit::TBS_VERT_ALPHA);
-		}
-	}
-
-	gGL.getTexUnit(0)->bind(image, true);
-
-	gGL.color4fv(color.mV);
-	
-	const S32 NUM_VERTICES = 9 * 4; // 9 quads
-	LLVector2 uv[NUM_VERTICES];
-	LLVector3 pos[NUM_VERTICES];
-
-	S32 index = 0;
-
-	gGL.begin(LLRender::QUADS);
-	{
-		// draw bottom left
-		uv[index] = LLVector2(uv_outer_rect.mLeft, uv_outer_rect.mBottom);
-		pos[index] = LLVector3(draw_outer_rect.mLeft, draw_outer_rect.mBottom, 0.f);
-		index++;
-
-		uv[index] = LLVector2(uv_center_rect.mLeft, uv_outer_rect.mBottom);
-		pos[index] = LLVector3(draw_center_rect.mLeft, draw_outer_rect.mBottom, 0.f);
-		index++;
-
-		uv[index] = LLVector2(uv_center_rect.mLeft, uv_center_rect.mBottom);
-		pos[index] = LLVector3(draw_center_rect.mLeft, draw_center_rect.mBottom, 0.f);
-		index++;
-
-		uv[index] = LLVector2(uv_outer_rect.mLeft, uv_center_rect.mBottom);
-		pos[index] = LLVector3(draw_outer_rect.mLeft, draw_center_rect.mBottom, 0.f);
-		index++;
-
-		// draw bottom middle
-		uv[index] = LLVector2(uv_center_rect.mLeft, uv_outer_rect.mBottom);
-		pos[index] = LLVector3(draw_center_rect.mLeft, draw_outer_rect.mBottom, 0.f);
-		index++;
-
-		uv[index] = LLVector2(uv_center_rect.mRight, uv_outer_rect.mBottom);
-		pos[index] = LLVector3(draw_center_rect.mRight, draw_outer_rect.mBottom, 0.f);
-		index++;
-
-		uv[index] = LLVector2(uv_center_rect.mRight, uv_center_rect.mBottom);
-		pos[index] = LLVector3(draw_center_rect.mRight, draw_center_rect.mBottom, 0.f);
-		index++;
-
-		uv[index] = LLVector2(uv_center_rect.mLeft, uv_center_rect.mBottom);
-		pos[index] = LLVector3(draw_center_rect.mLeft, draw_center_rect.mBottom, 0.f);
-		index++;
-
-		// draw bottom right
-		uv[index] = LLVector2(uv_center_rect.mRight, uv_outer_rect.mBottom);
-		pos[index] = LLVector3(draw_center_rect.mRight, draw_outer_rect.mBottom, 0.f);
-		index++;
-
-		uv[index] = LLVector2(uv_outer_rect.mRight, uv_outer_rect.mBottom);
-		pos[index] = LLVector3(draw_outer_rect.mRight, draw_outer_rect.mBottom, 0.f);
-		index++;
-
-		uv[index] = LLVector2(uv_outer_rect.mRight, uv_center_rect.mBottom);
-		pos[index] = LLVector3(draw_outer_rect.mRight, draw_center_rect.mBottom, 0.f);
-		index++;
-
-		uv[index] = LLVector2(uv_center_rect.mRight, uv_center_rect.mBottom);
-		pos[index] = LLVector3(draw_center_rect.mRight, draw_center_rect.mBottom, 0.f);
-		index++;
-
-		// draw left 
-		uv[index] = LLVector2(uv_outer_rect.mLeft, uv_center_rect.mBottom);
-		pos[index] = LLVector3(draw_outer_rect.mLeft, draw_center_rect.mBottom, 0.f);
-		index++;
-
-		uv[index] = LLVector2(uv_center_rect.mLeft, uv_center_rect.mBottom);
-		pos[index] = LLVector3(draw_center_rect.mLeft, draw_center_rect.mBottom, 0.f);
-		index++;
-
-		uv[index] = LLVector2(uv_center_rect.mLeft, uv_center_rect.mTop);
-		pos[index] = LLVector3(draw_center_rect.mLeft, draw_center_rect.mTop, 0.f);
-		index++;
-
-		uv[index] = LLVector2(uv_outer_rect.mLeft, uv_center_rect.mTop);
-		pos[index] = LLVector3(draw_outer_rect.mLeft, draw_center_rect.mTop, 0.f);
-		index++;
-
-		// draw middle
-		uv[index] = LLVector2(uv_center_rect.mLeft, uv_center_rect.mBottom);
-		pos[index] = LLVector3(draw_center_rect.mLeft, draw_center_rect.mBottom, 0.f);
-		index++;
-
-		uv[index] = LLVector2(uv_center_rect.mRight, uv_center_rect.mBottom);
-		pos[index] = LLVector3(draw_center_rect.mRight, draw_center_rect.mBottom, 0.f);
-		index++;
-
-		uv[index] = LLVector2(uv_center_rect.mRight, uv_center_rect.mTop);
-		pos[index] = LLVector3(draw_center_rect.mRight, draw_center_rect.mTop, 0.f);
-		index++;
-
-		uv[index] = LLVector2(uv_center_rect.mLeft, uv_center_rect.mTop);
-		pos[index] = LLVector3(draw_center_rect.mLeft, draw_center_rect.mTop, 0.f);
-		index++;
-
-		// draw right 
-		uv[index] = LLVector2(uv_center_rect.mRight, uv_center_rect.mBottom);
-		pos[index] = LLVector3(draw_center_rect.mRight, draw_center_rect.mBottom, 0.f);
-		index++;
-
-		uv[index] = LLVector2(uv_outer_rect.mRight, uv_center_rect.mBottom);
-		pos[index] = LLVector3(draw_outer_rect.mRight, draw_center_rect.mBottom, 0.f);
-		index++;
-
-		uv[index] = LLVector2(uv_outer_rect.mRight, uv_center_rect.mTop);
-		pos[index] = LLVector3(draw_outer_rect.mRight, draw_center_rect.mTop, 0.f);
-		index++;
-
-		uv[index] = LLVector2(uv_center_rect.mRight, uv_center_rect.mTop);
-		pos[index] = LLVector3(draw_center_rect.mRight, draw_center_rect.mTop, 0.f);
-		index++;
-
-		// draw top left
-		uv[index] = LLVector2(uv_outer_rect.mLeft, uv_center_rect.mTop);
-		pos[index] = LLVector3(draw_outer_rect.mLeft, draw_center_rect.mTop, 0.f);
-		index++;
-
-		uv[index] = LLVector2(uv_center_rect.mLeft, uv_center_rect.mTop);
-		pos[index] = LLVector3(draw_center_rect.mLeft, draw_center_rect.mTop, 0.f);
-		index++;
-
-		uv[index] = LLVector2(uv_center_rect.mLeft, uv_outer_rect.mTop);
-		pos[index] = LLVector3(draw_center_rect.mLeft, draw_outer_rect.mTop, 0.f);
-		index++;
-
-		uv[index] = LLVector2(uv_outer_rect.mLeft, uv_outer_rect.mTop);
-		pos[index] = LLVector3(draw_outer_rect.mLeft, draw_outer_rect.mTop, 0.f);
-		index++;
-
-		// draw top middle
-		uv[index] = LLVector2(uv_center_rect.mLeft, uv_center_rect.mTop);
-		pos[index] = LLVector3(draw_center_rect.mLeft, draw_center_rect.mTop, 0.f);
-		index++;
-
-		uv[index] = LLVector2(uv_center_rect.mRight, uv_center_rect.mTop);
-		pos[index] = LLVector3(draw_center_rect.mRight, draw_center_rect.mTop, 0.f);
-		index++;
-
-		uv[index] = LLVector2(uv_center_rect.mRight, uv_outer_rect.mTop);
-		pos[index] = LLVector3(draw_center_rect.mRight, draw_outer_rect.mTop, 0.f);
-		index++;
-
-		uv[index] = LLVector2(uv_center_rect.mLeft, uv_outer_rect.mTop);
-		pos[index] = LLVector3(draw_center_rect.mLeft, draw_outer_rect.mTop, 0.f);
-		index++;
-
-		// draw top right
-		uv[index] = LLVector2(uv_center_rect.mRight, uv_center_rect.mTop);
-		pos[index] = LLVector3(draw_center_rect.mRight, draw_center_rect.mTop, 0.f);
-		index++;
-
-		uv[index] = LLVector2(uv_outer_rect.mRight, uv_center_rect.mTop);
-		pos[index] = LLVector3(draw_outer_rect.mRight, draw_center_rect.mTop, 0.f);
-		index++;
-
-		uv[index] = LLVector2(uv_outer_rect.mRight, uv_outer_rect.mTop);
-		pos[index] = LLVector3(draw_outer_rect.mRight, draw_outer_rect.mTop, 0.f);
-		index++;
-
-		uv[index] = LLVector2(uv_center_rect.mRight, uv_outer_rect.mTop);
-		pos[index] = LLVector3(draw_center_rect.mRight, draw_outer_rect.mTop, 0.f);
-		index++;
-
-		gGL.vertexBatchPreTransformed(pos, uv, NUM_VERTICES);
-	}
-	gGL.end();
-
-	if (solid_color)
-	{
-		if (LLGLSLShader::sNoFixedFunction)
-		{
-			gUIProgram.bind();
-		}
-		else
-		{
-			gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT);
-		}
-	}
-}
-
-void gl_draw_rotated_image(S32 x, S32 y, F32 degrees, LLTexture* image, const LLColor4& color, const LLRectf& uv_rect)
-{
-	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)
-{
-	if (NULL == image)
-	{
-		llwarns << "image == NULL; aborting function" << llendl;
-		return;
-	}
-
-	LLGLSUIDefault gls_ui;
-
-
-	gGL.getTexUnit(0)->bind(image, true);
-
-	gGL.color4fv(color.mV);
-
-	if (degrees == 0.f)
-	{
-		const S32 NUM_VERTICES = 4; // 9 quads
-		LLVector2 uv[NUM_VERTICES];
-		LLVector3 pos[NUM_VERTICES];
-
-		gGL.begin(LLRender::QUADS);
-		{
-			LLVector3 ui_scale = gGL.getUIScale();
-			LLVector3 ui_translation = gGL.getUITranslation();
-			ui_translation.mV[VX] += x;
-			ui_translation.mV[VY] += y;
-			ui_translation.scaleVec(ui_scale);
-			S32 index = 0;
-			S32 scaled_width = llround(width * ui_scale.mV[VX]);
-			S32 scaled_height = llround(height * ui_scale.mV[VY]);
-
-			uv[index] = LLVector2(uv_rect.mRight, uv_rect.mTop);
-			pos[index] = LLVector3(ui_translation.mV[VX] + scaled_width, ui_translation.mV[VY] + scaled_height, 0.f);
-			index++;
-
-			uv[index] = LLVector2(uv_rect.mLeft, uv_rect.mTop);
-			pos[index] = LLVector3(ui_translation.mV[VX], ui_translation.mV[VY] + scaled_height, 0.f);
-			index++;
-
-			uv[index] = LLVector2(uv_rect.mLeft, uv_rect.mBottom);
-			pos[index] = LLVector3(ui_translation.mV[VX], ui_translation.mV[VY], 0.f);
-			index++;
-
-			uv[index] = LLVector2(uv_rect.mRight, uv_rect.mBottom);
-			pos[index] = LLVector3(ui_translation.mV[VX] + scaled_width, ui_translation.mV[VY], 0.f);
-			index++;
-
-			gGL.vertexBatchPreTransformed(pos, uv, NUM_VERTICES);
-		}
-		gGL.end();
-	}
-	else
-	{
-		gGL.pushUIMatrix();
-		gGL.translateUI((F32)x, (F32)y, 0.f);
-	
-		F32 offset_x = F32(width/2);
-		F32 offset_y = F32(height/2);
-
-		gGL.translateUI(offset_x, offset_y, 0.f);
-
-		LLMatrix3 quat(0.f, 0.f, degrees*DEG_TO_RAD);
-		
-		gGL.getTexUnit(0)->bind(image, true);
-
-		gGL.color4fv(color.mV);
-		
-		gGL.begin(LLRender::QUADS);
-		{
-			LLVector3 v;
-
-			v = LLVector3(offset_x, offset_y, 0.f) * quat;
-			gGL.texCoord2f(uv_rect.mRight, uv_rect.mTop);
-			gGL.vertex2f(v.mV[0], v.mV[1] );
-
-			v = LLVector3(-offset_x, offset_y, 0.f) * quat;
-			gGL.texCoord2f(uv_rect.mLeft, uv_rect.mTop);
-			gGL.vertex2f(v.mV[0], v.mV[1] );
-
-			v = LLVector3(-offset_x, -offset_y, 0.f) * quat;
-			gGL.texCoord2f(uv_rect.mLeft, uv_rect.mBottom);
-			gGL.vertex2f(v.mV[0], v.mV[1] );
-
-			v = LLVector3(offset_x, -offset_y, 0.f) * quat;
-			gGL.texCoord2f(uv_rect.mRight, uv_rect.mBottom);
-			gGL.vertex2f(v.mV[0], v.mV[1] );
-		}
-		gGL.end();
-		gGL.popUIMatrix();
-	}
-}
-
-
-void gl_stippled_line_3d( const LLVector3& start, const LLVector3& end, const LLColor4& color, F32 phase )
-{
-	phase = fmod(phase, 1.f);
-
-	S32 shift = S32(phase * 4.f) % 4;
-
-	// Stippled line
-	LLGLEnable stipple(GL_LINE_STIPPLE);
-	
-	gGL.color4f(color.mV[VRED], color.mV[VGREEN], color.mV[VBLUE], color.mV[VALPHA]);
-
-	gGL.flush();
-	glLineWidth(2.5f);
-
-	if (!LLGLSLShader::sNoFixedFunction)
-	{
-		glLineStipple(2, 0x3333 << shift);
-	}
-
-	gGL.begin(LLRender::LINES);
-	{
-		gGL.vertex3fv( start.mV );
-		gGL.vertex3fv( end.mV );
-	}
-	gGL.end();
-
-	LLUI::setLineWidth(1.f);
-}
-
-void gl_arc_2d(F32 center_x, F32 center_y, F32 radius, S32 steps, BOOL filled, F32 start_angle, F32 end_angle)
-{
-	if (end_angle < start_angle)
-	{
-		end_angle += F_TWO_PI;
-	}
-
-	gGL.pushUIMatrix();
-	{
-		gGL.translateUI(center_x, center_y, 0.f);
-
-		// Inexact, but reasonably fast.
-		F32 delta = (end_angle - start_angle) / steps;
-		F32 sin_delta = sin( delta );
-		F32 cos_delta = cos( delta );
-		F32 x = cosf(start_angle) * radius;
-		F32 y = sinf(start_angle) * radius;
-
-		if (filled)
-		{
-			gGL.begin(LLRender::TRIANGLE_FAN);
-			gGL.vertex2f(0.f, 0.f);
-			// make sure circle is complete
-			steps += 1;
-		}
-		else
-		{
-			gGL.begin(LLRender::LINE_STRIP);
-		}
-
-		while( steps-- )
-		{
-			// Successive rotations
-			gGL.vertex2f( x, y );
-			F32 x_new = x * cos_delta - y * sin_delta;
-			y = x * sin_delta +  y * cos_delta;
-			x = x_new;
-		}
-		gGL.end();
-	}
-	gGL.popUIMatrix();
-}
-
-void gl_circle_2d(F32 center_x, F32 center_y, F32 radius, S32 steps, BOOL filled)
-{
-	gGL.pushUIMatrix();
-	{
-		gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
-		gGL.translateUI(center_x, center_y, 0.f);
-
-		// Inexact, but reasonably fast.
-		F32 delta = F_TWO_PI / steps;
-		F32 sin_delta = sin( delta );
-		F32 cos_delta = cos( delta );
-		F32 x = radius;
-		F32 y = 0.f;
-
-		if (filled)
-		{
-			gGL.begin(LLRender::TRIANGLE_FAN);
-			gGL.vertex2f(0.f, 0.f);
-			// make sure circle is complete
-			steps += 1;
-		}
-		else
-		{
-			gGL.begin(LLRender::LINE_LOOP);
-		}
-
-		while( steps-- )
-		{
-			// Successive rotations
-			gGL.vertex2f( x, y );
-			F32 x_new = x * cos_delta - y * sin_delta;
-			y = x * sin_delta +  y * cos_delta;
-			x = x_new;
-		}
-		gGL.end();
-	}
-	gGL.popUIMatrix();
-}
-
-// Renders a ring with sides (tube shape)
-void gl_deep_circle( F32 radius, F32 depth, S32 steps )
-{
-	F32 x = radius;
-	F32 y = 0.f;
-	F32 angle_delta = F_TWO_PI / (F32)steps;
-	gGL.begin( LLRender::TRIANGLE_STRIP  );
-	{
-		S32 step = steps + 1; // An extra step to close the circle.
-		while( step-- )
-		{
-			gGL.vertex3f( x, y, depth );
-			gGL.vertex3f( x, y, 0.f );
-
-			F32 x_new = x * cosf(angle_delta) - y * sinf(angle_delta);
-			y = x * sinf(angle_delta) +  y * cosf(angle_delta);
-			x = x_new;
-		}
-	}
-	gGL.end();
-}
-
-void gl_ring( F32 radius, F32 width, const LLColor4& center_color, const LLColor4& side_color, S32 steps, BOOL render_center )
-{
-	gGL.pushUIMatrix();
-	{
-		gGL.translateUI(0.f, 0.f, -width / 2);
-		if( render_center )
-		{
-			gGL.color4fv(center_color.mV);
-			gGL.diffuseColor4fv(center_color.mV);
-			gl_deep_circle( radius, width, steps );
-		}
-		else
-		{
-			gGL.diffuseColor4fv(side_color.mV);
-			gl_washer_2d(radius, radius - width, steps, side_color, side_color);
-			gGL.translateUI(0.f, 0.f, width);
-			gl_washer_2d(radius - width, radius, steps, side_color, side_color);
-		}
-	}
-	gGL.popUIMatrix();
-}
-
-// Draw gray and white checkerboard with black border
-void gl_rect_2d_checkerboard(const LLRect& rect, GLfloat alpha)
-{
-	if (!LLGLSLShader::sNoFixedFunction)
-	{ 
-		// Initialize the first time this is called.
-		const S32 PIXELS = 32;
-		static GLubyte checkerboard[PIXELS * PIXELS];
-		static BOOL first = TRUE;
-		if( first )
-		{
-			for( S32 i = 0; i < PIXELS; i++ )
-			{
-				for( S32 j = 0; j < PIXELS; j++ )
-				{
-					checkerboard[i * PIXELS + j] = ((i & 1) ^ (j & 1)) * 0xFF;
-				}
-			}
-			first = FALSE;
-		}
-	
-		gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
-
-		// ...white squares
-		gGL.color4f( 1.f, 1.f, 1.f, alpha );
-		gl_rect_2d(rect);
-
-		// ...gray squares
-		gGL.color4f( .7f, .7f, .7f, alpha );
-		gGL.flush();
-
-		glPolygonStipple( checkerboard );
-
-		LLGLEnable polygon_stipple(GL_POLYGON_STIPPLE);
-		gl_rect_2d(rect);
-	}
-	else
-	{ //polygon stipple is deprecated, use "Checker" texture
-		LLPointer<LLUIImage> img = LLUI::getUIImage("Checker");
-		gGL.getTexUnit(0)->bind(img->getImage());
-		gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_WRAP);
-		gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_POINT);
-
-		LLColor4 color(1.f, 1.f, 1.f, alpha);
-		LLRectf uv_rect(0, 0, rect.getWidth()/32.f, rect.getHeight()/32.f);
-
-		gl_draw_scaled_image(rect.mLeft, rect.mBottom, rect.getWidth(), rect.getHeight(),
-			img->getImage(), color, uv_rect);
-	}
-	
-	gGL.flush();
-}
-
-
-// Draws the area between two concentric circles, like
-// a doughnut or washer.
-void gl_washer_2d(F32 outer_radius, F32 inner_radius, S32 steps, const LLColor4& inner_color, const LLColor4& outer_color)
-{
-	const F32 DELTA = F_TWO_PI / steps;
-	const F32 SIN_DELTA = sin( DELTA );
-	const F32 COS_DELTA = cos( DELTA );
-
-	F32 x1 = outer_radius;
-	F32 y1 = 0.f;
-	F32 x2 = inner_radius;
-	F32 y2 = 0.f;
-
-	gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
-
-	gGL.begin( LLRender::TRIANGLE_STRIP  );
-	{
-		steps += 1; // An extra step to close the circle.
-		while( steps-- )
-		{
-			gGL.color4fv(outer_color.mV);
-			gGL.vertex2f( x1, y1 );
-			gGL.color4fv(inner_color.mV);
-			gGL.vertex2f( x2, y2 );
-
-			F32 x1_new = x1 * COS_DELTA - y1 * SIN_DELTA;
-			y1 = x1 * SIN_DELTA +  y1 * COS_DELTA;
-			x1 = x1_new;
-
-			F32 x2_new = x2 * COS_DELTA - y2 * SIN_DELTA;
-			y2 = x2 * SIN_DELTA +  y2 * COS_DELTA;
-			x2 = x2_new;
-		}
-	}
-	gGL.end();
-}
-
-// Draws the area between two concentric circles, like
-// a doughnut or washer.
-void gl_washer_segment_2d(F32 outer_radius, F32 inner_radius, F32 start_radians, F32 end_radians, S32 steps, const LLColor4& inner_color, const LLColor4& outer_color)
-{
-	const F32 DELTA = (end_radians - start_radians) / steps;
-	const F32 SIN_DELTA = sin( DELTA );
-	const F32 COS_DELTA = cos( DELTA );
-
-	F32 x1 = outer_radius * cos( start_radians );
-	F32 y1 = outer_radius * sin( start_radians );
-	F32 x2 = inner_radius * cos( start_radians );
-	F32 y2 = inner_radius * sin( start_radians );
-
-	gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
-	gGL.begin( LLRender::TRIANGLE_STRIP  );
-	{
-		steps += 1; // An extra step to close the circle.
-		while( steps-- )
-		{
-			gGL.color4fv(outer_color.mV);
-			gGL.vertex2f( x1, y1 );
-			gGL.color4fv(inner_color.mV);
-			gGL.vertex2f( x2, y2 );
-
-			F32 x1_new = x1 * COS_DELTA - y1 * SIN_DELTA;
-			y1 = x1 * SIN_DELTA +  y1 * COS_DELTA;
-			x1 = x1_new;
-
-			F32 x2_new = x2 * COS_DELTA - y2 * SIN_DELTA;
-			y2 = x2 * SIN_DELTA +  y2 * COS_DELTA;
-			x2 = x2_new;
-		}
-	}
-	gGL.end();
-}
-
-void gl_rect_2d_simple_tex( S32 width, S32 height )
-{
-	gGL.begin( LLRender::QUADS );
-
-		gGL.texCoord2f(1.f, 1.f);
-		gGL.vertex2i(width, height);
-
-		gGL.texCoord2f(0.f, 1.f);
-		gGL.vertex2i(0, height);
-
-		gGL.texCoord2f(0.f, 0.f);
-		gGL.vertex2i(0, 0);
-
-		gGL.texCoord2f(1.f, 0.f);
-		gGL.vertex2i(width, 0);
-	
-	gGL.end();
-}
-
-void gl_rect_2d_simple( S32 width, S32 height )
-{
-	gGL.begin( LLRender::QUADS );
-		gGL.vertex2i(width, height);
-		gGL.vertex2i(0, height);
-		gGL.vertex2i(0, 0);
-		gGL.vertex2i(width, 0);
-	gGL.end();
-}
-
-void gl_segmented_rect_2d_tex(const S32 left, 
-							  const S32 top, 
-							  const S32 right, 
-							  const S32 bottom, 
-							  const S32 texture_width, 
-							  const S32 texture_height, 
-							  const S32 border_size, 
-							  const U32 edges)
-{
-	S32 width = llabs(right - left);
-	S32 height = llabs(top - bottom);
-
-	gGL.pushUIMatrix();
-
-	gGL.translateUI((F32)left, (F32)bottom, 0.f);
-	LLVector2 border_uv_scale((F32)border_size / (F32)texture_width, (F32)border_size / (F32)texture_height);
-
-	if (border_uv_scale.mV[VX] > 0.5f)
-	{
-		border_uv_scale *= 0.5f / border_uv_scale.mV[VX];
-	}
-	if (border_uv_scale.mV[VY] > 0.5f)
-	{
-		border_uv_scale *= 0.5f / border_uv_scale.mV[VY];
-	}
-
-	F32 border_scale = llmin((F32)border_size, (F32)width * 0.5f, (F32)height * 0.5f);
-	LLVector2 border_width_left = ((edges & (~(U32)ROUNDED_RECT_RIGHT)) != 0) ? LLVector2(border_scale, 0.f) : LLVector2::zero;
-	LLVector2 border_width_right = ((edges & (~(U32)ROUNDED_RECT_LEFT)) != 0) ? LLVector2(border_scale, 0.f) : LLVector2::zero;
-	LLVector2 border_height_bottom = ((edges & (~(U32)ROUNDED_RECT_TOP)) != 0) ? LLVector2(0.f, border_scale) : LLVector2::zero;
-	LLVector2 border_height_top = ((edges & (~(U32)ROUNDED_RECT_BOTTOM)) != 0) ? LLVector2(0.f, border_scale) : LLVector2::zero;
-	LLVector2 width_vec((F32)width, 0.f);
-	LLVector2 height_vec(0.f, (F32)height);
-
-	gGL.begin(LLRender::QUADS);
-	{
-		// draw bottom left
-		gGL.texCoord2f(0.f, 0.f);
-		gGL.vertex2f(0.f, 0.f);
-
-		gGL.texCoord2f(border_uv_scale.mV[VX], 0.f);
-		gGL.vertex2fv(border_width_left.mV);
-
-		gGL.texCoord2f(border_uv_scale.mV[VX], border_uv_scale.mV[VY]);
-		gGL.vertex2fv((border_width_left + border_height_bottom).mV);
-
-		gGL.texCoord2f(0.f, border_uv_scale.mV[VY]);
-		gGL.vertex2fv(border_height_bottom.mV);
-
-		// draw bottom middle
-		gGL.texCoord2f(border_uv_scale.mV[VX], 0.f);
-		gGL.vertex2fv(border_width_left.mV);
-
-		gGL.texCoord2f(1.f - border_uv_scale.mV[VX], 0.f);
-		gGL.vertex2fv((width_vec - border_width_right).mV);
-
-		gGL.texCoord2f(1.f - border_uv_scale.mV[VX], border_uv_scale.mV[VY]);
-		gGL.vertex2fv((width_vec - border_width_right + border_height_bottom).mV);
-
-		gGL.texCoord2f(border_uv_scale.mV[VX], border_uv_scale.mV[VY]);
-		gGL.vertex2fv((border_width_left + border_height_bottom).mV);
-
-		// draw bottom right
-		gGL.texCoord2f(1.f - border_uv_scale.mV[VX], 0.f);
-		gGL.vertex2fv((width_vec - border_width_right).mV);
-
-		gGL.texCoord2f(1.f, 0.f);
-		gGL.vertex2fv(width_vec.mV);
-
-		gGL.texCoord2f(1.f, border_uv_scale.mV[VY]);
-		gGL.vertex2fv((width_vec + border_height_bottom).mV);
-
-		gGL.texCoord2f(1.f - border_uv_scale.mV[VX], border_uv_scale.mV[VY]);
-		gGL.vertex2fv((width_vec - border_width_right + border_height_bottom).mV);
-
-		// draw left 
-		gGL.texCoord2f(0.f, border_uv_scale.mV[VY]);
-		gGL.vertex2fv(border_height_bottom.mV);
-
-		gGL.texCoord2f(border_uv_scale.mV[VX], border_uv_scale.mV[VY]);
-		gGL.vertex2fv((border_width_left + border_height_bottom).mV);
-
-		gGL.texCoord2f(border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]);
-		gGL.vertex2fv((border_width_left + height_vec - border_height_top).mV);
-
-		gGL.texCoord2f(0.f, 1.f - border_uv_scale.mV[VY]);
-		gGL.vertex2fv((height_vec - border_height_top).mV);
-
-		// draw middle
-		gGL.texCoord2f(border_uv_scale.mV[VX], border_uv_scale.mV[VY]);
-		gGL.vertex2fv((border_width_left + border_height_bottom).mV);
-
-		gGL.texCoord2f(1.f - border_uv_scale.mV[VX], border_uv_scale.mV[VY]);
-		gGL.vertex2fv((width_vec - border_width_right + border_height_bottom).mV);
-
-		gGL.texCoord2f(1.f - border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]);
-		gGL.vertex2fv((width_vec - border_width_right + height_vec - border_height_top).mV);
-
-		gGL.texCoord2f(border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]);
-		gGL.vertex2fv((border_width_left + height_vec - border_height_top).mV);
-
-		// draw right 
-		gGL.texCoord2f(1.f - border_uv_scale.mV[VX], border_uv_scale.mV[VY]);
-		gGL.vertex2fv((width_vec - border_width_right + border_height_bottom).mV);
-
-		gGL.texCoord2f(1.f, border_uv_scale.mV[VY]);
-		gGL.vertex2fv((width_vec + border_height_bottom).mV);
-
-		gGL.texCoord2f(1.f, 1.f - border_uv_scale.mV[VY]);
-		gGL.vertex2fv((width_vec + height_vec - border_height_top).mV);
-
-		gGL.texCoord2f(1.f - border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]);
-		gGL.vertex2fv((width_vec - border_width_right + height_vec - border_height_top).mV);
-
-		// draw top left
-		gGL.texCoord2f(0.f, 1.f - border_uv_scale.mV[VY]);
-		gGL.vertex2fv((height_vec - border_height_top).mV);
-
-		gGL.texCoord2f(border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]);
-		gGL.vertex2fv((border_width_left + height_vec - border_height_top).mV);
-
-		gGL.texCoord2f(border_uv_scale.mV[VX], 1.f);
-		gGL.vertex2fv((border_width_left + height_vec).mV);
-
-		gGL.texCoord2f(0.f, 1.f);
-		gGL.vertex2fv((height_vec).mV);
-
-		// draw top middle
-		gGL.texCoord2f(border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]);
-		gGL.vertex2fv((border_width_left + height_vec - border_height_top).mV);
-
-		gGL.texCoord2f(1.f - border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]);
-		gGL.vertex2fv((width_vec - border_width_right + height_vec - border_height_top).mV);
-
-		gGL.texCoord2f(1.f - border_uv_scale.mV[VX], 1.f);
-		gGL.vertex2fv((width_vec - border_width_right + height_vec).mV);
-
-		gGL.texCoord2f(border_uv_scale.mV[VX], 1.f);
-		gGL.vertex2fv((border_width_left + height_vec).mV);
-
-		// draw top right
-		gGL.texCoord2f(1.f - border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]);
-		gGL.vertex2fv((width_vec - border_width_right + height_vec - border_height_top).mV);
-
-		gGL.texCoord2f(1.f, 1.f - border_uv_scale.mV[VY]);
-		gGL.vertex2fv((width_vec + height_vec - border_height_top).mV);
-
-		gGL.texCoord2f(1.f, 1.f);
-		gGL.vertex2fv((width_vec + height_vec).mV);
-
-		gGL.texCoord2f(1.f - border_uv_scale.mV[VX], 1.f);
-		gGL.vertex2fv((width_vec - border_width_right + height_vec).mV);
-	}
-	gGL.end();
-
-	gGL.popUIMatrix();
-}
-
-//FIXME: rewrite to use scissor?
-void gl_segmented_rect_2d_fragment_tex(const S32 left, 
-									   const S32 top, 
-									   const S32 right, 
-									   const S32 bottom, 
-									   const S32 texture_width, 
-									   const S32 texture_height, 
-									   const S32 border_size, 
-									   const F32 start_fragment, 
-									   const F32 end_fragment, 
-									   const U32 edges)
-{
-	S32 width = llabs(right - left);
-	S32 height = llabs(top - bottom);
-
-	gGL.pushUIMatrix();
-
-	gGL.translateUI((F32)left, (F32)bottom, 0.f);
-	LLVector2 border_uv_scale((F32)border_size / (F32)texture_width, (F32)border_size / (F32)texture_height);
-
-	if (border_uv_scale.mV[VX] > 0.5f)
-	{
-		border_uv_scale *= 0.5f / border_uv_scale.mV[VX];
-	}
-	if (border_uv_scale.mV[VY] > 0.5f)
-	{
-		border_uv_scale *= 0.5f / border_uv_scale.mV[VY];
-	}
-
-	F32 border_scale = llmin((F32)border_size, (F32)width * 0.5f, (F32)height * 0.5f);
-	LLVector2 border_width_left = ((edges & (~(U32)ROUNDED_RECT_RIGHT)) != 0) ? LLVector2(border_scale, 0.f) : LLVector2::zero;
-	LLVector2 border_width_right = ((edges & (~(U32)ROUNDED_RECT_LEFT)) != 0) ? LLVector2(border_scale, 0.f) : LLVector2::zero;
-	LLVector2 border_height_bottom = ((edges & (~(U32)ROUNDED_RECT_TOP)) != 0) ? LLVector2(0.f, border_scale) : LLVector2::zero;
-	LLVector2 border_height_top = ((edges & (~(U32)ROUNDED_RECT_BOTTOM)) != 0) ? LLVector2(0.f, border_scale) : LLVector2::zero;
-	LLVector2 width_vec((F32)width, 0.f);
-	LLVector2 height_vec(0.f, (F32)height);
-
-	F32 middle_start = border_scale / (F32)width;
-	F32 middle_end = 1.f - middle_start;
-
-	F32 u_min;
-	F32 u_max;
-	LLVector2 x_min;
-	LLVector2 x_max;
-
-	gGL.begin(LLRender::QUADS);
-	{
-		if (start_fragment < middle_start)
-		{
-			u_min = (start_fragment / middle_start) * border_uv_scale.mV[VX];
-			u_max = llmin(end_fragment / middle_start, 1.f) * border_uv_scale.mV[VX];
-			x_min = (start_fragment / middle_start) * border_width_left;
-			x_max = llmin(end_fragment / middle_start, 1.f) * border_width_left;
-
-			// draw bottom left
-			gGL.texCoord2f(u_min, 0.f);
-			gGL.vertex2fv(x_min.mV);
-
-			gGL.texCoord2f(border_uv_scale.mV[VX], 0.f);
-			gGL.vertex2fv(x_max.mV);
-
-			gGL.texCoord2f(u_max, border_uv_scale.mV[VY]);
-			gGL.vertex2fv((x_max + border_height_bottom).mV);
-
-			gGL.texCoord2f(u_min, border_uv_scale.mV[VY]);
-			gGL.vertex2fv((x_min + border_height_bottom).mV);
-
-			// draw left 
-			gGL.texCoord2f(u_min, border_uv_scale.mV[VY]);
-			gGL.vertex2fv((x_min + border_height_bottom).mV);
-
-			gGL.texCoord2f(u_max, border_uv_scale.mV[VY]);
-			gGL.vertex2fv((x_max + border_height_bottom).mV);
-
-			gGL.texCoord2f(u_max, 1.f - border_uv_scale.mV[VY]);
-			gGL.vertex2fv((x_max + height_vec - border_height_top).mV);
-
-			gGL.texCoord2f(u_min, 1.f - border_uv_scale.mV[VY]);
-			gGL.vertex2fv((x_min + height_vec - border_height_top).mV);
-			
-			// draw top left
-			gGL.texCoord2f(u_min, 1.f - border_uv_scale.mV[VY]);
-			gGL.vertex2fv((x_min + height_vec - border_height_top).mV);
-
-			gGL.texCoord2f(u_max, 1.f - border_uv_scale.mV[VY]);
-			gGL.vertex2fv((x_max + height_vec - border_height_top).mV);
-
-			gGL.texCoord2f(u_max, 1.f);
-			gGL.vertex2fv((x_max + height_vec).mV);
-
-			gGL.texCoord2f(u_min, 1.f);
-			gGL.vertex2fv((x_min + height_vec).mV);
-		}
-
-		if (end_fragment > middle_start || start_fragment < middle_end)
-		{
-			x_min = border_width_left + ((llclamp(start_fragment, middle_start, middle_end) - middle_start)) * width_vec;
-			x_max = border_width_left + ((llclamp(end_fragment, middle_start, middle_end) - middle_start)) * width_vec;
-
-			// draw bottom middle
-			gGL.texCoord2f(border_uv_scale.mV[VX], 0.f);
-			gGL.vertex2fv(x_min.mV);
-
-			gGL.texCoord2f(1.f - border_uv_scale.mV[VX], 0.f);
-			gGL.vertex2fv((x_max).mV);
-
-			gGL.texCoord2f(1.f - border_uv_scale.mV[VX], border_uv_scale.mV[VY]);
-			gGL.vertex2fv((x_max + border_height_bottom).mV);
-
-			gGL.texCoord2f(border_uv_scale.mV[VX], border_uv_scale.mV[VY]);
-			gGL.vertex2fv((x_min + border_height_bottom).mV);
-
-			// draw middle
-			gGL.texCoord2f(border_uv_scale.mV[VX], border_uv_scale.mV[VY]);
-			gGL.vertex2fv((x_min + border_height_bottom).mV);
-
-			gGL.texCoord2f(1.f - border_uv_scale.mV[VX], border_uv_scale.mV[VY]);
-			gGL.vertex2fv((x_max + border_height_bottom).mV);
-
-			gGL.texCoord2f(1.f - border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]);
-			gGL.vertex2fv((x_max + height_vec - border_height_top).mV);
-
-			gGL.texCoord2f(border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]);
-			gGL.vertex2fv((x_min + height_vec - border_height_top).mV);
-
-			// draw top middle
-			gGL.texCoord2f(border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]);
-			gGL.vertex2fv((x_min + height_vec - border_height_top).mV);
-
-			gGL.texCoord2f(1.f - border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]);
-			gGL.vertex2fv((x_max + height_vec - border_height_top).mV);
-
-			gGL.texCoord2f(1.f - border_uv_scale.mV[VX], 1.f);
-			gGL.vertex2fv((x_max + height_vec).mV);
-
-			gGL.texCoord2f(border_uv_scale.mV[VX], 1.f);
-			gGL.vertex2fv((x_min + height_vec).mV);
-		}
-
-		if (end_fragment > middle_end)
-		{
-			u_min = (1.f - llmax(0.f, ((start_fragment - middle_end) / middle_start))) * border_uv_scale.mV[VX];
-			u_max = (1.f - ((end_fragment - middle_end) / middle_start)) * border_uv_scale.mV[VX];
-			x_min = width_vec - ((1.f - llmax(0.f, ((start_fragment - middle_end) / middle_start))) * border_width_right);
-			x_max = width_vec - ((1.f - ((end_fragment - middle_end) / middle_start)) * border_width_right);
-
-			// draw bottom right
-			gGL.texCoord2f(u_min, 0.f);
-			gGL.vertex2fv((x_min).mV);
-
-			gGL.texCoord2f(u_max, 0.f);
-			gGL.vertex2fv(x_max.mV);
-
-			gGL.texCoord2f(u_max, border_uv_scale.mV[VY]);
-			gGL.vertex2fv((x_max + border_height_bottom).mV);
-
-			gGL.texCoord2f(u_min, border_uv_scale.mV[VY]);
-			gGL.vertex2fv((x_min + border_height_bottom).mV);
-
-			// draw right 
-			gGL.texCoord2f(u_min, border_uv_scale.mV[VY]);
-			gGL.vertex2fv((x_min + border_height_bottom).mV);
-
-			gGL.texCoord2f(u_max, border_uv_scale.mV[VY]);
-			gGL.vertex2fv((x_max + border_height_bottom).mV);
-
-			gGL.texCoord2f(u_max, 1.f - border_uv_scale.mV[VY]);
-			gGL.vertex2fv((x_max + height_vec - border_height_top).mV);
-
-			gGL.texCoord2f(u_min, 1.f - border_uv_scale.mV[VY]);
-			gGL.vertex2fv((x_min + height_vec - border_height_top).mV);
-
-			// draw top right
-			gGL.texCoord2f(u_min, 1.f - border_uv_scale.mV[VY]);
-			gGL.vertex2fv((x_min + height_vec - border_height_top).mV);
-
-			gGL.texCoord2f(u_max, 1.f - border_uv_scale.mV[VY]);
-			gGL.vertex2fv((x_max + height_vec - border_height_top).mV);
-
-			gGL.texCoord2f(u_max, 1.f);
-			gGL.vertex2fv((x_max + height_vec).mV);
-
-			gGL.texCoord2f(u_min, 1.f);
-			gGL.vertex2fv((x_min + height_vec).mV);
-		}
-	}
-	gGL.end();
-
-	gGL.popUIMatrix();
-}
-
-void gl_segmented_rect_3d_tex(const LLVector2& border_scale, const LLVector3& border_width, 
-							  const LLVector3& border_height, const LLVector3& width_vec, const LLVector3& height_vec,
-							  const U32 edges)
-{
-	LLVector3 left_border_width = ((edges & (~(U32)ROUNDED_RECT_RIGHT)) != 0) ? border_width : LLVector3::zero;
-	LLVector3 right_border_width = ((edges & (~(U32)ROUNDED_RECT_LEFT)) != 0) ? border_width : LLVector3::zero;
-
-	LLVector3 top_border_height = ((edges & (~(U32)ROUNDED_RECT_BOTTOM)) != 0) ? border_height : LLVector3::zero;
-	LLVector3 bottom_border_height = ((edges & (~(U32)ROUNDED_RECT_TOP)) != 0) ? border_height : LLVector3::zero;
-
-
-	gGL.begin(LLRender::QUADS);
-	{
-		// draw bottom left
-		gGL.texCoord2f(0.f, 0.f);
-		gGL.vertex3f(0.f, 0.f, 0.f);
-
-		gGL.texCoord2f(border_scale.mV[VX], 0.f);
-		gGL.vertex3fv(left_border_width.mV);
-
-		gGL.texCoord2f(border_scale.mV[VX], border_scale.mV[VY]);
-		gGL.vertex3fv((left_border_width + bottom_border_height).mV);
-
-		gGL.texCoord2f(0.f, border_scale.mV[VY]);
-		gGL.vertex3fv(bottom_border_height.mV);
-
-		// draw bottom middle
-		gGL.texCoord2f(border_scale.mV[VX], 0.f);
-		gGL.vertex3fv(left_border_width.mV);
-
-		gGL.texCoord2f(1.f - border_scale.mV[VX], 0.f);
-		gGL.vertex3fv((width_vec - right_border_width).mV);
-
-		gGL.texCoord2f(1.f - border_scale.mV[VX], border_scale.mV[VY]);
-		gGL.vertex3fv((width_vec - right_border_width + bottom_border_height).mV);
-
-		gGL.texCoord2f(border_scale.mV[VX], border_scale.mV[VY]);
-		gGL.vertex3fv((left_border_width + bottom_border_height).mV);
-
-		// draw bottom right
-		gGL.texCoord2f(1.f - border_scale.mV[VX], 0.f);
-		gGL.vertex3fv((width_vec - right_border_width).mV);
-
-		gGL.texCoord2f(1.f, 0.f);
-		gGL.vertex3fv(width_vec.mV);
-
-		gGL.texCoord2f(1.f, border_scale.mV[VY]);
-		gGL.vertex3fv((width_vec + bottom_border_height).mV);
-
-		gGL.texCoord2f(1.f - border_scale.mV[VX], border_scale.mV[VY]);
-		gGL.vertex3fv((width_vec - right_border_width + bottom_border_height).mV);
-
-		// draw left 
-		gGL.texCoord2f(0.f, border_scale.mV[VY]);
-		gGL.vertex3fv(bottom_border_height.mV);
-
-		gGL.texCoord2f(border_scale.mV[VX], border_scale.mV[VY]);
-		gGL.vertex3fv((left_border_width + bottom_border_height).mV);
-
-		gGL.texCoord2f(border_scale.mV[VX], 1.f - border_scale.mV[VY]);
-		gGL.vertex3fv((left_border_width + height_vec - top_border_height).mV);
-
-		gGL.texCoord2f(0.f, 1.f - border_scale.mV[VY]);
-		gGL.vertex3fv((height_vec - top_border_height).mV);
-
-		// draw middle
-		gGL.texCoord2f(border_scale.mV[VX], border_scale.mV[VY]);
-		gGL.vertex3fv((left_border_width + bottom_border_height).mV);
-
-		gGL.texCoord2f(1.f - border_scale.mV[VX], border_scale.mV[VY]);
-		gGL.vertex3fv((width_vec - right_border_width + bottom_border_height).mV);
-
-		gGL.texCoord2f(1.f - border_scale.mV[VX], 1.f - border_scale.mV[VY]);
-		gGL.vertex3fv((width_vec - right_border_width + height_vec - top_border_height).mV);
-
-		gGL.texCoord2f(border_scale.mV[VX], 1.f - border_scale.mV[VY]);
-		gGL.vertex3fv((left_border_width + height_vec - top_border_height).mV);
-
-		// draw right 
-		gGL.texCoord2f(1.f - border_scale.mV[VX], border_scale.mV[VY]);
-		gGL.vertex3fv((width_vec - right_border_width + bottom_border_height).mV);
-
-		gGL.texCoord2f(1.f, border_scale.mV[VY]);
-		gGL.vertex3fv((width_vec + bottom_border_height).mV);
-
-		gGL.texCoord2f(1.f, 1.f - border_scale.mV[VY]);
-		gGL.vertex3fv((width_vec + height_vec - top_border_height).mV);
-
-		gGL.texCoord2f(1.f - border_scale.mV[VX], 1.f - border_scale.mV[VY]);
-		gGL.vertex3fv((width_vec - right_border_width + height_vec - top_border_height).mV);
-
-		// draw top left
-		gGL.texCoord2f(0.f, 1.f - border_scale.mV[VY]);
-		gGL.vertex3fv((height_vec - top_border_height).mV);
-
-		gGL.texCoord2f(border_scale.mV[VX], 1.f - border_scale.mV[VY]);
-		gGL.vertex3fv((left_border_width + height_vec - top_border_height).mV);
-
-		gGL.texCoord2f(border_scale.mV[VX], 1.f);
-		gGL.vertex3fv((left_border_width + height_vec).mV);
-
-		gGL.texCoord2f(0.f, 1.f);
-		gGL.vertex3fv((height_vec).mV);
-
-		// draw top middle
-		gGL.texCoord2f(border_scale.mV[VX], 1.f - border_scale.mV[VY]);
-		gGL.vertex3fv((left_border_width + height_vec - top_border_height).mV);
-
-		gGL.texCoord2f(1.f - border_scale.mV[VX], 1.f - border_scale.mV[VY]);
-		gGL.vertex3fv((width_vec - right_border_width + height_vec - top_border_height).mV);
-
-		gGL.texCoord2f(1.f - border_scale.mV[VX], 1.f);
-		gGL.vertex3fv((width_vec - right_border_width + height_vec).mV);
-
-		gGL.texCoord2f(border_scale.mV[VX], 1.f);
-		gGL.vertex3fv((left_border_width + height_vec).mV);
-
-		// draw top right
-		gGL.texCoord2f(1.f - border_scale.mV[VX], 1.f - border_scale.mV[VY]);
-		gGL.vertex3fv((width_vec - right_border_width + height_vec - top_border_height).mV);
-
-		gGL.texCoord2f(1.f, 1.f - border_scale.mV[VY]);
-		gGL.vertex3fv((width_vec + height_vec - top_border_height).mV);
-
-		gGL.texCoord2f(1.f, 1.f);
-		gGL.vertex3fv((width_vec + height_vec).mV);
-
-		gGL.texCoord2f(1.f - border_scale.mV[VX], 1.f);
-		gGL.vertex3fv((width_vec - right_border_width + height_vec).mV);
-	}
-	gGL.end();
-
-}
-
-void gl_segmented_rect_3d_tex_top(const LLVector2& border_scale, const LLVector3& border_width, const LLVector3& border_height, const LLVector3& width_vec, const LLVector3& height_vec)
-{
-	gl_segmented_rect_3d_tex(border_scale, border_width, border_height, width_vec, height_vec, ROUNDED_RECT_TOP);
-}
-
 void LLUI::initClass(const settings_map_t& settings,
 					 LLImageProviderInterface* image_provider,
 					 LLUIAudioCallback audio_callback,
 					 const LLVector2* scale_factor,
 					 const std::string& language)
 {
+	LLRender2D::initClass(image_provider, scale_factor);
 	sSettingGroups = settings;
 
 	if ((get_ptr_in_map(sSettingGroups, std::string("config")) == NULL) ||
@@ -1632,9 +151,7 @@ void LLUI::initClass(const settings_map_t& settings,
 		llerrs << "Failure to initialize configuration groups" << llendl;
 	}
 
-	sImageProvider = image_provider;
 	sAudioCallback = audio_callback;
-	sGLScaleFactor = (scale_factor == NULL) ? LLVector2(1.f, 1.f) : *scale_factor;
 	sWindow = NULL; // set later in startup
 	LLFontGL::sShadowColor = LLUIColorTable::instance().getColor("ColorDropShadow");
 
@@ -1668,10 +185,7 @@ void LLUI::initClass(const settings_map_t& settings,
 
 void LLUI::cleanupClass()
 {
-	if(sImageProvider)
-	{
-	sImageProvider->cleanUp();
-}
+	LLRender2D::cleanupClass();
 }
 
 void LLUI::setPopupFuncs(const add_popup_t& add_popup, const remove_popup_t& remove_popup,  const clear_popups_t& clear_popups)
@@ -1695,60 +209,12 @@ void LLUI::dirtyRect(LLRect rect)
 	}		
 }
  
-
-//static
-void LLUI::translate(F32 x, F32 y, F32 z)
-{
-	gGL.translateUI(x,y,z);
-	LLFontGL::sCurOrigin.mX += (S32) x;
-	LLFontGL::sCurOrigin.mY += (S32) y;
-	LLFontGL::sCurDepth += z;
-}
-
-//static
-void LLUI::pushMatrix()
-{
-	gGL.pushUIMatrix();
-	LLFontGL::sOriginStack.push_back(std::make_pair(LLFontGL::sCurOrigin, LLFontGL::sCurDepth));
-}
-
-//static
-void LLUI::popMatrix()
-{
-	gGL.popUIMatrix();
-	LLFontGL::sCurOrigin = LLFontGL::sOriginStack.back().first;
-	LLFontGL::sCurDepth = LLFontGL::sOriginStack.back().second;
-	LLFontGL::sOriginStack.pop_back();
-}
-
-//static 
-void LLUI::loadIdentity()
-{
-	gGL.loadUIIdentity(); 
-	LLFontGL::sCurOrigin.mX = 0;
-	LLFontGL::sCurOrigin.mY = 0;
-	LLFontGL::sCurDepth = 0.f;
-}
-
-//static
-void LLUI::setScaleFactor(const LLVector2 &scale_factor)
-{
-	sGLScaleFactor = scale_factor;
-}
-
-//static
-void LLUI::setLineWidth(F32 width)
-{
-	gGL.flush();
-	glLineWidth(width * lerp(sGLScaleFactor.mV[VX], sGLScaleFactor.mV[VY], 0.5f));
-}
-
 //static 
 void LLUI::setMousePositionScreen(S32 x, S32 y)
 {
 	S32 screen_x, screen_y;
-	screen_x = llround((F32)x * sGLScaleFactor.mV[VX]);
-	screen_y = llround((F32)y * sGLScaleFactor.mV[VY]);
+	screen_x = llround((F32)x * getScaleFactor().mV[VX]);
+	screen_y = llround((F32)y * getScaleFactor().mV[VY]);
 	
 	LLView::getWindow()->setCursorPosition(LLCoordGL(screen_x, screen_y).convert());
 }
@@ -1759,8 +225,8 @@ void LLUI::getMousePositionScreen(S32 *x, S32 *y)
 	LLCoordWindow cursor_pos_window;
 	getWindow()->getCursorPosition(&cursor_pos_window);
 	LLCoordGL cursor_pos_gl(cursor_pos_window.convert());
-	*x = llround((F32)cursor_pos_gl.mX / sGLScaleFactor.mV[VX]);
-	*y = llround((F32)cursor_pos_gl.mY / sGLScaleFactor.mV[VX]);
+	*x = llround((F32)cursor_pos_gl.mX / getScaleFactor().mV[VX]);
+	*y = llround((F32)cursor_pos_gl.mY / getScaleFactor().mV[VX]);
 }
 
 //static 
@@ -1925,21 +391,21 @@ LLVector2 LLUI::getWindowSize()
 	LLCoordWindow window_rect;
 	sWindow->getSize(&window_rect);
 
-	return LLVector2(window_rect.mX / sGLScaleFactor.mV[VX], window_rect.mY / sGLScaleFactor.mV[VY]);
+	return LLVector2(window_rect.mX / getScaleFactor().mV[VX], window_rect.mY / getScaleFactor().mV[VY]);
 }
 
 //static
 void LLUI::screenPointToGL(S32 screen_x, S32 screen_y, S32 *gl_x, S32 *gl_y)
 {
-	*gl_x = llround((F32)screen_x * sGLScaleFactor.mV[VX]);
-	*gl_y = llround((F32)screen_y * sGLScaleFactor.mV[VY]);
+	*gl_x = llround((F32)screen_x * getScaleFactor().mV[VX]);
+	*gl_y = llround((F32)screen_y * getScaleFactor().mV[VY]);
 }
 
 //static
 void LLUI::glPointToScreen(S32 gl_x, S32 gl_y, S32 *screen_x, S32 *screen_y)
 {
-	*screen_x = llround((F32)gl_x / sGLScaleFactor.mV[VX]);
-	*screen_y = llround((F32)gl_y / sGLScaleFactor.mV[VY]);
+	*screen_x = llround((F32)gl_x / getScaleFactor().mV[VX]);
+	*screen_y = llround((F32)gl_y / getScaleFactor().mV[VY]);
 }
 
 //static
@@ -1956,27 +422,6 @@ void LLUI::glRectToScreen(const LLRect& gl, LLRect *screen)
 	glPointToScreen(gl.mRight, gl.mBottom, &screen->mRight, &screen->mBottom);
 }
 
-//static
-LLPointer<LLUIImage> LLUI::getUIImageByID(const LLUUID& image_id, S32 priority)
-{
-	if (sImageProvider)
-	{
-		return sImageProvider->getUIImageByID(image_id, priority);
-	}
-	else
-	{
-		return NULL;
-	}
-}
-
-//static 
-LLPointer<LLUIImage> LLUI::getUIImage(const std::string& name, S32 priority)
-{
-	if (!name.empty() && sImageProvider)
-		return sImageProvider->getUIImage(name, priority);
-	else
-		return NULL;
-}
 
 LLControlGroup& LLUI::getControlControlGroup (const std::string& controlname)
 {
diff --git a/indra/llui/llui.h b/indra/llui/llui.h
index 28e84fa44410e55174ea478d1600f1786cc631c3..a38ae9a560332a1189fc0df9d0e8009b451eaa04 100644
--- a/indra/llui/llui.h
+++ b/indra/llui/llui.h
@@ -1,6 +1,6 @@
 /** 
  * @file llui.h
- * @brief GL function declarations and other general static UI services.
+ * @brief General static UI services.
  *
  * $LicenseInfo:firstyear=2001&license=viewerlgpl$
  * Second Life Viewer Source Code
@@ -24,122 +24,37 @@
  * $/LicenseInfo$
  */
 
-// All immediate-mode gl drawing should happen here.
 
 #ifndef LL_LLUI_H
 #define LL_LLUI_H
 
-#include "llpointer.h"		// LLPointer<>
 #include "llrect.h"
 #include "llcontrol.h"
 #include "llcoord.h"
-#include "llglslshader.h"
+#include "v2math.h"
 #include "llinitparam.h"
 #include "llregistry.h"
+#include "llrender2dutils.h"
+#include "llpointer.h"
 #include "lluicolor.h"
 #include "lluicolortable.h"
+#include "lluiimage.h"
 #include <boost/signals2.hpp>
 #include "lllazyvalue.h"
 #include "llframetimer.h"
 #include <limits>
 
-// LLUIFactory
-#include "llsd.h"
-
 // for initparam specialization
 #include "llfontgl.h"
 
 
-class LLColor4; 
-class LLVector3;
-class LLVector2;
-class LLUIImage;
 class LLUUID;
 class LLWindow;
 class LLView;
 class LLHelp;
 
-// UI colors
-extern const LLColor4 UI_VERTEX_COLOR;
 void make_ui_sound(const char* name);
 
-BOOL ui_point_in_rect(S32 x, S32 y, S32 left, S32 top, S32 right, S32 bottom);
-void gl_state_for_2d(S32 width, S32 height);
-
-void gl_line_2d(S32 x1, S32 y1, S32 x2, S32 y2);
-void gl_line_2d(S32 x1, S32 y1, S32 x2, S32 y2, const LLColor4 &color );
-void gl_triangle_2d(S32 x1, S32 y1, S32 x2, S32 y2, S32 x3, S32 y3, const LLColor4& color, BOOL filled);
-void gl_rect_2d_simple( S32 width, S32 height );
-
-void gl_draw_x(const LLRect& rect, const LLColor4& color);
-
-void gl_rect_2d(S32 left, S32 top, S32 right, S32 bottom, BOOL filled = TRUE );
-void gl_rect_2d(S32 left, S32 top, S32 right, S32 bottom, const LLColor4 &color, BOOL filled = TRUE );
-void gl_rect_2d_offset_local( S32 left, S32 top, S32 right, S32 bottom, const LLColor4 &color, S32 pixel_offset = 0, BOOL filled = TRUE );
-void gl_rect_2d_offset_local( S32 left, S32 top, S32 right, S32 bottom, S32 pixel_offset = 0, BOOL filled = TRUE );
-void gl_rect_2d(const LLRect& rect, BOOL filled = TRUE );
-void gl_rect_2d(const LLRect& rect, const LLColor4& color, BOOL filled = TRUE );
-void gl_rect_2d_checkerboard(const LLRect& rect, GLfloat alpha = 1.0f);
-
-void gl_drop_shadow(S32 left, S32 top, S32 right, S32 bottom, const LLColor4 &start_color, S32 lines);
-
-void gl_circle_2d(F32 x, F32 y, F32 radius, S32 steps, BOOL filled);
-void gl_arc_2d(F32 center_x, F32 center_y, F32 radius, S32 steps, BOOL filled, F32 start_angle, F32 end_angle);
-void gl_deep_circle( F32 radius, F32 depth );
-void gl_ring( F32 radius, F32 width, const LLColor4& center_color, const LLColor4& side_color, S32 steps, BOOL render_center );
-void gl_corners_2d(S32 left, S32 top, S32 right, S32 bottom, S32 length, F32 max_frac);
-void gl_washer_2d(F32 outer_radius, F32 inner_radius, S32 steps, const LLColor4& inner_color, const LLColor4& outer_color);
-void gl_washer_segment_2d(F32 outer_radius, F32 inner_radius, F32 start_radians, F32 end_radians, S32 steps, const LLColor4& inner_color, const LLColor4& outer_color);
-
-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_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_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));
-
-void gl_stippled_line_3d( const LLVector3& start, const LLVector3& end, const LLColor4& color, F32 phase = 0.f ); 
-
-void gl_rect_2d_simple_tex( S32 width, S32 height );
-
-// segmented rectangles
-
-/*
-   TL |______TOP_________| TR 
-     /|                  |\  
-   _/_|__________________|_\_
-   L| |    MIDDLE        | |R
-   _|_|__________________|_|_
-    \ |    BOTTOM        | /  
-   BL\|__________________|/ BR
-      |                  |    
-*/
-
-typedef enum e_rounded_edge
-{
-	ROUNDED_RECT_LEFT	= 0x1, 
-	ROUNDED_RECT_TOP	= 0x2, 
-	ROUNDED_RECT_RIGHT	= 0x4, 
-	ROUNDED_RECT_BOTTOM	= 0x8,
-	ROUNDED_RECT_ALL	= 0xf
-}ERoundedEdge;
-
-
-void gl_segmented_rect_2d_tex(const S32 left, const S32 top, const S32 right, const S32 bottom, const S32 texture_width, const S32 texture_height, const S32 border_size, const U32 edges = ROUNDED_RECT_ALL);
-void gl_segmented_rect_2d_fragment_tex(const S32 left, const S32 top, const S32 right, const S32 bottom, const S32 texture_width, const S32 texture_height, const S32 border_size, const F32 start_fragment, const F32 end_fragment, const U32 edges = ROUNDED_RECT_ALL);
-void gl_segmented_rect_3d_tex(const LLVector2& border_scale, const LLVector3& border_width, const LLVector3& border_height, const LLVector3& width_vec, const LLVector3& height_vec, U32 edges = ROUNDED_RECT_ALL);
-void gl_segmented_rect_3d_tex_top(const LLVector2& border_scale, const LLVector3& border_width, const LLVector3& border_height, const LLVector3& width_vec, const LLVector3& height_vec);
-
-inline void gl_rect_2d( const LLRect& rect, BOOL filled )
-{
-	gl_rect_2d( rect.mLeft, rect.mTop, rect.mRight, rect.mBottom, filled );
-}
-
-inline void gl_rect_2d_offset_local( const LLRect& rect, S32 pixel_offset, BOOL filled)
-{
-	gl_rect_2d_offset_local( rect.mLeft, rect.mTop, rect.mRight, rect.mBottom, pixel_offset, filled );
-}
-
 class LLImageProviderInterface;
 
 typedef	void (*LLUIAudioCallback)(const LLUUID& uuid);
@@ -280,10 +195,10 @@ public:
 	static void cleanupClass();
 	static void setPopupFuncs(const add_popup_t& add_popup, const remove_popup_t&, const clear_popups_t& );
 
-	static void pushMatrix();
-	static void popMatrix();
-	static void loadIdentity();
-	static void translate(F32 x, F32 y, F32 z = 0.0f);
+	static void pushMatrix() { LLRender2D::pushMatrix(); }
+	static void popMatrix() { LLRender2D::popMatrix(); }
+	static void loadIdentity() { LLRender2D::loadIdentity(); }
+	static void translate(F32 x, F32 y, F32 z = 0.0f) { LLRender2D::translate(x, y, z); }
 
 	static LLRect	sDirtyRect;
 	static BOOL		sDirty;
@@ -333,10 +248,13 @@ public:
 	static void getMousePositionScreen(S32 *x, S32 *y);
 	static void setMousePositionLocal(const LLView* viewp, S32 x, S32 y);
 	static void getMousePositionLocal(const LLView* viewp, S32 *x, S32 *y);
-	static void setScaleFactor(const LLVector2& scale_factor);
-	static void setLineWidth(F32 width);
-	static LLPointer<LLUIImage> getUIImageByID(const LLUUID& image_id, S32 priority = 0);
-	static LLPointer<LLUIImage> getUIImage(const std::string& name, S32 priority = 0);
+	static LLVector2& getScaleFactor() { return LLRender2D::sGLScaleFactor; }
+	static void setScaleFactor(const LLVector2& scale_factor) { LLRender2D::setScaleFactor(scale_factor); }
+	static void setLineWidth(F32 width) { LLRender2D::setLineWidth(width); }
+	static LLPointer<LLUIImage> getUIImageByID(const LLUUID& image_id, S32 priority = 0)
+		{ return LLRender2D::getUIImageByID(image_id, priority); }
+	static LLPointer<LLUIImage> getUIImage(const std::string& name, S32 priority = 0)
+		{ return LLRender2D::getUIImage(name, priority); }
 	static LLVector2 getWindowSize();
 	static void screenPointToGL(S32 screen_x, S32 screen_y, S32 *gl_x, S32 *gl_y);
 	static void glPointToScreen(S32 gl_x, S32 gl_y, S32 *screen_x, S32 *screen_y);
@@ -365,12 +283,10 @@ public:
 	//
 	static settings_map_t sSettingGroups;
 	static LLUIAudioCallback sAudioCallback;
-	static LLVector2		sGLScaleFactor;
 	static LLWindow*		sWindow;
 	static LLView*			sRootView;
 	static LLHelp*			sHelpImpl;
 private:
-	static LLImageProviderInterface* sImageProvider;
 	static std::vector<std::string> sXUIPaths;
 	static LLFrameTimer		sMouseIdleTimer;
 	static add_popup_t		sAddPopupFunc;
@@ -381,18 +297,6 @@ private:
 
 // Moved LLLocalClipRect to lllocalcliprect.h
 
-//RN: maybe this needs to moved elsewhere?
-class LLImageProviderInterface
-{
-protected:
-	LLImageProviderInterface() {};
-	virtual ~LLImageProviderInterface() {};
-public:
-	virtual LLPointer<LLUIImage> getUIImage(const std::string& name, S32 priority) = 0;
-	virtual LLPointer<LLUIImage> getUIImageByID(const LLUUID& id, S32 priority) = 0;
-	virtual void cleanUp() = 0;
-};
-
 class LLCallbackRegistry
 {
 public:
@@ -603,7 +507,4 @@ namespace LLInitParam
 	};
 }
 
-extern LLGLSLShader gSolidColorProgram;
-extern LLGLSLShader gUIProgram;
-
 #endif
diff --git a/indra/llui/tests/llurlentry_test.cpp b/indra/llui/tests/llurlentry_test.cpp
index 8f0a48018fb26132f0ca1b5257a1110850dce4d3..6c51024d2ca35734bc55f594848e32fb6457f615 100644
--- a/indra/llui/tests/llurlentry_test.cpp
+++ b/indra/llui/tests/llurlentry_test.cpp
@@ -31,7 +31,7 @@
 #include "llurlentry_stub.cpp"
 #include "lltut.h"
 #include "../lluicolortable.h"
-#include "../lluiimage.h"
+#include "lluiimage.h"
 
 #include <boost/regex.hpp>
 
diff --git a/indra/llui/tests/llurlmatch_test.cpp b/indra/llui/tests/llurlmatch_test.cpp
index 963473c92ab0d2f18c7bcb47a9ff7a7f1a793cf5..88a2cfb1e059b8a4c1cb6b6ecb8748b5156588fa 100644
--- a/indra/llui/tests/llurlmatch_test.cpp
+++ b/indra/llui/tests/llurlmatch_test.cpp
@@ -28,7 +28,7 @@
 #include "linden_common.h"
 
 #include "../llurlmatch.h"
-#include "../lluiimage.h"
+#include "lluiimage.h"
 #include "lltut.h"
 
 // link seams
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index 21b1512e582adf1b88f7db33d1f87e40a00ace4a..a17a3b11ec24ceee28e333f780473dff4d9b4009 100755
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -304,6 +304,7 @@ set(viewer_SOURCE_FILES
     llinventorybridge.cpp
     llinventoryfilter.cpp
     llinventoryfunctions.cpp
+    llinventoryicon.cpp
     llinventoryitemslist.cpp
     llinventorylistitem.cpp
     llinventorymodel.cpp
@@ -872,6 +873,7 @@ set(viewer_HEADER_FILES
     llinventorybridge.h
     llinventoryfilter.h
     llinventoryfunctions.h
+    llinventoryicon.h
     llinventoryitemslist.h
     llinventorylistitem.h
     llinventorymodel.h
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index 6ca77ba4dd536677ca3e9422ec7ff3bc36e39d55..fbf15ff5ce448803cf966c2fe65d2d5493dc1254 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -771,7 +771,7 @@ bool LLAppViewer::init()
 	LLUI::initClass(settings_map,
 		LLUIImageList::getInstance(),
 		ui_audio_callback,
-		&LLUI::sGLScaleFactor);
+		&LLUI::getScaleFactor());
 	LL_INFOS("InitInfo") << "UI initialized." << LL_ENDL ;
 
 	// Setup paths and LLTrans after LLUI::initClass has been called.
diff --git a/indra/newview/llfloaterbuycontents.cpp b/indra/newview/llfloaterbuycontents.cpp
index 809d344d0162a1bbcc9aa56c68967ed5f315476d..df802f0a0e2cca71515e78ae3fe8a793ddc8819b 100644
--- a/indra/newview/llfloaterbuycontents.cpp
+++ b/indra/newview/llfloaterbuycontents.cpp
@@ -40,6 +40,7 @@
 #include "llcheckboxctrl.h"
 #include "llinventorydefines.h"
 #include "llinventoryfunctions.h"
+#include "llinventoryicon.h"
 #include "llinventorymodel.h"	// for gInventory
 #include "llfirstuse.h"
 #include "llfloaterreg.h"
diff --git a/indra/newview/llglsandbox.cpp b/indra/newview/llglsandbox.cpp
index 1208c9378e9024f84582c879eed315a5b7f1c597..60fa53f491c1d94b9d6e2018a5a1e330f2eb4260 100644
--- a/indra/newview/llglsandbox.cpp
+++ b/indra/newview/llglsandbox.cpp
@@ -79,10 +79,10 @@ void LLToolSelectRect::handleRectangleSelection(S32 x, S32 y, MASK mask)
 	S32 top =	llmax(y, mDragStartY);
 	S32 bottom =llmin(y, mDragStartY);
 
-	left = llround((F32) left * LLUI::sGLScaleFactor.mV[VX]);
-	right = llround((F32) right * LLUI::sGLScaleFactor.mV[VX]);
-	top = llround((F32) top * LLUI::sGLScaleFactor.mV[VY]);
-	bottom = llround((F32) bottom * LLUI::sGLScaleFactor.mV[VY]);
+	left = llround((F32) left * LLUI::getScaleFactor().mV[VX]);
+	right = llround((F32) right * LLUI::getScaleFactor().mV[VX]);
+	top = llround((F32) top * LLUI::getScaleFactor().mV[VY]);
+	bottom = llround((F32) bottom * LLUI::getScaleFactor().mV[VY]);
 
 	F32 old_far_plane = LLViewerCamera::getInstance()->getFar();
 	F32 old_near_plane = LLViewerCamera::getInstance()->getNear();
diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp
index dc6147898a3f0505338147c61df750ebf6273812..4834d8dd705d8b3edf3dccd151237caf99a75677 100755
--- a/indra/newview/llinventorybridge.cpp
+++ b/indra/newview/llinventorybridge.cpp
@@ -50,6 +50,7 @@
 #include "llclipboard.h"
 #include "llinventorydefines.h"
 #include "llinventoryfunctions.h"
+#include "llinventoryicon.h"
 #include "llinventorymodel.h"
 #include "llinventorymodelbackgroundfetch.h"
 #include "llinventorypanel.h"
@@ -1510,7 +1511,7 @@ LLUIImagePtr LLItemBridge::getIcon() const
 										mIsLink);
 	}
 	
-	return LLInventoryIcon::getIcon(LLInventoryIcon::ICONNAME_OBJECT);
+	return LLInventoryIcon::getIcon(LLInventoryType::ICONNAME_OBJECT);
 }
 
 PermissionMask LLItemBridge::getPermissionMask() const
diff --git a/indra/llappearance/llinventoryicon.cpp b/indra/newview/llinventoryicon.cpp
similarity index 52%
rename from indra/llappearance/llinventoryicon.cpp
rename to indra/newview/llinventoryicon.cpp
index 371f60353b6ab718cf5b1eb1a89e8b8d2112e99f..14efc25fb968bc6992937ff524b1499d5eb87e27 100644
--- a/indra/llappearance/llinventoryicon.cpp
+++ b/indra/newview/llinventoryicon.cpp
@@ -41,7 +41,7 @@ struct IconEntry : public LLDictionaryEntry
 };
 
 class LLIconDictionary : public LLSingleton<LLIconDictionary>,
-						 public LLDictionary<LLInventoryIcon::EIconName, IconEntry>
+						 public LLDictionary<LLInventoryType::EIconName, IconEntry>
 {
 public:
 	LLIconDictionary();
@@ -49,48 +49,48 @@ public:
 
 LLIconDictionary::LLIconDictionary()
 {
-	addEntry(LLInventoryIcon::ICONNAME_TEXTURE, 				new IconEntry("Inv_Texture"));
-	addEntry(LLInventoryIcon::ICONNAME_SOUND, 					new IconEntry("Inv_Sound"));
-	addEntry(LLInventoryIcon::ICONNAME_CALLINGCARD_ONLINE, 		new IconEntry("Inv_CallingCard"));
-	addEntry(LLInventoryIcon::ICONNAME_CALLINGCARD_OFFLINE, 	new IconEntry("Inv_CallingCard"));
-	addEntry(LLInventoryIcon::ICONNAME_LANDMARK, 				new IconEntry("Inv_Landmark"));
-	addEntry(LLInventoryIcon::ICONNAME_LANDMARK_VISITED, 		new IconEntry("Inv_Landmark"));
-	addEntry(LLInventoryIcon::ICONNAME_SCRIPT, 					new IconEntry("Inv_Script"));
-	addEntry(LLInventoryIcon::ICONNAME_CLOTHING, 				new IconEntry("Inv_Clothing"));
-	addEntry(LLInventoryIcon::ICONNAME_OBJECT, 					new IconEntry("Inv_Object"));
-	addEntry(LLInventoryIcon::ICONNAME_OBJECT_MULTI, 			new IconEntry("Inv_Object_Multi"));
-	addEntry(LLInventoryIcon::ICONNAME_NOTECARD, 				new IconEntry("Inv_Notecard"));
-	addEntry(LLInventoryIcon::ICONNAME_BODYPART, 				new IconEntry("Inv_Skin"));
-	addEntry(LLInventoryIcon::ICONNAME_SNAPSHOT, 				new IconEntry("Inv_Snapshot"));
-
-	addEntry(LLInventoryIcon::ICONNAME_BODYPART_SHAPE, 			new IconEntry("Inv_BodyShape"));
-	addEntry(LLInventoryIcon::ICONNAME_BODYPART_SKIN, 			new IconEntry("Inv_Skin"));
-	addEntry(LLInventoryIcon::ICONNAME_BODYPART_HAIR, 			new IconEntry("Inv_Hair"));
-	addEntry(LLInventoryIcon::ICONNAME_BODYPART_EYES, 			new IconEntry("Inv_Eye"));
-
-	addEntry(LLInventoryIcon::ICONNAME_CLOTHING_SHIRT, 			new IconEntry("Inv_Shirt"));
-	addEntry(LLInventoryIcon::ICONNAME_CLOTHING_PANTS, 			new IconEntry("Inv_Pants"));
-	addEntry(LLInventoryIcon::ICONNAME_CLOTHING_SHOES, 			new IconEntry("Inv_Shoe"));
-	addEntry(LLInventoryIcon::ICONNAME_CLOTHING_SOCKS, 			new IconEntry("Inv_Socks"));
-	addEntry(LLInventoryIcon::ICONNAME_CLOTHING_JACKET, 		new IconEntry("Inv_Jacket"));
-	addEntry(LLInventoryIcon::ICONNAME_CLOTHING_GLOVES, 		new IconEntry("Inv_Gloves"));
-	addEntry(LLInventoryIcon::ICONNAME_CLOTHING_UNDERSHIRT, 	new IconEntry("Inv_Undershirt"));
-	addEntry(LLInventoryIcon::ICONNAME_CLOTHING_UNDERPANTS, 	new IconEntry("Inv_Underpants"));
-	addEntry(LLInventoryIcon::ICONNAME_CLOTHING_SKIRT, 			new IconEntry("Inv_Skirt"));
-	addEntry(LLInventoryIcon::ICONNAME_CLOTHING_ALPHA, 			new IconEntry("Inv_Alpha"));
-	addEntry(LLInventoryIcon::ICONNAME_CLOTHING_TATTOO, 		new IconEntry("Inv_Tattoo"));
-	addEntry(LLInventoryIcon::ICONNAME_ANIMATION, 				new IconEntry("Inv_Animation"));
-	addEntry(LLInventoryIcon::ICONNAME_GESTURE, 				new IconEntry("Inv_Gesture"));
-
-	addEntry(LLInventoryIcon::ICONNAME_CLOTHING_PHYSICS, 		new IconEntry("Inv_Physics"));
-
-	addEntry(LLInventoryIcon::ICONNAME_LINKITEM, 				new IconEntry("Inv_LinkItem"));
-	addEntry(LLInventoryIcon::ICONNAME_LINKFOLDER, 				new IconEntry("Inv_LinkFolder"));
-	addEntry(LLInventoryIcon::ICONNAME_MESH,	 				new IconEntry("Inv_Mesh"));
-
-	addEntry(LLInventoryIcon::ICONNAME_INVALID, 				new IconEntry("Inv_Invalid"));
-
-	addEntry(LLInventoryIcon::ICONNAME_NONE, 					new IconEntry("NONE"));
+	addEntry(LLInventoryType::ICONNAME_TEXTURE, 				new IconEntry("Inv_Texture"));
+	addEntry(LLInventoryType::ICONNAME_SOUND, 					new IconEntry("Inv_Sound"));
+	addEntry(LLInventoryType::ICONNAME_CALLINGCARD_ONLINE, 		new IconEntry("Inv_CallingCard"));
+	addEntry(LLInventoryType::ICONNAME_CALLINGCARD_OFFLINE, 	new IconEntry("Inv_CallingCard"));
+	addEntry(LLInventoryType::ICONNAME_LANDMARK, 				new IconEntry("Inv_Landmark"));
+	addEntry(LLInventoryType::ICONNAME_LANDMARK_VISITED, 		new IconEntry("Inv_Landmark"));
+	addEntry(LLInventoryType::ICONNAME_SCRIPT, 					new IconEntry("Inv_Script"));
+	addEntry(LLInventoryType::ICONNAME_CLOTHING, 				new IconEntry("Inv_Clothing"));
+	addEntry(LLInventoryType::ICONNAME_OBJECT, 					new IconEntry("Inv_Object"));
+	addEntry(LLInventoryType::ICONNAME_OBJECT_MULTI, 			new IconEntry("Inv_Object_Multi"));
+	addEntry(LLInventoryType::ICONNAME_NOTECARD, 				new IconEntry("Inv_Notecard"));
+	addEntry(LLInventoryType::ICONNAME_BODYPART, 				new IconEntry("Inv_Skin"));
+	addEntry(LLInventoryType::ICONNAME_SNAPSHOT, 				new IconEntry("Inv_Snapshot"));
+
+	addEntry(LLInventoryType::ICONNAME_BODYPART_SHAPE, 			new IconEntry("Inv_BodyShape"));
+	addEntry(LLInventoryType::ICONNAME_BODYPART_SKIN, 			new IconEntry("Inv_Skin"));
+	addEntry(LLInventoryType::ICONNAME_BODYPART_HAIR, 			new IconEntry("Inv_Hair"));
+	addEntry(LLInventoryType::ICONNAME_BODYPART_EYES, 			new IconEntry("Inv_Eye"));
+
+	addEntry(LLInventoryType::ICONNAME_CLOTHING_SHIRT, 			new IconEntry("Inv_Shirt"));
+	addEntry(LLInventoryType::ICONNAME_CLOTHING_PANTS, 			new IconEntry("Inv_Pants"));
+	addEntry(LLInventoryType::ICONNAME_CLOTHING_SHOES, 			new IconEntry("Inv_Shoe"));
+	addEntry(LLInventoryType::ICONNAME_CLOTHING_SOCKS, 			new IconEntry("Inv_Socks"));
+	addEntry(LLInventoryType::ICONNAME_CLOTHING_JACKET, 		new IconEntry("Inv_Jacket"));
+	addEntry(LLInventoryType::ICONNAME_CLOTHING_GLOVES, 		new IconEntry("Inv_Gloves"));
+	addEntry(LLInventoryType::ICONNAME_CLOTHING_UNDERSHIRT, 	new IconEntry("Inv_Undershirt"));
+	addEntry(LLInventoryType::ICONNAME_CLOTHING_UNDERPANTS, 	new IconEntry("Inv_Underpants"));
+	addEntry(LLInventoryType::ICONNAME_CLOTHING_SKIRT, 			new IconEntry("Inv_Skirt"));
+	addEntry(LLInventoryType::ICONNAME_CLOTHING_ALPHA, 			new IconEntry("Inv_Alpha"));
+	addEntry(LLInventoryType::ICONNAME_CLOTHING_TATTOO, 		new IconEntry("Inv_Tattoo"));
+	addEntry(LLInventoryType::ICONNAME_ANIMATION, 				new IconEntry("Inv_Animation"));
+	addEntry(LLInventoryType::ICONNAME_GESTURE, 				new IconEntry("Inv_Gesture"));
+
+	addEntry(LLInventoryType::ICONNAME_CLOTHING_PHYSICS, 		new IconEntry("Inv_Physics"));
+
+	addEntry(LLInventoryType::ICONNAME_LINKITEM, 				new IconEntry("Inv_LinkItem"));
+	addEntry(LLInventoryType::ICONNAME_LINKFOLDER, 				new IconEntry("Inv_LinkFolder"));
+	addEntry(LLInventoryType::ICONNAME_MESH,	 				new IconEntry("Inv_Mesh"));
+
+	addEntry(LLInventoryType::ICONNAME_INVALID, 				new IconEntry("Inv_Invalid"));
+
+	addEntry(LLInventoryType::ICONNAME_NONE, 					new IconEntry("NONE"));
 }
 
 LLUIImagePtr LLInventoryIcon::getIcon(LLAssetType::EType asset_type,
@@ -102,7 +102,7 @@ LLUIImagePtr LLInventoryIcon::getIcon(LLAssetType::EType asset_type,
 	return LLUI::getUIImage(icon_name);
 }
 
-LLUIImagePtr LLInventoryIcon::getIcon(EIconName idx)
+LLUIImagePtr LLInventoryIcon::getIcon(LLInventoryType::EIconName idx)
 {
 	return LLUI::getUIImage(getIconName(idx));
 }
@@ -112,56 +112,56 @@ const std::string& LLInventoryIcon::getIconName(LLAssetType::EType asset_type,
 												U32 misc_flag,
 												BOOL item_is_multi)
 {
-	EIconName idx = ICONNAME_OBJECT;
+	LLInventoryType::EIconName idx = LLInventoryType::ICONNAME_OBJECT;
 	if (item_is_multi)
 	{
-		idx = ICONNAME_OBJECT_MULTI;
+		idx = LLInventoryType::ICONNAME_OBJECT_MULTI;
 		return getIconName(idx);
 	}
 	
 	switch(asset_type)
 	{
 		case LLAssetType::AT_TEXTURE:
-			idx = (inventory_type == LLInventoryType::IT_SNAPSHOT) ? ICONNAME_SNAPSHOT : ICONNAME_TEXTURE;
+			idx = (inventory_type == LLInventoryType::IT_SNAPSHOT) ? LLInventoryType::ICONNAME_SNAPSHOT : LLInventoryType::ICONNAME_TEXTURE;
 			break;
 		case LLAssetType::AT_SOUND:
-			idx = ICONNAME_SOUND;
+			idx = LLInventoryType::ICONNAME_SOUND;
 			break;
 		case LLAssetType::AT_CALLINGCARD:
-			idx = (misc_flag != 0) ? ICONNAME_CALLINGCARD_ONLINE : ICONNAME_CALLINGCARD_OFFLINE;
+			idx = (misc_flag != 0) ? LLInventoryType::ICONNAME_CALLINGCARD_ONLINE : LLInventoryType::ICONNAME_CALLINGCARD_OFFLINE;
 			break;
 		case LLAssetType::AT_LANDMARK:
-			idx = (misc_flag != 0) ? ICONNAME_LANDMARK_VISITED : ICONNAME_LANDMARK;
+			idx = (misc_flag != 0) ? LLInventoryType::ICONNAME_LANDMARK_VISITED : LLInventoryType::ICONNAME_LANDMARK;
 			break;
 		case LLAssetType::AT_SCRIPT:
 		case LLAssetType::AT_LSL_TEXT:
 		case LLAssetType::AT_LSL_BYTECODE:
-			idx = ICONNAME_SCRIPT;
+			idx = LLInventoryType::ICONNAME_SCRIPT;
 			break;
 		case LLAssetType::AT_CLOTHING:
 		case LLAssetType::AT_BODYPART:
 			idx = assignWearableIcon(misc_flag);
 			break;
 		case LLAssetType::AT_NOTECARD:
-			idx = ICONNAME_NOTECARD;
+			idx = LLInventoryType::ICONNAME_NOTECARD;
 			break;
 		case LLAssetType::AT_ANIMATION:
-			idx = ICONNAME_ANIMATION;
+			idx = LLInventoryType::ICONNAME_ANIMATION;
 			break;
 		case LLAssetType::AT_GESTURE:
-			idx = ICONNAME_GESTURE;
+			idx = LLInventoryType::ICONNAME_GESTURE;
 			break;
 		case LLAssetType::AT_LINK:
-			idx = ICONNAME_LINKITEM;
+			idx = LLInventoryType::ICONNAME_LINKITEM;
 			break;
 		case LLAssetType::AT_LINK_FOLDER:
-			idx = ICONNAME_LINKFOLDER;
+			idx = LLInventoryType::ICONNAME_LINKFOLDER;
 			break;
 		case LLAssetType::AT_OBJECT:
-			idx = ICONNAME_OBJECT;
+			idx = LLInventoryType::ICONNAME_OBJECT;
 			break;
 		case LLAssetType::AT_MESH:
-			idx = ICONNAME_MESH;
+			idx = LLInventoryType::ICONNAME_MESH;
 		default:
 			break;
 	}
@@ -170,13 +170,13 @@ const std::string& LLInventoryIcon::getIconName(LLAssetType::EType asset_type,
 }
 
 
-const std::string& LLInventoryIcon::getIconName(EIconName idx)
+const std::string& LLInventoryIcon::getIconName(LLInventoryType::EIconName idx)
 {
 	const IconEntry *entry = LLIconDictionary::instance().lookup(idx);
 	return entry->mName;
 }
 
-LLInventoryIcon::EIconName LLInventoryIcon::assignWearableIcon(U32 misc_flag)
+LLInventoryType::EIconName LLInventoryIcon::assignWearableIcon(U32 misc_flag)
 {
 	const LLWearableType::EType wearable_type = LLWearableType::EType(LLInventoryItemFlags::II_FLAGS_WEARABLES_MASK & misc_flag);
 	return LLWearableType::getIconName(wearable_type);
diff --git a/indra/llappearance/llinventoryicon.h b/indra/newview/llinventoryicon.h
similarity index 62%
rename from indra/llappearance/llinventoryicon.h
rename to indra/newview/llinventoryicon.h
index c7e2998a20fb37062a3bac6eb74cb7c2bb730732..659448143da5aed429bf00e7db7bf0a084fd3ee3 100644
--- a/indra/llappearance/llinventoryicon.h
+++ b/indra/newview/llinventoryicon.h
@@ -35,66 +35,20 @@
 class LLInventoryIcon
 {
 public:
-	enum EIconName
-	{
-		ICONNAME_TEXTURE,
-		ICONNAME_SOUND,
-		ICONNAME_CALLINGCARD_ONLINE,
-		ICONNAME_CALLINGCARD_OFFLINE,
-		ICONNAME_LANDMARK,
-		ICONNAME_LANDMARK_VISITED,
-		ICONNAME_SCRIPT,
-		ICONNAME_CLOTHING,
-		ICONNAME_OBJECT,
-		ICONNAME_OBJECT_MULTI,
-		ICONNAME_NOTECARD,
-		ICONNAME_BODYPART,
-		ICONNAME_SNAPSHOT,
-		
-		ICONNAME_BODYPART_SHAPE,
-		ICONNAME_BODYPART_SKIN,
-		ICONNAME_BODYPART_HAIR,
-		ICONNAME_BODYPART_EYES,
-		ICONNAME_CLOTHING_SHIRT,
-		ICONNAME_CLOTHING_PANTS,
-		ICONNAME_CLOTHING_SHOES,
-		ICONNAME_CLOTHING_SOCKS,
-		ICONNAME_CLOTHING_JACKET,
-		ICONNAME_CLOTHING_GLOVES,
-		ICONNAME_CLOTHING_UNDERSHIRT,
-		ICONNAME_CLOTHING_UNDERPANTS,
-		ICONNAME_CLOTHING_SKIRT,
-		ICONNAME_CLOTHING_ALPHA,
-		ICONNAME_CLOTHING_TATTOO,
-
-		ICONNAME_ANIMATION,
-		ICONNAME_GESTURE,
-
-		ICONNAME_CLOTHING_PHYSICS,
-		
-		ICONNAME_LINKITEM,
-		ICONNAME_LINKFOLDER,
-		ICONNAME_MESH,
-
-		ICONNAME_INVALID,
-		ICONNAME_COUNT,
-		ICONNAME_NONE = -1
-	};
-
 	static const std::string& getIconName(LLAssetType::EType asset_type,
 										  LLInventoryType::EType inventory_type = LLInventoryType::IT_NONE,
 										  U32 misc_flag = 0, // different meanings depending on item type
 										  BOOL item_is_multi = FALSE);
-	static const std::string& getIconName(EIconName idx);
+	static const std::string& getIconName(LLInventoryType::EIconName idx);
 
 	static LLUIImagePtr getIcon(LLAssetType::EType asset_type,
 								LLInventoryType::EType inventory_type = LLInventoryType::IT_NONE,
 								U32 misc_flag = 0, // different meanings depending on item type
 								BOOL item_is_multi = FALSE);
-	static LLUIImagePtr getIcon(EIconName idx);
+	static LLUIImagePtr getIcon(LLInventoryType::EIconName idx);
 
 protected:
-	static EIconName assignWearableIcon(U32 misc_flag);
+	static LLInventoryType::EIconName assignWearableIcon(U32 misc_flag);
 };
 #endif // LL_LLINVENTORYICON_H
 
diff --git a/indra/newview/llinventorylistitem.cpp b/indra/newview/llinventorylistitem.cpp
index 3e0849a79578d793e0890e45d8a4d74b77b46545..26041767fd4a78713579f060f9036c3604ffe2c7 100644
--- a/indra/newview/llinventorylistitem.cpp
+++ b/indra/newview/llinventorylistitem.cpp
@@ -37,6 +37,7 @@
 #include "lltextutil.h"
 
 // newview
+#include "llinventoryicon.h"
 #include "llinventorymodel.h"
 #include "llviewerinventory.h"
 
diff --git a/indra/newview/llmediactrl.cpp b/indra/newview/llmediactrl.cpp
index 7650fe92296b825db8d8f873f38f198910d0227c..04744ab34cae784e02716f54f3d177610e5a0e17 100644
--- a/indra/newview/llmediactrl.cpp
+++ b/indra/newview/llmediactrl.cpp
@@ -119,8 +119,8 @@ LLMediaCtrl::LLMediaCtrl( const Params& p) :
 
 	if(!getDecoupleTextureSize())
 	{
-		S32 screen_width = llround((F32)getRect().getWidth() * LLUI::sGLScaleFactor.mV[VX]);
-		S32 screen_height = llround((F32)getRect().getHeight() * LLUI::sGLScaleFactor.mV[VY]);
+		S32 screen_width = llround((F32)getRect().getWidth() * LLUI::getScaleFactor().mV[VX]);
+		S32 screen_height = llround((F32)getRect().getHeight() * LLUI::getScaleFactor().mV[VY]);
 			
 		setTextureSize(screen_width, screen_height);
 	}
@@ -469,8 +469,8 @@ void LLMediaCtrl::reshape( S32 width, S32 height, BOOL called_from_parent )
 {
 	if(!getDecoupleTextureSize())
 	{
-		S32 screen_width = llround((F32)width * LLUI::sGLScaleFactor.mV[VX]);
-		S32 screen_height = llround((F32)height * LLUI::sGLScaleFactor.mV[VY]);
+		S32 screen_width = llround((F32)width * LLUI::getScaleFactor().mV[VX]);
+		S32 screen_height = llround((F32)height * LLUI::getScaleFactor().mV[VY]);
 
 		// when floater is minimized, these sizes are negative
 		if ( screen_height > 0 && screen_width > 0 )
@@ -687,7 +687,7 @@ bool LLMediaCtrl::ensureMediaSourceExists()
 			mMediaSource->addObserver( this );
 			mMediaSource->setBackgroundColor( getBackgroundColor() );
 			mMediaSource->setTrustedBrowser(mTrusted);
-			mMediaSource->setPageZoomFactor( LLUI::sGLScaleFactor.mV[ VX ] );
+			mMediaSource->setPageZoomFactor( LLUI::getScaleFactor().mV[ VX ] );
 
 			if(mClearCache)
 			{
@@ -770,7 +770,7 @@ void LLMediaCtrl::draw()
 	{
 		gGL.pushUIMatrix();
 		{
-			mMediaSource->setPageZoomFactor( LLUI::sGLScaleFactor.mV[ VX ] );
+			mMediaSource->setPageZoomFactor( LLUI::getScaleFactor().mV[ VX ] );
 
 			// scale texture to fit the space using texture coords
 			gGL.getTexUnit(0)->bind(media_texture);
@@ -884,14 +884,14 @@ void LLMediaCtrl::convertInputCoords(S32& x, S32& y)
 		coords_opengl = mMediaSource->getMediaPlugin()->getTextureCoordsOpenGL();
 	}
 	
-	x = llround((F32)x * LLUI::sGLScaleFactor.mV[VX]);
+	x = llround((F32)x * LLUI::getScaleFactor().mV[VX]);
 	if ( ! coords_opengl )
 	{
-		y = llround((F32)(y) * LLUI::sGLScaleFactor.mV[VY]);
+		y = llround((F32)(y) * LLUI::getScaleFactor().mV[VY]);
 	}
 	else
 	{
-		y = llround((F32)(getRect().getHeight() - y) * LLUI::sGLScaleFactor.mV[VY]);
+		y = llround((F32)(getRect().getHeight() - y) * LLUI::getScaleFactor().mV[VY]);
 	};
 }
 
diff --git a/indra/newview/llpanelgroupnotices.cpp b/indra/newview/llpanelgroupnotices.cpp
index 31c0e3d01a740015b8d343b86181321aca8d6336..9a3ea0774bcf22766d7f91fad33c93d47bf6481a 100644
--- a/indra/newview/llpanelgroupnotices.cpp
+++ b/indra/newview/llpanelgroupnotices.cpp
@@ -35,6 +35,7 @@
 #include "llviewerinventory.h"
 #include "llinventorydefines.h"
 #include "llinventoryfunctions.h"
+#include "llinventoryicon.h"
 #include "llinventorymodel.h"
 #include "llfloaterinventory.h"
 #include "llagent.h"
diff --git a/indra/newview/llpanelobjectinventory.cpp b/indra/newview/llpanelobjectinventory.cpp
index 1ca24f30316339da42901fe3e6e0acddb20090cc..7c3425d71b9e97dff1b146351e3880cf69dfe04e 100644
--- a/indra/newview/llpanelobjectinventory.cpp
+++ b/indra/newview/llpanelobjectinventory.cpp
@@ -47,6 +47,7 @@
 #include "llfolderview.h"
 #include "llinventorybridge.h"
 #include "llinventorydefines.h"
+#include "llinventoryicon.h"
 #include "llinventoryfilter.h"
 #include "llinventoryfunctions.h"
 #include "llpreviewanim.h"
diff --git a/indra/newview/lltoastgroupnotifypanel.cpp b/indra/newview/lltoastgroupnotifypanel.cpp
index 75178a6ef8a6fcaa8a560d795d90742be6084636..64be5408bed4db5b0570c51c32e16281b7a20deb 100644
--- a/indra/newview/lltoastgroupnotifypanel.cpp
+++ b/indra/newview/lltoastgroupnotifypanel.cpp
@@ -33,6 +33,7 @@
 #include "llbutton.h"
 #include "lliconctrl.h"
 #include "llinventoryfunctions.h"
+#include "llinventoryicon.h"
 #include "llnotifications.h"
 #include "llviewertexteditor.h"
 
diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp
index 3b486efd7e0fdf5284684826adca1121c264722c..cc697f8510e85282531f3b3e44b2734308fcd3e9 100644
--- a/indra/newview/llviewerdisplay.cpp
+++ b/indra/newview/llviewerdisplay.cpp
@@ -1440,7 +1440,7 @@ void render_ui_2d()
 		gGL.pushMatrix();
 		S32 half_width = (gViewerWindow->getWorldViewWidthScaled() / 2);
 		S32 half_height = (gViewerWindow->getWorldViewHeightScaled() / 2);
-		gGL.scalef(LLUI::sGLScaleFactor.mV[0], LLUI::sGLScaleFactor.mV[1], 1.f);
+		gGL.scalef(LLUI::getScaleFactor().mV[0], LLUI::getScaleFactor().mV[1], 1.f);
 		gGL.translatef((F32)half_width, (F32)half_height, 0.f);
 		F32 zoom = gAgentCamera.mHUDCurZoom;
 		gGL.scalef(zoom,zoom,1.f);
@@ -1478,10 +1478,10 @@ void render_ui_2d()
 				LLUI::sDirtyRect = last_rect;
 				last_rect = t_rect;
 			
-				last_rect.mLeft = LLRect::tCoordType(last_rect.mLeft / LLUI::sGLScaleFactor.mV[0]);
-				last_rect.mRight = LLRect::tCoordType(last_rect.mRight / LLUI::sGLScaleFactor.mV[0]);
-				last_rect.mTop = LLRect::tCoordType(last_rect.mTop / LLUI::sGLScaleFactor.mV[1]);
-				last_rect.mBottom = LLRect::tCoordType(last_rect.mBottom / LLUI::sGLScaleFactor.mV[1]);
+				last_rect.mLeft = LLRect::tCoordType(last_rect.mLeft / LLUI::getScaleFactor().mV[0]);
+				last_rect.mRight = LLRect::tCoordType(last_rect.mRight / LLUI::getScaleFactor().mV[0]);
+				last_rect.mTop = LLRect::tCoordType(last_rect.mTop / LLUI::getScaleFactor().mV[1]);
+				last_rect.mBottom = LLRect::tCoordType(last_rect.mBottom / LLUI::getScaleFactor().mV[1]);
 
 				LLRect clip_rect(last_rect);
 				
diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp
index d5ca01931f11f5a3d3016dc1ce1bc90d4d04ea03..dd29260f701ed7d8aae560b12f5017cf7c064bd1 100755
--- a/indra/newview/llviewerwindow.cpp
+++ b/indra/newview/llviewerwindow.cpp
@@ -2140,7 +2140,7 @@ void LLViewerWindow::reshape(S32 width, S32 height)
 
 		calcDisplayScale();
 	
-		BOOL display_scale_changed = mDisplayScale != LLUI::sGLScaleFactor;
+		BOOL display_scale_changed = mDisplayScale != LLUI::getScaleFactor();
 		LLUI::setScaleFactor(mDisplayScale);
 
 		// update our window rectangle
@@ -2346,7 +2346,7 @@ void LLViewerWindow::draw()
 		// scale view by UI global scale factor and aspect ratio correction factor
 		gGL.scaleUI(mDisplayScale.mV[VX], mDisplayScale.mV[VY], 1.f);
 
-		LLVector2 old_scale_factor = LLUI::sGLScaleFactor;
+		LLVector2 old_scale_factor = LLUI::getScaleFactor();
 		// apply camera zoom transform (for high res screenshots)
 		F32 zoom_factor = LLViewerCamera::getInstance()->getZoomFactor();
 		S16 sub_region = LLViewerCamera::getInstance()->getZoomSubRegion();
@@ -2360,7 +2360,7 @@ void LLViewerWindow::draw()
 						(F32)getWindowHeightScaled() * -(F32)pos_y, 
 						0.f);
 			gGL.scalef(zoom_factor, zoom_factor, 1.f);
-			LLUI::sGLScaleFactor *= zoom_factor;
+			LLUI::getScaleFactor() *= zoom_factor;
 		}
 
 		// Draw tool specific overlay on world
@@ -2408,7 +2408,7 @@ void LLViewerWindow::draw()
 				LLFontGL::HCENTER, LLFontGL::TOP);
 		}
 
-		LLUI::sGLScaleFactor = old_scale_factor;
+		LLUI::setScaleFactor(old_scale_factor);
 	}
 	LLUI::popMatrix();
 	gGL.popMatrix();
@@ -3208,8 +3208,8 @@ void LLViewerWindow::updateLayout()
 
 void LLViewerWindow::updateMouseDelta()
 {
-	S32 dx = lltrunc((F32) (mCurrentMousePoint.mX - mLastMousePoint.mX) * LLUI::sGLScaleFactor.mV[VX]);
-	S32 dy = lltrunc((F32) (mCurrentMousePoint.mY - mLastMousePoint.mY) * LLUI::sGLScaleFactor.mV[VY]);
+	S32 dx = lltrunc((F32) (mCurrentMousePoint.mX - mLastMousePoint.mX) * LLUI::getScaleFactor().mV[VX]);
+	S32 dy = lltrunc((F32) (mCurrentMousePoint.mY - mLastMousePoint.mY) * LLUI::getScaleFactor().mV[VY]);
 
 	//RN: fix for asynchronous notification of mouse leaving window not working
 	LLCoordWindow mouse_pos;
diff --git a/indra/newview/llwearableitemslist.cpp b/indra/newview/llwearableitemslist.cpp
index c7e921564327f7c47b242111b1b76c17c6c56639..c196d70617d7d69aade31e05ea392cd6b3afbc3b 100755
--- a/indra/newview/llwearableitemslist.cpp
+++ b/indra/newview/llwearableitemslist.cpp
@@ -34,6 +34,7 @@
 #include "llagentwearables.h"
 #include "llappearancemgr.h"
 #include "llinventoryfunctions.h"
+#include "llinventoryicon.h"
 #include "lltransutil.h"
 #include "llviewerattachmenu.h"
 #include "llvoavatarself.h"
diff --git a/indra/newview/llworldmapview.cpp b/indra/newview/llworldmapview.cpp
index a3ccf87cfc9540dcabafdb9d0858d6d473b0ad3d..428be8efb967e102b38935cee33ab4aeb14ea5b7 100644
--- a/indra/newview/llworldmapview.cpp
+++ b/indra/newview/llworldmapview.cpp
@@ -421,7 +421,7 @@ void LLWorldMapView::draw()
 			{
 				// Inform the fetch mechanism of the size we need
 				S32 draw_size = llround(sMapScale);
-				overlayimage->setKnownDrawSize(llround(draw_size * LLUI::sGLScaleFactor.mV[VX]), llround(draw_size * LLUI::sGLScaleFactor.mV[VY]));
+				overlayimage->setKnownDrawSize(llround(draw_size * LLUI::getScaleFactor().mV[VX]), llround(draw_size * LLUI::getScaleFactor().mV[VY]));
 				// Draw something whenever we have enough info
 				if (overlayimage->hasGLTexture())
 				{