diff options
Diffstat (limited to 'src/mbgl/gl')
-rw-r--r-- | src/mbgl/gl/custom_layer.cpp | 59 | ||||
-rw-r--r-- | src/mbgl/gl/custom_layer_factory.cpp | 21 | ||||
-rw-r--r-- | src/mbgl/gl/custom_layer_impl.cpp | 20 | ||||
-rw-r--r-- | src/mbgl/gl/custom_layer_impl.hpp | 35 | ||||
-rw-r--r-- | src/mbgl/gl/render_custom_layer.cpp | 104 | ||||
-rw-r--r-- | src/mbgl/gl/render_custom_layer.hpp | 27 |
6 files changed, 266 insertions, 0 deletions
diff --git a/src/mbgl/gl/custom_layer.cpp b/src/mbgl/gl/custom_layer.cpp new file mode 100644 index 0000000000..456467e904 --- /dev/null +++ b/src/mbgl/gl/custom_layer.cpp @@ -0,0 +1,59 @@ +#include <mbgl/gl/custom_layer.hpp> +#include <mbgl/gl/custom_layer_impl.hpp> +#include <mbgl/gl/render_custom_layer.hpp> +#include <mbgl/style/layer_observer.hpp> + +namespace mbgl { +namespace style { + +namespace { +const LayerTypeInfo typeInfoCustom{"", + LayerTypeInfo::Source::NotRequired, + LayerTypeInfo::Pass3D::NotRequired, + LayerTypeInfo::Layout::NotRequired, + LayerTypeInfo::FadingTiles::NotRequired, + LayerTypeInfo::CrossTileIndex::NotRequired, + LayerTypeInfo::TileKind::NotRequired}; +} // namespace + +CustomLayer::CustomLayer(const std::string& layerID, + std::unique_ptr<CustomLayerHost> host) + : Layer(makeMutable<Impl>(layerID, std::move(host))) { +} + +CustomLayer::~CustomLayer() = default; + +const CustomLayer::Impl& CustomLayer::impl() const { + return static_cast<const Impl&>(*baseImpl); +} + +Mutable<CustomLayer::Impl> CustomLayer::mutableImpl() const { + return makeMutable<Impl>(impl()); +} + +std::unique_ptr<Layer> CustomLayer::cloneRef(const std::string&) const { + assert(false); + return nullptr; +} + +using namespace conversion; + +optional<Error> CustomLayer::setProperty(const std::string&, const Convertible&) { + return Error { "layer doesn't support this property" }; +} + +StyleProperty CustomLayer::getProperty(const std::string&) const { + return {}; +} + +Mutable<Layer::Impl> CustomLayer::mutableBaseImpl() const { + return staticMutableCast<Layer::Impl>(mutableImpl()); +} + +// static +const LayerTypeInfo* CustomLayer::Impl::staticTypeInfo() noexcept { + return &typeInfoCustom; +} + +} // namespace style +} // namespace mbgl diff --git a/src/mbgl/gl/custom_layer_factory.cpp b/src/mbgl/gl/custom_layer_factory.cpp new file mode 100644 index 0000000000..616d0271e0 --- /dev/null +++ b/src/mbgl/gl/custom_layer_factory.cpp @@ -0,0 +1,21 @@ +#include <mbgl/gl/custom_layer.hpp> +#include <mbgl/gl/custom_layer_factory.hpp> +#include <mbgl/gl/custom_layer_impl.hpp> +#include <mbgl/gl/render_custom_layer.hpp> + +namespace mbgl { + +const style::LayerTypeInfo* CustomLayerFactory::getTypeInfo() const noexcept { + return style::CustomLayer::Impl::staticTypeInfo(); +} + +std::unique_ptr<style::Layer> CustomLayerFactory::createLayer(const std::string&, const style::conversion::Convertible&) noexcept { + assert(false); + return nullptr; +} + +std::unique_ptr<RenderLayer> CustomLayerFactory::createRenderLayer(Immutable<style::Layer::Impl> impl) noexcept { + return std::make_unique<RenderCustomLayer>(staticImmutableCast<style::CustomLayer::Impl>(impl)); +} + +} // namespace mbgl diff --git a/src/mbgl/gl/custom_layer_impl.cpp b/src/mbgl/gl/custom_layer_impl.cpp new file mode 100644 index 0000000000..85df44bc80 --- /dev/null +++ b/src/mbgl/gl/custom_layer_impl.cpp @@ -0,0 +1,20 @@ +#include <mbgl/gl/custom_layer_impl.hpp> + +namespace mbgl { +namespace style { + +CustomLayer::Impl::Impl(const std::string& id_, + std::unique_ptr<CustomLayerHost> host_) + : Layer::Impl(id_, std::string()) { + host = std::move(host_); +} + +bool CustomLayer::Impl::hasLayoutDifference(const Layer::Impl&) const { + return false; +} + +void CustomLayer::Impl::stringifyLayout(rapidjson::Writer<rapidjson::StringBuffer>&) const { +} + +} // namespace style +} // namespace mbgl diff --git a/src/mbgl/gl/custom_layer_impl.hpp b/src/mbgl/gl/custom_layer_impl.hpp new file mode 100644 index 0000000000..0c9339adf1 --- /dev/null +++ b/src/mbgl/gl/custom_layer_impl.hpp @@ -0,0 +1,35 @@ +#pragma once + +#include <mbgl/gl/custom_layer.hpp> +#include <mbgl/style/layer_impl.hpp> +#include <mbgl/style/layer_properties.hpp> + +#include <memory> + +namespace mbgl { + +class TransformState; + +namespace style { + +class CustomLayer::Impl : public Layer::Impl { +public: + Impl(const std::string& id, + std::unique_ptr<CustomLayerHost> host); + + bool hasLayoutDifference(const Layer::Impl&) const override; + void stringifyLayout(rapidjson::Writer<rapidjson::StringBuffer>&) const override; + + std::shared_ptr<CustomLayerHost> host; + + DECLARE_LAYER_TYPE_INFO; +}; + +class CustomLayerProperties final : public LayerProperties { +public: + explicit CustomLayerProperties(Immutable<CustomLayer::Impl> impl) + : LayerProperties(std::move(impl)) {} +}; + +} // namespace style +} // namespace mbgl diff --git a/src/mbgl/gl/render_custom_layer.cpp b/src/mbgl/gl/render_custom_layer.cpp new file mode 100644 index 0000000000..bb12ec1fcf --- /dev/null +++ b/src/mbgl/gl/render_custom_layer.cpp @@ -0,0 +1,104 @@ +#include <mbgl/gfx/backend_scope.hpp> +#include <mbgl/gfx/renderer_backend.hpp> +#include <mbgl/gl/context.hpp> +#include <mbgl/gl/custom_layer_impl.hpp> +#include <mbgl/gl/render_custom_layer.hpp> +#include <mbgl/gl/renderable_resource.hpp> +#include <mbgl/map/transform_state.hpp> +#include <mbgl/platform/gl_functions.hpp> +#include <mbgl/renderer/bucket.hpp> +#include <mbgl/renderer/paint_parameters.hpp> +#include <mbgl/util/mat4.hpp> + +namespace mbgl { + +using namespace style; + +namespace { + +inline const CustomLayer::Impl& impl(const Immutable<style::Layer::Impl>& impl) { + assert(impl->getTypeInfo() == CustomLayer::Impl::staticTypeInfo()); + return static_cast<const CustomLayer::Impl&>(*impl); +} + +} // namespace + +RenderCustomLayer::RenderCustomLayer(Immutable<style::CustomLayer::Impl> _impl) + : RenderLayer(makeMutable<CustomLayerProperties>(std::move(_impl))), + host(impl(baseImpl).host) { + assert(gfx::BackendScope::exists()); + MBGL_CHECK_ERROR(host->initialize()); +} + +RenderCustomLayer::~RenderCustomLayer() { + assert(gfx::BackendScope::exists()); + if (contextDestroyed) { + host->contextLost(); + } else { + MBGL_CHECK_ERROR(host->deinitialize()); + } +} + +void RenderCustomLayer::evaluate(const PropertyEvaluationParameters&) { + passes = RenderPass::Translucent; + // It is fine to not update `evaluatedProperties`, as `baseImpl` should never be updated for this layer. +} + +bool RenderCustomLayer::hasTransition() const { + return false; +} +bool RenderCustomLayer::hasCrossfade() const { + return false; +} + +void RenderCustomLayer::markContextDestroyed() { + contextDestroyed = true; +} + +void RenderCustomLayer::prepare(const LayerPrepareParameters&) { +} + +void RenderCustomLayer::render(PaintParameters& paintParameters) { + if (host != impl(baseImpl).host) { + //If the context changed, deinitialize the previous one before initializing the new one. + if (host && !contextDestroyed) { + MBGL_CHECK_ERROR(host->deinitialize()); + } + host = impl(baseImpl).host; + MBGL_CHECK_ERROR(host->initialize()); + } + + // TODO: remove cast + auto& glContext = static_cast<gl::Context&>(paintParameters.context); + const TransformState& state = paintParameters.state; + + // Reset GL state to a known state so the CustomLayer always has a clean slate. + glContext.bindVertexArray = 0; + glContext.setDepthMode(paintParameters.depthModeForSublayer(0, gfx::DepthMaskType::ReadOnly)); + glContext.setStencilMode(gfx::StencilMode::disabled()); + glContext.setColorMode(paintParameters.colorModeForRenderPass()); + glContext.setCullFaceMode(gfx::CullFaceMode::disabled()); + + CustomLayerRenderParameters parameters; + + parameters.width = state.getSize().width; + parameters.height = state.getSize().height; + parameters.latitude = state.getLatLng().latitude(); + parameters.longitude = state.getLatLng().longitude(); + parameters.zoom = state.getZoom(); + parameters.bearing = -state.getBearing() * util::RAD2DEG; + parameters.pitch = state.getPitch(); + parameters.fieldOfView = state.getFieldOfView(); + mat4 projMatrix; + state.getProjMatrix(projMatrix); + parameters.projectionMatrix = projMatrix; + + MBGL_CHECK_ERROR(host->render(parameters)); + + // Reset the view back to our original one, just in case the CustomLayer changed + // the viewport or Framebuffer. + paintParameters.backend.getDefaultRenderable().getResource<gl::RenderableResource>().bind(); + glContext.setDirtyState(); +} + +} // namespace mbgl diff --git a/src/mbgl/gl/render_custom_layer.hpp b/src/mbgl/gl/render_custom_layer.hpp new file mode 100644 index 0000000000..2f5ae28209 --- /dev/null +++ b/src/mbgl/gl/render_custom_layer.hpp @@ -0,0 +1,27 @@ +#pragma once + +#include <mbgl/gl/custom_layer_impl.hpp> +#include <mbgl/renderer/render_layer.hpp> + +namespace mbgl { + +class RenderCustomLayer final : public RenderLayer { +public: + explicit RenderCustomLayer(Immutable<style::CustomLayer::Impl>); + ~RenderCustomLayer() override; + +private: + void transition(const TransitionParameters&) override {} + void evaluate(const PropertyEvaluationParameters&) override; + bool hasTransition() const override; + bool hasCrossfade() const override; + void markContextDestroyed() override; + void prepare(const LayerPrepareParameters&) override; + + void render(PaintParameters&) override; + + bool contextDestroyed = false; + std::shared_ptr<style::CustomLayerHost> host; +}; + +} // namespace mbgl |