Git Product home page Git Product logo

Comments (25)

ssundell avatar ssundell commented on September 27, 2024 1

I'm having similar issues with plain desktop Chrome: when zooming, the map flickers, and on some zoom levels it goes blank completely. WMS and vector tile layers seem to work ok, but if you add a vector layer, flickering starts. Adding the className parameter removes flickering.

Not sure if I can help much with debugging, just came to comment that it's probably not just an issue related to Nothing phone hardware; the hardware I'm using is a Lenovo laptop with Intel graphics...

from openlayers.

ahocevar avatar ahocevar commented on September 27, 2024

Would you be able to share the transform values on the canvas that cause the map to flicker?

from openlayers.

mgurzixo avatar mgurzixo commented on September 27, 2024

I will instrument the code, do a run and pastebin the result.
I should be able to do this by the end of the week

from openlayers.

mgurzixo avatar mgurzixo commented on September 27, 2024

In fact I just did it.
The code:

const matrixPrecision = [1e6, 1e6, 1e6, 1e6, 2, 2];
let transformStringDiv;

let myNumber = 0;

export function toString(mat) {
  const newTransformString =
    'matrix(' +
    mat
      .map(
        (value, i) =>
          Math.round(value * matrixPrecision[i]) / matrixPrecision[i],
      )
      .join(', ') +
    ')';

  const transformString = 'matrix(' + mat.join(', ') + ')';
  const node =
    transformStringDiv || (transformStringDiv = document.createElement('div'));
  node.style.transform = transformString;
  const oldTransformString= node.style.transform;

  console.log(`[OL.transform.toString] #${myNumber++} mat:"${mat}" old:"${oldTransformString}" new:"${newTransformString}" ${oldTransformString == newTransformString}`)

  return newTransformString;
}

Run is available here

It looks like you do not round the last 2 elements, but just zero them.
Changing matrixPrecision to:

const matrixPrecision = [1e6, 1e6, 1e6, 1e6, 1e6, 1e6];

albeit not giving exactly the same thing for the last 2 numbers (see here) seems to solve the problem, as there is no flickering anymore.

I don't know enough the internals of OL for being able to draw conclusions ;)

A quick addition: changing matrixPrecision to:

const matrixPrecision = [1e6, 1e6, 1e6, 1e6, 1e7, 1e7];

gives now exactly the same results (run 3) between the 2 methods.

Another quick addition:

  • The fix works also on Ios (iphone)
  • I made a 4th run with a console.warn so as to get the stack frames. Maybe you can understand why 1 transform out of 4 has non null last 2 parameters.

from openlayers.

ahocevar avatar ahocevar commented on September 27, 2024

So far so good. But can you mark the transforms that cause the map to disappear or flicker?

from openlayers.

mgurzixo avatar mgurzixo commented on September 27, 2024

I just checked, and it looks like the transforms do NOT change, except when I change screen orientation from portrait to paysage.
Panning or zooming does not change values. Maybe the m̀at should be cached, or OL is performing useless calculations?

But the flickering is definitively panning and zoomLevel dependent. I could have to do with fractional zoom levels?

Anyway, the new matrixPrecision initialization solves completely the problem on all my test systems (Ios, Android, browsers, electron). I keep this value in my fork and I recommend the update of OL.

Thanks for all the hard work on this exceptional product!

Michel

from openlayers.

ahocevar avatar ahocevar commented on September 27, 2024

The problem is: the reason for #15344 was that the precision of the matrix parameters was too high, so canvases could not be grouped together any more, even if their transform was de facto the same.

I'd really like to fix this issue, but since I'm not able to reproduce the issue I have to rely on reports here. So can you please provide a minimal example with code that causes your devices in question to flicker? And also a video that shows when and how the flickering occurs?

from openlayers.

mgurzixo avatar mgurzixo commented on September 27, 2024

