Skip to content

Commit 7abf366

Browse files
lasselammiactions-userkediarov
authored andcommitted
[MAPS3D-865] Make line-emissive-strength data-driven (#5075)
This PR makes the property `line-emissive-strength` data-driven. Implemented for both GL JS and Native. ``` <public> [MAPS3D-865] Make line-emissive-strength data-driven (#5075) </public> ``` ## Background Making `line-emissive-strength` data-driven should allow merging road layers in the Standard style as a performance optimization. More details are in the ticket: https://mapbox.atlassian.net/browse/MAPS3D-865 ## Draping support During draping we must be able to accumulate the per-feature emissive strength values from each layer, so that they can be used later when the lighting is applied during the terrain/globe raster pass. For this we have two approaches: **dual-source blending** and **MRT fallback**. ### Dual-source blending Dual-source blending is fully compatible with our previous emissive strength support where the emissive values are accumulated in the alpha channel of the main color texture. The old approach applies emissive strength as a constant alpha value for the blend mode, which means no per-feature emissive strength is possible for draping. With dual-source blending, we output the emissive strength value from the fragment shader along with the color value, which are then blended together with `Src1Alpha` blend factor. Using dual-source blending is the optimal approach, since it doesn't increase memory usage and has no performance penalty compared to our previous approach. Unfortunately it's not available on every device, so before we use it we must check that it's supported. This is done in different ways depending on the platform. **GL-JS:** - Support for dual-source blending is checked using the WebGL extension `WEBGL_blend_func_extended` - Latest versions of Chrome and Safari support dual-source blending. Firefox doesn't have support for it yet **GL-Native:** - OpenGL: Support for dual-source blending is checked using `glad` with the extensions `GLAD_GL_ARB_blend_func_extended` and `GLAD_GL_EXT_blend_func_extended` - Metal: Support is checked by using GPU family information queried at runtime similar to how it's done for occlusion queries - Vulkan: Support is checked using physical device feature `dualSrcBlend` queried at runtime ### MRT (multiple render targets) fallback All of the platforms and devices that we support should support a minimum of 4 color attachments for FBOs and we only need 2 for the MRT fallback approach for data-driven emissive strength. The fallback mode is only activated when dual-source blending is not available and when the style has a layer with a data-driven `line-emissive-strength` property. This is when a secondary color attachment is added to offscreen textures that are used for draping using the format `gfx::PixelFormat::R8`. In this mode, all of the layers that use emissive strength accumulate it into the secondary color texture instead of the alpha channel of the main color texture. These secondary color textures are expected to increase memory usage of the draping pool by 25%. ### MRT support for Vulkan I didn't want to make this PR any bigger than it already is, so it only includes support for dual-source blending for Vulkan. MRT support for Vulkan can be implemented as a follow-up PR. ### Render tests To ensure that support for MRT attachments remains fully functional even as more platforms start supporting dual-source blending, I added a new render test flag `forceEmissiveFallback` to force render tests to use the MRT fallback render path. In this way all platforms will run tests for the MRT fallback approach even when dual-source blending is available. ### Shell example I added a Shell example for data-driven `line-emissive-strength`. By using the example it is possible to use both dual-source blending (when available) and MRT fallback. When the example is active it also shows which mode is currently being used, so it is possible to check if a particular device supports dual-source blending by running the Shell app on it and enabling the example. The code for the Shell example is mostly AI generated. <img width="1358" height="960" alt="image" src="https://github.com/user-attachments/assets/806de749-60cd-401b-b7b5-92c5b827c73f" /> ## Performance considerations The changes in this PR should not affect the performance of styles that don't contain any layers with data-driven `line-emissive-strength` property. When a style does contain a layer with a data-driven `line-emissive-strength` property: **Without draping:** - No issues here since the emissive strength is applied normally in the fragment shader during immediate rendering **With draping:** - Dual-source blending: - No extra memory used - No expected performance decrease (benchmarks still needed) - MRT fallback: - Extra memory for draping pool (25% increase) - Extra memory bandwidth needed for writing to multiple render targets. For this render path we must write emissive values from **all layers** to the secondary emissive attachment. I tested loading and rendering performance using a style with reduced number of road layers which is available here https://mapbox.atlassian.net/browse/MAPS3D-865?focusedCommentId=534175 **Loading performance:** Profiled using Xcode with an iPhone 15. I didn't see any clear performance difference in my tests. **Rendering performance:** Tested with S22 Ultra, zoom 12, pitch 60 near Munich. 113 FPS with the original style vs 117 FPS with the updated style using data-driven `line-emissive-strength`. cc @mapbox/gl-js cc @mapbox/gl-native [MAPS3D-865]: https://mapbox.atlassian.net/browse/MAPS3D-865?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ cc @mapbox/maps-android cc @mapbox/maps-ios cc @mapbox/sdk-ci --------- Co-authored-by: Changelog autocreator bot <[email protected]> Co-authored-by: Kirill Kediarov <[email protected]> GitOrigin-RevId: aac743c91adfe15e67295e27cc9ff4702d328d42
1 parent 4c88dfd commit 7abf366

File tree

12 files changed

+168
-14
lines changed

12 files changed

+168
-14
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ Mapbox welcomes participation and contributions from everyone.
1313
* Add `FillExtrusionLayer.castShadows` property.
1414
* Add `GeoJsonSource.minZoom` property.
1515
* Add `RasterArraySource.volatile` experimental property.
16+
* Make `line-emissive-strength` property data-driven.
1617

1718
## Bug fixes 🐞
1819
* Fix camera listener not unsubscribed when disabling ScaleBar via `updateSettings { enabled = false }`

app/src/androidTest/java/com/mapbox/maps/testapp/annotation/generated/PolylineAnnotationManagerAndroidTest.kt

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

extension-compose/api/Release/metalava.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1119,6 +1119,7 @@ package com.mapbox.maps.extension.compose.annotation.generated {
11191119
method public Double? getLineBorderWidth();
11201120
method public androidx.compose.ui.graphics.Color? getLineColor();
11211121
method public String? getLineColorUseTheme();
1122+
method public Double? getLineEmissiveStrength();
11221123
method public Double? getLineGapWidth();
11231124
method public com.mapbox.maps.extension.style.layers.properties.generated.LineJoin? getLineJoin();
11241125
method public Double? getLineOffset();
@@ -1133,6 +1134,7 @@ package com.mapbox.maps.extension.compose.annotation.generated {
11331134
method public void setLineBorderWidth(Double?);
11341135
method public void setLineColor(androidx.compose.ui.graphics.Color?);
11351136
method public void setLineColorUseTheme(String?);
1137+
method public void setLineEmissiveStrength(Double?);
11361138
method public void setLineGapWidth(Double?);
11371139
method public void setLineJoin(com.mapbox.maps.extension.style.layers.properties.generated.LineJoin?);
11381140
method public void setLineOffset(Double?);
@@ -1147,6 +1149,7 @@ package com.mapbox.maps.extension.compose.annotation.generated {
11471149
property public final Double? lineBorderWidth;
11481150
property public final androidx.compose.ui.graphics.Color? lineColor;
11491151
property public final String? lineColorUseTheme;
1152+
property public final Double? lineEmissiveStrength;
11501153
property public final Double? lineGapWidth;
11511154
property public final com.mapbox.maps.extension.style.layers.properties.generated.LineJoin? lineJoin;
11521155
property public final Double? lineOffset;

extension-compose/api/extension-compose.api

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -881,6 +881,7 @@ public final class com/mapbox/maps/extension/compose/annotation/generated/Polyli
881881
public final fun getLineBorderWidth ()Ljava/lang/Double;
882882
public final fun getLineColor-QN2ZGVo ()Landroidx/compose/ui/graphics/Color;
883883
public final fun getLineColorUseTheme ()Ljava/lang/String;
884+
public final fun getLineEmissiveStrength ()Ljava/lang/Double;
884885
public final fun getLineGapWidth ()Ljava/lang/Double;
885886
public final fun getLineJoin ()Lcom/mapbox/maps/extension/style/layers/properties/generated/LineJoin;
886887
public final fun getLineOffset ()Ljava/lang/Double;
@@ -895,6 +896,7 @@ public final class com/mapbox/maps/extension/compose/annotation/generated/Polyli
895896
public final fun setLineBorderWidth (Ljava/lang/Double;)V
896897
public final fun setLineColor-Y2TPw74 (Landroidx/compose/ui/graphics/Color;)V
897898
public final fun setLineColorUseTheme (Ljava/lang/String;)V
899+
public final fun setLineEmissiveStrength (Ljava/lang/Double;)V
898900
public final fun setLineGapWidth (Ljava/lang/Double;)V
899901
public final fun setLineJoin (Lcom/mapbox/maps/extension/style/layers/properties/generated/LineJoin;)V
900902
public final fun setLineOffset (Ljava/lang/Double;)V

extension-compose/src/main/java/com/mapbox/maps/extension/compose/annotation/generated/PolylineAnnotationState.kt

Lines changed: 17 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

extension-style-app/src/androidTest/java/com/mapbox/maps/testapp/style/layers/generated/LineLayerTest.kt

Lines changed: 7 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

plugin-annotation/api/Release/metalava.txt

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1237,6 +1237,7 @@ package com.mapbox.maps.plugin.annotation.generated {
12371237
method @ColorInt public Integer? getLineColorInt();
12381238
method public String? getLineColorString();
12391239
method public String? getLineColorUseTheme();
1240+
method public Double? getLineEmissiveStrength();
12401241
method public Double? getLineGapWidth();
12411242
method public com.mapbox.maps.extension.style.layers.properties.generated.LineJoin? getLineJoin();
12421243
method public Double? getLineOffset();
@@ -1256,6 +1257,7 @@ package com.mapbox.maps.plugin.annotation.generated {
12561257
method public void setLineColorInt(@ColorInt Integer?);
12571258
method public void setLineColorString(String?);
12581259
method public void setLineColorUseTheme(String?);
1260+
method public void setLineEmissiveStrength(Double?);
12591261
method public void setLineGapWidth(Double?);
12601262
method public void setLineJoin(com.mapbox.maps.extension.style.layers.properties.generated.LineJoin?);
12611263
method public void setLineOffset(Double?);
@@ -1274,6 +1276,7 @@ package com.mapbox.maps.plugin.annotation.generated {
12741276
property @ColorInt public final Integer? lineColorInt;
12751277
property public final String? lineColorString;
12761278
property public final String? lineColorUseTheme;
1279+
property public final Double? lineEmissiveStrength;
12771280
property public final Double? lineGapWidth;
12781281
property public final com.mapbox.maps.extension.style.layers.properties.generated.LineJoin? lineJoin;
12791282
property public final Double? lineOffset;
@@ -1450,6 +1453,7 @@ package com.mapbox.maps.plugin.annotation.generated {
14501453
method public Double? getLineBorderWidth();
14511454
method public String? getLineColor();
14521455
method public String? getLineColorUseTheme();
1456+
method public Double? getLineEmissiveStrength();
14531457
method public Double? getLineGapWidth();
14541458
method public com.mapbox.maps.extension.style.layers.properties.generated.LineJoin? getLineJoin();
14551459
method public Double? getLineOffset();
@@ -1465,6 +1469,7 @@ package com.mapbox.maps.plugin.annotation.generated {
14651469
method public void setLineBorderWidth(Double?);
14661470
method public void setLineColor(String?);
14671471
method public void setLineColorUseTheme(String?);
1472+
method public void setLineEmissiveStrength(Double?);
14681473
method public void setLineGapWidth(Double?);
14691474
method public void setLineJoin(com.mapbox.maps.extension.style.layers.properties.generated.LineJoin?);
14701475
method public void setLineOffset(Double?);
@@ -1484,6 +1489,7 @@ package com.mapbox.maps.plugin.annotation.generated {
14841489
method public com.mapbox.maps.plugin.annotation.generated.PolylineAnnotationOptions withLineColor(String lineColor);
14851490
method public com.mapbox.maps.plugin.annotation.generated.PolylineAnnotationOptions withLineColor(@ColorInt int lineColor);
14861491
method public com.mapbox.maps.plugin.annotation.generated.PolylineAnnotationOptions withLineColorUseTheme(String lineColorUseTheme);
1492+
method public com.mapbox.maps.plugin.annotation.generated.PolylineAnnotationOptions withLineEmissiveStrength(double lineEmissiveStrength);
14871493
method public com.mapbox.maps.plugin.annotation.generated.PolylineAnnotationOptions withLineGapWidth(double lineGapWidth);
14881494
method public com.mapbox.maps.plugin.annotation.generated.PolylineAnnotationOptions withLineJoin(com.mapbox.maps.extension.style.layers.properties.generated.LineJoin lineJoin);
14891495
method public com.mapbox.maps.plugin.annotation.generated.PolylineAnnotationOptions withLineOffset(double lineOffset);
@@ -1499,6 +1505,7 @@ package com.mapbox.maps.plugin.annotation.generated {
14991505
property public final Double? lineBorderWidth;
15001506
property public final String? lineColor;
15011507
property public final String? lineColorUseTheme;
1508+
property public final Double? lineEmissiveStrength;
15021509
property public final Double? lineGapWidth;
15031510
property public final com.mapbox.maps.extension.style.layers.properties.generated.LineJoin? lineJoin;
15041511
property public final Double? lineOffset;
@@ -1514,6 +1521,7 @@ package com.mapbox.maps.plugin.annotation.generated {
15141521
field public static final String PROPERTY_LINE_BORDER_WIDTH = "line-border-width";
15151522
field public static final String PROPERTY_LINE_COLOR = "line-color";
15161523
field public static final String PROPERTY_LINE_COLOR_USE_THEME = "line-color-use-theme";
1524+
field public static final String PROPERTY_LINE_EMISSIVE_STRENGTH = "line-emissive-strength";
15171525
field public static final String PROPERTY_LINE_GAP_WIDTH = "line-gap-width";
15181526
field public static final String PROPERTY_LINE_JOIN = "line-join";
15191527
field public static final String PROPERTY_LINE_OFFSET = "line-offset";

plugin-annotation/api/plugin-annotation.api

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -972,6 +972,7 @@ public final class com/mapbox/maps/plugin/annotation/generated/PolylineAnnotatio
972972
public final fun getLineColorInt ()Ljava/lang/Integer;
973973
public final fun getLineColorString ()Ljava/lang/String;
974974
public final fun getLineColorUseTheme ()Ljava/lang/String;
975+
public final fun getLineEmissiveStrength ()Ljava/lang/Double;
975976
public final fun getLineGapWidth ()Ljava/lang/Double;
976977
public final fun getLineJoin ()Lcom/mapbox/maps/extension/style/layers/properties/generated/LineJoin;
977978
public final fun getLineOffset ()Ljava/lang/Double;
@@ -992,6 +993,7 @@ public final class com/mapbox/maps/plugin/annotation/generated/PolylineAnnotatio
992993
public final fun setLineColorInt (Ljava/lang/Integer;)V
993994
public final fun setLineColorString (Ljava/lang/String;)V
994995
public final fun setLineColorUseTheme (Ljava/lang/String;)V
996+
public final fun setLineEmissiveStrength (Ljava/lang/Double;)V
995997
public final fun setLineGapWidth (Ljava/lang/Double;)V
996998
public final fun setLineJoin (Lcom/mapbox/maps/extension/style/layers/properties/generated/LineJoin;)V
997999
public final fun setLineOffset (Ljava/lang/Double;)V
@@ -1120,6 +1122,7 @@ public final class com/mapbox/maps/plugin/annotation/generated/PolylineAnnotatio
11201122
public static final field PROPERTY_LINE_BORDER_WIDTH Ljava/lang/String;
11211123
public static final field PROPERTY_LINE_COLOR Ljava/lang/String;
11221124
public static final field PROPERTY_LINE_COLOR_USE_THEME Ljava/lang/String;
1125+
public static final field PROPERTY_LINE_EMISSIVE_STRENGTH Ljava/lang/String;
11231126
public static final field PROPERTY_LINE_GAP_WIDTH Ljava/lang/String;
11241127
public static final field PROPERTY_LINE_JOIN Ljava/lang/String;
11251128
public static final field PROPERTY_LINE_OFFSET Ljava/lang/String;
@@ -1140,6 +1143,7 @@ public final class com/mapbox/maps/plugin/annotation/generated/PolylineAnnotatio
11401143
public final fun getLineBorderWidth ()Ljava/lang/Double;
11411144
public final fun getLineColor ()Ljava/lang/String;
11421145
public final fun getLineColorUseTheme ()Ljava/lang/String;
1146+
public final fun getLineEmissiveStrength ()Ljava/lang/Double;
11431147
public final fun getLineGapWidth ()Ljava/lang/Double;
11441148
public final fun getLineJoin ()Lcom/mapbox/maps/extension/style/layers/properties/generated/LineJoin;
11451149
public final fun getLineOffset ()Ljava/lang/Double;
@@ -1155,6 +1159,7 @@ public final class com/mapbox/maps/plugin/annotation/generated/PolylineAnnotatio
11551159
public final fun setLineBorderWidth (Ljava/lang/Double;)V
11561160
public final fun setLineColor (Ljava/lang/String;)V
11571161
public final fun setLineColorUseTheme (Ljava/lang/String;)V
1162+
public final fun setLineEmissiveStrength (Ljava/lang/Double;)V
11581163
public final fun setLineGapWidth (Ljava/lang/Double;)V
11591164
public final fun setLineJoin (Lcom/mapbox/maps/extension/style/layers/properties/generated/LineJoin;)V
11601165
public final fun setLineOffset (Ljava/lang/Double;)V
@@ -1174,6 +1179,7 @@ public final class com/mapbox/maps/plugin/annotation/generated/PolylineAnnotatio
11741179
public final fun withLineColor (I)Lcom/mapbox/maps/plugin/annotation/generated/PolylineAnnotationOptions;
11751180
public final fun withLineColor (Ljava/lang/String;)Lcom/mapbox/maps/plugin/annotation/generated/PolylineAnnotationOptions;
11761181
public final fun withLineColorUseTheme (Ljava/lang/String;)Lcom/mapbox/maps/plugin/annotation/generated/PolylineAnnotationOptions;
1182+
public final fun withLineEmissiveStrength (D)Lcom/mapbox/maps/plugin/annotation/generated/PolylineAnnotationOptions;
11771183
public final fun withLineGapWidth (D)Lcom/mapbox/maps/plugin/annotation/generated/PolylineAnnotationOptions;
11781184
public final fun withLineJoin (Lcom/mapbox/maps/extension/style/layers/properties/generated/LineJoin;)Lcom/mapbox/maps/plugin/annotation/generated/PolylineAnnotationOptions;
11791185
public final fun withLineOffset (D)Lcom/mapbox/maps/plugin/annotation/generated/PolylineAnnotationOptions;

plugin-annotation/src/main/java/com/mapbox/maps/plugin/annotation/generated/PolylineAnnotation.kt

Lines changed: 36 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)