Drawable Renderer (#1570), first cut at layer groups
This commit is contained in:
committed by
Bart Louwers
parent
d8ea91de98
commit
af39aca061
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
70
include/mbgl/renderer/layer_group.hpp
Normal file
70
include/mbgl/renderer/layer_group.hpp
Normal 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
|
||||
@@ -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
|
||||
|
||||
55
src/mbgl/renderer/layer_group.cpp
Normal file
55
src/mbgl/renderer/layer_group.cpp
Normal 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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user