I did a video, available here .
As the app is actually under embargo, I started to cleanup everything except the map, and I was surprised to see that everything became OK.
The flickering starts to occur as soon as a marker is visible, or not far away in the margins.
This marker is in a vector layer:

 poiSource = new VectorSource({
    features: myPlaces.getMarkersFeatures().value,
  });
  const poiLayer = new VectorLayer({
    source: poiSource,
  });

and the style is done with:

let myCanvas = document.createElement("canvas");
      let myContext = myCanvas.getContext("2d");
      myCanvas.width = upngImage.width;
      myCanvas.height = upngImage.height;
      const upngImageData = new ImageData(
        new Uint8ClampedArray(rgba8),
        upngImage.width,
        upngImage.height,
      );
      myContext.putImageData(upngImageData, 0, 0);

      myStyle = new Style({
        image: new Icon({
          anchor: options.anchor,
          anchorXUnits: "fraction",
          anchorYUnits: "fraction",
          crossOrigin: "anonymous",
          img: myCanvas,
          rotation: options.rotation,
          displacement: options.displacement,
          opacity: options.opacity,
          scale: options.scale || DEFAULTS.SCALE,
          color: options.color,
          rotateWithView: options.rotateWithView,
        }),
      });

the width and height are 64x64px
and rgba8 is created with:

rgba8 = composeBitmap(
          new Uint8ClampedArray(stencil),
          upngImage.width,
          upngImage.height,
          options.strokeColor || DEFAULTS.STROKE_COLOR,
          options.fillColor || DEFAULTS.FILL_COLOR,
        );

stencil is an array of RGBA pixels created with UPNG.toRGBA8() from the upng-js library.

If I remove this marker, or if it is far away from the viewport, everything is OK.
I have other markers in this layer, created from SVG images, that does NOT cause any problem.

So, it looks like there is a bad interaction when a feature in a vector layer is created from a canvas, which does not occur when the (nearly) same image is created from an SVG.

I am using Quasar which uses vue3 and capacitor underneath. The exact same code works OK with any browser (chromium, firefox) on the same phone. It occurs only when using the webview.

I have plenty of workarounds to solve this problem and I do not need support, but it is not a good thing to leave questions unanswered.

I am not very fluent in creating a simple OL example from scratch and making it run in a webview, but I am ready to test on this particular phone any test that you could create.

from openlayers.

ahocevar avatar ahocevar commented on September 27, 2024

Thanks for this excellent report, @mgurzixo. Reading that I assume the problem is not the transform itself, but the fact that with the change the marker layer is combined with the base map, at least sometimes.

As a test, can you add the config option className: 'poi' to the poiLayer, and see if the issue persists?

from openlayers.

mgurzixo avatar mgurzixo commented on September 27, 2024

When adding this option:

  const poiLayer = new VectorLayer({
    source: poiSource,
    className:"poi",
  });

Everything works OK with both the old and the new initialization. The markers are OK and there is absolutely no flickering.

I suspect a phenomenon of moiré between the poiLayer canvas and the tileLayer canvas; maybe you don´t apply exactly the very same transformation to both layers and there is a very slight difference in the rotation part. We are talking about physical pixels here and this explanation is compatible with everything observed.

There is actually a move towards hardware composition. Depending on the hardware rounding errors, number of pixels of the screen and so on... this phenomenon could or could not occur. Maybe also you can do things in a webview (authorizations, direct access to hardware, part of it running in kernel space ...) that you cannot do with a browser just running in userland.

For myself, I switched everything from bitmap to SVG, so I am not concerned anymore and markers are crisper ;)

I still suggest using the [1e6, 1e6, 1e6, 1e6, 1e7, 1e7] initialization, and provide a switch (could be an option when creating the layer) to fallback to the old DOM method, just in case...

Thank you @ahocevar for taking so much care to make a perfect product

Michel

from openlayers.

ahocevar avatar ahocevar commented on September 27, 2024

Can you test one more thing for me: with the original code (without className), what is document.querySelectorAll('.ol-layer canvas').length when rendering is correct, and what when there's the flicker?

