summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKonstantin Käfer <mail@kkaefer.com>2016-10-06 13:23:50 +0200
committerKonstantin Käfer <mail@kkaefer.com>2016-10-25 13:52:36 -0700
commit5cc390d694fc7510d445310d8eb9e32429a5e67b (patch)
tree7a24706f919ac3e8154be8b4ce33aed5bf42188d
parent45f4dc0166f2d609d014d2174209fdbe1994c943 (diff)
downloadqtlocation-mapboxgl-5cc390d694fc7510d445310d8eb9e32429a5e67b.tar.gz
[core] separate Backend from View for headless rendering
-rw-r--r--benchmark/api/query.benchmark.cpp8
-rw-r--r--bin/glfw.cpp8
-rw-r--r--bin/render.cpp5
-rw-r--r--cmake/core-files.cmake4
-rw-r--r--include/mbgl/gl/implementation.hpp14
-rw-r--r--include/mbgl/map/backend.hpp34
-rw-r--r--include/mbgl/map/map.hpp7
-rw-r--r--include/mbgl/map/view.hpp39
-rw-r--r--include/mbgl/platform/default/glfw_view.hpp34
-rw-r--r--include/mbgl/platform/default/headless_backend.hpp78
-rw-r--r--include/mbgl/platform/default/headless_display.hpp9
-rw-r--r--include/mbgl/platform/default/headless_view.hpp74
-rwxr-xr-xplatform/android/src/native_map_view.cpp12
-rwxr-xr-xplatform/android/src/native_map_view.hpp7
-rw-r--r--platform/darwin/src/headless_backend_cgl.cpp58
-rw-r--r--platform/darwin/src/headless_backend_eagl.mm46
-rw-r--r--platform/darwin/src/headless_view_cgl.cpp51
-rw-r--r--platform/darwin/src/headless_view_eagl.cpp (renamed from platform/darwin/src/headless_view_eagl.mm)43
-rw-r--r--platform/default/glfw_view.cpp4
-rw-r--r--platform/default/headless_backend.cpp56
-rw-r--r--platform/default/headless_backend_glx.cpp67
-rw-r--r--platform/default/headless_display.cpp7
-rw-r--r--platform/default/headless_view.cpp72
-rw-r--r--platform/default/headless_view_glx.cpp64
-rw-r--r--platform/ios/config.cmake6
-rw-r--r--platform/ios/src/MGLMapView.mm22
-rw-r--r--platform/linux/config.cmake4
-rw-r--r--platform/macos/config.cmake2
-rw-r--r--platform/macos/src/MGLMapView.mm29
-rw-r--r--platform/node/src/node_map.cpp7
-rw-r--r--platform/node/src/node_map.hpp2
-rw-r--r--platform/qt/config.cmake2
-rw-r--r--platform/qt/src/qmapboxgl.cpp7
-rw-r--r--platform/qt/src/qmapboxgl_p.hpp6
-rw-r--r--platform/qt/test/headless_backend_qt.cpp46
-rw-r--r--platform/qt/test/headless_view_qt.cpp38
-rw-r--r--src/mbgl/map/backend.cpp12
-rw-r--r--src/mbgl/map/map.cpp89
-rw-r--r--src/mbgl/map/view.cpp11
-rw-r--r--src/mbgl/renderer/paint_parameters.hpp2
-rw-r--r--src/mbgl/renderer/painter.cpp25
-rw-r--r--src/mbgl/renderer/painter.hpp7
-rw-r--r--src/mbgl/renderer/painter_debug.cpp14
-rw-r--r--src/mbgl/renderer/painter_fill.cpp3
-rw-r--r--test/api/annotations.test.cpp8
-rw-r--r--test/api/api_misuse.test.cpp16
-rw-r--r--test/api/custom_layer.test.cpp8
-rw-r--r--test/api/query.test.cpp8
-rw-r--r--test/api/render_missing.test.cpp8
-rw-r--r--test/api/repeated_render.test.cpp9
-rw-r--r--test/gl/object.test.cpp8
-rw-r--r--test/map/map.test.cpp62
-rw-r--r--test/util/memory.test.cpp21
-rw-r--r--test/util/offscreen_texture.test.cpp11
54 files changed, 774 insertions, 520 deletions
diff --git a/benchmark/api/query.benchmark.cpp b/benchmark/api/query.benchmark.cpp
index a9c4ade2da..5fa6a84db7 100644
--- a/benchmark/api/query.benchmark.cpp
+++ b/benchmark/api/query.benchmark.cpp
@@ -2,7 +2,7 @@
#include <mbgl/benchmark/util.hpp>
#include <mbgl/map/map.hpp>
-#include <mbgl/platform/default/headless_display.hpp>
+#include <mbgl/platform/default/headless_backend.hpp>
#include <mbgl/platform/default/headless_view.hpp>
#include <mbgl/platform/default/thread_pool.hpp>
#include <mbgl/sprite/sprite_image.hpp>
@@ -35,11 +35,11 @@ public:
}
util::RunLoop loop;
- std::shared_ptr<HeadlessDisplay> display{ std::make_shared<HeadlessDisplay>() };
- HeadlessView view{ display, 1 };
+ HeadlessBackend backend;
+ HeadlessView view;
DefaultFileSource fileSource{ "benchmark/fixtures/api/cache.db", "." };
ThreadPool threadPool{ 4 };
- Map map{ view, fileSource, threadPool, MapMode::Still };
+ Map map{ backend, view, view.getPixelRatio(), fileSource, threadPool, MapMode::Still };
ScreenBox box{{ 0, 0 }, { 1000, 1000 }};
};
diff --git a/bin/glfw.cpp b/bin/glfw.cpp
index c0d61820f8..44713d7532 100644
--- a/bin/glfw.cpp
+++ b/bin/glfw.cpp
@@ -16,7 +16,7 @@
namespace {
-std::unique_ptr<GLFWView> view;
+GLFWView* view = nullptr;
}
@@ -104,7 +104,8 @@ int main(int argc, char *argv[]) {
mbgl::Log::Info(mbgl::Event::General, "BENCHMARK MODE: Some optimizations are disabled.");
}
- view = std::make_unique<GLFWView>(fullscreen, benchmark);
+ GLFWView backend(fullscreen, benchmark);
+ view = &backend;
mbgl::DefaultFileSource fileSource("/tmp/mbgl-cache.db", ".");
@@ -118,7 +119,7 @@ int main(int argc, char *argv[]) {
mbgl::ThreadPool threadPool(4);
- mbgl::Map map(*view, fileSource, threadPool);
+ mbgl::Map map(backend, backend, backend.getPixelRatio(), fileSource, threadPool);
// Load settings
mbgl::Settings_JSON settings;
@@ -181,5 +182,6 @@ int main(int argc, char *argv[]) {
"Exit location: --lat=\"%f\" --lon=\"%f\" --zoom=\"%f\" --bearing \"%f\"",
settings.latitude, settings.longitude, settings.zoom, settings.bearing);
+ view = nullptr;
return 0;
}
diff --git a/bin/render.cpp b/bin/render.cpp
index e4d9951c05..f9574d0523 100644
--- a/bin/render.cpp
+++ b/bin/render.cpp
@@ -3,7 +3,7 @@
#include <mbgl/util/io.hpp>
#include <mbgl/util/run_loop.hpp>
-#include <mbgl/platform/default/headless_display.hpp>
+#include <mbgl/platform/default/headless_backend.hpp>
#include <mbgl/platform/default/headless_view.hpp>
#include <mbgl/platform/default/thread_pool.hpp>
#include <mbgl/storage/default_file_source.hpp>
@@ -84,9 +84,10 @@ int main(int argc, char *argv[]) {
fileSource.setAccessToken(std::string(token));
}
+ HeadlessBackend backend;
HeadlessView view(pixelRatio, width, height);
ThreadPool threadPool(4);
- Map map(view, fileSource, threadPool, MapMode::Still);
+ Map map(backend, view, view.getPixelRatio(), fileSource, threadPool, MapMode::Still);
map.setStyleJSON(style);
map.setClasses(classes);
diff --git a/cmake/core-files.cmake b/cmake/core-files.cmake
index fac5490bb4..255d40fa50 100644
--- a/cmake/core-files.cmake
+++ b/cmake/core-files.cmake
@@ -54,6 +54,7 @@ set(MBGL_CORE_FILES
# gl
include/mbgl/gl/gl.hpp
+ include/mbgl/gl/implementation.hpp
src/mbgl/gl/attribute.hpp
src/mbgl/gl/context.cpp
src/mbgl/gl/context.hpp
@@ -92,11 +93,13 @@ set(MBGL_CORE_FILES
src/mbgl/layout/symbol_layout.hpp
# map
+ include/mbgl/map/backend.hpp
include/mbgl/map/camera.hpp
include/mbgl/map/map.hpp
include/mbgl/map/mode.hpp
include/mbgl/map/update.hpp
include/mbgl/map/view.hpp
+ src/mbgl/map/backend.cpp
src/mbgl/map/change.hpp
src/mbgl/map/map.cpp
src/mbgl/map/transform.cpp
@@ -130,6 +133,7 @@ set(MBGL_CORE_FILES
# platform/default
include/mbgl/platform/default/glfw_view.hpp
+ include/mbgl/platform/default/headless_backend.hpp
include/mbgl/platform/default/headless_display.hpp
include/mbgl/platform/default/headless_view.hpp
include/mbgl/platform/default/settings_json.hpp
diff --git a/include/mbgl/gl/implementation.hpp b/include/mbgl/gl/implementation.hpp
new file mode 100644
index 0000000000..4e3a3e51c7
--- /dev/null
+++ b/include/mbgl/gl/implementation.hpp
@@ -0,0 +1,14 @@
+#pragma once
+
+#if defined(__QT__)
+ #define MBGL_USE_QT 1
+#elif defined(__APPLE__)
+ #include <TargetConditionals.h>
+ #if TARGET_OS_IOS
+ #define MBGL_USE_EAGL 1
+ #else
+ #define MBGL_USE_CGL 1
+ #endif
+#else
+ #define MBGL_USE_GLX 1
+#endif
diff --git a/include/mbgl/map/backend.hpp b/include/mbgl/map/backend.hpp
new file mode 100644
index 0000000000..e4a5634b88
--- /dev/null
+++ b/include/mbgl/map/backend.hpp
@@ -0,0 +1,34 @@
+#pragma once
+
+#include <mbgl/map/change.hpp>
+
+namespace mbgl {
+
+class Map;
+
+class Backend {
+public:
+ virtual ~Backend() = default;
+
+ // Called when the backend's GL context needs to be made active or inactive. These are called,
+ // as a matched pair, in four situations:
+ //
+ // 1. When releasing GL resources during Map destruction
+ // 2. When calling a CustomLayerInitializeFunction, during Map::addLayer
+ // 3. When calling a CustomLayerDeinitializeFunction, during Map::removeLayer
+ // 4. When rendering for Map::renderStill
+ //
+ // They are *not* called for Map::render; it is assumed that the correct context is already
+ // activated prior to calling Map::render.
+ virtual void activate() = 0;
+ virtual void deactivate() = 0;
+
+ // Called when the map needs to be rendered; the backend should call Map::render() at some point
+ // in the near future. (Not called for Map::renderStill() mode.)
+ virtual void invalidate() = 0;
+
+ // Notifies a watcher of map x/y/scale/rotation changes.
+ virtual void notifyMapChange(MapChange change);
+};
+
+} // namespace mbgl
diff --git a/include/mbgl/map/map.hpp b/include/mbgl/map/map.hpp
index 2831206d54..4f6207fc6f 100644
--- a/include/mbgl/map/map.hpp
+++ b/include/mbgl/map/map.hpp
@@ -19,6 +19,7 @@
namespace mbgl {
+class Backend;
class View;
class FileSource;
class Scheduler;
@@ -33,7 +34,11 @@ class Layer;
class Map : private util::noncopyable {
public:
- explicit Map(View&, FileSource&, Scheduler&,
+ explicit Map(Backend&,
+ View&,
+ float pixelRatio,
+ FileSource&,
+ Scheduler&,
MapMode mapMode = MapMode::Continuous,
GLContextMode contextMode = GLContextMode::Unique,
ConstrainMode constrainMode = ConstrainMode::HeightOnly,
diff --git a/include/mbgl/map/view.hpp b/include/mbgl/map/view.hpp
index 590eef7237..0dff4b3602 100644
--- a/include/mbgl/map/view.hpp
+++ b/include/mbgl/map/view.hpp
@@ -1,24 +1,23 @@
#pragma once
-#include <mbgl/map/change.hpp>
-#include <mbgl/util/chrono.hpp>
#include <mbgl/util/image.hpp>
#include <array>
-#include <functional>
-#include <memory>
namespace mbgl {
class Map;
-class View {
+class View : private util::noncopyable {
public:
virtual ~View() = default;
- // Called directly after initialization. Must always return the same value, i.e. it may
- // not change over time.
- virtual float getPixelRatio() const = 0;
+ // Called when this View is associated with a Map object.
+ virtual void initialize(Map*);
+
+ // Called when this View is used for rendering. Implementations should ensure that a renderable
+ // object is bound and glClear/glDraw* calls can be done.
+ virtual void bind() = 0;
// Called when the View signaled a dimension change. Must return the logical dimension
// of this map in pixels.
@@ -30,34 +29,12 @@ public:
// different from that rule.
virtual std::array<uint16_t, 2> getFramebufferSize() const = 0;
- // Called when this View is associated with a Map object.
- virtual void initialize(Map*);
-
- // Called when the view's GL context needs to be made active or inactive. These are called,
- // as a matched pair, in four situations:
- //
- // 1. When releasing GL resources during Map destruction
- // 2. When calling a CustomLayerInitializeFunction, during Map::addLayer
- // 3. When calling a CustomLayerDeinitializeFunction, during Map::removeLayer
- // 4. When rendering for Map::renderStill
- //
- // They are *not* called for Map::render; it is assumed that the correct context is already
- // activated prior to calling Map::render.
- virtual void activate() = 0;
- virtual void deactivate() = 0;
-
- // Called when the map needs to be rendered; the view should call Map::render() at some point
- // in the near future. (Not called for Map::renderStill() mode.)
- virtual void invalidate() = 0;
-
// Reads the pixel data from the current framebuffer. If your View implementation
// doesn't support reading from the framebuffer, return a null pointer.
virtual PremultipliedImage readStillImage(std::array<uint16_t, 2> size = {{ 0, 0 }});
- // Notifies a watcher of map x/y/scale/rotation changes.
- virtual void notifyMapChange(MapChange change);
-
protected:
mbgl::Map *map = nullptr;
};
+
} // namespace mbgl
diff --git a/include/mbgl/platform/default/glfw_view.hpp b/include/mbgl/platform/default/glfw_view.hpp
index 8662a90bf3..a115d03d7f 100644
--- a/include/mbgl/platform/default/glfw_view.hpp
+++ b/include/mbgl/platform/default/glfw_view.hpp
@@ -1,6 +1,7 @@
#pragma once
#include <mbgl/mbgl.hpp>
+#include <mbgl/map/backend.hpp>
#include <mbgl/util/run_loop.hpp>
#include <mbgl/util/timer.hpp>
#include <mbgl/util/geometry.hpp>
@@ -11,20 +12,36 @@
#define GL_GLEXT_PROTOTYPES
#include <GLFW/glfw3.h>
-class GLFWView : public mbgl::View {
+class GLFWView : public mbgl::View, public mbgl::Backend {
public:
GLFWView(bool fullscreen = false, bool benchmark = false);
~GLFWView() override;
- float getPixelRatio() const override;
+ float getPixelRatio() const;
+
+ // Callback called when the user presses the key mapped to style change.
+ // The expected action is to set a new style, different to the current one.
+ void setChangeStyleCallback(std::function<void()> callback);
+
+ void setShouldClose();
+
+ void setWindowTitle(const std::string&);
+
+ void run();
+
+private:
+ // mbgl::View implementation
+ void initialize(mbgl::Map*) override;
+ void bind() override;
std::array<uint16_t, 2> getSize() const override;
std::array<uint16_t, 2> getFramebufferSize() const override;
- void initialize(mbgl::Map*) override;
+ // mbgl::Backend implementation
void activate() override;
void deactivate() override;
void invalidate() override;
+ // Window callbacks
static void onKey(GLFWwindow *window, int key, int scancode, int action, int mods);
static void onScroll(GLFWwindow *window, double xoffset, double yoffset);
static void onWindowResize(GLFWwindow *window, int width, int height);
@@ -32,21 +49,12 @@ public:
static void onMouseClick(GLFWwindow *window, int button, int action, int modifiers);
static void onMouseMove(GLFWwindow *window, double x, double y);
- // Callback called when the user presses the key mapped to style change.
- // The expected action is to set a new style, different to the current one.
- void setChangeStyleCallback(std::function<void()> callback);
-
- void setShouldClose();
-
- void setWindowTitle(const std::string&);
-
- void run();
+ // Internal
void report(float duration);
void setMapChangeCallback(std::function<void(mbgl::MapChange)> callback);
void notifyMapChange(mbgl::MapChange change) override;
-private:
mbgl::Color makeRandomColor() const;
mbgl::Point<double> makeRandomPoint() const;
static std::shared_ptr<const mbgl::SpriteImage>
diff --git a/include/mbgl/platform/default/headless_backend.hpp b/include/mbgl/platform/default/headless_backend.hpp
new file mode 100644
index 0000000000..2f4886a365
--- /dev/null
+++ b/include/mbgl/platform/default/headless_backend.hpp
@@ -0,0 +1,78 @@
+#pragma once
+
+#include <mbgl/gl/implementation.hpp>
+
+#if MBGL_USE_QT
+class QGLWidget;
+#elif MBGL_USE_CGL
+#include <OpenGL/OpenGL.h>
+#elif MBGL_USE_GLX
+typedef struct _XDisplay Display;
+typedef struct __GLXcontextRec* GLXContext;
+typedef struct __GLXFBConfigRec* GLXFBConfig;
+typedef long unsigned int XID;
+typedef XID GLXPbuffer;
+#endif
+
+#include <mbgl/map/backend.hpp>
+#include <mbgl/gl/extension.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); }
+
+private:
+ void activateContext();
+ void deactivateContext();
+
+private:
+ // Implementation specific functions
+ static gl::glProc initializeExtension(const char*);
+ void createContext();
+ void destroyContext();
+
+ std::shared_ptr<HeadlessDisplay> display;
+
+ bool extensionsLoaded = false;
+ bool active = false;
+
+#if MBGL_USE_QT
+ QGLWidget* glContext = nullptr;
+#endif
+
+#if MBGL_USE_CGL
+ CGLContextObj glContext = nullptr;
+#endif
+
+#if MBGL_USE_EAGL
+ void *glContext = nullptr;
+#endif
+
+#if MBGL_USE_GLX
+ Display *xDisplay = nullptr;
+ GLXFBConfig *fbConfigs = nullptr;
+ GLXContext glContext = nullptr;
+ GLXPbuffer glxPbuffer = 0;
+#endif
+
+ std::function<void(MapChange)> mapChangeCallback;
+
+};
+
+} // namespace mbgl
diff --git a/include/mbgl/platform/default/headless_display.hpp b/include/mbgl/platform/default/headless_display.hpp
index edcc905221..f43e61340f 100644
--- a/include/mbgl/platform/default/headless_display.hpp
+++ b/include/mbgl/platform/default/headless_display.hpp
@@ -1,6 +1,13 @@
#pragma once
-#include <mbgl/platform/default/headless_view.hpp>
+#include <mbgl/gl/implementation.hpp>
+
+#if MBGL_USE_CGL
+#include <OpenGL/OpenGL.h>
+#elif MBGL_USE_GLX
+typedef struct _XDisplay Display;
+typedef struct __GLXFBConfigRec* GLXFBConfig;
+#endif
namespace mbgl {
diff --git a/include/mbgl/platform/default/headless_view.hpp b/include/mbgl/platform/default/headless_view.hpp
index 23f1e8251a..27af4fc9d9 100644
--- a/include/mbgl/platform/default/headless_view.hpp
+++ b/include/mbgl/platform/default/headless_view.hpp
@@ -1,95 +1,37 @@
#pragma once
-#if defined(__QT__)
-#define MBGL_USE_QT 1
-class QGLWidget;
-#elif defined(__APPLE__)
-#include <TargetConditionals.h>
-#if TARGET_OS_IOS
-#define MBGL_USE_EAGL 1
-#else
-#define MBGL_USE_CGL 1
-#endif
-#else
-#define GL_GLEXT_PROTOTYPES
-#define MBGL_USE_GLX 1
-typedef struct _XDisplay Display;
-typedef struct __GLXcontextRec* GLXContext;
-typedef struct __GLXFBConfigRec* GLXFBConfig;
-typedef long unsigned int XID;
-typedef XID GLXPbuffer;
-#endif
-
-#include <mbgl/mbgl.hpp>
-#include <mbgl/gl/gl.hpp>
+#include <mbgl/map/view.hpp>
#include <mbgl/gl/types.hpp>
-#include <mbgl/gl/extension.hpp>
-
-#include <memory>
-#include <thread>
namespace mbgl {
-class HeadlessDisplay;
-
class HeadlessView : public View {
public:
- HeadlessView(float pixelRatio, uint16_t width = 256, uint16_t height = 256);
- HeadlessView(std::shared_ptr<HeadlessDisplay> display, float pixelRatio, uint16_t width = 256, uint16_t height = 256);
+ HeadlessView(float pixelRatio = 1, uint16_t width = 256, uint16_t height = 256);
~HeadlessView() override;
- float getPixelRatio() const override;
+ void bind() override;
+
std::array<uint16_t, 2> getSize() const override;
std::array<uint16_t, 2> getFramebufferSize() const override;
- void invalidate() override;
- void activate() override;
- void deactivate() override;
- void notifyMapChange(MapChange) override;
PremultipliedImage readStillImage(std::array<uint16_t, 2> size = {{ 0, 0 }}) override;
+ float getPixelRatio() const;
+
void resize(uint16_t width, uint16_t height);
- void setMapChangeCallback(std::function<void(MapChange)>&& cb) { mapChangeCallback = std::move(cb); }
private:
- // Implementation specific functions
- static gl::glProc initializeExtension(const char*);
- void createContext();
- void destroyContext();
void clearBuffers();
void resizeFramebuffer();
- void activateContext();
- void deactivateContext();
+ void bindFramebuffer();
- std::shared_ptr<HeadlessDisplay> display;
+private:
const float pixelRatio;
std::array<uint16_t, 2> dimensions;
bool needsResize = false;
- bool extensionsLoaded = false;
- bool active = false;
-
-#if MBGL_USE_QT
- QGLWidget* glContext = nullptr;
-#endif
-
-#if MBGL_USE_CGL
- CGLContextObj glContext = nullptr;
-#endif
-
-#if MBGL_USE_EAGL
- void *glContext = nullptr;
-#endif
-
-#if MBGL_USE_GLX
- Display *xDisplay = nullptr;
- GLXFBConfig *fbConfigs = nullptr;
- GLXContext glContext = nullptr;
- GLXPbuffer glxPbuffer = 0;
-#endif
-
- std::function<void(MapChange)> mapChangeCallback;
gl::FramebufferID fbo = 0;
gl::RenderbufferID fboDepthStencil = 0;
diff --git a/platform/android/src/native_map_view.cpp b/platform/android/src/native_map_view.cpp
index 5bd2694932..fe201ac069 100755
--- a/platform/android/src/native_map_view.cpp
+++ b/platform/android/src/native_map_view.cpp
@@ -55,10 +55,8 @@ void log_gl_string(GLenum name, const char *label) {
}
}
-NativeMapView::NativeMapView(JNIEnv *env_, jobject obj_, float pixelRatio_, int availableProcessors_, size_t totalMemory_)
- : mbgl::View(*this),
- env(env_),
- pixelRatio(pixelRatio_),
+NativeMapView::NativeMapView(JNIEnv *env_, jobject obj_, float pixelRatio, int availableProcessors_, size_t totalMemory_)
+ : env(env_),
availableProcessors(availableProcessors_),
totalMemory(totalMemory_),
threadPool(4) {
@@ -82,7 +80,7 @@ NativeMapView::NativeMapView(JNIEnv *env_, jobject obj_, float pixelRatio_, int
mbgl::android::cachePath + "/mbgl-offline.db",
mbgl::android::apkPath);
- map = std::make_unique<mbgl::Map>(*this, *fileSource, threadPool, MapMode::Continuous);
+ map = std::make_unique<mbgl::Map>(*this, *this, pixelRatio, *fileSource, threadPool, MapMode::Continuous);
float zoomFactor = map->getMaxZoom() - map->getMinZoom() + 1;
float cpuFactor = availableProcessors;
@@ -114,8 +112,8 @@ NativeMapView::~NativeMapView() {
vm = nullptr;
}
-float NativeMapView::getPixelRatio() const {
- return pixelRatio;
+void NativeMapView::bind() {
+ MBGL_CHECK_ERROR(glBindFramebuffer(GL_FRAMEBUFFER, 0));
}
std::array<uint16_t, 2> NativeMapView::getSize() const {
diff --git a/platform/android/src/native_map_view.hpp b/platform/android/src/native_map_view.hpp
index d42890dae2..42a9a10ad4 100755
--- a/platform/android/src/native_map_view.hpp
+++ b/platform/android/src/native_map_view.hpp
@@ -2,6 +2,7 @@
#include <mbgl/map/map.hpp>
#include <mbgl/map/view.hpp>
+#include <mbgl/map/backend.hpp>
#include <mbgl/util/noncopyable.hpp>
#include <mbgl/platform/default/thread_pool.hpp>
#include <mbgl/storage/default_file_source.hpp>
@@ -14,12 +15,13 @@
namespace mbgl {
namespace android {
-class NativeMapView : public mbgl::View, private mbgl::util::noncopyable {
+class NativeMapView : public mbgl::View, public mbgl::Backend {
public:
NativeMapView(JNIEnv *env, jobject obj, float pixelRatio, int availableProcessors, size_t totalMemory);
virtual ~NativeMapView();
- float getPixelRatio() const override;
+ void bind() override;
+
std::array<uint16_t, 2> getSize() const override;
std::array<uint16_t, 2> getFramebufferSize() const override;
void activate() override;
@@ -89,7 +91,6 @@ private:
int height = 0;
int fbWidth = 0;
int fbHeight = 0;
- const float pixelRatio;
int availableProcessors = 0;
size_t totalMemory = 0;
diff --git a/platform/darwin/src/headless_backend_cgl.cpp b/platform/darwin/src/headless_backend_cgl.cpp
new file mode 100644
index 0000000000..4ca567f55c
--- /dev/null
+++ b/platform/darwin/src/headless_backend_cgl.cpp
@@ -0,0 +1,58 @@
+#include <mbgl/platform/default/headless_backend.hpp>
+#include <mbgl/platform/default/headless_display.hpp>
+
+#include <CoreFoundation/CoreFoundation.h>
+
+#include <string>
+#include <stdexcept>
+
+namespace mbgl {
+
+gl::glProc HeadlessBackend::initializeExtension(const char* name) {
+ static CFBundleRef framework = CFBundleGetBundleWithIdentifier(CFSTR("com.apple.opengl"));
+ if (!framework) {
+ throw std::runtime_error("Failed to load OpenGL framework.");
+ }
+
+ CFStringRef str = CFStringCreateWithCString(kCFAllocatorDefault, name, kCFStringEncodingASCII);
+ void* symbol = CFBundleGetFunctionPointerForName(framework, str);
+ CFRelease(str);
+
+ return reinterpret_cast<gl::glProc>(symbol);
+}
+
+void HeadlessBackend::createContext() {
+ CGLError error = CGLCreateContext(display->pixelFormat, nullptr, &glContext);
+ if (error != kCGLNoError) {
+ throw std::runtime_error(std::string("Error creating GL context object:") +
+ CGLErrorString(error) + "\n");
+ }
+
+ error = CGLEnable(glContext, kCGLCEMPEngine);
+ if (error != kCGLNoError) {
+ throw std::runtime_error(std::string("Error enabling OpenGL multithreading:") +
+ CGLErrorString(error) + "\n");
+ }
+}
+
+void HeadlessBackend::destroyContext() {
+ CGLDestroyContext(glContext);
+}
+
+void HeadlessBackend::activateContext() {
+ CGLError error = CGLSetCurrentContext(glContext);
+ if (error != kCGLNoError) {
+ throw std::runtime_error(std::string("Switching OpenGL context failed:") +
+ CGLErrorString(error) + "\n");
+ }
+}
+
+void HeadlessBackend::deactivateContext() {
+ CGLError error = CGLSetCurrentContext(nullptr);
+ if (error != kCGLNoError) {
+ throw std::runtime_error(std::string("Removing OpenGL context failed:") +
+ CGLErrorString(error) + "\n");
+ }
+}
+
+} // namespace mbgl
diff --git a/platform/darwin/src/headless_backend_eagl.mm b/platform/darwin/src/headless_backend_eagl.mm
new file mode 100644
index 0000000000..0a1ae706b8
--- /dev/null
+++ b/platform/darwin/src/headless_backend_eagl.mm
@@ -0,0 +1,46 @@
+#include <mbgl/platform/default/headless_backend.hpp>
+
+#include <mbgl/gl/extension.hpp>
+
+#include <OpenGLES/EAGL.h>
+
+#include <stdexcept>
+
+namespace mbgl {
+
+gl::glProc HeadlessBackend::initializeExtension(const char* name) {
+ static CFBundleRef framework = CFBundleGetBundleWithIdentifier(CFSTR("com.apple.opengles"));
+ if (!framework) {
+ throw std::runtime_error("Failed to load OpenGL framework.");
+ }
+
+ CFStringRef str = CFStringCreateWithCString(kCFAllocatorDefault, name, kCFStringEncodingASCII);
+ void* symbol = CFBundleGetFunctionPointerForName(framework, str);
+ CFRelease(str);
+
+ return reinterpret_cast<gl::glProc>(symbol);
+}
+
+void HeadlessBackend::createContext() {
+ glContext = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];
+ if (glContext == nil) {
+ throw std::runtime_error("Error creating GL context object");
+ }
+ [reinterpret_cast<EAGLContext*>(glContext) retain];
+ reinterpret_cast<EAGLContext*>(glContext).multiThreaded = YES;
+}
+
+void HeadlessBackend::destroyContext() {
+ [reinterpret_cast<EAGLContext*>(glContext) release];
+ glContext = nil;
+}
+
+void HeadlessBackend::activateContext() {
+ [EAGLContext setCurrentContext:reinterpret_cast<EAGLContext*>(glContext)];
+}
+
+void HeadlessBackend::deactivateContext() {
+ [EAGLContext setCurrentContext:nil];
+}
+
+} // namespace mbgl
diff --git a/platform/darwin/src/headless_view_cgl.cpp b/platform/darwin/src/headless_view_cgl.cpp
index dc58463b5d..08f0da8751 100644
--- a/platform/darwin/src/headless_view_cgl.cpp
+++ b/platform/darwin/src/headless_view_cgl.cpp
@@ -1,37 +1,14 @@
#include <mbgl/platform/default/headless_view.hpp>
-#include <mbgl/platform/default/headless_display.hpp>
-#include <CoreFoundation/CoreFoundation.h>
+#include <mbgl/gl/gl.hpp>
-namespace mbgl {
-
-gl::glProc HeadlessView::initializeExtension(const char* name) {
- static CFBundleRef framework = CFBundleGetBundleWithIdentifier(CFSTR("com.apple.opengl"));
- if (!framework) {
- throw std::runtime_error("Failed to load OpenGL framework.");
- }
-
- CFStringRef str = CFStringCreateWithCString(kCFAllocatorDefault, name, kCFStringEncodingASCII);
- void* symbol = CFBundleGetFunctionPointerForName(framework, str);
- CFRelease(str);
-
- return reinterpret_cast<gl::glProc>(symbol);
-}
-
-void HeadlessView::createContext() {
- CGLError error = CGLCreateContext(display->pixelFormat, nullptr, &glContext);
- if (error != kCGLNoError) {
- throw std::runtime_error(std::string("Error creating GL context object:") + CGLErrorString(error) + "\n");
- }
+#include <cassert>
- error = CGLEnable(glContext, kCGLCEMPEngine);
- if (error != kCGLNoError) {
- throw std::runtime_error(std::string("Error enabling OpenGL multithreading:") + CGLErrorString(error) + "\n");
- }
-}
+namespace mbgl {
-void HeadlessView::destroyContext() {
- CGLDestroyContext(glContext);
+void HeadlessView::bindFramebuffer() {
+ assert(fbo);
+ MBGL_CHECK_ERROR(glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo));
}
void HeadlessView::resizeFramebuffer() {
@@ -76,8 +53,6 @@ void HeadlessView::resizeFramebuffer() {
}
void HeadlessView::clearBuffers() {
- assert(active);
-
MBGL_CHECK_ERROR(glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0));
if (fbo) {
@@ -96,18 +71,4 @@ void HeadlessView::clearBuffers() {
}
}
-void HeadlessView::activateContext() {
- CGLError error = CGLSetCurrentContext(glContext);
- if (error != kCGLNoError) {
- throw std::runtime_error(std::string("Switching OpenGL context failed:") + CGLErrorString(error) + "\n");
- }
-}
-
-void HeadlessView::deactivateContext() {
- CGLError error = CGLSetCurrentContext(nullptr);
- if (error != kCGLNoError) {
- throw std::runtime_error(std::string("Removing OpenGL context failed:") + CGLErrorString(error) + "\n");
- }
-}
-
} // namespace mbgl
diff --git a/platform/darwin/src/headless_view_eagl.mm b/platform/darwin/src/headless_view_eagl.cpp
index a1f335fc6e..cc378912f9 100644
--- a/platform/darwin/src/headless_view_eagl.mm
+++ b/platform/darwin/src/headless_view_eagl.cpp
@@ -1,35 +1,14 @@
#include <mbgl/platform/default/headless_view.hpp>
-#include <mbgl/platform/default/headless_display.hpp>
-#include <OpenGLES/EAGL.h>
+#include <mbgl/gl/gl.hpp>
-namespace mbgl {
-
-gl::glProc HeadlessView::initializeExtension(const char* name) {
- static CFBundleRef framework = CFBundleGetBundleWithIdentifier(CFSTR("com.apple.opengles"));
- if (!framework) {
- throw std::runtime_error("Failed to load OpenGL framework.");
- }
-
- CFStringRef str = CFStringCreateWithCString(kCFAllocatorDefault, name, kCFStringEncodingASCII);
- void* symbol = CFBundleGetFunctionPointerForName(framework, str);
- CFRelease(str);
+#include <cassert>
- return reinterpret_cast<gl::glProc>(symbol);
-}
-
-void HeadlessView::createContext() {
- glContext = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];
- if (glContext == nil) {
- throw std::runtime_error("Error creating GL context object");
- }
- [reinterpret_cast<EAGLContext*>(glContext) retain];
- reinterpret_cast<EAGLContext*>(glContext).multiThreaded = YES;
-}
+namespace mbgl {
-void HeadlessView::destroyContext() {
- [reinterpret_cast<EAGLContext*>(glContext) release];
- glContext = nil;
+void HeadlessView::bindFramebuffer() {
+ assert(fbo);
+ MBGL_CHECK_ERROR(glBindFramebuffer(GL_FRAMEBUFFER, fbo));
}
void HeadlessView::resizeFramebuffer() {
@@ -72,8 +51,6 @@ void HeadlessView::resizeFramebuffer() {
}
void HeadlessView::clearBuffers() {
- assert(active);
-
MBGL_CHECK_ERROR(glBindFramebuffer(GL_FRAMEBUFFER, 0));
if (fbo) {
@@ -92,12 +69,4 @@ void HeadlessView::clearBuffers() {
}
}
-void HeadlessView::activateContext() {
- [EAGLContext setCurrentContext:reinterpret_cast<EAGLContext*>(glContext)];
-}
-
-void HeadlessView::deactivateContext() {
- [EAGLContext setCurrentContext:nil];
-}
-
} // namespace mbgl
diff --git a/platform/default/glfw_view.cpp b/platform/default/glfw_view.cpp
index 9c54fc4ebf..044181e8c8 100644
--- a/platform/default/glfw_view.cpp
+++ b/platform/default/glfw_view.cpp
@@ -129,6 +129,10 @@ void GLFWView::initialize(mbgl::Map *map_) {
map->addAnnotationIcon("default_marker", makeSpriteImage(22, 22, 1));
}
+void GLFWView::bind() {
+ MBGL_CHECK_ERROR(glBindFramebuffer(GL_FRAMEBUFFER, 0));
+}
+
void GLFWView::onKey(GLFWwindow *window, int key, int /*scancode*/, int action, int mods) {
GLFWView *view = reinterpret_cast<GLFWView *>(glfwGetWindowUserPointer(window));
diff --git a/platform/default/headless_backend.cpp b/platform/default/headless_backend.cpp
new file mode 100644
index 0000000000..279a7973c9
--- /dev/null
+++ b/platform/default/headless_backend.cpp
@@ -0,0 +1,56 @@
+#include <mbgl/platform/default/headless_backend.hpp>
+#include <mbgl/platform/default/headless_display.hpp>
+
+#include <cassert>
+#include <stdexcept>
+
+namespace mbgl {
+
+HeadlessBackend::HeadlessBackend() : display(std::make_shared<HeadlessDisplay>()) {
+ activate();
+}
+
+HeadlessBackend::HeadlessBackend(std::shared_ptr<HeadlessDisplay> display_)
+ : display(std::move(display_)) {
+ activate();
+}
+
+HeadlessBackend::~HeadlessBackend() {
+ deactivate();
+ destroyContext();
+}
+
+void HeadlessBackend::activate() {
+ active = true;
+
+ if (!glContext) {
+ if (!display) {
+ 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::notifyMapChange(MapChange change) {
+ if (mapChangeCallback) {
+ mapChangeCallback(change);
+ }
+}
+
+} // namespace mbgl
diff --git a/platform/default/headless_backend_glx.cpp b/platform/default/headless_backend_glx.cpp
new file mode 100644
index 0000000000..bbfd19345b
--- /dev/null
+++ b/platform/default/headless_backend_glx.cpp
@@ -0,0 +1,67 @@
+#include <mbgl/platform/default/headless_backend.hpp>
+#include <mbgl/platform/default/headless_display.hpp>
+
+#include <mbgl/platform/log.hpp>
+
+// #include <cassert>
+
+#include <GL/glx.h>
+
+namespace mbgl {
+
+gl::glProc HeadlessBackend::initializeExtension(const char* name) {
+ return glXGetProcAddress(reinterpret_cast<const GLubyte*>(name));
+}
+
+void HeadlessBackend::createContext() {
+ xDisplay = display->xDisplay;
+ fbConfigs = display->fbConfigs;
+
+ if (!glContext) {
+ // Try to create a legacy context
+ glContext = glXCreateNewContext(xDisplay, fbConfigs[0], GLX_RGBA_TYPE, None, True);
+ if (glContext) {
+ if (!glXIsDirect(xDisplay, glContext)) {
+ Log::Error(Event::OpenGL, "failed to create direct OpenGL Legacy context");
+ glXDestroyContext(xDisplay, glContext);
+ glContext = nullptr;
+ }
+ }
+ }
+
+ if (glContext == nullptr) {
+ throw std::runtime_error("Error creating GL context object.");
+ }
+
+ // Create a dummy pbuffer. We will render to framebuffers anyway, but we need a pbuffer to
+ // activate the context.
+ int pbufferAttributes[] = {
+ GLX_PBUFFER_WIDTH, 8,
+ GLX_PBUFFER_HEIGHT, 8,
+ None
+ };
+ glxPbuffer = glXCreatePbuffer(xDisplay, fbConfigs[0], pbufferAttributes);
+}
+
+void HeadlessBackend::destroyContext() {
+ if (glxPbuffer) {
+ glXDestroyPbuffer(xDisplay, glxPbuffer);
+ glxPbuffer = 0;
+ }
+
+ glXDestroyContext(xDisplay, glContext);
+}
+
+void HeadlessBackend::activateContext() {
+ if (!glXMakeContextCurrent(xDisplay, glxPbuffer, glxPbuffer, glContext)) {
+ throw std::runtime_error("Switching OpenGL context failed.\n");
+ }
+}
+
+void HeadlessBackend::deactivateContext() {
+ if (!glXMakeContextCurrent(xDisplay, 0, 0, nullptr)) {
+ throw std::runtime_error("Removing OpenGL context failed.\n");
+ }
+}
+
+} // namespace mbgl
diff --git a/platform/default/headless_display.cpp b/platform/default/headless_display.cpp
index 8b9f3fe04b..b98aef7903 100644
--- a/platform/default/headless_display.cpp
+++ b/platform/default/headless_display.cpp
@@ -1,12 +1,13 @@
#include <mbgl/platform/default/headless_display.hpp>
-#include <cstring>
-#include <stdexcept>
-
#if MBGL_USE_GLX
#include <GL/glx.h>
#endif
+#include <cstring>
+#include <stdexcept>
+#include <string>
+
namespace mbgl {
HeadlessDisplay::HeadlessDisplay() {
diff --git a/platform/default/headless_view.cpp b/platform/default/headless_view.cpp
index 95b196b746..f96b0a7f6d 100644
--- a/platform/default/headless_view.cpp
+++ b/platform/default/headless_view.cpp
@@ -1,34 +1,27 @@
#include <mbgl/platform/default/headless_view.hpp>
-#include <mbgl/platform/default/headless_display.hpp>
-#include <cassert>
+#include <mbgl/gl/gl.hpp>
+
#include <cstring>
namespace mbgl {
HeadlessView::HeadlessView(float pixelRatio_, uint16_t width, uint16_t height)
- : display(std::make_shared<HeadlessDisplay>())
- , pixelRatio(pixelRatio_)
- , dimensions({{ width, height }})
- , needsResize(true) {
-}
-
-HeadlessView::HeadlessView(std::shared_ptr<HeadlessDisplay> display_,
- float pixelRatio_,
- uint16_t width,
- uint16_t height)
- : display(std::move(display_))
- , pixelRatio(pixelRatio_)
- , dimensions({{ width, height }})
- , needsResize(true) {
+ : pixelRatio(pixelRatio_), dimensions({ { width, height } }), needsResize(true) {
}
HeadlessView::~HeadlessView() {
- activate();
clearBuffers();
- deactivate();
+}
- destroyContext();
+void HeadlessView::bind() {
+ if (needsResize) {
+ clearBuffers();
+ resizeFramebuffer();
+ needsResize = false;
+ } else {
+ bindFramebuffer();
+ }
}
void HeadlessView::resize(const uint16_t width, const uint16_t height) {
@@ -41,8 +34,6 @@ void HeadlessView::resize(const uint16_t width, const uint16_t height) {
}
PremultipliedImage HeadlessView::readStillImage(std::array<uint16_t, 2> size) {
- assert(active);
-
if (!size[0] || !size[1]) {
size[0] = dimensions[0] * pixelRatio;
size[1] = dimensions[1] * pixelRatio;
@@ -76,43 +67,4 @@ std::array<uint16_t, 2> HeadlessView::getFramebufferSize() const {
static_cast<uint16_t>(dimensions[1] * pixelRatio) }};
}
-void HeadlessView::activate() {
- active = true;
-
- if (!glContext) {
- if (!display) {
- throw std::runtime_error("Display is not set");
- }
- createContext();
- }
-
- activateContext();
-
- if (!extensionsLoaded) {
- gl::InitializeExtensions(initializeExtension);
- extensionsLoaded = true;
- }
-
- if (needsResize) {
- clearBuffers();
- resizeFramebuffer();
- needsResize = false;
- }
-}
-
-void HeadlessView::deactivate() {
- deactivateContext();
- active = false;
-}
-
-void HeadlessView::invalidate() {
- assert(false);
-}
-
-void HeadlessView::notifyMapChange(MapChange change) {
- if (mapChangeCallback) {
- mapChangeCallback(change);
- }
-}
-
} // namespace mbgl
diff --git a/platform/default/headless_view_glx.cpp b/platform/default/headless_view_glx.cpp
index 55d9313f99..08f0da8751 100644
--- a/platform/default/headless_view_glx.cpp
+++ b/platform/default/headless_view_glx.cpp
@@ -1,54 +1,14 @@
#include <mbgl/platform/default/headless_view.hpp>
-#include <mbgl/platform/default/headless_display.hpp>
-#include <mbgl/platform/log.hpp>
-#include <cassert>
+#include <mbgl/gl/gl.hpp>
-#include <GL/glx.h>
+#include <cassert>
namespace mbgl {
-gl::glProc HeadlessView::initializeExtension(const char* name) {
- return glXGetProcAddress(reinterpret_cast<const GLubyte*>(name));
-}
-
-void HeadlessView::createContext() {
- xDisplay = display->xDisplay;
- fbConfigs = display->fbConfigs;
-
- if (!glContext) {
- // Try to create a legacy context
- glContext = glXCreateNewContext(xDisplay, fbConfigs[0], GLX_RGBA_TYPE, None, True);
- if (glContext) {
- if (!glXIsDirect(xDisplay, glContext)) {
- Log::Error(Event::OpenGL, "failed to create direct OpenGL Legacy context");
- glXDestroyContext(xDisplay, glContext);
- glContext = nullptr;
- }
- }
- }
-
- if (glContext == nullptr) {
- throw std::runtime_error("Error creating GL context object.");
- }
-
- // Create a dummy pbuffer. We will render to framebuffers anyway, but we need a pbuffer to
- // activate the context.
- int pbufferAttributes[] = {
- GLX_PBUFFER_WIDTH, 8,
- GLX_PBUFFER_HEIGHT, 8,
- None
- };
- glxPbuffer = glXCreatePbuffer(xDisplay, fbConfigs[0], pbufferAttributes);
-}
-
-void HeadlessView::destroyContext() {
- if (glxPbuffer) {
- glXDestroyPbuffer(xDisplay, glxPbuffer);
- glxPbuffer = 0;
- }
-
- glXDestroyContext(xDisplay, glContext);
+void HeadlessView::bindFramebuffer() {
+ assert(fbo);
+ MBGL_CHECK_ERROR(glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo));
}
void HeadlessView::resizeFramebuffer() {
@@ -93,8 +53,6 @@ void HeadlessView::resizeFramebuffer() {
}
void HeadlessView::clearBuffers() {
- assert(active);
-
MBGL_CHECK_ERROR(glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0));
if (fbo) {
@@ -113,16 +71,4 @@ void HeadlessView::clearBuffers() {
}
}
-void HeadlessView::activateContext() {
- if (!glXMakeContextCurrent(xDisplay, glxPbuffer, glxPbuffer, glContext)) {
- throw std::runtime_error("Switching OpenGL context failed.\n");
- }
-}
-
-void HeadlessView::deactivateContext() {
- if (!glXMakeContextCurrent(xDisplay, 0, 0, nullptr)) {
- throw std::runtime_error("Removing OpenGL context failed.\n");
- }
-}
-
} // namespace mbgl
diff --git a/platform/ios/config.cmake b/platform/ios/config.cmake
index e5480e37df..db75d7a4de 100644
--- a/platform/ios/config.cmake
+++ b/platform/ios/config.cmake
@@ -37,7 +37,9 @@ macro(mbgl_platform_core)
PRIVATE platform/darwin/src/image.mm
# Headless view
- PRIVATE platform/darwin/src/headless_view_eagl.mm
+ PRIVATE platform/darwin/src/headless_backend_eagl.mm
+ PRIVATE platform/darwin/src/headless_view_eagl.cpp
+ PRIVATE platform/default/headless_backend.cpp
PRIVATE platform/default/headless_display.cpp
PRIVATE platform/default/headless_view.cpp
@@ -53,7 +55,7 @@ macro(mbgl_platform_core)
# TODO: Remove this by converting to ARC
set_source_files_properties(
- platform/darwin/src/headless_view_eagl.mm
+ platform/darwin/src/headless_backend_eagl.mm
PROPERTIES
COMPILE_FLAGS -fno-objc-arc
)
diff --git a/platform/ios/src/MGLMapView.mm b/platform/ios/src/MGLMapView.mm
index 194f1a88d4..3d93dc8fc9 100644
--- a/platform/ios/src/MGLMapView.mm
+++ b/platform/ios/src/MGLMapView.mm
@@ -18,6 +18,7 @@
#include <mbgl/storage/network_status.hpp>
#include <mbgl/style/transition_options.hpp>
#include <mbgl/style/layers/custom_layer.hpp>
+#include <mbgl/map/backend.hpp>
#include <mbgl/math/wrap.hpp>
#include <mbgl/util/geo.hpp>
#include <mbgl/util/constants.hpp>
@@ -389,8 +390,7 @@ public:
self.clipsToBounds = YES;
// setup mbgl view
- const float scaleFactor = [UIScreen instancesRespondToSelector:@selector(nativeScale)] ? [[UIScreen mainScreen] nativeScale] : [[UIScreen mainScreen] scale];
- _mbglView = new MBGLView(self, scaleFactor);
+ _mbglView = new MBGLView(self);
// Delete the pre-offline ambient cache at ~/Library/Caches/cache.db.
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
@@ -398,9 +398,10 @@ public:
[[NSFileManager defaultManager] removeItemAtPath:fileCachePath error:NULL];
// setup mbgl map
+ const float scaleFactor = [UIScreen instancesRespondToSelector:@selector(nativeScale)] ? [[UIScreen mainScreen] nativeScale] : [[UIScreen mainScreen] scale];
mbgl::DefaultFileSource *mbglFileSource = [MGLOfflineStorage sharedOfflineStorage].mbglFileSource;
_mbglThreadPool = new mbgl::ThreadPool(4);
- _mbglMap = new mbgl::Map(*_mbglView, *mbglFileSource, *_mbglThreadPool, mbgl::MapMode::Continuous, mbgl::GLContextMode::Unique, mbgl::ConstrainMode::None, mbgl::ViewportMode::Default);
+ _mbglMap = new mbgl::Map(*_mbglView, *_mbglView, scaleFactor, *mbglFileSource, *_mbglThreadPool, mbgl::MapMode::Continuous, mbgl::GLContextMode::Unique, mbgl::ConstrainMode::None, mbgl::ViewportMode::Default);
[self validateTileCacheSize];
// start paused if in IB
@@ -4938,15 +4939,11 @@ public:
return _annotationViewReuseQueueByIdentifier[identifier];
}
-class MBGLView : public mbgl::View
+class MBGLView : public mbgl::View, public mbgl::Backend
{
public:
- MBGLView(MGLMapView* nativeView_, const float scaleFactor_)
- : nativeView(nativeView_), scaleFactor(scaleFactor_) {
- }
-
- float getPixelRatio() const override {
- return scaleFactor;
+ MBGLView(MGLMapView* nativeView_)
+ : nativeView(nativeView_) {
}
std::array<uint16_t, 2> getSize() const override {
@@ -4959,6 +4956,10 @@ public:
static_cast<uint16_t>([[nativeView glView] drawableHeight]) }};
}
+ void bind() override {
+ [nativeView.glView bindDrawable];
+ }
+
void notifyMapChange(mbgl::MapChange change) override
{
[nativeView notifyMapChange:change];
@@ -4981,7 +4982,6 @@ public:
private:
__weak MGLMapView *nativeView = nullptr;
- const float scaleFactor;
};
@end
diff --git a/platform/linux/config.cmake b/platform/linux/config.cmake
index 86e8697f8c..d033f9df21 100644
--- a/platform/linux/config.cmake
+++ b/platform/linux/config.cmake
@@ -41,9 +41,11 @@ macro(mbgl_platform_core)
PRIVATE platform/default/webp_reader.cpp
# Headless view
+ PRIVATE platform/default/headless_backend_glx.cpp
+ PRIVATE platform/default/headless_view_glx.cpp
+ PRIVATE platform/default/headless_backend.cpp
PRIVATE platform/default/headless_display.cpp
PRIVATE platform/default/headless_view.cpp
- PRIVATE platform/default/headless_view_glx.cpp
# Thread pool
PRIVATE platform/default/thread_pool.cpp
diff --git a/platform/macos/config.cmake b/platform/macos/config.cmake
index 645feb90c3..198dfc7083 100644
--- a/platform/macos/config.cmake
+++ b/platform/macos/config.cmake
@@ -35,7 +35,9 @@ macro(mbgl_platform_core)
PRIVATE platform/darwin/src/image.mm
# Headless view
+ PRIVATE platform/darwin/src/headless_backend_cgl.cpp
PRIVATE platform/darwin/src/headless_view_cgl.cpp
+ PRIVATE platform/default/headless_backend.cpp
PRIVATE platform/default/headless_display.cpp
PRIVATE platform/default/headless_view.cpp
diff --git a/platform/macos/src/MGLMapView.mm b/platform/macos/src/MGLMapView.mm
index 46766b573b..475ca2d259 100644
--- a/platform/macos/src/MGLMapView.mm
+++ b/platform/macos/src/MGLMapView.mm
@@ -25,6 +25,7 @@
#import <mbgl/platform/default/thread_pool.hpp>
#import <mbgl/gl/extension.hpp>
#import <mbgl/gl/gl.hpp>
+#import <mbgl/map/backend.hpp>
#import <mbgl/sprite/sprite_image.hpp>
#import <mbgl/storage/default_file_source.hpp>
#import <mbgl/storage/network_status.hpp>
@@ -248,7 +249,7 @@ public:
_isTargetingInterfaceBuilder = NSProcessInfo.processInfo.mgl_isInterfaceBuilderDesignablesAgent;
// Set up cross-platform controllers and resources.
- _mbglView = new MGLMapViewImpl(self, [NSScreen mainScreen].backingScaleFactor);
+ _mbglView = new MGLMapViewImpl(self);
// Delete the pre-offline ambient cache at
// ~/Library/Caches/com.mapbox.sdk.ios/cache.db.
@@ -264,7 +265,7 @@ public:
mbgl::DefaultFileSource *mbglFileSource = [MGLOfflineStorage sharedOfflineStorage].mbglFileSource;
_mbglThreadPool = new mbgl::ThreadPool(4);
- _mbglMap = new mbgl::Map(*_mbglView, *mbglFileSource, *_mbglThreadPool, mbgl::MapMode::Continuous, mbgl::GLContextMode::Unique, mbgl::ConstrainMode::None, mbgl::ViewportMode::Default);
+ _mbglMap = new mbgl::Map(*_mbglView, *_mbglView, [NSScreen mainScreen].backingScaleFactor, *mbglFileSource, *_mbglThreadPool, mbgl::MapMode::Continuous, mbgl::GLContextMode::Unique, mbgl::ConstrainMode::None, mbgl::ViewportMode::Default);
[self validateTileCacheSize];
// Install the OpenGL layer. Interface Builder’s synchronous drawing means
@@ -745,6 +746,8 @@ public:
return reinterpret_cast<mbgl::gl::glProc>(symbol);
});
+ _mbglView->updateFramebufferBinding();
+
_mbglMap->render();
if (_isPrinting) {
@@ -2531,14 +2534,10 @@ public:
}
/// Adapter responsible for bridging calls from mbgl to MGLMapView and Cocoa.
-class MGLMapViewImpl : public mbgl::View {
+class MGLMapViewImpl : public mbgl::View, public mbgl::Backend {
public:
- MGLMapViewImpl(MGLMapView *nativeView_, const float scaleFactor_)
- : nativeView(nativeView_), scaleFactor(scaleFactor_) {}
-
- float getPixelRatio() const override {
- return scaleFactor;
- }
+ MGLMapViewImpl(MGLMapView *nativeView_)
+ : nativeView(nativeView_) {}
std::array<uint16_t, 2> getSize() const override {
return {{ static_cast<uint16_t>(nativeView.bounds.size.width),
@@ -2568,6 +2567,14 @@ public:
[NSOpenGLContext clearCurrentContext];
}
+ void updateFramebufferBinding() {
+ MBGL_CHECK_ERROR(glGetIntegerv(GL_FRAMEBUFFER_BINDING, &fbo));
+ }
+
+ void bind() override {
+ MBGL_CHECK_ERROR(glBindFramebuffer(GL_FRAMEBUFFER, fbo));
+ }
+
mbgl::PremultipliedImage readStillImage(std::array<uint16_t, 2> size = {{ 0, 0 }}) override {
if (!size[0] || !size[1]) {
size = getFramebufferSize();
@@ -2592,8 +2599,8 @@ private:
/// Cocoa map view that this adapter bridges to.
__weak MGLMapView *nativeView = nullptr;
- /// Backing scale factor of the view.
- const float scaleFactor;
+ /// The current framebuffer of the NSOpenGLLayer we are painting to.
+ GLint fbo = 0;
};
@end
diff --git a/platform/node/src/node_map.cpp b/platform/node/src/node_map.cpp
index a13adbc417..ebdf8d62c3 100644
--- a/platform/node/src/node_map.cpp
+++ b/platform/node/src/node_map.cpp
@@ -773,15 +773,16 @@ void NodeMap::QueryRenderedFeatures(const Nan::FunctionCallbackInfo<v8::Value>&
}
NodeMap::NodeMap(v8::Local<v8::Object> options) :
- view(sharedDisplay(), [&] {
+ backend(sharedDisplay()),
+ view([&] {
Nan::HandleScope scope;
return Nan::Has(options, Nan::New("ratio").ToLocalChecked()).FromJust() ? Nan::Get(options, Nan::New("ratio").ToLocalChecked()).ToLocalChecked()->NumberValue() : 1.0;
}()),
threadpool(),
- map(std::make_unique<mbgl::Map>(view, *this, threadpool, mbgl::MapMode::Still)),
+ map(std::make_unique<mbgl::Map>(backend, view, view.getPixelRatio(), *this, threadpool, mbgl::MapMode::Still)),
async(new uv_async_t) {
- view.setMapChangeCallback([&](mbgl::MapChange change) {
+ backend.setMapChangeCallback([&](mbgl::MapChange change) {
if (change == mbgl::MapChangeDidFailLoadingMap) {
throw std::runtime_error("Requires a map style to be a valid style JSON");
}
diff --git a/platform/node/src/node_map.hpp b/platform/node/src/node_map.hpp
index 588ece2c74..48ff2caab1 100644
--- a/platform/node/src/node_map.hpp
+++ b/platform/node/src/node_map.hpp
@@ -4,6 +4,7 @@
#include <mbgl/map/map.hpp>
#include <mbgl/storage/file_source.hpp>
+#include <mbgl/platform/default/headless_backend.hpp>
#include <mbgl/platform/default/headless_view.hpp>
#pragma GCC diagnostic push
@@ -53,6 +54,7 @@ public:
std::unique_ptr<mbgl::AsyncRequest> request(const mbgl::Resource&, mbgl::FileSource::Callback);
+ mbgl::HeadlessBackend backend;
mbgl::HeadlessView view;
NodeThreadPool threadpool;
std::unique_ptr<mbgl::Map> map;
diff --git a/platform/qt/config.cmake b/platform/qt/config.cmake
index d8ede6b450..6df311f885 100644
--- a/platform/qt/config.cmake
+++ b/platform/qt/config.cmake
@@ -43,8 +43,10 @@ endmacro()
macro(mbgl_platform_test)
target_sources(mbgl-test
PRIVATE test/src/main.cpp
+ PRIVATE platform/qt/test/headless_backend_qt.cpp
PRIVATE platform/qt/test/headless_view_qt.cpp
PRIVATE platform/qt/test/qmapboxgl.cpp
+ PRIVATE platform/default/headless_backend.cpp
PRIVATE platform/default/headless_display.cpp
PRIVATE platform/default/headless_view.cpp
)
diff --git a/platform/qt/src/qmapboxgl.cpp b/platform/qt/src/qmapboxgl.cpp
index d0a05301f8..73a1771908 100644
--- a/platform/qt/src/qmapboxgl.cpp
+++ b/platform/qt/src/qmapboxgl.cpp
@@ -813,7 +813,7 @@ QMapboxGLPrivate::QMapboxGLPrivate(QMapboxGL *q, const QMapboxGLSettings &settin
settings.cacheDatabaseMaximumSize()))
, threadPool(4)
, mapObj(std::make_unique<mbgl::Map>(
- *this, *fileSourceObj, threadPool,
+ *this, *this, getPixelRatio(), *fileSourceObj, threadPool,
static_cast<mbgl::MapMode>(settings.mapMode()),
static_cast<mbgl::GLContextMode>(settings.contextMode()),
static_cast<mbgl::ConstrainMode>(settings.constrainMode()),
@@ -845,6 +845,11 @@ float QMapboxGLPrivate::getPixelRatio() const
return pixelRatio;
}
+void QMapboxGLPrivate::bind()
+{
+ MBGL_CHECK_ERROR(glBindFramebuffer(GL_FRAMEBUFFER, 0));
+}
+
std::array<uint16_t, 2> QMapboxGLPrivate::getSize() const
{
return {{ static_cast<uint16_t>(size.width()), static_cast<uint16_t>(size.height()) }};
diff --git a/platform/qt/src/qmapboxgl_p.hpp b/platform/qt/src/qmapboxgl_p.hpp
index c35ac4e7ba..5a228896dc 100644
--- a/platform/qt/src/qmapboxgl_p.hpp
+++ b/platform/qt/src/qmapboxgl_p.hpp
@@ -3,6 +3,7 @@
#include "qmapboxgl.hpp"
#include <mbgl/map/map.hpp>
+#include <mbgl/map/backend.hpp>
#include <mbgl/map/view.hpp>
#include <mbgl/platform/default/thread_pool.hpp>
#include <mbgl/storage/default_file_source.hpp>
@@ -11,7 +12,7 @@
#include <QObject>
#include <QSize>
-class QMapboxGLPrivate : public QObject, public mbgl::View
+class QMapboxGLPrivate : public QObject, public mbgl::View, public mbgl::Backend
{
Q_OBJECT
@@ -20,7 +21,8 @@ public:
virtual ~QMapboxGLPrivate();
// mbgl::View implementation.
- float getPixelRatio() const final;
+ float getPixelRatio() const;
+ void bind() final;
std::array<uint16_t, 2> getSize() const final;
std::array<uint16_t, 2> getFramebufferSize() const final;
diff --git a/platform/qt/test/headless_backend_qt.cpp b/platform/qt/test/headless_backend_qt.cpp
new file mode 100644
index 0000000000..3f287ae578
--- /dev/null
+++ b/platform/qt/test/headless_backend_qt.cpp
@@ -0,0 +1,46 @@
+#include <mbgl/platform/default/headless_backend.hpp>
+#include <mbgl/platform/default/headless_display.hpp>
+
+#include <QApplication>
+#include <QGLContext>
+#include <QGLWidget>
+
+#if QT_VERSION >= 0x050000
+#include <QOpenGLContext>
+#endif
+
+namespace mbgl {
+
+gl::glProc HeadlessBackend::initializeExtension(const char* name) {
+#if QT_VERSION >= 0x050000
+ QOpenGLContext* thisContext = QOpenGLContext::currentContext();
+ return thisContext->getProcAddress(name);
+#else
+ const QGLContext* thisContext = QGLContext::currentContext();
+ return reinterpret_cast<mbgl::gl::glProc>(thisContext->getProcAddress(name));
+#endif
+}
+
+void HeadlessBackend::createContext() {
+ static const char* argv[] = { "mbgl" };
+ static int argc = 1;
+ static auto* app = new QApplication(argc, const_cast<char**>(argv));
+
+ Q_UNUSED(app);
+
+ glContext = new QGLWidget;
+}
+
+void HeadlessBackend::destroyContext() {
+ delete glContext;
+}
+
+void HeadlessBackend::activateContext() {
+ glContext->makeCurrent();
+}
+
+void HeadlessBackend::deactivateContext() {
+ glContext->doneCurrent();
+}
+
+} // namespace mbgl
diff --git a/platform/qt/test/headless_view_qt.cpp b/platform/qt/test/headless_view_qt.cpp
index 03ecb741ab..133b4a2371 100644
--- a/platform/qt/test/headless_view_qt.cpp
+++ b/platform/qt/test/headless_view_qt.cpp
@@ -1,6 +1,7 @@
-#include <mbgl/platform/default/headless_display.hpp>
#include <mbgl/platform/default/headless_view.hpp>
+#include <mbgl/gl/gl.hpp>
+
#include <QApplication>
#include <QGLContext>
#include <QGLWidget>
@@ -9,30 +10,13 @@
#include <QOpenGLContext>
#endif
-namespace mbgl {
-
-gl::glProc HeadlessView::initializeExtension(const char* name) {
-#if QT_VERSION >= 0x050000
- QOpenGLContext* thisContext = QOpenGLContext::currentContext();
- return thisContext->getProcAddress(name);
-#else
- const QGLContext* thisContext = QGLContext::currentContext();
- return reinterpret_cast<mbgl::gl::glProc>(thisContext->getProcAddress(name));
-#endif
-}
-
-void HeadlessView::createContext() {
- static const char* argv[] = { "mbgl" };
- static int argc = 1;
- static auto* app = new QApplication(argc, const_cast<char**>(argv));
-
- Q_UNUSED(app);
+#include <cassert>
- glContext = new QGLWidget;
-}
+namespace mbgl {
-void HeadlessView::destroyContext() {
- delete glContext;
+void HeadlessView::bindFramebuffer() {
+ assert(fbo);
+ MBGL_CHECK_ERROR(glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo));
}
void HeadlessView::resizeFramebuffer() {
@@ -95,12 +79,4 @@ void HeadlessView::clearBuffers() {
}
}
-void HeadlessView::activateContext() {
- glContext->makeCurrent();
-}
-
-void HeadlessView::deactivateContext() {
- glContext->doneCurrent();
-}
-
} // namespace mbgl
diff --git a/src/mbgl/map/backend.cpp b/src/mbgl/map/backend.cpp
new file mode 100644
index 0000000000..fea4b70ce9
--- /dev/null
+++ b/src/mbgl/map/backend.cpp
@@ -0,0 +1,12 @@
+#include <mbgl/map/backend.hpp>
+
+#include <cassert>
+
+namespace mbgl {
+
+void Backend::notifyMapChange(MapChange) {
+ // no-op
+}
+
+
+} // namespace mbgl
diff --git a/src/mbgl/map/map.cpp b/src/mbgl/map/map.cpp
index d948225d8a..ab85187c98 100644
--- a/src/mbgl/map/map.cpp
+++ b/src/mbgl/map/map.cpp
@@ -1,6 +1,7 @@
#include <mbgl/map/map.hpp>
#include <mbgl/map/camera.hpp>
#include <mbgl/map/view.hpp>
+#include <mbgl/map/backend.hpp>
#include <mbgl/map/transform.hpp>
#include <mbgl/map/transform_state.hpp>
#include <mbgl/annotation/annotation_manager.hpp>
@@ -36,7 +37,15 @@ enum class RenderState : uint8_t {
class Map::Impl : public style::Observer {
public:
- Impl(View&, FileSource&, Scheduler&, MapMode, GLContextMode, ConstrainMode, ViewportMode);
+ Impl(Backend&,
+ View&,
+ float pixelRatio,
+ FileSource&,
+ Scheduler&,
+ MapMode,
+ GLContextMode,
+ ConstrainMode,
+ ViewportMode);
void onSourceAttributionChanged(style::Source&, const std::string&) override;
void onUpdate(Update) override;
@@ -49,6 +58,7 @@ public:
void loadStyleJSON(const std::string&);
+ Backend& backend;
View& view;
FileSource& fileSource;
Scheduler& scheduler;
@@ -81,34 +91,53 @@ public:
bool loading = false;
};
-Map::Map(View& view, FileSource& fileSource, Scheduler& scheduler, MapMode mapMode, GLContextMode contextMode, ConstrainMode constrainMode, ViewportMode viewportMode)
- : impl(std::make_unique<Impl>(view, fileSource, scheduler, mapMode, contextMode, constrainMode, viewportMode)) {
+Map::Map(Backend& backend,
+ View& view,
+ const float pixelRatio,
+ FileSource& fileSource,
+ Scheduler& scheduler,
+ MapMode mapMode,
+ GLContextMode contextMode,
+ ConstrainMode constrainMode,
+ ViewportMode viewportMode)
+ : impl(std::make_unique<Impl>(backend,
+ view,
+ pixelRatio,
+ fileSource,
+ scheduler,
+ mapMode,
+ contextMode,
+ constrainMode,
+ viewportMode)) {
view.initialize(this);
update(Update::Dimensions);
}
-Map::Impl::Impl(View& view_,
+Map::Impl::Impl(Backend& backend_,
+ View& view_,
+ float pixelRatio_,
FileSource& fileSource_,
Scheduler& scheduler_,
MapMode mode_,
GLContextMode contextMode_,
ConstrainMode constrainMode_,
ViewportMode viewportMode_)
- : view(view_),
+ : backend(backend_),
+ view(view_),
fileSource(fileSource_),
scheduler(scheduler_),
- transform([this](MapChange change) { view.notifyMapChange(change); },
+ transform([this](MapChange change) { backend.notifyMapChange(change); },
constrainMode_,
viewportMode_),
mode(mode_),
contextMode(contextMode_),
- pixelRatio(view.getPixelRatio()),
+ pixelRatio(pixelRatio_),
asyncUpdate([this] { update(); }),
annotationManager(std::make_unique<AnnotationManager>(pixelRatio)) {
}
Map::~Map() {
- impl->view.activate();
+ impl->backend.activate();
impl->styleRequest = nullptr;
@@ -118,7 +147,7 @@ Map::~Map() {
impl->annotationManager.reset();
impl->painter.reset();
- impl->view.deactivate();
+ impl->backend.deactivate();
}
void Map::renderStill(StillImageCallback callback) {
@@ -162,16 +191,16 @@ void Map::render() {
}
if (impl->renderState == RenderState::Never) {
- impl->view.notifyMapChange(MapChangeWillStartRenderingMap);
+ impl->backend.notifyMapChange(MapChangeWillStartRenderingMap);
}
- impl->view.notifyMapChange(MapChangeWillStartRenderingFrame);
+ impl->backend.notifyMapChange(MapChangeWillStartRenderingFrame);
const Update flags = impl->transform.updateTransitions(Clock::now());
impl->render();
- impl->view.notifyMapChange(isFullyLoaded() ?
+ impl->backend.notifyMapChange(isFullyLoaded() ?
MapChangeDidFinishRenderingFrameFullyRendered :
MapChangeDidFinishRenderingFrame);
@@ -179,10 +208,10 @@ void Map::render() {
impl->renderState = RenderState::Partial;
} else if (impl->renderState != RenderState::Fully) {
impl->renderState = RenderState::Fully;
- impl->view.notifyMapChange(MapChangeDidFinishRenderingMapFullyRendered);
+ impl->backend.notifyMapChange(MapChangeDidFinishRenderingMapFullyRendered);
if (impl->loading) {
impl->loading = false;
- impl->view.notifyMapChange(MapChangeDidFinishLoadingMap);
+ impl->backend.notifyMapChange(MapChangeDidFinishLoadingMap);
}
}
@@ -240,11 +269,11 @@ void Map::Impl::update() {
style->updateTiles(parameters);
if (mode == MapMode::Continuous) {
- view.invalidate();
+ backend.invalidate();
} else if (callback && style->isLoaded()) {
- view.activate();
+ backend.activate();
render();
- view.deactivate();
+ backend.deactivate();
}
updateFlags = Update::Nothing;
@@ -255,8 +284,7 @@ void Map::Impl::render() {
painter = std::make_unique<Painter>(transform.getState());
}
- FrameData frameData { view.getFramebufferSize(),
- timePoint,
+ FrameData frameData { timePoint,
pixelRatio,
mode,
contextMode,
@@ -264,6 +292,7 @@ void Map::Impl::render() {
painter->render(*style,
frameData,
+ view,
annotationManager->getSpriteAtlas());
if (mode == MapMode::Still) {
@@ -291,7 +320,7 @@ void Map::setStyleURL(const std::string& url) {
impl->loading = true;
- impl->view.notifyMapChange(MapChangeWillStartLoadingMap);
+ impl->backend.notifyMapChange(MapChangeWillStartLoadingMap);
impl->styleRequest = nullptr;
impl->styleURL = url;
@@ -335,7 +364,7 @@ void Map::setStyleJSON(const std::string& json) {
impl->loading = true;
- impl->view.notifyMapChange(MapChangeWillStartLoadingMap);
+ impl->backend.notifyMapChange(MapChangeWillStartLoadingMap);
impl->styleURL.clear();
impl->styleJSON.clear();
@@ -801,12 +830,12 @@ void Map::addLayer(std::unique_ptr<Layer> layer, const optional<std::string>& be
}
impl->styleMutated = true;
- impl->view.activate();
+ impl->backend.activate();
impl->style->addLayer(std::move(layer), before);
update(Update::Classes);
- impl->view.deactivate();
+ impl->backend.deactivate();
}
void Map::removeLayer(const std::string& id) {
@@ -815,12 +844,12 @@ void Map::removeLayer(const std::string& id) {
}
impl->styleMutated = true;
- impl->view.activate();
+ impl->backend.activate();
impl->style->removeLayer(id);
update(Update::Classes);
- impl->view.deactivate();
+ impl->backend.deactivate();
}
void Map::addImage(const std::string& name, std::unique_ptr<const SpriteImage> image) {
@@ -971,7 +1000,7 @@ void Map::setSourceTileCacheSize(size_t size) {
impl->sourceCacheSize = size;
if (!impl->style) return;
impl->style->setSourceTileCacheSize(size);
- impl->view.invalidate();
+ impl->backend.invalidate();
}
}
@@ -981,12 +1010,12 @@ void Map::onLowMemory() {
}
if (impl->style) {
impl->style->onLowMemory();
- impl->view.invalidate();
+ impl->backend.invalidate();
}
}
void Map::Impl::onSourceAttributionChanged(style::Source&, const std::string&) {
- view.notifyMapChange(MapChangeSourceDidChange);
+ backend.notifyMapChange(MapChangeSourceDidChange);
}
void Map::Impl::onUpdate(Update flags) {
@@ -999,11 +1028,11 @@ void Map::Impl::onUpdate(Update flags) {
}
void Map::Impl::onStyleLoaded() {
- view.notifyMapChange(MapChangeDidFinishLoadingStyle);
+ backend.notifyMapChange(MapChangeDidFinishLoadingStyle);
}
void Map::Impl::onStyleError() {
- view.notifyMapChange(MapChangeDidFailLoadingMap);
+ backend.notifyMapChange(MapChangeDidFailLoadingMap);
}
void Map::Impl::onResourceError(std::exception_ptr error) {
diff --git a/src/mbgl/map/view.cpp b/src/mbgl/map/view.cpp
index 8541753c7a..23ce70a3cf 100644
--- a/src/mbgl/map/view.cpp
+++ b/src/mbgl/map/view.cpp
@@ -5,18 +5,13 @@
namespace mbgl {
-void View::initialize(Map *map_) {
- assert(map_);
- map = map_;
-}
-
PremultipliedImage View::readStillImage(std::array<uint16_t, 2>) {
return {};
}
-void View::notifyMapChange(MapChange) {
- // no-op
+void View::initialize(Map *map_) {
+ assert(map_);
+ map = map_;
}
-
} // namespace mbgl
diff --git a/src/mbgl/renderer/paint_parameters.hpp b/src/mbgl/renderer/paint_parameters.hpp
index 13bf21080d..bd67dc9cfd 100644
--- a/src/mbgl/renderer/paint_parameters.hpp
+++ b/src/mbgl/renderer/paint_parameters.hpp
@@ -3,10 +3,12 @@
namespace mbgl {
class Shaders;
+class View;
class PaintParameters {
public:
Shaders& shaders;
+ View& view;
};
} // namespace mbgl
diff --git a/src/mbgl/renderer/painter.cpp b/src/mbgl/renderer/painter.cpp
index ad0e75cd92..ee7ef6d212 100644
--- a/src/mbgl/renderer/painter.cpp
+++ b/src/mbgl/renderer/painter.cpp
@@ -5,6 +5,8 @@
#include <mbgl/style/source.hpp>
#include <mbgl/style/source_impl.hpp>
+#include <mbgl/map/view.hpp>
+
#include <mbgl/platform/log.hpp>
#include <mbgl/gl/gl.hpp>
#include <mbgl/gl/debugging.hpp>
@@ -90,19 +92,18 @@ void Painter::cleanup() {
context.performCleanup();
}
-void Painter::render(const Style& style, const FrameData& frame_, SpriteAtlas& annotationSpriteAtlas) {
- if (frame.framebufferSize != frame_.framebufferSize) {
- context.viewport.setDefaultValue(
- { 0, 0, frame_.framebufferSize[0], frame_.framebufferSize[1] });
- }
+void Painter::render(const Style& style, const FrameData& frame_, View& view, SpriteAtlas& annotationSpriteAtlas) {
+ context.viewport.setDefaultValue(
+ { 0, 0, view.getFramebufferSize()[0], view.getFramebufferSize()[1] });
frame = frame_;
PaintParameters parameters {
#ifndef NDEBUG
- paintMode() == PaintMode::Overdraw ? *overdrawShaders : *shaders
+ paintMode() == PaintMode::Overdraw ? *overdrawShaders : *shaders,
#else
- *shaders
+ *shaders,
#endif
+ view
};
glyphAtlas = style.glyphAtlas.get();
@@ -148,7 +149,8 @@ void Painter::render(const Style& style, const FrameData& frame_, SpriteAtlas& a
// tiles whatsoever.
{
MBGL_DEBUG_GROUP("clear");
- context.bindFramebuffer.reset();
+ context.bindFramebuffer.setDirty();
+ view.bind();
context.viewport.reset();
context.stencilFunc.reset();
context.stencilTest = true;
@@ -188,7 +190,7 @@ void Painter::render(const Style& style, const FrameData& frame_, SpriteAtlas& a
#if not MBGL_USE_GLES2 and not defined(NDEBUG)
if (frame.debugOptions & MapDebugOptions::StencilClip) {
- renderClipMasks();
+ renderClipMasks(parameters);
return;
}
#endif
@@ -231,7 +233,7 @@ void Painter::render(const Style& style, const FrameData& frame_, SpriteAtlas& a
#if not MBGL_USE_GLES2 and not defined(NDEBUG)
if (frame.debugOptions & MapDebugOptions::DepthBuffer) {
- renderDepthBuffer();
+ renderDepthBuffer(parameters);
}
#endif
@@ -302,7 +304,8 @@ void Painter::renderPass(PaintParameters& parameters,
setDepthSublayer(0);
layer.as<CustomLayer>()->impl->render(state);
context.setDirtyState();
- context.bindFramebuffer.reset();
+ context.bindFramebuffer.setDirty();
+ parameters.view.bind();
context.viewport.reset();
} else {
MBGL_DEBUG_GROUP(layer.baseImpl->id + " - " + util::toString(item.tile->id));
diff --git a/src/mbgl/renderer/painter.hpp b/src/mbgl/renderer/painter.hpp
index 28aa5aab44..d2c89c04a9 100644
--- a/src/mbgl/renderer/painter.hpp
+++ b/src/mbgl/renderer/painter.hpp
@@ -28,6 +28,7 @@ namespace mbgl {
class RenderTile;
class SpriteAtlas;
+class View;
class GlyphAtlas;
class LineAtlas;
struct FrameData;
@@ -58,7 +59,6 @@ class BackgroundLayer;
} // namespace style
struct FrameData {
- std::array<uint16_t, 2> framebufferSize = {{ 0, 0 }};
TimePoint timePoint;
float pixelRatio;
MapMode mapMode;
@@ -73,6 +73,7 @@ public:
void render(const style::Style&,
const FrameData&,
+ View&,
SpriteAtlas& annotationSpriteAtlas);
void cleanup();
@@ -85,9 +86,9 @@ public:
#ifndef NDEBUG
// Renders tile clip boundaries, using stencil buffer to calculate fill color.
- void renderClipMasks();
+ void renderClipMasks(PaintParameters&);
// Renders the depth buffer.
- void renderDepthBuffer();
+ void renderDepthBuffer(PaintParameters&);
#endif
void renderDebugText(Tile&, const mat4&);
diff --git a/src/mbgl/renderer/painter_debug.cpp b/src/mbgl/renderer/painter_debug.cpp
index 23a2a8e571..ca961f84e7 100644
--- a/src/mbgl/renderer/painter_debug.cpp
+++ b/src/mbgl/renderer/painter_debug.cpp
@@ -1,6 +1,8 @@
#include <mbgl/renderer/painter.hpp>
#include <mbgl/renderer/debug_bucket.hpp>
#include <mbgl/renderer/render_tile.hpp>
+#include <mbgl/renderer/paint_parameters.hpp>
+#include <mbgl/map/view.hpp>
#include <mbgl/tile/tile.hpp>
#include <mbgl/shader/shaders.hpp>
#include <mbgl/util/string.hpp>
@@ -87,7 +89,7 @@ void Painter::renderDebugFrame(const mat4 &matrix) {
}
#ifndef NDEBUG
-void Painter::renderClipMasks() {
+void Painter::renderClipMasks(PaintParameters& parameters) {
context.stencilTest = false;
context.depthTest = false;
context.program = 0;
@@ -98,7 +100,7 @@ void Painter::renderClipMasks() {
context.rasterPos = { -1, -1, 0, 0 };
// Read the stencil buffer
- const auto& fbSize = frame.framebufferSize;
+ const auto& fbSize = parameters.view.getFramebufferSize();
auto pixels = std::make_unique<uint8_t[]>(fbSize[0] * fbSize[1]);
MBGL_CHECK_ERROR(glReadPixels(
0, // GLint x
@@ -120,12 +122,14 @@ void Painter::renderClipMasks() {
MBGL_CHECK_ERROR(glWindowPos2i(0, 0));
MBGL_CHECK_ERROR(glDrawPixels(fbSize[0], fbSize[1], GL_LUMINANCE, GL_UNSIGNED_BYTE, pixels.get()));
+#else
+ (void)parameters;
#endif // MBGL_USE_GLES2
}
#endif // NDEBUG
#ifndef NDEBUG
-void Painter::renderDepthBuffer() {
+void Painter::renderDepthBuffer(PaintParameters& parameters) {
context.stencilTest = false;
context.depthTest = false;
context.program = 0;
@@ -136,7 +140,7 @@ void Painter::renderDepthBuffer() {
context.rasterPos = { -1, -1, 0, 0 };
// Read the stencil buffer
- const auto& fbSize = frame.framebufferSize;
+ const auto& fbSize = parameters.view.getFramebufferSize();
auto pixels = std::make_unique<GLubyte[]>(fbSize[0] * fbSize[1]);
const double base = 1.0 / (1.0 - depthRangeSize);
@@ -155,6 +159,8 @@ void Painter::renderDepthBuffer() {
MBGL_CHECK_ERROR(glWindowPos2i(0, 0));
MBGL_CHECK_ERROR(glDrawPixels(fbSize[0], fbSize[1], GL_LUMINANCE, GL_UNSIGNED_BYTE, pixels.get()));
+#else
+ (void)parameters;
#endif // MBGL_USE_GLES2
}
#endif // NDEBUG
diff --git a/src/mbgl/renderer/painter_fill.cpp b/src/mbgl/renderer/painter_fill.cpp
index 50ead900f6..1fc5f11079 100644
--- a/src/mbgl/renderer/painter_fill.cpp
+++ b/src/mbgl/renderer/painter_fill.cpp
@@ -1,6 +1,7 @@
#include <mbgl/renderer/painter.hpp>
#include <mbgl/renderer/paint_parameters.hpp>
#include <mbgl/gl/gl.hpp>
+#include <mbgl/map/view.hpp>
#include <mbgl/renderer/fill_bucket.hpp>
#include <mbgl/renderer/render_tile.hpp>
@@ -29,7 +30,7 @@ void Painter::renderFill(PaintParameters& parameters,
const bool isOutlineColorDefined = !properties.fillOutlineColor.isUndefined();
Color strokeColor = isOutlineColorDefined? properties.fillOutlineColor : fillColor;
- auto worldSize = util::convert<GLfloat>(frame.framebufferSize);
+ auto worldSize = util::convert<GLfloat>(parameters.view.getFramebufferSize());
bool pattern = !properties.fillPattern.value.from.empty();
bool outline = properties.fillAntialias && !pattern && isOutlineColorDefined;
diff --git a/test/api/annotations.test.cpp b/test/api/annotations.test.cpp
index c1716a5228..53c0182ee9 100644
--- a/test/api/annotations.test.cpp
+++ b/test/api/annotations.test.cpp
@@ -5,7 +5,7 @@
#include <mbgl/annotation/annotation.hpp>
#include <mbgl/sprite/sprite_image.hpp>
#include <mbgl/map/map.hpp>
-#include <mbgl/platform/default/headless_display.hpp>
+#include <mbgl/platform/default/headless_backend.hpp>
#include <mbgl/platform/default/headless_view.hpp>
#include <mbgl/util/io.hpp>
#include <mbgl/util/run_loop.hpp>
@@ -23,11 +23,11 @@ std::shared_ptr<SpriteImage> namedMarker(const std::string &name) {
class AnnotationTest {
public:
util::RunLoop loop;
- std::shared_ptr<HeadlessDisplay> display { std::make_shared<HeadlessDisplay>() };
- HeadlessView view { display, 1 };
+ HeadlessBackend backend;
+ HeadlessView view;
StubFileSource fileSource;
ThreadPool threadPool { 4 };
- Map map { view, fileSource, threadPool, MapMode::Still };
+ Map map { backend, view, view.getPixelRatio(), fileSource, threadPool, MapMode::Still };
void checkRendering(const char * name) {
test::checkImage(std::string("test/fixtures/annotations/") + name,
diff --git a/test/api/api_misuse.test.cpp b/test/api/api_misuse.test.cpp
index 2016e278da..f11363fa3c 100644
--- a/test/api/api_misuse.test.cpp
+++ b/test/api/api_misuse.test.cpp
@@ -3,7 +3,8 @@
#include <mbgl/test/fixture_log_observer.hpp>
#include <mbgl/map/map.hpp>
-#include <mbgl/platform/default/headless_display.hpp>
+#include <mbgl/platform/default/headless_backend.hpp>
+#include <mbgl/platform/default/headless_view.hpp>
#include <mbgl/storage/online_file_source.hpp>
#include <mbgl/platform/default/thread_pool.hpp>
#include <mbgl/util/exception.hpp>
@@ -19,13 +20,14 @@ TEST(API, RenderWithoutCallback) {
util::RunLoop loop;
- auto display = std::make_shared<mbgl::HeadlessDisplay>();
- HeadlessView view(display, 1);
+ HeadlessBackend backend;
+ HeadlessView view;
view.resize(128, 512);
StubFileSource fileSource;
ThreadPool threadPool(4);
- std::unique_ptr<Map> map = std::make_unique<Map>(view, fileSource, threadPool, MapMode::Still);
+ std::unique_ptr<Map> map = std::make_unique<Map>(backend, view, view.getPixelRatio(),
+ fileSource, threadPool, MapMode::Still);
map->renderStill(nullptr);
// Force Map thread to join.
@@ -44,13 +46,13 @@ TEST(API, RenderWithoutCallback) {
TEST(API, RenderWithoutStyle) {
util::RunLoop loop;
- auto display = std::make_shared<mbgl::HeadlessDisplay>();
- HeadlessView view(display, 1);
+ HeadlessBackend backend;
+ HeadlessView view;
view.resize(128, 512);
StubFileSource fileSource;
ThreadPool threadPool(4);
- Map map(view, fileSource, threadPool, MapMode::Still);
+ Map map(backend, view, view.getPixelRatio(), fileSource, threadPool, MapMode::Still);
std::exception_ptr error;
map.renderStill([&](std::exception_ptr error_, PremultipliedImage&&) {
diff --git a/test/api/custom_layer.test.cpp b/test/api/custom_layer.test.cpp
index 1342dfa50c..84ae780174 100644
--- a/test/api/custom_layer.test.cpp
+++ b/test/api/custom_layer.test.cpp
@@ -2,7 +2,7 @@
#include <mbgl/gl/gl.hpp>
#include <mbgl/map/map.hpp>
-#include <mbgl/platform/default/headless_display.hpp>
+#include <mbgl/platform/default/headless_backend.hpp>
#include <mbgl/platform/default/headless_view.hpp>
#include <mbgl/platform/default/thread_pool.hpp>
#include <mbgl/storage/default_file_source.hpp>
@@ -85,8 +85,8 @@ public:
TEST(CustomLayer, Basic) {
util::RunLoop loop;
- auto display = std::make_shared<mbgl::HeadlessDisplay>();
- HeadlessView view(display, 1);
+ HeadlessBackend backend;
+ HeadlessView view;
#ifdef MBGL_ASSET_ZIP
// Regenerate with `cd test/fixtures/api/ && zip -r assets.zip assets/`
@@ -97,7 +97,7 @@ TEST(CustomLayer, Basic) {
ThreadPool threadPool(4);
- Map map(view, fileSource, threadPool, MapMode::Still);
+ Map map(backend, view, view.getPixelRatio(), fileSource, threadPool, MapMode::Still);
map.setStyleJSON(util::read_file("test/fixtures/api/water.json"));
map.setLatLngZoom({ 37.8, -122.5 }, 10);
map.addLayer(std::make_unique<CustomLayer>(
diff --git a/test/api/query.test.cpp b/test/api/query.test.cpp
index da38dd0cb2..d989d222c5 100644
--- a/test/api/query.test.cpp
+++ b/test/api/query.test.cpp
@@ -1,5 +1,5 @@
#include <mbgl/map/map.hpp>
-#include <mbgl/platform/default/headless_display.hpp>
+#include <mbgl/platform/default/headless_backend.hpp>
#include <mbgl/platform/default/headless_view.hpp>
#include <mbgl/platform/default/thread_pool.hpp>
#include <mbgl/sprite/sprite_image.hpp>
@@ -26,11 +26,11 @@ public:
}
util::RunLoop loop;
- std::shared_ptr<HeadlessDisplay> display { std::make_shared<HeadlessDisplay>() };
- HeadlessView view { display, 1 };
+ HeadlessBackend backend;
+ HeadlessView view;
StubFileSource fileSource;
ThreadPool threadPool { 4 };
- Map map { view, fileSource, threadPool, MapMode::Still };
+ Map map { backend, view, view.getPixelRatio(), fileSource, threadPool, MapMode::Still };
};
} // end namespace
diff --git a/test/api/render_missing.test.cpp b/test/api/render_missing.test.cpp
index d57a5a98bd..8123070282 100644
--- a/test/api/render_missing.test.cpp
+++ b/test/api/render_missing.test.cpp
@@ -2,7 +2,7 @@
#include <mbgl/test/fixture_log_observer.hpp>
#include <mbgl/map/map.hpp>
-#include <mbgl/platform/default/headless_display.hpp>
+#include <mbgl/platform/default/headless_backend.hpp>
#include <mbgl/platform/default/headless_view.hpp>
#include <mbgl/platform/default/thread_pool.hpp>
#include <mbgl/storage/default_file_source.hpp>
@@ -25,8 +25,8 @@ TEST(API, TEST_REQUIRES_SERVER(RenderMissingTile)) {
const auto style = util::read_file("test/fixtures/api/water_missing_tiles.json");
- auto display = std::make_shared<mbgl::HeadlessDisplay>();
- HeadlessView view(display, 1, 256, 512);
+ HeadlessBackend backend;
+ HeadlessView view(1, 256, 512);
#ifdef MBGL_ASSET_ZIP
// Regenerate with `cd test/fixtures/api/ && zip -r assets.zip assets/`
DefaultFileSource fileSource(":memory:", "test/fixtures/api/assets.zip");
@@ -38,7 +38,7 @@ TEST(API, TEST_REQUIRES_SERVER(RenderMissingTile)) {
Log::setObserver(std::make_unique<FixtureLogObserver>());
- Map map(view, fileSource, threadPool, MapMode::Still);
+ Map map(backend, view, view.getPixelRatio(), fileSource, threadPool, MapMode::Still);
std::string message;
diff --git a/test/api/repeated_render.test.cpp b/test/api/repeated_render.test.cpp
index 4229f9d7ad..5bc57198bd 100644
--- a/test/api/repeated_render.test.cpp
+++ b/test/api/repeated_render.test.cpp
@@ -2,7 +2,7 @@
#include <mbgl/test/fixture_log_observer.hpp>
#include <mbgl/map/map.hpp>
-#include <mbgl/platform/default/headless_display.hpp>
+#include <mbgl/platform/default/headless_backend.hpp>
#include <mbgl/platform/default/headless_view.hpp>
#include <mbgl/platform/default/thread_pool.hpp>
#include <mbgl/storage/default_file_source.hpp>
@@ -19,9 +19,8 @@ TEST(API, RepeatedRender) {
const auto style = util::read_file("test/fixtures/api/water.json");
- auto display = std::make_shared<mbgl::HeadlessDisplay>();
- HeadlessView view(display, 1, 256, 512);
-
+ HeadlessBackend backend;
+ HeadlessView view(1, 256, 512);
#ifdef MBGL_ASSET_ZIP
// Regenerate with `cd test/fixtures/api/ && zip -r assets.zip assets/`
DefaultFileSource fileSource(":memory:", "test/fixtures/api/assets.zip");
@@ -33,7 +32,7 @@ TEST(API, RepeatedRender) {
Log::setObserver(std::make_unique<FixtureLogObserver>());
- Map map(view, fileSource, threadPool, MapMode::Still);
+ Map map(backend, view, view.getPixelRatio(), fileSource, threadPool, MapMode::Still);
{
map.setStyleJSON(style);
diff --git a/test/gl/object.test.cpp b/test/gl/object.test.cpp
index 1a90cec83b..1f9d48cff7 100644
--- a/test/gl/object.test.cpp
+++ b/test/gl/object.test.cpp
@@ -1,6 +1,6 @@
#include <mbgl/test/util.hpp>
-#include <mbgl/platform/default/headless_display.hpp>
+#include <mbgl/platform/default/headless_backend.hpp>
#include <mbgl/platform/default/headless_view.hpp>
#include <mbgl/gl/gl.hpp>
@@ -67,8 +67,8 @@ TEST(GLObject, Value) {
}
TEST(GLObject, Store) {
- mbgl::HeadlessView view(std::make_shared<mbgl::HeadlessDisplay>(), 1);
- view.activate();
+ mbgl::HeadlessBackend backend;
+ mbgl::HeadlessView view;
mbgl::gl::Context context;
EXPECT_TRUE(context.empty());
@@ -106,5 +106,5 @@ TEST(GLObject, Store) {
context.reset();
EXPECT_TRUE(context.empty());
- view.deactivate();
+ backend.deactivate();
}
diff --git a/test/map/map.test.cpp b/test/map/map.test.cpp
index c03a038dc0..a5d634e77a 100644
--- a/test/map/map.test.cpp
+++ b/test/map/map.test.cpp
@@ -4,7 +4,7 @@
#include <mbgl/test/fixture_log_observer.hpp>
#include <mbgl/map/map.hpp>
-#include <mbgl/platform/default/headless_display.hpp>
+#include <mbgl/platform/default/headless_backend.hpp>
#include <mbgl/platform/default/headless_view.hpp>
#include <mbgl/platform/default/thread_pool.hpp>
#include <mbgl/sprite/sprite_image.hpp>
@@ -22,15 +22,16 @@ using namespace std::literals::string_literals;
struct MapTest {
util::RunLoop runLoop;
- std::shared_ptr<HeadlessDisplay> display { std::make_shared<mbgl::HeadlessDisplay>() };
- HeadlessView view { display, 1 };
+ HeadlessBackend backend;
+ HeadlessView view;
StubFileSource fileSource;
ThreadPool threadPool { 4 };
};
TEST(Map, LatLngBehavior) {
MapTest test;
- Map map(test.view, test.fileSource, test.threadPool, MapMode::Still);
+ Map map(test.backend, test.view, test.view.getPixelRatio(), test.fileSource, test.threadPool,
+ MapMode::Still);
map.setStyleJSON(util::read_file("test/fixtures/api/empty.json"));
@@ -64,7 +65,8 @@ TEST(Map, Offline) {
fileSource.put(Resource::glyphs(prefix + "{fontstack}/{range}.pbf", {{"Helvetica"}}, {0, 255}), expiredItem("glyph.pbf"));
NetworkStatus::Set(NetworkStatus::Status::Offline);
- Map map(test.view, fileSource, test.threadPool, MapMode::Still);
+ Map map(test.backend, test.view, test.view.getPixelRatio(), fileSource, test.threadPool,
+ MapMode::Still);
map.setStyleURL(prefix + "style.json");
test::checkImage("test/fixtures/map/offline",
@@ -81,14 +83,15 @@ TEST(Map, SetStyleInvalidJSON) {
Log::setObserver(std::make_unique<FixtureLogObserver>());
bool fail = false;
- test.view.setMapChangeCallback([&](MapChange change) {
+ test.backend.setMapChangeCallback([&](MapChange change) {
if (change == mbgl::MapChangeDidFailLoadingMap) {
fail = true;
}
});
{
- Map map(test.view, test.fileSource, test.threadPool, MapMode::Still);
+ Map map(test.backend, test.view, test.view.getPixelRatio(), test.fileSource,
+ test.threadPool, MapMode::Still);
map.setStyleJSON("invalid");
}
@@ -113,13 +116,14 @@ TEST(Map, SetStyleInvalidURL) {
return response;
};
- test.view.setMapChangeCallback([&](MapChange change) {
+ test.backend.setMapChangeCallback([&](MapChange change) {
if (change == mbgl::MapChangeDidFailLoadingMap) {
test.runLoop.stop();
}
});
- Map map(test.view, test.fileSource, test.threadPool, MapMode::Still);
+ Map map(test.backend, test.view, test.view.getPixelRatio(), test.fileSource, test.threadPool,
+ MapMode::Still);
map.setStyleURL("mapbox://bar");
test.runLoop.run();
@@ -128,7 +132,8 @@ TEST(Map, SetStyleInvalidURL) {
TEST(Map, DoubleStyleLoad) {
MapTest test;
- Map map(test.view, test.fileSource, test.threadPool, MapMode::Still);
+ Map map(test.backend, test.view, test.view.getPixelRatio(), test.fileSource, test.threadPool,
+ MapMode::Still);
map.setStyleJSON("");
map.setStyleJSON("");
}
@@ -139,7 +144,8 @@ TEST(Map, StyleFresh) {
MapTest test;
FakeFileSource fileSource;
- Map map(test.view, fileSource, test.threadPool, MapMode::Still);
+ Map map(test.backend, test.view, test.view.getPixelRatio(), fileSource, test.threadPool,
+ MapMode::Still);
map.setStyleURL("mapbox://styles/test");
EXPECT_EQ(1u, fileSource.requests.size());
@@ -159,7 +165,8 @@ TEST(Map, StyleExpired) {
MapTest test;
FakeFileSource fileSource;
- Map map(test.view, fileSource, test.threadPool, MapMode::Still);
+ Map map(test.backend, test.view, test.view.getPixelRatio(), fileSource, test.threadPool,
+ MapMode::Still);
map.setStyleURL("mapbox://styles/test");
EXPECT_EQ(1u, fileSource.requests.size());
@@ -186,7 +193,8 @@ TEST(Map, StyleExpiredWithAnnotations) {
MapTest test;
FakeFileSource fileSource;
- Map map(test.view, fileSource, test.threadPool, MapMode::Still);
+ Map map(test.backend, test.view, test.view.getPixelRatio(), fileSource, test.threadPool,
+ MapMode::Still);
map.setStyleURL("mapbox://styles/test");
EXPECT_EQ(1u, fileSource.requests.size());
@@ -210,7 +218,8 @@ TEST(Map, StyleEarlyMutation) {
MapTest test;
FakeFileSource fileSource;
- Map map(test.view, fileSource, test.threadPool, MapMode::Still);
+ Map map(test.backend, test.view, test.view.getPixelRatio(), fileSource, test.threadPool,
+ MapMode::Still);
map.setStyleURL("mapbox://styles/test");
map.addLayer(std::make_unique<style::BackgroundLayer>("bg"));
@@ -224,11 +233,12 @@ TEST(Map, StyleEarlyMutation) {
TEST(Map, StyleLoadedSignal) {
MapTest test;
- Map map(test.view, test.fileSource, test.threadPool, MapMode::Still);
-
+ Map map(test.backend, test.view, test.view.getPixelRatio(), test.fileSource, test.threadPool,
+ MapMode::Still);
+
// The map should emit a signal on style loaded
bool emitted = false;
- test.view.setMapChangeCallback([&](MapChange change) {
+ test.backend.setMapChangeCallback([&](MapChange change) {
if (change == mbgl::MapChangeDidFinishLoadingStyle) {
emitted = true;
}
@@ -245,7 +255,8 @@ TEST(Map, StyleLoadedSignal) {
TEST(Map, AddLayer) {
MapTest test;
- Map map(test.view, test.fileSource, test.threadPool, MapMode::Still);
+ Map map(test.backend, test.view, test.view.getPixelRatio(), test.fileSource, test.threadPool,
+ MapMode::Still);
map.setStyleJSON(util::read_file("test/fixtures/api/empty.json"));
auto layer = std::make_unique<BackgroundLayer>("background");
@@ -258,7 +269,8 @@ TEST(Map, AddLayer) {
TEST(Map, RemoveLayer) {
MapTest test;
- Map map(test.view, test.fileSource, test.threadPool, MapMode::Still);
+ Map map(test.backend, test.view, test.view.getPixelRatio(), test.fileSource, test.threadPool,
+ MapMode::Still);
map.setStyleJSON(util::read_file("test/fixtures/api/empty.json"));
auto layer = std::make_unique<BackgroundLayer>("background");
@@ -283,7 +295,8 @@ TEST(Map, DisabledSources) {
return {};
};
- Map map(test.view, test.fileSource, test.threadPool, MapMode::Still);
+ Map map(test.backend, test.view, test.view.getPixelRatio(), test.fileSource, test.threadPool,
+ MapMode::Still);
map.setZoom(1);
// This stylesheet has two raster layers, one that starts at zoom 1, the other at zoom 0.
@@ -333,7 +346,8 @@ TEST(Map, DisabledSources) {
TEST(Map, Classes) {
MapTest test;
- Map map(test.view, test.fileSource, test.threadPool, MapMode::Still);
+ Map map(test.backend, test.view, test.view.getPixelRatio(), test.fileSource, test.threadPool,
+ MapMode::Still);
map.setStyleJSON(util::read_file("test/fixtures/api/empty.json"));
EXPECT_FALSE(map.getTransitionOptions().duration);
@@ -367,7 +381,8 @@ TEST(Map, Classes) {
TEST(Map, AddImage) {
MapTest test;
- Map map(test.view, test.fileSource, test.threadPool, MapMode::Still);
+ Map map(test.backend, test.view, test.view.getPixelRatio(), test.fileSource, test.threadPool,
+ MapMode::Still);
auto decoded1 = decodeImage(util::read_file("test/fixtures/sprites/default_marker.png"));
auto decoded2 = decodeImage(util::read_file("test/fixtures/sprites/default_marker.png"));
auto image1 = std::make_unique<SpriteImage>(std::move(decoded1), 1.0);
@@ -384,7 +399,8 @@ TEST(Map, AddImage) {
TEST(Map, RemoveImage) {
MapTest test;
- Map map(test.view, test.fileSource, test.threadPool, MapMode::Still);
+ Map map(test.backend, test.view, test.view.getPixelRatio(), test.fileSource, test.threadPool,
+ MapMode::Still);
auto decoded = decodeImage(util::read_file("test/fixtures/sprites/default_marker.png"));
auto image = std::make_unique<SpriteImage>(std::move(decoded), 1.0);
diff --git a/test/util/memory.test.cpp b/test/util/memory.test.cpp
index e2ace99c41..2ab3a03799 100644
--- a/test/util/memory.test.cpp
+++ b/test/util/memory.test.cpp
@@ -2,7 +2,7 @@
#include <mbgl/test/util.hpp>
#include <mbgl/map/map.hpp>
-#include <mbgl/platform/default/headless_display.hpp>
+#include <mbgl/platform/default/headless_backend.hpp>
#include <mbgl/platform/default/headless_view.hpp>
#include <mbgl/platform/default/thread_pool.hpp>
#include <mbgl/util/io.hpp>
@@ -56,8 +56,8 @@ public:
}
util::RunLoop runLoop;
- std::shared_ptr<HeadlessDisplay> display { std::make_shared<mbgl::HeadlessDisplay>() };
- HeadlessView view { display, 2 };
+ HeadlessBackend backend;
+ HeadlessView view{ 2 };
StubFileSource fileSource;
ThreadPool threadPool { 4 };
@@ -93,7 +93,8 @@ private:
TEST(Memory, Vector) {
MemoryTest test;
- Map map(test.view, test.fileSource, test.threadPool, MapMode::Still);
+ Map map(test.backend, test.view, test.view.getPixelRatio(), test.fileSource, test.threadPool,
+ MapMode::Still);
map.setZoom(16); // more map features
map.setStyleURL("mapbox://streets");
@@ -103,7 +104,8 @@ TEST(Memory, Vector) {
TEST(Memory, Raster) {
MemoryTest test;
- Map map(test.view, test.fileSource, test.threadPool, MapMode::Still);
+ Map map(test.backend, test.view, test.view.getPixelRatio(), test.fileSource, test.threadPool,
+ MapMode::Still);
map.setStyleURL("mapbox://satellite");
test::render(map);
@@ -130,7 +132,8 @@ TEST(Memory, Footprint) {
// Warm up buffers and cache.
for (unsigned i = 0; i < 10; ++i) {
- Map map(test.view, test.fileSource,test.threadPool, MapMode::Still);
+ Map map(test.backend, test.view, test.view.getPixelRatio(), test.fileSource,
+ test.threadPool, MapMode::Still);
renderMap(&map, "mapbox://streets");
renderMap(&map, "mapbox://satellite");
};
@@ -144,7 +147,8 @@ TEST(Memory, Footprint) {
long vectorInitialRSS = getRSS();
for (unsigned i = 0; i < runs; ++i) {
- auto vector = std::make_unique<Map>(test.view, test.fileSource, test.threadPool, MapMode::Still);
+ auto vector = std::make_unique<Map>(test.backend, test.view, test.view.getPixelRatio(),
+ test.fileSource, test.threadPool, MapMode::Still);
renderMap(vector.get(), "mapbox://streets");
maps.push_back(std::move(vector));
};
@@ -153,7 +157,8 @@ TEST(Memory, Footprint) {
long rasterInitialRSS = getRSS();
for (unsigned i = 0; i < runs; ++i) {
- auto raster = std::make_unique<Map>(test.view, test.fileSource, test.threadPool, MapMode::Still);
+ auto raster = std::make_unique<Map>(test.backend, test.view, test.view.getPixelRatio(),
+ test.fileSource, test.threadPool, MapMode::Still);
renderMap(raster.get(), "mapbox://satellite");
maps.push_back(std::move(raster));
};
diff --git a/test/util/offscreen_texture.test.cpp b/test/util/offscreen_texture.test.cpp
index 301fc2c250..e281a3d65b 100644
--- a/test/util/offscreen_texture.test.cpp
+++ b/test/util/offscreen_texture.test.cpp
@@ -1,15 +1,18 @@
#include <mbgl/test/util.hpp>
#include <mbgl/gl/context.hpp>
+#include <mbgl/platform/default/headless_backend.hpp>
#include <mbgl/platform/default/headless_view.hpp>
+#include <mbgl/gl/gl.hpp>
#include <mbgl/util/offscreen_texture.hpp>
using namespace mbgl;
TEST(OffscreenTexture, EmptyRed) {
+ HeadlessBackend backend;
HeadlessView view(1.0f, 512, 256);
- view.activate();
+ view.bind();
MBGL_CHECK_ERROR(glClearColor(1.0f, 0.0f, 0.0f, 1.0f));
MBGL_CHECK_ERROR(glClear(GL_COLOR_BUFFER_BIT));
@@ -64,11 +67,11 @@ struct Buffer {
TEST(OffscreenTexture, RenderToTexture) {
+ HeadlessBackend backend;
HeadlessView view(1.0f, 512, 256);
- view.activate();
+ view.bind();
gl::Context context;
context.viewport.setDefaultValue(gl::value::Viewport::Get());
- context.bindFramebuffer.setDefaultValue(gl::value::BindFramebuffer::Get());
MBGL_CHECK_ERROR(glEnable(GL_BLEND));
MBGL_CHECK_ERROR(glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA));
@@ -130,6 +133,8 @@ void main() {
// Now reset the FBO back to normal and retrieve the original (restored) framebuffer.
context.resetState();
+ context.bindFramebuffer.setDirty();
+ view.bind();
image = view.readStillImage();
test::checkImage("test/fixtures/offscreen_texture/render-to-fbo", image, 0, 0);