diff options
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"); |