Skip to content

qt: reset texture state in `QSGTextureView` on source texture update

This is important because if the source texture has no mipmaps, but the view has mipmap filtering enabled, depending on the graphics backend the texture might not be rendered at all (reproduced with OpenGL, not with Vulkan).

Currently we are not accounting for the case when the source texture is the same*, but it starts having mipmaps or no longer has mipmaps after the initial QSGTextureView::setTexture() call. At the same time, the workaround for the Qt bug where the source texture has mipmap filtering but no mipmaps should be considered better with hasMipmaps() rather than isAtlasTexture() (maybe we should check both, but only hasMipmaps() seemed fine to me), where I also changed in this merge request. In the future, if Qt still has this bug, we can test QRhiTexture::flags() with QRhiTexture::MipMapped for a better check if the underlying/native texture actually has mipmaps.

The rest of the parameters, such as wrap mode, or anisotropy level should be independent of the source texture. We do not need to reset them in this case, but for consistency I reset the whole state altogether. If the view wants to have a different state than the source texture, they should be set again after reset.

  • state is reset regardless of if the texture pointer changes in ::setTexture(). I was hesitant before about what the signal QSGTextureProvider::textureChanged() actually meant, because it was not obvious to me if it was referring only to the whole texture changes (residing in different address), or also if it meant the properties of the provided texture. But I can now tell that there is at least one case it is signalled even if the provider's texture is the same*, but states change (QQuickImage). This makes sense, as there is no other signal that indicates state changes in QSGTextureProvider. Though, I would name the signal QSGTextureProvider::textureUpdated(), or better, have a separate signal for that.
  • state is reset if the source texture is a layer and it signals update request (QSGLayer::updateRequested()), whether or not ::setTexture() is called. We are already re-adjusting the normal coordinates in this case, I just added a new connection.

(*) as in, the same pointer, not meaning deep compare

Merge request reports

Loading