diff --git a/indra/llappearance/lltexlayer.cpp b/indra/llappearance/lltexlayer.cpp
index bf2fd1e30d06d125bc50a0d2a473df47fda8d035..0d3219c4e06e7c6fdd9655e5d2e50bb004a32d44 100644
--- a/indra/llappearance/lltexlayer.cpp
+++ b/indra/llappearance/lltexlayer.cpp
@@ -40,6 +40,7 @@
 #include "lltexturemanagerbridge.h"
 #include "llui.h"
 #include "llwearable.h"
+#include "llvertexbuffer.h"
 #include "llviewervisualparam.h"
 
 //#include "../tools/imdebug/imdebug.h"
@@ -89,6 +90,92 @@ private:
 	param_alpha_info_list_t		mParamAlphaInfoList;
 };
 
+//-----------------------------------------------------------------------------
+// LLTexLayerSetBuffer
+// The composite image that a LLViewerTexLayerSet writes to.  Each LLViewerTexLayerSet has one.
+//-----------------------------------------------------------------------------
+
+LLTexLayerSetBuffer::LLTexLayerSetBuffer(LLTexLayerSet* const owner) :
+	mTexLayerSet(owner)
+{
+}
+
+LLTexLayerSetBuffer::~LLTexLayerSetBuffer()
+{
+}
+
+void LLTexLayerSetBuffer::pushProjection() const
+{
+	gGL.matrixMode(LLRender::MM_PROJECTION);
+	gGL.pushMatrix();
+	gGL.loadIdentity();
+	gGL.ortho(0.0f, getCompositeWidth(), 0.0f, getCompositeHeight(), -1.0f, 1.0f);
+
+	gGL.matrixMode(LLRender::MM_MODELVIEW);
+	gGL.pushMatrix();
+	gGL.loadIdentity();
+}
+
+void LLTexLayerSetBuffer::popProjection() const
+{
+	gGL.matrixMode(LLRender::MM_PROJECTION);
+	gGL.popMatrix();
+
+	gGL.matrixMode(LLRender::MM_MODELVIEW);
+	gGL.popMatrix();
+}
+
+// virtual
+void LLTexLayerSetBuffer::preRenderTexLayerSet()
+{
+	// Set up an ortho projection
+	pushProjection();
+}
+
+// virtual
+void LLTexLayerSetBuffer::postRenderTexLayerSet(BOOL success)
+{
+	popProjection();
+}
+
+BOOL LLTexLayerSetBuffer::renderTexLayerSet()
+{
+	// Default color mask for tex layer render
+	gGL.setColorMask(true, true);
+
+	BOOL success = TRUE;
+	
+	bool use_shaders = LLGLSLShader::sNoFixedFunction;
+
+	if (use_shaders)
+	{
+		gAlphaMaskProgram.bind();
+		gAlphaMaskProgram.setMinimumAlpha(0.004f);
+	}
+
+	LLVertexBuffer::unbind();
+
+	// Composite the color data
+	LLGLSUIDefault gls_ui;
+	success &= mTexLayerSet->render( getCompositeOriginX(), getCompositeOriginY(), 
+									 getCompositeWidth(), getCompositeHeight() );
+	gGL.flush();
+
+	midRenderTexLayerSet(success);
+
+	if (use_shaders)
+	{
+		gAlphaMaskProgram.unbind();
+	}
+
+	LLVertexBuffer::unbind();
+	
+	// reset GL state
+	gGL.setColorMask(true, true);
+	gGL.setSceneBlendType(LLRender::BT_ALPHA);
+
+	return success;
+}
 
 //-----------------------------------------------------------------------------
 // LLTexLayerSetInfo
@@ -381,6 +468,28 @@ const std::string LLTexLayerSet::getBodyRegionName() const
 }
 
 