from openlayers.

mgurzixo avatar mgurzixo commented on September 27, 2024

It is always 1 and does not vary, flickering or not.

Code is:

console.warn(`[OL.transform.toString] length:${document.querySelectorAll('.ol-layer canvas').length}`);

I sampled it both in transform.js#toString()and in my view.on("change:center")handler.

from openlayers.

mgurzixo avatar mgurzixo commented on September 27, 2024

BTW, I don't know precisely the internals of OL, but are you aware of that?

from openlayers.

ahocevar avatar ahocevar commented on September 27, 2024

BTW, I don't know precisely the internals of OL, but are you aware of that?

Yes, that's exactly how we do it.

from openlayers.

ahocevar avatar ahocevar commented on September 27, 2024

I still suggest using the [1e6, 1e6, 1e6, 1e6, 1e7, 1e7] initialization, and provide a switch (could be an option when creating the layer) to fallback to the old DOM method, just in case...

That would break a test, and deoptimise composition by using multiple canvases. Since you can use the className config in userland to achieve that, you have a viable option to fix this strange problem which is very likely a hardware problem on the device in question.

from openlayers.

mgurzixo avatar mgurzixo commented on September 27, 2024

I understand that, and it makes sense as long as there is a workaround available. OL strength and weakness is all the layer processing to mix apples and oranges (ie. different projections, rotations, resolutions and constraints) onto the same display. This means that we users should avoid throwing other bitmaps (especially hand-made) into this complexity, and stick to vectors, SVG and standard HTML.
BTW, I think that it is not a hardware problem but a hardware particularity ;)

from openlayers.

ahocevar avatar ahocevar commented on September 27, 2024

Thanks for reporting your finding, @ssundell. If you are able to provide a minimal example, e.g. in a jsfiddle or codesandbox, that would help a lot.

from openlayers.

ahocevar avatar ahocevar commented on September 27, 2024

#15620 should fix this problem.

from openlayers.

mgurzixo avatar mgurzixo commented on September 27, 2024

@ahocevar
I tried your transform branch, it still flickers on the NOTHING phone (either using className:"poi", or not).
The "behaviour" of the flicker is different (sorry, I cannot precisely define it, this is just a feeling).
It does not flicker on other phones.
I have another vector layer with only lineStrings in it, and your branch seems to mess it: depending on the zoom level, the lineStrings are shifted and ?magnified?
This is not the case with my markers layer (my old version using bitmaps) which is OK and still displayed correctly, even when the tile layer shows nothing.
That was a very quick test, and maybe I am not using a good fork/version/branch of OL. I am not very fluent with git and GitHub intricacies. Could you give me a link to a branch with your patch that I could clone locally and link with my (old flickering) version for better testing?

from openlayers.

ahocevar avatar ahocevar commented on September 27, 2024

For that pull request, you can test with the full build: https://deploy-preview-15620--ol-site.netlify.app/en/latest/ol/dist/ol.js and https://deploy-preview-15620--ol-site.netlify.app/en/latest/ol/ol.css

from openlayers.

jankosk avatar jankosk commented on September 27, 2024

I have similar map flickering issues with tile layers when zooming on desktop Chrome with Intel graphics. Applying the patch in #15620 seems to work for me.

from openlayers.

bjornharrtell avatar bjornharrtell commented on September 27, 2024

Also seeing this flickering primarily on the combination Windows and Chrome.

from openlayers.

ahocevar avatar ahocevar commented on September 27, 2024

@bjornharrtell Thanks for reporting. Can you please also check if #15620 fixes the problem for you?

from openlayers.

ahocevar avatar ahocevar commented on September 27, 2024

#15620 is now merged, so ol package users please test if the issue is fixed by doing an npm install ol@dev.

from openlayers.

bjornharrtell avatar bjornharrtell commented on September 27, 2024

@ahocevar limited testing indicates that #15620 is effective in our case.

from openlayers.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.