Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

use webgl2 when available #1891

Merged
merged 5 commits into from May 12, 2023
Merged

use webgl2 when available #1891

merged 5 commits into from May 12, 2023

Conversation

rotu
Copy link
Contributor

@rotu rotu commented Nov 30, 2022

Use WebGL2 rendering context when available.

Launch Checklist

  • Confirm your changes do not include backports from Mapbox projects (unless with compliant license) - if you are not sure about this, please ask!
  • Briefly describe the changes in this PR.
  • Link to related issues.
  • Include before/after visuals or gifs if this PR includes visual changes.
  • Write tests for all new functionality.
  • Document any changes to public APIs.
  • Post benchmark scores.
  • Manually test the debug page.
  • Add an entry to CHANGELOG.md under the ## main section.

@rotu rotu marked this pull request as ready for review November 30, 2022 06:26
@rotu rotu marked this pull request as draft November 30, 2022 06:26
@github-actions
Copy link
Contributor

github-actions bot commented Nov 30, 2022

Bundle size report:

Size Change: -411 B
Total Size Before: 207 kB
Total Size After: 207 kB

Output file Before After Change
maplibre-gl.js 198 kB 198 kB -411 B
maplibre-gl.css 9.1 kB 9.1 kB 0 B
ℹ️ View Details
Source file Before After Change
src/gl/webgl2.ts 0 B 88 B +88 B
src/gl/context.ts 1.28 kB 1.34 kB +60 B
src/gl/value.ts 1.09 kB 1.13 kB +39 B
src/render/draw_heatmap.ts 1.04 kB 1.06 kB +27 B
src/style-spec/util/deep_equal.ts 194 B 211 B +17 B
src/render/draw_raster.ts 1.04 kB 1.06 kB +12 B
src/shaders/shaders.ts 1.49 kB 1.49 kB +7 B
node_modules/gl-matrix/esm/vec3.js 810 B 816 B +6 B
src/render/program/circle_program.ts 454 B 459 B +5 B
src/render/draw_symbol.ts 2.6 kB 2.6 kB +5 B
src/render/program/terrain_program.ts 702 B 706 B +4 B
node_modules/gl-matrix/esm/mat3.js 221 B 225 B +4 B
src/render/program/heatmap_program.ts 557 B 561 B +4 B
src/render/program/line_program.ts 1.15 kB 1.16 kB +4 B
src/render/program/raster_program.ts 559 B 563 B +4 B
src/render/draw_line.ts 1.04 kB 1.05 kB +4 B
src/render/draw_custom.ts 338 B 342 B +4 B
src/ui/handler/handler_util.ts 174 B 178 B +4 B
src/shaders/terrain.vertex.glsl.g.ts 218 B 221 B +3 B
src/shaders/fill_extrusion.vertex.glsl.g.ts 620 B 623 B +3 B
src/gl/depth_mode.ts 133 B 136 B +3 B
src/ui/handler/map_event.ts 443 B 446 B +3 B
node_modules/gl-matrix/esm/vec2.js 255 B 257 B +2 B
node_modules/@mapbox/tiny-sdf/index.js 1.1 kB 1.11 kB +2 B
src/source/raster_dem_tile_source.ts 968 B 970 B +2 B
src/shaders/heatmap_texture.fragment.glsl.g.ts 205 B 207 B +2 B
src/shaders/collision_box.fragment.glsl.g.ts 146 B 148 B +2 B
src/shaders/fill_pattern.vertex.glsl.g.ts 387 B 389 B +2 B
src/shaders/line_pattern.fragment.glsl.g.ts 705 B 707 B +2 B
src/render/draw_fill_extrusion.ts 788 B 790 B +2 B
src/ui/handler/touch_pan.ts 539 B 541 B +2 B
src/data/pos3d_attributes.ts 86 B 88 B +2 B
src/source/tile_bounds.ts 316 B 317 B +1 B
src/source/raster_tile_source.ts 910 B 911 B +1 B
src/source/image_source.ts 1.14 kB 1.14 kB +1 B
src/source/query_features.ts 1.21 kB 1.21 kB +1 B
src/source/tile.ts 1.97 kB 1.97 kB +1 B
src/symbol/path_interpolator.ts 310 B 311 B +1 B
src/source/pixels_to_tile_units.ts 103 B 104 B +1 B
src/symbol/placement.ts 5.08 kB 5.08 kB +1 B
src/symbol/cross_tile_symbol_index.ts 1.37 kB 1.37 kB +1 B
src/shaders/line_sdf.fragment.glsl.g.ts 459 B 460 B +1 B
src/render/program/background_program.ts 472 B 473 B +1 B
src/render/draw_collision_debug.ts 1.14 kB 1.14 kB +1 B
src/render/draw_background.ts 578 B 579 B +1 B
src/geo/edge_insets.ts 430 B 431 B +1 B
node_modules/gl-matrix/esm/mat2.js 229 B 230 B +1 B
src/ui/hash.ts 937 B 938 B +1 B
src/util/throttle.ts 144 B 145 B +1 B
src/ui/handler/drag_move_state_manager.ts 337 B 338 B +1 B
src/ui/handler/scroll_zoom.ts 1.28 kB 1.28 kB +1 B
src/ui/handler/tap_drag_zoom.ts 481 B 482 B +1 B
src/util/debug.ts 160 B 161 B +1 B
src/ui/control/attribution_control.ts 1.08 kB 1.08 kB +1 B
src/ui/control/logo_control.ts 485 B 486 B +1 B
src/gl/render_pool.ts 583 B 584 B +1 B
src/render/render_to_texture.ts 1 kB 1 kB +1 B
src/ui/control/geolocate_control.ts 2.24 kB 2.24 kB +1 B
src/ui/control/scale_control.ts 733 B 734 B +1 B
src/ui/control/fullscreen_control.ts 782 B 783 B +1 B
src/style/style_image.ts 126 B 125 B -1 B
src/source/video_source.ts 875 B 874 B -1 B
src/source/tile_cache.ts 556 B 555 B -1 B
src/style-spec/empty.ts 156 B 155 B -1 B
src/shaders/_prelude.fragment.glsl.g.ts 121 B 120 B -1 B
src/shaders/collision_box.vertex.glsl.g.ts 316 B 315 B -1 B
src/gl/index_buffer.ts 348 B 347 B -1 B
src/gl/vertex_buffer.ts 610 B 609 B -1 B
src/render/draw_circle.ts 622 B 621 B -1 B
src/geo/transform.ts 4.49 kB 4.49 kB -1 B
src/ui/events.ts 357 B 356 B -1 B
src/ui/handler/two_fingers_touch.ts 1.03 kB 1.03 kB -1 B
src/ui/handler/keyboard.ts 572 B 571 B -1 B
src/ui/handler/shim/drag_pan.ts 215 B 214 B -1 B
src/ui/handler/shim/drag_rotate.ts 179 B 178 B -1 B
src/ui/handler/shim/two_fingers_touch.ts 281 B 280 B -1 B
src/util/task_queue.ts 315 B 314 B -1 B
src/util/dispatcher.ts 359 B 357 B -2 B
src/util/offscreen_canvas_supported.ts 156 B 154 B -2 B
src/style/style.ts 7.37 kB 7.37 kB -2 B
src/shaders/heatmap.vertex.glsl.g.ts 368 B 366 B -2 B
src/shaders/heatmap_texture.vertex.glsl.g.ts 145 B 143 B -2 B
src/shaders/fill_pattern.fragment.glsl.g.ts 396 B 394 B -2 B
src/shaders/fill_extrusion.fragment.glsl.g.ts 119 B 117 B -2 B
src/shaders/line_pattern.vertex.glsl.g.ts 789 B 787 B -2 B
src/shaders/line_sdf.vertex.glsl.g.ts 809 B 807 B -2 B
src/shaders/terrain_coords.fragment.glsl.g.ts 170 B 168 B -2 B
src/render/program/symbol_program.ts 1.29 kB 1.29 kB -2 B
src/ui/handler/drag_handler.ts 496 B 494 B -2 B
src/ui/handler_manager.ts 2.64 kB 2.64 kB -2 B
src/ui/default_locale.ts 313 B 311 B -2 B
src/render/terrain.ts 2.22 kB 2.22 kB -2 B
src/ui/handler/one_finger_touch_drag.ts 416 B 414 B -2 B
src/source/source.ts 355 B 352 B -3 B
src/symbol/projection.ts 1.82 kB 1.82 kB -3 B
src/render/program/debug_program.ts 195 B 192 B -3 B
src/gl/stencil_mode.ts 154 B 151 B -3 B
src/ui/handler/mouse.ts 524 B 521 B -3 B
src/ui/camera.ts 3.41 kB 3.4 kB -3 B
src/ui/control/navigation_control.ts 1.82 kB 1.81 kB -3 B
src/util/global_worker_pool.ts 332 B 328 B -4 B
src/data/pos_attributes.ts 85 B 81 B -4 B
src/render/program/collision_program.ts 721 B 717 B -4 B
src/render/program/program_uniforms.ts 958 B 954 B -4 B
src/render/draw_hillshade.ts 1.16 kB 1.16 kB -4 B
src/ui/handler/tap_recognizer.ts 535 B 530 B -5 B
src/render/draw_terrain.ts 1.75 kB 1.74 kB -6 B
src/util/primitives.ts 1.01 kB 1 kB -8 B
src/render/program/fill_program.ts 575 B 562 B -13 B
src/render/draw_debug.ts 1.37 kB 1.36 kB -13 B
node_modules/@mapbox/mapbox-gl-supported/index.js 938 B 922 B -16 B
src/render/vertex_array_object.ts 580 B 526 B -54 B
src/ui/map.ts 7.23 kB 6.98 kB -245 B
src/render/painter.ts 3.75 kB 3.49 kB -268 B

