summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--android/cpp/jni.cpp27
-rw-r--r--android/cpp/native_map_view.cpp26
-rw-r--r--android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxgl/views/MapView.java11
-rw-r--r--android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxgl/views/NativeMapView.java29
-rw-r--r--bin/render.cpp3
-rw-r--r--include/mbgl/android/native_map_view.hpp14
-rw-r--r--include/mbgl/map/map.hpp1
-rw-r--r--include/mbgl/map/update.hpp1
-rw-r--r--include/mbgl/map/view.hpp18
-rw-r--r--include/mbgl/platform/default/glfw_view.hpp10
-rw-r--r--include/mbgl/platform/default/headless_view.hpp25
-rw-r--r--platform/default/glfw_view.cpp36
-rw-r--r--platform/default/headless_view.cpp69
-rw-r--r--platform/ios/MGLMapView.mm39
-rw-r--r--src/mbgl/map/map.cpp25
-rw-r--r--src/mbgl/map/map_context.cpp15
-rw-r--r--src/mbgl/map/map_context.hpp12
-rw-r--r--src/mbgl/map/map_data.hpp6
-rw-r--r--src/mbgl/map/source.cpp4
-rw-r--r--src/mbgl/map/transform.cpp13
-rw-r--r--src/mbgl/map/transform.hpp4
-rw-r--r--src/mbgl/map/transform_state.cpp17
-rw-r--r--src/mbgl/map/transform_state.hpp11
-rw-r--r--src/mbgl/map/view.cpp4
-rw-r--r--src/mbgl/renderer/painter.cpp10
-rw-r--r--src/mbgl/renderer/painter.hpp9
-rw-r--r--src/mbgl/renderer/painter_debug.cpp6
-rw-r--r--src/mbgl/renderer/painter_fill.cpp8
-rw-r--r--src/mbgl/renderer/painter_line.cpp11
-rw-r--r--src/mbgl/renderer/painter_symbol.cpp2
-rw-r--r--src/mbgl/style/style.cpp8
-rw-r--r--test/api/api_misuse.cpp8
-rw-r--r--test/api/repeated_render.cpp10
-rw-r--r--test/api/set_style.cpp2
-rw-r--r--test/fixtures/mock_view.hpp6
-rw-r--r--test/headless/headless.cpp3
-rw-r--r--test/miscellaneous/map.cpp8
-rw-r--r--test/miscellaneous/map_context.cpp4
-rw-r--r--test/style/pending_resources.cpp3
-rw-r--r--test/style/resource_loading.cpp4
40 files changed, 308 insertions, 214 deletions
diff --git a/android/cpp/jni.cpp b/android/cpp/jni.cpp
index 36ef273d68..cfb1291bcd 100644
--- a/android/cpp/jni.cpp
+++ b/android/cpp/jni.cpp
@@ -180,12 +180,12 @@ namespace {
using namespace mbgl::android;
jlong JNICALL
-nativeCreate(JNIEnv *env, jobject obj, jstring cachePath_, jstring dataPath_, jstring apkPath_) {
+nativeCreate(JNIEnv *env, jobject obj, jstring cachePath_, jstring dataPath_, jstring apkPath_, jfloat pixelRatio) {
mbgl::Log::Debug(mbgl::Event::JNI, "nativeCreate");
cachePath = std_string_from_jstring(env, cachePath_);
dataPath = std_string_from_jstring(env, dataPath_);
apkPath = std_string_from_jstring(env, apkPath_);
- NativeMapView *nativeMapView = new NativeMapView(env, obj);
+ NativeMapView *nativeMapView = new NativeMapView(env, obj, pixelRatio);
jlong mapViewPtr = reinterpret_cast<jlong>(nativeMapView);
return mapViewPtr;
}
@@ -285,20 +285,26 @@ void JNICALL nativeOnInvalidate(JNIEnv *env, jobject obj, jlong nativeMapViewPtr
nativeMapView->onInvalidate();
}
-void JNICALL nativeResize(JNIEnv *env, jobject obj, jlong nativeMapViewPtr, jint width, jint height,
- jfloat ratio, jint fbWidth, jint fbHeight) {
- mbgl::Log::Debug(mbgl::Event::JNI, "nativeResize");
+void JNICALL nativeViewResize(JNIEnv *env, jobject obj, jlong nativeMapViewPtr, jint width, jint height) {
+ mbgl::Log::Debug(mbgl::Event::JNI, "nativeViewResize");
assert(nativeMapViewPtr != 0);
assert(width >= 0);
assert(height >= 0);
assert(width <= UINT16_MAX);
assert(height <= UINT16_MAX);
+ NativeMapView *nativeMapView = reinterpret_cast<NativeMapView *>(nativeMapViewPtr);
+ nativeMapView->resizeView(width, height);
+}
+
+void JNICALL nativeFramebufferResize(JNIEnv *env, jobject obj, jlong nativeMapViewPtr, jint fbWidth, jint fbHeight) {
+ mbgl::Log::Debug(mbgl::Event::JNI, "nativeFramebufferResize");
+ assert(nativeMapViewPtr != 0);
assert(fbWidth >= 0);
assert(fbHeight >= 0);
assert(fbWidth <= UINT16_MAX);
assert(fbHeight <= UINT16_MAX);
NativeMapView *nativeMapView = reinterpret_cast<NativeMapView *>(nativeMapViewPtr);
- nativeMapView->getMap().resize(width, height, ratio);
+ nativeMapView->resizeFramebuffer(fbWidth, fbHeight);
}
void JNICALL nativeRemoveClass(JNIEnv *env, jobject obj, jlong nativeMapViewPtr, jstring clazz) {
@@ -922,7 +928,7 @@ extern "C" JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) {
}
const std::vector<JNINativeMethod> methods = {
- {"nativeCreate", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)J",
+ {"nativeCreate", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;F)J",
reinterpret_cast<void *>(&nativeCreate)},
{"nativeDestroy", "(J)V", reinterpret_cast<void *>(&nativeDestroy)},
{"nativeInitializeDisplay", "(J)V", reinterpret_cast<void *>(&nativeInitializeDisplay)},
@@ -936,9 +942,12 @@ extern "C" JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) {
{"nativeResume", "(J)V", reinterpret_cast<void *>(&nativeResume)},
{"nativeUpdate", "(J)V", reinterpret_cast<void *>(&nativeUpdate)},
{"nativeOnInvalidate", "(J)V", reinterpret_cast<void *>(&nativeOnInvalidate)},
- {"nativeResize", "(JIIFII)V",
+ {"nativeViewResize", "(JII)V",
+ reinterpret_cast<void *>(static_cast<void JNICALL (
+ *)(JNIEnv *, jobject, jlong, jint, jint)>(&nativeViewResize))},
+ {"nativeFramebufferResize", "(JII)V",
reinterpret_cast<void *>(static_cast<void JNICALL (
- *)(JNIEnv *, jobject, jlong, jint, jint, jfloat, jint, jint)>(&nativeResize))},
+ *)(JNIEnv *, jobject, jlong, jint, jint)>(&nativeFramebufferResize))},
{"nativeAddClass", "(JLjava/lang/String;)V",
reinterpret_cast<void *>(&nativeAddClass)},
{"nativeRemoveClass", "(JLjava/lang/String;)V",
diff --git a/android/cpp/native_map_view.cpp b/android/cpp/native_map_view.cpp
index 983797767a..ebdc7f7f68 100644
--- a/android/cpp/native_map_view.cpp
+++ b/android/cpp/native_map_view.cpp
@@ -52,8 +52,9 @@ void log_gl_string(GLenum name, const char *label) {
}
}
-NativeMapView::NativeMapView(JNIEnv *env, jobject obj_)
+NativeMapView::NativeMapView(JNIEnv *env, jobject obj_, float pixelRatio_)
: mbgl::View(*this),
+ pixelRatio(pixelRatio_),
fileCache(mbgl::android::cachePath + "/mbgl-cache.db"),
fileSource(&fileCache),
map(*this, fileSource, MapMode::Continuous) {
@@ -98,6 +99,18 @@ NativeMapView::~NativeMapView() {
vm = nullptr;
}
+float NativeMapView::getPixelRatio() const {
+ return pixelRatio;
+}
+
+std::array<uint16_t, 2> NativeMapView::getSize() const {
+ return {{ static_cast<uint16_t>(width), static_cast<uint16_t>(height) }};
+}
+
+std::array<uint16_t, 2> NativeMapView::getFramebufferSize() const {
+ return {{ static_cast<uint16_t>(fbWidth), static_cast<uint16_t>(fbHeight) }};
+}
+
void NativeMapView::activate() {
mbgl::Log::Debug(mbgl::Event::Android, "NativeMapView::activate");
if ((display != EGL_NO_DISPLAY) && (surface != EGL_NO_SURFACE) && (context != EGL_NO_CONTEXT)) {
@@ -754,5 +767,16 @@ void NativeMapView::onInvalidate() {
}
}
+void NativeMapView::resizeView(int w, int h) {
+ width = w;
+ height = h;
+ map.update(mbgl::Update::Dimensions);
+}
+
+void NativeMapView::resizeFramebuffer(int w, int h) {
+ fbWidth = w;
+ fbHeight = h;
+}
+
}
}
diff --git a/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxgl/views/MapView.java b/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxgl/views/MapView.java
index f5ebad4fb2..0f359ab100 100644
--- a/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxgl/views/MapView.java
+++ b/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxgl/views/MapView.java
@@ -145,7 +145,7 @@ public class MapView extends SurfaceView {
String apkPath = context.getPackageCodePath();
// Create the NativeMapView
- mNativeMapView = new NativeMapView(this, cachePath, dataPath, apkPath);
+ mNativeMapView = new NativeMapView(this, cachePath, dataPath, apkPath, mScreenDensity);
// Load the attributes
TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.MapView, 0, 0);
@@ -477,6 +477,10 @@ public class MapView extends SurfaceView {
mNativeMapView.resume();
}
+ public void onSizeChanged(int width, int height, int oldw, int oldh) {
+ mNativeMapView.resizeView((int)(width / mScreenDensity), (int)(height / mScreenDensity));
+ }
+
// This class handles SurfaceHolder callbacks
private class Callbacks implements SurfaceHolder.Callback {
@@ -498,9 +502,8 @@ public class MapView extends SurfaceView {
// changed
// Must handle window resizing here.
@Override
- public void surfaceChanged(SurfaceHolder holder, int format, int width,
- int height) {
- mNativeMapView.resize((int) (width / mScreenDensity), (int) (height / mScreenDensity), mScreenDensity, width, height);
+ public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
+ mNativeMapView.resizeFramebuffer(width, height);
}
}
diff --git a/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxgl/views/NativeMapView.java b/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxgl/views/NativeMapView.java
index 6c27d5f2df..643fcbd720 100644
--- a/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxgl/views/NativeMapView.java
+++ b/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxgl/views/NativeMapView.java
@@ -39,11 +39,11 @@ class NativeMapView {
// Constructors
//
- public NativeMapView(MapView mapView, String cachePath, String dataPath, String apkPath) {
+ public NativeMapView(MapView mapView, String cachePath, String dataPath, String apkPath, float pixelRatio) {
mMapView = mapView;
// Create the NativeMapView
- mNativeMapViewPtr = nativeCreate(cachePath, dataPath, apkPath);
+ mNativeMapViewPtr = nativeCreate(cachePath, dataPath, apkPath, pixelRatio);
}
//
@@ -90,8 +90,7 @@ class NativeMapView {
nativeOnInvalidate(mNativeMapViewPtr);
}
- public void resize(int width, int height, float ratio, int fbWidth,
- int fbHeight) {
+ public void resizeView(int width, int height) {
if (width < 0) {
throw new IllegalArgumentException("width cannot be negative.");
}
@@ -100,6 +99,19 @@ class NativeMapView {
throw new IllegalArgumentException("height cannot be negative.");
}
+ if (width > 65535) {
+ throw new IllegalArgumentException(
+ "width cannot be greater than 65535.");
+ }
+
+ if (height > 65535) {
+ throw new IllegalArgumentException(
+ "height cannot be greater than 65535.");
+ }
+ nativeViewResize(mNativeMapViewPtr, width, height);
+ }
+
+ public void resizeFramebuffer(int fbWidth, int fbHeight) {
if (fbWidth < 0) {
throw new IllegalArgumentException("fbWidth cannot be negative.");
}
@@ -117,7 +129,7 @@ class NativeMapView {
throw new IllegalArgumentException(
"fbHeight cannot be greater than 65535.");
}
- nativeResize(mNativeMapViewPtr, width, height, ratio, fbWidth, fbHeight);
+ nativeFramebufferResize(mNativeMapViewPtr, fbWidth, fbHeight);
}
public void addClass(String clazz) {
@@ -370,7 +382,7 @@ class NativeMapView {
super.finalize();
}
- private native long nativeCreate(String cachePath, String dataPath, String apkPath);
+ private native long nativeCreate(String cachePath, String dataPath, String apkPath, float pixelRatio);
private native void nativeDestroy(long nativeMapViewPtr);
@@ -395,8 +407,9 @@ class NativeMapView {
private native void nativeOnInvalidate(long nativeMapViewPtr);
- private native void nativeResize(long nativeMapViewPtr, int width,
- int height, float ratio, int fbWidth, int fbHeight);
+ private native void nativeViewResize(long nativeMapViewPtr, int width, int height);
+
+ private native void nativeFramebufferResize(long nativeMapViewPtr, int fbWidth, int fbHeight);
private native void nativeAddClass(long nativeMapViewPtr, String clazz);
diff --git a/bin/render.cpp b/bin/render.cpp
index 5ae83c1d48..3da0c93586 100644
--- a/bin/render.cpp
+++ b/bin/render.cpp
@@ -85,13 +85,12 @@ int main(int argc, char *argv[]) {
fileSource.setAccessToken(std::string(token));
}
- HeadlessView view;
+ HeadlessView view(pixelRatio, width, height);
Map map(view, fileSource, MapMode::Still);
map.setStyleJSON(style, ".");
map.setClasses(classes);
- map.resize(width, height, pixelRatio);
map.setLatLngZoom({ lat, lon }, zoom);
map.setBearing(bearing);
diff --git a/include/mbgl/android/native_map_view.hpp b/include/mbgl/android/native_map_view.hpp
index af8f76bd74..5e0df4dd44 100644
--- a/include/mbgl/android/native_map_view.hpp
+++ b/include/mbgl/android/native_map_view.hpp
@@ -17,9 +17,12 @@ namespace android {
class NativeMapView : public mbgl::View, private mbgl::util::noncopyable {
public:
- NativeMapView(JNIEnv *env, jobject obj);
+ NativeMapView(JNIEnv *env, jobject obj, float pixelRatio);
virtual ~NativeMapView();
+ float getPixelRatio() const override;
+ std::array<uint16_t, 2> getSize() const override;
+ std::array<uint16_t, 2> getFramebufferSize() const override;
void activate() override;
void deactivate() override;
void notify() override;
@@ -48,6 +51,9 @@ public:
void onInvalidate();
+ void resizeView(int width, int height);
+ void resizeFramebuffer(int width, int height);
+
private:
EGLConfig chooseConfig(const EGLConfig configs[], EGLint numConfigs);
@@ -73,6 +79,12 @@ private:
bool fpsEnabled = false;
double fps = 0.0;
+ int width = 0;
+ int height = 0;
+ int fbWidth = 0;
+ int fbHeight = 0;
+ const float pixelRatio;
+
// Ensure these are initialised last
mbgl::SQLiteCache fileCache;
mbgl::DefaultFileSource fileSource;
diff --git a/include/mbgl/map/map.hpp b/include/mbgl/map/map.hpp
index e1dd4671b2..e9d25bfe89 100644
--- a/include/mbgl/map/map.hpp
+++ b/include/mbgl/map/map.hpp
@@ -113,7 +113,6 @@ public:
void resetNorth();
// Size
- void resize(uint16_t width, uint16_t height, float ratio = 1);
uint16_t getWidth() const;
uint16_t getHeight() const;
diff --git a/include/mbgl/map/update.hpp b/include/mbgl/map/update.hpp
index b4c6b5f13c..40cc1bc2bc 100644
--- a/include/mbgl/map/update.hpp
+++ b/include/mbgl/map/update.hpp
@@ -9,6 +9,7 @@ using UpdateType = uint32_t;
enum class Update : UpdateType {
Nothing = 0,
+ Dimensions = 1 << 1,
DefaultTransitionDuration = 1 << 2,
Classes = 1 << 3,
Zoom = 1 << 4,
diff --git a/include/mbgl/map/view.hpp b/include/mbgl/map/view.hpp
index 575d0df015..3086d51aab 100644
--- a/include/mbgl/map/view.hpp
+++ b/include/mbgl/map/view.hpp
@@ -30,6 +30,21 @@ enum MapChange : uint8_t {
class View {
public:
+ // Called from the main thread directly after initialization. Must always return the same value,
+ // i.e. it may not change over time.
+ virtual float getPixelRatio() const = 0;
+
+ // Called from the main thread when the View signaled a dimension change. Must return the
+ // logical dimension of this map in pixels.
+ virtual std::array<uint16_t, 2> getSize() const = 0;
+
+ // Called from the main thread for every frame that is being rendered. Must return the absolute
+ // dimensions of the current framebuffer. Typically, this is the logical width scaled by the
+ // pixel ratio, but in case the view was moved to display with a different pixel ratio, it can
+ // also be different from that rule.
+ virtual std::array<uint16_t, 2> getFramebufferSize() const = 0;
+
+ // Called from the main thread when this View is associated with a Map object.
virtual void initialize(Map *map_);
// Called from the render thread. Makes the GL context active in the current
@@ -43,9 +58,6 @@ public:
virtual void notify() = 0;
- // Called from the render thread. The implementation should resize the framebuffer.
- virtual void resize(uint16_t width, uint16_t height, float pixelRatio);
-
// Called from the render thread. The implementation must trigger a rerender.
// (map->renderSync() from the main thread must be called as a result of this)
virtual void invalidate() = 0;
diff --git a/include/mbgl/platform/default/glfw_view.hpp b/include/mbgl/platform/default/glfw_view.hpp
index 6e03953cbd..cb40db1248 100644
--- a/include/mbgl/platform/default/glfw_view.hpp
+++ b/include/mbgl/platform/default/glfw_view.hpp
@@ -15,6 +15,10 @@ public:
GLFWView(bool fullscreen = false);
~GLFWView();
+ float getPixelRatio() const override;
+ std::array<uint16_t, 2> getSize() const override;
+ std::array<uint16_t, 2> getFramebufferSize() const override;
+
void initialize(mbgl::Map *map) override;
void activate() override;
void deactivate() override;
@@ -24,7 +28,8 @@ public:
static void onKey(GLFWwindow *window, int key, int scancode, int action, int mods);
static void onScroll(GLFWwindow *window, double xoffset, double yoffset);
- static void onResize(GLFWwindow *window, int width, int height);
+ static void onWindowResize(GLFWwindow *window, int width, int height);
+ static void onFramebufferResize(GLFWwindow *window, int width, int height);
static void onMouseClick(GLFWwindow *window, int button, int action, int modifiers);
static void onMouseMove(GLFWwindow *window, double x, double y);
@@ -57,6 +62,9 @@ private:
int width = 1024;
int height = 768;
+ int fbWidth;
+ int fbHeight;
+ float pixelRatio;
double lastX = 0, lastY = 0;
diff --git a/include/mbgl/platform/default/headless_view.hpp b/include/mbgl/platform/default/headless_view.hpp
index 61e60ebaff..ce0ff2a685 100644
--- a/include/mbgl/platform/default/headless_view.hpp
+++ b/include/mbgl/platform/default/headless_view.hpp
@@ -25,18 +25,23 @@ class HeadlessDisplay;
class HeadlessView : public View {
public:
- HeadlessView(uint16_t width = 256, uint16_t height = 256, float pixelRatio = 1);
- HeadlessView(std::shared_ptr<HeadlessDisplay> display, uint16_t width = 256, uint16_t height = 256, float pixelRatio = 1);
+ 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 getPixelRatio() const override;
+ std::array<uint16_t, 2> getSize() const override;
+ std::array<uint16_t, 2> getFramebufferSize() const override;
+
void activate() override;
void deactivate() override;
void notify() override;
- void resize(uint16_t width, uint16_t height, float pixelRatio) override;
void invalidate() override;
void swap() override;
std::unique_ptr<StillImage> readStillImage() override;
+ void resize(uint16_t width, uint16_t height);
+
private:
void createContext();
void loadExtensions();
@@ -45,18 +50,8 @@ private:
private:
std::shared_ptr<HeadlessDisplay> display;
-
- struct Dimensions {
- inline Dimensions(uint16_t width = 0, uint16_t height = 0, float pixelRatio = 0);
- inline uint16_t pixelWidth() const { return width * pixelRatio; }
- inline uint16_t pixelHeight() const { return height * pixelRatio; }
-
- uint16_t width = 0;
- uint16_t height = 0;
- float pixelRatio = 0;
- };
-
- Dimensions dimensions;
+ const float pixelRatio;
+ std::array<uint16_t, 2> dimensions;
#if MBGL_USE_CGL
CGLContextObj glContext = nullptr;
diff --git a/platform/default/glfw_view.cpp b/platform/default/glfw_view.cpp
index fe37b398d2..9ccf194f62 100644
--- a/platform/default/glfw_view.cpp
+++ b/platform/default/glfw_view.cpp
@@ -58,13 +58,17 @@ GLFWView::GLFWView(bool fullscreen_) : fullscreen(fullscreen_) {
glfwSetCursorPosCallback(window, onMouseMove);
glfwSetMouseButtonCallback(window, onMouseClick);
- glfwSetWindowSizeCallback(window, onResize);
- glfwSetFramebufferSizeCallback(window, onResize);
+ glfwSetWindowSizeCallback(window, onWindowResize);
+ glfwSetFramebufferSizeCallback(window, onFramebufferResize);
glfwSetScrollCallback(window, onScroll);
glfwSetKeyCallback(window, onKey);
mbgl::gl::InitializeExtensions(glfwGetProcAddress);
+ glfwGetWindowSize(window, &width, &height);
+ glfwGetFramebufferSize(window, &fbWidth, &fbHeight);
+ pixelRatio = static_cast<float>(fbWidth) / width;
+
glfwMakeContextCurrent(nullptr);
}
@@ -75,9 +79,6 @@ GLFWView::~GLFWView() {
void GLFWView::initialize(mbgl::Map *map_) {
View::initialize(map_);
-
- glfwGetWindowSize(window, &width, &height);
- onResize(window, width, height);
}
void GLFWView::onKey(GLFWwindow *window, int key, int /*scancode*/, int action, int mods) {
@@ -226,15 +227,20 @@ void GLFWView::onScroll(GLFWwindow *window, double /*xOffset*/, double yOffset)
view->map->scaleBy(scale, view->lastX, view->lastY);
}
-void GLFWView::onResize(GLFWwindow *window, int width, int height ) {
+void GLFWView::onWindowResize(GLFWwindow *window, int width, int height) {
GLFWView *view = reinterpret_cast<GLFWView *>(glfwGetWindowUserPointer(window));
view->width = width;
view->height = height;
- int fbWidth, fbHeight;
- glfwGetFramebufferSize(window, &fbWidth, &fbHeight);
+ view->map->update(mbgl::Update::Dimensions);
+}
- view->map->resize(width, height, static_cast<float>(fbWidth) / static_cast<float>(width));
+void GLFWView::onFramebufferResize(GLFWwindow *window, int width, int height) {
+ GLFWView *view = reinterpret_cast<GLFWView *>(glfwGetWindowUserPointer(window));
+ view->fbWidth = width;
+ view->fbHeight = height;
+
+ view->map->update();
}
void GLFWView::onMouseClick(GLFWwindow *window, int button, int action, int modifiers) {
@@ -287,6 +293,18 @@ void GLFWView::run() {
}
}
+float GLFWView::getPixelRatio() const {
+ return pixelRatio;
+}
+
+std::array<uint16_t, 2> GLFWView::getSize() const {
+ return {{ static_cast<uint16_t>(width), static_cast<uint16_t>(height) }};
+}
+
+std::array<uint16_t, 2> GLFWView::getFramebufferSize() const {
+ return {{ static_cast<uint16_t>(fbWidth), static_cast<uint16_t>(fbHeight) }};
+}
+
void GLFWView::activate() {
glfwMakeContextCurrent(window);
}
diff --git a/platform/default/headless_view.cpp b/platform/default/headless_view.cpp
index f4411bb2ee..2d65277850 100644
--- a/platform/default/headless_view.cpp
+++ b/platform/default/headless_view.cpp
@@ -20,21 +20,17 @@
namespace mbgl {
-HeadlessView::HeadlessView(uint16_t width, uint16_t height, float pixelRatio)
- : display(std::make_shared<HeadlessDisplay>()) {
- activate();
- resize(width, height, pixelRatio);
- deactivate();
+HeadlessView::HeadlessView(float pixelRatio_, uint16_t width, uint16_t height)
+ : display(std::make_shared<HeadlessDisplay>()), pixelRatio(pixelRatio_) {
+ resize(width, height);
}
HeadlessView::HeadlessView(std::shared_ptr<HeadlessDisplay> display_,
+ float pixelRatio_,
uint16_t width,
- uint16_t height,
- float pixelRatio)
- : display(display_) {
- activate();
- resize(width, height, pixelRatio);
- deactivate();
+ uint16_t height)
+ : display(display_), pixelRatio(pixelRatio_) {
+ resize(width, height);
}
void HeadlessView::loadExtensions() {
@@ -118,17 +114,15 @@ bool HeadlessView::isActive() {
return std::this_thread::get_id() == thread;
}
-HeadlessView::Dimensions::Dimensions(uint16_t width_, uint16_t height_, float pixelRatio_)
- : width(width_), height(height_), pixelRatio(pixelRatio_) {
-}
+void HeadlessView::resize(const uint16_t width, const uint16_t height) {
+ activate();
-void HeadlessView::resize(const uint16_t width, const uint16_t height, const float pixelRatio) {
- dimensions = { width, height, pixelRatio };
+ dimensions = {{ width, height }};
clearBuffers();
- const unsigned int w = dimensions.width * dimensions.pixelRatio;
- const unsigned int h = dimensions.height * dimensions.pixelRatio;
+ const unsigned int w = dimensions[0] * pixelRatio;
+ const unsigned int h = dimensions[1] * pixelRatio;
// Create depth/stencil buffer
MBGL_CHECK_ERROR(glGenRenderbuffersEXT(1, &fboDepthStencil));
@@ -150,26 +144,28 @@ void HeadlessView::resize(const uint16_t width, const uint16_t height, const flo
GLenum status = MBGL_CHECK_ERROR(glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT));
if (status != GL_FRAMEBUFFER_COMPLETE_EXT) {
- std::stringstream error("Couldn't create framebuffer: ");
+ std::string error("Couldn't create framebuffer: ");
switch (status) {
- case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT: (error << "incomplete attachment.\n"); break;
- case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT: error << "incomplete missing attachment.\n"; break;
- case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT: error << "incomplete dimensions.\n"; break;
- case GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT: error << "incomplete formats.\n"; break;
- case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT: error << "incomplete draw buffer.\n"; break;
- case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT: error << "incomplete read buffer.\n"; break;
- case GL_FRAMEBUFFER_UNSUPPORTED: error << "unsupported.\n"; break;
- default: error << "other\n"; break;
+ case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT: (error += "incomplete attachment"); break;
+ case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT: error += "incomplete missing attachment"; break;
+ case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT: error += "incomplete dimensions"; break;
+ case GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT: error += "incomplete formats"; break;
+ case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT: error += "incomplete draw buffer"; break;
+ case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT: error += "incomplete read buffer"; break;
+ case GL_FRAMEBUFFER_UNSUPPORTED: error += "unsupported"; break;
+ default: error += "other"; break;
}
- throw std::runtime_error(error.str());
+ throw std::runtime_error(error);
}
+
+ deactivate();
}
std::unique_ptr<StillImage> HeadlessView::readStillImage() {
assert(isActive());
- const unsigned int w = dimensions.pixelWidth();
- const unsigned int h = dimensions.pixelHeight();
+ const unsigned int w = dimensions[0] * pixelRatio;
+ const unsigned int h = dimensions[1] * pixelRatio;
auto image = std::make_unique<StillImage>();
image->width = w;
@@ -234,6 +230,19 @@ void HeadlessView::notify() {
// no-op
}
+float HeadlessView::getPixelRatio() const {
+ return pixelRatio;
+}
+
+std::array<uint16_t, 2> HeadlessView::getSize() const {
+ return dimensions;
+}
+
+std::array<uint16_t, 2> HeadlessView::getFramebufferSize() const {
+ return {{ static_cast<uint16_t>(dimensions[0] * pixelRatio),
+ static_cast<uint16_t>(dimensions[1] * pixelRatio) }};
+}
+
void HeadlessView::activate() {
if (thread != std::thread::id()) {
throw std::runtime_error("OpenGL context was already current");
diff --git a/platform/ios/MGLMapView.mm b/platform/ios/MGLMapView.mm
index 79e829247d..9542d63d07 100644
--- a/platform/ios/MGLMapView.mm
+++ b/platform/ios/MGLMapView.mm
@@ -218,9 +218,9 @@ std::chrono::steady_clock::duration secondsAsDuration(float duration)
_glView.enableSetNeedsDisplay = YES;
_glView.drawableStencilFormat = GLKViewDrawableStencilFormat8;
_glView.drawableDepthFormat = GLKViewDrawableDepthFormat16;
- if ([UIScreen instancesRespondToSelector:@selector(nativeScale)]) {
- _glView.contentScaleFactor = [[UIScreen mainScreen] nativeScale];
- }
+
+ const float scaleFactor = [UIScreen instancesRespondToSelector:@selector(nativeScale)] ? [[UIScreen mainScreen] nativeScale] : [[UIScreen mainScreen] scale];
+ _glView.contentScaleFactor = scaleFactor;
_glView.delegate = self;
[_glView bindDrawable];
[self insertSubview:_glView atIndex:0];
@@ -247,7 +247,7 @@ std::chrono::steady_clock::duration secondsAsDuration(float duration)
// setup mbgl map
//
- _mbglView = new MBGLView(self);
+ _mbglView = new MBGLView(self, scaleFactor);
_mbglFileSource = new mbgl::DefaultFileSource([MGLFileCache obtainSharedCacheWithObject:self]);
// Start paused on the IB canvas
@@ -255,7 +255,6 @@ std::chrono::steady_clock::duration secondsAsDuration(float duration)
if (_isTargetingInterfaceBuilder) {
_mbglMap->pause();
}
- _mbglMap->resize(self.bounds.size.width, self.bounds.size.height, _glView.contentScaleFactor);
// Observe for changes to the global access token (and find out the current one).
[[MGLAccountManager sharedManager] addObserver:self
@@ -666,12 +665,10 @@ std::chrono::steady_clock::duration secondsAsDuration(float duration)
}
// This is the delegate of the GLKView object's display call.
-- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect
+- (void)glkView:(__unused GLKView *)view drawInRect:(__unused CGRect)rect
{
if ( ! self.isDormant)
{
- _mbglMap->resize(rect.size.width, rect.size.height, view.contentScaleFactor);
-
CGFloat zoomFactor = _mbglMap->getMaxZoom() - _mbglMap->getMinZoom() + 1;
CGFloat cpuFactor = (CGFloat)[[NSProcessInfo processInfo] processorCount];
CGFloat memoryFactor = (CGFloat)[[NSProcessInfo processInfo] physicalMemory] / 1000 / 1000 / 1000;
@@ -693,7 +690,7 @@ std::chrono::steady_clock::duration secondsAsDuration(float duration)
if ( ! _isTargetingInterfaceBuilder)
{
- _mbglMap->update();
+ _mbglMap->update(mbgl::Update::Dimensions);
}
if (self.attributionSheet.visible)
@@ -2449,6 +2446,11 @@ CLLocationCoordinate2D MGLLocationCoordinate2DFromLatLng(mbgl::LatLng latLng)
- (void)notifyMapChange:(mbgl::MapChange)change
{
+ // Ignore map updates when the Map object isn't set.
+ if (!_mbglMap) {
+ return;
+ }
+
switch (change)
{
case mbgl::MapChangeRegionWillChange:
@@ -2778,10 +2780,26 @@ CLLocationCoordinate2D MGLLocationCoordinate2DFromLatLng(mbgl::LatLng latLng)
class MBGLView : public mbgl::View
{
public:
- MBGLView(MGLMapView *nativeView_) : nativeView(nativeView_) {}
+ MBGLView(MGLMapView* nativeView_, const float scaleFactor_)
+ : nativeView(nativeView_), scaleFactor(scaleFactor_) {
+ }
virtual ~MBGLView() {}
+ float getPixelRatio() const override {
+ return scaleFactor;
+ }
+
+ std::array<uint16_t, 2> getSize() const override {
+ return {{ static_cast<uint16_t>([nativeView bounds].size.width),
+ static_cast<uint16_t>([nativeView bounds].size.height) }};
+ }
+
+ std::array<uint16_t, 2> getFramebufferSize() const override {
+ return {{ static_cast<uint16_t>([[nativeView glView] drawableWidth]),
+ static_cast<uint16_t>([[nativeView glView] drawableHeight]) }};
+ }
+
void notify() override
{
// no-op
@@ -2817,6 +2835,7 @@ class MBGLView : public mbgl::View
private:
__weak MGLMapView *nativeView = nullptr;
+ const float scaleFactor;
};
@end
diff --git a/src/mbgl/map/map.cpp b/src/mbgl/map/map.cpp
index 94d3e57d41..ca8303ec6e 100644
--- a/src/mbgl/map/map.cpp
+++ b/src/mbgl/map/map.cpp
@@ -15,10 +15,11 @@ namespace mbgl {
Map::Map(View& view_, FileSource& fileSource, MapMode mode)
: view(view_),
transform(std::make_unique<Transform>(view)),
- data(std::make_unique<MapData>(mode)),
+ data(std::make_unique<MapData>(mode, view.getPixelRatio())),
context(std::make_unique<util::Thread<MapContext>>(util::ThreadContext{"Map", util::ThreadType::Map, util::ThreadPriority::Regular}, view, fileSource, *data))
{
view.initialize(this);
+ update(Update::Dimensions);
}
Map::~Map() {
@@ -43,7 +44,8 @@ void Map::resume() {
}
void Map::renderStill(StillImageCallback callback) {
- context->invoke(&MapContext::renderStill, transform->getState(), callback);
+ context->invoke(&MapContext::renderStill, transform->getState(),
+ FrameData{ view.getFramebufferSize() }, callback);
}
void Map::renderSync() {
@@ -53,8 +55,8 @@ void Map::renderSync() {
view.notifyMapChange(MapChangeWillStartRenderingFrame);
- MapContext::RenderResult result =
- context->invokeSync<MapContext::RenderResult>(&MapContext::renderSync, transform->getState());
+ MapContext::RenderResult result = context->invokeSync<MapContext::RenderResult>(
+ &MapContext::renderSync, transform->getState(), FrameData{ view.getFramebufferSize() });
view.notifyMapChange(result.fullyLoaded ?
MapChangeDidFinishRenderingFrameFullyRendered :
@@ -75,6 +77,10 @@ void Map::renderSync() {
}
void Map::update(Update update_) {
+ if (update_ == Update::Dimensions) {
+ transform->resize(view.getSize());
+ }
+
context->invoke(&MapContext::triggerUpdate, transform->getState(), update_);
}
@@ -96,15 +102,6 @@ std::string Map::getStyleJSON() const {
return context->invokeSync<std::string>(&MapContext::getStyleJSON);
}
-#pragma mark - Size
-
-void Map::resize(uint16_t width, uint16_t height, float ratio) {
- if (transform->resize(width, height, ratio, width * ratio, height * ratio)) {
- context->invoke(&MapContext::resize, width, height, ratio);
- update();
- }
-}
-
#pragma mark - Transitions
void Map::cancelTransitions() {
@@ -185,7 +182,7 @@ void Map::fitBounds(AnnotationSegment segment, EdgeInsets padding, Duration dura
if (segment.empty()) {
return;
}
-
+
// Calculate the bounds of the possibly rotated shape with respect to the viewport.
vec2<> nePixel = {-INFINITY, -INFINITY};
vec2<> swPixel = {INFINITY, INFINITY};
diff --git a/src/mbgl/map/map_context.cpp b/src/mbgl/map/map_context.cpp
index f6dba408da..455539436f 100644
--- a/src/mbgl/map/map_context.cpp
+++ b/src/mbgl/map/map_context.cpp
@@ -79,10 +79,6 @@ void MapContext::pause() {
view.activate();
}
-void MapContext::resize(uint16_t width, uint16_t height, float ratio) {
- view.resize(width, height, ratio);
-}
-
void MapContext::triggerUpdate(const TransformState& state, const Update u) {
transformState = state;
updated |= static_cast<UpdateType>(u);
@@ -266,14 +262,14 @@ void MapContext::update() {
if (data.mode == MapMode::Continuous) {
view.invalidate();
} else if (callback && style->isLoaded()) {
- renderSync(transformState);
+ renderSync(transformState, frameData);
}
}
updated = static_cast<UpdateType>(Update::Nothing);
}
-void MapContext::renderStill(const TransformState& state, StillImageCallback fn) {
+void MapContext::renderStill(const TransformState& state, const FrameData& frame, StillImageCallback fn) {
if (!fn) {
Log::Error(Event::General, "StillImageCallback not set");
return;
@@ -301,12 +297,13 @@ void MapContext::renderStill(const TransformState& state, StillImageCallback fn)
callback = fn;
transformState = state;
+ frameData = frame;
updated |= static_cast<UpdateType>(Update::RenderStill);
asyncUpdate->send();
}
-MapContext::RenderResult MapContext::renderSync(const TransformState& state) {
+MapContext::RenderResult MapContext::renderSync(const TransformState& state, const FrameData& frame) {
assert(util::ThreadContext::currentlyOn(util::ThreadType::Map));
// Style was not loaded yet.
@@ -320,12 +317,12 @@ MapContext::RenderResult MapContext::renderSync(const TransformState& state) {
glObjectStore.performCleanup();
if (!painter) {
- painter = std::make_unique<Painter>();
+ painter = std::make_unique<Painter>(data.pixelRatio);
painter->setup();
}
painter->setDebug(data.getDebug());
- painter->render(*style, transformState, data.getAnimationTime());
+ painter->render(*style, transformState, frame, data.getAnimationTime());
if (data.mode == MapMode::Still) {
callback(nullptr, view.readStillImage());
diff --git a/src/mbgl/map/map_context.hpp b/src/mbgl/map/map_context.hpp
index 724920b825..2c085c1aa8 100644
--- a/src/mbgl/map/map_context.hpp
+++ b/src/mbgl/map/map_context.hpp
@@ -26,6 +26,11 @@ class StillImage;
struct LatLng;
struct LatLngBounds;
+
+struct FrameData {
+ std::array<uint16_t, 2> framebufferSize;
+};
+
class MapContext : public Style::Observer {
public:
MapContext(View&, FileSource&, MapData&);
@@ -38,13 +43,11 @@ public:
void pause();
- void resize(uint16_t width, uint16_t height, float ratio);
-
using StillImageCallback = std::function<void(std::exception_ptr, std::unique_ptr<const StillImage>)>;
void triggerUpdate(const TransformState&, Update = Update::Nothing);
- void renderStill(const TransformState&, StillImageCallback callback);
- RenderResult renderSync(const TransformState&);
+ void renderStill(const TransformState&, const FrameData&, StillImageCallback callback);
+ RenderResult renderSync(const TransformState&, const FrameData&);
void setStyleURL(const std::string&);
void setStyleJSON(const std::string& json, const std::string& base);
@@ -95,6 +98,7 @@ private:
StillImageCallback callback;
size_t sourceCacheSize;
TransformState transformState;
+ FrameData frameData;
};
}
diff --git a/src/mbgl/map/map_data.hpp b/src/mbgl/map/map_data.hpp
index 7e5955d744..75ada0615e 100644
--- a/src/mbgl/map/map_data.hpp
+++ b/src/mbgl/map/map_data.hpp
@@ -20,7 +20,8 @@ class MapData {
using Lock = std::lock_guard<std::mutex>;
public:
- inline MapData(MapMode mode_) : mode(mode_) {
+ inline MapData(MapMode mode_, const float pixelRatio_) : mode(mode_), pixelRatio(pixelRatio_) {
+ assert(pixelRatio > 0);
setAnimationTime(TimePoint::min());
setDefaultTransitionDuration(Duration::zero());
}
@@ -77,7 +78,7 @@ public:
}
inline void setDefaultTransitionDuration(Duration duration) {
defaultTransitionDuration = duration;
- };
+ }
util::exclusive<AnnotationManager> getAnnotationManager() {
return util::exclusive<AnnotationManager>(
@@ -87,6 +88,7 @@ public:
public:
const MapMode mode;
+ const float pixelRatio;
private:
mutable std::mutex annotationManagerMutex;
diff --git a/src/mbgl/map/source.cpp b/src/mbgl/map/source.cpp
index 7532bd8f93..4ca64747bc 100644
--- a/src/mbgl/map/source.cpp
+++ b/src/mbgl/map/source.cpp
@@ -292,11 +292,11 @@ TileData::State Source::addTile(MapData& data,
if (info.type == SourceType::Vector) {
auto tileData = std::make_shared<VectorTileData>(normalized_id, style, info,
transformState.getAngle(), data.getCollisionDebug());
- tileData->request(transformState.getPixelRatio(), callback);
+ tileData->request(data.pixelRatio, callback);
new_tile.data = tileData;
} else if (info.type == SourceType::Raster) {
auto tileData = std::make_shared<RasterTileData>(normalized_id, texturePool, info, style.workers);
- tileData->request(transformState.getPixelRatio(), callback);
+ tileData->request(data.pixelRatio, callback);
new_tile.data = tileData;
} else if (info.type == SourceType::Annotations) {
new_tile.data = std::make_shared<LiveTileData>(normalized_id,
diff --git a/src/mbgl/map/transform.cpp b/src/mbgl/map/transform.cpp
index 48e0e30e9c..12698a1e81 100644
--- a/src/mbgl/map/transform.cpp
+++ b/src/mbgl/map/transform.cpp
@@ -34,18 +34,13 @@ Transform::Transform(View &view_)
#pragma mark - Map View
-bool Transform::resize(const uint16_t w, const uint16_t h, const float ratio,
- const uint16_t fb_w, const uint16_t fb_h) {
- if (state.width != w || state.height != h || state.pixelRatio != ratio ||
- state.framebuffer[0] != fb_w || state.framebuffer[1] != fb_h) {
+bool Transform::resize(const std::array<uint16_t, 2> size) {
+ if (state.width != size[0] || state.height != size[1]) {
view.notifyMapChange(MapChangeRegionWillChange);
- state.width = w;
- state.height = h;
- state.pixelRatio = ratio;
- state.framebuffer[0] = fb_w;
- state.framebuffer[1] = fb_h;
+ state.width = size[0];
+ state.height = size[1];
state.constrain(state.scale, state.y);
view.notifyMapChange(MapChangeRegionDidChange);
diff --git a/src/mbgl/map/transform.hpp b/src/mbgl/map/transform.hpp
index 96e5198dba..c2c4aad2de 100644
--- a/src/mbgl/map/transform.hpp
+++ b/src/mbgl/map/transform.hpp
@@ -20,9 +20,7 @@ public:
Transform(View&);
// Map view
- // Note: width * ratio does not necessarily equal fb_width
- bool resize(uint16_t width, uint16_t height, float ratio,
- uint16_t fb_width, uint16_t fb_height);
+ bool resize(std::array<uint16_t, 2> size);
// Position
void moveBy(double dx, double dy, Duration = Duration::zero());
diff --git a/src/mbgl/map/transform_state.cpp b/src/mbgl/map/transform_state.cpp
index 6a0c2a0d6a..bb3e86d33e 100644
--- a/src/mbgl/map/transform_state.cpp
+++ b/src/mbgl/map/transform_state.cpp
@@ -74,23 +74,6 @@ uint16_t TransformState::getHeight() const {
return height;
}
-uint16_t TransformState::getFramebufferWidth() const {
- return framebuffer[0];
-}
-
-uint16_t TransformState::getFramebufferHeight() const {
- return framebuffer[1];
-}
-
-const std::array<uint16_t, 2> TransformState::getFramebufferDimensions() const {
- return framebuffer;
-}
-
-float TransformState::getPixelRatio() const {
- return pixelRatio;
-}
-
-
#pragma mark - Position
const LatLng TransformState::getLatLng() const {
diff --git a/src/mbgl/map/transform_state.hpp b/src/mbgl/map/transform_state.hpp
index 63aa6444fb..16f2de2f79 100644
--- a/src/mbgl/map/transform_state.hpp
+++ b/src/mbgl/map/transform_state.hpp
@@ -27,10 +27,6 @@ public:
bool hasSize() const;
uint16_t getWidth() const;
uint16_t getHeight() const;
- uint16_t getFramebufferWidth() const;
- uint16_t getFramebufferHeight() const;
- const std::array<uint16_t, 2> getFramebufferDimensions() const;
- float getPixelRatio() const;
float worldSize() const;
float lngX(float lon) const;
@@ -73,12 +69,7 @@ private:
// logical dimensions
uint16_t width = 0, height = 0;
- // physical (framebuffer) dimensions
- std::array<uint16_t, 2> framebuffer = {{ 0, 0 }};
-
- // map scale factor
- float pixelRatio = 0;
-
+private:
// animation state
bool rotating = false;
bool scaling = false;
diff --git a/src/mbgl/map/view.cpp b/src/mbgl/map/view.cpp
index 7d507d87a5..5da290534a 100644
--- a/src/mbgl/map/view.cpp
+++ b/src/mbgl/map/view.cpp
@@ -11,10 +11,6 @@ void View::initialize(Map *map_) {
map = map_;
}
-void View::resize(uint16_t, uint16_t, float) {
- // no-op
-}
-
std::unique_ptr<StillImage> View::readStillImage() {
return nullptr;
}
diff --git a/src/mbgl/renderer/painter.cpp b/src/mbgl/renderer/painter.cpp
index 742572a351..33f1687a95 100644
--- a/src/mbgl/renderer/painter.cpp
+++ b/src/mbgl/renderer/painter.cpp
@@ -2,6 +2,7 @@
#include <mbgl/map/source.hpp>
#include <mbgl/map/tile.hpp>
+#include <mbgl/map/map_context.hpp>
#include <mbgl/platform/log.hpp>
#include <mbgl/gl/debugging.hpp>
@@ -40,7 +41,7 @@
using namespace mbgl;
-Painter::Painter() {
+Painter::Painter(const float pixelRatio_) : pixelRatio(pixelRatio_) {
}
Painter::~Painter() {
@@ -104,8 +105,8 @@ void Painter::setupShaders() {
}
void Painter::resize() {
- if (gl_viewport != state.getFramebufferDimensions()) {
- gl_viewport = state.getFramebufferDimensions();
+ if (gl_viewport != frame.framebufferSize) {
+ gl_viewport = frame.framebufferSize;
assert(gl_viewport[0] > 0 && gl_viewport[1] > 0);
MBGL_CHECK_ERROR(glViewport(0, 0, gl_viewport[0], gl_viewport[1]));
}
@@ -164,8 +165,9 @@ void Painter::prepareTile(const Tile& tile) {
config.stencilFunc = { GL_EQUAL, ref, mask };
}
-void Painter::render(const Style& style, TransformState state_, TimePoint time) {
+void Painter::render(const Style& style, TransformState state_, const FrameData& frame_, TimePoint time) {
state = state_;
+ frame = frame_;
glyphAtlas = style.glyphAtlas.get();
spriteAtlas = style.spriteAtlas.get();
diff --git a/src/mbgl/renderer/painter.hpp b/src/mbgl/renderer/painter.hpp
index 465bf5ba33..f7342b15c9 100644
--- a/src/mbgl/renderer/painter.hpp
+++ b/src/mbgl/renderer/painter.hpp
@@ -2,6 +2,7 @@
#define MBGL_RENDERER_PAINTER
#include <mbgl/map/transform_state.hpp>
+#include <mbgl/map/map_context.hpp>
#include <mbgl/renderer/frame_history.hpp>
#include <mbgl/renderer/bucket.hpp>
@@ -31,6 +32,7 @@ class SpriteAtlas;
class GlyphAtlas;
class LineAtlas;
class Source;
+struct FrameData;
class DebugBucket;
@@ -79,7 +81,7 @@ struct RenderItem {
class Painter : private util::noncopyable {
public:
- Painter();
+ Painter(float pixelRatio);
~Painter();
void setup();
@@ -93,6 +95,7 @@ public:
void render(const Style& style,
TransformState state,
+ const FrameData& frame,
TimePoint time);
// Renders debug information for a tile.
@@ -118,6 +121,7 @@ public:
void createPrerendered(RasterBucket& bucket, const StyleLayer &layer_desc, const TileID& id);
+ // Adjusts the dimensions of the OpenGL viewport
void resize();
// Changes whether debug information is drawn onto the map
@@ -187,7 +191,10 @@ public:
}();
private:
+ const float pixelRatio;
+
TransformState state;
+ FrameData frame;
bool debug = false;
int indent = 0;
diff --git a/src/mbgl/renderer/painter_debug.cpp b/src/mbgl/renderer/painter_debug.cpp
index bd145085df..b5d9e343e8 100644
--- a/src/mbgl/renderer/painter_debug.cpp
+++ b/src/mbgl/renderer/painter_debug.cpp
@@ -28,7 +28,7 @@ void Painter::renderDebugText(DebugBucket& bucket, const mat4 &matrix) {
// Draw white outline
plainShader->u_color = {{ 1.0f, 1.0f, 1.0f, 1.0f }};
- lineWidth(4.0f * state.getPixelRatio());
+ lineWidth(4.0f * pixelRatio);
bucket.drawLines(*plainShader);
#ifndef GL_ES_VERSION_2_0
@@ -39,7 +39,7 @@ void Painter::renderDebugText(DebugBucket& bucket, const mat4 &matrix) {
// Draw black text.
plainShader->u_color = {{ 0.0f, 0.0f, 0.0f, 1.0f }};
- lineWidth(2.0f * state.getPixelRatio());
+ lineWidth(2.0f * pixelRatio);
bucket.drawLines(*plainShader);
config.depthTest = true;
@@ -60,6 +60,6 @@ void Painter::renderDebugFrame(const mat4 &matrix) {
// draw tile outline
tileBorderArray.bind(*plainShader, tileBorderBuffer, BUFFER_OFFSET(0));
plainShader->u_color = {{ 1.0f, 0.0f, 0.0f, 1.0f }};
- lineWidth(4.0f * state.getPixelRatio());
+ lineWidth(4.0f * pixelRatio);
MBGL_CHECK_ERROR(glDrawArrays(GL_LINE_STRIP, 0, (GLsizei)tileBorderBuffer.index()));
}
diff --git a/src/mbgl/renderer/painter_fill.cpp b/src/mbgl/renderer/painter_fill.cpp
index 5514ebc858..2f683665ed 100644
--- a/src/mbgl/renderer/painter_fill.cpp
+++ b/src/mbgl/renderer/painter_fill.cpp
@@ -52,8 +52,8 @@ void Painter::renderFill(FillBucket& bucket, const StyleLayer &layer_desc, const
// Draw the entire line
outlineShader->u_world = {{
- static_cast<float>(state.getFramebufferWidth()),
- static_cast<float>(state.getFramebufferHeight())
+ static_cast<float>(frame.framebufferSize[0]),
+ static_cast<float>(frame.framebufferSize[1])
}};
config.depthRange = { strata, 1.0f };
bucket.drawVertices(*outlineShader);
@@ -128,8 +128,8 @@ void Painter::renderFill(FillBucket& bucket, const StyleLayer &layer_desc, const
// Draw the entire line
outlineShader->u_world = {{
- static_cast<float>(state.getFramebufferWidth()),
- static_cast<float>(state.getFramebufferHeight())
+ static_cast<float>(frame.framebufferSize[0]),
+ static_cast<float>(frame.framebufferSize[1])
}};
config.depthRange = { strata + strata_epsilon + strata_epsilon, 1.0f };
diff --git a/src/mbgl/renderer/painter_line.cpp b/src/mbgl/renderer/painter_line.cpp
index e084147deb..5f5a89d419 100644
--- a/src/mbgl/renderer/painter_line.cpp
+++ b/src/mbgl/renderer/painter_line.cpp
@@ -26,7 +26,7 @@ void Painter::renderLine(LineBucket& bucket, const StyleLayer &layer_desc, const
// the distance over which the line edge fades out.
// Retina devices need a smaller distance to avoid aliasing.
- float antialiasing = 1 / state.getPixelRatio();
+ float antialiasing = 1.0 / pixelRatio;
float blur = properties.blur + antialiasing;
float edgeWidth = properties.width / 2.0;
@@ -50,7 +50,6 @@ void Painter::renderLine(LineBucket& bucket, const StyleLayer &layer_desc, const
color[2] *= properties.opacity;
color[3] *= properties.opacity;
- float ratio = state.getPixelRatio();
mat4 vtxMatrix = translatedMatrix(matrix, properties.translate, id, properties.translateAnchor);
config.depthRange = { strata, 1.0f };
@@ -62,7 +61,7 @@ void Painter::renderLine(LineBucket& bucket, const StyleLayer &layer_desc, const
linesdfShader->u_matrix = vtxMatrix;
linesdfShader->u_exmatrix = extrudeMatrix;
linesdfShader->u_linewidth = {{ outset, inset }};
- linesdfShader->u_ratio = ratio;
+ linesdfShader->u_ratio = pixelRatio;
linesdfShader->u_blur = blur;
linesdfShader->u_color = color;
@@ -81,7 +80,7 @@ void Painter::renderLine(LineBucket& bucket, const StyleLayer &layer_desc, const
linesdfShader->u_patternscale_b = {{ scaleXB, scaleYB }};
linesdfShader->u_tex_y_b = posB.y;
linesdfShader->u_image = 0;
- linesdfShader->u_sdfgamma = lineAtlas->width / (properties.dash_line_width * std::min(posA.width, posB.width) * 256.0 * state.getPixelRatio()) / 2;
+ linesdfShader->u_sdfgamma = lineAtlas->width / (properties.dash_line_width * std::min(posA.width, posB.width) * 256.0 * pixelRatio) / 2;
linesdfShader->u_mix = properties.dash_array.t;
bucket.drawLineSDF(*linesdfShader);
@@ -97,7 +96,7 @@ void Painter::renderLine(LineBucket& bucket, const StyleLayer &layer_desc, const
linepatternShader->u_matrix = vtxMatrix;
linepatternShader->u_exmatrix = extrudeMatrix;
linepatternShader->u_linewidth = {{ outset, inset }};
- linepatternShader->u_ratio = ratio;
+ linepatternShader->u_ratio = pixelRatio;
linepatternShader->u_blur = blur;
linepatternShader->u_pattern_size_a = {{imagePosA.size[0] * factor * properties.image.fromScale, imagePosA.size[1]}};
@@ -121,7 +120,7 @@ void Painter::renderLine(LineBucket& bucket, const StyleLayer &layer_desc, const
lineShader->u_matrix = vtxMatrix;
lineShader->u_exmatrix = extrudeMatrix;
lineShader->u_linewidth = {{ outset, inset }};
- lineShader->u_ratio = ratio;
+ lineShader->u_ratio = pixelRatio;
lineShader->u_blur = blur;
lineShader->u_color = color;
diff --git a/src/mbgl/renderer/painter_symbol.cpp b/src/mbgl/renderer/painter_symbol.cpp
index 2a02a30f6d..d0757d6297 100644
--- a/src/mbgl/renderer/painter_symbol.cpp
+++ b/src/mbgl/renderer/painter_symbol.cpp
@@ -60,7 +60,7 @@ void Painter::renderSDF(SymbolBucket &bucket,
// The default gamma value has to be adjust for the current pixelratio so that we're not
// drawing blurry font on retina screens.
- const float gamma = 0.105 * sdfFontSize / fontSize / state.getPixelRatio();
+ const float gamma = 0.105 * sdfFontSize / fontSize / pixelRatio;
const float sdfPx = 8.0f;
const float blurOffset = 1.19f;
diff --git a/src/mbgl/style/style.cpp b/src/mbgl/style/style.cpp
index 23d32689ef..c844a656d9 100644
--- a/src/mbgl/style/style.cpp
+++ b/src/mbgl/style/style.cpp
@@ -1,5 +1,6 @@
#include <mbgl/style/style.hpp>
#include <mbgl/map/sprite.hpp>
+#include <mbgl/map/map_data.hpp>
#include <mbgl/map/source.hpp>
#include <mbgl/map/transform_state.hpp>
#include <mbgl/style/style_layer.hpp>
@@ -67,12 +68,11 @@ Style::~Style() {
void Style::update(MapData& data,
const TransformState& transform,
TexturePool& texturePool) {
- const float pixelRatio = transform.getPixelRatio();
- if (!sprite || !sprite->hasPixelRatio(pixelRatio)) {
- sprite = std::make_unique<Sprite>(spriteURL, pixelRatio);
+ if (!sprite || !sprite->hasPixelRatio(data.pixelRatio)) {
+ sprite = std::make_unique<Sprite>(spriteURL, data.pixelRatio);
sprite->setObserver(this);
- spriteAtlas->resize(pixelRatio);
+ spriteAtlas->resize(data.pixelRatio);
spriteAtlas->setSprite(sprite);
}
diff --git a/test/api/api_misuse.cpp b/test/api/api_misuse.cpp
index a98cf04101..1f54855323 100644
--- a/test/api/api_misuse.cpp
+++ b/test/api/api_misuse.cpp
@@ -17,11 +17,11 @@ TEST(API, RenderWithoutCallback) {
Log::setObserver(std::unique_ptr<Log::Observer>(log));
auto display = std::make_shared<mbgl::HeadlessDisplay>();
- HeadlessView view(display);
+ HeadlessView view(display, 1);
+ view.resize(128, 512);
DefaultFileSource fileSource(nullptr);
std::unique_ptr<Map> map = std::make_unique<Map>(view, fileSource, MapMode::Still);
- map->resize(128, 512, 1);
map->renderStill(nullptr);
// Force Map thread to join.
@@ -39,11 +39,11 @@ TEST(API, RenderWithoutCallback) {
TEST(API, RenderWithoutStyle) {
auto display = std::make_shared<mbgl::HeadlessDisplay>();
- HeadlessView view(display);
+ HeadlessView view(display, 1);
+ view.resize(128, 512);
DefaultFileSource fileSource(nullptr);
Map map(view, fileSource, MapMode::Still);
- map.resize(128, 512, 1);
std::promise<std::exception_ptr> promise;
map.renderStill([&promise](std::exception_ptr error, std::unique_ptr<const StillImage>) {
diff --git a/test/api/repeated_render.cpp b/test/api/repeated_render.cpp
index 7f55237744..f8b92b85b8 100644
--- a/test/api/repeated_render.cpp
+++ b/test/api/repeated_render.cpp
@@ -17,7 +17,7 @@ TEST(API, RepeatedRender) {
const auto style = util::read_file("test/fixtures/api/water.json");
auto display = std::make_shared<mbgl::HeadlessDisplay>();
- HeadlessView view(display);
+ HeadlessView view(display, 1, 256, 512);
DefaultFileSource fileSource(nullptr);
Log::setObserver(std::make_unique<FixtureLogObserver>());
@@ -25,29 +25,27 @@ TEST(API, RepeatedRender) {
Map map(view, fileSource, MapMode::Still);
{
- map.resize(128, 512, 1);
map.setStyleJSON(style, "test/suite");
std::promise<std::unique_ptr<const StillImage>> promise;
map.renderStill([&promise](std::exception_ptr, std::unique_ptr<const StillImage> image) {
promise.set_value(std::move(image));
});
auto result = promise.get_future().get();
- ASSERT_EQ(128, result->width);
+ ASSERT_EQ(256, result->width);
ASSERT_EQ(512, result->height);
const std::string png = util::compress_png(result->width, result->height, result->pixels.get());
util::write_file("test/fixtures/api/1.png", png);
}
{
- map.resize(512, 512, 2);
map.setStyleJSON(style, "TEST_DATA/suite");
std::promise<std::unique_ptr<const StillImage>> promise;
map.renderStill([&promise](std::exception_ptr, std::unique_ptr<const StillImage> image) {
promise.set_value(std::move(image));
});
auto result = promise.get_future().get();
- ASSERT_EQ(1024, result->width);
- ASSERT_EQ(1024, result->height);
+ ASSERT_EQ(256, result->width);
+ ASSERT_EQ(512, result->height);
const std::string png = util::compress_png(result->width, result->height, result->pixels.get());
util::write_file("test/fixtures/api/2.png", png);
}
diff --git a/test/api/set_style.cpp b/test/api/set_style.cpp
index 72260e6343..db31254dbb 100644
--- a/test/api/set_style.cpp
+++ b/test/api/set_style.cpp
@@ -11,7 +11,7 @@ TEST(API, SetStyle) {
using namespace mbgl;
auto display = std::make_shared<mbgl::HeadlessDisplay>();
- HeadlessView view(display);
+ HeadlessView view(display, 1);
DefaultFileSource fileSource(nullptr);
Log::setObserver(std::make_unique<FixtureLogObserver>());
diff --git a/test/fixtures/mock_view.hpp b/test/fixtures/mock_view.hpp
index dcbe3fef84..ace8befbc1 100644
--- a/test/fixtures/mock_view.hpp
+++ b/test/fixtures/mock_view.hpp
@@ -3,6 +3,8 @@
#include <mbgl/map/view.hpp>
+#include <array>
+
namespace mbgl {
class MockView : public View {
@@ -10,6 +12,10 @@ public:
MockView() = default;
// View implementation.
+ float getPixelRatio() const { return 1; }
+ std::array<uint16_t, 2> getSize() const { return {{ 0, 0 }}; }
+ std::array<uint16_t, 2> getFramebufferSize() const { return {{ 0, 0 }}; }
+
void activate() override {};
void deactivate() override {};
void notify() override {};
diff --git a/test/headless/headless.cpp b/test/headless/headless.cpp
index c65e9855e7..60f72b0be3 100644
--- a/test/headless/headless.cpp
+++ b/test/headless/headless.cpp
@@ -141,11 +141,10 @@ TEST_P(HeadlessTest, render) {
std::promise<void> promise;
- HeadlessView view(display, width, height, pixelRatio);
+ HeadlessView view(display, pixelRatio, width, height);
DefaultFileSource fileSource(nullptr);
Map map(view, fileSource, MapMode::Still);
- map.resize(width, height, pixelRatio);
map.setClasses(classes);
map.setStyleJSON(style, "test/suite");
map.setLatLngZoom(mbgl::LatLng(latitude, longitude), zoom);
diff --git a/test/miscellaneous/map.cpp b/test/miscellaneous/map.cpp
index b8707f3902..fdd33c1466 100644
--- a/test/miscellaneous/map.cpp
+++ b/test/miscellaneous/map.cpp
@@ -11,7 +11,7 @@ TEST(Map, PauseResume) {
using namespace mbgl;
auto display = std::make_shared<mbgl::HeadlessDisplay>();
- HeadlessView view(display);
+ HeadlessView view(display, 1);
DefaultFileSource fileSource(nullptr);
Map map(view, fileSource, MapMode::Continuous);
@@ -24,7 +24,7 @@ TEST(Map, DoublePause) {
using namespace mbgl;
auto display = std::make_shared<mbgl::HeadlessDisplay>();
- HeadlessView view(display);
+ HeadlessView view(display, 1);
DefaultFileSource fileSource(nullptr);
Map map(view, fileSource, MapMode::Continuous);
@@ -38,7 +38,7 @@ TEST(Map, ResumeWithoutPause) {
using namespace mbgl;
auto display = std::make_shared<mbgl::HeadlessDisplay>();
- HeadlessView view(display);
+ HeadlessView view(display, 1);
DefaultFileSource fileSource(nullptr);
Map map(view, fileSource, MapMode::Continuous);
@@ -50,7 +50,7 @@ TEST(Map, DestroyPaused) {
using namespace mbgl;
auto display = std::make_shared<mbgl::HeadlessDisplay>();
- HeadlessView view(display);
+ HeadlessView view(display, 1);
DefaultFileSource fileSource(nullptr);
Map map(view, fileSource, MapMode::Continuous);
diff --git a/test/miscellaneous/map_context.cpp b/test/miscellaneous/map_context.cpp
index f1f26a9c47..ec88862f05 100644
--- a/test/miscellaneous/map_context.cpp
+++ b/test/miscellaneous/map_context.cpp
@@ -11,9 +11,9 @@ using namespace mbgl;
TEST(MapContext, DoubleStyleLoad) {
std::shared_ptr<HeadlessDisplay> display = std::make_shared<HeadlessDisplay>();
- HeadlessView view(display, 512, 512, 1);
+ HeadlessView view(display, 1, 512, 512);
DefaultFileSource fileSource(nullptr);
- MapData data(MapMode::Continuous);
+ MapData data(MapMode::Continuous, view.getPixelRatio());
util::Thread<MapContext> context({"Map", util::ThreadType::Map, util::ThreadPriority::Regular}, view, fileSource, data);
diff --git a/test/style/pending_resources.cpp b/test/style/pending_resources.cpp
index 4614c187b7..8eea81191d 100644
--- a/test/style/pending_resources.cpp
+++ b/test/style/pending_resources.cpp
@@ -29,7 +29,7 @@ TEST_P(PendingResources, DeleteMapObjectWithPendingRequest) {
util::RunLoop loop(uv_default_loop());
auto display = std::make_shared<mbgl::HeadlessDisplay>();
- HeadlessView view(display);
+ HeadlessView view(display, 1, 1000, 1000);
MockFileSource fileSource(MockFileSource::SuccessWithDelay, GetParam());
std::unique_ptr<Map> map = std::make_unique<Map>(view, fileSource, MapMode::Still);
@@ -43,7 +43,6 @@ TEST_P(PendingResources, DeleteMapObjectWithPendingRequest) {
fileSource.setOnRequestDelayedCallback([&endTest] { endTest.send(); });
const std::string style = util::read_file("test/fixtures/resources/style.json");
- map->resize(1000, 1000, 1.0);
map->setStyleJSON(style, ".");
map->renderStill([&endTest](std::exception_ptr, std::unique_ptr<const StillImage>) {
diff --git a/test/style/resource_loading.cpp b/test/style/resource_loading.cpp
index fc8905f7bb..071df09338 100644
--- a/test/style/resource_loading.cpp
+++ b/test/style/resource_loading.cpp
@@ -23,12 +23,12 @@ public:
MockMapContext(View& view,
FileSource& fileSource,
const std::function<void(std::exception_ptr error)>& callback)
- : data_(MapMode::Still),
+ : data_(MapMode::Still, view.getPixelRatio()),
transform_(view),
callback_(callback) {
util::ThreadContext::setFileSource(&fileSource);
- transform_.resize(1000, 1000, 1.0, 1000, 1000);
+ transform_.resize({{ 1000, 1000 }});
transform_.setLatLngZoom({0, 0}, 16);
const std::string style = util::read_file("test/fixtures/resources/style.json");