|  | @@ -548,13 +548,19 @@ void Shader::attach(bool temporary)
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  		if (!temporary)
 | 
	
		
			
				|  |  |  		{
 | 
	
		
			
				|  |  | -			// make sure all sent textures are properly bound to their respective texture units
 | 
	
		
			
				|  |  | -			// note: list potentially contains texture ids of deleted/invalid textures!
 | 
	
		
			
				|  |  | +			// Make sure all textures are properly bound to their respective
 | 
	
		
			
				|  |  | +			// texture units.
 | 
	
		
			
				|  |  |  			for (int i = 1; i < (int) textureUnits.size(); ++i)
 | 
	
		
			
				|  |  |  			{
 | 
	
		
			
				|  |  |  				if (textureUnits[i].active)
 | 
	
		
			
				|  |  |  					gl.bindTextureToUnit(textureUnits[i].texture, i, false);
 | 
	
		
			
				|  |  |  			}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +			// send any pending uniforms to the shader program.
 | 
	
		
			
				|  |  | +			for (const auto &p : pendingUniformUpdates)
 | 
	
		
			
				|  |  | +				updateUniform(p.first, p.second);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +			pendingUniformUpdates.clear();
 | 
	
		
			
				|  |  |  		}
 | 
	
		
			
				|  |  |  	}
 | 
	
		
			
				|  |  |  }
 | 
	
	
		
			
				|  | @@ -587,11 +593,15 @@ const Shader::UniformInfo *Shader::getUniformInfo(const std::string &name) const
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  void Shader::updateUniform(const UniformInfo *info, int count, bool internalUpdate)
 | 
	
		
			
				|  |  |  {
 | 
	
		
			
				|  |  | +	if (current != this)
 | 
	
		
			
				|  |  | +	{
 | 
	
		
			
				|  |  | +		pendingUniformUpdates.push_back(std::make_pair(info, count));
 | 
	
		
			
				|  |  | +		return;
 | 
	
		
			
				|  |  | +	}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |  	if (!internalUpdate)
 | 
	
		
			
				|  |  |  		flushStreamDraws();
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -	TemporaryAttacher attacher(this, !internalUpdate);
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  |  	int location = info->location;
 | 
	
		
			
				|  |  |  	UniformType type = info->baseType;
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -682,7 +692,9 @@ void Shader::sendTextures(const UniformInfo *info, Texture **textures, int count
 | 
	
		
			
				|  |  |  	if (info->baseType != UNIFORM_SAMPLER)
 | 
	
		
			
				|  |  |  		return;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -	if (!internalUpdate)
 | 
	
		
			
				|  |  | +	bool shaderactive = current == this;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	if (!internalUpdate && shaderactive)
 | 
	
		
			
				|  |  |  		flushStreamDraws();
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  	count = std::min(count, info->count);
 | 
	
	
		
			
				|  | @@ -721,14 +733,17 @@ void Shader::sendTextures(const UniformInfo *info, Texture **textures, int count
 | 
	
		
			
				|  |  |  		{
 | 
	
		
			
				|  |  |  			GLuint gltex = (GLuint) textures[i]->getHandle();
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -			gl.bindTextureToUnit(gltex, texunit, false);
 | 
	
		
			
				|  |  | +			if (shaderactive)
 | 
	
		
			
				|  |  | +				gl.bindTextureToUnit(gltex, texunit, false);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -			// store texture id so it can be re-bound to the proper texture unit later
 | 
	
		
			
				|  |  | +			// Store texture id so it can be re-bound to the texture unit later.
 | 
	
		
			
				|  |  |  			textureUnits[texunit].texture = gltex;
 | 
	
		
			
				|  |  |  		}
 | 
	
		
			
				|  |  |  		else
 | 
	
		
			
				|  |  |  		{
 | 
	
		
			
				|  |  | -			gl.bindTextureToUnit((GLuint) 0, texunit, false);
 | 
	
		
			
				|  |  | +			if (shaderactive)
 | 
	
		
			
				|  |  | +				gl.bindTextureToUnit((GLuint) 0, texunit, false);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |  			textureUnits[texunit].texture = 0;
 | 
	
		
			
				|  |  |  			textureUnits[texunit].active = false;
 | 
	
		
			
				|  |  |  		}
 | 
	
	
		
			
				|  | @@ -812,7 +827,8 @@ void Shader::setVideoTextures(GLuint ytexture, GLuint cbtexture, GLuint crtextur
 | 
	
		
			
				|  |  |  		{
 | 
	
		
			
				|  |  |  			// Store texture id so it can be re-bound later.
 | 
	
		
			
				|  |  |  			textureUnits[videoTextureUnits[i]].texture = textures[i];
 | 
	
		
			
				|  |  | -			gl.bindTextureToUnit(textures[i], videoTextureUnits[i], false);
 | 
	
		
			
				|  |  | +			if (current == this)
 | 
	
		
			
				|  |  | +				gl.bindTextureToUnit(textures[i], videoTextureUnits[i], false);
 | 
	
		
			
				|  |  |  		}
 | 
	
		
			
				|  |  |  	}
 | 
	
		
			
				|  |  |  }
 | 
	
	
		
			
				|  | @@ -824,7 +840,7 @@ void Shader::checkSetScreenParams()
 | 
	
		
			
				|  |  |  	auto gfx = Module::getInstance<Graphics>(Module::M_GRAPHICS);
 | 
	
		
			
				|  |  |  	bool canvasActive = gfx->isCanvasActive();
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -	if (view == lastViewport && canvasWasActive == canvasActive)
 | 
	
		
			
				|  |  | +	if ((view == lastViewport && canvasWasActive == canvasActive) || current != this)
 | 
	
		
			
				|  |  |  		return;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  	// In the shader, we do pixcoord.y = gl_FragCoord.y * params.z + params.w.
 | 
	
	
		
			
				|  | @@ -850,12 +866,8 @@ void Shader::checkSetScreenParams()
 | 
	
		
			
				|  |  |  	}
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  	GLint location = builtinUniforms[BUILTIN_SCREEN_SIZE];
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  |  	if (location >= 0)
 | 
	
		
			
				|  |  | -	{
 | 
	
		
			
				|  |  | -		TemporaryAttacher attacher(this, true);
 | 
	
		
			
				|  |  |  		glUniform4fv(location, 1, params);
 | 
	
		
			
				|  |  | -	}
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  	canvasWasActive = canvasActive;
 | 
	
		
			
				|  |  |  	lastViewport = view;
 | 
	
	
		
			
				|  | @@ -863,22 +875,21 @@ void Shader::checkSetScreenParams()
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  void Shader::checkSetPointSize(float size)
 | 
	
		
			
				|  |  |  {
 | 
	
		
			
				|  |  | -	if (size == lastPointSize)
 | 
	
		
			
				|  |  | +	if (size == lastPointSize || current != this)
 | 
	
		
			
				|  |  |  		return;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  	GLint location = builtinUniforms[BUILTIN_POINT_SIZE];
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  |  	if (location >= 0)
 | 
	
		
			
				|  |  | -	{
 | 
	
		
			
				|  |  | -		TemporaryAttacher attacher(this, true);
 | 
	
		
			
				|  |  |  		glUniform1f(location, size);
 | 
	
		
			
				|  |  | -	}
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  	lastPointSize = size;
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  void Shader::checkSetBuiltinUniforms()
 | 
	
		
			
				|  |  |  {
 | 
	
		
			
				|  |  | +	if (current != this)
 | 
	
		
			
				|  |  | +		return;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |  	checkSetScreenParams();
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  	// We use a more efficient method for sending transformation matrices to
 | 
	
	
		
			
				|  | @@ -888,10 +899,9 @@ void Shader::checkSetBuiltinUniforms()
 | 
	
		
			
				|  |  |  		checkSetPointSize(gl.getPointSize());
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  		auto gfx = Module::getInstance<graphics::Graphics>(Module::M_GRAPHICS);
 | 
	
		
			
				|  |  | -		const Matrix4 &curproj = gfx->getProjection();
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +		const Matrix4 &curproj = gfx->getProjection();
 | 
	
		
			
				|  |  |  		const Matrix4 &curxform = gfx->getTransform();
 | 
	
		
			
				|  |  | -		TemporaryAttacher attacher(this, true);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  		bool tpmatrixneedsupdate = false;
 | 
	
		
			
				|  |  |  
 |