@rotu rotu force-pushed the webgl2 branch 2 times, most recently from 3dc59b1 to b8caa7a Compare November 30, 2022 19:47
@JannikGM
Copy link
Contributor

JannikGM commented Dec 1, 2022

What's the benefit of this, until we actually use WebGL2 features?

@rotu
Copy link
Contributor Author

rotu commented Dec 1, 2022

@JannikGM The reason this came up is that I'm using a custom 3D layer and some shader features that were working in plain threejs (which defaults to webgl2) were failing in my MapLibre layer and vice versa.

CHANGELOG.md Outdated Show resolved Hide resolved
src/ui/map.ts Show resolved Hide resolved
@dangerden
Copy link

I would also suggest using WebGL2 by default. It might be needed for VAOs available in WebGL2 only and easy state switching between several custom layers.

@JannikGM
Copy link
Contributor

JannikGM commented Dec 5, 2022

I'd assume that any WebGL2 capable browser would also expose OES_vertex_array_object on WebGL. maplibre is also already using that:

this.extVertexArrayObject = this.gl.getExtension('OES_vertex_array_object');

If extensions want to use VAOs, they should probably also support WebGL with that extension for wider compatibility.

Edit:
To be clear; I'd still also advocate for WebGL2 context if available. Did someone check if common add-ons like deck.gl still work with WebGL2?

