maplibre-gl 6.2.0 → 6.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (124) hide show
  1. package/dist/maplibre-gl-dev.mjs +522 -223
  2. package/dist/maplibre-gl-dev.mjs.map +1 -1
  3. package/dist/maplibre-gl-shared-dev.mjs +103 -58
  4. package/dist/maplibre-gl-shared-dev.mjs.map +1 -1
  5. package/dist/maplibre-gl-shared.mjs +2 -2
  6. package/dist/maplibre-gl-shared.mjs.map +1 -1
  7. package/dist/maplibre-gl-worker-dev.mjs +23 -49
  8. package/dist/maplibre-gl-worker-dev.mjs.map +1 -1
  9. package/dist/maplibre-gl-worker.mjs +2 -2
  10. package/dist/maplibre-gl-worker.mjs.map +1 -1
  11. package/dist/maplibre-gl.css +1 -1
  12. package/dist/maplibre-gl.d.ts +214 -59
  13. package/dist/maplibre-gl.mjs +44 -44
  14. package/dist/maplibre-gl.mjs.map +1 -1
  15. package/package.json +10 -20
  16. package/src/data/feature_index.bench.ts +21 -0
  17. package/src/data/segment.test.ts +2 -2
  18. package/src/geo/edge_insets.test.ts +1 -1
  19. package/src/geo/lng_lat.test.ts +7 -7
  20. package/src/geo/lng_lat_bounds.test.ts +4 -4
  21. package/src/geo/mercator_coordinate.test.ts +2 -2
  22. package/src/geo/projection/camera_helper.ts +5 -0
  23. package/src/geo/projection/globe_transform.test.ts +25 -0
  24. package/src/geo/projection/globe_transform.ts +7 -3
  25. package/src/geo/projection/mercator_camera_helper.ts +1 -1
  26. package/src/geo/projection/mercator_transform.ts +21 -5
  27. package/src/geo/projection/vertical_perspective_camera_helper.ts +60 -31
  28. package/src/geo/projection/vertical_perspective_transform.ts +7 -1
  29. package/src/geo/transform_interface.ts +13 -1
  30. package/src/index.ts +7 -2
  31. package/src/render/image_atlas.test.ts +72 -0
  32. package/src/render/image_atlas.ts +17 -2
  33. package/src/render/image_manager.test.ts +46 -0
  34. package/src/render/image_manager.ts +9 -2
  35. package/src/render/painter.ts +1 -12
  36. package/src/render/update_pattern_positions_in_program.test.ts +1 -1
  37. package/src/shaders/glsl/_prelude.vertex.glsl +2 -3
  38. package/src/shaders/glsl/_prelude.vertex.glsl.g.ts +1 -1
  39. package/src/shaders/glsl/circle.vertex.glsl +4 -4
  40. package/src/shaders/glsl/circle.vertex.glsl.g.ts +1 -1
  41. package/src/shaders/glsl/fill_extrusion.vertex.glsl +3 -3
  42. package/src/shaders/glsl/fill_extrusion.vertex.glsl.g.ts +1 -1
  43. package/src/shaders/glsl/fill_extrusion_pattern.vertex.glsl +5 -5
  44. package/src/shaders/glsl/fill_extrusion_pattern.vertex.glsl.g.ts +1 -1
  45. package/src/shaders/glsl/heatmap.vertex.glsl +4 -4
  46. package/src/shaders/glsl/heatmap.vertex.glsl.g.ts +1 -1
  47. package/src/shaders/glsl/line.vertex.glsl +7 -7
  48. package/src/shaders/glsl/line.vertex.glsl.g.ts +1 -1
  49. package/src/shaders/glsl/line_gradient.vertex.glsl +6 -6
  50. package/src/shaders/glsl/line_gradient.vertex.glsl.g.ts +1 -1
  51. package/src/shaders/glsl/line_gradient_sdf.vertex.glsl +7 -7
  52. package/src/shaders/glsl/line_gradient_sdf.vertex.glsl.g.ts +1 -1
  53. package/src/shaders/glsl/line_pattern.vertex.glsl +7 -7
  54. package/src/shaders/glsl/line_pattern.vertex.glsl.g.ts +1 -1
  55. package/src/shaders/glsl/line_sdf.vertex.glsl +7 -7
  56. package/src/shaders/glsl/line_sdf.vertex.glsl.g.ts +1 -1
  57. package/src/shaders/glsl/raster.fragment.glsl +4 -4
  58. package/src/shaders/glsl/raster.fragment.glsl.g.ts +1 -1
  59. package/src/shaders/glsl/raster.vertex.glsl +11 -6
  60. package/src/shaders/glsl/raster.vertex.glsl.g.ts +1 -1
  61. package/src/shaders/glsl/symbol_icon.vertex.glsl +5 -5
  62. package/src/shaders/glsl/symbol_icon.vertex.glsl.g.ts +1 -1
  63. package/src/shaders/glsl/symbol_sdf.vertex.glsl +5 -5
  64. package/src/shaders/glsl/symbol_sdf.vertex.glsl.g.ts +1 -1
  65. package/src/shaders/glsl/symbol_text_and_icon.vertex.glsl +6 -6
  66. package/src/shaders/glsl/symbol_text_and_icon.vertex.glsl.g.ts +1 -1
  67. package/src/source/canvas_source.test.ts +31 -0
  68. package/src/source/canvas_source.ts +2 -1
  69. package/src/source/geojson_worker_source.test.ts +88 -0
  70. package/src/source/geojson_worker_source.ts +22 -39
  71. package/src/source/image_source.test.ts +205 -7
  72. package/src/source/image_source.ts +118 -4
  73. package/src/source/raster_dem_tile_worker_source.test.ts +1 -1
  74. package/src/source/vector_tile_worker_source.test.ts +94 -2
  75. package/src/source/vector_tile_worker_source.ts +18 -27
  76. package/src/source/video_source.test.ts +12 -8
  77. package/src/source/worker_tile.bench.ts +10 -0
  78. package/src/source/worker_tile.ts +0 -3
  79. package/src/style/create_style_layer.bench.ts +15 -0
  80. package/src/style/properties.bench.ts +81 -0
  81. package/src/style/style.test.ts +11 -10
  82. package/src/style/style_image.ts +67 -9
  83. package/src/style/style_layer.bench.ts +65 -0
  84. package/src/style/style_layer.test.ts +1 -1
  85. package/src/style/style_layer.ts +2 -2
  86. package/src/style/validate_style.bench.ts +11 -0
  87. package/src/style/validate_style.test.ts +2 -2
  88. package/src/symbol/anchor.test.ts +2 -2
  89. package/src/symbol/collision_index.bench.ts +116 -0
  90. package/src/symbol/cross_tile_symbol_index.bench.ts +49 -0
  91. package/src/symbol/shaping.test.ts +2 -1
  92. package/src/symbol/symbol_layout.bench.ts +30 -0
  93. package/src/tile/tile_id.test.ts +1 -1
  94. package/src/tile/tile_manager.ts +2 -2
  95. package/src/ui/control/fullscreen_control.test.ts +10 -10
  96. package/src/ui/control/geolocate_control.test.ts +3 -5
  97. package/src/ui/control/globe_control.test.ts +6 -6
  98. package/src/ui/events.ts +1 -1
  99. package/src/ui/handler/scroll_zoom.test.ts +50 -0
  100. package/src/ui/handler/two_fingers_touch.test.ts +3 -3
  101. package/src/ui/handler_manager.test.ts +243 -3
  102. package/src/ui/handler_manager.ts +79 -16
  103. package/src/ui/map.ts +17 -3
  104. package/src/ui/map_tests/map_cross_window.test.ts +2 -2
  105. package/src/ui/map_tests/map_events.test.ts +3 -3
  106. package/src/ui/map_tests/map_images.test.ts +29 -0
  107. package/src/ui/map_tests/map_style.test.ts +9 -8
  108. package/src/ui/map_tests/map_webgl.test.ts +29 -0
  109. package/src/ui/marker.test.ts +26 -42
  110. package/src/ui/popup.test.ts +14 -14
  111. package/src/util/evented.test.ts +33 -28
  112. package/src/util/evented.ts +69 -43
  113. package/src/util/test/null_gl.ts +10 -0
  114. package/src/util/test/util.ts +2 -1
  115. package/src/util/util.test.ts +1 -1
  116. package/src/util/web_worker_transfer.test.ts +5 -5
  117. package/src/webgl/context.ts +20 -0
  118. package/src/webgl/draw/draw_raster.ts +11 -6
  119. package/src/webgl/program/raster_program.ts +11 -0
  120. package/src/webgl/program.ts +31 -16
  121. package/src/webgl/texture.test.ts +16 -1
  122. package/src/webgl/texture.ts +3 -0
  123. package/src/webgl/vertex_buffer.test.ts +17 -2
  124. package/src/webgl/vertex_buffer.ts +24 -13
