diff --git a/indra/llrender/llglslshader.cpp b/indra/llrender/llglslshader.cpp
index 52b8de8365e33aad52101c46ad8e0f33f98b4899..8790b1ed7d7455ff490deb0e7cf1fab555b7cc02 100755
--- a/indra/llrender/llglslshader.cpp
+++ b/indra/llrender/llglslshader.cpp
@@ -1278,6 +1278,28 @@ void LLGLSLShader::uniformMatrix4fv(U32 index, U32 count, GLboolean transpose, c
     }
 }
 
+void LLGLSLShader::uniform1b(U32 index, GLboolean x)
+{
+	if (mProgramObject > 0)
+	{
+		if (mUniform.size() <= index)
+		{
+			UNIFORM_ERRS << "Uniform index out of bounds." << LL_ENDL;
+			return;
+		}
+
+		if (mUniform[index] >= 0)
+		{
+			std::map<GLint, LLVector4>::iterator iter = mValue.find(mUniform[index]);
+			if (iter == mValue.end() || iter->second.mV[0] != x)
+			{
+				glUniform1iARB(mUniform[index], x);
+				mValue[mUniform[index]] = LLVector4(x, 0.f, 0.f, 0.f);
+			}
+		}
+	}
+}
+
 GLint LLGLSLShader::getUniformLocation(const LLStaticHashedString& uniform)
 {
     GLint ret = -1;
diff --git a/indra/llrender/llglslshader.h b/indra/llrender/llglslshader.h
index 0746e8760abfbd5426f60502f631d812f10d12b4..8663a5a5ffe5bdf4a7e01fd0f9777f34dd856755 100755
--- a/indra/llrender/llglslshader.h
+++ b/indra/llrender/llglslshader.h
@@ -125,6 +125,7 @@ class LLGLSLShader
 	void uniform3fv(const LLStaticHashedString& uniform, U32 count, const GLfloat* v);
 	void uniform4fv(const LLStaticHashedString& uniform, U32 count, const GLfloat* v);
 	void uniformMatrix4fv(const LLStaticHashedString& uniform, U32 count, GLboolean transpose, const GLfloat *v);
+	void uniform1b(U32 index, GLboolean b);
 
 	void setMinimumAlpha(F32 minimum);
 
diff --git a/indra/llrender/llrender.cpp b/indra/llrender/llrender.cpp
index 69420dd0bb338b07539a62847916ddfdc443743b..b5ed67f66a8a6b5d1eda50d0d2ae172839389529 100755
--- a/indra/llrender/llrender.cpp
+++ b/indra/llrender/llrender.cpp
@@ -1466,6 +1466,14 @@ U32 LLRender::getMatrixMode()
 	return mMatrixMode;
 }
 
+void LLRender::setInverseTexCoordByY(bool v)
+{
+	LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr;
+	if (shader)
+	{
+		shader->uniform1b(LLShaderMgr::INVERSE_TEX_Y, v);
+	}
+}
 
 void LLRender::loadIdentity()
 {
diff --git a/indra/llrender/llrender.h b/indra/llrender/llrender.h
index a67fb8da522ff130259d44b2e02deb94c4f3eaa8..4c3547f8e40314c457e2e2afe89325a9e9a5a818 100755
--- a/indra/llrender/llrender.h
+++ b/indra/llrender/llrender.h
@@ -355,6 +355,7 @@ class LLRender
 	void multMatrix(const GLfloat* m);
 	void matrixMode(U32 mode);	
 	U32 getMatrixMode();
+	void setInverseTexCoordByY(bool v);
 
 	const glh::matrix4f& getModelviewMatrix();
 	const glh::matrix4f& getProjectionMatrix();
diff --git a/indra/llrender/llshadermgr.cpp b/indra/llrender/llshadermgr.cpp
index b2be3cc3b6cd30c2804e6756493f23816a13f01f..79e0b3da2804a4c65d853af4c6badd8b4fdbb26b 100755
--- a/indra/llrender/llshadermgr.cpp
+++ b/indra/llrender/llshadermgr.cpp
@@ -1206,6 +1206,7 @@ void LLShaderMgr::initAttribsAndUniforms()
 
 	mReservedUniforms.push_back("origin");
 	mReservedUniforms.push_back("display_gamma");
+	mReservedUniforms.push_back("invert_tex_y");
 	llassert(mReservedUniforms.size() == END_RESERVED_UNIFORMS);
 
 	std::set<std::string> dupe_check;
diff --git a/indra/llrender/llshadermgr.h b/indra/llrender/llshadermgr.h
index 394b38f832329964798deee031671f4b6d715fa2..50b7c8b9d9a71ddf6883042cca98e618dea62849 100755
--- a/indra/llrender/llshadermgr.h
+++ b/indra/llrender/llshadermgr.h
@@ -215,7 +215,8 @@ class LLShaderMgr
 		TERRAIN_ALPHARAMP,
 		
 		SHINY_ORIGIN,
-DISPLAY_GAMMA,
+		DISPLAY_GAMMA,
+		INVERSE_TEX_Y,
 		END_RESERVED_UNIFORMS
 	} eGLSLReservedUniforms;
 
