diff --git a/src/modules/graphics/opengl/Shader.cpp b/src/modules/graphics/opengl/Shader.cpp index ba723a14e..9648ea133 100644 --- a/src/modules/graphics/opengl/Shader.cpp +++ b/src/modules/graphics/opengl/Shader.cpp @@ -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(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(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; diff --git a/src/modules/graphics/opengl/Shader.h b/src/modules/graphics/opengl/Shader.h index 3ebce2c06..d74be1c42 100644 --- a/src/modules/graphics/opengl/Shader.h +++ b/src/modules/graphics/opengl/Shader.h @@ -243,6 +243,8 @@ private: // Texture unit pool for setting images std::vector textureUnits; + std::vector> pendingUniformUpdates; + bool canvasWasActive; Rect lastViewport;