@@ -30,13 +30,34 @@ function getTokenizedAttributesAndUniforms(array: string[]): string[] {
30
30
  return result;
31
31
  }
32
32
 
33
+ function getIntegerAttributeNames(gl: WebGL2RenderingContext, program: WebGLProgram): Set<string> {
34
+ const integerTypes = new Set<number>([
35
+ gl.INT, gl.INT_VEC2, gl.INT_VEC3, gl.INT_VEC4,
36
+ gl.UNSIGNED_INT, gl.UNSIGNED_INT_VEC2, gl.UNSIGNED_INT_VEC3, gl.UNSIGNED_INT_VEC4
37
+ ]);
38
+ const names = new Set<string>();
39
+ const numActiveAttributes = gl.getProgramParameter(program, gl.ACTIVE_ATTRIBUTES);
40
+ for (let i = 0; i < numActiveAttributes; i++) {
41
+ const attribute = gl.getActiveAttrib(program, i);
42
+ if (attribute && integerTypes.has(attribute.type)) {
43
+ names.add(attribute.name);
44
+ }
45
+ }
46
+ return names;
47
+ }
48
+
49
+ export type ProgramAttribute = {
50
+ location: number;
51
+ isInteger: boolean;
52
+ };
53
+
33
54
  /**
34
55
  * @internal
35
56
  * A webgl program to execute in the GPU space
36
57
  */
