diff --git a/include/mbgl/gfx/dynamic_texture.hpp b/include/mbgl/gfx/dynamic_texture.hpp index 4414507ea..2475f3955 100644 --- a/include/mbgl/gfx/dynamic_texture.hpp +++ b/include/mbgl/gfx/dynamic_texture.hpp @@ -65,8 +65,11 @@ public: virtual bool removeTexture(const TextureHandle& texHandle); protected: + DynamicTexture(Size size, TexturePixelType pixelType); + mapbox::ShelfPack shelfPack; Texture2DPtr texture; + TexturePixelType pixelFormat; int numTextures = 0; std::mutex mutex; }; diff --git a/include/mbgl/webgpu/dynamic_texture.hpp b/include/mbgl/webgpu/dynamic_texture.hpp index 57aa42708..09234deda 100644 --- a/include/mbgl/webgpu/dynamic_texture.hpp +++ b/include/mbgl/webgpu/dynamic_texture.hpp @@ -19,6 +19,9 @@ public: std::unordered_map, gfx::TextureHandle::Hasher>; private: + Context& context; + Size size; + gfx::TexturePixelType pixelType; bool deferredCreation = false; ImagesToUpload imagesToUpload; }; diff --git a/src/mbgl/gfx/dynamic_texture.cpp b/src/mbgl/gfx/dynamic_texture.cpp index 60bec826e..5dfa10a0b 100644 --- a/src/mbgl/gfx/dynamic_texture.cpp +++ b/src/mbgl/gfx/dynamic_texture.cpp @@ -5,11 +5,15 @@ namespace mbgl { namespace gfx { -DynamicTexture::DynamicTexture(Context& context, Size size, TexturePixelType pixelType) { +DynamicTexture::DynamicTexture(Size size, TexturePixelType pixelType) + : pixelFormat(pixelType) { mapbox::ShelfPack::ShelfPackOptions options; options.autoResize = false; shelfPack = mapbox::ShelfPack(size.width, size.height, options); +} +DynamicTexture::DynamicTexture(Context& context, Size size, TexturePixelType pixelType) + : DynamicTexture(size, pixelType) { texture = context.createTexture2D(); texture->setSize(size); texture->setFormat(pixelType, gfx::TextureChannelDataType::UnsignedByte); @@ -24,7 +28,7 @@ const gfx::Texture2DPtr& DynamicTexture::getTexture() const { } TexturePixelType DynamicTexture::getPixelFormat() const { - return getTexture()->getFormat(); + return pixelFormat; } bool DynamicTexture::isEmpty() const { diff --git a/src/mbgl/webgpu/dynamic_texture.cpp b/src/mbgl/webgpu/dynamic_texture.cpp index 545f9b785..bc955daaa 100644 --- a/src/mbgl/webgpu/dynamic_texture.cpp +++ b/src/mbgl/webgpu/dynamic_texture.cpp @@ -6,18 +6,37 @@ namespace mbgl { namespace webgpu { DynamicTexture::DynamicTexture(Context& context, Size size, gfx::TexturePixelType pixelType) - : gfx::DynamicTexture(context, size, pixelType) { + : gfx::DynamicTexture(size, pixelType), + context(context), + size(size), + pixelType(pixelType) { deferredCreation = true; } +namespace { +size_t pixelStride(gfx::TexturePixelType pixelType) { + switch (pixelType) { + case gfx::TexturePixelType::Alpha: + case gfx::TexturePixelType::Luminance: + return 1; + case gfx::TexturePixelType::RGBA: + return 4; + case gfx::TexturePixelType::Stencil: + case gfx::TexturePixelType::Depth: + return 4; + } + return 4; +} +} // namespace + void DynamicTexture::uploadImage(const uint8_t* pixelData, gfx::TextureHandle& texHandle) { std::scoped_lock lock(mutex); const auto& rect = texHandle.getRectangle(); const auto imageSize = Size(rect.w, rect.h); - auto size = imageSize.area() * texture->getPixelStride(); - auto imageData = std::make_unique(size); - std::copy(pixelData, pixelData + size, imageData.get()); + auto byteSize = imageSize.area() * pixelStride(pixelType); + auto imageData = std::make_unique(byteSize); + std::copy(pixelData, pixelData + byteSize, imageData.get()); imagesToUpload.emplace(texHandle, std::move(imageData)); gfx::DynamicTexture::uploadImage(pixelData, texHandle); @@ -26,6 +45,12 @@ void DynamicTexture::uploadImage(const uint8_t* pixelData, gfx::TextureHandle& t void DynamicTexture::uploadDeferredImages(gfx::UploadPass&) { std::scoped_lock lock(mutex); if (deferredCreation) { + texture = context.createTexture2D(); + texture->setSize(size); + texture->setFormat(pixelType, gfx::TextureChannelDataType::UnsignedByte); + texture->setSamplerConfiguration({.filter = gfx::TextureFilterType::Linear, + .wrapU = gfx::TextureWrapType::Clamp, + .wrapV = gfx::TextureWrapType::Clamp}); texture->create(); deferredCreation = false; }