@rotu
Copy link
Contributor Author

rotu commented Dec 10, 2022

@JannikGM Could you give this a quick look? How do I tell whether users of the WebGL timing functions are getting the right results?
Also, does the heatmap debug page actually work? I'm getting "Cannot add layer "heatmap" before non-existing layer "waterway-label"."

@klokan
Copy link
Member

klokan commented Dec 10, 2022

Would be amazing to take this into v3 release. People from DeckGL wanted to switch to WebGL2 as well - FYI @HarelM

@klokan klokan added this to the 3.0.0 milestone Dec 10, 2022
@HarelM
Copy link
Member

HarelM commented Dec 10, 2022

@klokan I'm watching this PR closely, but a) it's still in draft b) it incorporates a lot of small fixes that should not be part of this PR.
but since it's still in draft I prefer not to start a review and allow the person who opened the PR to let us know when it's ready for review. 😀

@rotu rotu force-pushed the webgl2 branch 4 times, most recently from 9321800 to 4ccbab6 Compare December 11, 2022 16:56
@HarelM
Copy link
Member

HarelM commented Dec 11, 2022

Please make sure to add the relevant unit tests to the added functionality.

src/gl/timing.ts Outdated Show resolved Hide resolved
@rotu
Copy link
Contributor Author

rotu commented Dec 12, 2022

Please make sure to add the relevant unit tests to the added functionality.

I'm not intending to add any functionality in this PR. I only want to make sure existing functionality continues to work with both WebGL1 and WebGL2. Could you help me out with the testing? I can't figure out how to make the unit tests run on different browser engines. Even the dev dependency gl is DOA on my machine: stackgl/headless-gl#243

@HarelM
Copy link
Member

HarelM commented Dec 13, 2022

There are changes in context.ts and timing.ts and some changing in other files, these changes need to be covered in tests. This is a functionality that was added.

@rotu
Copy link
Contributor Author

rotu commented Dec 13, 2022

Can you help me write a test to check that the Context.timing function returns something when Context is constructed against a canvas that supports WebGL2? I’m struggling greatly with the testing infrastructure in this repo. I’m happy to flesh out test coverage once I get over that hump.

@HarelM
Copy link
Member

HarelM commented Dec 13, 2022

Check out the info here:
https://github.com/maplibre/maplibre-gl-js/tree/main/test#writing-unit-tests
Basically, you should create a test file that matches the file you changed and use jest to create a unit test around the logic you changed/added.
There are a lot of unit tests in this project, and you can easily get inspiration from them.
It's less about getting the actual webgl2 functionality, although this is important too.
You can test the webgl2 in the integration tests (test like browser tests I guess) and not in the unit tests.
I would focus on adding unit tests to the added functionality and think of a way to test the webgl2 added code, I'm not sure how to do that, maybe the render test can do that.
In any case, this repo is filled with docs on how to write and run the tests.
If the docs are not clear, feel free to submit a PR to improve the docs.

@rotu
Copy link
Contributor Author

rotu commented Dec 13, 2022

