maplibre / maplibre-gl-js

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

Map sometimes renders custom images or font characters instead of basemap tiles #2811

Open gabeschine opened 1 year ago

gabeschine commented 1 year ago

We have recently seen very intermittent, odd behavior of the base map layer showing up as a set of our internal icons tiled across the map or a set of letters tiled across the map.

In one case, it appears a base map layer has partially loaded with these icons overlayed on top of it.

Here is my best attempt at a text description of the symptoms. See the video below (https://github.com/maplibre/maplibre-gl-js/issues/2811#issuecomment-2249318129) for a great example.

Helpful images / videos

Screenshot 2023-06-27 at 4 50 04 PM

And in the second, it appears to just be the set of english characters tiled.

Screenshot 2023-06-27 at 4 50 31 PM image image image image

I have caught the bug twice on a dev device, but did not catch the transition from working -> broken while attached and using developer tools. Once the map experience is broken, there are no console logs.

I am using:

maplibre-gl: 3.1.0 and react-map-gl: ^7.0.25

Originally posted by @davidemerritt in https://github.com/maplibre/maplibre-gl-js/discussions/2738

HarelM commented 1 year ago

I would start and try to reproduce this without the react wrapper. Generally speaking, if you can't create a jsbin that reproduces this it will be almost impossible to help you...

zta6 commented 1 year ago

Just commenting to note that we're seeing this also. It's occurring rarely and we don't have reproduction steps yet. But I'll post here if we figure anything out.

wipfli commented 10 months ago

I think I also saw it now:

wipfli commented 10 months ago

markup_1000031133 (1)

davidemerritt commented 5 months ago

I'm also seeing this - very similar with the font or icons being patterned across the base maps.

bulbwheatie commented 5 months ago

We're having issues with this as well. We're seeing icons, fonts and neighboring tiles being patterned. Seems to mostly happen on iOS. We're not using the React wrapper, but similarly don't have solid steps to reproduce it...

Update: We've also seen this once on Chrome

zta6 commented 5 months ago

We’re willing to pay a contractor to fix this bug for us. If you’re interested please reach out to me at zadam@caltopo.com and we can talk about the details!

davidemerritt commented 4 months ago

Adding an interesting video capture of the bug in our application:

https://github.com/user-attachments/assets/42ce41a8-b403-41b2-b611-17db9d8cd500

birkskyum commented 4 months ago

@wipfli , did you use react-map-gl here? are you able to repro it with a codepen?

gabeschine commented 4 months ago

@birkskyum - we have been working with CalTopo behind the scenes to try and diagnose this. They are not using react-map-gl. Would it be useful to see how they are handling the Map instance's lifecycle?

In my experience, this issue is triggered by some lifecycle event that happens when the page is re-focused after being in the background for some period of time (could be short, could be long - no correlation I could see).

wipfli commented 4 months ago

I was using https://onthegomap.com in Chrome on Android. @msbarry do you use react-map-gl for onthegomap?

msbarry commented 4 months ago

@msbarry do you use react-map-gl for onthegomap?

It's not react-map-gl, just a custom integration of maplibre into react, basically react just sets up a dom node and maplibre renders into that like it would be on a non-react page.

gabeschine commented 4 months ago

An interesting thing has happened the two times I have been able to attach the Safari devtools to the remote WebKit instance running on the iPhone. In both cases, I was not able to catch the transition from "working" to "broken", but I was able to poke around. What I noticed was that there are two canvases (one 2d, one 3d/webgl) that are known to the web container.

In the broken state, the 2d canvas is blank:

image

While when things are running correctly, that same canvas contains the style's sprites:

image

I have so far found where this canvas is created (browser.getImageCanvasContext()), but I cannot find where the canvas' content is purposefully cleared. I also don't know WebKit well enough to know when/why it would clear a canvas' content. I suppose it's possible that if somehow bad sprites data was downloaded, that could result in what appears to be a cleared canvas, by attempting to write said bad image data and it not working.

Just an interesting tidbit that will hopefully result in some insight from one of the maplibre contributors :).

EDIT: I just noticed after posting that the dimensions are just a little different (2048x1020 vs 2048x1014). That's odd because nothing about the style has changed in our app for a long time.

HarelM commented 4 months ago

I think there were a few iteration regarding getting an image bitmap/pixel value due to all kinds of security limitations (mainly firefox) and browsers limitations (mainly safari). The code in utils, browser, offscreen canvas is related to it, which might explain why you see this mostly in safari.

gabeschine commented 4 months ago

@wipfli is your app also a react js app?

Does the statement about when this bug is triggered for us (on app resume from suspend / background) also your experience? @wipfli @bulbwheatie @msbarry?

Interestingly, we've had a couple reports of the same event "healing" the broken state. Usually, people force-quit the app - but if you don't, it can fix itself. I've observed this as well.

gabeschine commented 3 months ago

Here are two more videos. https://github.com/user-attachments/assets/e8021a74-d917-4cbb-aea7-70711d6a4160

https://github.com/user-attachments/assets/8cd48d07-7f33-42b9-b8af-3591be23367d

bulbwheatie commented 3 months ago

A new variation reported by one of our users. IMG_9421

Also the behavior described by Gabe is consistent with what we've been seeing as well:

In my experience, this issue is triggered by some lifecycle event that happens when the page is re-focused after being in the background for some period of time (could be short, could be long - no correlation I could see).

gabeschine commented 3 months ago

Just updated the description with information about where we have seen the bug appear with these rendering symptoms:

Unless Firefox, Chrome, and WebKit share some of their WebGL/rendering architecture, it seems to imply that the issue is specific to maplibre. I'm happy to be educated more on the browsers respective architectures as it's not my area of expertise.

gabeschine commented 2 months ago

An update: I have added a "bug detector" to our app. It seems to detect the bug correctly some percentage of the time (no exact metrics here) by looking for a blank sprite canvas. Since this symptom only occurs some of the time, it's not good enough to automate the workaround of reloading the app/web page for all users. It is good enough to collect diagnostic data, however, and use that to better identify where this bug's origins may be.

I'm about to deploy a version that will collect a PNG of the map canvas. I cannot collect a full JSON dump of the maplibre.Map object, because it's too big. So is just Map.painter with the tile cache filtered, which is where I thought I'd start. I'm getting JSON that is still >100mb.

Would folks on the maplibre team let me know what diagnostic data in the Map instance would be valuable to collect from the device? We see enough occurrences of this bug in production to be able to collect information from a lot of devices.

HarelM commented 2 months ago

I don't think I have a good idea what would be helpful unfortunately. I think your best bet would be to try and dig deep into it and suggest a PR that fixes this issue...

HarelM commented 1 month ago

For anyone interested in solving this and getting paid for it, there is a big bounty on this issue now, see here: https://osmus.slack.com/archives/C03TFH5NE83/p1729028937096989?thread_ts=1729028937.096989&cid=C03TFH5NE83 This bounty is not related to the bounty program of MapLibre, it's an external bounty.