From 867555b1c9ef51fec23ce77c682cf7d5b5a23c5e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Konstantin=20K=C3=A4fer?= Date: Mon, 13 May 2019 17:13:31 -0700 Subject: [core] add gfx::UploadPass, split startRender into prepare and upload --- include/mbgl/gfx/renderable.hpp | 3 + src/core-files.json | 4 + src/mbgl/annotation/render_annotation_source.cpp | 8 +- src/mbgl/annotation/render_annotation_source.hpp | 3 +- src/mbgl/geometry/line_atlas.cpp | 14 +- src/mbgl/geometry/line_atlas.hpp | 6 +- src/mbgl/gfx/command_encoder.hpp | 2 + src/mbgl/gfx/context.hpp | 96 +------- src/mbgl/gfx/stencil_mode.hpp | 9 + src/mbgl/gfx/upload_pass.hpp | 109 +++++++++ src/mbgl/gl/command_encoder.cpp | 6 + src/mbgl/gl/command_encoder.hpp | 3 +- src/mbgl/gl/context.cpp | 112 +++------- src/mbgl/gl/context.hpp | 17 +- src/mbgl/gl/object.cpp | 3 +- src/mbgl/gl/object.hpp | 2 +- src/mbgl/gl/offscreen_texture.cpp | 1 + src/mbgl/gl/upload_pass.cpp | 117 ++++++++++ src/mbgl/gl/upload_pass.hpp | 42 ++++ src/mbgl/programs/program.hpp | 1 + src/mbgl/renderer/bucket.hpp | 4 +- src/mbgl/renderer/buckets/circle_bucket.cpp | 8 +- src/mbgl/renderer/buckets/circle_bucket.hpp | 2 +- src/mbgl/renderer/buckets/debug_bucket.cpp | 13 +- src/mbgl/renderer/buckets/debug_bucket.hpp | 12 +- src/mbgl/renderer/buckets/fill_bucket.cpp | 10 +- src/mbgl/renderer/buckets/fill_bucket.hpp | 2 +- .../renderer/buckets/fill_extrusion_bucket.cpp | 8 +- .../renderer/buckets/fill_extrusion_bucket.hpp | 2 +- src/mbgl/renderer/buckets/heatmap_bucket.cpp | 8 +- src/mbgl/renderer/buckets/heatmap_bucket.hpp | 2 +- src/mbgl/renderer/buckets/hillshade_bucket.cpp | 8 +- src/mbgl/renderer/buckets/hillshade_bucket.hpp | 2 +- src/mbgl/renderer/buckets/line_bucket.cpp | 8 +- src/mbgl/renderer/buckets/line_bucket.hpp | 2 +- src/mbgl/renderer/buckets/raster_bucket.cpp | 10 +- src/mbgl/renderer/buckets/raster_bucket.hpp | 2 +- src/mbgl/renderer/buckets/symbol_bucket.cpp | 46 ++-- src/mbgl/renderer/buckets/symbol_bucket.hpp | 2 +- src/mbgl/renderer/image_atlas.cpp | 11 +- src/mbgl/renderer/image_atlas.hpp | 8 +- src/mbgl/renderer/image_manager.cpp | 12 +- src/mbgl/renderer/image_manager.hpp | 6 +- .../renderer/layers/render_background_layer.cpp | 19 +- .../renderer/layers/render_background_layer.hpp | 1 + src/mbgl/renderer/layers/render_heatmap_layer.cpp | 19 +- src/mbgl/renderer/layers/render_heatmap_layer.hpp | 1 + .../renderer/layers/render_hillshade_layer.cpp | 8 +- src/mbgl/renderer/layers/render_line_layer.cpp | 43 +++- src/mbgl/renderer/layers/render_line_layer.hpp | 1 + src/mbgl/renderer/layers/render_raster_layer.cpp | 4 +- src/mbgl/renderer/layers/render_symbol_layer.cpp | 244 ++++++++++++--------- src/mbgl/renderer/layers/render_symbol_layer.hpp | 2 + src/mbgl/renderer/paint_parameters.cpp | 8 +- src/mbgl/renderer/paint_parameters.hpp | 5 +- src/mbgl/renderer/paint_property_binder.hpp | 27 +-- src/mbgl/renderer/render_layer.hpp | 2 + src/mbgl/renderer/render_pass.hpp | 1 + src/mbgl/renderer/render_source.hpp | 7 +- src/mbgl/renderer/render_static_data.cpp | 19 +- src/mbgl/renderer/render_static_data.hpp | 14 +- src/mbgl/renderer/render_tile.cpp | 63 +++--- src/mbgl/renderer/render_tile.hpp | 14 +- src/mbgl/renderer/renderer_impl.cpp | 47 +++- .../sources/render_custom_geometry_source.cpp | 8 +- .../sources/render_custom_geometry_source.hpp | 3 +- .../renderer/sources/render_geojson_source.cpp | 8 +- .../renderer/sources/render_geojson_source.hpp | 3 +- src/mbgl/renderer/sources/render_image_source.cpp | 16 +- src/mbgl/renderer/sources/render_image_source.hpp | 3 +- .../renderer/sources/render_raster_dem_source.cpp | 8 +- .../renderer/sources/render_raster_dem_source.hpp | 3 +- src/mbgl/renderer/sources/render_raster_source.cpp | 8 +- src/mbgl/renderer/sources/render_raster_source.hpp | 3 +- src/mbgl/renderer/sources/render_vector_source.cpp | 8 +- src/mbgl/renderer/sources/render_vector_source.hpp | 3 +- src/mbgl/renderer/tile_pyramid.cpp | 10 +- src/mbgl/renderer/tile_pyramid.hpp | 3 +- src/mbgl/renderer/upload_parameters.hpp | 31 +++ src/mbgl/text/placement.hpp | 4 +- src/mbgl/tile/geometry_tile.cpp | 10 +- src/mbgl/tile/geometry_tile.hpp | 2 +- src/mbgl/tile/raster_dem_tile.cpp | 4 +- src/mbgl/tile/raster_dem_tile.hpp | 2 +- src/mbgl/tile/raster_tile.cpp | 4 +- src/mbgl/tile/raster_tile.hpp | 2 +- src/mbgl/tile/tile.cpp | 1 - src/mbgl/tile/tile.hpp | 14 +- test/gl/bucket.test.cpp | 20 +- test/util/string.test.cpp | 4 +- 90 files changed, 944 insertions(+), 536 deletions(-) create mode 100644 src/mbgl/gfx/upload_pass.hpp create mode 100644 src/mbgl/gl/upload_pass.cpp create mode 100644 src/mbgl/gl/upload_pass.hpp create mode 100644 src/mbgl/renderer/upload_parameters.hpp diff --git a/include/mbgl/gfx/renderable.hpp b/include/mbgl/gfx/renderable.hpp index 3a973e6693..1aca5a789d 100644 --- a/include/mbgl/gfx/renderable.hpp +++ b/include/mbgl/gfx/renderable.hpp @@ -23,6 +23,7 @@ protected: Renderable(const Size size_, std::unique_ptr resource_) : size(size_), resource(std::move(resource_)) { } + virtual ~Renderable() = default; public: Size getSize() const { @@ -35,6 +36,8 @@ public: return static_cast(*resource); } + virtual void wait() {} + protected: Size size; std::unique_ptr resource; diff --git a/src/core-files.json b/src/core-files.json index b5b131461b..a52797acd7 100644 --- a/src/core-files.json +++ b/src/core-files.json @@ -29,6 +29,7 @@ "src/mbgl/gl/renderer_backend.cpp", "src/mbgl/gl/texture.cpp", "src/mbgl/gl/uniform.cpp", + "src/mbgl/gl/upload_pass.cpp", "src/mbgl/gl/value.cpp", "src/mbgl/gl/vertex_array.cpp", "src/mbgl/layermanager/background_layer_factory.cpp", @@ -528,6 +529,7 @@ "mbgl/gfx/texture.hpp": "src/mbgl/gfx/texture.hpp", "mbgl/gfx/types.hpp": "src/mbgl/gfx/types.hpp", "mbgl/gfx/uniform.hpp": "src/mbgl/gfx/uniform.hpp", + "mbgl/gfx/upload_pass.hpp": "src/mbgl/gfx/upload_pass.hpp", "mbgl/gfx/vertex_buffer.hpp": "src/mbgl/gfx/vertex_buffer.hpp", "mbgl/gfx/vertex_vector.hpp": "src/mbgl/gfx/vertex_vector.hpp", "mbgl/gl/attribute.hpp": "src/mbgl/gl/attribute.hpp", @@ -553,6 +555,7 @@ "mbgl/gl/texture_resource.hpp": "src/mbgl/gl/texture_resource.hpp", "mbgl/gl/types.hpp": "src/mbgl/gl/types.hpp", "mbgl/gl/uniform.hpp": "src/mbgl/gl/uniform.hpp", + "mbgl/gl/upload_pass.hpp": "src/mbgl/gl/upload_pass.hpp", "mbgl/gl/value.hpp": "src/mbgl/gl/value.hpp", "mbgl/gl/vertex_array.hpp": "src/mbgl/gl/vertex_array.hpp", "mbgl/gl/vertex_array_extension.hpp": "src/mbgl/gl/vertex_array_extension.hpp", @@ -659,6 +662,7 @@ "mbgl/renderer/tile_pyramid.hpp": "src/mbgl/renderer/tile_pyramid.hpp", "mbgl/renderer/transition_parameters.hpp": "src/mbgl/renderer/transition_parameters.hpp", "mbgl/renderer/update_parameters.hpp": "src/mbgl/renderer/update_parameters.hpp", + "mbgl/renderer/upload_parameters.hpp": "src/mbgl/renderer/upload_parameters.hpp", "mbgl/sprite/sprite_loader.hpp": "src/mbgl/sprite/sprite_loader.hpp", "mbgl/sprite/sprite_loader_observer.hpp": "src/mbgl/sprite/sprite_loader_observer.hpp", "mbgl/sprite/sprite_loader_worker.hpp": "src/mbgl/sprite/sprite_loader_worker.hpp", diff --git a/src/mbgl/annotation/render_annotation_source.cpp b/src/mbgl/annotation/render_annotation_source.cpp index 740ad32244..fcf9a8d8a7 100644 --- a/src/mbgl/annotation/render_annotation_source.cpp +++ b/src/mbgl/annotation/render_annotation_source.cpp @@ -47,8 +47,12 @@ void RenderAnnotationSource::update(Immutable baseImpl_, }); } -void RenderAnnotationSource::startRender(PaintParameters& parameters) { - tilePyramid.startRender(parameters); +void RenderAnnotationSource::upload(gfx::UploadPass& uploadPass) { + tilePyramid.upload(uploadPass); +} + +void RenderAnnotationSource::prepare(PaintParameters& parameters) { + tilePyramid.prepare(parameters); } void RenderAnnotationSource::finishRender(PaintParameters& parameters) { diff --git a/src/mbgl/annotation/render_annotation_source.hpp b/src/mbgl/annotation/render_annotation_source.hpp index 0d08d0af99..46fd9ed06f 100644 --- a/src/mbgl/annotation/render_annotation_source.hpp +++ b/src/mbgl/annotation/render_annotation_source.hpp @@ -18,7 +18,8 @@ public: bool needsRelayout, const TileParameters&) final; - void startRender(PaintParameters&) final; + void upload(gfx::UploadPass&) final; + void prepare(PaintParameters&) final; void finishRender(PaintParameters&) final; std::vector> getRenderTiles() final; diff --git a/src/mbgl/geometry/line_atlas.cpp b/src/mbgl/geometry/line_atlas.cpp index a3c1c9abce..106a24d015 100644 --- a/src/mbgl/geometry/line_atlas.cpp +++ b/src/mbgl/geometry/line_atlas.cpp @@ -1,5 +1,5 @@ #include -#include +#include #include #include #include @@ -126,18 +126,20 @@ Size LineAtlas::getSize() const { return image.size; } -void LineAtlas::upload(gfx::Context& context) { +void LineAtlas::upload(gfx::UploadPass& uploadPass) { if (!texture) { - texture = context.createTexture(image); + texture = uploadPass.createTexture(image); } else if (dirty) { - context.updateTexture(*texture, image); + uploadPass.updateTexture(*texture, image); } dirty = false; } -gfx::TextureBinding LineAtlas::textureBinding(gfx::Context& context) { - upload(context); +gfx::TextureBinding LineAtlas::textureBinding() { + assert(texture); + // All _changes_ to the texture should've been made and uploaded already. + assert(!dirty); return { texture->getResource(), gfx::TextureFilterType::Linear, gfx::TextureMipMapType::No, gfx::TextureWrapType::Repeat, gfx::TextureWrapType::Clamp }; } diff --git a/src/mbgl/geometry/line_atlas.hpp b/src/mbgl/geometry/line_atlas.hpp index 3a238f8507..b43583c9c8 100644 --- a/src/mbgl/geometry/line_atlas.hpp +++ b/src/mbgl/geometry/line_atlas.hpp @@ -11,7 +11,7 @@ namespace mbgl { namespace gfx { -class Context; +class UploadPass; } // namespace gfx class LinePatternPos { @@ -32,11 +32,11 @@ public: ~LineAtlas(); // Binds the atlas texture to the GPU, and uploads data if it is out of date. - gfx::TextureBinding textureBinding(gfx::Context&); + gfx::TextureBinding textureBinding(); // Uploads the texture to the GPU to be available when we need it. This is a lazy operation; // the texture is only bound when the data is out of date (=dirty). - void upload(gfx::Context&); + void upload(gfx::UploadPass&); LinePatternPos getDashPosition(const std::vector&, LinePatternCap); LinePatternPos addDash(const std::vector& dasharray, LinePatternCap); diff --git a/src/mbgl/gfx/command_encoder.hpp b/src/mbgl/gfx/command_encoder.hpp index 46ae551982..5692615643 100644 --- a/src/mbgl/gfx/command_encoder.hpp +++ b/src/mbgl/gfx/command_encoder.hpp @@ -10,6 +10,7 @@ namespace gfx { class RenderPassDescriptor; class RenderPass; class Renderable; +class UploadPass; class CommandEncoder { protected: @@ -28,6 +29,7 @@ public: return { *this, name }; } + virtual std::unique_ptr createUploadPass(const char* name) = 0; virtual std::unique_ptr createRenderPass(const char* name, const RenderPassDescriptor&) = 0; virtual void present(Renderable&) = 0; }; diff --git a/src/mbgl/gfx/context.hpp b/src/mbgl/gfx/context.hpp index c56ace2252..118df30a26 100644 --- a/src/mbgl/gfx/context.hpp +++ b/src/mbgl/gfx/context.hpp @@ -1,15 +1,11 @@ #pragma once -#include -#include -#include -#include -#include #include #include #include #include #include +#include namespace mbgl { @@ -43,95 +39,25 @@ public: virtual void performCleanup() = 0; public: - template - VertexBuffer - createVertexBuffer(VertexVector&& v, - const BufferUsageType usage = BufferUsageType::StaticDraw) { - return { v.elements(), createVertexBufferResource(v.data(), v.bytes(), usage) }; - } - - template - void updateVertexBuffer(VertexBuffer& buffer, VertexVector&& v) { - assert(v.elements() == buffer.elements); - updateVertexBufferResource(buffer.getResource(), v.data(), v.bytes()); - } - - template - IndexBuffer createIndexBuffer(IndexVector&& v, - const BufferUsageType usage = BufferUsageType::StaticDraw) { - return { v.elements(), createIndexBufferResource(v.data(), v.bytes(), usage) }; - } - - template - void updateIndexBuffer(IndexBuffer& buffer, IndexVector&& v) { - assert(v.elements() == buffer.elements); - updateIndexBufferResource(buffer.getResource(), v.data(), v.bytes()); - } - -protected: - virtual std::unique_ptr - createVertexBufferResource(const void* data, std::size_t size, const BufferUsageType) = 0; - virtual void - updateVertexBufferResource(VertexBufferResource&, const void* data, std::size_t size) = 0; - - virtual std::unique_ptr - createIndexBufferResource(const void* data, std::size_t size, const BufferUsageType) = 0; - virtual void - updateIndexBufferResource(IndexBufferResource&, const void* data, std::size_t size) = 0; + virtual std::unique_ptr + createOffscreenTexture(Size, + TextureChannelDataType = TextureChannelDataType::UnsignedByte) = 0; + virtual std::unique_ptr + createOffscreenTexture(Size, + Renderbuffer&, + TextureChannelDataType = TextureChannelDataType::UnsignedByte) = 0; public: - // Create a texture from an image with data. - template - Texture createTexture(const Image& image, - TextureChannelDataType type = TextureChannelDataType::UnsignedByte) { - auto format = image.channels == 4 ? TexturePixelType::RGBA : TexturePixelType::Alpha; - return { image.size, - createTextureResource(image.size, image.data.get(), format, type) }; - } - // Creates an empty texture with the specified dimensions. Texture createTexture(const Size size, TexturePixelType format = TexturePixelType::RGBA, TextureChannelDataType type = TextureChannelDataType::UnsignedByte) { - return { size, createTextureResource(size, nullptr, format, type) }; - } - - template - void updateTexture(Texture& texture, - const Image& image, - TextureChannelDataType type = TextureChannelDataType::UnsignedByte) { - auto format = image.channels == 4 ? TexturePixelType::RGBA : TexturePixelType::Alpha; - updateTextureResource(texture.getResource(), image.size, image.data.get(), format, type); - texture.size = image.size; - } - - template - void updateTextureSub(Texture& texture, - const Image& image, - const uint16_t offsetX, - const uint16_t offsetY, - TextureChannelDataType type = TextureChannelDataType::UnsignedByte) { - assert(image.size.width + offsetX <= texture.size.width); - assert(image.size.height + offsetY <= texture.size.height); - auto format = image.channels == 4 ? TexturePixelType::RGBA : TexturePixelType::Alpha; - updateTextureResourceSub(texture.getResource(), offsetX, offsetY, image.size, image.data.get(), format, type); + return { size, createTextureResource(size, format, type) }; } protected: - virtual std::unique_ptr createTextureResource( - Size, const void* data, TexturePixelType, TextureChannelDataType) = 0; - virtual void updateTextureResource(TextureResource&, Size, const void* data, - TexturePixelType, TextureChannelDataType) = 0; - virtual void updateTextureResourceSub(TextureResource&, uint16_t xOffset, uint16_t yOffset, Size, const void* data, - TexturePixelType, TextureChannelDataType) = 0; - -public: - virtual std::unique_ptr createOffscreenTexture( - Size, gfx::TextureChannelDataType = gfx::TextureChannelDataType::UnsignedByte) = 0; - virtual std::unique_ptr createOffscreenTexture( - Size, - gfx::Renderbuffer&, - gfx::TextureChannelDataType = gfx::TextureChannelDataType::UnsignedByte) = 0; + virtual std::unique_ptr + createTextureResource(Size, TexturePixelType, TextureChannelDataType) = 0; public: template diff --git a/src/mbgl/gfx/stencil_mode.hpp b/src/mbgl/gfx/stencil_mode.hpp index 3ba2687b8c..aec403b59b 100644 --- a/src/mbgl/gfx/stencil_mode.hpp +++ b/src/mbgl/gfx/stencil_mode.hpp @@ -52,5 +52,14 @@ public: } }; +template +constexpr StencilFunctionType StencilMode::SimpleTest::func; + +template +constexpr uint32_t StencilMode::SimpleTest::mask; + +template +constexpr StencilFunctionType StencilMode::MaskedTest::func; + } // namespace gfx } // namespace mbgl diff --git a/src/mbgl/gfx/upload_pass.hpp b/src/mbgl/gfx/upload_pass.hpp new file mode 100644 index 0000000000..f0bf9d7e2d --- /dev/null +++ b/src/mbgl/gfx/upload_pass.hpp @@ -0,0 +1,109 @@ +#pragma once + +#include +#include +#include +#include +#include +#include +#include + +namespace mbgl { +namespace gfx { + +class UploadPass { +protected: + UploadPass() = default; + + friend class DebugGroup; + virtual void pushDebugGroup(const char* name) = 0; + virtual void popDebugGroup() = 0; + +public: + virtual ~UploadPass() = default; + UploadPass(const UploadPass&) = delete; + UploadPass& operator=(const UploadPass&) = delete; + + DebugGroup createDebugGroup(const char* name) { + return { *this, name }; + } + +public: + template + VertexBuffer + createVertexBuffer(VertexVector&& v, + const BufferUsageType usage = BufferUsageType::StaticDraw) { + return { v.elements(), createVertexBufferResource(v.data(), v.bytes(), usage) }; + } + + template + void updateVertexBuffer(VertexBuffer& buffer, VertexVector&& v) { + assert(v.elements() == buffer.elements); + updateVertexBufferResource(buffer.getResource(), v.data(), v.bytes()); + } + + template + IndexBuffer createIndexBuffer(IndexVector&& v, + const BufferUsageType usage = BufferUsageType::StaticDraw) { + return { v.elements(), createIndexBufferResource(v.data(), v.bytes(), usage) }; + } + + template + void updateIndexBuffer(IndexBuffer& buffer, IndexVector&& v) { + assert(v.elements() == buffer.elements); + updateIndexBufferResource(buffer.getResource(), v.data(), v.bytes()); + } + +protected: + virtual std::unique_ptr + createVertexBufferResource(const void* data, std::size_t size, const BufferUsageType) = 0; + virtual void + updateVertexBufferResource(VertexBufferResource&, const void* data, std::size_t size) = 0; + + virtual std::unique_ptr + createIndexBufferResource(const void* data, std::size_t size, const BufferUsageType) = 0; + virtual void + updateIndexBufferResource(IndexBufferResource&, const void* data, std::size_t size) = 0; + +public: + // Create a texture from an image with data. + template + Texture createTexture(const Image& image, + TextureChannelDataType type = TextureChannelDataType::UnsignedByte) { + auto format = image.channels == 4 ? TexturePixelType::RGBA : TexturePixelType::Alpha; + return { image.size, + createTextureResource(image.size, image.data.get(), format, type) }; + } + + template + void updateTexture(Texture& texture, + const Image& image, + TextureChannelDataType type = TextureChannelDataType::UnsignedByte) { + auto format = image.channels == 4 ? TexturePixelType::RGBA : TexturePixelType::Alpha; + updateTextureResource(texture.getResource(), image.size, image.data.get(), format, type); + texture.size = image.size; + } + + template + void updateTextureSub(Texture& texture, + const Image& image, + const uint16_t offsetX, + const uint16_t offsetY, + TextureChannelDataType type = TextureChannelDataType::UnsignedByte) { + assert(image.size.width + offsetX <= texture.size.width); + assert(image.size.height + offsetY <= texture.size.height); + auto format = image.channels == 4 ? TexturePixelType::RGBA : TexturePixelType::Alpha; + updateTextureResourceSub(texture.getResource(), offsetX, offsetY, image.size, image.data.get(), format, type); + } + +protected: + virtual std::unique_ptr createTextureResource( + Size, const void* data, TexturePixelType, TextureChannelDataType) = 0; + virtual void updateTextureResource(TextureResource&, Size, const void* data, + TexturePixelType, TextureChannelDataType) = 0; + virtual void updateTextureResourceSub(TextureResource&, uint16_t xOffset, uint16_t yOffset, Size, const void* data, + TexturePixelType, TextureChannelDataType) = 0; +}; + +} // namespace gfx +} // namespace mbgl diff --git a/src/mbgl/gl/command_encoder.cpp b/src/mbgl/gl/command_encoder.cpp index 37c4479734..a7df14df09 100644 --- a/src/mbgl/gl/command_encoder.cpp +++ b/src/mbgl/gl/command_encoder.cpp @@ -1,4 +1,5 @@ #include +#include #include #include #include @@ -15,6 +16,11 @@ CommandEncoder::~CommandEncoder() { context.performCleanup(); } +std::unique_ptr +CommandEncoder::createUploadPass(const char* name) { + return std::make_unique(*this, name); +} + std::unique_ptr CommandEncoder::createRenderPass(const char* name, const gfx::RenderPassDescriptor& descriptor) { return std::make_unique(*this, name, descriptor); diff --git a/src/mbgl/gl/command_encoder.hpp b/src/mbgl/gl/command_encoder.hpp index 31d67d13a6..f47aad4946 100644 --- a/src/mbgl/gl/command_encoder.hpp +++ b/src/mbgl/gl/command_encoder.hpp @@ -6,7 +6,6 @@ namespace mbgl { namespace gl { class Context; -class RenderPass; class CommandEncoder final : public gfx::CommandEncoder { public: @@ -15,8 +14,10 @@ public: ~CommandEncoder() override; + friend class UploadPass; friend class RenderPass; + std::unique_ptr createUploadPass(const char* name) override; std::unique_ptr createRenderPass(const char* name, const gfx::RenderPassDescriptor&) override; void present(gfx::Renderable&) override; diff --git a/src/mbgl/gl/context.cpp b/src/mbgl/gl/context.cpp index b6a7bcc44c..f1288dc7ed 100644 --- a/src/mbgl/gl/context.cpp +++ b/src/mbgl/gl/context.cpp @@ -1,8 +1,6 @@ #include #include #include -#include -#include #include #include #include @@ -222,41 +220,6 @@ void Context::verifyProgramLinkage(ProgramID program_) { throw std::runtime_error("program failed to link"); } -std::unique_ptr -Context::createVertexBufferResource(const void* data, std::size_t size, const gfx::BufferUsageType usage) { - BufferID id = 0; - MBGL_CHECK_ERROR(glGenBuffers(1, &id)); - UniqueBuffer result { std::move(id), { this } }; - vertexBuffer = result; - MBGL_CHECK_ERROR(glBufferData(GL_ARRAY_BUFFER, size, data, Enum::to(usage))); - return std::make_unique(std::move(result)); -} - -void Context::updateVertexBufferResource(gfx::VertexBufferResource& resource, const void* data, std::size_t size) { - vertexBuffer = static_cast(resource).buffer; - MBGL_CHECK_ERROR(glBufferSubData(GL_ARRAY_BUFFER, 0, size, data)); -} - -std::unique_ptr -Context::createIndexBufferResource(const void* data, std::size_t size, const gfx::BufferUsageType usage) { - BufferID id = 0; - MBGL_CHECK_ERROR(glGenBuffers(1, &id)); - UniqueBuffer result { std::move(id), { this } }; - bindVertexArray = 0; - globalVertexArrayState.indexBuffer = result; - MBGL_CHECK_ERROR(glBufferData(GL_ELEMENT_ARRAY_BUFFER, size, data, Enum::to(usage))); - return std::make_unique(std::move(result)); -} - -void Context::updateIndexBufferResource(gfx::IndexBufferResource& resource, const void* data, std::size_t size) { - // Be sure to unbind any existing vertex array object before binding the index buffer - // so that we don't mess up another VAO - bindVertexArray = 0; - globalVertexArrayState.indexBuffer = static_cast(resource).buffer; - MBGL_CHECK_ERROR(glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, size, data)); -} - - UniqueTexture Context::createUniqueTexture() { if (pooledTextures.empty()) { pooledTextures.resize(TextureMax); @@ -339,6 +302,32 @@ UniqueFramebuffer Context::createFramebuffer() { return UniqueFramebuffer{ std::move(id), { this } }; } +std::unique_ptr Context::createTextureResource( + const Size size, const gfx::TexturePixelType format, const gfx::TextureChannelDataType type) { + auto obj = createUniqueTexture(); + std::unique_ptr resource = + std::make_unique(std::move(obj)); + + // Always use texture unit 0 for manipulating it. + activeTextureUnit = 0; + texture[0] = static_cast(*resource).texture; + + // Creates an empty texture with the specified size and format. + MBGL_CHECK_ERROR(glTexImage2D(GL_TEXTURE_2D, 0, Enum::to(format), + size.width, size.height, 0, + Enum::to(format), + Enum::to(type), nullptr)); + + // We are using clamp to edge here since OpenGL ES doesn't allow GL_REPEAT on NPOT textures. + // We use those when the pixelRatio isn't a power of two, e.g. on iPhone 6 Plus. + MBGL_CHECK_ERROR(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE)); + MBGL_CHECK_ERROR(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE)); + MBGL_CHECK_ERROR(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST)); + MBGL_CHECK_ERROR(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST)); + + return resource; +} + std::unique_ptr Context::createRenderbufferResource(const gfx::RenderbufferPixelType type, const Size size) { RenderbufferID id = 0; @@ -506,55 +495,6 @@ Context::createFramebuffer(const gfx::Texture& color, return { depth.getSize(), std::move(fbo) }; } -std::unique_ptr -Context::createTextureResource(const Size size, - const void* data, - gfx::TexturePixelType format, - gfx::TextureChannelDataType type) { - auto obj = createUniqueTexture(); - std::unique_ptr resource = std::make_unique(std::move(obj)); - pixelStoreUnpack = { 1 }; - updateTextureResource(*resource, size, data, format, type); - // We are using clamp to edge here since OpenGL ES doesn't allow GL_REPEAT on NPOT textures. - // We use those when the pixelRatio isn't a power of two, e.g. on iPhone 6 Plus. - MBGL_CHECK_ERROR(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE)); - MBGL_CHECK_ERROR(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE)); - MBGL_CHECK_ERROR(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST)); - MBGL_CHECK_ERROR(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST)); - return resource; -} - -void Context::updateTextureResource(gfx::TextureResource& resource, - const Size size, - const void* data, - gfx::TexturePixelType format, - gfx::TextureChannelDataType type) { - // Always use texture unit 0 for manipulating it. - activeTextureUnit = 0; - texture[0] = static_cast(resource).texture; - MBGL_CHECK_ERROR(glTexImage2D(GL_TEXTURE_2D, 0, Enum::to(format), - size.width, size.height, 0, - Enum::to(format), - Enum::to(type), data)); -} - -void Context::updateTextureResourceSub(gfx::TextureResource& resource, - const uint16_t xOffset, - const uint16_t yOffset, - const Size size, - const void* data, - gfx::TexturePixelType format, - gfx::TextureChannelDataType type) { - // Always use texture unit 0 for manipulating it. - activeTextureUnit = 0; - texture[0] = static_cast(resource).texture; - MBGL_CHECK_ERROR(glTexSubImage2D(GL_TEXTURE_2D, 0, - xOffset, yOffset, - size.width, size.height, - Enum::to(format), - Enum::to(type), data)); -} - std::unique_ptr Context::createOffscreenTexture(const Size size, const gfx::TextureChannelDataType type) { return std::make_unique(*this, size, type); diff --git a/src/mbgl/gl/context.hpp b/src/mbgl/gl/context.hpp index aa8d2c4c84..41e5b5f22d 100644 --- a/src/mbgl/gl/context.hpp +++ b/src/mbgl/gl/context.hpp @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include @@ -42,6 +43,8 @@ public: Context(const Context&) = delete; Context& operator=(const Context& other) = delete; + std::unique_ptr createCommandEncoder() override; + void initializeExtensions(const std::function&); void enableDebugging(); @@ -189,15 +192,6 @@ private: State pointSize; #endif // MBGL_USE_GLES2 - std::unique_ptr createVertexBufferResource(const void* data, std::size_t size, const gfx::BufferUsageType) override; - void updateVertexBufferResource(gfx::VertexBufferResource&, const void* data, std::size_t size) override; - std::unique_ptr createIndexBufferResource(const void* data, std::size_t size, const gfx::BufferUsageType) override; - void updateIndexBufferResource(gfx::IndexBufferResource&, const void* data, std::size_t size) override; - - std::unique_ptr createTextureResource(Size, const void* data, gfx::TexturePixelType, gfx::TextureChannelDataType) override; - void updateTextureResource(gfx::TextureResource&, Size, const void* data, gfx::TexturePixelType, gfx::TextureChannelDataType) override; - void updateTextureResourceSub(gfx::TextureResource&, const uint16_t xOffset, const uint16_t yOffset, Size, const void* data, gfx::TexturePixelType, gfx::TextureChannelDataType) override; - std::unique_ptr createOffscreenTexture( Size, gfx::TextureChannelDataType = gfx::TextureChannelDataType::UnsignedByte) override; std::unique_ptr createOffscreenTexture( @@ -205,6 +199,9 @@ private: gfx::Renderbuffer&, gfx::TextureChannelDataType = gfx::TextureChannelDataType::UnsignedByte) override; + std::unique_ptr + createTextureResource(Size, gfx::TexturePixelType, gfx::TextureChannelDataType) override; + std::unique_ptr createRenderbufferResource(gfx::RenderbufferPixelType, Size size) override; std::unique_ptr createDrawScopeResource() override; @@ -218,8 +215,6 @@ private: VertexArray createVertexArray(); bool supportsVertexArrays() const; - std::unique_ptr createCommandEncoder() override; - friend detail::ProgramDeleter; friend detail::ShaderDeleter; friend detail::BufferDeleter; diff --git a/src/mbgl/gl/object.cpp b/src/mbgl/gl/object.cpp index 2c5f1bca1f..ec2998a27d 100644 --- a/src/mbgl/gl/object.cpp +++ b/src/mbgl/gl/object.cpp @@ -18,8 +18,7 @@ void ShaderDeleter::operator()(ShaderID id) const { } void BufferDeleter::operator()(BufferID id) const { - assert(context); - context->abandonedBuffers.push_back(id); + context.abandonedBuffers.push_back(id); } void TextureDeleter::operator()(TextureID id) const { diff --git a/src/mbgl/gl/object.hpp b/src/mbgl/gl/object.hpp index 1408add65a..9598e0c59e 100644 --- a/src/mbgl/gl/object.hpp +++ b/src/mbgl/gl/object.hpp @@ -22,7 +22,7 @@ struct ShaderDeleter { }; struct BufferDeleter { - Context* context; + Context& context; void operator()(BufferID) const; }; diff --git a/src/mbgl/gl/offscreen_texture.cpp b/src/mbgl/gl/offscreen_texture.cpp index 0b06fedf46..5feef95edf 100644 --- a/src/mbgl/gl/offscreen_texture.cpp +++ b/src/mbgl/gl/offscreen_texture.cpp @@ -25,6 +25,7 @@ public: void bind() override { if (!framebuffer) { + assert(!texture); texture = context.createTexture(size, gfx::TexturePixelType::RGBA, type); if (depth) { framebuffer = context.createFramebuffer(*texture, *depth); diff --git a/src/mbgl/gl/upload_pass.cpp b/src/mbgl/gl/upload_pass.cpp new file mode 100644 index 0000000000..358f1a7203 --- /dev/null +++ b/src/mbgl/gl/upload_pass.cpp @@ -0,0 +1,117 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +namespace mbgl { +namespace gl { + +using namespace platform; + +UploadPass::UploadPass(gl::CommandEncoder& commandEncoder_, const char* name) + : commandEncoder(commandEncoder_), debugGroup(commandEncoder.createDebugGroup(name)) { +} + +std::unique_ptr UploadPass::createVertexBufferResource( + const void* data, std::size_t size, const gfx::BufferUsageType usage) { + BufferID id = 0; + MBGL_CHECK_ERROR(glGenBuffers(1, &id)); + UniqueBuffer result{ std::move(id), { commandEncoder.context } }; + commandEncoder.context.vertexBuffer = result; + MBGL_CHECK_ERROR( + glBufferData(GL_ARRAY_BUFFER, size, data, Enum::to(usage))); + return std::make_unique(std::move(result)); +} + +void UploadPass::updateVertexBufferResource(gfx::VertexBufferResource& resource, + const void* data, + std::size_t size) { + commandEncoder.context.vertexBuffer = static_cast(resource).buffer; + MBGL_CHECK_ERROR(glBufferSubData(GL_ARRAY_BUFFER, 0, size, data)); +} + +std::unique_ptr UploadPass::createIndexBufferResource( + const void* data, std::size_t size, const gfx::BufferUsageType usage) { + BufferID id = 0; + MBGL_CHECK_ERROR(glGenBuffers(1, &id)); + UniqueBuffer result{ std::move(id), { commandEncoder.context } }; + commandEncoder.context.bindVertexArray = 0; + commandEncoder.context.globalVertexArrayState.indexBuffer = result; + MBGL_CHECK_ERROR( + glBufferData(GL_ELEMENT_ARRAY_BUFFER, size, data, Enum::to(usage))); + return std::make_unique(std::move(result)); +} + +void UploadPass::updateIndexBufferResource(gfx::IndexBufferResource& resource, + const void* data, + std::size_t size) { + // Be sure to unbind any existing vertex array object before binding the index buffer + // so that we don't mess up another VAO + commandEncoder.context.bindVertexArray = 0; + commandEncoder.context.globalVertexArrayState.indexBuffer = + static_cast(resource).buffer; + MBGL_CHECK_ERROR(glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, size, data)); +} + +std::unique_ptr +UploadPass::createTextureResource(const Size size, + const void* data, + gfx::TexturePixelType format, + gfx::TextureChannelDataType type) { + auto obj = commandEncoder.context.createUniqueTexture(); + std::unique_ptr resource = + std::make_unique(std::move(obj)); + commandEncoder.context.pixelStoreUnpack = { 1 }; + updateTextureResource(*resource, size, data, format, type); + // We are using clamp to edge here since OpenGL ES doesn't allow GL_REPEAT on NPOT textures. + // We use those when the pixelRatio isn't a power of two, e.g. on iPhone 6 Plus. + MBGL_CHECK_ERROR(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE)); + MBGL_CHECK_ERROR(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE)); + MBGL_CHECK_ERROR(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST)); + MBGL_CHECK_ERROR(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST)); + return resource; +} + +void UploadPass::updateTextureResource(gfx::TextureResource& resource, + const Size size, + const void* data, + gfx::TexturePixelType format, + gfx::TextureChannelDataType type) { + // Always use texture unit 0 for manipulating it. + commandEncoder.context.activeTextureUnit = 0; + commandEncoder.context.texture[0] = static_cast(resource).texture; + MBGL_CHECK_ERROR(glTexImage2D(GL_TEXTURE_2D, 0, Enum::to(format), + size.width, size.height, 0, + Enum::to(format), + Enum::to(type), data)); +} + +void UploadPass::updateTextureResourceSub(gfx::TextureResource& resource, + const uint16_t xOffset, + const uint16_t yOffset, + const Size size, + const void* data, + gfx::TexturePixelType format, + gfx::TextureChannelDataType type) { + // Always use texture unit 0 for manipulating it. + commandEncoder.context.activeTextureUnit = 0; + commandEncoder.context.texture[0] = static_cast(resource).texture; + MBGL_CHECK_ERROR(glTexSubImage2D(GL_TEXTURE_2D, 0, xOffset, yOffset, size.width, size.height, + Enum::to(format), + Enum::to(type), data)); +} + +void UploadPass::pushDebugGroup(const char* name) { + commandEncoder.pushDebugGroup(name); +} + +void UploadPass::popDebugGroup() { + commandEncoder.popDebugGroup(); +} + +} // namespace gl +} // namespace mbgl diff --git a/src/mbgl/gl/upload_pass.hpp b/src/mbgl/gl/upload_pass.hpp new file mode 100644 index 0000000000..8b4f71b88d --- /dev/null +++ b/src/mbgl/gl/upload_pass.hpp @@ -0,0 +1,42 @@ +#pragma once + +#include + +namespace mbgl { +namespace gfx { + +class CommandEncoder; + +} // namespace gfx + +namespace gl { + +class CommandEncoder; +class Context; + +class UploadPass final : public gfx::UploadPass { +public: + UploadPass(gl::CommandEncoder&, const char* name); + +private: + void pushDebugGroup(const char* name) override; + void popDebugGroup() override; + +public: + std::unique_ptr createVertexBufferResource(const void* data, std::size_t size, const gfx::BufferUsageType) override; + void updateVertexBufferResource(gfx::VertexBufferResource&, const void* data, std::size_t size) override; + std::unique_ptr createIndexBufferResource(const void* data, std::size_t size, const gfx::BufferUsageType) override; + void updateIndexBufferResource(gfx::IndexBufferResource&, const void* data, std::size_t size) override; + +public: + std::unique_ptr createTextureResource(Size, const void* data, gfx::TexturePixelType, gfx::TextureChannelDataType) override; + void updateTextureResource(gfx::TextureResource&, Size, const void* data, gfx::TexturePixelType, gfx::TextureChannelDataType) override; + void updateTextureResourceSub(gfx::TextureResource&, const uint16_t xOffset, const uint16_t yOffset, Size, const void* data, gfx::TexturePixelType, gfx::TextureChannelDataType) override; + +private: + gl::CommandEncoder& commandEncoder; + const gfx::DebugGroup debugGroup; +}; + +} // namespace gl +} // namespace mbgl diff --git a/src/mbgl/programs/program.hpp b/src/mbgl/programs/program.hpp index cb68735bf8..ae9d1d3669 100644 --- a/src/mbgl/programs/program.hpp +++ b/src/mbgl/programs/program.hpp @@ -2,6 +2,7 @@ #include #include +#include #include #include #include diff --git a/src/mbgl/renderer/bucket.hpp b/src/mbgl/renderer/bucket.hpp index e345f0b5ec..a0d2895b70 100644 --- a/src/mbgl/renderer/bucket.hpp +++ b/src/mbgl/renderer/bucket.hpp @@ -9,7 +9,7 @@ namespace mbgl { namespace gfx { -class Context; +class UploadPass; } // namespace gfx class RenderLayer; @@ -33,7 +33,7 @@ public: // As long as this bucket has a Prepare render pass, this function is getting called. Typically, // this only happens once when the bucket is being rendered for the first time. - virtual void upload(gfx::Context&) = 0; + virtual void upload(gfx::UploadPass&) = 0; virtual bool hasData() const = 0; diff --git a/src/mbgl/renderer/buckets/circle_bucket.cpp b/src/mbgl/renderer/buckets/circle_bucket.cpp index 376f4e682f..d9ba5f31ca 100644 --- a/src/mbgl/renderer/buckets/circle_bucket.cpp +++ b/src/mbgl/renderer/buckets/circle_bucket.cpp @@ -24,12 +24,12 @@ CircleBucket::CircleBucket(const BucketParameters& parameters, const std::vector CircleBucket::~CircleBucket() = default; -void CircleBucket::upload(gfx::Context& context) { - vertexBuffer = context.createVertexBuffer(std::move(vertices)); - indexBuffer = context.createIndexBuffer(std::move(triangles)); +void CircleBucket::upload(gfx::UploadPass& uploadPass) { + vertexBuffer = uploadPass.createVertexBuffer(std::move(vertices)); + indexBuffer = uploadPass.createIndexBuffer(std::move(triangles)); for (auto& pair : paintPropertyBinders) { - pair.second.upload(context); + pair.second.upload(uploadPass); } uploaded = true; diff --git a/src/mbgl/renderer/buckets/circle_bucket.hpp b/src/mbgl/renderer/buckets/circle_bucket.hpp index 58f76327ab..145748f313 100644 --- a/src/mbgl/renderer/buckets/circle_bucket.hpp +++ b/src/mbgl/renderer/buckets/circle_bucket.hpp @@ -25,7 +25,7 @@ public: bool hasData() const override; - void upload(gfx::Context&) override; + void upload(gfx::UploadPass&) override; float getQueryRadius(const RenderLayer&) const override; bool supportsLayer(const style::Layer::Impl&) const override; diff --git a/src/mbgl/renderer/buckets/debug_bucket.cpp b/src/mbgl/renderer/buckets/debug_bucket.cpp index dac7622996..13380c0905 100644 --- a/src/mbgl/renderer/buckets/debug_bucket.cpp +++ b/src/mbgl/renderer/buckets/debug_bucket.cpp @@ -1,5 +1,4 @@ #include -#include #include #include #include @@ -16,8 +15,7 @@ DebugBucket::DebugBucket(const OverscaledTileID& id, const bool complete_, optional modified_, optional expires_, - MapDebugOptions debugMode_, - gfx::Context& context) + MapDebugOptions debugMode_) : renderable(renderable_), complete(complete_), modified(std::move(modified_)), @@ -25,9 +23,6 @@ DebugBucket::DebugBucket(const OverscaledTileID& id, debugMode(debugMode_), drawScopeID("__debug/" + util::toHex(util::nextID())) { - gfx::VertexVector vertices; - gfx::IndexVector indices; - auto addText = [&] (const std::string& text, double left, double baseline, double scale) { for (uint8_t c : text) { if (c < 32 || c >= 127) @@ -77,10 +72,12 @@ DebugBucket::DebugBucket(const OverscaledTileID& id, } segments.emplace_back(0, 0, vertices.elements(), indices.elements()); +} +void DebugBucket::upload(gfx::UploadPass& uploadPass) { if (!vertices.empty()) { - vertexBuffer = context.createVertexBuffer(std::move(vertices)); - indexBuffer = context.createIndexBuffer(std::move(indices)); + vertexBuffer = uploadPass.createVertexBuffer(std::move(vertices)); + indexBuffer = uploadPass.createIndexBuffer(std::move(indices)); } } diff --git a/src/mbgl/renderer/buckets/debug_bucket.hpp b/src/mbgl/renderer/buckets/debug_bucket.hpp index 30d5ff67c8..2b735b4987 100644 --- a/src/mbgl/renderer/buckets/debug_bucket.hpp +++ b/src/mbgl/renderer/buckets/debug_bucket.hpp @@ -8,13 +8,14 @@ #include #include #include +#include namespace mbgl { class OverscaledTileID; namespace gl { -class Context; +class UploadPass; } // namespace gl class DebugBucket : private util::noncopyable { @@ -24,8 +25,9 @@ public: bool complete, optional modified, optional expires, - MapDebugOptions, - gfx::Context&); + MapDebugOptions); + + void upload(gfx::UploadPass&); const bool renderable; const bool complete; @@ -33,6 +35,10 @@ public: const optional expires; const MapDebugOptions debugMode; + + gfx::VertexVector vertices; + gfx::IndexVector indices; + SegmentVector segments; optional> vertexBuffer; optional indexBuffer; diff --git a/src/mbgl/renderer/buckets/fill_bucket.cpp b/src/mbgl/renderer/buckets/fill_bucket.cpp index c69b60327d..e4cfd339d4 100644 --- a/src/mbgl/renderer/buckets/fill_bucket.cpp +++ b/src/mbgl/renderer/buckets/fill_bucket.cpp @@ -121,13 +121,13 @@ void FillBucket::addFeature(const GeometryTileFeature& feature, } } -void FillBucket::upload(gfx::Context& context) { - vertexBuffer = context.createVertexBuffer(std::move(vertices)); - lineIndexBuffer = context.createIndexBuffer(std::move(lines)); - triangleIndexBuffer = context.createIndexBuffer(std::move(triangles)); +void FillBucket::upload(gfx::UploadPass& uploadPass) { + vertexBuffer = uploadPass.createVertexBuffer(std::move(vertices)); + lineIndexBuffer = uploadPass.createIndexBuffer(std::move(lines)); + triangleIndexBuffer = uploadPass.createIndexBuffer(std::move(triangles)); for (auto& pair : paintPropertyBinders) { - pair.second.upload(context); + pair.second.upload(uploadPass); } uploaded = true; diff --git a/src/mbgl/renderer/buckets/fill_bucket.hpp b/src/mbgl/renderer/buckets/fill_bucket.hpp index 217524c945..1a0d77dff7 100644 --- a/src/mbgl/renderer/buckets/fill_bucket.hpp +++ b/src/mbgl/renderer/buckets/fill_bucket.hpp @@ -33,7 +33,7 @@ public: bool hasData() const override; - void upload(gfx::Context&) override; + void upload(gfx::UploadPass&) override; float getQueryRadius(const RenderLayer&) const override; bool supportsLayer(const style::Layer::Impl&) const override; diff --git a/src/mbgl/renderer/buckets/fill_extrusion_bucket.cpp b/src/mbgl/renderer/buckets/fill_extrusion_bucket.cpp index 7fa7293f33..51202b3ee4 100644 --- a/src/mbgl/renderer/buckets/fill_extrusion_bucket.cpp +++ b/src/mbgl/renderer/buckets/fill_extrusion_bucket.cpp @@ -165,12 +165,12 @@ void FillExtrusionBucket::addFeature(const GeometryTileFeature& feature, } } -void FillExtrusionBucket::upload(gfx::Context& context) { - vertexBuffer = context.createVertexBuffer(std::move(vertices)); - indexBuffer = context.createIndexBuffer(std::move(triangles)); +void FillExtrusionBucket::upload(gfx::UploadPass& uploadPass) { + vertexBuffer = uploadPass.createVertexBuffer(std::move(vertices)); + indexBuffer = uploadPass.createIndexBuffer(std::move(triangles)); for (auto& pair : paintPropertyBinders) { - pair.second.upload(context); + pair.second.upload(uploadPass); } uploaded = true; diff --git a/src/mbgl/renderer/buckets/fill_extrusion_bucket.hpp b/src/mbgl/renderer/buckets/fill_extrusion_bucket.hpp index 85867031a7..8fa2f4f8e8 100644 --- a/src/mbgl/renderer/buckets/fill_extrusion_bucket.hpp +++ b/src/mbgl/renderer/buckets/fill_extrusion_bucket.hpp @@ -33,7 +33,7 @@ public: bool supportsLayer(const style::Layer::Impl&) const override; - void upload(gfx::Context&) override; + void upload(gfx::UploadPass&) override; float getQueryRadius(const RenderLayer&) const override; diff --git a/src/mbgl/renderer/buckets/heatmap_bucket.cpp b/src/mbgl/renderer/buckets/heatmap_bucket.cpp index 111911a88c..287c9ed26a 100644 --- a/src/mbgl/renderer/buckets/heatmap_bucket.cpp +++ b/src/mbgl/renderer/buckets/heatmap_bucket.cpp @@ -24,12 +24,12 @@ HeatmapBucket::HeatmapBucket(const BucketParameters& parameters, const std::vect HeatmapBucket::~HeatmapBucket() = default; -void HeatmapBucket::upload(gfx::Context& context) { - vertexBuffer = context.createVertexBuffer(std::move(vertices)); - indexBuffer = context.createIndexBuffer(std::move(triangles)); +void HeatmapBucket::upload(gfx::UploadPass& uploadPass) { + vertexBuffer = uploadPass.createVertexBuffer(std::move(vertices)); + indexBuffer = uploadPass.createIndexBuffer(std::move(triangles)); for (auto& pair : paintPropertyBinders) { - pair.second.upload(context); + pair.second.upload(uploadPass); } uploaded = true; diff --git a/src/mbgl/renderer/buckets/heatmap_bucket.hpp b/src/mbgl/renderer/buckets/heatmap_bucket.hpp index b11c1626cd..e3d0b7c769 100644 --- a/src/mbgl/renderer/buckets/heatmap_bucket.hpp +++ b/src/mbgl/renderer/buckets/heatmap_bucket.hpp @@ -24,7 +24,7 @@ public: const PatternLayerMap&) override; bool hasData() const override; - void upload(gfx::Context&) override; + void upload(gfx::UploadPass&) override; float getQueryRadius(const RenderLayer&) const override; bool supportsLayer(const style::Layer::Impl&) const override; diff --git a/src/mbgl/renderer/buckets/hillshade_bucket.cpp b/src/mbgl/renderer/buckets/hillshade_bucket.cpp index 3c14845dd8..08f941f990 100644 --- a/src/mbgl/renderer/buckets/hillshade_bucket.cpp +++ b/src/mbgl/renderer/buckets/hillshade_bucket.cpp @@ -26,18 +26,18 @@ DEMData& HillshadeBucket::getDEMData() { return demdata; } -void HillshadeBucket::upload(gfx::Context& context) { +void HillshadeBucket::upload(gfx::UploadPass& uploadPass) { if (!hasData()) { return; } const PremultipliedImage* image = demdata.getImage(); - dem = context.createTexture(*image); + dem = uploadPass.createTexture(*image); if (!segments.empty()) { - vertexBuffer = context.createVertexBuffer(std::move(vertices)); - indexBuffer = context.createIndexBuffer(std::move(indices)); + vertexBuffer = uploadPass.createVertexBuffer(std::move(vertices)); + indexBuffer = uploadPass.createIndexBuffer(std::move(indices)); } uploaded = true; } diff --git a/src/mbgl/renderer/buckets/hillshade_bucket.hpp b/src/mbgl/renderer/buckets/hillshade_bucket.hpp index f3e89642cc..08acdff0c3 100644 --- a/src/mbgl/renderer/buckets/hillshade_bucket.hpp +++ b/src/mbgl/renderer/buckets/hillshade_bucket.hpp @@ -22,7 +22,7 @@ public: HillshadeBucket(DEMData&&); ~HillshadeBucket() override; - void upload(gfx::Context&) override; + void upload(gfx::UploadPass&) override; bool hasData() const override; bool supportsLayer(const style::Layer::Impl&) const override; diff --git a/src/mbgl/renderer/buckets/line_bucket.cpp b/src/mbgl/renderer/buckets/line_bucket.cpp index c2cce632b3..0536992707 100644 --- a/src/mbgl/renderer/buckets/line_bucket.cpp +++ b/src/mbgl/renderer/buckets/line_bucket.cpp @@ -508,12 +508,12 @@ void LineBucket::addPieSliceVertex(const GeometryCoordinate& currentVertex, } } -void LineBucket::upload(gfx::Context& context) { - vertexBuffer = context.createVertexBuffer(std::move(vertices)); - indexBuffer = context.createIndexBuffer(std::move(triangles)); +void LineBucket::upload(gfx::UploadPass& uploadPass) { + vertexBuffer = uploadPass.createVertexBuffer(std::move(vertices)); + indexBuffer = uploadPass.createIndexBuffer(std::move(triangles)); for (auto& pair : paintPropertyBinders) { - pair.second.upload(context); + pair.second.upload(uploadPass); } uploaded = true; diff --git a/src/mbgl/renderer/buckets/line_bucket.hpp b/src/mbgl/renderer/buckets/line_bucket.hpp index 9afe7fecee..342f5cd88c 100644 --- a/src/mbgl/renderer/buckets/line_bucket.hpp +++ b/src/mbgl/renderer/buckets/line_bucket.hpp @@ -33,7 +33,7 @@ public: bool hasData() const override; - void upload(gfx::Context&) override; + void upload(gfx::UploadPass&) override; float getQueryRadius(const RenderLayer&) const override; bool supportsLayer(const style::Layer::Impl&) const override; diff --git a/src/mbgl/renderer/buckets/raster_bucket.cpp b/src/mbgl/renderer/buckets/raster_bucket.cpp index 7afb6172f5..57d3ba1896 100644 --- a/src/mbgl/renderer/buckets/raster_bucket.cpp +++ b/src/mbgl/renderer/buckets/raster_bucket.cpp @@ -1,7 +1,7 @@ #include #include #include -#include +#include #include namespace mbgl { @@ -20,16 +20,16 @@ RasterBucket::RasterBucket(std::shared_ptr image_) RasterBucket::~RasterBucket() = default; -void RasterBucket::upload(gfx::Context& context) { +void RasterBucket::upload(gfx::UploadPass& uploadPass) { if (!hasData()) { return; } if (!texture) { - texture = context.createTexture(*image); + texture = uploadPass.createTexture(*image); } if (!segments.empty()) { - vertexBuffer = context.createVertexBuffer(std::move(vertices)); - indexBuffer = context.createIndexBuffer(std::move(indices)); + vertexBuffer = uploadPass.createVertexBuffer(std::move(vertices)); + indexBuffer = uploadPass.createIndexBuffer(std::move(indices)); } uploaded = true; } diff --git a/src/mbgl/renderer/buckets/raster_bucket.hpp b/src/mbgl/renderer/buckets/raster_bucket.hpp index db1de4d0d1..b6182f7b2c 100644 --- a/src/mbgl/renderer/buckets/raster_bucket.hpp +++ b/src/mbgl/renderer/buckets/raster_bucket.hpp @@ -18,7 +18,7 @@ public: RasterBucket(std::shared_ptr); ~RasterBucket() override; - void upload(gfx::Context&) override; + void upload(gfx::UploadPass&) override; bool hasData() const override; bool supportsLayer(const style::Layer::Impl&) const override; diff --git a/src/mbgl/renderer/buckets/symbol_bucket.cpp b/src/mbgl/renderer/buckets/symbol_bucket.cpp index fb5a38f913..f290288114 100644 --- a/src/mbgl/renderer/buckets/symbol_bucket.cpp +++ b/src/mbgl/renderer/buckets/symbol_bucket.cpp @@ -43,76 +43,76 @@ SymbolBucket::SymbolBucket(style::SymbolLayoutProperties::PossiblyEvaluated layo SymbolBucket::~SymbolBucket() = default; -void SymbolBucket::upload(gfx::Context& context) { +void SymbolBucket::upload(gfx::UploadPass& uploadPass) { if (hasTextData()) { if (!staticUploaded) { - text.indexBuffer = context.createIndexBuffer(std::move(text.triangles), sortFeaturesByY ? gfx::BufferUsageType::StreamDraw : gfx::BufferUsageType::StaticDraw); - text.vertexBuffer = context.createVertexBuffer(std::move(text.vertices)); + text.indexBuffer = uploadPass.createIndexBuffer(std::move(text.triangles), sortFeaturesByY ? gfx::BufferUsageType::StreamDraw : gfx::BufferUsageType::StaticDraw); + text.vertexBuffer = uploadPass.createVertexBuffer(std::move(text.vertices)); for (auto& pair : paintProperties) { - pair.second.textBinders.upload(context); + pair.second.textBinders.upload(uploadPass); } } else if (!sortUploaded) { - context.updateIndexBuffer(*text.indexBuffer, std::move(text.triangles)); + uploadPass.updateIndexBuffer(*text.indexBuffer, std::move(text.triangles)); } if (!dynamicUploaded) { - text.dynamicVertexBuffer = context.createVertexBuffer(std::move(text.dynamicVertices), gfx::BufferUsageType::StreamDraw); + text.dynamicVertexBuffer = uploadPass.createVertexBuffer(std::move(text.dynamicVertices), gfx::BufferUsageType::StreamDraw); } if (!placementChangesUploaded) { if (!text.opacityVertexBuffer) { - text.opacityVertexBuffer = context.createVertexBuffer(std::move(text.opacityVertices), gfx::BufferUsageType::StreamDraw); + text.opacityVertexBuffer = uploadPass.createVertexBuffer(std::move(text.opacityVertices), gfx::BufferUsageType::StreamDraw); } else { - context.updateVertexBuffer(*text.opacityVertexBuffer, std::move(text.opacityVertices)); + uploadPass.updateVertexBuffer(*text.opacityVertexBuffer, std::move(text.opacityVertices)); } } } if (hasIconData()) { if (!staticUploaded) { - icon.indexBuffer = context.createIndexBuffer(std::move(icon.triangles), sortFeaturesByY ? gfx::BufferUsageType::StreamDraw : gfx::BufferUsageType::StaticDraw); - icon.vertexBuffer = context.createVertexBuffer(std::move(icon.vertices)); + icon.indexBuffer = uploadPass.createIndexBuffer(std::move(icon.triangles), sortFeaturesByY ? gfx::BufferUsageType::StreamDraw : gfx::BufferUsageType::StaticDraw); + icon.vertexBuffer = uploadPass.createVertexBuffer(std::move(icon.vertices)); for (auto& pair : paintProperties) { - pair.second.iconBinders.upload(context); + pair.second.iconBinders.upload(uploadPass); } } else if (!sortUploaded) { - context.updateIndexBuffer(*icon.indexBuffer, std::move(icon.triangles)); + uploadPass.updateIndexBuffer(*icon.indexBuffer, std::move(icon.triangles)); } if (!dynamicUploaded) { - icon.dynamicVertexBuffer = context.createVertexBuffer(std::move(icon.dynamicVertices), gfx::BufferUsageType::StreamDraw); + icon.dynamicVertexBuffer = uploadPass.createVertexBuffer(std::move(icon.dynamicVertices), gfx::BufferUsageType::StreamDraw); } if (!placementChangesUploaded) { if (!icon.opacityVertexBuffer) { - icon.opacityVertexBuffer = context.createVertexBuffer(std::move(icon.opacityVertices), gfx::BufferUsageType::StreamDraw); + icon.opacityVertexBuffer = uploadPass.createVertexBuffer(std::move(icon.opacityVertices), gfx::BufferUsageType::StreamDraw); } else { - context.updateVertexBuffer(*icon.opacityVertexBuffer, std::move(icon.opacityVertices)); + uploadPass.updateVertexBuffer(*icon.opacityVertexBuffer, std::move(icon.opacityVertices)); } } } if (hasCollisionBoxData()) { if (!staticUploaded) { - collisionBox.indexBuffer = context.createIndexBuffer(std::move(collisionBox.lines)); - collisionBox.vertexBuffer = context.createVertexBuffer(std::move(collisionBox.vertices)); + collisionBox.indexBuffer = uploadPass.createIndexBuffer(std::move(collisionBox.lines)); + collisionBox.vertexBuffer = uploadPass.createVertexBuffer(std::move(collisionBox.vertices)); } if (!placementChangesUploaded) { if (!collisionBox.dynamicVertexBuffer) { - collisionBox.dynamicVertexBuffer = context.createVertexBuffer(std::move(collisionBox.dynamicVertices), gfx::BufferUsageType::StreamDraw); + collisionBox.dynamicVertexBuffer = uploadPass.createVertexBuffer(std::move(collisionBox.dynamicVertices), gfx::BufferUsageType::StreamDraw); } else { - context.updateVertexBuffer(*collisionBox.dynamicVertexBuffer, std::move(collisionBox.dynamicVertices)); + uploadPass.updateVertexBuffer(*collisionBox.dynamicVertexBuffer, std::move(collisionBox.dynamicVertices)); } } } if (hasCollisionCircleData()) { if (!staticUploaded) { - collisionCircle.indexBuffer = context.createIndexBuffer(std::move(collisionCircle.triangles)); - collisionCircle.vertexBuffer = context.createVertexBuffer(std::move(collisionCircle.vertices)); + collisionCircle.indexBuffer = uploadPass.createIndexBuffer(std::move(collisionCircle.triangles)); + collisionCircle.vertexBuffer = uploadPass.createVertexBuffer(std::move(collisionCircle.vertices)); } if (!placementChangesUploaded) { if (!collisionCircle.dynamicVertexBuffer) { - collisionCircle.dynamicVertexBuffer = context.createVertexBuffer(std::move(collisionCircle.dynamicVertices), gfx::BufferUsageType::StreamDraw); + collisionCircle.dynamicVertexBuffer = uploadPass.createVertexBuffer(std::move(collisionCircle.dynamicVertices), gfx::BufferUsageType::StreamDraw); } else { - context.updateVertexBuffer(*collisionCircle.dynamicVertexBuffer, std::move(collisionCircle.dynamicVertices)); + uploadPass.updateVertexBuffer(*collisionCircle.dynamicVertexBuffer, std::move(collisionCircle.dynamicVertices)); } } } diff --git a/src/mbgl/renderer/buckets/symbol_bucket.hpp b/src/mbgl/renderer/buckets/symbol_bucket.hpp index 7db17f0062..0b9c5e583f 100644 --- a/src/mbgl/renderer/buckets/symbol_bucket.hpp +++ b/src/mbgl/renderer/buckets/symbol_bucket.hpp @@ -54,7 +54,7 @@ public: const float tilePixelRatio); ~SymbolBucket() override; - void upload(gfx::Context&) override; + void upload(gfx::UploadPass&) override; bool hasData() const override; bool supportsLayer(const style::Layer::Impl&) const override; bool hasTextData() const; diff --git a/src/mbgl/renderer/image_atlas.cpp b/src/mbgl/renderer/image_atlas.cpp index 282f135ac9..da7f5a30be 100644 --- a/src/mbgl/renderer/image_atlas.cpp +++ b/src/mbgl/renderer/image_atlas.cpp @@ -1,4 +1,5 @@ #include +#include #include #include @@ -52,26 +53,26 @@ const mapbox::Bin& _packImage(mapbox::ShelfPack& pack, const style::Image::Impl& return bin; } -void ImageAtlas::patchUpdatedImages(gfx::Context& context, gfx::Texture& atlasTexture, const ImageManager& imageManager) { +void ImageAtlas::patchUpdatedImages(gfx::UploadPass& uploadPass, gfx::Texture& atlasTexture, const ImageManager& imageManager) { for (auto& updatedImageVersion : imageManager.updatedImageVersions) { auto iconPosition = iconPositions.find(updatedImageVersion.first); if (iconPosition != iconPositions.end()) { - patchUpdatedImage(context, atlasTexture, iconPosition->second, imageManager, updatedImageVersion.first, updatedImageVersion.second); + patchUpdatedImage(uploadPass, atlasTexture, iconPosition->second, imageManager, updatedImageVersion.first, updatedImageVersion.second); } auto patternPosition = patternPositions.find(updatedImageVersion.first); if (patternPosition != patternPositions.end()) { - patchUpdatedImage(context, atlasTexture, patternPosition->second, imageManager, updatedImageVersion.first, updatedImageVersion.second); + patchUpdatedImage(uploadPass, atlasTexture, patternPosition->second, imageManager, updatedImageVersion.first, updatedImageVersion.second); } } } -void ImageAtlas::patchUpdatedImage(gfx::Context& context, gfx::Texture& atlasTexture, ImagePosition& position, const ImageManager& imageManager, const std::string& name, uint16_t version) { +void ImageAtlas::patchUpdatedImage(gfx::UploadPass& uploadPass, gfx::Texture& atlasTexture, ImagePosition& position, const ImageManager& imageManager, const std::string& name, uint16_t version) { if (position.version == version) return; auto updatedImage = imageManager.getImage(name); if (updatedImage == nullptr) return; - context.updateTextureSub(atlasTexture, updatedImage->image, position.textureRect.x, position.textureRect.y); + uploadPass.updateTextureSub(atlasTexture, updatedImage->image, position.textureRect.x, position.textureRect.y); position.version = version; } diff --git a/src/mbgl/renderer/image_atlas.hpp b/src/mbgl/renderer/image_atlas.hpp index 080a490ab2..b59153c4a6 100644 --- a/src/mbgl/renderer/image_atlas.hpp +++ b/src/mbgl/renderer/image_atlas.hpp @@ -10,8 +10,8 @@ namespace mbgl { namespace gfx { - class Texture; - class Context; +class UploadPass; +class Texture; } // namespace gfx class ImageManager; @@ -60,9 +60,9 @@ public: ImagePositions iconPositions; ImagePositions patternPositions; - void patchUpdatedImages(gfx::Context&, gfx::Texture&, const ImageManager&); + void patchUpdatedImages(gfx::UploadPass&, gfx::Texture&, const ImageManager&); private: - void patchUpdatedImage(gfx::Context&, gfx::Texture&, ImagePosition& position, const ImageManager& imageManager, const std::string& name, uint16_t version); + void patchUpdatedImage(gfx::UploadPass&, gfx::Texture&, ImagePosition& position, const ImageManager& imageManager, const std::string& name, uint16_t version); }; ImageAtlas makeImageAtlas(const ImageMap&, const ImageMap&, const std::unordered_map& versionMap); diff --git a/src/mbgl/renderer/image_manager.cpp b/src/mbgl/renderer/image_manager.cpp index 936dac75c3..10375fe900 100644 --- a/src/mbgl/renderer/image_manager.cpp +++ b/src/mbgl/renderer/image_manager.cpp @@ -2,6 +2,7 @@ #include #include #include +#include #include #include @@ -285,18 +286,19 @@ Size ImageManager::getPixelSize() const { }; } -void ImageManager::upload(gfx::Context& context) { +void ImageManager::upload(gfx::UploadPass& uploadPass) { if (!atlasTexture) { - atlasTexture = context.createTexture(atlasImage); + atlasTexture = uploadPass.createTexture(atlasImage); } else if (dirty) { - context.updateTexture(*atlasTexture, atlasImage); + uploadPass.updateTexture(*atlasTexture, atlasImage); } dirty = false; } -gfx::TextureBinding ImageManager::textureBinding(gfx::Context& context) { - upload(context); +gfx::TextureBinding ImageManager::textureBinding() { + assert(atlasTexture); + assert(!dirty); return { atlasTexture->getResource(), gfx::TextureFilterType::Linear }; } diff --git a/src/mbgl/renderer/image_manager.hpp b/src/mbgl/renderer/image_manager.hpp index c2d6466b3a..533259039f 100644 --- a/src/mbgl/renderer/image_manager.hpp +++ b/src/mbgl/renderer/image_manager.hpp @@ -19,7 +19,7 @@ template class Actor; namespace gfx { -class Context; +class UploadPass; } // namespace gfx class ImageRequestor; @@ -83,8 +83,8 @@ private: public: optional getPattern(const std::string& name); - gfx::TextureBinding textureBinding(gfx::Context&); - void upload(gfx::Context&); + gfx::TextureBinding textureBinding(); + void upload(gfx::UploadPass&); Size getPixelSize() const; diff --git a/src/mbgl/renderer/layers/render_background_layer.cpp b/src/mbgl/renderer/layers/render_background_layer.cpp index 3eb9bc2a30..51c4f2ae4f 100644 --- a/src/mbgl/renderer/layers/render_background_layer.cpp +++ b/src/mbgl/renderer/layers/render_background_layer.cpp @@ -1,6 +1,7 @@ #include #include #include +#include #include #include #include @@ -37,6 +38,9 @@ void RenderBackgroundLayer::evaluate(const PropertyEvaluationParameters ¶met passes = properties->evaluated.get() > 0 ? RenderPass::Translucent : RenderPass::None; + if (passes != RenderPass::None && !properties->evaluated.get().to.empty()) { + passes |= RenderPass::Upload; + } evaluatedProperties = std::move(properties); } @@ -48,6 +52,15 @@ bool RenderBackgroundLayer::hasCrossfade() const { return getCrossfade(evaluatedProperties).t != 1; } +void RenderBackgroundLayer::upload(gfx::UploadPass&, UploadParameters& parameters) { + const auto& evaluated = static_cast(*evaluatedProperties).evaluated; + if (!evaluated.get().to.empty()) { + // Ensures that the texture gets added and uploaded to the atlas. + parameters.imageManager.getPattern(evaluated.get().from); + parameters.imageManager.getPattern(evaluated.get().to); + } +} + void RenderBackgroundLayer::render(PaintParameters& parameters, RenderSource*) { // Note that for bottommost layers without a pattern, the background color is drawn with // glClear rather than this method. @@ -63,7 +76,7 @@ void RenderBackgroundLayer::render(PaintParameters& parameters, RenderSource*) { parameters.state.getZoom() ); const auto allAttributeBindings = program.computeAllAttributeBindings( - parameters.staticData.tileVertexBuffer, + *parameters.staticData.tileVertexBuffer, paintAttributeData, properties ); @@ -78,7 +91,7 @@ void RenderBackgroundLayer::render(PaintParameters& parameters, RenderSource*) { gfx::StencilMode::disabled(), parameters.colorModeForRenderPass(), gfx::CullFaceMode::disabled(), - parameters.staticData.quadTriangleIndexBuffer, + *parameters.staticData.quadTriangleIndexBuffer, parameters.staticData.tileTriangleSegments, allUniformValues, allAttributeBindings, @@ -109,7 +122,7 @@ void RenderBackgroundLayer::render(PaintParameters& parameters, RenderSource*) { parameters.state ), BackgroundPatternProgram::TextureBindings{ - textures::image::Value{ parameters.imageManager.textureBinding(parameters.context) }, + textures::image::Value{ parameters.imageManager.textureBinding() }, } ); } diff --git a/src/mbgl/renderer/layers/render_background_layer.hpp b/src/mbgl/renderer/layers/render_background_layer.hpp index de553eef90..248a3e1457 100644 --- a/src/mbgl/renderer/layers/render_background_layer.hpp +++ b/src/mbgl/renderer/layers/render_background_layer.hpp @@ -17,6 +17,7 @@ private: bool hasTransition() const override; bool hasCrossfade() const override; optional getSolidBackground() const override; + void upload(gfx::UploadPass&, UploadParameters&) override; void render(PaintParameters&, RenderSource*) override; // Paint properties diff --git a/src/mbgl/renderer/layers/render_heatmap_layer.cpp b/src/mbgl/renderer/layers/render_heatmap_layer.cpp index f1cce31ea4..053503bbaa 100644 --- a/src/mbgl/renderer/layers/render_heatmap_layer.cpp +++ b/src/mbgl/renderer/layers/render_heatmap_layer.cpp @@ -41,7 +41,7 @@ void RenderHeatmapLayer::evaluate(const PropertyEvaluationParameters& parameters unevaluated.evaluate(parameters)); passes = (properties->evaluated.get() > 0) - ? (RenderPass::Translucent | RenderPass::Pass3D) + ? (RenderPass::Translucent | RenderPass::Pass3D | RenderPass::Upload) : RenderPass::None; evaluatedProperties = std::move(properties); @@ -55,6 +55,13 @@ bool RenderHeatmapLayer::hasCrossfade() const { return false; } +void RenderHeatmapLayer::upload(gfx::UploadPass& uploadPass, UploadParameters&) { + if (!colorRampTexture) { + colorRampTexture = + uploadPass.createTexture(colorRamp, gfx::TextureChannelDataType::UnsignedByte); + } +} + void RenderHeatmapLayer::render(PaintParameters& parameters, RenderSource*) { if (parameters.pass == RenderPass::Opaque) { return; @@ -64,9 +71,7 @@ void RenderHeatmapLayer::render(PaintParameters& parameters, RenderSource*) { const auto& viewportSize = parameters.staticData.backendSize; const auto size = Size{viewportSize.width / 4, viewportSize.height / 4}; - if (!colorRampTexture) { - colorRampTexture = parameters.context.createTexture(colorRamp, gfx::TextureChannelDataType::UnsignedByte); - } + assert(colorRampTexture); if (!renderTexture || renderTexture->getSize() != size) { renderTexture.reset(); @@ -101,7 +106,7 @@ void RenderHeatmapLayer::render(PaintParameters& parameters, RenderSource*) { const auto& paintPropertyBinders = bucket.paintPropertyBinders.at(getID()); auto& programInstance = parameters.programs.getHeatmapLayerPrograms().heatmap; - + const auto allUniformValues = programInstance.computeAllUniformValues( HeatmapProgram::LayoutUniformValues { uniforms::intensity::Value( evaluated.get() ), @@ -159,7 +164,7 @@ void RenderHeatmapLayer::render(PaintParameters& parameters, RenderSource*) { parameters.state.getZoom() ); const auto allAttributeBindings = programInstance.computeAllAttributeBindings( - parameters.staticData.heatmapTextureVertexBuffer, + *parameters.staticData.heatmapTextureVertexBuffer, paintAttributeData, properties ); @@ -174,7 +179,7 @@ void RenderHeatmapLayer::render(PaintParameters& parameters, RenderSource*) { gfx::StencilMode::disabled(), parameters.colorModeForRenderPass(), gfx::CullFaceMode::disabled(), - parameters.staticData.quadTriangleIndexBuffer, + *parameters.staticData.quadTriangleIndexBuffer, parameters.staticData.heatmapTextureSegments, allUniformValues, allAttributeBindings, diff --git a/src/mbgl/renderer/layers/render_heatmap_layer.hpp b/src/mbgl/renderer/layers/render_heatmap_layer.hpp index 65dad9828b..f4c0299dd9 100644 --- a/src/mbgl/renderer/layers/render_heatmap_layer.hpp +++ b/src/mbgl/renderer/layers/render_heatmap_layer.hpp @@ -19,6 +19,7 @@ private: void evaluate(const PropertyEvaluationParameters&) override; bool hasTransition() const override; bool hasCrossfade() const override; + void upload(gfx::UploadPass&, UploadParameters&) override; void render(PaintParameters&, RenderSource*) override; bool queryIntersectsFeature( diff --git a/src/mbgl/renderer/layers/render_hillshade_layer.cpp b/src/mbgl/renderer/layers/render_hillshade_layer.cpp index 19af5b6202..a13de7c4cd 100644 --- a/src/mbgl/renderer/layers/render_hillshade_layer.cpp +++ b/src/mbgl/renderer/layers/render_hillshade_layer.cpp @@ -162,7 +162,7 @@ void RenderHillshadeLayer::render(PaintParameters& parameters, RenderSource* src parameters.state.getZoom() ); const auto allAttributeBindings = programInstance.computeAllAttributeBindings( - parameters.staticData.rasterVertexBuffer, + *parameters.staticData.rasterVertexBuffer, paintAttributeData, properties ); @@ -177,7 +177,7 @@ void RenderHillshadeLayer::render(PaintParameters& parameters, RenderSource* src gfx::StencilMode::disabled(), parameters.colorModeForRenderPass(), gfx::CullFaceMode::disabled(), - parameters.staticData.quadTriangleIndexBuffer, + *parameters.staticData.quadTriangleIndexBuffer, parameters.staticData.rasterSegments, allUniformValues, allAttributeBindings, @@ -204,8 +204,8 @@ void RenderHillshadeLayer::render(PaintParameters& parameters, RenderSource* src } else { // Draw the full tile. draw(parameters.matrixForTile(tile.id, true), - parameters.staticData.rasterVertexBuffer, - parameters.staticData.quadTriangleIndexBuffer, + *parameters.staticData.rasterVertexBuffer, + *parameters.staticData.quadTriangleIndexBuffer, parameters.staticData.rasterSegments, tile.id, HillshadeProgram::TextureBindings{ diff --git a/src/mbgl/renderer/layers/render_line_layer.cpp b/src/mbgl/renderer/layers/render_line_layer.cpp index a34c634f58..bfb6ac619e 100644 --- a/src/mbgl/renderer/layers/render_line_layer.cpp +++ b/src/mbgl/renderer/layers/render_line_layer.cpp @@ -2,6 +2,7 @@ #include #include #include +#include #include #include #include @@ -46,7 +47,7 @@ void RenderLineLayer::evaluate(const PropertyEvaluationParameters& parameters) { passes = (evaluated.get().constantOr(1.0) > 0 && evaluated.get().constantOr(Color::black()).a > 0 && evaluated.get().constantOr(1.0) > 0) - ? RenderPass::Translucent : RenderPass::None; + ? RenderPass::Translucent | RenderPass::Upload : RenderPass::None; evaluatedProperties = std::move(properties); } @@ -58,6 +59,38 @@ bool RenderLineLayer::hasCrossfade() const { return getCrossfade(evaluatedProperties).t != 1; } +void RenderLineLayer::upload(gfx::UploadPass& uploadPass, UploadParameters& uploadParameters) { + for (const RenderTile& tile : renderTiles) { + const LayerRenderData* renderData = tile.tile.getLayerRenderData(*baseImpl); + if (!renderData) { + continue; + } + auto& bucket = static_cast(*renderData->bucket); + const auto& evaluated = getEvaluated(renderData->layerProperties); + + if (!evaluated.get().from.empty()) { + const LinePatternCap cap = bucket.layout.get() == LineCapType::Round + ? LinePatternCap::Round : LinePatternCap::Square; + // Ensures that the dash data gets added and uploaded to the atlas. + uploadParameters.lineAtlas.getDashPosition(evaluated.get().from, cap); + uploadParameters.lineAtlas.getDashPosition(evaluated.get().to, cap); + + } else if (!unevaluated.get().isUndefined()) { + const auto& linePatternValue = evaluated.get().constantOr(Faded>{ "", ""}); + auto& geometryTile = static_cast(tile.tile); + + // Ensures that the pattern gets added and uplodated to the atlas. + geometryTile.getPattern(linePatternValue.from); + geometryTile.getPattern(linePatternValue.to); + + } else if (!unevaluated.get().getValue().isUndefined()) { + if (!colorRampTexture) { + colorRampTexture = uploadPass.createTexture(colorRamp); + } + } + } +} + void RenderLineLayer::render(PaintParameters& parameters, RenderSource*) { if (parameters.pass == RenderPass::Opaque) { return; @@ -133,12 +166,12 @@ void RenderLineLayer::render(PaintParameters& parameters, RenderSource*) { {}, {}, LineSDFProgram::TextureBindings{ - parameters.lineAtlas.textureBinding(parameters.context), + parameters.lineAtlas.textureBinding(), }); } else if (!unevaluated.get().isUndefined()) { const auto& linePatternValue = evaluated.get().constantOr(Faded>{ "", ""}); - auto& geometryTile = static_cast(tile.tile); + auto& geometryTile = static_cast(tile.tile); const Size texsize = geometryTile.iconAtlasTexture->size; optional posA = geometryTile.getPattern(linePatternValue.from); @@ -159,9 +192,7 @@ void RenderLineLayer::render(PaintParameters& parameters, RenderSource*) { textures::image::Value{ geometryTile.iconAtlasTexture->getResource(), gfx::TextureFilterType::Linear }, }); } else if (!unevaluated.get().getValue().isUndefined()) { - if (!colorRampTexture) { - colorRampTexture = parameters.context.createTexture(colorRamp); - } + assert(colorRampTexture); draw(parameters.programs.getLineLayerPrograms().lineGradient, LineGradientProgram::layoutUniformValues( diff --git a/src/mbgl/renderer/layers/render_line_layer.hpp b/src/mbgl/renderer/layers/render_line_layer.hpp index 657f72e5f1..0e1e81e557 100644 --- a/src/mbgl/renderer/layers/render_line_layer.hpp +++ b/src/mbgl/renderer/layers/render_line_layer.hpp @@ -20,6 +20,7 @@ private: void evaluate(const PropertyEvaluationParameters&) override; bool hasTransition() const override; bool hasCrossfade() const override; + void upload(gfx::UploadPass&, UploadParameters&) override; void render(PaintParameters&, RenderSource*) override; bool queryIntersectsFeature( diff --git a/src/mbgl/renderer/layers/render_raster_layer.cpp b/src/mbgl/renderer/layers/render_raster_layer.cpp index 8569303a06..ce4fb05929 100644 --- a/src/mbgl/renderer/layers/render_raster_layer.cpp +++ b/src/mbgl/renderer/layers/render_raster_layer.cpp @@ -175,8 +175,8 @@ void RenderRasterLayer::render(PaintParameters& parameters, RenderSource* source } else { // Draw the full tile. draw(parameters.matrixForTile(tile.id, true), - parameters.staticData.rasterVertexBuffer, - parameters.staticData.quadTriangleIndexBuffer, + *parameters.staticData.rasterVertexBuffer, + *parameters.staticData.quadTriangleIndexBuffer, parameters.staticData.rasterSegments, RasterProgram::TextureBindings{ textures::image0::Value{ bucket.texture->getResource(), filter }, diff --git a/src/mbgl/renderer/layers/render_symbol_layer.cpp b/src/mbgl/renderer/layers/render_symbol_layer.cpp index 9429cff469..576bdd92d8 100644 --- a/src/mbgl/renderer/layers/render_symbol_layer.cpp +++ b/src/mbgl/renderer/layers/render_symbol_layer.cpp @@ -3,6 +3,7 @@ #include #include #include +#include #include #include #include @@ -13,9 +14,11 @@ #include #include #include +#include #include #include #include +#include #include #include @@ -112,6 +115,122 @@ struct RenderableSegment { } }; +void uploadIcon(gfx::UploadPass& uploadPass, + UploadParameters& uploadParameters, + const RenderTile& tile, + const LayerRenderData& renderData) { + assert(tile.tile.kind == Tile::Kind::Geometry); + auto& bucket = static_cast(*renderData.bucket); + const auto& layout = bucket.layout; + + const bool alongLine = layout.get() != SymbolPlacementType::Point && + layout.get() == AlignmentType::Map; + + if (alongLine) { + const auto& evaluated = getEvaluated(renderData.layerProperties); + reprojectLineLabels(bucket.icon.dynamicVertices, bucket.icon.placedSymbols, tile.matrix, + iconPropertyValues(evaluated, layout), tile, *bucket.iconSizeBinder, + uploadParameters.state); + + uploadPass.updateVertexBuffer(*bucket.icon.dynamicVertexBuffer, + std::move(bucket.icon.dynamicVertices)); + } +} + +void uploadText(gfx::UploadPass& uploadPass, + UploadParameters& uploadParameters, + const RenderTile& tile, + const LayerRenderData& renderData, + bool& hasVariablePlacement) { + assert(tile.tile.kind == Tile::Kind::Geometry); + auto& bucket = static_cast(*renderData.bucket); + const auto& layout = bucket.layout; + + const bool alongLine = layout.get() != SymbolPlacementType::Point && + layout.get() == AlignmentType::Map; + + if (alongLine) { + const auto& evaluated = getEvaluated(renderData.layerProperties); + reprojectLineLabels(bucket.text.dynamicVertices, + bucket.text.placedSymbols, + tile.matrix, + textPropertyValues(evaluated, layout), + tile, + *bucket.textSizeBinder, + uploadParameters.state); + + uploadPass.updateVertexBuffer(*bucket.text.dynamicVertexBuffer, std::move(bucket.text.dynamicVertices)); + } else if (!layout.get().empty()) { + bucket.text.dynamicVertices.clear(); + + hasVariablePlacement = false; + + const auto partiallyEvaluatedSize = bucket.textSizeBinder->evaluateForZoom(uploadParameters.state.getZoom()); + const float tileScale = std::pow(2, uploadParameters.state.getZoom() - tile.tile.id.overscaledZ); + const bool rotateWithMap = layout.get() == AlignmentType::Map; + const bool pitchWithMap = layout.get() == AlignmentType::Map; + const float pixelsToTileUnits = tile.id.pixelsToTileUnits(1.0, uploadParameters.state.getZoom()); + const auto labelPlaneMatrix = getLabelPlaneMatrix(tile.matrix, pitchWithMap, rotateWithMap, uploadParameters.state, pixelsToTileUnits); + + for (const PlacedSymbol& symbol : bucket.text.placedSymbols) { + optional variableOffset; + if (!symbol.hidden && symbol.crossTileID != 0u) { + auto it = uploadParameters.variableOffsets.find(symbol.crossTileID); + if (it != uploadParameters.variableOffsets.end()) { + hasVariablePlacement |= true; + variableOffset = it->second; + } + } + + if (!variableOffset) { + // These symbols are from a justification that is not being used, or a label that wasn't placed + // so we don't need to do the extra math to figure out what incremental shift to apply. + hideGlyphs(symbol.glyphOffsets.size(), bucket.text.dynamicVertices); + } else { + const Point tileAnchor = symbol.anchorPoint; + const auto projectedAnchor = project(tileAnchor, pitchWithMap ? tile.matrix : labelPlaneMatrix); + const float perspectiveRatio = 0.5f + 0.5f * (uploadParameters.state.getCameraToCenterDistance() / projectedAnchor.second); + float renderTextSize = evaluateSizeForFeature(partiallyEvaluatedSize, symbol) * perspectiveRatio / util::ONE_EM; + if (pitchWithMap) { + // Go from size in pixels to equivalent size in tile units + renderTextSize *= bucket.tilePixelRatio / tileScale; + } + + auto shift = calculateVariableRenderShift( + (*variableOffset).anchor, + (*variableOffset).width, + (*variableOffset).height, + (*variableOffset).radialOffset, + (*variableOffset).textBoxScale, + renderTextSize); + + // Usual case is that we take the projected anchor and add the pixel-based shift + // calculated above. In the (somewhat weird) case of pitch-aligned text, we add an equivalent + // tile-unit based shift to the anchor before projecting to the label plane. + Point shiftedAnchor; + if (pitchWithMap) { + shiftedAnchor = project(Point(tileAnchor.x + shift.x, tileAnchor.y + shift.y), + labelPlaneMatrix).first; + } else { + if (rotateWithMap) { + auto rotated = util::rotate(shift, -uploadParameters.state.getPitch()); + shiftedAnchor = Point(projectedAnchor.first.x + rotated.x, + projectedAnchor.first.y + rotated.y); + } else { + shiftedAnchor = Point(projectedAnchor.first.x + shift.x, + projectedAnchor.first.y + shift.y); + } + } + + for (std::size_t i = 0; i < symbol.glyphOffsets.size(); i++) { + addDynamicAttributes(shiftedAnchor, 0, bucket.text.dynamicVertices); + } + } + } + uploadPass.updateVertexBuffer(*bucket.text.dynamicVertexBuffer, std::move(bucket.text.dynamicVertices)); + } +} + template void drawIcon(const DrawFn& draw, const RenderTile& tile, @@ -130,18 +249,6 @@ void drawIcon(const DrawFn& draw, const bool alongLine = layout.get() != SymbolPlacementType::Point && layout.get() == AlignmentType::Map; - if (alongLine) { - reprojectLineLabels(bucket.icon.dynamicVertices, - bucket.icon.placedSymbols, - tile.matrix, - values, - tile, - *bucket.iconSizeBinder, - parameters.state); - - parameters.context.updateVertexBuffer(*bucket.icon.dynamicVertexBuffer, std::move(bucket.icon.dynamicVertices)); - } - const bool iconScaled = layout.get().constantOr(1.0) != 1.0 || bucket.iconsNeedLinear; const bool iconTransformed = values.rotationAlignment == AlignmentType::Map || parameters.state.getPitch() != 0; @@ -206,7 +313,8 @@ void drawText(const DrawFn& draw, const LayerRenderData& renderData, SegmentsWrapper textSegments, const SymbolBucket::PaintProperties& bucketPaintProperties, - const PaintParameters& parameters) { + const PaintParameters& parameters, + bool hasVariablePlacement) { assert(tile.tile.kind == Tile::Kind::Geometry); auto& geometryTile = static_cast(tile.tile); auto& bucket = static_cast(*renderData.bucket); @@ -218,94 +326,15 @@ void drawText(const DrawFn& draw, auto values = textPropertyValues(evaluated, layout); const auto& paintPropertyValues = RenderSymbolLayer::textPaintProperties(evaluated); - bool hasVariablePacement = false; const bool alongLine = layout.get() != SymbolPlacementType::Point && layout.get() == AlignmentType::Map; - if (alongLine) { - reprojectLineLabels(bucket.text.dynamicVertices, - bucket.text.placedSymbols, - tile.matrix, - values, - tile, - *bucket.textSizeBinder, - parameters.state); - - parameters.context.updateVertexBuffer(*bucket.text.dynamicVertexBuffer, std::move(bucket.text.dynamicVertices)); - } else if (!layout.get().empty()) { - bucket.text.dynamicVertices.clear(); - - const auto partiallyEvaluatedSize = bucket.textSizeBinder->evaluateForZoom(parameters.state.getZoom()); - const float tileScale = std::pow(2, parameters.state.getZoom() - tile.tile.id.overscaledZ); - const bool rotateWithMap = layout.get() == AlignmentType::Map; - const bool pitchWithMap = layout.get() == AlignmentType::Map; - const float pixelsToTileUnits = tile.id.pixelsToTileUnits(1.0, parameters.state.getZoom()); - const auto labelPlaneMatrix = getLabelPlaneMatrix(tile.matrix, pitchWithMap, rotateWithMap, parameters.state, pixelsToTileUnits); - - for (const PlacedSymbol& symbol : bucket.text.placedSymbols) { - optional variableOffset; - if (!symbol.hidden && symbol.crossTileID != 0u) { - auto it = parameters.variableOffsets.get().find(symbol.crossTileID); - if (it != parameters.variableOffsets.get().end()) { - variableOffset = it->second; - hasVariablePacement |= true; - } - } - - if (!variableOffset) { - // These symbols are from a justification that is not being used, or a label that wasn't placed - // so we don't need to do the extra math to figure out what incremental shift to apply. - hideGlyphs(symbol.glyphOffsets.size(), bucket.text.dynamicVertices); - } else { - const Point tileAnchor = symbol.anchorPoint; - const auto projectedAnchor = project(tileAnchor, pitchWithMap ? tile.matrix : labelPlaneMatrix); - const float perspectiveRatio = 0.5f + 0.5f * (parameters.state.getCameraToCenterDistance() / projectedAnchor.second); - float renderTextSize = evaluateSizeForFeature(partiallyEvaluatedSize, symbol) * perspectiveRatio / util::ONE_EM; - if (pitchWithMap) { - // Go from size in pixels to equivalent size in tile units - renderTextSize *= bucket.tilePixelRatio / tileScale; - } - - auto shift = calculateVariableRenderShift( - (*variableOffset).anchor, - (*variableOffset).width, - (*variableOffset).height, - (*variableOffset).radialOffset, - (*variableOffset).textBoxScale, - renderTextSize); - - // Usual case is that we take the projected anchor and add the pixel-based shift - // calculated above. In the (somewhat weird) case of pitch-aligned text, we add an equivalent - // tile-unit based shift to the anchor before projecting to the label plane. - Point shiftedAnchor; - if (pitchWithMap) { - shiftedAnchor = project(Point(tileAnchor.x + shift.x, tileAnchor.y + shift.y), - labelPlaneMatrix).first; - } else { - if (rotateWithMap) { - auto rotated = util::rotate(shift, -parameters.state.getPitch()); - shiftedAnchor = Point(projectedAnchor.first.x + rotated.x, - projectedAnchor.first.y + rotated.y); - } else { - shiftedAnchor = Point(projectedAnchor.first.x + shift.x, - projectedAnchor.first.y + shift.y); - } - } - - for (std::size_t i = 0; i < symbol.glyphOffsets.size(); i++) { - addDynamicAttributes(shiftedAnchor, 0, bucket.text.dynamicVertices); - } - } - } - parameters.context.updateVertexBuffer(*bucket.text.dynamicVertexBuffer, std::move(bucket.text.dynamicVertices)); - } - const Size texsize = geometryTile.glyphAtlasTexture->size; if (values.hasHalo) { draw(parameters.programs.getSymbolLayerPrograms().symbolGlyph, - SymbolSDFTextProgram::layoutUniformValues(true, hasVariablePacement, values, texsize, parameters.pixelsToGLUnits, parameters.pixelRatio, alongLine, tile, parameters.state, parameters.symbolFadeChange, SymbolSDFPart::Halo), + SymbolSDFTextProgram::layoutUniformValues(true, hasVariablePlacement, values, texsize, parameters.pixelsToGLUnits, parameters.pixelRatio, alongLine, tile, parameters.state, parameters.symbolFadeChange, SymbolSDFPart::Halo), bucket.text, textSegments, bucket.textSizeBinder, @@ -320,7 +349,7 @@ void drawText(const DrawFn& draw, if (values.hasFill) { draw(parameters.programs.getSymbolLayerPrograms().symbolGlyph, - SymbolSDFTextProgram::layoutUniformValues(true, hasVariablePacement, values, texsize, parameters.pixelsToGLUnits, parameters.pixelRatio, alongLine, tile, parameters.state, parameters.symbolFadeChange, SymbolSDFPart::Fill), + SymbolSDFTextProgram::layoutUniformValues(true, hasVariablePlacement, values, texsize, parameters.pixelsToGLUnits, parameters.pixelRatio, alongLine, tile, parameters.state, parameters.symbolFadeChange, SymbolSDFPart::Fill), bucket.text, textSegments, bucket.textSizeBinder, @@ -370,7 +399,8 @@ void RenderSymbolLayer::evaluate(const PropertyEvaluationParameters& parameters) passes = ((evaluated.get().constantOr(1) > 0 && hasIconOpacity && iconSize > 0) || (evaluated.get().constantOr(1) > 0 && hasTextOpacity && textSize > 0)) - ? RenderPass::Translucent : RenderPass::None; + ? RenderPass::Translucent | RenderPass::Upload : RenderPass::None; + evaluatedProperties = std::move(properties); } @@ -398,6 +428,24 @@ SymbolBucket* RenderSymbolLayer::getSymbolBucket(const RenderTile& renderTile) c return renderTile.tile.getBucket(*baseImpl); } +void RenderSymbolLayer::upload(gfx::UploadPass& uploadPass, UploadParameters& uploadParameters) { + for (const RenderTile& tile : renderTiles) { + const LayerRenderData* renderData = tile.tile.getLayerRenderData(*baseImpl); + if (!renderData) { + continue; + } + + auto& bucket = static_cast(*renderData->bucket); + if (bucket.hasIconData()) { + uploadIcon(uploadPass, uploadParameters, tile, *renderData); + } + + if (bucket.hasTextData()) { + uploadText(uploadPass, uploadParameters, tile, *renderData, hasVariablePlacement); + } + } +} + void RenderSymbolLayer::render(PaintParameters& parameters, RenderSource*) { if (parameters.pass == RenderPass::Opaque) { return; @@ -504,7 +552,7 @@ void RenderSymbolLayer::render(PaintParameters& parameters, RenderSource*) { if (sortFeaturesByKey) { addRenderables(bucket.text.segments, true /*isText*/); } else { - drawText(draw, tile, *renderData, std::ref(bucket.text.segments), bucketPaintProperties, parameters); + drawText(draw, tile, *renderData, std::ref(bucket.text.segments), bucketPaintProperties, parameters, hasVariablePlacement); } } @@ -518,7 +566,6 @@ void RenderSymbolLayer::render(PaintParameters& parameters, RenderSource*) { {{ parameters.pixelsToGLUnits[0] / (pixelRatio * scale), parameters.pixelsToGLUnits[1] / (pixelRatio * scale) - }}; parameters.programs.getSymbolLayerPrograms().collisionBox.draw( parameters.context, @@ -555,7 +602,6 @@ void RenderSymbolLayer::render(PaintParameters& parameters, RenderSource*) { {{ parameters.pixelsToGLUnits[0] / (pixelRatio * scale), parameters.pixelsToGLUnits[1] / (pixelRatio * scale) - }}; parameters.programs.getSymbolLayerPrograms().collisionCircle.draw( @@ -588,7 +634,7 @@ void RenderSymbolLayer::render(PaintParameters& parameters, RenderSource*) { if (sortFeaturesByKey) { for (auto& renderable : renderableSegments) { if (renderable.isText) { - drawText(draw, renderable.tile, renderable.renderData, renderable.segment, renderable.bucketPaintProperties, parameters); + drawText(draw, renderable.tile, renderable.renderData, renderable.segment, renderable.bucketPaintProperties, parameters, hasVariablePlacement); } else { drawIcon(draw, renderable.tile, renderable.renderData, renderable.segment, renderable.bucketPaintProperties, parameters); } diff --git a/src/mbgl/renderer/layers/render_symbol_layer.hpp b/src/mbgl/renderer/layers/render_symbol_layer.hpp index ad33a2ab0e..67b8a58314 100644 --- a/src/mbgl/renderer/layers/render_symbol_layer.hpp +++ b/src/mbgl/renderer/layers/render_symbol_layer.hpp @@ -66,6 +66,7 @@ private: void evaluate(const PropertyEvaluationParameters&) override; bool hasTransition() const override; bool hasCrossfade() const override; + void upload(gfx::UploadPass&, UploadParameters&) override; void render(PaintParameters&, RenderSource*) override; void setRenderTiles(RenderTiles, const TransformState&) override; @@ -82,6 +83,7 @@ private: float textSize = 16.0f; bool hasFormatSectionOverrides = false; + bool hasVariablePlacement = false; }; } // namespace mbgl diff --git a/src/mbgl/renderer/paint_parameters.cpp b/src/mbgl/renderer/paint_parameters.cpp index e31392902e..38cdb11f9f 100644 --- a/src/mbgl/renderer/paint_parameters.cpp +++ b/src/mbgl/renderer/paint_parameters.cpp @@ -17,8 +17,7 @@ PaintParameters::PaintParameters(gfx::Context& context_, const EvaluatedLight& evaluatedLight_, RenderStaticData& staticData_, ImageManager& imageManager_, - LineAtlas& lineAtlas_, - Placement::VariableOffsets variableOffsets_) + LineAtlas& lineAtlas_) : context(context_), backend(backend_), encoder(context.createCommandEncoder()), @@ -31,7 +30,6 @@ PaintParameters::PaintParameters(gfx::Context& context_, debugOptions(updateParameters.debugOptions), timePoint(updateParameters.timePoint), pixelRatio(pixelRatio_), - variableOffsets(variableOffsets_), #ifndef NDEBUG programs((debugOptions & MapDebugOptions::Overdraw) ? staticData_.overdrawPrograms : staticData_.programs) #else @@ -135,7 +133,7 @@ void PaintParameters::renderTileClippingMasks(const std::vector #include #include -#include #include #include @@ -41,8 +40,7 @@ public: const EvaluatedLight&, RenderStaticData&, ImageManager&, - LineAtlas&, - Placement::VariableOffsets); + LineAtlas&); ~PaintParameters(); gfx::Context& context; @@ -63,7 +61,6 @@ public: TimePoint timePoint; float pixelRatio; - Placement::VariableOffsets variableOffsets; std::array pixelsToGLUnits; Programs& programs; diff --git a/src/mbgl/renderer/paint_property_binder.hpp b/src/mbgl/renderer/paint_property_binder.hpp index a54cb8fc34..5cd75645f4 100644 --- a/src/mbgl/renderer/paint_property_binder.hpp +++ b/src/mbgl/renderer/paint_property_binder.hpp @@ -3,6 +3,7 @@ #include #include #include +#include #include #include #include @@ -99,7 +100,7 @@ public: std::size_t length, const ImagePositions&, const optional&, const style::expression::Value&) = 0; - virtual void upload(gfx::Context& context) = 0; + virtual void upload(gfx::UploadPass&) = 0; virtual void setPatternParameters(const optional&, const optional&, const CrossfadeParameters&) = 0; virtual std::tuple>...> attributeBinding(const PossiblyEvaluatedType& currentValue) const = 0; virtual std::tuple...> interpolationFactor(float currentZoom) const = 0; @@ -118,7 +119,7 @@ public: } void populateVertexVector(const GeometryTileFeature&, std::size_t, const ImagePositions&, const optional&, const style::expression::Value&) override {} - void upload(gfx::Context&) override {} + void upload(gfx::UploadPass&) override {} void setPatternParameters(const optional&, const optional&, const CrossfadeParameters&) override {}; std::tuple> attributeBinding(const PossiblyEvaluatedPropertyValue&) const override { @@ -145,7 +146,7 @@ public: } void populateVertexVector(const GeometryTileFeature&, std::size_t, const ImagePositions&, const optional&, const style::expression::Value&) override {} - void upload(gfx::Context&) override {} + void upload(gfx::UploadPass&) override {} void setPatternParameters(const optional& posA, const optional& posB, const CrossfadeParameters&) override { if (!posA || !posB) { @@ -196,8 +197,8 @@ public: } } - void upload(gfx::Context& context) override { - vertexBuffer = context.createVertexBuffer(std::move(vertexVector)); + void upload(gfx::UploadPass& uploadPass) override { + vertexBuffer = uploadPass.createVertexBuffer(std::move(vertexVector)); } std::tuple> attributeBinding(const PossiblyEvaluatedPropertyValue& currentValue) const override { @@ -260,8 +261,8 @@ public: } } - void upload(gfx::Context& context) override { - vertexBuffer = context.createVertexBuffer(std::move(vertexVector)); + void upload(gfx::UploadPass& uploadPass) override { + vertexBuffer = uploadPass.createVertexBuffer(std::move(vertexVector)); } std::tuple> attributeBinding(const PossiblyEvaluatedPropertyValue& currentValue) const override { @@ -352,10 +353,10 @@ public: } } - void upload(gfx::Context& context) override { - patternToVertexBuffer = context.createVertexBuffer(std::move(patternToVertexVector)); - zoomInVertexBuffer = context.createVertexBuffer(std::move(zoomInVertexVector)); - zoomOutVertexBuffer = context.createVertexBuffer(std::move(zoomOutVertexVector)); + void upload(gfx::UploadPass& uploadPass) override { + patternToVertexBuffer = uploadPass.createVertexBuffer(std::move(patternToVertexVector)); + zoomInVertexBuffer = uploadPass.createVertexBuffer(std::move(zoomInVertexVector)); + zoomOutVertexBuffer = uploadPass.createVertexBuffer(std::move(zoomOutVertexVector)); } std::tuple, optional> attributeBinding(const PossiblyEvaluatedPropertyValue>& currentValue) const override { @@ -492,9 +493,9 @@ public: }); } - void upload(gfx::Context& context) { + void upload(gfx::UploadPass& uploadPass) { util::ignore({ - (binders.template get()->upload(context), 0)... + (binders.template get()->upload(uploadPass), 0)... }); } diff --git a/src/mbgl/renderer/render_layer.hpp b/src/mbgl/renderer/render_layer.hpp index 2bc2563f52..8b01739c31 100644 --- a/src/mbgl/renderer/render_layer.hpp +++ b/src/mbgl/renderer/render_layer.hpp @@ -13,6 +13,7 @@ namespace mbgl { class Bucket; class TransitionParameters; class PropertyEvaluationParameters; +class UploadParameters; class PaintParameters; class RenderSource; class RenderLayerSymbolInterface; @@ -62,6 +63,7 @@ public: // Checks whether the given zoom is inside this layer zoom range. bool supportsZoom(float zoom) const; + virtual void upload(gfx::UploadPass&, UploadParameters&) {} virtual void render(PaintParameters&, RenderSource*) = 0; // Check wether the given geometry intersects diff --git a/src/mbgl/renderer/render_pass.hpp b/src/mbgl/renderer/render_pass.hpp index 5d18304129..ee0a846d7e 100644 --- a/src/mbgl/renderer/render_pass.hpp +++ b/src/mbgl/renderer/render_pass.hpp @@ -12,6 +12,7 @@ enum class RenderPass : uint8_t { Opaque = 1 << 0, Translucent = 1 << 1, Pass3D = 1 << 2, + Upload = 1 << 3, }; MBGL_CONSTEXPR RenderPass operator|(RenderPass a, RenderPass b) { diff --git a/src/mbgl/renderer/render_source.hpp b/src/mbgl/renderer/render_source.hpp index 89e7f095fa..2e433c01f9 100644 --- a/src/mbgl/renderer/render_source.hpp +++ b/src/mbgl/renderer/render_source.hpp @@ -27,6 +27,10 @@ class RenderSourceObserver; class TileParameters; class CollisionIndex; +namespace gfx { +class UploadPass; +} // namespace gfx + class RenderSource : protected TileObserver { public: static std::unique_ptr create(Immutable); @@ -55,7 +59,8 @@ public: bool needsRelayout, const TileParameters&) = 0; - virtual void startRender(PaintParameters&) = 0; + virtual void upload(gfx::UploadPass&) = 0; + virtual void prepare(PaintParameters&) = 0; virtual void finishRender(PaintParameters&) = 0; // Returns a list of RenderTiles, sorted by tile id. diff --git a/src/mbgl/renderer/render_static_data.cpp b/src/mbgl/renderer/render_static_data.cpp index 0814d6341b..9090ef6579 100644 --- a/src/mbgl/renderer/render_static_data.cpp +++ b/src/mbgl/renderer/render_static_data.cpp @@ -1,5 +1,6 @@ #include #include +#include #include namespace mbgl { @@ -49,12 +50,7 @@ static gfx::VertexVector heatmapTextureVertices() { } RenderStaticData::RenderStaticData(gfx::Context& context, float pixelRatio, const optional& programCacheDir) - : tileVertexBuffer(context.createVertexBuffer(tileVertices())), - rasterVertexBuffer(context.createVertexBuffer(rasterVertices())), - heatmapTextureVertexBuffer(context.createVertexBuffer(heatmapTextureVertices())), - quadTriangleIndexBuffer(context.createIndexBuffer(quadTriangleIndices())), - tileBorderIndexBuffer(context.createIndexBuffer(tileLineStripIndices())), - programs(context, ProgramParameters { pixelRatio, false, programCacheDir }) + : programs(context, ProgramParameters { pixelRatio, false, programCacheDir }) #ifndef NDEBUG , overdrawPrograms(context, ProgramParameters { pixelRatio, true, programCacheDir }) #endif @@ -65,4 +61,15 @@ RenderStaticData::RenderStaticData(gfx::Context& context, float pixelRatio, cons heatmapTextureSegments.emplace_back(0, 0, 4, 6); } +void RenderStaticData::upload(gfx::UploadPass& uploadPass) { + if (!uploaded) { + tileVertexBuffer = uploadPass.createVertexBuffer(tileVertices()); + rasterVertexBuffer = uploadPass.createVertexBuffer(rasterVertices()); + heatmapTextureVertexBuffer = uploadPass.createVertexBuffer(heatmapTextureVertices()); + quadTriangleIndexBuffer = uploadPass.createIndexBuffer(quadTriangleIndices()); + tileBorderIndexBuffer = uploadPass.createIndexBuffer(tileLineStripIndices()); + uploaded = true; + } +} + } // namespace mbgl diff --git a/src/mbgl/renderer/render_static_data.hpp b/src/mbgl/renderer/render_static_data.hpp index ddf52f83f6..5b409933af 100644 --- a/src/mbgl/renderer/render_static_data.hpp +++ b/src/mbgl/renderer/render_static_data.hpp @@ -14,18 +14,21 @@ namespace mbgl { namespace gfx { class Context; +class UploadPass; } // namespace gfx class RenderStaticData { public: RenderStaticData(gfx::Context&, float pixelRatio, const optional& programCacheDir); - gfx::VertexBuffer> tileVertexBuffer; - gfx::VertexBuffer rasterVertexBuffer; - gfx::VertexBuffer heatmapTextureVertexBuffer; + void upload(gfx::UploadPass&); - gfx::IndexBuffer quadTriangleIndexBuffer; - gfx::IndexBuffer tileBorderIndexBuffer; + optional>> tileVertexBuffer; + optional> rasterVertexBuffer; + optional> heatmapTextureVertexBuffer; + + optional quadTriangleIndexBuffer; + optional tileBorderIndexBuffer; SegmentVector tileTriangleSegments; SegmentVector tileBorderSegments; @@ -34,6 +37,7 @@ public: optional> depthRenderbuffer; bool has3D = false; + bool uploaded = false; Size backendSize; Programs programs; diff --git a/src/mbgl/renderer/render_tile.cpp b/src/mbgl/renderer/render_tile.cpp index 2c2a82a8a8..828163bd6e 100644 --- a/src/mbgl/renderer/render_tile.cpp +++ b/src/mbgl/renderer/render_tile.cpp @@ -12,6 +12,11 @@ namespace mbgl { using namespace style; +RenderTile::RenderTile(UnwrappedTileID id_, Tile& tile_) : id(std::move(id_)), tile(tile_) { +} + +RenderTile::~RenderTile() = default; + mat4 RenderTile::translateVtxMatrix(const mat4& tileMatrix, const std::array& translation, TranslateAnchorType anchor, @@ -57,8 +62,27 @@ void RenderTile::setMask(TileMask&& mask) { tile.setMask(std::move(mask)); } -void RenderTile::startRender(PaintParameters& parameters) { - tile.upload(parameters.context); +void RenderTile::upload(gfx::UploadPass& uploadPass) { + tile.upload(uploadPass); + + if (debugBucket) { + debugBucket->upload(uploadPass); + } +} + +void RenderTile::prepare(PaintParameters& parameters) { + if (parameters.debugOptions != MapDebugOptions::NoDebug && + (!debugBucket || debugBucket->renderable != tile.isRenderable() || + debugBucket->complete != tile.isComplete() || + !(debugBucket->modified == tile.modified) || + !(debugBucket->expires == tile.expires) || + debugBucket->debugMode != parameters.debugOptions)) { + debugBucket = std::make_unique( + tile.id, tile.isRenderable(), tile.isComplete(), tile.modified, tile.expires, + parameters.debugOptions); + } else if (parameters.debugOptions == MapDebugOptions::NoDebug) { + debugBucket.reset(); + } // Calculate two matrices for this tile: matrix is the standard tile matrix; nearClippedMatrix // clips the near plane to 100 to save depth buffer precision @@ -77,21 +101,10 @@ void RenderTile::finishRender(PaintParameters& parameters) { auto& program = parameters.programs.debug; - if (parameters.debugOptions != MapDebugOptions::NoDebug && - (!tile.debugBucket || tile.debugBucket->renderable != tile.isRenderable() || - tile.debugBucket->complete != tile.isComplete() || - !(tile.debugBucket->modified == tile.modified) || - !(tile.debugBucket->expires == tile.expires) || - tile.debugBucket->debugMode != parameters.debugOptions)) { - tile.debugBucket = std::make_unique( - tile.id, tile.isRenderable(), tile.isComplete(), tile.modified, tile.expires, - parameters.debugOptions, parameters.context); - } - if (parameters.debugOptions & (MapDebugOptions::Timestamps | MapDebugOptions::ParseStatus)) { - assert(tile.debugBucket); + assert(debugBucket); const auto allAttributeBindings = program.computeAllAttributeBindings( - *tile.debugBucket->vertexBuffer, + *debugBucket->vertexBuffer, paintAttributeData, properties ); @@ -104,8 +117,8 @@ void RenderTile::finishRender(PaintParameters& parameters) { gfx::StencilMode::disabled(), gfx::ColorMode::unblended(), gfx::CullFaceMode::disabled(), - *tile.debugBucket->indexBuffer, - tile.debugBucket->segments, + *debugBucket->indexBuffer, + debugBucket->segments, program.computeAllUniformValues( DebugProgram::LayoutUniformValues { uniforms::matrix::Value( matrix ), @@ -117,7 +130,7 @@ void RenderTile::finishRender(PaintParameters& parameters) { ), allAttributeBindings, DebugProgram::TextureBindings{}, - "__debug/" + tile.debugBucket->drawScopeID + "/text-outline" + "__debug/" + debugBucket->drawScopeID + "/text-outline" ); program.draw( @@ -128,8 +141,8 @@ void RenderTile::finishRender(PaintParameters& parameters) { gfx::StencilMode::disabled(), gfx::ColorMode::unblended(), gfx::CullFaceMode::disabled(), - *tile.debugBucket->indexBuffer, - tile.debugBucket->segments, + *debugBucket->indexBuffer, + debugBucket->segments, program.computeAllUniformValues( DebugProgram::LayoutUniformValues { uniforms::matrix::Value( matrix ), @@ -141,12 +154,12 @@ void RenderTile::finishRender(PaintParameters& parameters) { ), allAttributeBindings, DebugProgram::TextureBindings{}, - "__debug/" + tile.debugBucket->drawScopeID + "/text" + "__debug/" + debugBucket->drawScopeID + "/text" ); } if (parameters.debugOptions & MapDebugOptions::TileBorders) { - assert(tile.debugBucket); + assert(debugBucket); parameters.programs.debug.draw( parameters.context, *parameters.renderPass, @@ -155,7 +168,7 @@ void RenderTile::finishRender(PaintParameters& parameters) { gfx::StencilMode::disabled(), gfx::ColorMode::unblended(), gfx::CullFaceMode::disabled(), - parameters.staticData.tileBorderIndexBuffer, + *parameters.staticData.tileBorderIndexBuffer, parameters.staticData.tileBorderSegments, program.computeAllUniformValues( DebugProgram::LayoutUniformValues { @@ -167,12 +180,12 @@ void RenderTile::finishRender(PaintParameters& parameters) { parameters.state.getZoom() ), program.computeAllAttributeBindings( - parameters.staticData.tileVertexBuffer, + *parameters.staticData.tileVertexBuffer, paintAttributeData, properties ), DebugProgram::TextureBindings{}, - "__debug/" + tile.debugBucket->drawScopeID + "__debug/" + debugBucket->drawScopeID ); } } diff --git a/src/mbgl/renderer/render_tile.hpp b/src/mbgl/renderer/render_tile.hpp index dbdae097ee..559f37a090 100644 --- a/src/mbgl/renderer/render_tile.hpp +++ b/src/mbgl/renderer/render_tile.hpp @@ -6,16 +6,23 @@ #include #include +#include namespace mbgl { +namespace gfx { +class UploadPass; +} // namespace gfx + class Tile; class TransformState; class PaintParameters; +class DebugBucket; class RenderTile final { public: - RenderTile(UnwrappedTileID id_, Tile& tile_) : id(std::move(id_)), tile(tile_) {} + RenderTile(UnwrappedTileID, Tile&); + ~RenderTile(); RenderTile(const RenderTile&) = delete; RenderTile(RenderTile&&) = default; RenderTile& operator=(const RenderTile&) = delete; @@ -26,6 +33,8 @@ public: mat4 matrix; mat4 nearClippedMatrix; bool used = false; + // Contains the tile ID string for painting debug information. + std::unique_ptr debugBucket; mat4 translatedMatrix(const std::array& translate, style::TranslateAnchorType anchor, @@ -36,7 +45,8 @@ public: const TransformState&) const; void setMask(TileMask&&); - void startRender(PaintParameters&); + void upload(gfx::UploadPass&); + void prepare(PaintParameters&); void finishRender(PaintParameters&); mat4 translateVtxMatrix(const mat4& tileMatrix, diff --git a/src/mbgl/renderer/renderer_impl.cpp b/src/mbgl/renderer/renderer_impl.cpp index 52a2342454..3f9b59a14a 100644 --- a/src/mbgl/renderer/renderer_impl.cpp +++ b/src/mbgl/renderer/renderer_impl.cpp @@ -6,6 +6,7 @@ #include #include #include +#include #include #include #include @@ -16,6 +17,7 @@ #include #include #include +#include #include #include #include @@ -347,8 +349,13 @@ void Renderer::Impl::render(const UpdateParameters& updateParameters) { } } + auto& context = backend.getContext(); + + // Blocks execution until the renderable is available. + backend.getDefaultRenderable().wait(); + PaintParameters parameters { - backend.getContext(), + context, pixelRatio, backend, updateParameters, @@ -356,25 +363,51 @@ void Renderer::Impl::render(const UpdateParameters& updateParameters) { *staticData, *imageManager, *lineAtlas, - placement->getVariableOffsets() }; parameters.symbolFadeChange = placement->symbolFadeChange(updateParameters.timePoint); + // TODO: move this pass to before the PaintParameters initialization + // - PREPARE PASS ------------------------------------------------------------------------------- + // Runs an initialization pass for all sources. + { + // Update all matrices and generate data that we should upload to the GPU. + for (const auto& entry : renderSources) { + if (entry.second->isEnabled()) { + entry.second->prepare(parameters); + } + } + } + // - UPLOAD PASS ------------------------------------------------------------------------------- // Uploads all required buffers and images before we do any actual rendering. { - const auto debugGroup(parameters.encoder->createDebugGroup("upload")); + const auto uploadPass = parameters.encoder->createUploadPass("upload"); - parameters.imageManager.upload(parameters.context); - parameters.lineAtlas.upload(parameters.context); - // Update all clipping IDs + upload buckets. for (const auto& entry : renderSources) { if (entry.second->isEnabled()) { - entry.second->startRender(parameters); + entry.second->upload(*uploadPass); } } + + UploadParameters uploadParameters{ + updateParameters.transformState, + placement->getVariableOffsets(), + *imageManager, + *lineAtlas, + }; + + for (auto& renderItem : renderItems) { + RenderLayer& renderLayer = renderItem.layer; + if (renderLayer.hasRenderPass(RenderPass::Upload)) { + renderLayer.upload(*uploadPass, uploadParameters); + } + } + + staticData->upload(*uploadPass); + imageManager->upload(*uploadPass); + lineAtlas->upload(*uploadPass); } // - 3D PASS ------------------------------------------------------------------------------------- diff --git a/src/mbgl/renderer/sources/render_custom_geometry_source.cpp b/src/mbgl/renderer/sources/render_custom_geometry_source.cpp index 8de79d8016..45d49ffa5b 100644 --- a/src/mbgl/renderer/sources/render_custom_geometry_source.cpp +++ b/src/mbgl/renderer/sources/render_custom_geometry_source.cpp @@ -47,8 +47,12 @@ void RenderCustomGeometrySource::update(Immutable baseImpl_ }); } -void RenderCustomGeometrySource::startRender(PaintParameters& parameters) { - tilePyramid.startRender(parameters); +void RenderCustomGeometrySource::upload(gfx::UploadPass& uploadPass) { + tilePyramid.upload(uploadPass); +} + +void RenderCustomGeometrySource::prepare(PaintParameters& parameters) { + tilePyramid.prepare(parameters); } void RenderCustomGeometrySource::finishRender(PaintParameters& parameters) { diff --git a/src/mbgl/renderer/sources/render_custom_geometry_source.hpp b/src/mbgl/renderer/sources/render_custom_geometry_source.hpp index be9e022eb9..485979bee9 100644 --- a/src/mbgl/renderer/sources/render_custom_geometry_source.hpp +++ b/src/mbgl/renderer/sources/render_custom_geometry_source.hpp @@ -18,7 +18,8 @@ public: bool needsRelayout, const TileParameters&) final; - void startRender(PaintParameters&) final; + void upload(gfx::UploadPass&) final; + void prepare(PaintParameters&) final; void finishRender(PaintParameters&) final; std::vector> getRenderTiles() final; diff --git a/src/mbgl/renderer/sources/render_geojson_source.cpp b/src/mbgl/renderer/sources/render_geojson_source.cpp index 0234b97eca..7ff371620a 100644 --- a/src/mbgl/renderer/sources/render_geojson_source.cpp +++ b/src/mbgl/renderer/sources/render_geojson_source.cpp @@ -123,8 +123,12 @@ void RenderGeoJSONSource::update(Immutable baseImpl_, }); } -void RenderGeoJSONSource::startRender(PaintParameters& parameters) { - tilePyramid.startRender(parameters); +void RenderGeoJSONSource::upload(gfx::UploadPass& parameters) { + tilePyramid.upload(parameters); +} + +void RenderGeoJSONSource::prepare(PaintParameters& parameters) { + tilePyramid.prepare(parameters); } void RenderGeoJSONSource::finishRender(PaintParameters& parameters) { diff --git a/src/mbgl/renderer/sources/render_geojson_source.hpp b/src/mbgl/renderer/sources/render_geojson_source.hpp index c8e98f96ee..1a2ff55427 100644 --- a/src/mbgl/renderer/sources/render_geojson_source.hpp +++ b/src/mbgl/renderer/sources/render_geojson_source.hpp @@ -23,7 +23,8 @@ public: bool needsRelayout, const TileParameters&) final; - void startRender(PaintParameters&) final; + void upload(gfx::UploadPass&) final; + void prepare(PaintParameters&) final; void finishRender(PaintParameters&) final; std::vector> getRenderTiles() final; diff --git a/src/mbgl/renderer/sources/render_image_source.cpp b/src/mbgl/renderer/sources/render_image_source.cpp index b6a75acacc..e63c9ad15c 100644 --- a/src/mbgl/renderer/sources/render_image_source.cpp +++ b/src/mbgl/renderer/sources/render_image_source.cpp @@ -31,7 +31,13 @@ bool RenderImageSource::isLoaded() const { return !!bucket; } -void RenderImageSource::startRender(PaintParameters& parameters) { +void RenderImageSource::upload(gfx::UploadPass& uploadPass) { + if (bucket->needsUpload()) { + bucket->upload(uploadPass); + } +} + +void RenderImageSource::prepare(PaintParameters& parameters) { if (!isLoaded()) { return; } @@ -45,10 +51,6 @@ void RenderImageSource::startRender(PaintParameters& parameters) { matrix::multiply(matrix, parameters.alignedProjMatrix, matrix); matrices.push_back(matrix); } - - if (bucket->needsUpload()) { - bucket->upload(parameters.context); - } } void RenderImageSource::finishRender(PaintParameters& parameters) { @@ -70,7 +72,7 @@ void RenderImageSource::finishRender(PaintParameters& parameters) { gfx::StencilMode::disabled(), gfx::ColorMode::unblended(), gfx::CullFaceMode::disabled(), - parameters.staticData.tileBorderIndexBuffer, + *parameters.staticData.tileBorderIndexBuffer, parameters.staticData.tileBorderSegments, programInstance.computeAllUniformValues( DebugProgram::LayoutUniformValues { @@ -82,7 +84,7 @@ void RenderImageSource::finishRender(PaintParameters& parameters) { parameters.state.getZoom() ), programInstance.computeAllAttributeBindings( - parameters.staticData.tileVertexBuffer, + *parameters.staticData.tileVertexBuffer, paintAttributeData, properties ), diff --git a/src/mbgl/renderer/sources/render_image_source.hpp b/src/mbgl/renderer/sources/render_image_source.hpp index e5cdcd4d81..c07fd467cb 100644 --- a/src/mbgl/renderer/sources/render_image_source.hpp +++ b/src/mbgl/renderer/sources/render_image_source.hpp @@ -15,7 +15,8 @@ public: bool isLoaded() const final; - void startRender(PaintParameters&) final; + void upload(gfx::UploadPass&) final; + void prepare(PaintParameters&) final; void finishRender(PaintParameters&) final; void update(Immutable, diff --git a/src/mbgl/renderer/sources/render_raster_dem_source.cpp b/src/mbgl/renderer/sources/render_raster_dem_source.cpp index c942432e64..c9f17f38c4 100644 --- a/src/mbgl/renderer/sources/render_raster_dem_source.cpp +++ b/src/mbgl/renderer/sources/render_raster_dem_source.cpp @@ -126,9 +126,13 @@ void RenderRasterDEMSource::onTileChanged(Tile& tile){ RenderSource::onTileChanged(tile); } -void RenderRasterDEMSource::startRender(PaintParameters& parameters) { +void RenderRasterDEMSource::upload(gfx::UploadPass& parameters) { + tilePyramid.upload(parameters); +} + +void RenderRasterDEMSource::prepare(PaintParameters& parameters) { algorithm::updateTileMasks(tilePyramid.getRenderTiles()); - tilePyramid.startRender(parameters); + tilePyramid.prepare(parameters); } void RenderRasterDEMSource::finishRender(PaintParameters& parameters) { diff --git a/src/mbgl/renderer/sources/render_raster_dem_source.hpp b/src/mbgl/renderer/sources/render_raster_dem_source.hpp index af76e22da7..57180bb4e2 100644 --- a/src/mbgl/renderer/sources/render_raster_dem_source.hpp +++ b/src/mbgl/renderer/sources/render_raster_dem_source.hpp @@ -18,7 +18,8 @@ public: bool needsRelayout, const TileParameters&) final; - void startRender(PaintParameters&) final; + void upload(gfx::UploadPass&) final; + void prepare(PaintParameters&) final; void finishRender(PaintParameters&) final; std::vector> getRenderTiles() final; diff --git a/src/mbgl/renderer/sources/render_raster_source.cpp b/src/mbgl/renderer/sources/render_raster_source.cpp index 96e793f9b2..39cccd47e6 100644 --- a/src/mbgl/renderer/sources/render_raster_source.cpp +++ b/src/mbgl/renderer/sources/render_raster_source.cpp @@ -57,9 +57,13 @@ void RenderRasterSource::update(Immutable baseImpl_, }); } -void RenderRasterSource::startRender(PaintParameters& parameters) { +void RenderRasterSource::upload(gfx::UploadPass& parameters) { + tilePyramid.upload(parameters); +} + +void RenderRasterSource::prepare(PaintParameters& parameters) { algorithm::updateTileMasks(tilePyramid.getRenderTiles()); - tilePyramid.startRender(parameters); + tilePyramid.prepare(parameters); } void RenderRasterSource::finishRender(PaintParameters& parameters) { diff --git a/src/mbgl/renderer/sources/render_raster_source.hpp b/src/mbgl/renderer/sources/render_raster_source.hpp index 24242949bb..e399893cb9 100644 --- a/src/mbgl/renderer/sources/render_raster_source.hpp +++ b/src/mbgl/renderer/sources/render_raster_source.hpp @@ -18,7 +18,8 @@ public: bool needsRelayout, const TileParameters&) final; - void startRender(PaintParameters&) final; + void upload(gfx::UploadPass&) final; + void prepare(PaintParameters&) final; void finishRender(PaintParameters&) final; std::vector> getRenderTiles() final; diff --git a/src/mbgl/renderer/sources/render_vector_source.cpp b/src/mbgl/renderer/sources/render_vector_source.cpp index 518692fc77..21b728e266 100644 --- a/src/mbgl/renderer/sources/render_vector_source.cpp +++ b/src/mbgl/renderer/sources/render_vector_source.cpp @@ -57,8 +57,12 @@ void RenderVectorSource::update(Immutable baseImpl_, }); } -void RenderVectorSource::startRender(PaintParameters& parameters) { - tilePyramid.startRender(parameters); +void RenderVectorSource::upload(gfx::UploadPass& parameters) { + tilePyramid.upload(parameters); +} + +void RenderVectorSource::prepare(PaintParameters& parameters) { + tilePyramid.prepare(parameters); } void RenderVectorSource::finishRender(PaintParameters& parameters) { diff --git a/src/mbgl/renderer/sources/render_vector_source.hpp b/src/mbgl/renderer/sources/render_vector_source.hpp index fe7147fc25..bea9bad20e 100644 --- a/src/mbgl/renderer/sources/render_vector_source.hpp +++ b/src/mbgl/renderer/sources/render_vector_source.hpp @@ -18,7 +18,8 @@ public: bool needsRelayout, const TileParameters&) final; - void startRender(PaintParameters&) final; + void upload(gfx::UploadPass&) final; + void prepare(PaintParameters&) final; void finishRender(PaintParameters&) final; std::vector> getRenderTiles() final; diff --git a/src/mbgl/renderer/tile_pyramid.cpp b/src/mbgl/renderer/tile_pyramid.cpp index 32b3ef0dba..36ac0162e6 100644 --- a/src/mbgl/renderer/tile_pyramid.cpp +++ b/src/mbgl/renderer/tile_pyramid.cpp @@ -40,9 +40,15 @@ bool TilePyramid::isLoaded() const { return true; } -void TilePyramid::startRender(PaintParameters& parameters) { +void TilePyramid::upload(gfx::UploadPass& parameters) { for (auto& tile : renderTiles) { - tile.startRender(parameters); + tile.upload(parameters); + } +} + +void TilePyramid::prepare(PaintParameters& parameters) { + for (auto& tile : renderTiles) { + tile.prepare(parameters); } } diff --git a/src/mbgl/renderer/tile_pyramid.hpp b/src/mbgl/renderer/tile_pyramid.hpp index 98eafc39e6..c912a669ff 100644 --- a/src/mbgl/renderer/tile_pyramid.hpp +++ b/src/mbgl/renderer/tile_pyramid.hpp @@ -43,7 +43,8 @@ public: optional bounds, std::function (const OverscaledTileID&)> createTile); - void startRender(PaintParameters&); + void upload(gfx::UploadPass&); + void prepare(PaintParameters&); void finishRender(PaintParameters&); std::vector> getRenderTiles(); diff --git a/src/mbgl/renderer/upload_parameters.hpp b/src/mbgl/renderer/upload_parameters.hpp new file mode 100644 index 0000000000..0328309927 --- /dev/null +++ b/src/mbgl/renderer/upload_parameters.hpp @@ -0,0 +1,31 @@ +#pragma once + +#include +#include + +namespace mbgl { + +class TransformState; +class LineAtlas; +class VariableOffset; +using VariableOffsets = std::unordered_map; + +class UploadParameters { +public: + UploadParameters(const TransformState& state_, + const VariableOffsets& variableOffsets_, + ImageManager& imageManager_, + LineAtlas& lineAtlas_) + : state(state_), + variableOffsets(variableOffsets_), + imageManager(imageManager_), + lineAtlas(lineAtlas_) { + } + + const TransformState& state; + const VariableOffsets& variableOffsets; + ImageManager& imageManager; + LineAtlas& lineAtlas; +}; + +} // namespace mbgl diff --git a/src/mbgl/text/placement.hpp b/src/mbgl/text/placement.hpp index 3f2a7b8a03..10ed642c4e 100644 --- a/src/mbgl/text/placement.hpp +++ b/src/mbgl/text/placement.hpp @@ -105,8 +105,8 @@ public: void setStale(); const RetainedQueryData& getQueryData(uint32_t bucketInstanceId) const; - using VariableOffsets = std::reference_wrapper>; - VariableOffsets getVariableOffsets() const { return std::cref(variableOffsets); } + using VariableOffsets = std::unordered_map; + const VariableOffsets& getVariableOffsets() const { return variableOffsets; } private: void placeLayerBucket( diff --git a/src/mbgl/tile/geometry_tile.cpp b/src/mbgl/tile/geometry_tile.cpp index 5469fa0e6f..46ab9e713b 100644 --- a/src/mbgl/tile/geometry_tile.cpp +++ b/src/mbgl/tile/geometry_tile.cpp @@ -176,10 +176,10 @@ const optional GeometryTile::getPattern(const std::string& patter return {}; } -void GeometryTile::upload(gfx::Context& context) { +void GeometryTile::upload(gfx::UploadPass& uploadPass) { auto uploadFn = [&] (Bucket& bucket) { if (bucket.needsUpload()) { - bucket.upload(context); + bucket.upload(uploadPass); } }; @@ -188,17 +188,17 @@ void GeometryTile::upload(gfx::Context& context) { } if (glyphAtlasImage) { - glyphAtlasTexture = context.createTexture(*glyphAtlasImage); + glyphAtlasTexture = uploadPass.createTexture(*glyphAtlasImage); glyphAtlasImage = {}; } if (iconAtlas.image.valid()) { - iconAtlasTexture = context.createTexture(iconAtlas.image); + iconAtlasTexture = uploadPass.createTexture(iconAtlas.image); iconAtlas.image = {}; } if (iconAtlasTexture) { - iconAtlas.patchUpdatedImages(context, *iconAtlasTexture, imageManager); + iconAtlas.patchUpdatedImages(uploadPass, *iconAtlasTexture, imageManager); } } diff --git a/src/mbgl/tile/geometry_tile.hpp b/src/mbgl/tile/geometry_tile.hpp index 5c2e8245ee..c7a0d76363 100644 --- a/src/mbgl/tile/geometry_tile.hpp +++ b/src/mbgl/tile/geometry_tile.hpp @@ -42,7 +42,7 @@ public: void getGlyphs(GlyphDependencies); void getImages(ImageRequestPair); - void upload(gfx::Context&) override; + void upload(gfx::UploadPass&) override; Bucket* getBucket(const style::Layer::Impl&) const override; const LayerRenderData* getLayerRenderData(const style::Layer::Impl&) const override; bool updateLayerProperties(const Immutable&) override; diff --git a/src/mbgl/tile/raster_dem_tile.cpp b/src/mbgl/tile/raster_dem_tile.cpp index 8b4e0113c7..cf70687ffe 100644 --- a/src/mbgl/tile/raster_dem_tile.cpp +++ b/src/mbgl/tile/raster_dem_tile.cpp @@ -69,9 +69,9 @@ void RasterDEMTile::onError(std::exception_ptr err, const uint64_t resultCorrela observer->onTileError(*this, err); } -void RasterDEMTile::upload(gfx::Context& context) { +void RasterDEMTile::upload(gfx::UploadPass& uploadPass) { if (bucket) { - bucket->upload(context); + bucket->upload(uploadPass); } } diff --git a/src/mbgl/tile/raster_dem_tile.hpp b/src/mbgl/tile/raster_dem_tile.hpp index ed25218e10..165a5b9d2b 100644 --- a/src/mbgl/tile/raster_dem_tile.hpp +++ b/src/mbgl/tile/raster_dem_tile.hpp @@ -72,7 +72,7 @@ public: void setMetadata(optional modified, optional expires); void setData(std::shared_ptr data); - void upload(gfx::Context&) override; + void upload(gfx::UploadPass&) override; Bucket* getBucket(const style::Layer::Impl&) const override; HillshadeBucket* getBucket() const; diff --git a/src/mbgl/tile/raster_tile.cpp b/src/mbgl/tile/raster_tile.cpp index 9da11b3595..1d8e7f3b3c 100644 --- a/src/mbgl/tile/raster_tile.cpp +++ b/src/mbgl/tile/raster_tile.cpp @@ -58,9 +58,9 @@ void RasterTile::onError(std::exception_ptr err, const uint64_t resultCorrelatio observer->onTileError(*this, err); } -void RasterTile::upload(gfx::Context& context) { +void RasterTile::upload(gfx::UploadPass& uploadPass) { if (bucket) { - bucket->upload(context); + bucket->upload(uploadPass); } } diff --git a/src/mbgl/tile/raster_tile.hpp b/src/mbgl/tile/raster_tile.hpp index 40f1e66bbc..f62ddebf57 100644 --- a/src/mbgl/tile/raster_tile.hpp +++ b/src/mbgl/tile/raster_tile.hpp @@ -28,7 +28,7 @@ public: void setMetadata(optional modified, optional expires); void setData(std::shared_ptr data); - void upload(gfx::Context&) override; + void upload(gfx::UploadPass&) override; Bucket* getBucket(const style::Layer::Impl&) const override; void setMask(TileMask&&) override; diff --git a/src/mbgl/tile/tile.cpp b/src/mbgl/tile/tile.cpp index 5a69df5b43..5e31898caf 100644 --- a/src/mbgl/tile/tile.cpp +++ b/src/mbgl/tile/tile.cpp @@ -1,6 +1,5 @@ #include #include -#include #include #include #include diff --git a/src/mbgl/tile/tile.hpp b/src/mbgl/tile/tile.hpp index c9b1af6beb..e98d192efd 100644 --- a/src/mbgl/tile/tile.hpp +++ b/src/mbgl/tile/tile.hpp @@ -20,20 +20,17 @@ namespace mbgl { -class DebugBucket; class LayerRenderData; class TransformState; class TileObserver; class RenderLayer; class RenderedQueryOptions; class SourceQueryOptions; - class CollisionIndex; -namespace gl { -class Context; -} // namespace gl - +namespace gfx { +class UploadPass; +} // namespace gfx class Tile { public: @@ -55,7 +52,7 @@ public: // Mark this tile as no longer needed and cancel any pending work. virtual void cancel(); - virtual void upload(gfx::Context&) = 0; + virtual void upload(gfx::UploadPass&) = 0; virtual Bucket* getBucket(const style::Layer::Impl&) const = 0; virtual const LayerRenderData* getLayerRenderData(const style::Layer::Impl&) const { assert(false); @@ -141,9 +138,6 @@ public: optional modified; optional expires; - // Contains the tile ID string for painting debug information. - std::unique_ptr debugBucket; - protected: bool triedOptional = false; bool renderable = false; diff --git a/test/gl/bucket.test.cpp b/test/gl/bucket.test.cpp index 277d988f9e..ff01b590fc 100644 --- a/test/gl/bucket.test.cpp +++ b/test/gl/bucket.test.cpp @@ -56,7 +56,9 @@ TEST(Buckets, CircleBucket) { ASSERT_TRUE(bucket.hasData()); ASSERT_TRUE(bucket.needsUpload()); - bucket.upload(context); + auto commandEncoder = context.createCommandEncoder(); + auto uploadPass = commandEncoder->createUploadPass("upload"); + bucket.upload(*uploadPass); ASSERT_TRUE(bucket.hasData()); ASSERT_FALSE(bucket.needsUpload()); } @@ -76,7 +78,9 @@ TEST(Buckets, FillBucket) { ASSERT_TRUE(bucket.hasData()); ASSERT_TRUE(bucket.needsUpload()); - bucket.upload(context); + auto commandEncoder = context.createCommandEncoder(); + auto uploadPass = commandEncoder->createUploadPass("upload"); + bucket.upload(*uploadPass); ASSERT_FALSE(bucket.needsUpload()); } @@ -100,7 +104,9 @@ TEST(Buckets, LineBucket) { ASSERT_TRUE(bucket.hasData()); ASSERT_TRUE(bucket.needsUpload()); - bucket.upload(context); + auto commandEncoder = context.createCommandEncoder(); + auto uploadPass = commandEncoder->createUploadPass("upload"); + bucket.upload(*uploadPass); ASSERT_FALSE(bucket.needsUpload()); } @@ -134,7 +140,9 @@ TEST(Buckets, SymbolBucket) { ASSERT_TRUE(bucket.hasData()); ASSERT_TRUE(bucket.needsUpload()); - bucket.upload(context); + auto commandEncoder = context.createCommandEncoder(); + auto uploadPass = commandEncoder->createUploadPass("upload"); + bucket.upload(*uploadPass); ASSERT_FALSE(bucket.needsUpload()); } @@ -150,7 +158,9 @@ TEST(Buckets, RasterBucket) { ASSERT_TRUE(bucket.hasData()); ASSERT_TRUE(bucket.needsUpload()); - bucket.upload(context); + auto commandEncoder = context.createCommandEncoder(); + auto uploadPass = commandEncoder->createUploadPass("upload"); + bucket.upload(*uploadPass); ASSERT_FALSE(bucket.needsUpload()); bucket.clear(); diff --git a/test/util/string.test.cpp b/test/util/string.test.cpp index 91e1b93685..f694702e69 100644 --- a/test/util/string.test.cpp +++ b/test/util/string.test.cpp @@ -21,9 +21,9 @@ TEST(ToString, FloatingPoint) { TEST(ToHex, SIZE_T) { #if INTPTR_MAX == INT32_MAX - EXPECT_EQ("a715b247", util::toHex((size_t)0xa715b247)); + EXPECT_EQ("a715b247", util::toHex((uint32_t)0xa715b247)); #elif INTPTR_MAX == INT64_MAX - EXPECT_EQ("a715b247df38cc29", util::toHex((size_t)0xa715b247df38cc29)); + EXPECT_EQ("a715b247df38cc29", util::toHex((uint64_t)0xa715b247df38cc29)); #endif } -- cgit v1.2.1