[core] add gfx::UploadPass, split startRender into prepare and upload
This commit is contained in:
@@ -23,6 +23,7 @@ protected:
|
||||
Renderable(const Size size_, std::unique_ptr<RenderableResource> resource_)
|
||||
: size(size_), resource(std::move(resource_)) {
|
||||
}
|
||||
virtual ~Renderable() = default;
|
||||
|
||||
public:
|
||||
Size getSize() const {
|
||||
@@ -35,6 +36,8 @@ public:
|
||||
return static_cast<T&>(*resource);
|
||||
}
|
||||
|
||||
virtual void wait() {}
|
||||
|
||||
protected:
|
||||
Size size;
|
||||
std::unique_ptr<RenderableResource> resource;
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -47,8 +47,12 @@ void RenderAnnotationSource::update(Immutable<style::Source::Impl> 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) {
|
||||
|
||||
@@ -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<std::reference_wrapper<RenderTile>> getRenderTiles() final;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#include <mbgl/geometry/line_atlas.hpp>
|
||||
#include <mbgl/gfx/context.hpp>
|
||||
#include <mbgl/gfx/upload_pass.hpp>
|
||||
#include <mbgl/util/logging.hpp>
|
||||
#include <mbgl/util/platform.hpp>
|
||||
#include <mbgl/util/hash.hpp>
|
||||
@@ -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 };
|
||||
}
|
||||
|
||||
@@ -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<float>&, LinePatternCap);
|
||||
LinePatternPos addDash(const std::vector<float>& dasharray, LinePatternCap);
|
||||
|
||||
@@ -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<UploadPass> createUploadPass(const char* name) = 0;
|
||||
virtual std::unique_ptr<RenderPass> createRenderPass(const char* name, const RenderPassDescriptor&) = 0;
|
||||
virtual void present(Renderable&) = 0;
|
||||
};
|
||||
|
||||
@@ -1,15 +1,11 @@
|
||||
#pragma once
|
||||
|
||||
#include <mbgl/gfx/vertex_vector.hpp>
|
||||
#include <mbgl/gfx/vertex_buffer.hpp>
|
||||
#include <mbgl/gfx/index_vector.hpp>
|
||||
#include <mbgl/gfx/index_buffer.hpp>
|
||||
#include <mbgl/gfx/texture.hpp>
|
||||
#include <mbgl/gfx/renderbuffer.hpp>
|
||||
#include <mbgl/gfx/command_encoder.hpp>
|
||||
#include <mbgl/gfx/draw_scope.hpp>
|
||||
#include <mbgl/gfx/program.hpp>
|
||||
#include <mbgl/gfx/types.hpp>
|
||||
#include <mbgl/gfx/texture.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
@@ -43,95 +39,25 @@ public:
|
||||
virtual void performCleanup() = 0;
|
||||
|
||||
public:
|
||||
template <class Vertex>
|
||||
VertexBuffer<Vertex>
|
||||
createVertexBuffer(VertexVector<Vertex>&& v,
|
||||
const BufferUsageType usage = BufferUsageType::StaticDraw) {
|
||||
return { v.elements(), createVertexBufferResource(v.data(), v.bytes(), usage) };
|
||||
}
|
||||
|
||||
template <class Vertex>
|
||||
void updateVertexBuffer(VertexBuffer<Vertex>& buffer, VertexVector<Vertex>&& v) {
|
||||
assert(v.elements() == buffer.elements);
|
||||
updateVertexBufferResource(buffer.getResource(), v.data(), v.bytes());
|
||||
}
|
||||
|
||||
template <class DrawMode>
|
||||
IndexBuffer createIndexBuffer(IndexVector<DrawMode>&& v,
|
||||
const BufferUsageType usage = BufferUsageType::StaticDraw) {
|
||||
return { v.elements(), createIndexBufferResource(v.data(), v.bytes(), usage) };
|
||||
}
|
||||
|
||||
template <class DrawMode>
|
||||
void updateIndexBuffer(IndexBuffer& buffer, IndexVector<DrawMode>&& v) {
|
||||
assert(v.elements() == buffer.elements);
|
||||
updateIndexBufferResource(buffer.getResource(), v.data(), v.bytes());
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual std::unique_ptr<VertexBufferResource>
|
||||
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<IndexBufferResource>
|
||||
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<OffscreenTexture>
|
||||
createOffscreenTexture(Size,
|
||||
TextureChannelDataType = TextureChannelDataType::UnsignedByte) = 0;
|
||||
virtual std::unique_ptr<OffscreenTexture>
|
||||
createOffscreenTexture(Size,
|
||||
Renderbuffer<RenderbufferPixelType::Depth>&,
|
||||
TextureChannelDataType = TextureChannelDataType::UnsignedByte) = 0;
|
||||
|
||||
public:
|
||||
// Create a texture from an image with data.
|
||||
template <typename Image>
|
||||
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 <typename Image>
|
||||
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 <typename Image>
|
||||
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<TextureResource> 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<gfx::OffscreenTexture> createOffscreenTexture(
|
||||
Size, gfx::TextureChannelDataType = gfx::TextureChannelDataType::UnsignedByte) = 0;
|
||||
virtual std::unique_ptr<gfx::OffscreenTexture> createOffscreenTexture(
|
||||
Size,
|
||||
gfx::Renderbuffer<gfx::RenderbufferPixelType::Depth>&,
|
||||
gfx::TextureChannelDataType = gfx::TextureChannelDataType::UnsignedByte) = 0;
|
||||
virtual std::unique_ptr<TextureResource>
|
||||
createTextureResource(Size, TexturePixelType, TextureChannelDataType) = 0;
|
||||
|
||||
public:
|
||||
template <RenderbufferPixelType pixelType>
|
||||
|
||||
@@ -52,5 +52,14 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
template <StencilFunctionType F>
|
||||
constexpr StencilFunctionType StencilMode::SimpleTest<F>::func;
|
||||
|
||||
template <StencilFunctionType F>
|
||||
constexpr uint32_t StencilMode::SimpleTest<F>::mask;
|
||||
|
||||
template <StencilFunctionType F>
|
||||
constexpr StencilFunctionType StencilMode::MaskedTest<F>::func;
|
||||
|
||||
} // namespace gfx
|
||||
} // namespace mbgl
|
||||
|
||||
109
src/mbgl/gfx/upload_pass.hpp
Normal file
109
src/mbgl/gfx/upload_pass.hpp
Normal file
@@ -0,0 +1,109 @@
|
||||
#pragma once
|
||||
|
||||
#include <mbgl/gfx/debug_group.hpp>
|
||||
#include <mbgl/gfx/vertex_vector.hpp>
|
||||
#include <mbgl/gfx/vertex_buffer.hpp>
|
||||
#include <mbgl/gfx/index_vector.hpp>
|
||||
#include <mbgl/gfx/index_buffer.hpp>
|
||||
#include <mbgl/gfx/texture.hpp>
|
||||
#include <mbgl/util/size.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
namespace gfx {
|
||||
|
||||
class UploadPass {
|
||||
protected:
|
||||
UploadPass() = default;
|
||||
|
||||
friend class DebugGroup<UploadPass>;
|
||||
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<UploadPass> createDebugGroup(const char* name) {
|
||||
return { *this, name };
|
||||
}
|
||||
|
||||
public:
|
||||
template <class Vertex>
|
||||
VertexBuffer<Vertex>
|
||||
createVertexBuffer(VertexVector<Vertex>&& v,
|
||||
const BufferUsageType usage = BufferUsageType::StaticDraw) {
|
||||
return { v.elements(), createVertexBufferResource(v.data(), v.bytes(), usage) };
|
||||
}
|
||||
|
||||
template <class Vertex>
|
||||
void updateVertexBuffer(VertexBuffer<Vertex>& buffer, VertexVector<Vertex>&& v) {
|
||||
assert(v.elements() == buffer.elements);
|
||||
updateVertexBufferResource(buffer.getResource(), v.data(), v.bytes());
|
||||
}
|
||||
|
||||
template <class DrawMode>
|
||||
IndexBuffer createIndexBuffer(IndexVector<DrawMode>&& v,
|
||||
const BufferUsageType usage = BufferUsageType::StaticDraw) {
|
||||
return { v.elements(), createIndexBufferResource(v.data(), v.bytes(), usage) };
|
||||
}
|
||||
|
||||
template <class DrawMode>
|
||||
void updateIndexBuffer(IndexBuffer& buffer, IndexVector<DrawMode>&& v) {
|
||||
assert(v.elements() == buffer.elements);
|
||||
updateIndexBufferResource(buffer.getResource(), v.data(), v.bytes());
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual std::unique_ptr<VertexBufferResource>
|
||||
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<IndexBufferResource>
|
||||
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 <typename Image>
|
||||
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 <typename Image>
|
||||
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 <typename Image>
|
||||
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<TextureResource> 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
|
||||
@@ -1,4 +1,5 @@
|
||||
#include <mbgl/gl/command_encoder.hpp>
|
||||
#include <mbgl/gl/upload_pass.hpp>
|
||||
#include <mbgl/gl/render_pass.hpp>
|
||||
#include <mbgl/gl/context.hpp>
|
||||
#include <mbgl/gl/renderable_resource.hpp>
|
||||
@@ -15,6 +16,11 @@ CommandEncoder::~CommandEncoder() {
|
||||
context.performCleanup();
|
||||
}
|
||||
|
||||
std::unique_ptr<gfx::UploadPass>
|
||||
CommandEncoder::createUploadPass(const char* name) {
|
||||
return std::make_unique<gl::UploadPass>(*this, name);
|
||||
}
|
||||
|
||||
std::unique_ptr<gfx::RenderPass>
|
||||
CommandEncoder::createRenderPass(const char* name, const gfx::RenderPassDescriptor& descriptor) {
|
||||
return std::make_unique<gl::RenderPass>(*this, name, descriptor);
|
||||
|
||||
@@ -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<gfx::UploadPass> createUploadPass(const char* name) override;
|
||||
std::unique_ptr<gfx::RenderPass> createRenderPass(const char* name, const gfx::RenderPassDescriptor&) override;
|
||||
void present(gfx::Renderable&) override;
|
||||
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
#include <mbgl/gl/context.hpp>
|
||||
#include <mbgl/gl/enum.hpp>
|
||||
#include <mbgl/gl/renderer_backend.hpp>
|
||||
#include <mbgl/gl/vertex_buffer_resource.hpp>
|
||||
#include <mbgl/gl/index_buffer_resource.hpp>
|
||||
#include <mbgl/gl/texture_resource.hpp>
|
||||
#include <mbgl/gl/renderbuffer_resource.hpp>
|
||||
#include <mbgl/gl/draw_scope_resource.hpp>
|
||||
@@ -222,41 +220,6 @@ void Context::verifyProgramLinkage(ProgramID program_) {
|
||||
throw std::runtime_error("program failed to link");
|
||||
}
|
||||
|
||||
std::unique_ptr<gfx::VertexBufferResource>
|
||||
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<gfx::BufferUsageType>::to(usage)));
|
||||
return std::make_unique<gl::VertexBufferResource>(std::move(result));
|
||||
}
|
||||
|
||||
void Context::updateVertexBufferResource(gfx::VertexBufferResource& resource, const void* data, std::size_t size) {
|
||||
vertexBuffer = static_cast<gl::VertexBufferResource&>(resource).buffer;
|
||||
MBGL_CHECK_ERROR(glBufferSubData(GL_ARRAY_BUFFER, 0, size, data));
|
||||
}
|
||||
|
||||
std::unique_ptr<gfx::IndexBufferResource>
|
||||
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<gfx::BufferUsageType>::to(usage)));
|
||||
return std::make_unique<gl::IndexBufferResource>(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<gl::IndexBufferResource&>(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<gfx::TextureResource> Context::createTextureResource(
|
||||
const Size size, const gfx::TexturePixelType format, const gfx::TextureChannelDataType type) {
|
||||
auto obj = createUniqueTexture();
|
||||
std::unique_ptr<gfx::TextureResource> resource =
|
||||
std::make_unique<gl::TextureResource>(std::move(obj));
|
||||
|
||||
// Always use texture unit 0 for manipulating it.
|
||||
activeTextureUnit = 0;
|
||||
texture[0] = static_cast<gl::TextureResource&>(*resource).texture;
|
||||
|
||||
// Creates an empty texture with the specified size and format.
|
||||
MBGL_CHECK_ERROR(glTexImage2D(GL_TEXTURE_2D, 0, Enum<gfx::TexturePixelType>::to(format),
|
||||
size.width, size.height, 0,
|
||||
Enum<gfx::TexturePixelType>::to(format),
|
||||
Enum<gfx::TextureChannelDataType>::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<gfx::RenderbufferResource>
|
||||
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<gfx::TextureResource>
|
||||
Context::createTextureResource(const Size size,
|
||||
const void* data,
|
||||
gfx::TexturePixelType format,
|
||||
gfx::TextureChannelDataType type) {
|
||||
auto obj = createUniqueTexture();
|
||||
std::unique_ptr<gfx::TextureResource> resource = std::make_unique<gl::TextureResource>(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<gl::TextureResource&>(resource).texture;
|
||||
MBGL_CHECK_ERROR(glTexImage2D(GL_TEXTURE_2D, 0, Enum<gfx::TexturePixelType>::to(format),
|
||||
size.width, size.height, 0,
|
||||
Enum<gfx::TexturePixelType>::to(format),
|
||||
Enum<gfx::TextureChannelDataType>::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<const gl::TextureResource&>(resource).texture;
|
||||
MBGL_CHECK_ERROR(glTexSubImage2D(GL_TEXTURE_2D, 0,
|
||||
xOffset, yOffset,
|
||||
size.width, size.height,
|
||||
Enum<gfx::TexturePixelType>::to(format),
|
||||
Enum<gfx::TextureChannelDataType>::to(type), data));
|
||||
}
|
||||
|
||||
std::unique_ptr<gfx::OffscreenTexture>
|
||||
Context::createOffscreenTexture(const Size size, const gfx::TextureChannelDataType type) {
|
||||
return std::make_unique<gl::OffscreenTexture>(*this, size, type);
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#include <mbgl/gl/framebuffer.hpp>
|
||||
#include <mbgl/gl/vertex_array.hpp>
|
||||
#include <mbgl/gl/types.hpp>
|
||||
#include <mbgl/gfx/texture.hpp>
|
||||
#include <mbgl/gfx/draw_mode.hpp>
|
||||
#include <mbgl/gfx/depth_mode.hpp>
|
||||
#include <mbgl/gfx/stencil_mode.hpp>
|
||||
@@ -42,6 +43,8 @@ public:
|
||||
Context(const Context&) = delete;
|
||||
Context& operator=(const Context& other) = delete;
|
||||
|
||||
std::unique_ptr<gfx::CommandEncoder> createCommandEncoder() override;
|
||||
|
||||
void initializeExtensions(const std::function<gl::ProcAddress(const char*)>&);
|
||||
|
||||
void enableDebugging();
|
||||
@@ -189,15 +192,6 @@ private:
|
||||
State<value::PointSize> pointSize;
|
||||
#endif // MBGL_USE_GLES2
|
||||
|
||||
std::unique_ptr<gfx::VertexBufferResource> 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<gfx::IndexBufferResource> 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<gfx::TextureResource> 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<gfx::OffscreenTexture> createOffscreenTexture(
|
||||
Size, gfx::TextureChannelDataType = gfx::TextureChannelDataType::UnsignedByte) override;
|
||||
std::unique_ptr<gfx::OffscreenTexture> createOffscreenTexture(
|
||||
@@ -205,6 +199,9 @@ private:
|
||||
gfx::Renderbuffer<gfx::RenderbufferPixelType::Depth>&,
|
||||
gfx::TextureChannelDataType = gfx::TextureChannelDataType::UnsignedByte) override;
|
||||
|
||||
std::unique_ptr<gfx::TextureResource>
|
||||
createTextureResource(Size, gfx::TexturePixelType, gfx::TextureChannelDataType) override;
|
||||
|
||||
std::unique_ptr<gfx::RenderbufferResource> createRenderbufferResource(gfx::RenderbufferPixelType, Size size) override;
|
||||
|
||||
std::unique_ptr<gfx::DrawScopeResource> createDrawScopeResource() override;
|
||||
@@ -218,8 +215,6 @@ private:
|
||||
VertexArray createVertexArray();
|
||||
bool supportsVertexArrays() const;
|
||||
|
||||
std::unique_ptr<gfx::CommandEncoder> createCommandEncoder() override;
|
||||
|
||||
friend detail::ProgramDeleter;
|
||||
friend detail::ShaderDeleter;
|
||||
friend detail::BufferDeleter;
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -22,7 +22,7 @@ struct ShaderDeleter {
|
||||
};
|
||||
|
||||
struct BufferDeleter {
|
||||
Context* context;
|
||||
Context& context;
|
||||
void operator()(BufferID) const;
|
||||
};
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
117
src/mbgl/gl/upload_pass.cpp
Normal file
117
src/mbgl/gl/upload_pass.cpp
Normal file
@@ -0,0 +1,117 @@
|
||||
#include <mbgl/gl/upload_pass.hpp>
|
||||
#include <mbgl/gl/context.hpp>
|
||||
#include <mbgl/gl/enum.hpp>
|
||||
#include <mbgl/gl/defines.hpp>
|
||||
#include <mbgl/gl/command_encoder.hpp>
|
||||
#include <mbgl/gl/vertex_buffer_resource.hpp>
|
||||
#include <mbgl/gl/index_buffer_resource.hpp>
|
||||
#include <mbgl/gl/texture_resource.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
namespace gl {
|
||||
|
||||
using namespace platform;
|
||||
|
||||
UploadPass::UploadPass(gl::CommandEncoder& commandEncoder_, const char* name)
|
||||
: commandEncoder(commandEncoder_), debugGroup(commandEncoder.createDebugGroup(name)) {
|
||||
}
|
||||
|
||||
std::unique_ptr<gfx::VertexBufferResource> 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<gfx::BufferUsageType>::to(usage)));
|
||||
return std::make_unique<gl::VertexBufferResource>(std::move(result));
|
||||
}
|
||||
|
||||
void UploadPass::updateVertexBufferResource(gfx::VertexBufferResource& resource,
|
||||
const void* data,
|
||||
std::size_t size) {
|
||||
commandEncoder.context.vertexBuffer = static_cast<gl::VertexBufferResource&>(resource).buffer;
|
||||
MBGL_CHECK_ERROR(glBufferSubData(GL_ARRAY_BUFFER, 0, size, data));
|
||||
}
|
||||
|
||||
std::unique_ptr<gfx::IndexBufferResource> 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<gfx::BufferUsageType>::to(usage)));
|
||||
return std::make_unique<gl::IndexBufferResource>(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<gl::IndexBufferResource&>(resource).buffer;
|
||||
MBGL_CHECK_ERROR(glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, size, data));
|
||||
}
|
||||
|
||||
std::unique_ptr<gfx::TextureResource>
|
||||
UploadPass::createTextureResource(const Size size,
|
||||
const void* data,
|
||||
gfx::TexturePixelType format,
|
||||
gfx::TextureChannelDataType type) {
|
||||
auto obj = commandEncoder.context.createUniqueTexture();
|
||||
std::unique_ptr<gfx::TextureResource> resource =
|
||||
std::make_unique<gl::TextureResource>(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<gl::TextureResource&>(resource).texture;
|
||||
MBGL_CHECK_ERROR(glTexImage2D(GL_TEXTURE_2D, 0, Enum<gfx::TexturePixelType>::to(format),
|
||||
size.width, size.height, 0,
|
||||
Enum<gfx::TexturePixelType>::to(format),
|
||||
Enum<gfx::TextureChannelDataType>::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<const gl::TextureResource&>(resource).texture;
|
||||
MBGL_CHECK_ERROR(glTexSubImage2D(GL_TEXTURE_2D, 0, xOffset, yOffset, size.width, size.height,
|
||||
Enum<gfx::TexturePixelType>::to(format),
|
||||
Enum<gfx::TextureChannelDataType>::to(type), data));
|
||||
}
|
||||
|
||||
void UploadPass::pushDebugGroup(const char* name) {
|
||||
commandEncoder.pushDebugGroup(name);
|
||||
}
|
||||
|
||||
void UploadPass::popDebugGroup() {
|
||||
commandEncoder.popDebugGroup();
|
||||
}
|
||||
|
||||
} // namespace gl
|
||||
} // namespace mbgl
|
||||
42
src/mbgl/gl/upload_pass.hpp
Normal file
42
src/mbgl/gl/upload_pass.hpp
Normal file
@@ -0,0 +1,42 @@
|
||||
#pragma once
|
||||
|
||||
#include <mbgl/gfx/upload_pass.hpp>
|
||||
|
||||
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<gfx::VertexBufferResource> 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<gfx::IndexBufferResource> 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<gfx::TextureResource> 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<gfx::CommandEncoder> debugGroup;
|
||||
};
|
||||
|
||||
} // namespace gl
|
||||
} // namespace mbgl
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
#include <mbgl/gfx/attribute.hpp>
|
||||
#include <mbgl/gfx/uniform.hpp>
|
||||
#include <mbgl/gfx/draw_mode.hpp>
|
||||
#include <mbgl/programs/segment.hpp>
|
||||
#include <mbgl/programs/attributes.hpp>
|
||||
#include <mbgl/programs/program_parameters.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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
#include <mbgl/renderer/buckets/debug_bucket.hpp>
|
||||
#include <mbgl/programs/fill_program.hpp>
|
||||
#include <mbgl/geometry/debug_font_data.hpp>
|
||||
#include <mbgl/tile/tile_id.hpp>
|
||||
#include <mbgl/util/string.hpp>
|
||||
@@ -16,8 +15,7 @@ DebugBucket::DebugBucket(const OverscaledTileID& id,
|
||||
const bool complete_,
|
||||
optional<Timestamp> modified_,
|
||||
optional<Timestamp> 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<FillLayoutVertex> vertices;
|
||||
gfx::IndexVector<gfx::Lines> 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));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -8,13 +8,14 @@
|
||||
#include <mbgl/gfx/vertex_buffer.hpp>
|
||||
#include <mbgl/gfx/index_buffer.hpp>
|
||||
#include <mbgl/programs/debug_program.hpp>
|
||||
#include <mbgl/programs/fill_program.hpp>
|
||||
|
||||
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<Timestamp> modified,
|
||||
optional<Timestamp> expires,
|
||||
MapDebugOptions,
|
||||
gfx::Context&);
|
||||
MapDebugOptions);
|
||||
|
||||
void upload(gfx::UploadPass&);
|
||||
|
||||
const bool renderable;
|
||||
const bool complete;
|
||||
@@ -33,6 +35,10 @@ public:
|
||||
const optional<Timestamp> expires;
|
||||
const MapDebugOptions debugMode;
|
||||
|
||||
|
||||
gfx::VertexVector<FillLayoutVertex> vertices;
|
||||
gfx::IndexVector<gfx::Lines> indices;
|
||||
|
||||
SegmentVector<DebugAttributes> segments;
|
||||
optional<gfx::VertexBuffer<DebugLayoutVertex>> vertexBuffer;
|
||||
optional<gfx::IndexBuffer> indexBuffer;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#include <mbgl/renderer/buckets/raster_bucket.hpp>
|
||||
#include <mbgl/renderer/layers/render_raster_layer.hpp>
|
||||
#include <mbgl/programs/raster_program.hpp>
|
||||
#include <mbgl/gfx/context.hpp>
|
||||
#include <mbgl/gfx/upload_pass.hpp>
|
||||
#include <mbgl/util/id.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
@@ -20,16 +20,16 @@ RasterBucket::RasterBucket(std::shared_ptr<PremultipliedImage> 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;
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ public:
|
||||
RasterBucket(std::shared_ptr<PremultipliedImage>);
|
||||
~RasterBucket() override;
|
||||
|
||||
void upload(gfx::Context&) override;
|
||||
void upload(gfx::UploadPass&) override;
|
||||
bool hasData() const override;
|
||||
bool supportsLayer(const style::Layer::Impl&) const override;
|
||||
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#include <mbgl/renderer/image_atlas.hpp>
|
||||
#include <mbgl/gfx/upload_pass.hpp>
|
||||
#include <mbgl/gfx/context.hpp>
|
||||
#include <mbgl/renderer/image_manager.hpp>
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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<std::string, uint32_t>& versionMap);
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#include <mbgl/actor/actor.hpp>
|
||||
#include <mbgl/actor/scheduler.hpp>
|
||||
#include <mbgl/util/logging.hpp>
|
||||
#include <mbgl/gfx/upload_pass.hpp>
|
||||
#include <mbgl/gfx/context.hpp>
|
||||
#include <mbgl/renderer/image_manager_observer.hpp>
|
||||
|
||||
@@ -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 };
|
||||
}
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@ template <class T>
|
||||
class Actor;
|
||||
|
||||
namespace gfx {
|
||||
class Context;
|
||||
class UploadPass;
|
||||
} // namespace gfx
|
||||
|
||||
class ImageRequestor;
|
||||
@@ -83,8 +83,8 @@ private:
|
||||
public:
|
||||
optional<ImagePosition> getPattern(const std::string& name);
|
||||
|
||||
gfx::TextureBinding textureBinding(gfx::Context&);
|
||||
void upload(gfx::Context&);
|
||||
gfx::TextureBinding textureBinding();
|
||||
void upload(gfx::UploadPass&);
|
||||
|
||||
Size getPixelSize() const;
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#include <mbgl/renderer/layers/render_background_layer.hpp>
|
||||
#include <mbgl/style/layers/background_layer_impl.hpp>
|
||||
#include <mbgl/renderer/bucket.hpp>
|
||||
#include <mbgl/renderer/upload_parameters.hpp>
|
||||
#include <mbgl/renderer/paint_parameters.hpp>
|
||||
#include <mbgl/renderer/image_manager.hpp>
|
||||
#include <mbgl/renderer/render_static_data.hpp>
|
||||
@@ -37,6 +38,9 @@ void RenderBackgroundLayer::evaluate(const PropertyEvaluationParameters ¶met
|
||||
|
||||
passes = properties->evaluated.get<style::BackgroundOpacity>() > 0 ? RenderPass::Translucent
|
||||
: RenderPass::None;
|
||||
if (passes != RenderPass::None && !properties->evaluated.get<style::BackgroundPattern>().to.empty()) {
|
||||
passes |= RenderPass::Upload;
|
||||
}
|
||||
evaluatedProperties = std::move(properties);
|
||||
}
|
||||
|
||||
@@ -48,6 +52,15 @@ bool RenderBackgroundLayer::hasCrossfade() const {
|
||||
return getCrossfade<BackgroundLayerProperties>(evaluatedProperties).t != 1;
|
||||
}
|
||||
|
||||
void RenderBackgroundLayer::upload(gfx::UploadPass&, UploadParameters& parameters) {
|
||||
const auto& evaluated = static_cast<const BackgroundLayerProperties&>(*evaluatedProperties).evaluated;
|
||||
if (!evaluated.get<BackgroundPattern>().to.empty()) {
|
||||
// Ensures that the texture gets added and uploaded to the atlas.
|
||||
parameters.imageManager.getPattern(evaluated.get<BackgroundPattern>().from);
|
||||
parameters.imageManager.getPattern(evaluated.get<BackgroundPattern>().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() },
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@ private:
|
||||
bool hasTransition() const override;
|
||||
bool hasCrossfade() const override;
|
||||
optional<Color> getSolidBackground() const override;
|
||||
void upload(gfx::UploadPass&, UploadParameters&) override;
|
||||
void render(PaintParameters&, RenderSource*) override;
|
||||
|
||||
// Paint properties
|
||||
|
||||
@@ -41,7 +41,7 @@ void RenderHeatmapLayer::evaluate(const PropertyEvaluationParameters& parameters
|
||||
unevaluated.evaluate(parameters));
|
||||
|
||||
passes = (properties->evaluated.get<style::HeatmapOpacity>() > 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<style::HeatmapIntensity>() ),
|
||||
@@ -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,
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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{
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#include <mbgl/renderer/buckets/line_bucket.hpp>
|
||||
#include <mbgl/renderer/render_tile.hpp>
|
||||
#include <mbgl/renderer/render_source.hpp>
|
||||
#include <mbgl/renderer/upload_parameters.hpp>
|
||||
#include <mbgl/renderer/paint_parameters.hpp>
|
||||
#include <mbgl/renderer/image_manager.hpp>
|
||||
#include <mbgl/programs/programs.hpp>
|
||||
@@ -46,7 +47,7 @@ void RenderLineLayer::evaluate(const PropertyEvaluationParameters& parameters) {
|
||||
passes = (evaluated.get<style::LineOpacity>().constantOr(1.0) > 0
|
||||
&& evaluated.get<style::LineColor>().constantOr(Color::black()).a > 0
|
||||
&& evaluated.get<style::LineWidth>().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<LineLayerProperties>(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<LineBucket&>(*renderData->bucket);
|
||||
const auto& evaluated = getEvaluated<LineLayerProperties>(renderData->layerProperties);
|
||||
|
||||
if (!evaluated.get<LineDasharray>().from.empty()) {
|
||||
const LinePatternCap cap = bucket.layout.get<LineCap>() == LineCapType::Round
|
||||
? LinePatternCap::Round : LinePatternCap::Square;
|
||||
// Ensures that the dash data gets added and uploaded to the atlas.
|
||||
uploadParameters.lineAtlas.getDashPosition(evaluated.get<LineDasharray>().from, cap);
|
||||
uploadParameters.lineAtlas.getDashPosition(evaluated.get<LineDasharray>().to, cap);
|
||||
|
||||
} else if (!unevaluated.get<LinePattern>().isUndefined()) {
|
||||
const auto& linePatternValue = evaluated.get<LinePattern>().constantOr(Faded<std::basic_string<char>>{ "", ""});
|
||||
auto& geometryTile = static_cast<GeometryTile&>(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<LineGradient>().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<LinePattern>().isUndefined()) {
|
||||
const auto& linePatternValue = evaluated.get<LinePattern>().constantOr(Faded<std::basic_string<char>>{ "", ""});
|
||||
auto& geometryTile = static_cast<GeometryTile&>(tile.tile);
|
||||
auto& geometryTile = static_cast<GeometryTile&>(tile.tile);
|
||||
const Size texsize = geometryTile.iconAtlasTexture->size;
|
||||
|
||||
optional<ImagePosition> 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<LineGradient>().getValue().isUndefined()) {
|
||||
if (!colorRampTexture) {
|
||||
colorRampTexture = parameters.context.createTexture(colorRamp);
|
||||
}
|
||||
assert(colorRampTexture);
|
||||
|
||||
draw(parameters.programs.getLineLayerPrograms().lineGradient,
|
||||
LineGradientProgram::layoutUniformValues(
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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 },
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
#include <mbgl/renderer/bucket_parameters.hpp>
|
||||
#include <mbgl/renderer/property_evaluation_parameters.hpp>
|
||||
#include <mbgl/renderer/render_tile.hpp>
|
||||
#include <mbgl/renderer/upload_parameters.hpp>
|
||||
#include <mbgl/renderer/paint_parameters.hpp>
|
||||
#include <mbgl/text/glyph_atlas.hpp>
|
||||
#include <mbgl/text/shaping.hpp>
|
||||
@@ -13,9 +14,11 @@
|
||||
#include <mbgl/tile/geometry_tile.hpp>
|
||||
#include <mbgl/tile/geometry_tile_data.hpp>
|
||||
#include <mbgl/style/layers/symbol_layer_impl.hpp>
|
||||
#include <mbgl/text/placement.hpp>
|
||||
#include <mbgl/gfx/cull_face_mode.hpp>
|
||||
#include <mbgl/layout/symbol_projection.hpp>
|
||||
#include <mbgl/layout/symbol_layout.hpp>
|
||||
#include <mbgl/layout/symbol_layout.hpp>
|
||||
#include <mbgl/util/math.hpp>
|
||||
|
||||
#include <cmath>
|
||||
@@ -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<SymbolBucket&>(*renderData.bucket);
|
||||
const auto& layout = bucket.layout;
|
||||
|
||||
const bool alongLine = layout.get<SymbolPlacement>() != SymbolPlacementType::Point &&
|
||||
layout.get<IconRotationAlignment>() == AlignmentType::Map;
|
||||
|
||||
if (alongLine) {
|
||||
const auto& evaluated = getEvaluated<SymbolLayerProperties>(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<SymbolBucket&>(*renderData.bucket);
|
||||
const auto& layout = bucket.layout;
|
||||
|
||||
const bool alongLine = layout.get<SymbolPlacement>() != SymbolPlacementType::Point &&
|
||||
layout.get<TextRotationAlignment>() == AlignmentType::Map;
|
||||
|
||||
if (alongLine) {
|
||||
const auto& evaluated = getEvaluated<SymbolLayerProperties>(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<TextVariableAnchor>().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<TextRotationAlignment>() == AlignmentType::Map;
|
||||
const bool pitchWithMap = layout.get<TextPitchAlignment>() == 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> 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<float> 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<float> shiftedAnchor;
|
||||
if (pitchWithMap) {
|
||||
shiftedAnchor = project(Point<float>(tileAnchor.x + shift.x, tileAnchor.y + shift.y),
|
||||
labelPlaneMatrix).first;
|
||||
} else {
|
||||
if (rotateWithMap) {
|
||||
auto rotated = util::rotate(shift, -uploadParameters.state.getPitch());
|
||||
shiftedAnchor = Point<float>(projectedAnchor.first.x + rotated.x,
|
||||
projectedAnchor.first.y + rotated.y);
|
||||
} else {
|
||||
shiftedAnchor = Point<float>(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 <typename DrawFn>
|
||||
void drawIcon(const DrawFn& draw,
|
||||
const RenderTile& tile,
|
||||
@@ -130,18 +249,6 @@ void drawIcon(const DrawFn& draw,
|
||||
const bool alongLine = layout.get<SymbolPlacement>() != SymbolPlacementType::Point &&
|
||||
layout.get<IconRotationAlignment>() == 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<IconSize>().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<GeometryTile&>(tile.tile);
|
||||
auto& bucket = static_cast<SymbolBucket&>(*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<SymbolPlacement>() != SymbolPlacementType::Point &&
|
||||
layout.get<TextRotationAlignment>() == 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<TextVariableAnchor>().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<TextRotationAlignment>() == AlignmentType::Map;
|
||||
const bool pitchWithMap = layout.get<TextPitchAlignment>() == 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> 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<float> 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<float> shiftedAnchor;
|
||||
if (pitchWithMap) {
|
||||
shiftedAnchor = project(Point<float>(tileAnchor.x + shift.x, tileAnchor.y + shift.y),
|
||||
labelPlaneMatrix).first;
|
||||
} else {
|
||||
if (rotateWithMap) {
|
||||
auto rotated = util::rotate(shift, -parameters.state.getPitch());
|
||||
shiftedAnchor = Point<float>(projectedAnchor.first.x + rotated.x,
|
||||
projectedAnchor.first.y + rotated.y);
|
||||
} else {
|
||||
shiftedAnchor = Point<float>(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<style::IconOpacity>().constantOr(1) > 0 && hasIconOpacity && iconSize > 0)
|
||||
|| (evaluated.get<style::TextOpacity>().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<SymbolBucket>(*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<SymbolBucket&>(*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);
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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<std::reference_w
|
||||
},
|
||||
gfx::ColorMode::disabled(),
|
||||
gfx::CullFaceMode::disabled(),
|
||||
staticData.quadTriangleIndexBuffer,
|
||||
*staticData.quadTriangleIndexBuffer,
|
||||
staticData.tileTriangleSegments,
|
||||
program.computeAllUniformValues(
|
||||
ClippingMaskProgram::LayoutUniformValues {
|
||||
@@ -146,7 +144,7 @@ void PaintParameters::renderTileClippingMasks(const std::vector<std::reference_w
|
||||
state.getZoom()
|
||||
),
|
||||
program.computeAllAttributeBindings(
|
||||
staticData.tileVertexBuffer,
|
||||
*staticData.tileVertexBuffer,
|
||||
paintAttributeData,
|
||||
properties
|
||||
),
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
#include <mbgl/gfx/stencil_mode.hpp>
|
||||
#include <mbgl/gfx/color_mode.hpp>
|
||||
#include <mbgl/util/mat4.hpp>
|
||||
#include <mbgl/text/placement.hpp>
|
||||
|
||||
#include <array>
|
||||
#include <map>
|
||||
@@ -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<float, 2> pixelsToGLUnits;
|
||||
|
||||
Programs& programs;
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
#include <mbgl/gfx/context.hpp>
|
||||
#include <mbgl/gfx/uniform.hpp>
|
||||
#include <mbgl/gfx/attribute.hpp>
|
||||
#include <mbgl/gfx/upload_pass.hpp>
|
||||
#include <mbgl/programs/attributes.hpp>
|
||||
#include <mbgl/util/literal.hpp>
|
||||
#include <mbgl/util/type_list.hpp>
|
||||
@@ -99,7 +100,7 @@ public:
|
||||
std::size_t length, const ImagePositions&,
|
||||
const optional<PatternDependency>&,
|
||||
const style::expression::Value&) = 0;
|
||||
virtual void upload(gfx::Context& context) = 0;
|
||||
virtual void upload(gfx::UploadPass&) = 0;
|
||||
virtual void setPatternParameters(const optional<ImagePosition>&, const optional<ImagePosition>&, const CrossfadeParameters&) = 0;
|
||||
virtual std::tuple<ExpandToType<As, optional<gfx::AttributeBinding>>...> attributeBinding(const PossiblyEvaluatedType& currentValue) const = 0;
|
||||
virtual std::tuple<ExpandToType<As, float>...> interpolationFactor(float currentZoom) const = 0;
|
||||
@@ -118,7 +119,7 @@ public:
|
||||
}
|
||||
|
||||
void populateVertexVector(const GeometryTileFeature&, std::size_t, const ImagePositions&, const optional<PatternDependency>&, const style::expression::Value&) override {}
|
||||
void upload(gfx::Context&) override {}
|
||||
void upload(gfx::UploadPass&) override {}
|
||||
void setPatternParameters(const optional<ImagePosition>&, const optional<ImagePosition>&, const CrossfadeParameters&) override {};
|
||||
|
||||
std::tuple<optional<gfx::AttributeBinding>> attributeBinding(const PossiblyEvaluatedPropertyValue<T>&) const override {
|
||||
@@ -145,7 +146,7 @@ public:
|
||||
}
|
||||
|
||||
void populateVertexVector(const GeometryTileFeature&, std::size_t, const ImagePositions&, const optional<PatternDependency>&, const style::expression::Value&) override {}
|
||||
void upload(gfx::Context&) override {}
|
||||
void upload(gfx::UploadPass&) override {}
|
||||
|
||||
void setPatternParameters(const optional<ImagePosition>& posA, const optional<ImagePosition>& 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<optional<gfx::AttributeBinding>> attributeBinding(const PossiblyEvaluatedPropertyValue<T>& 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<optional<gfx::AttributeBinding>> attributeBinding(const PossiblyEvaluatedPropertyValue<T>& 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<gfx::AttributeBinding>, optional<gfx::AttributeBinding>> attributeBinding(const PossiblyEvaluatedPropertyValue<Faded<T>>& currentValue) const override {
|
||||
@@ -492,9 +493,9 @@ public:
|
||||
});
|
||||
}
|
||||
|
||||
void upload(gfx::Context& context) {
|
||||
void upload(gfx::UploadPass& uploadPass) {
|
||||
util::ignore({
|
||||
(binders.template get<Ps>()->upload(context), 0)...
|
||||
(binders.template get<Ps>()->upload(uploadPass), 0)...
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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<RenderSource> create(Immutable<style::Source::Impl>);
|
||||
@@ -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.
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#include <mbgl/renderer/render_static_data.hpp>
|
||||
#include <mbgl/gfx/context.hpp>
|
||||
#include <mbgl/gfx/upload_pass.hpp>
|
||||
#include <mbgl/programs/program_parameters.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
@@ -49,12 +50,7 @@ static gfx::VertexVector<HeatmapTextureLayoutVertex> heatmapTextureVertices() {
|
||||
}
|
||||
|
||||
RenderStaticData::RenderStaticData(gfx::Context& context, float pixelRatio, const optional<std::string>& 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
|
||||
|
||||
@@ -14,18 +14,21 @@
|
||||
namespace mbgl {
|
||||
namespace gfx {
|
||||
class Context;
|
||||
class UploadPass;
|
||||
} // namespace gfx
|
||||
|
||||
class RenderStaticData {
|
||||
public:
|
||||
RenderStaticData(gfx::Context&, float pixelRatio, const optional<std::string>& programCacheDir);
|
||||
|
||||
gfx::VertexBuffer<gfx::Vertex<PositionOnlyLayoutAttributes>> tileVertexBuffer;
|
||||
gfx::VertexBuffer<RasterLayoutVertex> rasterVertexBuffer;
|
||||
gfx::VertexBuffer<HeatmapTextureLayoutVertex> heatmapTextureVertexBuffer;
|
||||
void upload(gfx::UploadPass&);
|
||||
|
||||
gfx::IndexBuffer quadTriangleIndexBuffer;
|
||||
gfx::IndexBuffer tileBorderIndexBuffer;
|
||||
optional<gfx::VertexBuffer<gfx::Vertex<PositionOnlyLayoutAttributes>>> tileVertexBuffer;
|
||||
optional<gfx::VertexBuffer<RasterLayoutVertex>> rasterVertexBuffer;
|
||||
optional<gfx::VertexBuffer<HeatmapTextureLayoutVertex>> heatmapTextureVertexBuffer;
|
||||
|
||||
optional<gfx::IndexBuffer> quadTriangleIndexBuffer;
|
||||
optional<gfx::IndexBuffer> tileBorderIndexBuffer;
|
||||
|
||||
SegmentVector<BackgroundAttributes> tileTriangleSegments;
|
||||
SegmentVector<DebugAttributes> tileBorderSegments;
|
||||
@@ -34,6 +37,7 @@ public:
|
||||
|
||||
optional<gfx::Renderbuffer<gfx::RenderbufferPixelType::Depth>> depthRenderbuffer;
|
||||
bool has3D = false;
|
||||
bool uploaded = false;
|
||||
Size backendSize;
|
||||
|
||||
Programs programs;
|
||||
|
||||
@@ -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<float, 2>& 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<DebugBucket>(
|
||||
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<DebugBucket>(
|
||||
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
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,16 +6,23 @@
|
||||
#include <mbgl/renderer/tile_mask.hpp>
|
||||
|
||||
#include <array>
|
||||
#include <memory>
|
||||
|
||||
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> debugBucket;
|
||||
|
||||
mat4 translatedMatrix(const std::array<float, 2>& 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,
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#include <mbgl/renderer/render_layer.hpp>
|
||||
#include <mbgl/renderer/render_static_data.hpp>
|
||||
#include <mbgl/renderer/update_parameters.hpp>
|
||||
#include <mbgl/renderer/upload_parameters.hpp>
|
||||
#include <mbgl/renderer/paint_parameters.hpp>
|
||||
#include <mbgl/renderer/transition_parameters.hpp>
|
||||
#include <mbgl/renderer/property_evaluation_parameters.hpp>
|
||||
@@ -16,6 +17,7 @@
|
||||
#include <mbgl/gfx/backend_scope.hpp>
|
||||
#include <mbgl/renderer/image_manager.hpp>
|
||||
#include <mbgl/gfx/renderer_backend.hpp>
|
||||
#include <mbgl/gfx/upload_pass.hpp>
|
||||
#include <mbgl/gfx/render_pass.hpp>
|
||||
#include <mbgl/gfx/cull_face_mode.hpp>
|
||||
#include <mbgl/gfx/context.hpp>
|
||||
@@ -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 -------------------------------------------------------------------------------------
|
||||
|
||||
@@ -47,8 +47,12 @@ void RenderCustomGeometrySource::update(Immutable<style::Source::Impl> 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) {
|
||||
|
||||
@@ -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<std::reference_wrapper<RenderTile>> getRenderTiles() final;
|
||||
|
||||
@@ -123,8 +123,12 @@ void RenderGeoJSONSource::update(Immutable<style::Source::Impl> 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) {
|
||||
|
||||
@@ -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<std::reference_wrapper<RenderTile>> getRenderTiles() final;
|
||||
|
||||
@@ -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
|
||||
),
|
||||
|
||||
@@ -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<style::Source::Impl>,
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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<std::reference_wrapper<RenderTile>> getRenderTiles() final;
|
||||
|
||||
@@ -57,9 +57,13 @@ void RenderRasterSource::update(Immutable<style::Source::Impl> 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) {
|
||||
|
||||
@@ -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<std::reference_wrapper<RenderTile>> getRenderTiles() final;
|
||||
|
||||
@@ -57,8 +57,12 @@ void RenderVectorSource::update(Immutable<style::Source::Impl> 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) {
|
||||
|
||||
@@ -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<std::reference_wrapper<RenderTile>> getRenderTiles() final;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -43,7 +43,8 @@ public:
|
||||
optional<LatLngBounds> bounds,
|
||||
std::function<std::unique_ptr<Tile> (const OverscaledTileID&)> createTile);
|
||||
|
||||
void startRender(PaintParameters&);
|
||||
void upload(gfx::UploadPass&);
|
||||
void prepare(PaintParameters&);
|
||||
void finishRender(PaintParameters&);
|
||||
|
||||
std::vector<std::reference_wrapper<RenderTile>> getRenderTiles();
|
||||
|
||||
31
src/mbgl/renderer/upload_parameters.hpp
Normal file
31
src/mbgl/renderer/upload_parameters.hpp
Normal file
@@ -0,0 +1,31 @@
|
||||
#pragma once
|
||||
|
||||
#include <unordered_map>
|
||||
#include <cstdint>
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
class TransformState;
|
||||
class LineAtlas;
|
||||
class VariableOffset;
|
||||
using VariableOffsets = std::unordered_map<uint32_t, VariableOffset>;
|
||||
|
||||
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
|
||||
@@ -105,8 +105,8 @@ public:
|
||||
void setStale();
|
||||
|
||||
const RetainedQueryData& getQueryData(uint32_t bucketInstanceId) const;
|
||||
using VariableOffsets = std::reference_wrapper<const std::unordered_map<uint32_t, VariableOffset>>;
|
||||
VariableOffsets getVariableOffsets() const { return std::cref(variableOffsets); }
|
||||
using VariableOffsets = std::unordered_map<uint32_t, VariableOffset>;
|
||||
const VariableOffsets& getVariableOffsets() const { return variableOffsets; }
|
||||
|
||||
private:
|
||||
void placeLayerBucket(
|
||||
|
||||
@@ -176,10 +176,10 @@ const optional<ImagePosition> 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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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<style::LayerProperties>&) override;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -72,7 +72,7 @@ public:
|
||||
void setMetadata(optional<Timestamp> modified, optional<Timestamp> expires);
|
||||
void setData(std::shared_ptr<const std::string> data);
|
||||
|
||||
void upload(gfx::Context&) override;
|
||||
void upload(gfx::UploadPass&) override;
|
||||
Bucket* getBucket(const style::Layer::Impl&) const override;
|
||||
|
||||
HillshadeBucket* getBucket() const;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@ public:
|
||||
void setMetadata(optional<Timestamp> modified, optional<Timestamp> expires);
|
||||
void setData(std::shared_ptr<const std::string> data);
|
||||
|
||||
void upload(gfx::Context&) override;
|
||||
void upload(gfx::UploadPass&) override;
|
||||
Bucket* getBucket(const style::Layer::Impl&) const override;
|
||||
|
||||
void setMask(TileMask&&) override;
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
#include <mbgl/tile/tile.hpp>
|
||||
#include <mbgl/tile/tile_observer.hpp>
|
||||
#include <mbgl/renderer/buckets/debug_bucket.hpp>
|
||||
#include <mbgl/renderer/query.hpp>
|
||||
#include <mbgl/util/string.hpp>
|
||||
#include <mbgl/util/logging.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<Timestamp> modified;
|
||||
optional<Timestamp> expires;
|
||||
|
||||
// Contains the tile ID string for painting debug information.
|
||||
std::unique_ptr<DebugBucket> debugBucket;
|
||||
|
||||
protected:
|
||||
bool triedOptional = false;
|
||||
bool renderable = false;
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user