@HarelM Every single unit test around Context requires using the headless-gl library, which is DoA on MacOS, doesn't support WebGL2, and doesn't even mock anything. I don't want to write these tests until I feel confident this works with an actual webgl2 instance.

That Timing class is only to facilitate the timing queries in Map._render and Painter.gpuTimingStart. What existing tests exist around this? How do I check that the timing features work today and continue working after this PR?

@HarelM
Copy link
Member

HarelM commented Dec 14, 2022

Unfortunately, I don't know the answer of which tests exists to cover the classes you changed.
In terms of how you test the functionality you added - the answer is always the same - you know what you changed, and you should know how to test it - even if you know how to manually test it, that a good start, and we can think how to automate it.
If you need guidance in order to use some testing infra or you need to create new kind of tests, feel free to ask. :-)

@HarelM
Copy link
Member

HarelM commented Apr 9, 2023

@rotu where are we on this PR? What's missing in order to merge this?

@birkskyum
Copy link
Member

birkskyum commented Apr 17, 2023

I've been exploring moving our tests to WebGL2, which requires us to swap JSDOM and all the browser mocking with a headless browser like puppeteer or playwright, because there is no maintained node implementations of WebGL2 we can use.

For the longest time WebGL2 wasn't widely supported, due to lacking safari support, but it's finally getting there. Currently webgl2's support is ~93.96%, but growing as iPhones get updated - for reference await is at 95.07%, which we don't compile away with the current config, so we're not currently at 100% anyway.

What I wonder is, could we simply move to webgl2 entirely (similar to how MapLibre Native recently moved to OpenGL ES 3) as the support becomes sufficient, and thus save all this conditional logic and all the gl1/gl2 checks? Would there be any downsides to that?

@HarelM
Copy link
Member

HarelM commented Apr 18, 2023

The downside would be the support of old devices and old browsers.
Of course, one could use an old version of maplibre to support old browsers, but this is the same as what we did with the removal of the support of IE. I'm not saying we shouldn't, we just need to make sure that do that with proper communication.
I would advise to try and concentrate the logic around webgl 1 in a single file as much as possible so that removing support for it would be mainly remove that file.

@birkskyum
Copy link
Member

birkskyum commented Apr 18, 2023

@HarelM it's a good point to try to keep the logic of each graphics backend isolated, also with webgpu on the horizon, somewhat similar to the modularization effort on Native. I'd love to see some benchmarks of this PR, as that would be the main selling point of introducing webgl 2. As long as we stay compatible with webgl 1, we might not be able to opt in tomany of the optimizations from webgl 2, so I wonder what the results would be. Here is the PR from MapLibre Native that has most of the webgl 2 shader changes: https://github.com/maplibre/maplibre-gl-native/pull/995/files#diff-524519fde8010b2a448977ac84de5feefa300da4983495a0a2bbdc30a62d2bd8

@birkskyum
Copy link
Member

If almost everybody has webgl2 and this opts for that when available, I'm concerned about merging this before having the ability to test webgl2.

@birkskyum
Copy link
Member

The changes to map.ts has to be resolved for this to proceed. @rotu , would it be possible for you to have a look at the merge conflict? We are getting closer to having some webgl2 tests in place, but I can't tests it against this PR due to the conflicts in map.ts.

@birkskyum
Copy link
Member

@rotu, the render test suite is now webgl2 compatible. Also the github test workflows has been refactored so it's broken into separate workflows so it's easier to dive into. It does require rebasing these changes to main though.

@birkskyum
Copy link
Member

I wonder what happened with the fadeDuration since this suddenly can't build. There is also #2501 which might be related. @zhangyiatmicrosoft do you know what's been changing around this?

@birkskyum
Copy link
Member

@pramilk , I think the #2447 did something here - can you give us some pointers on how to update the code so fadeDuration can be found again in the build step?

@birkskyum
Copy link
Member

Here are benchmarks, using webgl2.
Screenshot 2023-05-12 at 00 14 40

@birkskyum birkskyum requested a review from HarelM May 11, 2023 22:39
Copy link
Member

@HarelM HarelM left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall approved, Thanks for all the hard work.
I left a very small comment about a variable that I'm not sure is being used.
If it is being used feel free to merge, if not, please remove it and merge.

@JannikGM
Copy link
Contributor

I can't unresolve conversations, so I'm linking for exposure:

Other than that, new code looks okay to me. 👍

@birkskyum
Copy link
Member

birkskyum commented May 12, 2023

I'll make a follow up PR to simplify the type narrowing / add types to the getContext(), and remove this unused emptyTexture

@birkskyum birkskyum merged commit 7a1d5b5 into maplibre:main May 12, 2023
13 checks passed
@birkskyum birkskyum mentioned this pull request May 12, 2023
8 tasks
@rotu rotu deleted the webgl2 branch June 21, 2023 03:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

7 participants