summaryrefslogtreecommitdiff
path: root/src/mbgl/gl
diff options
context:
space:
mode:
Diffstat (limited to 'src/mbgl/gl')
-rw-r--r--src/mbgl/gl/custom_layer.cpp59
-rw-r--r--src/mbgl/gl/custom_layer_factory.cpp21
-rw-r--r--src/mbgl/gl/custom_layer_impl.cpp20
-rw-r--r--src/mbgl/gl/custom_layer_impl.hpp35
-rw-r--r--src/mbgl/gl/render_custom_layer.cpp104
-rw-r--r--src/mbgl/gl/render_custom_layer.hpp27
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