Drawable Renderer (#1570), first cut at layer groups

This commit is contained in:
Tim Sylvester
2023-05-11 10:43:14 -07:00
committed by Bart Louwers
parent d8ea91de98
commit af39aca061
9 changed files with 297 additions and 25 deletions

View File

@@ -180,6 +180,7 @@ list(APPEND INCLUDE_FILES
${PROJECT_SOURCE_DIR}/include/mbgl/platform/settings.hpp
${PROJECT_SOURCE_DIR}/include/mbgl/platform/thread.hpp
${PROJECT_SOURCE_DIR}/include/mbgl/renderer/query.hpp
${PROJECT_SOURCE_DIR}/include/mbgl/renderer/layer_group.hpp
${PROJECT_SOURCE_DIR}/include/mbgl/renderer/renderer.hpp
${PROJECT_SOURCE_DIR}/include/mbgl/renderer/renderer_frontend.hpp
${PROJECT_SOURCE_DIR}/include/mbgl/renderer/renderer_observer.hpp
@@ -518,6 +519,7 @@ list(APPEND SRC_FILES
${PROJECT_SOURCE_DIR}/src/mbgl/renderer/image_manager.cpp
${PROJECT_SOURCE_DIR}/src/mbgl/renderer/image_manager.hpp
${PROJECT_SOURCE_DIR}/src/mbgl/renderer/image_manager_observer.hpp
${PROJECT_SOURCE_DIR}/src/mbgl/renderer/layer_group.cpp
${PROJECT_SOURCE_DIR}/src/mbgl/renderer/layers/render_background_layer.cpp
${PROJECT_SOURCE_DIR}/src/mbgl/renderer/layers/render_background_layer.hpp
${PROJECT_SOURCE_DIR}/src/mbgl/renderer/layers/render_circle_layer.cpp

View File

@@ -7,9 +7,15 @@
#include <vector>
namespace mbgl {
class ChangeRequest;
class LayerGroup;
class RenderOrchestrator;
using ChangeRequestPtr = std::shared_ptr<ChangeRequest>;
using UniqueChangeRequest = std::unique_ptr<ChangeRequest>;
using UniqueChangeRequestVec = std::vector<UniqueChangeRequest>;
using UniqueLayerGroup = std::unique_ptr<LayerGroup>;
namespace gfx {
class Drawable;
using DrawablePtr = std::shared_ptr<Drawable>;
@@ -30,20 +36,15 @@ public:
protected:
};
using ChangeRequestPtr = std::shared_ptr<ChangeRequest>;
using UniqueChangeRequest = std::unique_ptr<ChangeRequest>;
using UniqueChangeRequestVec = std::vector<UniqueChangeRequest>;
/**
Base for drawable-related change requests
Base for change requests based on an ID reference
*/
class DrawableRefChangeRequest : public ChangeRequest {
class RefChangeRequest : public ChangeRequest {
protected:
DrawableRefChangeRequest(util::SimpleIdentity id)
: drawableID(id) {}
DrawableRefChangeRequest(const DrawableRefChangeRequest &) = default;
RefChangeRequest(util::SimpleIdentity id_) : id(id_) {}
RefChangeRequest(const RefChangeRequest&) = default;
util::SimpleIdentity drawableID;
util::SimpleIdentity id;
};
/**
@@ -56,7 +57,7 @@ public:
AddDrawableRequest(AddDrawableRequest &&other)
: drawable(std::move(other.drawable)) {}
void execute(RenderOrchestrator &) override;
void execute(RenderOrchestrator&) override;
protected:
gfx::DrawablePtr drawable;
@@ -65,29 +66,58 @@ protected:
/**
Remove a drawable from the scene
*/
class RemoveDrawableRequest : public DrawableRefChangeRequest {
class RemoveDrawableRequest : public RefChangeRequest {
public:
RemoveDrawableRequest(util::SimpleIdentity id)
: DrawableRefChangeRequest(id) {}
: RefChangeRequest(id) {}
RemoveDrawableRequest(const RemoveDrawableRequest &) = default;
void execute(RenderOrchestrator &) override;
void execute(RenderOrchestrator&) override;
};
/**
Change the color of all vertexes
*/
class ResetColorRequest : public DrawableRefChangeRequest {
class ResetColorRequest : public RefChangeRequest {
public:
ResetColorRequest(util::SimpleIdentity id, Color color)
: DrawableRefChangeRequest(id),
: RefChangeRequest(id),
newColor(color) {}
ResetColorRequest(const ResetColorRequest &other) = default;
void execute(RenderOrchestrator &) override;
void execute(RenderOrchestrator&) override;
protected:
Color newColor;
};
/**
Add a new layer group to the scene
*/
class AddLayerGroupRequest : public ChangeRequest {
public:
AddLayerGroupRequest(UniqueLayerGroup&& layerGroup_, bool canReplace);
AddLayerGroupRequest(AddLayerGroupRequest&& other);
void execute(RenderOrchestrator&) override;
protected:
UniqueLayerGroup layerGroup;
bool replace;
};
/**
Remove a layer group from the scene
*/
class RemoveLayerGroupRequest : public RefChangeRequest {
public:
RemoveLayerGroupRequest(util::SimpleIdentity id)
: RefChangeRequest(id) {}
RemoveLayerGroupRequest(const RemoveLayerGroupRequest &) = default;
void execute(RenderOrchestrator&) override;
};
} // namespace mbgl

View File

@@ -0,0 +1,70 @@
#pragma once
#include <mbgl/renderer/render_pass.hpp>
#include <mbgl/tile/tile_id.hpp>
#include <mbgl/util/identity.hpp>
#include <memory>
#include <vector>
namespace mbgl {
class LayerGroup;
class PaintParameters;
class RenderOrchestrator;
class TileLayerGroup;
using LayerGroupPtr = std::shared_ptr<LayerGroup>;
namespace gfx {
class Context;
class Drawable;
class UploadPass;
using DrawablePtr = std::shared_ptr<Drawable>;
using UniqueDrawable = std::unique_ptr<Drawable>;
} // namespace gfx
/**
A layer-like group of drawables, not a group of layers.
*/
class LayerGroup : public util::SimpleIdentifiable {
protected:
LayerGroup(int32_t layerIndex);
LayerGroup(const LayerGroup&) = delete;
LayerGroup& operator=(const LayerGroup&) = delete;
public:
virtual ~LayerGroup() = default;
int32_t getLayerIndex() const { return layerIndex; }
/// Called before starting each frame
virtual void preRender(RenderOrchestrator&, PaintParameters&) { }
/// Called during the upload pass
virtual void upload(gfx::Context&, gfx::UploadPass&) { }
/// Called during each render pass
virtual void render(RenderOrchestrator&, PaintParameters&) { }
/// Called at the end of each frame
virtual void postRender(RenderOrchestrator&, PaintParameters&) { }
protected:
int32_t layerIndex;
};
/**
A layer group for tile-based drawables
*/
class TileLayerGroup : public LayerGroup {
public:
TileLayerGroup(int32_t layerIndex, std::size_t initialCapacity);
~TileLayerGroup() override;
void render(RenderOrchestrator&, PaintParameters&) override;
protected:
struct Impl;
std::unique_ptr<Impl> impl;
};
} // namespace mbgl

View File

@@ -8,13 +8,29 @@ void AddDrawableRequest::execute(RenderOrchestrator &orchestrator) {
}
void RemoveDrawableRequest::execute(RenderOrchestrator &orchestrator) {
orchestrator.removeDrawable(drawableID);
orchestrator.removeDrawable(id);
}
void ResetColorRequest::execute(RenderOrchestrator &orchestrator) {
if (auto &drawable = orchestrator.getDrawable(drawableID)) {
if (auto &drawable = orchestrator.getDrawable(id)) {
drawable->resetColor(newColor);
}
}
AddLayerGroupRequest::AddLayerGroupRequest(UniqueLayerGroup&& layerGroup_, bool canReplace)
: layerGroup(std::move(layerGroup_)), replace(canReplace) {
}
AddLayerGroupRequest::AddLayerGroupRequest(AddLayerGroupRequest&& other)
: layerGroup(std::move(other.layerGroup)) {
}
void AddLayerGroupRequest::execute(RenderOrchestrator &orchestrator) {
orchestrator.addLayerGroup(std::move(layerGroup), replace);
}
void RemoveLayerGroupRequest::execute(RenderOrchestrator &orchestrator) {
orchestrator.removeLayerGroup(id);
}
} // namespace mbgl

View File

@@ -0,0 +1,55 @@
#include <mbgl/renderer/layer_group.hpp>
#include <mbgl/gfx/upload_pass.hpp>
#include <mbgl/renderer/paint_parameters.hpp>
#include <mbgl/renderer/render_orchestrator.hpp>
#include <unordered_map>
namespace mbgl {
struct TileLayerGroupTileKey {
mbgl::RenderPass renderPass;
OverscaledTileID tileID;
bool operator==(const TileLayerGroupTileKey& other) const {
return renderPass == other.renderPass && tileID == other.tileID;
}
struct hash {
size_t operator()(const mbgl::TileLayerGroupTileKey& k) const {
return (std::hash<mbgl::RenderPass>()(k.renderPass) ^
std::hash<OverscaledTileID>()(k.tileID) << 1);
}
};
};
struct TileLayerGroup::Impl {
Impl(std::size_t capacity) : tileDrawables(capacity) { }
using TileMap = std::unordered_map<TileLayerGroupTileKey, gfx::UniqueDrawable, TileLayerGroupTileKey::hash>;
TileMap tileDrawables;
};
LayerGroup::LayerGroup(int32_t layerIndex_) :
layerIndex(layerIndex_) {
}
TileLayerGroup::TileLayerGroup(int32_t layerIndex_, std::size_t initialCapacity) :
LayerGroup(layerIndex_),
impl(std::make_unique<Impl>(initialCapacity))
{
}
TileLayerGroup::~TileLayerGroup() {
}
void TileLayerGroup::render([[maybe_unused]] RenderOrchestrator& orchestrator, [[maybe_unused]] PaintParameters& parameters) {
auto pass = mbgl::RenderPass::Opaque;
auto id = OverscaledTileID{0,0,0,0,0};
auto key = TileLayerGroupTileKey{pass, id};
impl->tileDrawables.insert(std::make_pair(key, gfx::UniqueDrawable()));
}
} // namespace mbgl

View File

@@ -4,20 +4,21 @@
#include <mbgl/gfx/cull_face_mode.hpp>
#include <mbgl/gfx/shader_registry.hpp>
#include <mbgl/gfx/drawable_builder.hpp>
#include <mbgl/style/layers/background_layer_impl.hpp>
#include <mbgl/style/layer_properties.hpp>
#include <mbgl/map/transform_state.hpp>
#include <mbgl/programs/programs.hpp>
#include <mbgl/renderer/bucket.hpp>
#include <mbgl/renderer/change_request.hpp>
#include <mbgl/renderer/image_manager.hpp>
#include <mbgl/renderer/layer_group.hpp>
#include <mbgl/renderer/paint_parameters.hpp>
#include <mbgl/renderer/pattern_atlas.hpp>
#include <mbgl/renderer/render_pass.hpp>
#include <mbgl/renderer/render_static_data.hpp>
#include <mbgl/renderer/upload_parameters.hpp>
#include <mbgl/programs/programs.hpp>
#include <mbgl/shaders/shader_program_base.hpp>
#include <mbgl/style/layers/background_layer_impl.hpp>
#include <mbgl/style/layer_properties.hpp>
#include <mbgl/util/tile_cover.hpp>
#include <mbgl/map/transform_state.hpp>
#include <mbgl/util/convert.hpp>
#include <mbgl/util/logging.hpp>
@@ -223,6 +224,8 @@ void RenderBackgroundLayer::update(const int32_t layerIndex,
shader = context.getGenericShader(shaders, shaderName);
}
changes.emplace_back(std::make_unique<AddLayerGroupRequest>(std::make_unique<TileLayerGroup>(layerIndex, 10), /*replace*/true));
const auto& evaluated = getEvaluated<BackgroundLayerProperties>(evaluatedProperties);
// TODO: If background is solid, we can skip drawables and rely on the clear color

View File

@@ -776,6 +776,64 @@ const gfx::DrawablePtr& RenderOrchestrator::getDrawable(const util::SimpleIdenti
return (hit != drawables.end()) ? hit->second : noDrawable;
}
void RenderOrchestrator::onRemoveLayerGroup(LayerGroup&) {
}
bool RenderOrchestrator::addLayerGroup(UniqueLayerGroup&& layerGroup, const bool replace) {
const auto index = layerGroup->getLayerIndex();
const auto result = layerGroupsByLayerIndex.insert(std::make_pair(index, UniqueLayerGroup{}));
if (result.second) {
// added
result.first->second = std::move(layerGroup);
return true;
} else {
// not added
if (replace) {
onRemoveLayerGroup(*result.first->second);
result.first->second = std::move(layerGroup);
return true;
} else {
return false;
}
}
}
bool RenderOrchestrator::removeLayerGroup(const int32_t layerIndex) {
const auto hit = layerGroupsByLayerIndex.find(layerIndex);
if (hit != layerGroupsByLayerIndex.end()) {
onRemoveLayerGroup(*hit->second);
layerGroupsByLayerIndex.erase(hit);
return true;
} else {
return false;
}
}
static const UniqueLayerGroup no_group;
const UniqueLayerGroup& RenderOrchestrator::getLayerGroup(const int32_t layerIndex) const {
const auto hit = layerGroupsByLayerIndex.find(layerIndex);
return (hit == layerGroupsByLayerIndex.end()) ? no_group : hit->second;
}
void RenderOrchestrator::observeLayerGroups(std::function<void(LayerGroup&)> f) {
for (auto& pair : layerGroupsByLayerIndex) {
if (pair.second) {
f(*pair.second);
}
}
}
void RenderOrchestrator::observeLayerGroups(std::function<void(const LayerGroup&)> f) const {
for (const auto& pair : layerGroupsByLayerIndex) {
if (pair.second) {
f(*pair.second);
}
}
}
void RenderOrchestrator::updateLayers(gfx::ShaderRegistry& shaders,
gfx::Context& context,
const TransformState& state,

View File

@@ -1,5 +1,6 @@
#pragma once
#include <mbgl/renderer/layer_group.hpp>
#include <mbgl/renderer/renderer.hpp>
#include <mbgl/renderer/render_source_observer.hpp>
#include <mbgl/renderer/render_light.hpp>
@@ -13,6 +14,7 @@
#include <mbgl/renderer/image_manager_observer.hpp>
#include <mbgl/text/placement.hpp>
#include <map>
#include <memory>
#include <string>
#include <unordered_map>
@@ -101,6 +103,12 @@ public:
const gfx::DrawablePtr& getDrawable(const util::SimpleIdentity&);
bool addLayerGroup(UniqueLayerGroup&&, bool replace);
bool removeLayerGroup(const int32_t layerIndex);
const UniqueLayerGroup& getLayerGroup(const int32_t layerIndex) const;
void observeLayerGroups(std::function<void(LayerGroup&)>);
void observeLayerGroups(std::function<void(const LayerGroup&)>) const;
void updateLayers(gfx::ShaderRegistry&,
gfx::Context&,
const TransformState&,
@@ -142,6 +150,8 @@ private:
/// Move changes into the pending set, clearing the provided collection
void addChanges(UniqueChangeRequestVec&);
void onRemoveLayerGroup(LayerGroup&);
RendererObserver* observer;
ZoomHistory zoomHistory;
@@ -173,9 +183,12 @@ private:
RenderLayerReferences orderedLayers;
RenderLayerReferences layersNeedPlacement;
protected:
DrawableMap drawables;
std::vector<std::unique_ptr<ChangeRequest>> pendingChanges;
using LayerGroupMap = std::map<int32_t, UniqueLayerGroup>;
LayerGroupMap layerGroupsByLayerIndex;
};
} // namespace mbgl

View File

@@ -103,6 +103,11 @@ void Renderer::Impl::render(const RenderTree& renderTree) {
}
}
// Give the layers a chance to do setup
orchestrator.observeLayerGroups([&](LayerGroup& layerGroup){
layerGroup.preRender(orchestrator, parameters);
});
// Sort the drawables
std::sort(drawables.begin(), drawables.end(), gfx::DrawablePtrLessByLayer(/*descending=*/true));
@@ -155,6 +160,11 @@ void Renderer::Impl::render(const RenderTree& renderTree) {
drawableGL.setVertexArray(std::move(vertexArray), std::move(vertexBuffer), std::move(indexBuffer));
}
}
// Give the layers a chance to upload
orchestrator.observeLayerGroups([&](LayerGroup& layerGroup){
layerGroup.upload(context, *uploadPass);
});
}
// - 3D PASS
@@ -243,6 +253,11 @@ void Renderer::Impl::render(const RenderTree& renderTree) {
}
};
// draw layer groups, opaque pass
orchestrator.observeLayerGroups([&](LayerGroup& layerGroup){
layerGroup.render(orchestrator, parameters);
});
parameters.pass = RenderPass::Opaque;
parameters.currentLayer = 0;
parameters.opaquePassCutoff = 1;
@@ -276,6 +291,11 @@ void Renderer::Impl::render(const RenderTree& renderTree) {
parameters.opaquePassCutoff = 1;
drawDrawables(parameters.pass);
// draw layer groups, translucent pass
orchestrator.observeLayerGroups([&](LayerGroup& layerGroup){
layerGroup.render(orchestrator, parameters);
});
parameters.opaquePassCutoff = renderTreeParameters.opaquePassCutOff;
// - TRANSLUCENT PASS --------------------------------------------------------------------------
@@ -318,6 +338,11 @@ void Renderer::Impl::render(const RenderTree& renderTree) {
}
#endif
// Give the layers a chance to do cleanup
orchestrator.observeLayerGroups([&](LayerGroup& layerGroup){
layerGroup.postRender(orchestrator, parameters);
});
// Ends the RenderPass
parameters.renderPass.reset();
const bool isMapModeContinuous = renderTreeParameters.mapMode == MapMode::Continuous;