[core] add gfx::UploadPass, split startRender into prepare and upload

This commit is contained in:
Konstantin Käfer
2019-05-13 17:13:31 -07:00
parent bf0998697e
commit 3a6ff7710f
90 changed files with 944 additions and 536 deletions

View File

@@ -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;

View File

@@ -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",

View File

@@ -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) {

View File

@@ -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;

View File

@@ -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 };
}

View File

@@ -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);

View File

@@ -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;
};

View File

@@ -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>

View File

@@ -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

View 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

View File

@@ -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);

View File

@@ -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;

View File

@@ -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);

View File

@@ -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;

View File

@@ -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 {

View File

@@ -22,7 +22,7 @@ struct ShaderDeleter {
};
struct BufferDeleter {
Context* context;
Context& context;
void operator()(BufferID) const;
};

View File

@@ -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
View 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

View 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

View File

@@ -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>

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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));
}
}

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;
}

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;
}

View File

@@ -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;

View File

@@ -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));
}
}
}

View File

@@ -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;

View File

@@ -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;
}

View File

@@ -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);

View File

@@ -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 };
}

View File

@@ -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;

View File

@@ -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 &paramet
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() },
}
);
}

View File

@@ -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

View File

@@ -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,

View File

@@ -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(

View File

@@ -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{

View File

@@ -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(

View File

@@ -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(

View File

@@ -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 },

View File

@@ -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);
}

View File

@@ -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

View File

@@ -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
),

View File

@@ -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;

View File

@@ -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)...
});
}

View File

@@ -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

View File

@@ -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) {

View File

@@ -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.

View File

@@ -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

View File

@@ -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;

View File

@@ -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
);
}
}

View File

@@ -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,

View File

@@ -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 -------------------------------------------------------------------------------------

View File

@@ -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) {

View File

@@ -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;

View File

@@ -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) {

View File

@@ -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;

View File

@@ -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
),

View File

@@ -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>,

View File

@@ -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) {

View File

@@ -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;

View File

@@ -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) {

View File

@@ -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;

View File

@@ -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) {

View File

@@ -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;

View File

@@ -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);
}
}

View File

@@ -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();

View 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

View File

@@ -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(

View File

@@ -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);
}
}

View File

@@ -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;

View File

@@ -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);
}
}

View File

@@ -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;

View File

@@ -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);
}
}

View File

@@ -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;

View File

@@ -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>

View File

@@ -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;

View File

@@ -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();

View File

@@ -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
}