Fix Vulkan headless backend resize (#4030)

This commit is contained in:
Adrian Cojocaru
2026-01-08 12:54:58 +02:00
committed by GitHub
parent 3f64c7e646
commit 32eed7a806
4 changed files with 34 additions and 6 deletions

View File

@@ -66,6 +66,7 @@ public:
private:
MTL::PixelFormat getMetalPixelFormat() const noexcept;
void createMetalTexture() noexcept;
void destroyMetalTexture() noexcept;
Context& context;
MTLTexturePtr metalTexture;

View File

@@ -75,16 +75,21 @@ gfx::Renderable& HeadlessBackend::getDefaultRenderable() {
}
PremultipliedImage HeadlessBackend::readStillImage() {
if (!resource) {
resource = std::make_unique<HeadlessRenderableResource>(*this);
}
auto& contextImpl = static_cast<Context&>(*context);
auto& resourceImpl = static_cast<HeadlessRenderableResource&>(*resource);
if (!texture) {
texture = std::make_unique<Texture2D>(contextImpl);
texture->setFormat(gfx::TexturePixelType::RGBA, gfx::TextureChannelDataType::UnsignedByte);
texture->setSize(size);
texture->setUsage(Texture2DUsage::Read);
}
texture->setSize(size);
contextImpl.waitFrame();
texture->copyImage(resourceImpl.getAcquiredImage());

View File

@@ -14,10 +14,7 @@ Texture2D::Texture2D(Context& context_)
: context(context_) {}
Texture2D::~Texture2D() {
if (metalTexture) {
context.renderingStats().numActiveTextures--;
context.renderingStats().memTextures -= getDataSize(); // NOLINT(clang-analyzer-optin.cplusplus.VirtualCall)
}
destroyMetalTexture();
}
gfx::Texture2D& Texture2D::setSamplerConfiguration(const SamplerState& samplerState_) noexcept {
@@ -36,6 +33,9 @@ gfx::Texture2D& Texture2D::setFormat(gfx::TexturePixelType pixelFormat_,
if (pixelFormat_ == pixelFormat && channelType_ == channelType) {
return *this;
}
destroyMetalTexture();
pixelFormat = pixelFormat_;
channelType = channelType_;
textureDirty = true;
@@ -46,6 +46,9 @@ gfx::Texture2D& Texture2D::setSize(mbgl::Size size_) noexcept {
if (size_ == size) {
return *this;
}
destroyMetalTexture();
size = size_;
textureDirty = true;
return *this;
@@ -146,7 +149,8 @@ void Texture2D::createMetalTexture() noexcept {
if (size == Size{0, 0}) {
return;
}
metalTexture.reset();
destroyMetalTexture();
const auto format = getMetalPixelFormat();
if (format == MTL::PixelFormat::PixelFormatInvalid) {
@@ -195,6 +199,16 @@ void Texture2D::create() noexcept {
}
}
void Texture2D::destroyMetalTexture() noexcept {
if (!metalTexture) {
return;
}
metalTexture.reset();
context.renderingStats().numActiveTextures--;
context.renderingStats().memTextures -= getDataSize();
}
gfx::Texture2D& Texture2D::setUsage(MTL::TextureUsage usage_) noexcept {
usage = usage_;
textureDirty = true;

View File

@@ -62,6 +62,9 @@ gfx::Texture2D& Texture2D::setFormat(gfx::TexturePixelType pixelFormat_,
if (pixelFormat_ == pixelFormat && channelType_ == channelType) {
return *this;
}
destroyTexture();
pixelFormat = pixelFormat_;
channelType = channelType_;
textureDirty = true;
@@ -72,6 +75,9 @@ gfx::Texture2D& Texture2D::setSize(mbgl::Size size_) noexcept {
if (size_ == size) {
return *this;
}
destroyTexture();
size = size_;
textureDirty = true;
return *this;
@@ -267,6 +273,8 @@ vk::SamplerAddressMode Texture2D::vulkanAddressMode(const gfx::TextureWrapType t
void Texture2D::createTexture() {
if (size.width == 0 || size.height == 0) return;
destroyTexture();
const auto& backend = context.getBackend();
const auto format = vulkanFormat(pixelFormat, channelType);