Qt: effect used in mini player background no longer represents the correct region of the source
As per the Qt source code [1]:
QRectF QSGRhiShaderEffectNode::updateNormalizedTextureSubRect(bool supportsAtlasTextures)
{
QRectF srcRect(0, 0, 1, 1);
bool geometryUsesTextureSubRect = false;
if (supportsAtlasTextures) {
QSGTextureProvider *tp = nullptr;
for (int binding = 0, count = m_material.m_textureProviders.size(); binding != count; ++binding) {
if (QSGTextureProvider *candidate = m_material.m_textureProviders.at(binding)) {
if (!tp) {
tp = candidate;
} else { // there can only be one...
tp = nullptr;
break;
}
}
}
if (tp && tp->texture()) {
srcRect = tp->texture()->normalizedTextureSubRect();
geometryUsesTextureSubRect = true;
}
}
if (m_material.m_geometryUsesTextureSubRect != geometryUsesTextureSubRect) {
m_material.m_geometryUsesTextureSubRect = geometryUsesTextureSubRect;
markDirty(QSGNode::DirtyMaterial);
}
return srcRect;
}
The node does not respect the texture's normalizedTextureSubRect()
if the ShaderEffect
does not have the property supportsAtlasTextures
set. I consider this a Qt bug, because normalizedTextureSubRect()
should be respected whether the texture is in the atlas or not. The documentation states that [2]:
Returns the rectangle inside textureSize() that this texture represents in normalized coordinates. The default implementation returns a rect at position (0, 0) with width and height of 1.
Neither the documentation nor the method name suggests that normalizedTextureSubRect()
is only meant for atlas textures...
Unfortunately, while !7064 (merged) fixed an issue, it caused a regression in the mini player background where we use sub-textures due to this.
[1] https://github.com/qt/qtdeclarative/blob/6.8.1/src/quick/scenegraph/qsgrhishadereffectnode.cpp#L656 [2] https://doc.qt.io/qt-6/qsgtexture.html#normalizedTextureSubRect