maplibre / maplibre-gl-js

MapLibre GL JS - Interactive vector tile maps in the browser
https://maplibre.org/maplibre-gl-js/docs/
Other
6.75k stars 727 forks source link

[Bug] With hardware acceleration set to false weird behaviour with initial paint for layers #4647

Open ToHold opened 2 months ago

ToHold commented 2 months ago

maplibre-gl-js version: 4.5.0

browser: Chromium 128.0.6613.84

Steps to Trigger Behavior

  1. Disable hardware acceleration
  2. Use style with a fill extrusion layer
  3. Add a layer without paint before this one
  4. Set second layer paint with map.getLayer('layer').setPaintProperty()

Link to Demonstration

https://codepen.io/ToHold/pen/abgRaye

Expected Behavior

This should work like with hardware acceleration on

Actual Behavior

Layer are weirdly overlapping each other. In on of my project with threejs, I can see other app windows behind my browser (like vscode).

HarelM commented 2 months ago

Thanks for taking the time to report this issue. I'm not sure the assumptions that this should work without hardware acceleration is a valid assumption. Maplibre uses webgl and the GPU heavily...

neodescis commented 2 months ago

We have users running MapLibre without hardware acceleration. It's actually pretty decent if you don't have terrain turned on.

That said, the codepen above has layers overlapping in weird ways for me even with acceleration turned on. The behavior is the same for me with acceleration turned off, aside from being very slow.

ToHold commented 2 months ago

Yes my bad with hardware acceleration, it also happen, should I rename the issue ?

HarelM commented 2 months ago

I believe the correct way to do it would be to use the map API and not the layer API:

map.setPaintProperty('rectangle-layer', 'fill-color', [
    'get',
    'fill-color'
  ]);

  map.setPaintProperty('rectangle-layer', 'fill-opacity', [
    'get',
    'fill-opacity'
  ]);

The return type of getLayer is StyleLayer and I don't think it support this method. See here: https://maplibre.org/maplibre-gl-js/docs/API/classes/StyleLayer/

I would strongly advise to use typescript in order to avoid these kind of issues...

ToHold commented 2 months ago

Well I use Typescript, why not prefix it by underscored then ? Maybe @internal tag would be interesting too.

ToHold commented 2 months ago

And yes I also have users without hardware acceleration that's why I encounter some bugs, yes this one isnt related to hardware acceleration but I can't easly reproduce it in a codepen.

ToHold commented 2 months ago

I believe the correct way to do it would be to use the map API and not the layer API:

map.setPaintProperty('rectangle-layer', 'fill-color', [
    'get',
    'fill-color'
  ]);

  map.setPaintProperty('rectangle-layer', 'fill-opacity', [
    'get',
    'fill-opacity'
  ]);

The return type of getLayer is StyleLayer and I don't think it support this method. See here: https://maplibre.org/maplibre-gl-js/docs/API/classes/StyleLayer/

I would strongly advise to use typescript in order to avoid these kind of issues...

Well I'll give a try this way, thank you

HarelM commented 2 months ago

I've looked at the code, and it is similar but not identical. I'm not sure setting it to "internal" will actually solve the issue since you'll still be able to call this method. Here's the relevant code inside style object: https://github.com/maplibre/maplibre-gl-js/blob/956485c2cc7868184af08ca2a84e4565e6ae7258/src/style/style.ts#L1178-L1198