37
58
  export class Program<Us extends UniformBindings> {
38
59
  program: WebGLProgram;
39
- attributes: {[_: string]: number};
60
+ attributes: {[_: string]: ProgramAttribute};
40
61
  numAttributes: number;
41
62
  fixedUniforms: Us;
42
63
  terrainUniforms: TerrainPreludeUniformsType;
@@ -123,27 +144,21 @@ export class Program<Us extends UniformBindings> {
123
144
 
124
145
  this.numAttributes = allAttrInfo.length;
125
146
 
126
- for (let i = 0; i < this.numAttributes; i++) {
127
- if (allAttrInfo[i]) {
128
- this.attributes[allAttrInfo[i]] = i;
129
- }
130
- }
131
-
132
147
  gl.linkProgram(this.program);
133
148
 
134
- for (const name in this.attributes) {
135
- const actual = gl.getAttribLocation(this.program, name);
136
- if (actual >= 0) {
137
- this.attributes[name] = actual;
138
- } else {
139
- delete this.attributes[name];
140
- }
141
- }
142
-
143
149
  if (!gl.getProgramParameter(this.program, gl.LINK_STATUS)) {
144
150
  throw new Error(`Program failed to link: ${gl.getProgramInfoLog(this.program)}`);
145
151
  }
146
152
 
153
+ const integerAttributeNames = getIntegerAttributeNames(gl, this.program);
154
+ for (const name of allAttrInfo) {
155
+ if (!name) continue;
156
+ const location = gl.getAttribLocation(this.program, name);
157
+ if (location >= 0) {
158
+ this.attributes[name] = {location, isInteger: integerAttributeNames.has(name)};
159
+ }
160
+ }
161
+
147
162
  gl.deleteShader(vertexShader);
148
163
  gl.deleteShader(fragmentShader);
149
164
 
@@ -1,4 +1,4 @@
1
- import {describe, expect, test} from 'vitest';
1
+ import {describe, expect, test, vi} from 'vitest';
2
2
  import {Context} from './context.ts';
3
3
  import {Texture} from './texture.ts';
4
4
  import {premultiplyAlpha, RGBAImage} from '../util/image.ts';
@@ -68,6 +68,21 @@ describe('Texture', () => {
68
68
  expect(gl.deleteTexture).toHaveBeenCalled();
69
69
  });
70
70
 
71
+ test('resizing re-applies filter and wrap to the new handle', () => {
72
+ const gl = createNullGL();
73
+ const context = new Context(gl);
74
+ const texture = new Texture(context, new RGBAImage({width: 2, height: 2}, new Uint8Array(2 * 2 * 4)), gl.RGBA);
75
+ texture.bind(gl.LINEAR, gl.CLAMP_TO_EDGE);
76
+
77
+ texture.update(new RGBAImage({width: 4, height: 4}, new Uint8Array(4 * 4 * 4)));
78
+ vi.mocked(gl.texParameteri).mockClear();
79
+ texture.bind(gl.LINEAR, gl.CLAMP_TO_EDGE);
80
+
81
+ // Same values as before, but on a new handle, so both have to be written again.
82
+ expect(gl.texParameteri).toHaveBeenCalledWith(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
83
+ expect(gl.texParameteri).toHaveBeenCalledWith(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
84
+ });
85
+
71
86
  test('premultiplyAlpha produces correct output', () => {
72
87
  // pixel: r=200, g=100, b=50, a=128 (half transparent)
73
88
  const data = new Uint8Array([200, 100, 50, 128]);
@@ -64,6 +64,9 @@ export class Texture {
64
64
  gl.deleteTexture(this.texture);
65
65
  this.texture = gl.createTexture();
66
66
  this._ownedHandle = this.texture;
67
+ // A fresh handle is back on GL's defaults, so bind() has to re-apply these.
68
+ this.filter = undefined;
69
+ this.wrap = undefined;
67
70
  }
68
71
 
69
72
  gl.bindTexture(gl.TEXTURE_2D, this.texture);
@@ -40,7 +40,7 @@ describe('VertexBuffer', () => {
40
40
  const array = new TestArray();
41
41
  const buffer = new VertexBuffer(context, array, attributes);
42
42
  const spy = vi.spyOn(context.gl, 'enableVertexAttribArray').mockImplementation(() => {});
43
- buffer.enableAttributes(context.gl, {attributes: {map: 5, box: 6}} as any);
43
+ buffer.enableAttributes(context.gl, {attributes: {map: {location: 5, isInteger: false}, box: {location: 6, isInteger: false}}} as any);
44
44
  expect(spy.mock.calls).toEqual([[5], [6]]);
45
45
  });
46
46
 
@@ -49,13 +49,28 @@ describe('VertexBuffer', () => {
49
49
  const array = new TestArray();
50
50
  const buffer = new VertexBuffer(context, array, attributes);
51
51
  const spy = vi.spyOn(context.gl, 'vertexAttribPointer').mockImplementation(() => {});
52
- buffer.setVertexAttribPointers(context.gl, {attributes: {map: 5, box: 6}} as any, 50);
52
+ buffer.setVertexAttribPointers(context.gl, {attributes: {map: {location: 5, isInteger: false}, box: {location: 6, isInteger: false}}} as any, 50);
53
53
  expect(spy.mock.calls).toEqual([
54
54
  [5, 1, context.gl['SHORT'], false, 6, 300],
55
55
  [6, 2, context.gl['SHORT'], false, 6, 304]
56
56
  ]);
57
57
  });
58
58
 
59
+ test('setVertexAttribPointers uses vertexAttribIPointer for integer attributes', () => {
60
+ const context = new Context(gl);
61
+ const array = new TestArray();
62
+ const buffer = new VertexBuffer(context, array, attributes);
63
+ const integerSpy = vi.spyOn(context.gl, 'vertexAttribIPointer').mockImplementation(() => {});
64
+ const floatSpy = vi.spyOn(context.gl, 'vertexAttribPointer').mockImplementation(() => {});
65
+ buffer.setVertexAttribPointers(context.gl, {attributes: {map: {location: 5, isInteger: false}, box: {location: 6, isInteger: true}}} as any, 50);
66
+ expect(integerSpy.mock.calls).toEqual([
67
+ [6, 2, context.gl['SHORT'], 6, 304]
68
+ ]);
69
+ expect(floatSpy.mock.calls).toEqual([
70
+ [5, 1, context.gl['SHORT'], false, 6, 300]
71
+ ]);
72
+ });
73
+
59
74
  test('static buffer frees StructArray typed views after upload', () => {
60
75
  const context = new Context(gl);
61
76
  const array = new TestArray();
@@ -66,9 +66,9 @@ export class VertexBuffer {
66
66
 
67
67
  enableAttributes(gl: WebGL2RenderingContext, program: Program<any>): void {
68
68
  for (const member of this.attributes) {
69
- const attribIndex: number | void = program.attributes[member.name];
70
- if (attribIndex !== undefined) {
71
- gl.enableVertexAttribArray(attribIndex);
69
+ const attribute = program.attributes[member.name];
70
+ if (attribute !== undefined) {
71
+ gl.enableVertexAttribArray(attribute.location);
72
72
  }
73
73
  }
74
74
  }
@@ -81,17 +81,28 @@ export class VertexBuffer {
81
81
  */
82
82
  setVertexAttribPointers(gl: WebGL2RenderingContext, program: Program<any>, vertexOffset?: number | null): void {
83
83
  for (const member of this.attributes) {
84
- const attribIndex: number | void = program.attributes[member.name];
84
+ const attribute = program.attributes[member.name];
85
85
 
86
- if (attribIndex !== undefined) {
87
- gl.vertexAttribPointer(
88
- attribIndex,
89
- member.components,
90
- gl[AttributeType[member.type]],
91
- false,
92
- this.itemSize,
93
- member.offset + (this.itemSize * (vertexOffset || 0))
94
- );
86
+ if (attribute !== undefined) {
87
+ const offset = member.offset + (this.itemSize * (vertexOffset || 0));
88
+ if (attribute.isInteger) {
89
+ gl.vertexAttribIPointer(
90
+ attribute.location,
91
+ member.components,
92
+ gl[AttributeType[member.type]],
93
+ this.itemSize,
94
+ offset
95
+ );
96
+ } else {
97
+ gl.vertexAttribPointer(
98
+ attribute.location,
99
+ member.components,
100
+ gl[AttributeType[member.type]],
101
+ false,
102
+ this.itemSize,
103
+ offset
104
+ );
105
+ }
95
106
  }
96
107
  }
97
108
  }