Comments (25)
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.
Would you be able to share the transform values on the canvas that cause the map to flicker?
from openlayers.
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.
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.
So far so good. But can you mark the transforms that cause the map to disappear or flicker?
from openlayers.
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.
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.
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.
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.
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.
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.
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.
BTW, I don't know precisely the internals of OL, but are you aware of that?
from openlayers.
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.
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.
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.
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.
#15620 should fix this problem.
from openlayers.
@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.
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.
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.
Also seeing this flickering primarily on the combination Windows and Chrome.
from openlayers.
@bjornharrtell Thanks for reporting. Can you please also check if #15620 fixes the problem for you?
from openlayers.
#15620 is now merged, so ol package users please test if the issue is fixed by doing an npm install ol@dev
.
from openlayers.
@ahocevar limited testing indicates that #15620 is effective in our case.
from openlayers.
Related Issues (20)
- webgl memory leak HOT 1
- Examples don't display correctly OOTB in a web browser
- layerState is undefined in inView function HOT 1
- Idea: Make clustering more configurable HOT 4
- Small improvement in ol.interaction.DragAndDrop HOT 1
- OpenLayers unable to render Float32 GeoTiff HOT 4
- tileGrid key is not an available option in OGCVectorTile HOT 1
- WFS#writeTransaction() fails for undefined properties
- Add KMZ file into Openlayers map HOT 4
- Error when getting attributions of a BingMaps layer
- Vector tile source format type MVT doesn't accept - format: new MVT({ featureClass: Feature }) HOT 1
- KML with Nested MultiGeometry is not Rendered HOT 4
- Failed to resolve module specifier "ol/Map.js". Relative references must start with either "/", "./", or "../".
- how to render a planar coordinate FlatGeobuf data? HOT 2
- Flaky WebGL style parsing test
- webgl - stroke-pattern-start-offset HOT 3
- Graticule ,set latLabelPosition to 0.5 ,not always in the middle
- Replace polyfills link to safe one HOT 1
- Issue with Drawing and Modifying Geodesic Lines in MultiWorld Mode HOT 4
- SVG performance issues in Firefox HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
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.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from openlayers.