summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorm-stephen <truestyle2005@163.com>2019-07-10 10:08:27 +0800
committerGitHub <noreply@github.com>2019-07-10 10:08:27 +0800
commitb0b481279483414a9aa41083eee9ed36f9242e69 (patch)
tree4dd78fa3eff786b5dc7b39f713ff9a302456b694
parent604844a8b3f97952c2f9049746fd41a4e01f3ac0 (diff)
parent6b59db8fb0118633e354b4fff5d615a0f095faa7 (diff)
downloadqtlocation-mapboxgl-upstream/Stephen-Exclude-offline-CJK-By-Default.tar.gz
Merge branch 'master' into Stephen-Exclude-offline-CJK-By-Defaultupstream/Stephen-Exclude-offline-CJK-By-Default
-rw-r--r--circle.yml10
-rw-r--r--platform/android/CHANGELOG.md3
-rw-r--r--platform/darwin/src/MGLRendererConfiguration.h23
-rw-r--r--platform/darwin/src/MGLRendererConfiguration.mm51
-rw-r--r--platform/darwin/test/MGLRendererConfigurationTests.mm105
-rw-r--r--platform/glfw/glfw_view.cpp8
-rw-r--r--platform/glfw/glfw_view.hpp1
-rw-r--r--platform/ios/CHANGELOG.md3
-rw-r--r--platform/ios/app/Info.plist2
-rw-r--r--platform/ios/docs/guides/Info.plist Keys.md13
-rw-r--r--platform/macos/CHANGELOG.md3
-rw-r--r--platform/macos/app/Info.plist2
-rw-r--r--platform/macos/docs/guides/Info.plist Keys.md14
-rw-r--r--platform/node/test/ignores.json20
-rw-r--r--src/mbgl/annotation/render_annotation_source.cpp2
-rw-r--r--src/mbgl/annotation/render_annotation_source.hpp2
-rw-r--r--src/mbgl/geometry/feature_index.cpp21
-rw-r--r--src/mbgl/geometry/feature_index.hpp6
-rw-r--r--src/mbgl/map/transform.cpp2
-rw-r--r--src/mbgl/renderer/layers/render_circle_layer.cpp3
-rw-r--r--src/mbgl/renderer/layers/render_fill_extrusion_layer.cpp9
-rw-r--r--src/mbgl/renderer/layers/render_fill_extrusion_layer.hpp1
-rw-r--r--src/mbgl/renderer/layers/render_fill_layer.cpp14
-rw-r--r--src/mbgl/renderer/layers/render_heatmap_layer.cpp3
-rw-r--r--src/mbgl/renderer/layers/render_hillshade_layer.cpp3
-rw-r--r--src/mbgl/renderer/layers/render_line_layer.cpp5
-rw-r--r--src/mbgl/renderer/layers/render_raster_layer.cpp7
-rw-r--r--src/mbgl/renderer/layers/render_symbol_layer.cpp20
-rw-r--r--src/mbgl/renderer/paint_parameters.cpp25
-rw-r--r--src/mbgl/renderer/paint_parameters.hpp3
-rw-r--r--src/mbgl/renderer/render_layer.cpp15
-rw-r--r--src/mbgl/renderer/render_layer.hpp8
-rw-r--r--src/mbgl/renderer/render_orchestrator.cpp58
-rw-r--r--src/mbgl/renderer/render_orchestrator.hpp12
-rw-r--r--src/mbgl/renderer/render_source.hpp14
-rw-r--r--src/mbgl/renderer/render_tile.cpp2
-rw-r--r--src/mbgl/renderer/render_tree.hpp1
-rw-r--r--src/mbgl/renderer/renderer.cpp1
-rw-r--r--src/mbgl/renderer/renderer_impl.cpp1
-rw-r--r--src/mbgl/renderer/sources/render_image_source.cpp2
-rw-r--r--src/mbgl/renderer/sources/render_image_source.hpp4
-rw-r--r--src/mbgl/renderer/sources/render_raster_dem_source.cpp2
-rw-r--r--src/mbgl/renderer/sources/render_raster_dem_source.hpp2
-rw-r--r--src/mbgl/renderer/sources/render_raster_source.cpp2
-rw-r--r--src/mbgl/renderer/sources/render_raster_source.hpp2
-rw-r--r--src/mbgl/renderer/sources/render_tile_source.cpp43
-rw-r--r--src/mbgl/renderer/sources/render_tile_source.hpp8
-rw-r--r--src/mbgl/renderer/tile_pyramid.cpp2
-rw-r--r--src/mbgl/renderer/tile_pyramid.hpp2
-rw-r--r--src/mbgl/tile/geometry_tile.cpp10
-rw-r--r--src/mbgl/tile/geometry_tile.hpp4
-rw-r--r--src/mbgl/tile/tile.cpp4
-rw-r--r--src/mbgl/tile/tile.hpp4
53 files changed, 414 insertions, 173 deletions
diff --git a/circle.yml b/circle.yml
index e69ef56e0d..b15eb6610d 100644
--- a/circle.yml
+++ b/circle.yml
@@ -770,6 +770,7 @@ jobs:
environment:
BUILDTYPE: RelWithDebInfo
HOMEBREW_NO_AUTO_UPDATE: 1
+ HOMEBREW_NO_INSTALL_CLEANUP: 1
steps:
- install-macos-dependencies
- install-node-macos-dependencies
@@ -950,6 +951,7 @@ jobs:
environment:
BUILDTYPE: Debug
HOMEBREW_NO_AUTO_UPDATE: 1
+ HOMEBREW_NO_INSTALL_CLEANUP: 1
steps:
- install-macos-dependencies
- install-dependencies
@@ -990,6 +992,7 @@ jobs:
environment:
BUILDTYPE: Debug
HOMEBREW_NO_AUTO_UPDATE: 1
+ HOMEBREW_NO_INSTALL_CLEANUP: 1
SLACK_CHANNEL: C0ACM9Q2C
steps:
- install-macos-dependencies
@@ -1013,6 +1016,7 @@ jobs:
environment:
BUILDTYPE: Debug
HOMEBREW_NO_AUTO_UPDATE: 1
+ HOMEBREW_NO_INSTALL_CLEANUP: 1
SLACK_CHANNEL: C0ACM9Q2C
steps:
- install-macos-dependencies
@@ -1032,6 +1036,7 @@ jobs:
environment:
BUILDTYPE: Debug
HOMEBREW_NO_AUTO_UPDATE: 1
+ HOMEBREW_NO_INSTALL_CLEANUP: 1
SLACK_CHANNEL: C0ACM9Q2C
steps:
- install-macos-dependencies
@@ -1051,6 +1056,7 @@ jobs:
environment:
BUILDTYPE: Release
HOMEBREW_NO_AUTO_UPDATE: 1
+ HOMEBREW_NO_INSTALL_CLEANUP: 1
SLACK_CHANNEL: C0ACM9Q2C
steps:
- install-macos-dependencies
@@ -1091,6 +1097,7 @@ jobs:
environment:
BUILDTYPE: Release
HOMEBREW_NO_AUTO_UPDATE: 1
+ HOMEBREW_NO_INSTALL_CLEANUP: 1
SLACK_CHANNEL: C0ACM9Q2C
steps:
- checkout
@@ -1134,6 +1141,7 @@ jobs:
environment:
BUILDTYPE: Debug
HOMEBREW_NO_AUTO_UPDATE: 1
+ HOMEBREW_NO_INSTALL_CLEANUP: 1
steps:
- install-macos-dependencies
- install-dependencies
@@ -1159,6 +1167,7 @@ jobs:
environment:
BUILDTYPE: RelWithDebInfo
HOMEBREW_NO_AUTO_UPDATE: 1
+ HOMEBREW_NO_INSTALL_CLEANUP: 1
JOBS: 2
steps:
- install-macos-dependencies
@@ -1203,6 +1212,7 @@ jobs:
environment:
BUILDTYPE: Debug
HOMEBREW_NO_AUTO_UPDATE: 1
+ HOMEBREW_NO_INSTALL_CLEANUP: 1
steps:
- install-macos-dependencies
- install-qt-macos-dependencies
diff --git a/platform/android/CHANGELOG.md b/platform/android/CHANGELOG.md
index 9288256692..d4545e36a7 100644
--- a/platform/android/CHANGELOG.md
+++ b/platform/android/CHANGELOG.md
@@ -4,6 +4,9 @@ Mapbox welcomes participation and contributions from everyone. If you'd like to
## master
+* Performance improvements for queryRenderedFeatures API and optimization that allocates containers based on a number of rendered layers. ([#14930](https://github.com/mapbox/mapbox-gl-native/pull/14930))
+- Fixed rendering layers after fill-extrusion regression caused by optimization of fill-extrusion rendering [#15065](https://github.com/mapbox/mapbox-gl-native/pull/15065)
+
## 8.2.0-alpha.2 - July 3, 2019
### Bugs
diff --git a/platform/darwin/src/MGLRendererConfiguration.h b/platform/darwin/src/MGLRendererConfiguration.h
index ee5aaef174..bfe88b7209 100644
--- a/platform/darwin/src/MGLRendererConfiguration.h
+++ b/platform/darwin/src/MGLRendererConfiguration.h
@@ -23,14 +23,21 @@ MGL_EXPORT
/** The cache dir to use. */
@property (nonatomic, readonly) mbgl::optional<std::string> cacheDir;
-/** The name of the font family to use for client-side text rendering.
-
- Currently only used for CJK glyphs. Changing this at run time is not currently
- supported. Enable client-side rendering of CJK glyphs by setting
- `MGLIdeographicFontFamilyName` in your containing app's Info.plist to a value
- which will be available at run time. Default font for local ideograph font family
- is "PingFang". */
-@property (nonatomic, readonly) std::string localFontFamilyName;
+/** The name of the font family to use for client-side text rendering of CJK ideographs.
+
+ Set MGLIdeographicFontFamilyName in your containing application's Info.plist to
+ font family name(s) that will be available at run time, such as “PingFang TC”
+ or “Marker Felt”. This plist key accepts:
+
+ - A string value of a single font family name.
+
+ - An array of font family names. Fonts will be used in the defined order,
+ eventually falling back to default system font if none are available.
+
+ - A boolean value NO to disable client-side rendering of CJK glyphs —
+ remote fonts specified in your style will be used instead.
+ */
+@property (nonatomic, readonly) mbgl::optional<std::string> localFontFamilyName;
/**
A Boolean value indicating whether symbol layers may enable per-source symbol
diff --git a/platform/darwin/src/MGLRendererConfiguration.mm b/platform/darwin/src/MGLRendererConfiguration.mm
index d616e93eb2..54bdcaa691 100644
--- a/platform/darwin/src/MGLRendererConfiguration.mm
+++ b/platform/darwin/src/MGLRendererConfiguration.mm
@@ -9,6 +9,7 @@
#endif
static NSString * const MGLCollisionBehaviorPre4_0Key = @"MGLCollisionBehaviorPre4_0";
+static NSString * const MGLIdeographicFontFamilyNameKey = @"MGLIdeographicFontFamilyName";
@interface MGLRendererConfiguration ()
@property (nonatomic, readwrite) BOOL perSourceCollisions;
@@ -69,10 +70,54 @@ static NSString * const MGLCollisionBehaviorPre4_0Key = @"MGLCollisionBehaviorPr
return mbgl::optional<std::string>();
}
-- (std::string)localFontFamilyName {
- NSString *fontFamilyName = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"MGLIdeographicFontFamilyName"];
+- (mbgl::optional<std::string>)localFontFamilyName {
+ return [self _localFontFamilyNameWithPropertyDictionary:[[NSBundle mainBundle] infoDictionary]];
+}
- return fontFamilyName ? std::string([fontFamilyName UTF8String]) : std::string("PingFang");
+- (mbgl::optional<std::string>)_localFontFamilyNameWithPropertyDictionary:(nonnull NSDictionary *)properties {
+
+ std::string systemFontFamilyName;
+#if TARGET_OS_IPHONE
+ systemFontFamilyName = std::string([[UIFont systemFontOfSize:0 weight:UIFontWeightRegular].familyName UTF8String]);
+#else
+ systemFontFamilyName = std::string([[NSFont systemFontOfSize:0 weight:NSFontWeightRegular].familyName UTF8String]);
+#endif
+
+ id fontFamilyName = properties[MGLIdeographicFontFamilyNameKey];
+
+ if([fontFamilyName isKindOfClass:[NSNumber class]] && ![fontFamilyName boolValue])
+ {
+ return mbgl::optional<std::string>();
+ }
+ else if([fontFamilyName isKindOfClass:[NSString class]])
+ {
+ BOOL isValidFont = NO;
+#if TARGET_OS_IPHONE
+ if([[UIFont familyNames] containsObject:fontFamilyName]){
+ isValidFont = YES;
+ }
+#else
+ if([[[NSFontManager sharedFontManager] availableFontFamilies] containsObject:fontFamilyName]){
+ isValidFont = YES;
+ }
+#endif
+ return (fontFamilyName && isValidFont) ? std::string([fontFamilyName UTF8String]) : systemFontFamilyName;
+ }
+ // Ability to specify an array of fonts for fallbacks for `localIdeographicFontFamily`
+ else if ([fontFamilyName isKindOfClass:[NSArray class]]){
+ for(NSString *name in fontFamilyName){
+#if TARGET_OS_IPHONE
+ if([[UIFont familyNames] containsObject:name]){
+ return std::string([name UTF8String]);
+ }
+#else
+ if([[[NSFontManager sharedFontManager] availableFontFamilies] containsObject:name]){
+ return std::string([name UTF8String]);
+ }
+#endif
+ }
+ }
+ return systemFontFamilyName;
}
@end
diff --git a/platform/darwin/test/MGLRendererConfigurationTests.mm b/platform/darwin/test/MGLRendererConfigurationTests.mm
index a0c630ebb5..6483aa3587 100644
--- a/platform/darwin/test/MGLRendererConfigurationTests.mm
+++ b/platform/darwin/test/MGLRendererConfigurationTests.mm
@@ -6,6 +6,7 @@ static NSString * const MGLRendererConfigurationTests_collisionBehaviorKey = @"M
@interface MGLRendererConfiguration (Tests)
- (instancetype)initWithPropertyDictionary:(nonnull NSDictionary*)bundle;
+- (mbgl::optional<std::string>)_localFontFamilyNameWithPropertyDictionary:(nonnull NSDictionary *)properties;
@end
@@ -77,14 +78,12 @@ static NSString * const MGLRendererConfigurationTests_collisionBehaviorKey = @"M
}
- (void)testOverridingMGLCollisionBehaviorPre40 {
-
// Dictionary = NO, NSUserDefaults = YES
{
[[NSUserDefaults standardUserDefaults] setObject:@(YES) forKey:MGLRendererConfigurationTests_collisionBehaviorKey];
MGLRendererConfiguration *config = [[MGLRendererConfiguration alloc] initWithPropertyDictionary:@{MGLRendererConfigurationTests_collisionBehaviorKey:@(NO)}];
XCTAssert(config.perSourceCollisions);
}
-
// Dictionary = YES, NSUserDefaults = NO
{
[[NSUserDefaults standardUserDefaults] setObject:@(NO) forKey:MGLRendererConfigurationTests_collisionBehaviorKey];
@@ -93,4 +92,106 @@ static NSString * const MGLRendererConfigurationTests_collisionBehaviorKey = @"M
}
}
+- (void)testDefaultLocalFontFamilyName {
+
+ MGLRendererConfiguration *config = [[MGLRendererConfiguration alloc] init];
+ std::string localFontFamilyName = config.localFontFamilyName.value();
+
+ std::string systemFontFamilyName;
+#if TARGET_OS_IPHONE
+ systemFontFamilyName = std::string([[UIFont systemFontOfSize:0 weight:UIFontWeightRegular].familyName UTF8String]);
+#else
+ systemFontFamilyName = std::string([[NSFont systemFontOfSize:0 weight:NSFontWeightRegular].familyName UTF8String]);
+#endif
+
+ XCTAssertEqual(localFontFamilyName, systemFontFamilyName, @"Default local font family name should match default system font");
+}
+
+- (void)testSettingMGLIdeographicFontFamilyNameWithPlistValue {
+
+ MGLRendererConfiguration *config = [[MGLRendererConfiguration alloc] init];
+ NSDictionary *dic;
+
+ // `MGLIdeographicFontFamilyName` set to bool value `YES`
+ {
+ dic = @{@"MGLIdeographicFontFamilyName": @(YES)};
+ std::string localFontFamilyName = ([config _localFontFamilyNameWithPropertyDictionary:dic]).value();
+
+ std::string systemFontFamilyName;
+#if TARGET_OS_IPHONE
+ systemFontFamilyName = std::string([[UIFont systemFontOfSize:0 weight:UIFontWeightRegular].familyName UTF8String]);
+#else
+ systemFontFamilyName = std::string([[NSFont systemFontOfSize:0 weight:NSFontWeightRegular].familyName UTF8String]);
+#endif
+ XCTAssertEqual(localFontFamilyName, systemFontFamilyName, @"Local font family name should match default system font name when setting `YES`");
+ }
+
+ // `MGLIdeographicFontFamilyName` set to bool value `NO`
+ {
+ dic = @{@"MGLIdeographicFontFamilyName": @(NO)};
+ mbgl::optional<std::string> localFontFamilyName = [config _localFontFamilyNameWithPropertyDictionary:dic];
+ XCTAssertFalse(localFontFamilyName.has_value(), @"Client rendering font should use remote font when setting `NO`");
+ }
+
+ // `MGLIdeographicFontFamilyName` set to a valid font string value
+ {
+ dic = @{@"MGLIdeographicFontFamilyName": @"PingFang TC"};
+ std::string localFontFamilyName = ([config _localFontFamilyNameWithPropertyDictionary:dic]).value();
+ std::string targetFontFamilyName = std::string([@"PingFang TC" UTF8String]);
+ XCTAssertEqual(localFontFamilyName, targetFontFamilyName, @"Local font family name should match a custom valid font name");
+ }
+
+ // `MGLIdeographicFontFamilyName` set to an invalid font string value
+ {
+ dic = @{@"MGLIdeographicFontFamilyName": @"test font"};
+ std::string localFontFamilyName = ([config _localFontFamilyNameWithPropertyDictionary:dic]).value();
+
+ std::string systemFontFamilyName;
+#if TARGET_OS_IPHONE
+ systemFontFamilyName = std::string([[UIFont systemFontOfSize:0 weight:UIFontWeightRegular].familyName UTF8String]);
+#else
+ systemFontFamilyName = std::string([[NSFont systemFontOfSize:0 weight:NSFontWeightRegular].familyName UTF8String]);
+#endif
+ XCTAssertEqual(localFontFamilyName, systemFontFamilyName, @"Local font family name should match default system font name when setting an invalid font string");
+ }
+
+ // `MGLIdeographicFontFamilyName` set to a valid font family names array value
+ {
+ dic = @{@"MGLIdeographicFontFamilyName": @[@"test font 1", @"PingFang TC", @"test font 2"]};
+ std::string localFontFamilyName = ([config _localFontFamilyNameWithPropertyDictionary:dic]).value();
+ std::string targetFontFamilyName = std::string([@"PingFang TC" UTF8String]);
+ XCTAssertEqual(localFontFamilyName, targetFontFamilyName, @"Local font family name should match a custom valid font name in a font family names array");
+ }
+
+ // `MGLIdeographicFontFamilyName` set to an invalid font family names array value
+ {
+ dic = @{@"MGLIdeographicFontFamilyName": @[@"test font 1", @"test font 2", @"test font 3"]};
+ std::string localFontFamilyName = ([config _localFontFamilyNameWithPropertyDictionary:dic]).value();
+
+ std::string systemFontFamilyName;
+#if TARGET_OS_IPHONE
+ systemFontFamilyName = std::string([[UIFont systemFontOfSize:0 weight:UIFontWeightRegular].familyName UTF8String]);
+#else
+ systemFontFamilyName = std::string([[NSFont systemFontOfSize:0 weight:NSFontWeightRegular].familyName UTF8String]);
+#endif
+ XCTAssertEqual(localFontFamilyName, systemFontFamilyName, @"Local font family name should match default system font name when setting an invalid font family names array");
+ }
+
+ // `MGLIdeographicFontFamilyName` set to an invalid value type: NSDictionary, NSNumber, NSData, etc.
+ {
+ dic = @{@"MGLIdeographicFontFamilyName": [@"test font 1" dataUsingEncoding:NSUTF8StringEncoding]};
+ std::string localFontFamilyName = ([config _localFontFamilyNameWithPropertyDictionary:dic]).value();
+
+ std::string systemFontFamilyName;
+#if TARGET_OS_IPHONE
+ systemFontFamilyName = std::string([[UIFont systemFontOfSize:0 weight:UIFontWeightRegular].familyName UTF8String]);
+#else
+ systemFontFamilyName = std::string([[NSFont systemFontOfSize:0 weight:NSFontWeightRegular].familyName UTF8String]);
+#endif
+ XCTAssertEqual(localFontFamilyName, systemFontFamilyName, @"Local font family name should match default system font name when setting an invalid value type");
+ }
+}
+
+
+
@end
diff --git a/platform/glfw/glfw_view.cpp b/platform/glfw/glfw_view.cpp
index 41c3e93b35..43c4de9759 100644
--- a/platform/glfw/glfw_view.cpp
+++ b/platform/glfw/glfw_view.cpp
@@ -102,6 +102,7 @@ GLFWView::GLFWView(bool fullscreen_, bool benchmark_)
glfwSetFramebufferSizeCallback(window, onFramebufferResize);
glfwSetScrollCallback(window, onScroll);
glfwSetKeyCallback(window, onKey);
+ glfwSetWindowFocusCallback(window, onWindowFocus);
glfwGetWindowSize(window, &width, &height);
@@ -559,6 +560,13 @@ void GLFWView::onMouseMove(GLFWwindow *window, double x, double y) {
view->lastY = y;
}
+void GLFWView::onWindowFocus(GLFWwindow *window, int focused) {
+ if (focused == GLFW_FALSE) { // Focus lost.
+ auto *view = reinterpret_cast<GLFWView *>(glfwGetWindowUserPointer(window));
+ view->rendererFrontend->getRenderer()->reduceMemoryUse();
+ }
+}
+
void GLFWView::run() {
auto callback = [&] {
if (glfwWindowShouldClose(window)) {
diff --git a/platform/glfw/glfw_view.hpp b/platform/glfw/glfw_view.hpp
index 9c9661546c..54b89ba2d9 100644
--- a/platform/glfw/glfw_view.hpp
+++ b/platform/glfw/glfw_view.hpp
@@ -68,6 +68,7 @@ private:
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);
+ static void onWindowFocus(GLFWwindow *window, int focused);
// Internal
void report(float duration);
diff --git a/platform/ios/CHANGELOG.md b/platform/ios/CHANGELOG.md
index 723bba6e54..6b4255edd7 100644
--- a/platform/ios/CHANGELOG.md
+++ b/platform/ios/CHANGELOG.md
@@ -5,6 +5,9 @@ Mapbox welcomes participation and contributions from everyone. Please read [CONT
## master
* Ideographic glyphs from Chinese, Japanese, and Korean are no longer downloaded by default as part of offline packs; they are instead rendered on-device, saving bandwidth and storage while improving performance. ([#14176](https://github.com/mapbox/mapbox-gl-native/pull/14176))
+* The `MGLIdeographicFontFamilyName` Info.plist key now also accepts an array of font family names, to customize font fallback behavior. It can also be set to a Boolean value of `NO` to force the SDK to typeset CJK characters in a remote font specified by `MGLSymbolStyleLayer.textFontNames`. ([#14862](https://github.com/mapbox/mapbox-gl-native/pull/14862))
+* Performance improvements for queryRenderedFeatures API and optimization that allocates containers based on a number of rendered layers. ([#14930](https://github.com/mapbox/mapbox-gl-native/pull/14930))
+* Fixed rendering layers after fill-extrusion regression caused by optimization of fill-extrusion rendering. ([#15065](https://github.com/mapbox/mapbox-gl-native/pull/15065))
## 5.2.0
diff --git a/platform/ios/app/Info.plist b/platform/ios/app/Info.plist
index e2f294a5a5..c302f306a6 100644
--- a/platform/ios/app/Info.plist
+++ b/platform/ios/app/Info.plist
@@ -24,8 +24,6 @@
<string>7877</string>
<key>LSRequiresIPhoneOS</key>
<true/>
- <key>MGLIdeographicFontFamilyName</key>
- <string>PingFang TC</string>
<key>NSHumanReadableCopyright</key>
<string>© 2014–2019 Mapbox</string>
<key>NSLocationAlwaysUsageDescription</key>
diff --git a/platform/ios/docs/guides/Info.plist Keys.md b/platform/ios/docs/guides/Info.plist Keys.md
index 97b9d7419e..6322b42dc1 100644
--- a/platform/ios/docs/guides/Info.plist Keys.md
+++ b/platform/ios/docs/guides/Info.plist Keys.md
@@ -22,7 +22,15 @@ If you have implemented custom opt-out of Mapbox Telemetry within the user inter
## MGLIdeographicFontFamilyName
-The name of the font family to use for client-side text rendering of CJK ideographs. Set this to the name of a font family which will be available at run time, e.g. `PingFang TC` (iOS 9+), `Heiti TC` (iOS 8+), another appropriate built-in font, or a font provided by your application. Note that if a non-existent font is specified, iOS will fall back to using Helvetica which is likely not to include support for the glyphs needed to render maps in your application.
+The name of the font family to use for client-side text rendering of CJK ideographs.
+
+Set `MGLIdeographicFontFamilyName` in your containing application's Info.plist to font family name(s) that will be available at run time, such as “PingFang TC” or “Marker Felt”. This plist key accepts:
+
+- A string value of a single font family name.
+
+- An array of font family names. Fonts will be used in the defined order, eventually falling back to default system font if none are available.
+
+- A boolean value `NO` to disable client-side rendering of CJK glyphs — remote fonts specified in your style will be used instead.
## MGLCollisionBehaviorPre4_0
@@ -30,4 +38,5 @@ The name of the font family to use for client-side text rendering of CJK ideogra
Beginning in version 4.0, the SDK also performs collision detection between style layers based on different sources by default. For the default behavior, omit the `MGLCollisionBehaviorPre4_0` key or set it to NO (`false`).
-This property may also be set using `[[NSUserDefaults standardUserDefaults] setObject:@(YES) forKey:@"MGLCollisionBehaviorPre4_0"]`; it will override any value specified in the `Info.plist`. \ No newline at end of file
+This property may also be set using `[[NSUserDefaults standardUserDefaults] setObject:@(YES) forKey:@"MGLCollisionBehaviorPre4_0"]`; it will override any value specified in the `Info.plist`.
+
diff --git a/platform/macos/CHANGELOG.md b/platform/macos/CHANGELOG.md
index 3b3dabdea7..49dd5ff53a 100644
--- a/platform/macos/CHANGELOG.md
+++ b/platform/macos/CHANGELOG.md
@@ -5,6 +5,9 @@
* Added an `MGLMapView.prefetchesTiles` property to configure lower-resolution tile prefetching behavior. ([#14816](https://github.com/mapbox/mapbox-gl-native/pull/14816))
* Fixed queryRenderedFeatues bug caused by incorrect sort feature index calculation. ([#14884](https://github.com/mapbox/mapbox-gl-native/pull/14884))
* Ideographic glyphs from Chinese, Japanese, and Korean are no longer downloaded by default as part of offline packs; they are instead rendered on-device, saving bandwidth and storage while improving performance. ([#14176](https://github.com/mapbox/mapbox-gl-native/pull/14176))
+* The `MGLIdeographicFontFamilyName` Info.plist key now also accepts an array of font family names, to customize font fallback behavior. It can also be set to a Boolean value of `NO` to force the SDK to typeset CJK characters in a remote font specified by `MGLSymbolStyleLayer.textFontNames`. ([#14862](https://github.com/mapbox/mapbox-gl-native/pull/14862))
+* Performance improvements for queryRenderedFeatures API and optimization that allocates containers based on a number of rendered layers. ([#14930](https://github.com/mapbox/mapbox-gl-native/pull/14930))
+* Fixed rendering layers after fill-extrusion regression caused by optimization of fill-extrusion rendering. ([#15065](https://github.com/mapbox/mapbox-gl-native/pull/15065))
### Styles and rendering
diff --git a/platform/macos/app/Info.plist b/platform/macos/app/Info.plist
index 8bb225358c..21b86bfc75 100644
--- a/platform/macos/app/Info.plist
+++ b/platform/macos/app/Info.plist
@@ -2,8 +2,6 @@
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
- <key>MGLIdeographicFontFamilyName</key>
- <string>PingFang TC</string>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleDocumentTypes</key>
diff --git a/platform/macos/docs/guides/Info.plist Keys.md b/platform/macos/docs/guides/Info.plist Keys.md
index fe4c87b0c0..35ecf67e36 100644
--- a/platform/macos/docs/guides/Info.plist Keys.md
+++ b/platform/macos/docs/guides/Info.plist Keys.md
@@ -16,12 +16,20 @@ Use this key if you need to customize the API base URL used throughout the SDK.
The default value is `https://api.mapbox.com`.
-## MGLIdeographicFontFamilyName
+## MGLIdeographicFontFamilyName
-The name of the font family to use for client-side text rendering of CJK ideographs. Set this to the name of a font family which will be available at run time, e.g. `PingFang TC` (iOS 9+), `Heiti TC` (iOS 8+), another appropriate built-in font, or a font provided by your application. Note that if a non-existent font is specified, iOS will fall back to using Helvetica which is likely not to include support for the glyphs needed to render maps in your application.
+The name of the font family to use for client-side text rendering of CJK ideographs.
+
+Set `MGLIdeographicFontFamilyName` in your containing application's Info.plist to font family name(s) that will be available at run time, such as “PingFang TC” or “Marker Felt”. This plist key accepts:
+
+- A string value of a single font family name.
+
+- An array of font family names. Fonts will be used in the defined order, eventually falling back to default system font if none are available.
+
+- A boolean value `NO` to disable client-side rendering of CJK glyphs — remote fonts specified in your style will be used instead.
## MGLCollisionBehaviorPre4_0
If this key is set to YES (`true`), collision detection is performed only between symbol style layers based on the same source, as in versions 0.1–0.7 of the Mapbox Maps SDK for iOS. In other words, symbols in an `MGLSymbolStyleLayer` based on one source (for example, an `MGLShapeSource`) may overlap with symbols in another layer that is based on a different source (such as the Mapbox Streets source). This is the case regardless of the `MGLSymbolStyleLayer.iconAllowsOverlap`, `MGLSymbolStyleLayer.iconIgnoresPlacement`, `MGLSymbolStyleLayer.textAllowsOverlap`, and `MGLSymbolStyleLayer.textIgnoresPlacement` properties.
-Beginning in version 0.7, the SDK also performs collision detection between style layers based on different sources by default. For the default behavior, omit the `MGLCollisionBehaviorPre4_0` key or set it to NO (`false`). This property is so named because version 0.7 of the Mapbox Maps SDK for macOS corresponds to version 4.0 of the Mapbox Maps SDK for iOS. \ No newline at end of file
+Beginning in version 0.7, the SDK also performs collision detection between style layers based on different sources by default. For the default behavior, omit the `MGLCollisionBehaviorPre4_0` key or set it to NO (`false`). This property is so named because version 0.7 of the Mapbox Maps SDK for macOS corresponds to version 4.0 of the Mapbox Maps SDK for iOS.
diff --git a/platform/node/test/ignores.json b/platform/node/test/ignores.json
index 63b9764f22..a97ee70325 100644
--- a/platform/node/test/ignores.json
+++ b/platform/node/test/ignores.json
@@ -77,8 +77,6 @@
"render-tests/regressions/mapbox-gl-js#7271": "https://github.com/mapbox/mapbox-gl-native/issues/12888",
"render-tests/regressions/mapbox-gl-js#7302": "skip - js specific",
"render-tests/regressions/mapbox-gl-native#7357": "https://github.com/mapbox/mapbox-gl-native/issues/7357",
- "render-tests/runtime-styling/paint-property-fill-flat-to-extrude": "https://github.com/mapbox/mapbox-gl-native/issues/6745",
- "render-tests/runtime-styling/set-style-paint-property-fill-flat-to-extrude": "https://github.com/mapbox/mapbox-gl-native/issues/6745",
"render-tests/symbol-cross-fade/chinese": "https://github.com/mapbox/mapbox-gl-native/issues/10619",
"render-tests/symbol-visibility/visible": "https://github.com/mapbox/mapbox-gl-native/issues/10409",
"render-tests/text-pitch-alignment/auto-text-rotation-alignment-map": "https://github.com/mapbox/mapbox-gl-native/issues/9732",
@@ -87,25 +85,7 @@
"render-tests/text-rotate/with-offset": "https://github.com/mapbox/mapbox-gl-native/issues/11872",
"render-tests/video/default": "skip - https://github.com/mapbox/mapbox-gl-native/issues/601",
"render-tests/background-color/colorSpace-hcl": "needs issue",
- "render-tests/combinations/fill-extrusion-translucent--heatmap-translucent": "needs investigation",
"render-tests/combinations/heatmap-translucent--background-opaque": "needs investigation",
- "render-tests/combinations/heatmap-translucent--fill-extrusion-translucent": "needs investigation",
- "render-tests/combinations/background-opaque--fill-extrusion-translucent": "needs investigation",
- "render-tests/combinations/background-translucent--fill-extrusion-translucent": "needs investigation",
- "render-tests/combinations/circle-translucent--fill-extrusion-translucent": "needs investigation",
- "render-tests/combinations/fill-extrusion-translucent--background-translucent": "needs investigation",
- "render-tests/combinations/fill-extrusion-translucent--circle-translucent": "needs investigation",
- "render-tests/combinations/fill-extrusion-translucent--hillshade-translucent": "needs investigation",
- "render-tests/combinations/fill-extrusion-translucent--fill-extrusion-translucent": "needs investigation",
- "render-tests/combinations/fill-extrusion-translucent--fill-translucent": "needs investigation",
- "render-tests/combinations/fill-extrusion-translucent--line-translucent": "needs investigation",
- "render-tests/combinations/fill-extrusion-translucent--symbol-translucent": "needs investigation",
- "render-tests/combinations/hillshade-translucent--fill-extrusion-translucent": "needs investigation",
- "render-tests/combinations/fill-opaque--fill-extrusion-translucent": "needs investigation",
- "render-tests/combinations/fill-translucent--fill-extrusion-translucent": "needs investigation",
- "render-tests/combinations/line-translucent--fill-extrusion-translucent": "needs investigation",
- "render-tests/combinations/raster-translucent--fill-extrusion-translucent": "needs investigation",
- "render-tests/combinations/symbol-translucent--fill-extrusion-translucent": "needs investigation",
"render-tests/feature-state/composite-expression": "https://github.com/mapbox/mapbox-gl-native/issues/12613",
"render-tests/feature-state/data-expression": "https://github.com/mapbox/mapbox-gl-native/issues/12613",
"render-tests/feature-state/vector-source": "https://github.com/mapbox/mapbox-gl-native/issues/12613",
diff --git a/src/mbgl/annotation/render_annotation_source.cpp b/src/mbgl/annotation/render_annotation_source.cpp
index 123a776754..903825d5f5 100644
--- a/src/mbgl/annotation/render_annotation_source.cpp
+++ b/src/mbgl/annotation/render_annotation_source.cpp
@@ -46,7 +46,7 @@ void RenderAnnotationSource::update(Immutable<style::Source::Impl> baseImpl_,
std::unordered_map<std::string, std::vector<Feature>>
RenderAnnotationSource::queryRenderedFeatures(const ScreenLineString& geometry,
const TransformState& transformState,
- const std::vector<const RenderLayer*>& layers,
+ const std::unordered_map<std::string, const RenderLayer*>& layers,
const RenderedQueryOptions& options,
const mat4& projMatrix) const {
return tilePyramid.queryRenderedFeatures(geometry, transformState, layers, options, projMatrix);
diff --git a/src/mbgl/annotation/render_annotation_source.hpp b/src/mbgl/annotation/render_annotation_source.hpp
index 948a0b0d8d..c920d760c2 100644
--- a/src/mbgl/annotation/render_annotation_source.hpp
+++ b/src/mbgl/annotation/render_annotation_source.hpp
@@ -18,7 +18,7 @@ public:
std::unordered_map<std::string, std::vector<Feature>>
queryRenderedFeatures(const ScreenLineString& geometry,
const TransformState& transformState,
- const std::vector<const RenderLayer*>& layers,
+ const std::unordered_map<std::string, const RenderLayer*>& layers,
const RenderedQueryOptions& options,
const mat4& projMatrix) const final;
diff --git a/src/mbgl/geometry/feature_index.cpp b/src/mbgl/geometry/feature_index.cpp
index f61f89b8e7..3675e8bc6e 100644
--- a/src/mbgl/geometry/feature_index.cpp
+++ b/src/mbgl/geometry/feature_index.cpp
@@ -47,7 +47,7 @@ void FeatureIndex::query(
const double scale,
const RenderedQueryOptions& queryOptions,
const UnwrappedTileID& tileID,
- const std::vector<const RenderLayer*>& layers,
+ const std::unordered_map<std::string, const RenderLayer*>& layers,
const float additionalQueryPadding) const {
if (!tileData) {
@@ -81,7 +81,7 @@ void FeatureIndex::query(
std::unordered_map<std::string, std::vector<Feature>>
FeatureIndex::lookupSymbolFeatures(const std::vector<IndexedSubfeature>& symbolFeatures,
const RenderedQueryOptions& queryOptions,
- const std::vector<const RenderLayer*>& layers,
+ const std::unordered_map<std::string, const RenderLayer*>& layers,
const OverscaledTileID& tileID,
const std::shared_ptr<std::vector<size_t>>& featureSortOrder) const {
std::unordered_map<std::string, std::vector<Feature>> result;
@@ -123,31 +123,24 @@ void FeatureIndex::addFeature(
const IndexedSubfeature& indexedFeature,
const RenderedQueryOptions& options,
const CanonicalTileID& tileID,
- const std::vector<const RenderLayer*>& layers,
+ const std::unordered_map<std::string, const RenderLayer*>& layers,
const GeometryCoordinates& queryGeometry,
const TransformState& transformState,
const float pixelsToTileUnits,
const mat4& posMatrix) const {
- auto getRenderLayer = [&] (const std::string& layerID) -> const RenderLayer* {
- for (const auto& layer : layers) {
- if (layer->getID() == layerID) {
- return layer;
- }
- }
- return nullptr;
- };
-
// Lazily calculated.
std::unique_ptr<GeometryTileLayer> sourceLayer;
std::unique_ptr<GeometryTileFeature> geometryTileFeature;
for (const std::string& layerID : bucketLayerIDs.at(indexedFeature.bucketLeaderID)) {
- const RenderLayer* renderLayer = getRenderLayer(layerID);
- if (!renderLayer) {
+ const auto it = layers.find(layerID);
+ if (it == layers.end()) {
continue;
}
+ const RenderLayer* renderLayer = it->second;
+
if (!geometryTileFeature) {
sourceLayer = tileData->getLayer(indexedFeature.sourceLayerName);
assert(sourceLayer);
diff --git a/src/mbgl/geometry/feature_index.hpp b/src/mbgl/geometry/feature_index.hpp
index cd041a7fdb..1a212761fa 100644
--- a/src/mbgl/geometry/feature_index.hpp
+++ b/src/mbgl/geometry/feature_index.hpp
@@ -67,7 +67,7 @@ public:
const double scale,
const RenderedQueryOptions& options,
const UnwrappedTileID&,
- const std::vector<const RenderLayer*>&,
+ const std::unordered_map<std::string, const RenderLayer*>&,
const float additionalQueryPadding) const;
static optional<GeometryCoordinates> translateQueryGeometry(
@@ -82,7 +82,7 @@ public:
std::unordered_map<std::string, std::vector<Feature>> lookupSymbolFeatures(
const std::vector<IndexedSubfeature>& symbolFeatures,
const RenderedQueryOptions& options,
- const std::vector<const RenderLayer*>& layers,
+ const std::unordered_map<std::string, const RenderLayer*>& layers,
const OverscaledTileID& tileID,
const std::shared_ptr<std::vector<size_t>>& featureSortOrder) const;
@@ -92,7 +92,7 @@ private:
const IndexedSubfeature&,
const RenderedQueryOptions& options,
const CanonicalTileID&,
- const std::vector<const RenderLayer*>&,
+ const std::unordered_map<std::string, const RenderLayer*>&,
const GeometryCoordinates& queryGeometry,
const TransformState& transformState,
const float pixelsToTileUnits,
diff --git a/src/mbgl/map/transform.cpp b/src/mbgl/map/transform.cpp
index 88b559592e..a51d4dd4ff 100644
--- a/src/mbgl/map/transform.cpp
+++ b/src/mbgl/map/transform.cpp
@@ -236,7 +236,7 @@ void Transform::flyTo(const CameraOptions &camera, const AnimationOptions &anima
double r1 = r(1);
// When u₀ = u₁, the optimal path doesn’t require both ascent and descent.
- bool isClose = std::abs(u1) < 1.0 || !std::isfinite(r0) || !std::isfinite(r1);
+ bool isClose = std::abs(u1) < 0.000001 || !std::isfinite(r0) || !std::isfinite(r1);
/** w(s): Returns the visible span on the ground, measured in pixels with
respect to the initial scale.
diff --git a/src/mbgl/renderer/layers/render_circle_layer.cpp b/src/mbgl/renderer/layers/render_circle_layer.cpp
index e7496df074..3888e9fec6 100644
--- a/src/mbgl/renderer/layers/render_circle_layer.cpp
+++ b/src/mbgl/renderer/layers/render_circle_layer.cpp
@@ -53,11 +53,12 @@ bool RenderCircleLayer::hasCrossfade() const {
}
void RenderCircleLayer::render(PaintParameters& parameters) {
+ assert(renderTiles);
if (parameters.pass == RenderPass::Opaque) {
return;
}
- for (const RenderTile& tile : renderTiles) {
+ for (const RenderTile& tile : *renderTiles) {
const LayerRenderData* renderData = tile.getLayerRenderData(*baseImpl);
if (!renderData) {
continue;
diff --git a/src/mbgl/renderer/layers/render_fill_extrusion_layer.cpp b/src/mbgl/renderer/layers/render_fill_extrusion_layer.cpp
index 29002d8bdf..5ad2e53a5b 100644
--- a/src/mbgl/renderer/layers/render_fill_extrusion_layer.cpp
+++ b/src/mbgl/renderer/layers/render_fill_extrusion_layer.cpp
@@ -55,7 +55,12 @@ bool RenderFillExtrusionLayer::hasCrossfade() const {
return getCrossfade<FillExtrusionLayerProperties>(evaluatedProperties).t != 1;
}
+bool RenderFillExtrusionLayer::is3D() const {
+ return true;
+}
+
void RenderFillExtrusionLayer::render(PaintParameters& parameters) {
+ assert(renderTiles);
if (parameters.pass != RenderPass::Translucent) {
return;
}
@@ -115,7 +120,7 @@ void RenderFillExtrusionLayer::render(PaintParameters& parameters) {
if (unevaluated.get<FillExtrusionPattern>().isUndefined()) {
// Draw solid color extrusions
auto drawTiles = [&](const gfx::StencilMode& stencilMode_, const gfx::ColorMode& colorMode_, const std::string& name) {
- for (const RenderTile& tile : renderTiles) {
+ for (const RenderTile& tile : *renderTiles) {
const LayerRenderData* renderData = tile.getLayerRenderData(*baseImpl);
if (!renderData) {
continue;
@@ -162,7 +167,7 @@ void RenderFillExtrusionLayer::render(PaintParameters& parameters) {
// Draw textured extrusions
const auto fillPatternValue = evaluated.get<FillExtrusionPattern>().constantOr(mbgl::Faded<std::basic_string<char> >{"", ""});
auto drawTiles = [&](const gfx::StencilMode& stencilMode_, const gfx::ColorMode& colorMode_, const std::string& name) {
- for (const RenderTile& tile : renderTiles) {
+ for (const RenderTile& tile : *renderTiles) {
const LayerRenderData* renderData = tile.getLayerRenderData(*baseImpl);
if (!renderData) {
continue;
diff --git a/src/mbgl/renderer/layers/render_fill_extrusion_layer.hpp b/src/mbgl/renderer/layers/render_fill_extrusion_layer.hpp
index 9118601581..8bd1f52adf 100644
--- a/src/mbgl/renderer/layers/render_fill_extrusion_layer.hpp
+++ b/src/mbgl/renderer/layers/render_fill_extrusion_layer.hpp
@@ -17,6 +17,7 @@ private:
void evaluate(const PropertyEvaluationParameters&) override;
bool hasTransition() const override;
bool hasCrossfade() const override;
+ bool is3D() const override;
void render(PaintParameters&) override;
bool queryIntersectsFeature(
diff --git a/src/mbgl/renderer/layers/render_fill_layer.cpp b/src/mbgl/renderer/layers/render_fill_layer.cpp
index c549b338df..c2bf149582 100644
--- a/src/mbgl/renderer/layers/render_fill_layer.cpp
+++ b/src/mbgl/renderer/layers/render_fill_layer.cpp
@@ -73,9 +73,10 @@ bool RenderFillLayer::hasCrossfade() const {
}
void RenderFillLayer::render(PaintParameters& parameters) {
+ assert(renderTiles);
if (unevaluated.get<FillPattern>().isUndefined()) {
parameters.renderTileClippingMasks(renderTiles);
- for (const RenderTile& tile : renderTiles) {
+ for (const RenderTile& tile : *renderTiles) {
const LayerRenderData* renderData = tile.getLayerRenderData(*baseImpl);
if (!renderData) {
continue;
@@ -129,11 +130,10 @@ void RenderFillLayer::render(PaintParameters& parameters) {
);
};
- // Only draw the fill when it's opaque and we're drawing opaque fragments,
- // or when it's translucent and we're drawing translucent fragments.
- if (bucket.triangleIndexBuffer &&
- (evaluated.get<FillColor>().constantOr(Color()).a >= 1.0f &&
- evaluated.get<FillOpacity>().constantOr(0) >= 1.0f) == (parameters.pass == RenderPass::Opaque)) {
+ auto fillRenderPass = (evaluated.get<FillColor>().constantOr(Color()).a >= 1.0f
+ && evaluated.get<FillOpacity>().constantOr(0) >= 1.0f
+ && parameters.currentLayer >= parameters.opaquePassCutoff) ? RenderPass::Opaque : RenderPass::Translucent;
+ if (bucket.triangleIndexBuffer && parameters.pass == fillRenderPass) {
draw(parameters.programs.getFillLayerPrograms().fill,
gfx::Triangles(),
parameters.depthModeForSublayer(1, parameters.pass == RenderPass::Opaque
@@ -162,7 +162,7 @@ void RenderFillLayer::render(PaintParameters& parameters) {
parameters.renderTileClippingMasks(renderTiles);
- for (const RenderTile& tile : renderTiles) {
+ for (const RenderTile& tile : *renderTiles) {
const LayerRenderData* renderData = tile.getLayerRenderData(*baseImpl);
if (!renderData) {
continue;
diff --git a/src/mbgl/renderer/layers/render_heatmap_layer.cpp b/src/mbgl/renderer/layers/render_heatmap_layer.cpp
index 4b80dee5e7..e087d2ca69 100644
--- a/src/mbgl/renderer/layers/render_heatmap_layer.cpp
+++ b/src/mbgl/renderer/layers/render_heatmap_layer.cpp
@@ -63,6 +63,7 @@ void RenderHeatmapLayer::upload(gfx::UploadPass& uploadPass) {
}
void RenderHeatmapLayer::render(PaintParameters& parameters) {
+ assert(renderTiles);
if (parameters.pass == RenderPass::Opaque) {
return;
}
@@ -93,7 +94,7 @@ void RenderHeatmapLayer::render(PaintParameters& parameters) {
auto renderPass = parameters.encoder->createRenderPass(
"heatmap texture", { *renderTexture, Color{ 0.0f, 0.0f, 0.0f, 1.0f }, {}, {} });
- for (const RenderTile& tile : renderTiles) {
+ for (const RenderTile& tile : *renderTiles) {
const LayerRenderData* renderData = tile.getLayerRenderData(*baseImpl);
if (!renderData) {
continue;
diff --git a/src/mbgl/renderer/layers/render_hillshade_layer.cpp b/src/mbgl/renderer/layers/render_hillshade_layer.cpp
index 2cbb77f24b..9d1b5293c1 100644
--- a/src/mbgl/renderer/layers/render_hillshade_layer.cpp
+++ b/src/mbgl/renderer/layers/render_hillshade_layer.cpp
@@ -71,6 +71,7 @@ void RenderHillshadeLayer::prepare(const LayerPrepareParameters& params) {
}
void RenderHillshadeLayer::render(PaintParameters& parameters) {
+ assert(renderTiles);
if (parameters.pass != RenderPass::Translucent && parameters.pass != RenderPass::Pass3D)
return;
const auto& evaluated = static_cast<const HillshadeLayerProperties&>(*evaluatedProperties).evaluated;
@@ -126,7 +127,7 @@ void RenderHillshadeLayer::render(PaintParameters& parameters) {
matrix::ortho(mat, 0, util::EXTENT, -util::EXTENT, 0, 0, 1);
matrix::translate(mat, mat, 0, -util::EXTENT, 0);
- for (const RenderTile& tile : renderTiles) {
+ for (const RenderTile& tile : *renderTiles) {
auto* bucket_ = tile.getBucket(*baseImpl);
if (!bucket_) {
continue;
diff --git a/src/mbgl/renderer/layers/render_line_layer.cpp b/src/mbgl/renderer/layers/render_line_layer.cpp
index 595140634d..061be0aba1 100644
--- a/src/mbgl/renderer/layers/render_line_layer.cpp
+++ b/src/mbgl/renderer/layers/render_line_layer.cpp
@@ -61,7 +61,7 @@ bool RenderLineLayer::hasCrossfade() const {
void RenderLineLayer::prepare(const LayerPrepareParameters& params) {
RenderLayer::prepare(params);
- for (const RenderTile& tile : renderTiles) {
+ for (const RenderTile& tile : *renderTiles) {
const LayerRenderData* renderData = tile.getLayerRenderData(*baseImpl);
if (!renderData) continue;
@@ -84,13 +84,14 @@ void RenderLineLayer::upload(gfx::UploadPass& uploadPass) {
}
void RenderLineLayer::render(PaintParameters& parameters) {
+ assert(renderTiles);
if (parameters.pass == RenderPass::Opaque) {
return;
}
parameters.renderTileClippingMasks(renderTiles);
- for (const RenderTile& tile : renderTiles) {
+ for (const RenderTile& tile : *renderTiles) {
const LayerRenderData* renderData = tile.getLayerRenderData(*baseImpl);
if (!renderData) {
continue;
diff --git a/src/mbgl/renderer/layers/render_raster_layer.cpp b/src/mbgl/renderer/layers/render_raster_layer.cpp
index e22e14275c..ce1fa52f5e 100644
--- a/src/mbgl/renderer/layers/render_raster_layer.cpp
+++ b/src/mbgl/renderer/layers/render_raster_layer.cpp
@@ -74,8 +74,9 @@ static std::array<float, 3> spinWeights(float spin) {
}
void RenderRasterLayer::prepare(const LayerPrepareParameters& params) {
- RenderLayer::prepare(params);
+ renderTiles = params.source->getRenderTiles();
imageData = params.source->getImageRenderData();
+ assert(renderTiles || imageData);
}
void RenderRasterLayer::render(PaintParameters& parameters) {
@@ -153,8 +154,8 @@ void RenderRasterLayer::render(PaintParameters& parameters) {
},
bucket.drawScopeID + std::to_string(i++));
}
- } else {
- for (const RenderTile& tile : renderTiles) {
+ } else if (renderTiles) {
+ for (const RenderTile& tile : *renderTiles) {
auto* bucket_ = tile.getBucket(*baseImpl);
if (!bucket_) {
continue;
diff --git a/src/mbgl/renderer/layers/render_symbol_layer.cpp b/src/mbgl/renderer/layers/render_symbol_layer.cpp
index 60b0c8e2d8..b24e088ac4 100644
--- a/src/mbgl/renderer/layers/render_symbol_layer.cpp
+++ b/src/mbgl/renderer/layers/render_symbol_layer.cpp
@@ -276,6 +276,7 @@ bool RenderSymbolLayer::hasCrossfade() const {
}
void RenderSymbolLayer::render(PaintParameters& parameters) {
+ assert(renderTiles);
if (parameters.pass == RenderPass::Opaque) {
return;
}
@@ -348,7 +349,7 @@ void RenderSymbolLayer::render(PaintParameters& parameters) {
);
};
- for (const RenderTile& tile : renderTiles) {
+ for (const RenderTile& tile : *renderTiles) {
const LayerRenderData* renderData = tile.getLayerRenderData(*baseImpl);
if (!renderData) {
continue;
@@ -493,22 +494,11 @@ style::TextPaintProperties::PossiblyEvaluated RenderSymbolLayer::textPaintProper
}
void RenderSymbolLayer::prepare(const LayerPrepareParameters& params) {
- renderTiles = params.source->getRenderTiles();
- const auto comp = [bearing = params.state.getBearing()](const RenderTile& a, const RenderTile& b) {
- Point<float> pa(a.id.canonical.x, a.id.canonical.y);
- Point<float> pb(b.id.canonical.x, b.id.canonical.y);
-
- auto par = util::rotate(pa, bearing);
- auto pbr = util::rotate(pb, bearing);
-
- return std::tie(b.id.canonical.z, par.y, par.x) < std::tie(a.id.canonical.z, pbr.y, pbr.x);
- };
- // Sort symbol tiles in opposite y position, so tiles with overlapping symbols are drawn
- // on top of each other, with lower symbols being drawn on top of higher symbols.
- std::sort(renderTiles.begin(), renderTiles.end(), comp);
+ renderTiles = params.source->getRenderTilesSortedByYPosition();
+ assert(renderTiles);
placementData.clear();
- for (const RenderTile& renderTile : renderTiles) {
+ for (const RenderTile& renderTile : *renderTiles) {
auto* bucket = static_cast<SymbolBucket*>(renderTile.getBucket(*baseImpl));
if (bucket && bucket->bucketLeaderID == getID()) {
// Only place this layer if it's the "group leader" for the bucket
diff --git a/src/mbgl/renderer/paint_parameters.cpp b/src/mbgl/renderer/paint_parameters.cpp
index 0bb66972a8..6c6abc008b 100644
--- a/src/mbgl/renderer/paint_parameters.cpp
+++ b/src/mbgl/renderer/paint_parameters.cpp
@@ -19,10 +19,11 @@ TransformParameters::TransformParameters(const TransformState& state_)
// odd viewport sizes.
state.getProjMatrix(alignedProjMatrix, 1, true);
- // Calculate a second projection matrix with the near plane clipped to 100 so as
- // not to waste lots of depth buffer precision on very close empty space, for layer
- // types (fill-extrusion) that use the depth buffer to emulate real-world space.
- state.getProjMatrix(nearClippedProjMatrix, 100);
+ // Calculate a second projection matrix with the near plane moved further,
+ // to a tenth of the far value, so as not to waste depth buffer precision on
+ // very close empty space, for layer types (fill-extrusion) that use the
+ // depth buffer to emulate real-world space.
+ state.getProjMatrix(nearClippedProjMatrix, 0.1 * state.getCameraToCenterDistance());
}
PaintParameters::PaintParameters(gfx::Context& context_,
@@ -72,6 +73,9 @@ mat4 PaintParameters::matrixForTile(const UnwrappedTileID& tileID, bool aligned)
}
gfx::DepthMode PaintParameters::depthModeForSublayer(uint8_t n, gfx::DepthMaskType mask) const {
+ if (currentLayer < opaquePassCutoff) {
+ return gfx::DepthMode::disabled();
+ }
float depth = depthRangeSize + ((1 + currentLayer) * numSublayers + n) * depthEpsilon;
return gfx::DepthMode { gfx::DepthFunctionType::LessEqual, mask, { depth, depth } };
}
@@ -92,24 +96,25 @@ namespace {
// Detects a difference in keys of renderTiles and tileClippingMaskIDs
bool tileIDsIdentical(const RenderTiles& renderTiles,
const std::map<UnwrappedTileID, int32_t>& tileClippingMaskIDs) {
- assert(std::is_sorted(renderTiles.begin(), renderTiles.end(),
+ assert(renderTiles);
+ assert(std::is_sorted(renderTiles->begin(), renderTiles->end(),
[](const RenderTile& a, const RenderTile& b) { return a.id < b.id; }));
- if (renderTiles.size() != tileClippingMaskIDs.size()) {
+ if (renderTiles->size() != tileClippingMaskIDs.size()) {
return false;
}
- return std::equal(renderTiles.begin(), renderTiles.end(), tileClippingMaskIDs.begin(),
+ return std::equal(renderTiles->begin(), renderTiles->end(), tileClippingMaskIDs.begin(),
[](const RenderTile& a, const auto& b) { return a.id == b.first; });
}
} // namespace
void PaintParameters::renderTileClippingMasks(const RenderTiles& renderTiles) {
- if (renderTiles.empty() || tileIDsIdentical(renderTiles, tileClippingMaskIDs)) {
+ if (!renderTiles || renderTiles->empty() || tileIDsIdentical(renderTiles, tileClippingMaskIDs)) {
// The current stencil mask is for this source already; no need to draw another one.
return;
}
- if (nextStencilID + renderTiles.size() > 256) {
+ if (nextStencilID + renderTiles->size() > 256) {
// we'll run out of fresh IDs so we need to clear and start from scratch
clearStencil();
}
@@ -120,7 +125,7 @@ void PaintParameters::renderTileClippingMasks(const RenderTiles& renderTiles) {
const style::Properties<>::PossiblyEvaluated properties {};
const ClippingMaskProgram::Binders paintAttributeData(properties, 0);
- for (const RenderTile& renderTile : renderTiles) {
+ for (const RenderTile& renderTile : *renderTiles) {
const int32_t stencilID = nextStencilID++;
tileClippingMaskIDs.emplace(renderTile.id, stencilID);
diff --git a/src/mbgl/renderer/paint_parameters.hpp b/src/mbgl/renderer/paint_parameters.hpp
index a0d26df7c5..a043ad5578 100644
--- a/src/mbgl/renderer/paint_parameters.hpp
+++ b/src/mbgl/renderer/paint_parameters.hpp
@@ -104,8 +104,7 @@ public:
uint32_t currentLayer;
float depthRangeSize;
const float depthEpsilon = 1.0f / (1 << 16);
-
-
+ uint32_t opaquePassCutoff = 0;
float symbolFadeChange;
};
diff --git a/src/mbgl/renderer/render_layer.cpp b/src/mbgl/renderer/render_layer.cpp
index 9e79d7338c..b92b28998c 100644
--- a/src/mbgl/renderer/render_layer.cpp
+++ b/src/mbgl/renderer/render_layer.cpp
@@ -47,25 +47,14 @@ bool RenderLayer::supportsZoom(float zoom) const {
void RenderLayer::prepare(const LayerPrepareParameters& params) {
assert(params.source);
- renderTiles = filterRenderTiles(params.source->getRenderTiles());
+ renderTiles = params.source->getRenderTiles();
+ assert(renderTiles);
}
optional<Color> RenderLayer::getSolidBackground() const {
return nullopt;
}
-RenderTiles RenderLayer::filterRenderTiles(RenderTiles tiles) const {
- RenderTiles filtered;
-
- for (const RenderTile& tile : tiles) {
- if (tile.holdForFade()) {
- continue;
- }
- filtered.emplace_back(tile);
- }
- return filtered;
-}
-
void RenderLayer::markContextDestroyed() {
// no-op
}
diff --git a/src/mbgl/renderer/render_layer.hpp b/src/mbgl/renderer/render_layer.hpp
index 11c7587893..fe8b7c6529 100644
--- a/src/mbgl/renderer/render_layer.hpp
+++ b/src/mbgl/renderer/render_layer.hpp
@@ -1,6 +1,7 @@
#pragma once
#include <mbgl/layout/layout.hpp>
#include <mbgl/renderer/render_pass.hpp>
+#include <mbgl/renderer/render_source.hpp>
#include <mbgl/style/layer_properties.hpp>
#include <mbgl/tile/geometry_tile_data.hpp>
#include <mbgl/util/mat4.hpp>
@@ -15,7 +16,6 @@ class TransitionParameters;
class PropertyEvaluationParameters;
class UploadParameters;
class PaintParameters;
-class RenderSource;
class RenderTile;
class TransformState;
class PatternAtlas;
@@ -43,8 +43,6 @@ public:
const TransformState& state;
};
-using RenderTiles = std::vector<std::reference_wrapper<const RenderTile>>;
-
class RenderLayer {
protected:
RenderLayer(Immutable<style::LayerProperties>);
@@ -68,6 +66,9 @@ public:
// Returns true if the layer has a pattern property and is actively crossfading.
virtual bool hasCrossfade() const = 0;
+ // Returns true if layer writes to depth buffer by drawing using PaintParameters::depthModeFor3D().
+ virtual bool is3D() const { return false; }
+
// Returns true is the layer is subject to placement.
bool needsPlacement() const;
@@ -127,7 +128,6 @@ protected:
std::vector<LayerPlacementData> placementData;
private:
- RenderTiles filterRenderTiles(RenderTiles) const;
// Some layers may not render correctly on some hardware when the vertex attribute limit of
// that GPU is exceeded. More attributes are used when adding many data driven paint properties
// to a layer.
diff --git a/src/mbgl/renderer/render_orchestrator.cpp b/src/mbgl/renderer/render_orchestrator.cpp
index fafbc8b635..cf5a7d190e 100644
--- a/src/mbgl/renderer/render_orchestrator.cpp
+++ b/src/mbgl/renderer/render_orchestrator.cpp
@@ -271,11 +271,17 @@ std::unique_ptr<RenderTree> RenderOrchestrator::createRenderTree(const UpdatePar
std::vector<std::reference_wrapper<RenderLayer>> layersNeedPlacement;
auto renderItemsEmplaceHint = layerRenderItems.begin();
+ // Reserve size for filteredLayersForSource if there are sources.
+ if (!sourceImpls->empty()) {
+ filteredLayersForSource.reserve(layerImpls->size());
+ if (filteredLayersForSource.capacity() > layerImpls->size()) {
+ filteredLayersForSource.shrink_to_fit();
+ }
+ }
+
// Update all sources and initialize renderItems.
for (const auto& sourceImpl : *sourceImpls) {
RenderSource* source = renderSources.at(sourceImpl->id).get();
- std::vector<Immutable<LayerProperties>> filteredLayersForSource;
- filteredLayersForSource.reserve(layerImpls->size());
bool sourceNeedsRendering = false;
bool sourceNeedsRelayout = false;
@@ -321,6 +327,7 @@ std::unique_ptr<RenderTree> RenderOrchestrator::createRenderTree(const UpdatePar
sourceNeedsRendering,
sourceNeedsRelayout,
tileParameters);
+ filteredLayersForSource.clear();
}
renderTreeParameters->loaded = updateParameters.styleLoaded && isLoaded();
@@ -335,12 +342,17 @@ std::unique_ptr<RenderTree> RenderOrchestrator::createRenderTree(const UpdatePar
}
}
+ auto opaquePassCutOffEstimation = layerRenderItems.size();
for (auto& renderItem : layerRenderItems) {
RenderLayer& renderLayer = renderItem.layer;
renderLayer.prepare({renderItem.source, *imageManager, *patternAtlas, *lineAtlas, updateParameters.transformState});
if (renderLayer.needsPlacement()) {
layersNeedPlacement.emplace_back(renderLayer);
}
+ if (renderLayer.is3D() && renderTreeParameters->opaquePassCutOff == 0) {
+ --opaquePassCutOffEstimation;
+ renderTreeParameters->opaquePassCutOff = uint32_t(opaquePassCutOffEstimation);
+ }
}
// Symbol placement.
{
@@ -409,16 +421,16 @@ std::unique_ptr<RenderTree> RenderOrchestrator::createRenderTree(const UpdatePar
}
std::vector<Feature> RenderOrchestrator::queryRenderedFeatures(const ScreenLineString& geometry, const RenderedQueryOptions& options) const {
- std::vector<const RenderLayer*> layers;
+ std::unordered_map<std::string, const RenderLayer*> layers;
if (options.layerIDs) {
for (const auto& layerID : *options.layerIDs) {
if (const RenderLayer* layer = getRenderLayer(layerID)) {
- layers.emplace_back(layer);
+ layers.emplace(layer->getID(), layer);
}
}
} else {
for (const auto& entry : renderLayers) {
- layers.emplace_back(entry.second.get());
+ layers.emplace(entry.second->getID(), entry.second.get());
}
}
@@ -427,9 +439,22 @@ std::vector<Feature> RenderOrchestrator::queryRenderedFeatures(const ScreenLineS
void RenderOrchestrator::queryRenderedSymbols(std::unordered_map<std::string, std::vector<Feature>>& resultsByLayer,
const ScreenLineString& geometry,
- const std::vector<const RenderLayer*>& layers,
+ const std::unordered_map<std::string, const RenderLayer*>& layers,
const RenderedQueryOptions& options) const {
-
+ const auto hasCrossTileIndex = [] (const auto& pair) {
+ return pair.second->baseImpl->getTypeInfo()->crossTileIndex == style::LayerTypeInfo::CrossTileIndex::Required;
+ };
+
+ std::unordered_map<std::string, const RenderLayer*> crossTileSymbolIndexLayers;
+ std::copy_if(layers.begin(),
+ layers.end(),
+ std::inserter(crossTileSymbolIndexLayers, crossTileSymbolIndexLayers.begin()),
+ hasCrossTileIndex);
+
+ if (crossTileSymbolIndexLayers.empty()) {
+ return;
+ }
+
auto renderedSymbols = placement->getCollisionIndex().queryRenderedSymbols(geometry);
std::vector<std::reference_wrapper<const RetainedQueryData>> bucketQueryData;
for (auto entry : renderedSymbols) {
@@ -447,7 +472,7 @@ void RenderOrchestrator::queryRenderedSymbols(std::unordered_map<std::string, st
auto& queryData = wrappedQueryData.get();
auto bucketSymbols = queryData.featureIndex->lookupSymbolFeatures(renderedSymbols[queryData.bucketInstanceId],
options,
- layers,
+ crossTileSymbolIndexLayers,
queryData.tileID,
queryData.featureSortOrder);
@@ -458,10 +483,10 @@ void RenderOrchestrator::queryRenderedSymbols(std::unordered_map<std::string, st
}
}
-std::vector<Feature> RenderOrchestrator::queryRenderedFeatures(const ScreenLineString& geometry, const RenderedQueryOptions& options, const std::vector<const RenderLayer*>& layers) const {
+std::vector<Feature> RenderOrchestrator::queryRenderedFeatures(const ScreenLineString& geometry, const RenderedQueryOptions& options, const std::unordered_map<std::string, const RenderLayer*>& layers) const {
std::unordered_set<std::string> sourceIDs;
- for (const RenderLayer* layer : layers) {
- sourceIDs.emplace(layer->baseImpl->source);
+ for (const auto& pair : layers) {
+ sourceIDs.emplace(pair.second->baseImpl->source);
}
mat4 projMatrix;
@@ -484,13 +509,12 @@ std::vector<Feature> RenderOrchestrator::queryRenderedFeatures(const ScreenLineS
}
// Combine all results based on the style layer renderItems.
- for (const auto& layerImpl : *layerImpls) {
- const RenderLayer* layer = getRenderLayer(layerImpl->id);
- if (!layer->needsRendering() || !layer->supportsZoom(zoomHistory.lastZoom)) {
+ for (const auto& pair : layers) {
+ if (!pair.second->needsRendering() || !pair.second->supportsZoom(zoomHistory.lastZoom)) {
continue;
}
- auto it = resultsByLayer.find(layer->baseImpl->id);
+ auto it = resultsByLayer.find(pair.second->baseImpl->id);
if (it != resultsByLayer.end()) {
std::move(it->second.begin(), it->second.end(), std::back_inserter(result));
}
@@ -501,13 +525,13 @@ std::vector<Feature> RenderOrchestrator::queryRenderedFeatures(const ScreenLineS
std::vector<Feature> RenderOrchestrator::queryShapeAnnotations(const ScreenLineString& geometry) const {
assert(LayerManager::annotationsEnabled);
- std::vector<const RenderLayer*> shapeAnnotationLayers;
+ std::unordered_map<std::string, const RenderLayer*> shapeAnnotationLayers;
RenderedQueryOptions options;
for (const auto& layerImpl : *layerImpls) {
if (std::mismatch(layerImpl->id.begin(), layerImpl->id.end(),
AnnotationManager::ShapeLayerID.begin(), AnnotationManager::ShapeLayerID.end()).second == AnnotationManager::ShapeLayerID.end()) {
if (const RenderLayer* layer = getRenderLayer(layerImpl->id)) {
- shapeAnnotationLayers.emplace_back(layer);
+ shapeAnnotationLayers.emplace(layer->getID(), layer);
}
}
}
diff --git a/src/mbgl/renderer/render_orchestrator.hpp b/src/mbgl/renderer/render_orchestrator.hpp
index a60bac2e16..884bd21b7b 100644
--- a/src/mbgl/renderer/render_orchestrator.hpp
+++ b/src/mbgl/renderer/render_orchestrator.hpp
@@ -33,6 +33,10 @@ class PatternAtlas;
class CrossTileSymbolIndex;
class RenderTree;
+namespace style {
+ class LayerProperties;
+} // namespace style
+
class RenderOrchestrator final : public GlyphManagerObserver,
public ImageManagerObserver,
public RenderSourceObserver {
@@ -74,10 +78,10 @@ private:
void queryRenderedSymbols(std::unordered_map<std::string, std::vector<Feature>>& resultsByLayer,
const ScreenLineString& geometry,
- const std::vector<const RenderLayer*>& layers,
+ const std::unordered_map<std::string, const RenderLayer*>& layers,
const RenderedQueryOptions& options) const;
- std::vector<Feature> queryRenderedFeatures(const ScreenLineString&, const RenderedQueryOptions&, const std::vector<const RenderLayer*>&) const;
+ std::vector<Feature> queryRenderedFeatures(const ScreenLineString&, const RenderedQueryOptions&, const std::unordered_map<std::string, const RenderLayer*>&) const;
// GlyphManagerObserver implementation.
void onGlyphsError(const FontStack&, const GlyphRange&, std::exception_ptr) override;
@@ -113,6 +117,10 @@ private:
const bool backgroundLayerAsColor;
bool contextLost = false;
+
+ // Vector with reserved capacity of layerImpls->size() to avoid reallocation
+ // on each frame.
+ std::vector<Immutable<style::LayerProperties>> filteredLayersForSource;
};
} // namespace mbgl
diff --git a/src/mbgl/renderer/render_source.hpp b/src/mbgl/renderer/render_source.hpp
index fc770f83cf..cd471223a8 100644
--- a/src/mbgl/renderer/render_source.hpp
+++ b/src/mbgl/renderer/render_source.hpp
@@ -43,7 +43,7 @@ public:
const ImageManager& imageManager;
};
-using RenderTiles = std::vector<std::reference_wrapper<const RenderTile>>;
+using RenderTiles = std::shared_ptr<const std::vector<std::reference_wrapper<const RenderTile>>>;
class RenderSource : protected TileObserver {
public:
@@ -64,15 +64,21 @@ public:
virtual void prepare(const SourcePrepareParameters&) = 0;
virtual void updateFadingTiles() = 0;
virtual bool hasFadingTiles() const = 0;
- // Returns a list of RenderTiles, sorted by tile id.
- virtual RenderTiles getRenderTiles() = 0;
+ // If supported, returns a shared list of RenderTiles, sorted by tile id and excluding tiles hold for fade;
+ // returns nullptr otherwise.
+ virtual RenderTiles getRenderTiles() const { return nullptr; }
+ // If supported, returns a shared list of RenderTiles, sorted in opposite y position, so tiles with overlapping
+ // symbols are drawn on top of each other, with lower symbols being drawn on top of higher symbols;
+ // returns nullptr otherwise.
+ virtual RenderTiles getRenderTilesSortedByYPosition() const { return nullptr; }
+ // If supported, returns pointer to image data; returns nullptr otherwise.
virtual const ImageSourceRenderData* getImageRenderData() const { return nullptr; }
virtual const Tile* getRenderedTile(const UnwrappedTileID&) const { return nullptr; }
virtual std::unordered_map<std::string, std::vector<Feature>>
queryRenderedFeatures(const ScreenLineString& geometry,
const TransformState& transformState,
- const std::vector<const RenderLayer*>& layers,
+ const std::unordered_map<std::string, const RenderLayer*>& layers,
const RenderedQueryOptions& options,
const mat4& projMatrix) const = 0;
diff --git a/src/mbgl/renderer/render_tile.cpp b/src/mbgl/renderer/render_tile.cpp
index fbb2ae81de..65a6cb9f30 100644
--- a/src/mbgl/renderer/render_tile.cpp
+++ b/src/mbgl/renderer/render_tile.cpp
@@ -121,7 +121,7 @@ void RenderTile::prepare(const SourcePrepareParameters& parameters) {
}
// Calculate two matrices for this tile: matrix is the standard tile matrix; nearClippedMatrix
- // clips the near plane to 100 to save depth buffer precision
+ // has near plane moved further, to enhance depth buffer precision
const auto& transform = parameters.transform;
transform.state.matrixFor(matrix, id);
transform.state.matrixFor(nearClippedMatrix, id);
diff --git a/src/mbgl/renderer/render_tree.hpp b/src/mbgl/renderer/render_tree.hpp
index 4266ddec6d..cf62ccb03e 100644
--- a/src/mbgl/renderer/render_tree.hpp
+++ b/src/mbgl/renderer/render_tree.hpp
@@ -47,6 +47,7 @@ public:
TimePoint timePoint;
EvaluatedLight light;
bool has3D = false;
+ uint32_t opaquePassCutOff = 0;
Color backgroundColor;
float symbolFadeChange = 0.0f;
bool needsRepaint = false;
diff --git a/src/mbgl/renderer/renderer.cpp b/src/mbgl/renderer/renderer.cpp
index 76e618a50f..dd715bd3bc 100644
--- a/src/mbgl/renderer/renderer.cpp
+++ b/src/mbgl/renderer/renderer.cpp
@@ -116,6 +116,7 @@ void Renderer::dumpDebugLogs() {
}
void Renderer::reduceMemoryUse() {
+ gfx::BackendScope guard { impl->backend };
impl->reduceMemoryUse();
impl->orchestrator.reduceMemoryUse();
}
diff --git a/src/mbgl/renderer/renderer_impl.cpp b/src/mbgl/renderer/renderer_impl.cpp
index c536497c30..990d9cd3ab 100644
--- a/src/mbgl/renderer/renderer_impl.cpp
+++ b/src/mbgl/renderer/renderer_impl.cpp
@@ -77,6 +77,7 @@ void Renderer::Impl::render(const RenderTree& renderTree) {
};
parameters.symbolFadeChange = renderTreeParameters.symbolFadeChange;
+ parameters.opaquePassCutoff = renderTreeParameters.opaquePassCutOff;
const auto& sourceRenderItems = renderTree.getSourceRenderItems();
const auto& layerRenderItems = renderTree.getLayerRenderItems();
diff --git a/src/mbgl/renderer/sources/render_image_source.cpp b/src/mbgl/renderer/sources/render_image_source.cpp
index 7e793c6a4a..6d197df9db 100644
--- a/src/mbgl/renderer/sources/render_image_source.cpp
+++ b/src/mbgl/renderer/sources/render_image_source.cpp
@@ -106,7 +106,7 @@ void RenderImageSource::prepare(const SourcePrepareParameters& parameters) {
std::unordered_map<std::string, std::vector<Feature>>
RenderImageSource::queryRenderedFeatures(const ScreenLineString&,
const TransformState&,
- const std::vector<const RenderLayer*>&,
+ const std::unordered_map<std::string, const RenderLayer*>&,
const RenderedQueryOptions&,
const mat4&) const {
return std::unordered_map<std::string, std::vector<Feature>> {};
diff --git a/src/mbgl/renderer/sources/render_image_source.hpp b/src/mbgl/renderer/sources/render_image_source.hpp
index d21f4fae10..da0d899624 100644
--- a/src/mbgl/renderer/sources/render_image_source.hpp
+++ b/src/mbgl/renderer/sources/render_image_source.hpp
@@ -48,8 +48,6 @@ public:
bool needsRelayout,
const TileParameters&) final;
- RenderTiles getRenderTiles() override { return {}; }
-
const ImageSourceRenderData* getImageRenderData() const override {
return renderData.get();
}
@@ -57,7 +55,7 @@ public:
std::unordered_map<std::string, std::vector<Feature>>
queryRenderedFeatures(const ScreenLineString& geometry,
const TransformState& transformState,
- const std::vector<const RenderLayer*>& layers,
+ const std::unordered_map<std::string, const RenderLayer*>& layers,
const RenderedQueryOptions& options,
const mat4& projMatrix) const final;
diff --git a/src/mbgl/renderer/sources/render_raster_dem_source.cpp b/src/mbgl/renderer/sources/render_raster_dem_source.cpp
index 9854b4fdc3..841124fa4a 100644
--- a/src/mbgl/renderer/sources/render_raster_dem_source.cpp
+++ b/src/mbgl/renderer/sources/render_raster_dem_source.cpp
@@ -125,7 +125,7 @@ void RenderRasterDEMSource::onTileChanged(Tile& tile){
std::unordered_map<std::string, std::vector<Feature>>
RenderRasterDEMSource::queryRenderedFeatures(const ScreenLineString&,
const TransformState&,
- const std::vector<const RenderLayer*>&,
+ const std::unordered_map<std::string, const RenderLayer*>&,
const RenderedQueryOptions&,
const mat4&) const {
return std::unordered_map<std::string, std::vector<Feature>>{};
diff --git a/src/mbgl/renderer/sources/render_raster_dem_source.hpp b/src/mbgl/renderer/sources/render_raster_dem_source.hpp
index e49ad1d1d4..dd74f4d7e7 100644
--- a/src/mbgl/renderer/sources/render_raster_dem_source.hpp
+++ b/src/mbgl/renderer/sources/render_raster_dem_source.hpp
@@ -19,7 +19,7 @@ public:
std::unordered_map<std::string, std::vector<Feature>>
queryRenderedFeatures(const ScreenLineString& geometry,
const TransformState& transformState,
- const std::vector<const RenderLayer*>& layers,
+ const std::unordered_map<std::string, const RenderLayer*>& layers,
const RenderedQueryOptions& options,
const mat4& projMatrix) const override;
diff --git a/src/mbgl/renderer/sources/render_raster_source.cpp b/src/mbgl/renderer/sources/render_raster_source.cpp
index 827ffb9759..06eb36795b 100644
--- a/src/mbgl/renderer/sources/render_raster_source.cpp
+++ b/src/mbgl/renderer/sources/render_raster_source.cpp
@@ -60,7 +60,7 @@ void RenderRasterSource::prepare(const SourcePrepareParameters& parameters) {
std::unordered_map<std::string, std::vector<Feature>>
RenderRasterSource::queryRenderedFeatures(const ScreenLineString&,
const TransformState&,
- const std::vector<const RenderLayer*>&,
+ const std::unordered_map<std::string, const RenderLayer*>&,
const RenderedQueryOptions&,
const mat4&) const {
return std::unordered_map<std::string, std::vector<Feature>>{};
diff --git a/src/mbgl/renderer/sources/render_raster_source.hpp b/src/mbgl/renderer/sources/render_raster_source.hpp
index dc80630add..0071dddec9 100644
--- a/src/mbgl/renderer/sources/render_raster_source.hpp
+++ b/src/mbgl/renderer/sources/render_raster_source.hpp
@@ -19,7 +19,7 @@ public:
std::unordered_map<std::string, std::vector<Feature>>
queryRenderedFeatures(const ScreenLineString& geometry,
const TransformState& transformState,
- const std::vector<const RenderLayer*>& layers,
+ const std::unordered_map<std::string, const RenderLayer*>& layers,
const RenderedQueryOptions& options,
const mat4& projMatrix) const override;
diff --git a/src/mbgl/renderer/sources/render_tile_source.cpp b/src/mbgl/renderer/sources/render_tile_source.cpp
index 99bdfde485..6ee2eca1b1 100644
--- a/src/mbgl/renderer/sources/render_tile_source.cpp
+++ b/src/mbgl/renderer/sources/render_tile_source.cpp
@@ -6,6 +6,7 @@
#include <mbgl/renderer/paint_parameters.hpp>
#include <mbgl/renderer/tile_render_data.hpp>
#include <mbgl/tile/vector_tile.hpp>
+#include <mbgl/util/math.hpp>
namespace mbgl {
@@ -56,6 +57,9 @@ std::unique_ptr<RenderItem> RenderTileSource::createRenderItem() {
}
void RenderTileSource::prepare(const SourcePrepareParameters& parameters) {
+ bearing = parameters.transform.state.getBearing();
+ filteredRenderTiles = nullptr;
+ renderTilesSortedByY = nullptr;
auto tiles = makeMutable<std::vector<RenderTile>>();
tiles->reserve(tilePyramid.getRenderedTiles().size());
for (auto& entry : tilePyramid.getRenderedTiles()) {
@@ -73,8 +77,41 @@ bool RenderTileSource::hasFadingTiles() const {
return tilePyramid.hasFadingTiles();
}
-RenderTiles RenderTileSource::getRenderTiles() {
- return { renderTiles->begin(), renderTiles->end() };
+RenderTiles RenderTileSource::getRenderTiles() const {
+ if (!filteredRenderTiles) {
+ auto result = std::make_shared<std::vector<std::reference_wrapper<const RenderTile>>>();
+ for (const auto& renderTile : *renderTiles) {
+ if (renderTile.holdForFade()) {
+ continue;
+ }
+ result->emplace_back(renderTile);
+ }
+ filteredRenderTiles = std::move(result);
+ }
+ return filteredRenderTiles;
+}
+
+RenderTiles RenderTileSource::getRenderTilesSortedByYPosition() const {
+ if (!renderTilesSortedByY) {
+ const auto comp = [bearing = this->bearing](const RenderTile& a, const RenderTile& b) {
+ Point<float> pa(a.id.canonical.x, a.id.canonical.y);
+ Point<float> pb(b.id.canonical.x, b.id.canonical.y);
+
+ auto par = util::rotate(pa, bearing);
+ auto pbr = util::rotate(pb, bearing);
+
+ return std::tie(b.id.canonical.z, par.y, par.x) < std::tie(a.id.canonical.z, pbr.y, pbr.x);
+ };
+
+ auto result = std::make_shared<std::vector<std::reference_wrapper<const RenderTile>>>();
+ result->reserve(renderTiles->size());
+ for (const auto& renderTile : *renderTiles) {
+ result->emplace_back(renderTile);
+ }
+ std::sort(result->begin(), result->end(), comp);
+ renderTilesSortedByY = std::move(result);
+ }
+ return renderTilesSortedByY;
}
const Tile* RenderTileSource::getRenderedTile(const UnwrappedTileID& tileID) const {
@@ -84,7 +121,7 @@ const Tile* RenderTileSource::getRenderedTile(const UnwrappedTileID& tileID) con
std::unordered_map<std::string, std::vector<Feature>>
RenderTileSource::queryRenderedFeatures(const ScreenLineString& geometry,
const TransformState& transformState,
- const std::vector<const RenderLayer*>& layers,
+ const std::unordered_map<std::string, const RenderLayer*>& layers,
const RenderedQueryOptions& options,
const mat4& projMatrix) const {
return tilePyramid.queryRenderedFeatures(geometry, transformState, layers, options, projMatrix);
diff --git a/src/mbgl/renderer/sources/render_tile_source.hpp b/src/mbgl/renderer/sources/render_tile_source.hpp
index e3148b45b9..f961c20561 100644
--- a/src/mbgl/renderer/sources/render_tile_source.hpp
+++ b/src/mbgl/renderer/sources/render_tile_source.hpp
@@ -21,13 +21,14 @@ public:
void updateFadingTiles() override;
bool hasFadingTiles() const override;
- RenderTiles getRenderTiles() override;
+ RenderTiles getRenderTiles() const override;
+ RenderTiles getRenderTilesSortedByYPosition() const override;
const Tile* getRenderedTile(const UnwrappedTileID&) const override;
std::unordered_map<std::string, std::vector<Feature>>
queryRenderedFeatures(const ScreenLineString& geometry,
const TransformState& transformState,
- const std::vector<const RenderLayer*>& layers,
+ const std::unordered_map<std::string, const RenderLayer*>& layers,
const RenderedQueryOptions& options,
const mat4& projMatrix) const override;
@@ -40,6 +41,9 @@ public:
protected:
TilePyramid tilePyramid;
Immutable<std::vector<RenderTile>> renderTiles;
+ mutable RenderTiles filteredRenderTiles;
+ mutable RenderTiles renderTilesSortedByY;
+ float bearing = 0.0f;
};
} // namespace mbgl
diff --git a/src/mbgl/renderer/tile_pyramid.cpp b/src/mbgl/renderer/tile_pyramid.cpp
index e08803134d..f47198e275 100644
--- a/src/mbgl/renderer/tile_pyramid.cpp
+++ b/src/mbgl/renderer/tile_pyramid.cpp
@@ -284,7 +284,7 @@ void TilePyramid::handleWrapJump(float lng) {
std::unordered_map<std::string, std::vector<Feature>> TilePyramid::queryRenderedFeatures(const ScreenLineString& geometry,
const TransformState& transformState,
- const std::vector<const RenderLayer*>& layers,
+ const std::unordered_map<std::string, const RenderLayer*>& layers,
const RenderedQueryOptions& options,
const mat4& projMatrix) const {
std::unordered_map<std::string, std::vector<Feature>> result;
diff --git a/src/mbgl/renderer/tile_pyramid.hpp b/src/mbgl/renderer/tile_pyramid.hpp
index 675831fbc9..f80eb0db78 100644
--- a/src/mbgl/renderer/tile_pyramid.hpp
+++ b/src/mbgl/renderer/tile_pyramid.hpp
@@ -52,7 +52,7 @@ public:
std::unordered_map<std::string, std::vector<Feature>>
queryRenderedFeatures(const ScreenLineString& geometry,
const TransformState& transformState,
- const std::vector<const RenderLayer*>&,
+ const std::unordered_map<std::string, const RenderLayer*>&,
const RenderedQueryOptions& options,
const mat4& projMatrix) const;
diff --git a/src/mbgl/tile/geometry_tile.cpp b/src/mbgl/tile/geometry_tile.cpp
index e87d21503a..7f1bed49f4 100644
--- a/src/mbgl/tile/geometry_tile.cpp
+++ b/src/mbgl/tile/geometry_tile.cpp
@@ -291,12 +291,12 @@ LayerRenderData* GeometryTile::getLayerRenderData(const style::Layer::Impl& laye
return layoutResult ? layoutResult->getLayerRenderData(layerImpl) : nullptr;
}
-float GeometryTile::getQueryPadding(const std::vector<const RenderLayer*>& layers) {
+float GeometryTile::getQueryPadding(const std::unordered_map<std::string, const RenderLayer*>& layers) {
float queryPadding = 0;
- for (const RenderLayer* layer : layers) {
- const LayerRenderData* data = getLayerRenderData(*layer->baseImpl);
+ for (const auto& pair : layers) {
+ const LayerRenderData* data = getLayerRenderData(*pair.second->baseImpl);
if (data && data->bucket && data->bucket->hasData()) {
- queryPadding = std::max(queryPadding, data->bucket->getQueryRadius(*layer));
+ queryPadding = std::max(queryPadding, data->bucket->getQueryRadius(*pair.second));
}
}
return queryPadding;
@@ -306,7 +306,7 @@ void GeometryTile::queryRenderedFeatures(
std::unordered_map<std::string, std::vector<Feature>>& result,
const GeometryCoordinates& queryGeometry,
const TransformState& transformState,
- const std::vector<const RenderLayer*>& layers,
+ const std::unordered_map<std::string, const RenderLayer*>& layers,
const RenderedQueryOptions& options,
const mat4& projMatrix) {
diff --git a/src/mbgl/tile/geometry_tile.hpp b/src/mbgl/tile/geometry_tile.hpp
index 3d75dfc456..7c46edfc1d 100644
--- a/src/mbgl/tile/geometry_tile.hpp
+++ b/src/mbgl/tile/geometry_tile.hpp
@@ -52,7 +52,7 @@ public:
std::unordered_map<std::string, std::vector<Feature>>& result,
const GeometryCoordinates& queryGeometry,
const TransformState&,
- const std::vector<const RenderLayer*>& layers,
+ const std::unordered_map<std::string, const RenderLayer*>& layers,
const RenderedQueryOptions& options,
const mat4& projMatrix) override;
@@ -60,7 +60,7 @@ public:
std::vector<Feature>& result,
const SourceQueryOptions&) override;
- float getQueryPadding(const std::vector<const RenderLayer*>&) override;
+ float getQueryPadding(const std::unordered_map<std::string, const RenderLayer*>&) override;
void cancel() override;
diff --git a/src/mbgl/tile/tile.cpp b/src/mbgl/tile/tile.cpp
index 5e31898caf..2f342c092d 100644
--- a/src/mbgl/tile/tile.cpp
+++ b/src/mbgl/tile/tile.cpp
@@ -43,11 +43,11 @@ void Tile::queryRenderedFeatures(
std::unordered_map<std::string, std::vector<Feature>>&,
const GeometryCoordinates&,
const TransformState&,
- const std::vector<const RenderLayer*>&,
+ const std::unordered_map<std::string, const RenderLayer*>&,
const RenderedQueryOptions&,
const mat4&) {}
-float Tile::getQueryPadding(const std::vector<const RenderLayer*>&) {
+float Tile::getQueryPadding(const std::unordered_map<std::string, const RenderLayer*>&) {
return 0;
}
diff --git a/src/mbgl/tile/tile.hpp b/src/mbgl/tile/tile.hpp
index 4ba8bc1160..7a7d246aa6 100644
--- a/src/mbgl/tile/tile.hpp
+++ b/src/mbgl/tile/tile.hpp
@@ -71,7 +71,7 @@ public:
std::unordered_map<std::string, std::vector<Feature>>& result,
const GeometryCoordinates& queryGeometry,
const TransformState&,
- const std::vector<const RenderLayer*>&,
+ const std::unordered_map<std::string, const RenderLayer*>&,
const RenderedQueryOptions& options,
const mat4& projMatrix);
@@ -79,7 +79,7 @@ public:
std::vector<Feature>& result,
const SourceQueryOptions&);
- virtual float getQueryPadding(const std::vector<const RenderLayer*>&);
+ virtual float getQueryPadding(const std::unordered_map<std::string, const RenderLayer*>&);
void setTriedCache();