diff --git a/indra/newview/app_settings/shaders/class1/deferred/diffuseV.glsl b/indra/newview/app_settings/shaders/class1/deferred/diffuseV.glsl
index 3c026796c8b3a7fdd9e8df4076dfbc3561c12218..7e83389f6e4f8cb96181422b6639ab98177b8557 100755
--- a/indra/newview/app_settings/shaders/class1/deferred/diffuseV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/diffuseV.glsl
@@ -26,6 +26,13 @@
 uniform mat3 normal_matrix;
 uniform mat4 texture_matrix0;
 uniform mat4 modelview_projection_matrix;
+uniform bool invert_tex_y = false;
+const mat4 invTexM = mat4(
+  1, 0, 0, 0,
+  0,-1, 0, 0,
+  0, 0, 1, 0,
+  0, 0, 0, 1
+); 
 
 ATTRIBUTE vec3 position;
 ATTRIBUTE vec4 diffuse_color;
@@ -44,6 +51,10 @@ void main()
 	//transform vertex
 	gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0); 
 	vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
+  if(invert_tex_y) 
+	{
+		vary_texcoord0 = vec2(invTexM * vec4(vary_texcoord0,0,1)).xy;
+	}
 	
 	passTextureIndex();
 	vary_normal = normalize(normal_matrix * normal);
diff --git a/indra/newview/app_settings/shaders/class1/deferred/fullbrightV.glsl b/indra/newview/app_settings/shaders/class1/deferred/fullbrightV.glsl
index 8e899e3e0f32df89f36b81531d979ced9b57f534..259571288234ef4c2f1b3c420d7b79ebe6d11be6 100755
--- a/indra/newview/app_settings/shaders/class1/deferred/fullbrightV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/fullbrightV.glsl
@@ -26,6 +26,13 @@
 uniform mat4 texture_matrix0;
 uniform mat4 modelview_matrix;
 uniform mat4 modelview_projection_matrix;
+uniform bool invert_tex_y = false;
+const mat4 invTexM = mat4(
+  1, 0, 0, 0,
+  0,-1, 0, 0,
+  0, 0, 1, 0,
+  0, 0, 0, 1
+);
 
 
 ATTRIBUTE vec3 position;
@@ -62,6 +69,10 @@ void main()
 #endif
 
 	vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
+  if(invert_tex_y) 
+	{
+		vary_texcoord0 = vec2(invTexM * vec4(vary_texcoord0,0,1)).xy;
+	}
 	
 	calcAtmospherics(pos.xyz);
 
diff --git a/indra/newview/app_settings/shaders/class1/objects/fullbrightV.glsl b/indra/newview/app_settings/shaders/class1/objects/fullbrightV.glsl
index fc20d3270e2a349931b972de5e8a1117b9d0597c..a8efcd9857d44f146e7802f601a06f6da2693130 100755
--- a/indra/newview/app_settings/shaders/class1/objects/fullbrightV.glsl
+++ b/indra/newview/app_settings/shaders/class1/objects/fullbrightV.glsl
@@ -26,6 +26,14 @@
 uniform mat4 texture_matrix0;
 uniform mat4 modelview_matrix;
 uniform mat4 modelview_projection_matrix;
+
+uniform bool invert_tex_y = false;
+const mat4 invTexM = mat4(
+  1, 0, 0, 0,
+  0,-1, 0, 0,
+  0, 0, 1, 0,
+  0, 0, 0, 1
+);
  
 ATTRIBUTE vec3 position;
 void passTextureIndex();
@@ -49,6 +57,11 @@ void main()
 	vec4 pos = (modelview_matrix * vert);
 	gl_Position = modelview_projection_matrix*vec4(position.xyz, 1.0);
 	vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
+  
+  if(invert_tex_y) 
+	{
+		vary_texcoord0 = vec2(invTexM * vec4(vary_texcoord0,0,1)).xy;
+	}
 	
 	calcAtmospherics(pos.xyz);
 