+void LLTexLayerSet::destroyComposite()
+{
+	if( mComposite )
+	{
+		mComposite = NULL;
+	}
+}
+
+LLTexLayerSetBuffer* LLTexLayerSet::getComposite()
+{
+	if (!mComposite)
+	{
+		createComposite();
+	}
+	return mComposite;
+}
+
+const LLTexLayerSetBuffer* LLTexLayerSet::getComposite() const
+{
+	return mComposite;
+}
+
 void LLTexLayerSet::renderAlphaMaskTextures(S32 x, S32 y, S32 width, S32 height, bool forceClear)
 {
 	const LLTexLayerSetInfo *info = getInfo();
diff --git a/indra/llappearance/lltexlayer.h b/indra/llappearance/lltexlayer.h
index 5a413e929f84dc15e9442f42b4bbc32e304020a0..4f2ee5b045057f380d0e90e958b4b87cbb650e6d 100644
--- a/indra/llappearance/lltexlayer.h
+++ b/indra/llappearance/lltexlayer.h
@@ -40,6 +40,7 @@ class LLXmlTreeNode;
 class LLTexLayerSet;
 class LLTexLayerSetInfo;
 class LLTexLayerInfo;
+class LLTexLayerSetBuffer;
 class LLWearable;
 class LLViewerVisualParam;
 
@@ -178,10 +179,16 @@ private:
 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 class LLTexLayerSet
 {
+	friend class LLTexLayerSetBuffer;
 public:
 	LLTexLayerSet(LLAvatarAppearance* const appearance);
 	virtual ~LLTexLayerSet();
 
+	LLTexLayerSetBuffer*		getComposite();
+	const LLTexLayerSetBuffer* 	getComposite() const; // Do not create one if it doesn't exist.
+	virtual void				createComposite() = 0;
+	void						destroyComposite();
+
 	const LLTexLayerSetInfo* 	getInfo() const 			{ return mInfo; }
 	BOOL						setInfo(const LLTexLayerSetInfo *info); // This sets mInfo and calls initialization functions
 
@@ -199,6 +206,7 @@ public:
 	
 	LLAvatarAppearance*			getAvatarAppearance()	const		{ return mAvatarAppearance; }
 	const std::string			getBodyRegionName() const;
+	BOOL						hasComposite() const 		{ return (mComposite.notNull()); }
 	LLAvatarAppearanceDefines::EBakedTextureIndex getBakedTexIndex() { return mBakedTexIndex; }
 	void						setBakedTexIndex(LLAvatarAppearanceDefines::EBakedTextureIndex index) { mBakedTexIndex = index; }
 	BOOL						isVisible() const 			{ return mIsVisible; }
@@ -209,6 +217,7 @@ protected:
 	typedef std::vector<LLTexLayerInterface *> layer_list_t;
 	layer_list_t				mLayerList;
 	layer_list_t				mMaskLayerList;
+	LLPointer<LLTexLayerSetBuffer>	mComposite;
 	LLAvatarAppearance*	const	mAvatarAppearance; // note: backlink only; don't make this an LLPointer.
 	BOOL						mIsVisible;
 
@@ -241,6 +250,34 @@ protected:
 	layer_info_list_t		mLayerInfoList;
 };
 
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// LLTexLayerSetBuffer
+//
+// The composite image that a LLTexLayerSet writes to.  Each LLTexLayerSet has one.
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+class LLTexLayerSetBuffer : public virtual LLRefCount
+{
+	LOG_CLASS(LLTexLayerSetBuffer);
+
+public:
+	LLTexLayerSetBuffer(LLTexLayerSet* const owner);
+	virtual ~LLTexLayerSetBuffer();
+
+protected:
+	void					pushProjection() const;
+	void					popProjection() const;
+	virtual void			preRenderTexLayerSet();
+	virtual void			midRenderTexLayerSet(BOOL success) {}
+	virtual void			postRenderTexLayerSet(BOOL success);
+	virtual S32				getCompositeOriginX() const = 0;
+	virtual S32				getCompositeOriginY() const = 0;
+	virtual S32				getCompositeWidth() const = 0;
+	virtual S32				getCompositeHeight() const = 0;
+	BOOL					renderTexLayerSet();
+
+	LLTexLayerSet* const	mTexLayerSet;
+};
+
 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 // LLTexLayerStaticImageList
 //
diff --git a/indra/llrender/lltexture.h b/indra/llrender/lltexture.h
index a23aa725208b8f3db96b24324da2c0344924c58d..40245968d1961b88404187e1ddcf768b1bcd18c9 100644
--- a/indra/llrender/lltexture.h
+++ b/indra/llrender/lltexture.h
@@ -43,7 +43,7 @@ class LLImageRaw ;
 //this is an abstract class as the parent for the class LLViewerTexture
 //through the following virtual functions, the class LLViewerTexture can be reached from /llrender.
 //
-class LLTexture : public LLRefCount
+class LLTexture : public virtual LLRefCount
 {
 	friend class LLTexUnit ;
 	friend class LLFontGL ;
diff --git a/indra/newview/llassetuploadresponders.cpp b/indra/newview/llassetuploadresponders.cpp
index 35e44d73d470d63b5575eeca2d0660ab02b4cdeb..7c423af3c8aaac54b09ab8f74688b609593c1492 100644
--- a/indra/newview/llassetuploadresponders.cpp
+++ b/indra/newview/llassetuploadresponders.cpp
@@ -456,7 +456,7 @@ LLSendTexLayerResponder::LLSendTexLayerResponder(const LLSD& post_data,
 
 LLSendTexLayerResponder::~LLSendTexLayerResponder()
 {
-	// mBakedUploadData is normally deleted by calls to LLTexLayerSetBuffer::onTextureUploadComplete() below
+	// mBakedUploadData is normally deleted by calls to LLViewerTexLayerSetBuffer::onTextureUploadComplete() below
 	if (mBakedUploadData)
 	{	// ...but delete it in the case where uploadComplete() is never called
 		delete mBakedUploadData;
@@ -477,12 +477,12 @@ void LLSendTexLayerResponder::uploadComplete(const LLSD& content)
 	if (result == "complete"
 		&& mBakedUploadData != NULL)
 	{	// Invoke 
-		LLTexLayerSetBuffer::onTextureUploadComplete(new_id, (void*) mBakedUploadData, 0, LL_EXSTAT_NONE);
+		LLViewerTexLayerSetBuffer::onTextureUploadComplete(new_id, (void*) mBakedUploadData, 0, LL_EXSTAT_NONE);
 		mBakedUploadData = NULL;	// deleted in onTextureUploadComplete()
 	}
 	else
 	{	// Invoke the original callback with an error result
-		LLTexLayerSetBuffer::onTextureUploadComplete(new_id, (void*) mBakedUploadData, -1, LL_EXSTAT_NONE);
+		LLViewerTexLayerSetBuffer::onTextureUploadComplete(new_id, (void*) mBakedUploadData, -1, LL_EXSTAT_NONE);
 		mBakedUploadData = NULL;	// deleted in onTextureUploadComplete()
 	}
 }
@@ -492,7 +492,7 @@ void LLSendTexLayerResponder::error(U32 statusNum, const std::string& reason)
 	llinfos << "status: " << statusNum << " reason: " << reason << llendl;
 	
 	// Invoke the original callback with an error result
-	LLTexLayerSetBuffer::onTextureUploadComplete(LLUUID(), (void*) mBakedUploadData, -1, LL_EXSTAT_NONE);
+	LLViewerTexLayerSetBuffer::onTextureUploadComplete(LLUUID(), (void*) mBakedUploadData, -1, LL_EXSTAT_NONE);
 	mBakedUploadData = NULL;	// deleted in onTextureUploadComplete()
 }
 
diff --git a/indra/newview/lldynamictexture.h b/indra/newview/lldynamictexture.h
index c51e7d1e1a76ff64171cdd483ffc49c5d47c1bb1..d287ae6eebab25d83da53b8aa33bc0f4bb67c140 100644
--- a/indra/newview/lldynamictexture.h
+++ b/indra/newview/lldynamictexture.h
@@ -72,8 +72,8 @@ public:
 	
 	/*virtual*/ S8 getType() const ;
 
-	S32			getOriginX()	{ return mOrigin.mX; }
-	S32			getOriginY()	{ return mOrigin.mY; }
+	S32			getOriginX() const	{ return mOrigin.mX; }
+	S32			getOriginY() const	{ return mOrigin.mY; }
 	
 	S32			getSize()		{ return mFullWidth * mFullHeight * mComponents; }
 
diff --git a/indra/newview/lltextureview.cpp b/indra/newview/lltextureview.cpp
index 070009fe9c2042a46bd8d639581f4eb459fb9fc8..03529b924656459683e8f65f60991297811d4965 100755
--- a/indra/newview/lltextureview.cpp
+++ b/indra/newview/lltextureview.cpp
@@ -425,7 +425,7 @@ void LLAvatarTexBar::draw()
 		const LLAvatarAppearanceDefines::EBakedTextureIndex baked_index = baked_iter->first;
 		const LLViewerTexLayerSet *layerset = avatarp->debugGetLayerSet(baked_index);
 		if (!layerset) continue;
-		const LLTexLayerSetBuffer *layerset_buffer = layerset->getComposite();
+		const LLViewerTexLayerSetBuffer *layerset_buffer = layerset->getViewerComposite();
 		if (!layerset_buffer) continue;
 
 		LLColor4 text_color = LLColor4::white;
diff --git a/indra/newview/llviewerjointmesh.cpp b/indra/newview/llviewerjointmesh.cpp
index 79800c1df31c9af424114d33958bbb8b71854396..3532fac1bc02662e4feb56af442e0a3e570a6189 100755
--- a/indra/newview/llviewerjointmesh.cpp
+++ b/indra/newview/llviewerjointmesh.cpp
@@ -562,7 +562,7 @@ U32 LLViewerJointMesh::drawShape( F32 pixelArea, BOOL first_pass, BOOL is_dummy)
 	{
 		if(	mLayerSet->hasComposite() )
 		{
-			gGL.getTexUnit(diffuse_channel)->bind(mLayerSet->getComposite());
+			gGL.getTexUnit(diffuse_channel)->bind(mLayerSet->getViewerComposite());
 		}
 		else
 		{
diff --git a/indra/newview/llviewerstats.cpp b/indra/newview/llviewerstats.cpp
index f049130f3a09bb779226c4c8c67771b55dfad0f1..961c7082cfabed25e3234759822644b222813cd1 100755
--- a/indra/newview/llviewerstats.cpp
+++ b/indra/newview/llviewerstats.cpp
@@ -519,7 +519,7 @@ void output_statistics(void*)
 	llinfos << "Avatar Memory (partly overlaps with above stats):" << llendl;
 	LLTexLayerStaticImageList::getInstance()->dumpByteCount();
 	LLVOAvatarSelf::dumpScratchTextureByteCount();
-	LLTexLayerSetBuffer::dumpTotalByteCount();
+	LLViewerTexLayerSetBuffer::dumpTotalByteCount();
 	LLVOAvatarSelf::dumpTotalLocalTextureByteCount();
 	LLTexLayerParamAlpha::dumpCacheByteCount();
 	LLVOAvatar::dumpBakedStatus();
diff --git a/indra/newview/llviewertexlayer.cpp b/indra/newview/llviewertexlayer.cpp
index 051aa41ed152ec89aa7be9367f6a7f82822dc878..69457ab1db282b8f3301b113e8f1c37dd09b07b2 100644
--- a/indra/newview/llviewertexlayer.cpp
+++ b/indra/newview/llviewertexlayer.cpp
@@ -63,33 +63,33 @@ LLBakedUploadData::LLBakedUploadData(const LLVOAvatarSelf* avatar,
 }
 
 //-----------------------------------------------------------------------------
-// LLTexLayerSetBuffer
+// LLViewerTexLayerSetBuffer
 // The composite image that a LLViewerTexLayerSet writes to.  Each LLViewerTexLayerSet has one.
 //-----------------------------------------------------------------------------
 
 // static
-S32 LLTexLayerSetBuffer::sGLByteCount = 0;
+S32 LLViewerTexLayerSetBuffer::sGLByteCount = 0;
 
-LLTexLayerSetBuffer::LLTexLayerSetBuffer(LLViewerTexLayerSet* const owner, 
+LLViewerTexLayerSetBuffer::LLViewerTexLayerSetBuffer(LLTexLayerSet* const owner, 
 										 S32 width, S32 height) :
 	// ORDER_LAST => must render these after the hints are created.
+	LLTexLayerSetBuffer(owner),
 	LLViewerDynamicTexture( width, height, 4, LLViewerDynamicTexture::ORDER_LAST, TRUE ), 
 	mUploadPending(FALSE), // Not used for any logic here, just to sync sending of updates
 	mNeedsUpload(FALSE),
 	mNumLowresUploads(0),
 	mUploadFailCount(0),
 	mNeedsUpdate(TRUE),
-	mNumLowresUpdates(0),
-	mTexLayerSet(owner)
+	mNumLowresUpdates(0)
 {
-	LLTexLayerSetBuffer::sGLByteCount += getSize();
+	LLViewerTexLayerSetBuffer::sGLByteCount += getSize();
 	mNeedsUploadTimer.start();
 	mNeedsUpdateTimer.start();
 }
 
-LLTexLayerSetBuffer::~LLTexLayerSetBuffer()
+LLViewerTexLayerSetBuffer::~LLViewerTexLayerSetBuffer()
 {
-	LLTexLayerSetBuffer::sGLByteCount -= getSize();
+	LLViewerTexLayerSetBuffer::sGLByteCount -= getSize();
 	destroyGLTexture();
 	for( S32 order = 0; order < ORDER_COUNT; order++ )
 	{
@@ -98,30 +98,30 @@ LLTexLayerSetBuffer::~LLTexLayerSetBuffer()
 }
 
 //virtual 
-S8 LLTexLayerSetBuffer::getType() const 
+S8 LLViewerTexLayerSetBuffer::getType() const 
 {
 	return LLViewerDynamicTexture::LL_TEX_LAYER_SET_BUFFER ;
 }
 
 //virtual 
-void LLTexLayerSetBuffer::restoreGLTexture() 
+void LLViewerTexLayerSetBuffer::restoreGLTexture() 
 {	
 	LLViewerDynamicTexture::restoreGLTexture() ;
 }
 
 //virtual 
-void LLTexLayerSetBuffer::destroyGLTexture() 
+void LLViewerTexLayerSetBuffer::destroyGLTexture() 
 {
 	LLViewerDynamicTexture::destroyGLTexture() ;
 }
 
 // static
-void LLTexLayerSetBuffer::dumpTotalByteCount()
+void LLViewerTexLayerSetBuffer::dumpTotalByteCount()
 {
-	llinfos << "Composite System GL Buffers: " << (LLTexLayerSetBuffer::sGLByteCount/1024) << "KB" << llendl;
+	llinfos << "Composite System GL Buffers: " << (LLViewerTexLayerSetBuffer::sGLByteCount/1024) << "KB" << llendl;
 }
 
-void LLTexLayerSetBuffer::requestUpdate()
+void LLViewerTexLayerSetBuffer::requestUpdate()
 {
 	restartUpdateTimer();
 	mNeedsUpdate = TRUE;
@@ -131,7 +131,7 @@ void LLTexLayerSetBuffer::requestUpdate()
 	mUploadID.setNull();
 }
 
-void LLTexLayerSetBuffer::requestUpload()
+void LLViewerTexLayerSetBuffer::requestUpload()
 {
 	conditionalRestartUploadTimer();
 	mNeedsUpload = TRUE;
@@ -139,7 +139,7 @@ void LLTexLayerSetBuffer::requestUpload()
 	mUploadPending = TRUE;
 }
 
-void LLTexLayerSetBuffer::conditionalRestartUploadTimer()
+void LLViewerTexLayerSetBuffer::conditionalRestartUploadTimer()
 {
 	// If we requested a new upload but haven't even uploaded
 	// a low res version of our last upload request, then
@@ -155,13 +155,13 @@ void LLTexLayerSetBuffer::conditionalRestartUploadTimer()
 	}
 }
 
-void LLTexLayerSetBuffer::restartUpdateTimer()
+void LLViewerTexLayerSetBuffer::restartUpdateTimer()
 {
 	mNeedsUpdateTimer.reset();
 	mNeedsUpdateTimer.start();
 }
 
-void LLTexLayerSetBuffer::cancelUpload()
+void LLViewerTexLayerSetBuffer::cancelUpload()
 {
 	mNeedsUpload = FALSE;
 	mUploadPending = FALSE;
@@ -169,29 +169,8 @@ void LLTexLayerSetBuffer::cancelUpload()
 	mUploadRetryTimer.reset();
 }
 
-void LLTexLayerSetBuffer::pushProjection() const
-{
-	gGL.matrixMode(LLRender::MM_PROJECTION);
-	gGL.pushMatrix();
-	gGL.loadIdentity();
-	gGL.ortho(0.0f, mFullWidth, 0.0f, mFullHeight, -1.0f, 1.0f);
-
-	gGL.matrixMode(LLRender::MM_MODELVIEW);
-	gGL.pushMatrix();
-	gGL.loadIdentity();
-}
-
-void LLTexLayerSetBuffer::popProjection() const
-{
-	gGL.matrixMode(LLRender::MM_PROJECTION);
-	gGL.popMatrix();
-
-	gGL.matrixMode(LLRender::MM_MODELVIEW);
-	gGL.popMatrix();
-}
-
 // virtual
-BOOL LLTexLayerSetBuffer::needsRender()
+BOOL LLViewerTexLayerSetBuffer::needsRender()
 {
 	llassert(mTexLayerSet->getAvatarAppearance() == gAgentAvatarp);
 	if (!isAgentAvatarValid()) return FALSE;
@@ -212,7 +191,7 @@ BOOL LLTexLayerSetBuffer::needsRender()
 	}
 
 	// Don't render if we are trying to create a shirt texture but aren't wearing a skirt.
-	if (gAgentAvatarp->getBakedTE(mTexLayerSet) == LLAvatarAppearanceDefines::TEX_SKIRT_BAKED && 
+	if (gAgentAvatarp->getBakedTE(getViewerTexLayerSet()) == LLAvatarAppearanceDefines::TEX_SKIRT_BAKED && 
 		!gAgentAvatarp->isWearingWearableType(LLWearableType::WT_SKIRT))
 	{
 		cancelUpload();
@@ -220,51 +199,36 @@ BOOL LLTexLayerSetBuffer::needsRender()
 	}
 
 	// Render if we have at least minimal level of detail for each local texture.
-	return mTexLayerSet->isLocalTextureDataAvailable();
+	return getViewerTexLayerSet()->isLocalTextureDataAvailable();
 }
 
-void LLTexLayerSetBuffer::preRender(BOOL clear_depth)
+// virtual
+void LLViewerTexLayerSetBuffer::preRenderTexLayerSet()
 {
-	// Set up an ortho projection
-	pushProjection();
+	LLTexLayerSetBuffer::preRenderTexLayerSet();
 	
 	// keep depth buffer, we don't need to clear it
 	LLViewerDynamicTexture::preRender(FALSE);
 }
 
-void LLTexLayerSetBuffer::postRender(BOOL success)
+// virtual
+void LLViewerTexLayerSetBuffer::postRenderTexLayerSet(BOOL success)
 {
-	popProjection();
+	// *TODO: Old logic does not check success before setGLTextureCreated
+	// we have valid texture data now
+	mGLTexturep->setGLTextureCreated(true);
 
+	LLTexLayerSetBuffer::postRenderTexLayerSet(success);
 	LLViewerDynamicTexture::postRender(success);
 }
 
-BOOL LLTexLayerSetBuffer::render()
+// virtual
+void LLViewerTexLayerSetBuffer::midRenderTexLayerSet(BOOL success)
 {
-	// Default color mask for tex layer render
-	gGL.setColorMask(true, true);
-
 	// do we need to upload, and do we have sufficient data to create an uploadable composite?
 	// TODO: When do we upload the texture if gAgent.mNumPendingQueries is non-zero?
 	const BOOL upload_now = mNeedsUpload && isReadyToUpload();
 	const BOOL update_now = mNeedsUpdate && isReadyToUpdate();
-	
-	BOOL success = TRUE;
-	
-	bool use_shaders = LLGLSLShader::sNoFixedFunction;
-
-	if (use_shaders)
-	{
-		gAlphaMaskProgram.bind();
-		gAlphaMaskProgram.setMinimumAlpha(0.004f);
-	}
-
-	LLVertexBuffer::unbind();
-
-	// Composite the color data
-	LLGLSUIDefault gls_ui;
-	success &= mTexLayerSet->render( mOrigin.mX, mOrigin.mY, mFullWidth, mFullHeight );
-	gGL.flush();
 
 	if(upload_now)
 	{
@@ -275,9 +239,10 @@ BOOL LLTexLayerSetBuffer::render()
 		}
 		else
 		{
-			if (mTexLayerSet->isVisible())
+			LLViewerTexLayerSet* layer_set = getViewerTexLayerSet();
+			if (layer_set->isVisible())
 			{
-				mTexLayerSet->getAvatar()->debugBakedTextureUpload(mTexLayerSet->getBakedTexIndex(), FALSE); // FALSE for start of upload, TRUE for finish.
+				layer_set->getAvatar()->debugBakedTextureUpload(layer_set->getBakedTexIndex(), FALSE); // FALSE for start of upload, TRUE for finish.
 				doUpload();
 			}
 			else
@@ -285,7 +250,7 @@ BOOL LLTexLayerSetBuffer::render()
 				mUploadPending = FALSE;
 				mNeedsUpload = FALSE;
 				mNeedsUploadTimer.pause();
-				mTexLayerSet->getAvatar()->setNewBakedTexture(mTexLayerSet->getBakedTexIndex(),IMG_INVISIBLE);
+				layer_set->getAvatar()->setNewBakedTexture(layer_set->getBakedTexIndex(),IMG_INVISIBLE);
 			}
 		}
 	}
@@ -294,51 +259,35 @@ BOOL LLTexLayerSetBuffer::render()
 	{
 		doUpdate();
 	}
-
-	if (use_shaders)
-	{
-		gAlphaMaskProgram.unbind();
-	}
-
-	LLVertexBuffer::unbind();
-	
-	// reset GL state
-	gGL.setColorMask(true, true);
-	gGL.setSceneBlendType(LLRender::BT_ALPHA);
-
-	// we have valid texture data now
-	mGLTexturep->setGLTextureCreated(true);
-
-	return success;
 }
 
-BOOL LLTexLayerSetBuffer::isInitialized(void) const
+BOOL LLViewerTexLayerSetBuffer::isInitialized(void) const
 {
 	return mGLTexturep.notNull() && mGLTexturep->isGLTextureCreated();
 }
 
-BOOL LLTexLayerSetBuffer::uploadPending() const
+BOOL LLViewerTexLayerSetBuffer::uploadPending() const
 {
 	return mUploadPending;
 }
 
-BOOL LLTexLayerSetBuffer::uploadNeeded() const
+BOOL LLViewerTexLayerSetBuffer::uploadNeeded() const
 {
 	return mNeedsUpload;
 }
 
-BOOL LLTexLayerSetBuffer::uploadInProgress() const
+BOOL LLViewerTexLayerSetBuffer::uploadInProgress() const
 {
 	return !mUploadID.isNull();
 }
 
-BOOL LLTexLayerSetBuffer::isReadyToUpload() const
+BOOL LLViewerTexLayerSetBuffer::isReadyToUpload() const
 {
 	if (!gAgentQueryManager.hasNoPendingQueries()) return FALSE; // Can't upload if there are pending queries.
 	if (isAgentAvatarValid() && !gAgentAvatarp->isUsingBakedTextures()) return FALSE; // Don't upload if avatar is using composites.
 
 	BOOL ready = FALSE;
-	if (mTexLayerSet->isLocalTextureDataFinal())
+	if (getViewerTexLayerSet()->isLocalTextureDataFinal())
 	{
 		// If we requested an upload and have the final LOD ready, upload (or wait a while if this is a retry)
 		if (mUploadFailCount == 0)
@@ -363,7 +312,7 @@ BOOL LLTexLayerSetBuffer::isReadyToUpload() const
 
 			// If we hit our timeout and have textures available at even lower resolution, then upload.
 			const BOOL is_upload_textures_timeout = mNeedsUploadTimer.getElapsedTimeF32() >= texture_timeout_threshold;
-			const BOOL has_lower_lod = mTexLayerSet->isLocalTextureDataAvailable();
+			const BOOL has_lower_lod = getViewerTexLayerSet()->isLocalTextureDataAvailable();
 			ready = has_lower_lod && is_upload_textures_timeout;
 		}
 	}
@@ -371,10 +320,10 @@ BOOL LLTexLayerSetBuffer::isReadyToUpload() const
 	return ready;
 }
 
-BOOL LLTexLayerSetBuffer::isReadyToUpdate() const
+BOOL LLViewerTexLayerSetBuffer::isReadyToUpdate() const
 {
 	// If we requested an update and have the final LOD ready, then update.
-	if (mTexLayerSet->isLocalTextureDataFinal()) return TRUE;
+	if (getViewerTexLayerSet()->isLocalTextureDataFinal()) return TRUE;
 
 	// If we haven't done an update yet, then just do one now regardless of state of textures.
 	if (mNumLowresUpdates == 0) return TRUE;
@@ -386,14 +335,14 @@ BOOL LLTexLayerSetBuffer::isReadyToUpdate() const
 	{
 		// If we hit our timeout and have textures available at even lower resolution, then update.
 		const BOOL is_update_textures_timeout = mNeedsUpdateTimer.getElapsedTimeF32() >= texture_timeout;
-		const BOOL has_lower_lod = mTexLayerSet->isLocalTextureDataAvailable();
+		const BOOL has_lower_lod = getViewerTexLayerSet()->isLocalTextureDataAvailable();
 		if (has_lower_lod && is_update_textures_timeout) return TRUE; 
 	}
 
 	return FALSE;
 }
 
-BOOL LLTexLayerSetBuffer::requestUpdateImmediate()
+BOOL LLViewerTexLayerSetBuffer::requestUpdateImmediate()
 {
 	mNeedsUpdate = TRUE;
 	BOOL result = FALSE;
@@ -410,14 +359,15 @@ BOOL LLTexLayerSetBuffer::requestUpdateImmediate()
 
 // Create the baked texture, send it out to the server, then wait for it to come
 // back so we can switch to using it.
-void LLTexLayerSetBuffer::doUpload()
+void LLViewerTexLayerSetBuffer::doUpload()
 {
-	llinfos << "Uploading baked " << mTexLayerSet->getBodyRegionName() << llendl;
+	LLViewerTexLayerSet* layer_set = getViewerTexLayerSet();
+	llinfos << "Uploading baked " << layer_set->getBodyRegionName() << llendl;
 	LLViewerStats::getInstance()->incStat(LLViewerStats::ST_TEX_BAKES);
 
 	// Don't need caches since we're baked now.  (note: we won't *really* be baked 
 	// until this image is sent to the server and the Avatar Appearance message is received.)
-	mTexLayerSet->deleteCaches();
+	layer_set->deleteCaches();
 
 	// Get the COLOR information from our texture
 	U8* baked_color_data = new U8[ mFullWidth * mFullHeight * 4 ];
@@ -428,7 +378,7 @@ void LLTexLayerSetBuffer::doUpload()
 	LLGLSUIDefault gls_ui;
 	LLPointer<LLImageRaw> baked_mask_image = new LLImageRaw(mFullWidth, mFullHeight, 1 );
 	U8* baked_mask_data = baked_mask_image->getData(); 
-	mTexLayerSet->gatherMorphMaskAlpha(baked_mask_data, mFullWidth, mFullHeight);
+	layer_set->gatherMorphMaskAlpha(baked_mask_data, mFullWidth, mFullHeight);
 
 
 	// Create the baked image from our color and mask information
@@ -475,10 +425,10 @@ void LLTexLayerSetBuffer::doUpload()
 			
 			if (valid)
 			{
-				const bool highest_lod = mTexLayerSet->isLocalTextureDataFinal();
+				const bool highest_lod = layer_set->isLocalTextureDataFinal();
 				// Baked_upload_data is owned by the responder and deleted after the request completes.
 				LLBakedUploadData* baked_upload_data = new LLBakedUploadData(gAgentAvatarp, 
-																			 this->mTexLayerSet, 
+																			 layer_set, 
 																			 asset_id,
 																			 highest_lod);
 				// upload ID is used to avoid overlaps, e.g. when the user rapidly makes two changes outside of Face Edit.
@@ -491,7 +441,7 @@ void LLTexLayerSetBuffer::doUpload()
 					&& (mUploadFailCount < (BAKE_UPLOAD_ATTEMPTS - 1))) // Try last ditch attempt via asset store if cap upload is failing.
 				{
 					LLSD body = LLSD::emptyMap();
-					// The responder will call LLTexLayerSetBuffer::onTextureUploadComplete()
+					// The responder will call LLViewerTexLayerSetBuffer::onTextureUploadComplete()
 					LLHTTPClient::post(url, body, new LLSendTexLayerResponder(body, mUploadID, LLAssetType::AT_TEXTURE, baked_upload_data));
 					llinfos << "Baked texture upload via capability of " << mUploadID << " to " << url << llendl;
 				} 
@@ -499,7 +449,7 @@ void LLTexLayerSetBuffer::doUpload()
 				{
 					gAssetStorage->storeAssetData(tid,
 												  LLAssetType::AT_TEXTURE,
-												  LLTexLayerSetBuffer::onTextureUploadComplete,
+												  LLViewerTexLayerSetBuffer::onTextureUploadComplete,
 												  baked_upload_data,
 												  TRUE,		// temp_file
 												  TRUE,		// is_priority
@@ -527,12 +477,12 @@ void LLTexLayerSetBuffer::doUpload()
 				{
 					const std::string lod_str = highest_lod ? "HighRes" : "LowRes";
 					LLSD args;
-					args["EXISTENCE"] = llformat("%d",(U32)mTexLayerSet->getAvatar()->debugGetExistenceTimeElapsedF32());
+					args["EXISTENCE"] = llformat("%d",(U32)layer_set->getAvatar()->debugGetExistenceTimeElapsedF32());
 					args["TIME"] = llformat("%d",(U32)mNeedsUploadTimer.getElapsedTimeF32());
-					args["BODYREGION"] = mTexLayerSet->getBodyRegionName();
+					args["BODYREGION"] = layer_set->getBodyRegionName();
 					args["RESOLUTION"] = lod_str;
 					LLNotificationsUtil::add("AvatarRezSelfBakedTextureUploadNotification",args);
-					LL_DEBUGS("Avatar") << self_av_string() << "Uploading [ name: " << mTexLayerSet->getBodyRegionName() << " res:" << lod_str << " time:" << (U32)mNeedsUploadTimer.getElapsedTimeF32() << " ]" << LL_ENDL;
+					LL_DEBUGS("Avatar") << self_av_string() << "Uploading [ name: " << layer_set->getBodyRegionName() << " res:" << lod_str << " time:" << (U32)mNeedsUploadTimer.getElapsedTimeF32() << " ]" << LL_ENDL;
 				}
 			}
 			else
@@ -557,9 +507,10 @@ void LLTexLayerSetBuffer::doUpload()
 
 // Mostly bookkeeping; don't need to actually "do" anything since
 // render() will actually do the update.
-void LLTexLayerSetBuffer::doUpdate()
+void LLViewerTexLayerSetBuffer::doUpdate()
 {
-	const BOOL highest_lod = mTexLayerSet->isLocalTextureDataFinal();
+	LLViewerTexLayerSet* layer_set = getViewerTexLayerSet();
+	const BOOL highest_lod = layer_set->isLocalTextureDataFinal();
 	if (highest_lod)
 	{
 		mNeedsUpdate = FALSE;
@@ -573,25 +524,25 @@ void LLTexLayerSetBuffer::doUpdate()
 
 	// need to switch to using this layerset if this is the first update
 	// after getting the lowest LOD
-	mTexLayerSet->getAvatar()->updateMeshTextures();
+	layer_set->getAvatar()->updateMeshTextures();
 	
 	// Print out notification that we updated this texture.
 	if (gSavedSettings.getBOOL("DebugAvatarRezTime"))
 	{
-		const BOOL highest_lod = mTexLayerSet->isLocalTextureDataFinal();
+		const BOOL highest_lod = layer_set->isLocalTextureDataFinal();
 		const std::string lod_str = highest_lod ? "HighRes" : "LowRes";
 		LLSD args;
-		args["EXISTENCE"] = llformat("%d",(U32)mTexLayerSet->getAvatar()->debugGetExistenceTimeElapsedF32());
+		args["EXISTENCE"] = llformat("%d",(U32)layer_set->getAvatar()->debugGetExistenceTimeElapsedF32());
 		args["TIME"] = llformat("%d",(U32)mNeedsUpdateTimer.getElapsedTimeF32());
-		args["BODYREGION"] = mTexLayerSet->getBodyRegionName();
+		args["BODYREGION"] = layer_set->getBodyRegionName();
 		args["RESOLUTION"] = lod_str;
 		LLNotificationsUtil::add("AvatarRezSelfBakedTextureUpdateNotification",args);
-		LL_DEBUGS("Avatar") << self_av_string() << "Locally updating [ name: " << mTexLayerSet->getBodyRegionName() << " res:" << lod_str << " time:" << (U32)mNeedsUpdateTimer.getElapsedTimeF32() << " ]" << LL_ENDL;
+		LL_DEBUGS("Avatar") << self_av_string() << "Locally updating [ name: " << layer_set->getBodyRegionName() << " res:" << lod_str << " time:" << (U32)mNeedsUpdateTimer.getElapsedTimeF32() << " ]" << LL_ENDL;
 	}
 }
 
 // static
-void LLTexLayerSetBuffer::onTextureUploadComplete(const LLUUID& uuid,
+void LLViewerTexLayerSetBuffer::onTextureUploadComplete(const LLUUID& uuid,
 												  void* userdata,
 												  S32 result,
 												  LLExtStat ext_status) // StoreAssetData callback (not fixed)
@@ -603,7 +554,7 @@ void LLTexLayerSetBuffer::onTextureUploadComplete(const LLUUID& uuid,
 		(baked_upload_data->mAvatar == gAgentAvatarp) && // Sanity check: only the user's avatar should be uploading textures.
 		(baked_upload_data->mTexLayerSet->hasComposite()))
 	{
-		LLTexLayerSetBuffer* layerset_buffer = baked_upload_data->mTexLayerSet->getComposite();
+		LLViewerTexLayerSetBuffer* layerset_buffer = baked_upload_data->mTexLayerSet->getViewerComposite();
 		S32 failures = layerset_buffer->mUploadFailCount;
 		layerset_buffer->mUploadFailCount = 0;
 
@@ -627,7 +578,7 @@ void LLTexLayerSetBuffer::onTextureUploadComplete(const LLUUID& uuid,
 			if (result >= 0)
 			{
 				layerset_buffer->mUploadPending = FALSE; // Allows sending of AgentSetAppearance later
-				LLAvatarAppearanceDefines::ETextureIndex baked_te = gAgentAvatarp->getBakedTE(layerset_buffer->mTexLayerSet);
+				LLAvatarAppearanceDefines::ETextureIndex baked_te = gAgentAvatarp->getBakedTE(layerset_buffer->getViewerTexLayerSet());
 				// Update baked texture info with the new UUID
 				U64 now = LLFrameTimer::getTotalTime();		// Record starting time
 				llinfos << "Baked" << resolution << "texture upload for " << name << " took " << (S32)((now - baked_upload_data->mStartTime) / 1000) << " ms" << llendl;
@@ -673,7 +624,6 @@ void LLTexLayerSetBuffer::onTextureUploadComplete(const LLUUID& uuid,
 
 LLViewerTexLayerSet::LLViewerTexLayerSet(LLAvatarAppearance* const appearance) :
 	LLTexLayerSet(appearance),
-	mComposite( NULL ),
 	mUpdatesEnabled( FALSE )
 {
 }
@@ -704,24 +654,31 @@ void LLViewerTexLayerSet::requestUpdate()
 	if( mUpdatesEnabled )
 	{
 		createComposite();
-		mComposite->requestUpdate(); 
+		getViewerComposite()->requestUpdate(); 
 	}
 }
 
 void LLViewerTexLayerSet::requestUpload()
 {
 	createComposite();
-	mComposite->requestUpload();
+	getViewerComposite()->requestUpload();
 }
 
 void LLViewerTexLayerSet::cancelUpload()
 {
 	if(mComposite)
 	{
-		mComposite->cancelUpload();
+		getViewerComposite()->cancelUpload();
 	}
 }
 
+void LLViewerTexLayerSet::updateComposite()
+{
+	createComposite();
+	getViewerComposite()->requestUpdateImmediate();
+}
+
+// virtual
 void LLViewerTexLayerSet::createComposite()
 {
 	if(!mComposite)
@@ -733,15 +690,7 @@ void LLViewerTexLayerSet::createComposite()
 		{
 			llerrs << "composites should not be created for non-self avatars!" << llendl;
 		}
-		mComposite = new LLTexLayerSetBuffer( this, width, height );
-	}
-}
-
-void LLViewerTexLayerSet::destroyComposite()
-{
-	if( mComposite )
-	{
-		mComposite = NULL;
+		mComposite = new LLViewerTexLayerSetBuffer( this, width, height );
 	}
 }
 
@@ -751,26 +700,6 @@ void LLViewerTexLayerSet::setUpdatesEnabled( BOOL b )
 }
 
 
-void LLViewerTexLayerSet::updateComposite()
-{
-	createComposite();
-	mComposite->requestUpdateImmediate();
-}
-
-LLTexLayerSetBuffer* LLViewerTexLayerSet::getComposite()
-{
-	if (!mComposite)
-	{
-		createComposite();
-	}
-	return mComposite;
-}
-
-const LLTexLayerSetBuffer* LLViewerTexLayerSet::getComposite() const
-{
-	return mComposite;
-}
-
 void LLViewerTexLayerSet::gatherMorphMaskAlpha(U8 *data, S32 width, S32 height)
 {
 	memset(data, 255, width * height);
@@ -778,29 +707,44 @@ void LLViewerTexLayerSet::gatherMorphMaskAlpha(U8 *data, S32 width, S32 height)
 	for( layer_list_t::iterator iter = mLayerList.begin(); iter != mLayerList.end(); iter++ )
 	{
 		LLTexLayerInterface* layer = *iter;
-		layer->gatherAlphaMasks(data, mComposite->getOriginX(),mComposite->getOriginY(), width, height);
+		layer->gatherAlphaMasks(data, getViewerComposite()->getOriginX(),
+								getViewerComposite()->getOriginY(), width, height);
 	}
 	
 	// Set alpha back to that of our alpha masks.
-	renderAlphaMaskTextures(mComposite->getOriginX(), mComposite->getOriginY(), width, height, true);
+	renderAlphaMaskTextures(getViewerComposite()->getOriginX(), 
+							getViewerComposite()->getOriginY(), width, height, true);
 }
 
-
-LLVOAvatarSelf* LLViewerTexLayerSet::getAvatar() const
+LLVOAvatarSelf* LLViewerTexLayerSet::getAvatar()
 {
 	return dynamic_cast<LLVOAvatarSelf*> (mAvatarAppearance);
 }
 
+const LLVOAvatarSelf* LLViewerTexLayerSet::getAvatar() const
+{
+	return dynamic_cast<const LLVOAvatarSelf*> (mAvatarAppearance);
+}
+
+LLViewerTexLayerSetBuffer* LLViewerTexLayerSet::getViewerComposite()
+{
+	return dynamic_cast<LLViewerTexLayerSetBuffer*> (getComposite());
+}
+
+const LLViewerTexLayerSetBuffer* LLViewerTexLayerSet::getViewerComposite() const
+{
+	return dynamic_cast<const LLViewerTexLayerSetBuffer*> (getComposite());
+}
 
 
-const std::string LLTexLayerSetBuffer::dumpTextureInfo() const
+const std::string LLViewerTexLayerSetBuffer::dumpTextureInfo() const
 {
 	if (!isAgentAvatarValid()) return "";
 
 	const BOOL is_high_res = !mNeedsUpload;
 	const U32 num_low_res = mNumLowresUploads;
 	const U32 upload_time = (U32)mNeedsUploadTimer.getElapsedTimeF32();
-	const std::string local_texture_info = gAgentAvatarp->debugDumpLocalTextureDataInfo(mTexLayerSet);
+	const std::string local_texture_info = gAgentAvatarp->debugDumpLocalTextureDataInfo(getViewerTexLayerSet());
 
 	std::string status 				= "CREATING ";
 	if (!uploadNeeded()) status 	= "DONE     ";
diff --git a/indra/newview/llviewertexlayer.h b/indra/newview/llviewertexlayer.h
index 125bf82adffa13f128409c621a80abe5c2b8d025..6788214f3aff091c09c434d043e2f83e1bfc1440 100644
--- a/indra/newview/llviewertexlayer.h
+++ b/indra/newview/llviewertexlayer.h
@@ -31,7 +31,7 @@
 #include "lltexlayer.h"
 
 class LLVOAvatarSelf;
-class LLTexLayerSetBuffer;
+class LLViewerTexLayerSetBuffer;
 
 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 // LLViewerTexLayerSet
@@ -41,46 +41,43 @@ class LLTexLayerSetBuffer;
 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 class LLViewerTexLayerSet : public LLTexLayerSet
 {
-	friend class LLTexLayerSetBuffer;
 public:
 	LLViewerTexLayerSet(LLAvatarAppearance* const appearance);
 	virtual ~LLViewerTexLayerSet();
 
-	LLTexLayerSetBuffer*		getComposite();
-	const LLTexLayerSetBuffer* 	getComposite() const; // Do not create one if it doesn't exist.
 	virtual void				requestUpdate();
 	void						requestUpload();
 	void						cancelUpload();
-	void						updateComposite();
 	BOOL						isLocalTextureDataAvailable() const;
 	BOOL						isLocalTextureDataFinal() const;
-	void						createComposite();
-	void						destroyComposite();
+	void						updateComposite();
+	/*virtual*/void				createComposite();
 	void						setUpdatesEnabled(BOOL b);
 	BOOL						getUpdatesEnabled()	const 	{ return mUpdatesEnabled; }
 	void						gatherMorphMaskAlpha(U8 *data, S32 width, S32 height);
 
-	LLVOAvatarSelf*				getAvatar()	const;
-	BOOL						hasComposite() const 		{ return (mComposite.notNull()); }
+	LLVOAvatarSelf*				getAvatar();
+	const LLVOAvatarSelf*		getAvatar()	const;
+	LLViewerTexLayerSetBuffer*	getViewerComposite();
+	const LLViewerTexLayerSetBuffer*	getViewerComposite() const;
 
 private:
-	LLPointer<LLTexLayerSetBuffer>	mComposite;
 	BOOL						mUpdatesEnabled;
 
 };
 
 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// LLTexLayerSetBuffer
+// LLViewerTexLayerSetBuffer
 //
-// The composite image that a LLViewerTexLayerSet writes to.  Each LLTexLayerSet has one.
+// The composite image that a LLViewerTexLayerSet writes to.  Each LLViewerTexLayerSet has one.
 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-class LLTexLayerSetBuffer : public LLViewerDynamicTexture
+class LLViewerTexLayerSetBuffer : public LLTexLayerSetBuffer, public LLViewerDynamicTexture
 {
-	LOG_CLASS(LLTexLayerSetBuffer);
+	LOG_CLASS(LLViewerTexLayerSetBuffer);
 
 public:
-	LLTexLayerSetBuffer(LLViewerTexLayerSet* const owner, S32 width, S32 height);
-	virtual ~LLTexLayerSetBuffer();
+	LLViewerTexLayerSetBuffer(LLTexLayerSet* const owner, S32 width, S32 height);
+	virtual ~LLViewerTexLayerSetBuffer();
 
 public:
 	/*virtual*/ S8          getType() const;
@@ -89,23 +86,34 @@ public:
 	const std::string		dumpTextureInfo() const;
 	virtual void 			restoreGLTexture();
 	virtual void 			destroyGLTexture();
-protected:
-	void					pushProjection() const;
-	void					popProjection() const;
 private:
-	LLViewerTexLayerSet* const	mTexLayerSet;
+	LLViewerTexLayerSet*	getViewerTexLayerSet() 
+		{ return dynamic_cast<LLViewerTexLayerSet*> (mTexLayerSet); }
+	const LLViewerTexLayerSet*	getViewerTexLayerSet() const
+		{ return dynamic_cast<const LLViewerTexLayerSet*> (mTexLayerSet); }
 	static S32				sGLByteCount;
 
 	//--------------------------------------------------------------------
-	// Render
+	// Tex Layer Render
+	//--------------------------------------------------------------------
+	virtual void			preRenderTexLayerSet();
+	virtual void			midRenderTexLayerSet(BOOL success);
+	virtual void			postRenderTexLayerSet(BOOL success);
+	virtual S32				getCompositeOriginX() const { return getOriginX(); }
+	virtual S32				getCompositeOriginY() const { return getOriginY(); }
+	virtual S32				getCompositeWidth() const { return getFullWidth(); }
+	virtual S32				getCompositeHeight() const { return getFullHeight(); }
+
+	//--------------------------------------------------------------------
+	// Dynamic Texture Interface
 	//--------------------------------------------------------------------
 public:
 	/*virtual*/ BOOL		needsRender();
 protected:
-	BOOL					render(S32 x, S32 y, S32 width, S32 height);
-	virtual void			preRender(BOOL clear_depth);
-	virtual void			postRender(BOOL success);
-	virtual BOOL			render();	
+	// Pass these along for tex layer rendering.
+	virtual void			preRender(BOOL clear_depth) { preRenderTexLayerSet(); }
+	virtual void			postRender(BOOL success) { postRenderTexLayerSet(success); }
+	virtual BOOL			render() { return renderTexLayerSet(); }
 	
 	//--------------------------------------------------------------------
 	// Uploads
diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp
index 56ded53b5d1324e00340dc49a7c9d015f8bd18e3..4e17884e0e428b5e94ebfa399a2a153c99d1a32b 100755
--- a/indra/newview/llvoavatar.cpp
+++ b/indra/newview/llvoavatar.cpp
@@ -6722,7 +6722,7 @@ void LLVOAvatar::updateMeshTextures()
 			// use the last-known good baked texture until it finish the first
 			// render of the new layerset.
 			const BOOL layerset_invalid = mBakedTextureDatas[i].mTexLayerSet 
-										  && ( !mBakedTextureDatas[i].mTexLayerSet->getComposite()->isInitialized()
+										  && ( !mBakedTextureDatas[i].mTexLayerSet->getViewerComposite()->isInitialized()
 										  || !mBakedTextureDatas[i].mTexLayerSet->isLocalTextureDataAvailable() );
 			use_lkg_baked_layer[i] = (!is_layer_baked[i] 
 									  && (mBakedTextureDatas[i].mLastTextureIndex != IMG_DEFAULT_AVATAR) 
diff --git a/indra/newview/llvoavatarself.cpp b/indra/newview/llvoavatarself.cpp
index ec37e6f301a0116c68157923e36e51aa2ea3bf75..e836a5e4a8f65afd42495a33c47ed5ccf6ecaea1 100755
--- a/indra/newview/llvoavatarself.cpp
+++ b/indra/newview/llvoavatarself.cpp
@@ -1519,7 +1519,7 @@ BOOL LLVOAvatarSelf::isBakedTextureFinal(const LLAvatarAppearanceDefines::EBaked
 {
 	const LLViewerTexLayerSet *layerset = mBakedTextureDatas[index].mTexLayerSet;
 	if (!layerset) return FALSE;
-	const LLTexLayerSetBuffer *layerset_buffer = layerset->getComposite();
+	const LLViewerTexLayerSetBuffer *layerset_buffer = layerset->getViewerComposite();
 	if (!layerset_buffer) return FALSE;
 	return !layerset_buffer->uploadNeeded();
 }
@@ -1614,7 +1614,7 @@ bool LLVOAvatarSelf::hasPendingBakedUploads() const
 	for (U32 i = 0; i < mBakedTextureDatas.size(); i++)
 	{
 		LLViewerTexLayerSet* layerset = mBakedTextureDatas[i].mTexLayerSet;
-		if (layerset && layerset->getComposite() && layerset->getComposite()->uploadPending())
+		if (layerset && layerset->getViewerComposite() && layerset->getViewerComposite()->uploadPending())
 		{
 			return true;
 		}
@@ -2517,7 +2517,7 @@ void LLVOAvatarSelf::outputRezDiagnostics() const
 		const LLAvatarAppearanceDefines::EBakedTextureIndex baked_index = baked_iter->first;
 		const LLViewerTexLayerSet *layerset = debugGetLayerSet(baked_index);
 		if (!layerset) continue;
-		const LLTexLayerSetBuffer *layerset_buffer = layerset->getComposite();
+		const LLViewerTexLayerSetBuffer *layerset_buffer = layerset->getViewerComposite();
 		if (!layerset_buffer) continue;
 		LL_DEBUGS("Avatar") << layerset_buffer->dumpTextureInfo() << llendl;
 	}