summaryrefslogtreecommitdiff
path: root/platform/default/mbgl
diff options
context:
space:
mode:
Diffstat (limited to 'platform/default/mbgl')
-rw-r--r--platform/default/mbgl/gl/headless_backend.cpp72
-rw-r--r--platform/default/mbgl/gl/headless_backend.hpp57
-rw-r--r--platform/default/mbgl/gl/headless_display.cpp15
-rw-r--r--platform/default/mbgl/gl/headless_display.hpp20
-rw-r--r--platform/default/mbgl/gl/offscreen_view.cpp30
-rw-r--r--platform/default/mbgl/gl/offscreen_view.hpp33
6 files changed, 227 insertions, 0 deletions
diff --git a/platform/default/mbgl/gl/headless_backend.cpp b/platform/default/mbgl/gl/headless_backend.cpp
new file mode 100644
index 0000000000..0bfdf11c98
--- /dev/null
+++ b/platform/default/mbgl/gl/headless_backend.cpp
@@ -0,0 +1,72 @@
+#include <mbgl/gl/headless_backend.hpp>
+#include <mbgl/gl/headless_display.hpp>
+
+#include <cassert>
+#include <stdexcept>
+#include <type_traits>
+
+namespace mbgl {
+
+HeadlessBackend::HeadlessBackend() {
+ activate();
+}
+
+HeadlessBackend::HeadlessBackend(std::shared_ptr<HeadlessDisplay> display_)
+ : display(std::move(display_)) {
+ activate();
+}
+
+HeadlessBackend::~HeadlessBackend() {
+ deactivate();
+ destroyContext();
+}
+
+void HeadlessBackend::activate() {
+ active = true;
+
+ if (!hasContext()) {
+ if (!hasDisplay()) {
+ throw std::runtime_error("Display is not set");
+ }
+ createContext();
+ }
+
+ activateContext();
+
+ if (!extensionsLoaded) {
+ gl::InitializeExtensions(initializeExtension);
+ extensionsLoaded = true;
+ }
+}
+
+void HeadlessBackend::deactivate() {
+ deactivateContext();
+ active = false;
+}
+
+void HeadlessBackend::invalidate() {
+ assert(false);
+}
+
+void HeadlessBackend::destroyContext() {
+ assert(hasContext());
+ impl.reset();
+}
+
+void HeadlessBackend::activateContext() {
+ assert(hasContext());
+ impl->activateContext();
+}
+
+void HeadlessBackend::deactivateContext() {
+ assert(hasContext());
+ impl->deactivateContext();
+}
+
+void HeadlessBackend::notifyMapChange(MapChange change) {
+ if (mapChangeCallback) {
+ mapChangeCallback(change);
+ }
+}
+
+} // namespace mbgl
diff --git a/platform/default/mbgl/gl/headless_backend.hpp b/platform/default/mbgl/gl/headless_backend.hpp
new file mode 100644
index 0000000000..da8c55e044
--- /dev/null
+++ b/platform/default/mbgl/gl/headless_backend.hpp
@@ -0,0 +1,57 @@
+#pragma once
+
+#include <mbgl/gl/extension.hpp>
+
+#include <mbgl/map/backend.hpp>
+
+#include <memory>
+#include <functional>
+
+namespace mbgl {
+
+class HeadlessDisplay;
+
+class HeadlessBackend : public Backend {
+public:
+ HeadlessBackend();
+ HeadlessBackend(std::shared_ptr<HeadlessDisplay>);
+ ~HeadlessBackend() override;
+
+ void invalidate() override;
+ void activate() override;
+ void deactivate() override;
+ void notifyMapChange(MapChange) override;
+
+ void setMapChangeCallback(std::function<void(MapChange)>&& cb) { mapChangeCallback = std::move(cb); }
+
+ struct Impl {
+ virtual ~Impl() {}
+ virtual void activateContext() = 0;
+ virtual void deactivateContext() {}
+ };
+
+private:
+ // Implementation specific functions
+ static gl::glProc initializeExtension(const char*);
+
+ bool hasContext() const { return bool(impl); }
+ bool hasDisplay();
+
+ void createContext();
+
+private:
+ void destroyContext();
+
+ void activateContext();
+ void deactivateContext();
+
+ std::unique_ptr<Impl> impl;
+ std::shared_ptr<HeadlessDisplay> display;
+
+ bool extensionsLoaded = false;
+ bool active = false;
+
+ std::function<void(MapChange)> mapChangeCallback;
+};
+
+} // namespace mbgl
diff --git a/platform/default/mbgl/gl/headless_display.cpp b/platform/default/mbgl/gl/headless_display.cpp
new file mode 100644
index 0000000000..6247046c29
--- /dev/null
+++ b/platform/default/mbgl/gl/headless_display.cpp
@@ -0,0 +1,15 @@
+#include <mbgl/gl/headless_display.hpp>
+
+namespace mbgl {
+
+class HeadlessDisplay::Impl {};
+
+HeadlessDisplay::HeadlessDisplay() {
+ // no-op
+}
+
+HeadlessDisplay::~HeadlessDisplay() {
+ // no-op
+}
+
+} // namespace mbgl
diff --git a/platform/default/mbgl/gl/headless_display.hpp b/platform/default/mbgl/gl/headless_display.hpp
new file mode 100644
index 0000000000..a5c95085b8
--- /dev/null
+++ b/platform/default/mbgl/gl/headless_display.hpp
@@ -0,0 +1,20 @@
+#pragma once
+
+#include <memory>
+
+namespace mbgl {
+
+class HeadlessDisplay {
+public:
+ HeadlessDisplay();
+ ~HeadlessDisplay();
+
+ template <typename DisplayAttribute>
+ DisplayAttribute attribute() const;
+
+private:
+ class Impl;
+ std::unique_ptr<Impl> impl;
+};
+
+} // namespace mbgl
diff --git a/platform/default/mbgl/gl/offscreen_view.cpp b/platform/default/mbgl/gl/offscreen_view.cpp
new file mode 100644
index 0000000000..16faf6a4a9
--- /dev/null
+++ b/platform/default/mbgl/gl/offscreen_view.cpp
@@ -0,0 +1,30 @@
+#include <mbgl/gl/offscreen_view.hpp>
+#include <mbgl/gl/context.hpp>
+
+#include <cstring>
+#include <cassert>
+
+namespace mbgl {
+
+OffscreenView::OffscreenView(gl::Context& context_, const Size size_)
+ : size(std::move(size_)), context(context_) {
+ assert(size);
+}
+
+void OffscreenView::bind() {
+ if (!framebuffer) {
+ color = context.createRenderbuffer<gl::RenderbufferType::RGBA>(size);
+ depthStencil = context.createRenderbuffer<gl::RenderbufferType::DepthStencil>(size);
+ framebuffer = context.createFramebuffer(*color, *depthStencil);
+ } else {
+ context.bindFramebuffer = framebuffer->framebuffer;
+ }
+
+ context.viewport = { 0, 0, size };
+}
+
+PremultipliedImage OffscreenView::readStillImage() {
+ return context.readFramebuffer<PremultipliedImage>(size);
+}
+
+} // namespace mbgl
diff --git a/platform/default/mbgl/gl/offscreen_view.hpp b/platform/default/mbgl/gl/offscreen_view.hpp
new file mode 100644
index 0000000000..0e839e14cc
--- /dev/null
+++ b/platform/default/mbgl/gl/offscreen_view.hpp
@@ -0,0 +1,33 @@
+#pragma once
+
+#include <mbgl/map/view.hpp>
+#include <mbgl/gl/framebuffer.hpp>
+#include <mbgl/gl/renderbuffer.hpp>
+#include <mbgl/util/optional.hpp>
+#include <mbgl/util/image.hpp>
+
+namespace mbgl {
+
+namespace gl {
+class Context;
+} // namespace gl
+
+class OffscreenView : public View {
+public:
+ OffscreenView(gl::Context&, Size size = { 256, 256 });
+
+ void bind() override;
+
+ PremultipliedImage readStillImage();
+
+public:
+ const Size size;
+
+private:
+ gl::Context& context;
+ optional<gl::Framebuffer> framebuffer;
+ optional<gl::Renderbuffer<gl::RenderbufferType::RGBA>> color;
+ optional<gl::Renderbuffer<gl::RenderbufferType::DepthStencil>> depthStencil;
+};
+
+} // namespace mbgl