diff --git a/indra/newview/app_settings/shaders/class1/objects/simpleV.glsl b/indra/newview/app_settings/shaders/class1/objects/simpleV.glsl
index 37a20383e2c8499eaba3d370b63f7edab9958de9..c744dc13977e1a92ff172beda33d08ebb536a694 100755
--- a/indra/newview/app_settings/shaders/class1/objects/simpleV.glsl
+++ b/indra/newview/app_settings/shaders/class1/objects/simpleV.glsl
@@ -27,6 +27,13 @@ uniform mat3 normal_matrix;
 uniform mat4 texture_matrix0;
 uniform mat4 modelview_matrix;
 uniform mat4 modelview_projection_matrix;
+uniform bool invert_tex_y = false;
+const mat4 invTexM = mat4(
+  1, 0, 0, 0,
+  0,-1, 0, 0,
+  0, 0, 1, 0,
+  0, 0, 0, 1
+); 
 
 ATTRIBUTE vec3 position;
 void passTextureIndex();
@@ -51,7 +58,10 @@ void main()
 	gl_Position = modelview_projection_matrix*vec4(position.xyz, 1.0);
 	vary_texcoord0 = (texture_matrix0 * vec4(texcoord0, 0, 1)).xy;
 	
-	
+	if(invert_tex_y) 
+	{
+		vary_texcoord0 = vec2(invTexM * vec4(vary_texcoord0,0,1)).xy;
+	}
 	
 	vec3 norm = normalize(normal_matrix * normal);
 
diff --git a/indra/newview/lldrawpool.cpp b/indra/newview/lldrawpool.cpp
index f74164aea6b234e5cf1ea0f50210bcec8b5789b1..a6cf917cbdc7200d66c356274d913984f3fb0d32 100755
--- a/indra/newview/lldrawpool.cpp
+++ b/indra/newview/lldrawpool.cpp
@@ -473,6 +473,10 @@ void LLRenderPass::pushBatch(LLDrawInfo& params, U32 mask, BOOL texture, BOOL ba
 				if (params.mTextureList[i].notNull())
 				{
 					gGL.getTexUnit(i)->bind(params.mTextureList[i], TRUE);
+					if (LLViewerTexture::MEDIA_TEXTURE == params.mTextureList[i]->getType())
+					{
+						gGL.setInverseTexCoordByY(true);
+					}
 				}
 			}
 		}
@@ -482,13 +486,54 @@ void LLRenderPass::pushBatch(LLDrawInfo& params, U32 mask, BOOL texture, BOOL ba
 			{
 				params.mTexture->addTextureStats(params.mVSize);
 				gGL.getTexUnit(0)->bind(params.mTexture, TRUE) ;
+
+				if (!gPipeline.mVertexShadersEnabled)
+				{
+					if (LLViewerTexture::MEDIA_TEXTURE == params.mTexture->getType() && !params.mTextureMatrix)
+					{
+						static const float fIdntInvY[] = {
+							1, 0, 0, 0,
+							0, -1, 0, 0,
+							0, 0, 1, 0,
+							0, 0, 0, 1
+						};
+
+						gGL.getTexUnit(0)->activate();
+						gGL.matrixMode(LLRender::MM_TEXTURE);
+						gGL.loadMatrix((GLfloat*)fIdntInvY);
+						gPipeline.mTextureMatrixOps++;
+
+						tex_setup = true;
+					}
+				}
+				else
+				{
+					gGL.setInverseTexCoordByY(LLViewerTexture::MEDIA_TEXTURE == params.mTexture->getType());
+				}
+
 				if (params.mTextureMatrix)
 				{
 					tex_setup = true;
 					gGL.getTexUnit(0)->activate();
 					gGL.matrixMode(LLRender::MM_TEXTURE);
 					gGL.loadMatrix((GLfloat*) params.mTextureMatrix->mMatrix);
+
+					if (LLViewerTexture::MEDIA_TEXTURE == params.mTexture->getType() && !gPipeline.mVertexShadersEnabled)
+					{
+						static const float fIdntInvY[] = {
+							1, 0, 0, 0,
+							0, -1, 0, 0,
+							0, 0, 1, 0,
+							0, 0, 0, 1
+						};
+
+						gGL.multMatrix(fIdntInvY);
+						gPipeline.mMatrixOpCount++;
+					}
+
 					gPipeline.mTextureMatrixOps++;
+
+					tex_setup = true;
 				}
 			}
 			else