Skip to content

Simplification of the loading process for rasterized tiles and mesh tiles #2609

Draft
gchoqueux wants to merge 7 commits intoiTowns:masterfrom
gchoqueux:refacto/simple_loading_tile
Draft

Simplification of the loading process for rasterized tiles and mesh tiles #2609
gchoqueux wants to merge 7 commits intoiTowns:masterfrom
gchoqueux:refacto/simple_loading_tile

Conversation

@gchoqueux
Copy link
Contributor

@gchoqueux gchoqueux commented Oct 6, 2025

Description

This PR proposes a possible simplification of the loading process for rasterized tiles and mesh tiles.

Summary of changes

  • TileMesh instances are now created directly in TiledGeometryLayer, without using commands or providers.
  • TileMesh.pendingSubdivision has been removed.
  • TiledGeometryLayer#hasEnoughTexturesToSubdivide has been removed.
  • updateLayeredMaterialNodeImagery and updateLayeredMaterialNodeElevation have been merged into a single lightweight method.
  • TileProvider has been deleted.
  • Texture loading is now handled by RasterTile#load.

@gchoqueux gchoqueux changed the title Simplification of the loading process for **rasterized tiles** and **mesh tiles**. Simplification of the loading process for rasterized tiles and mesh tiles Oct 6, 2025
@gchoqueux gchoqueux force-pushed the refacto/simple_loading_tile branch 13 times, most recently from 489581c to afdfc01 Compare October 8, 2025 13:13
@gchoqueux
Copy link
Contributor Author

Rebased

@gchoqueux
Copy link
Contributor Author

I’ve come up with a possible way to simplify this — what do you think of these changes?

@gchoqueux gchoqueux force-pushed the refacto/simple_loading_tile branch from afdfc01 to 6f64fdf Compare October 10, 2025 09:24
@jailln
Copy link
Contributor

jailln commented Oct 10, 2025

It seems related to #2521 and #2525 which haven't been merged yet; but it goes a bit further, is that right? These PR where not merged because of #2530 . Do you have the same issue?

@gchoqueux gchoqueux force-pushed the refacto/simple_loading_tile branch 4 times, most recently from 2cec783 to 15dfa04 Compare October 13, 2025 11:12
@gchoqueux
Copy link
Contributor Author

gchoqueux commented Oct 13, 2025

It seems related to #2521 and #2525 which haven't been merged yet; but it goes a bit further, is that right? These PR where not merged because of #2530 . Do you have the same issue?

It doesn’t seem to have the same issue in the functional tests.
However, I did change the number of displayed tiles in the functional tests — maybe because this PR is not finished yet.

@gchoqueux gchoqueux force-pushed the refacto/simple_loading_tile branch 4 times, most recently from c7b4635 to 4bd5c32 Compare October 14, 2025 09:13
@gchoqueux
Copy link
Contributor Author

gchoqueux commented Oct 14, 2025

My bad, there's a issue with VIEW_EVENTS.LAYERS_INITIALIZED, but it is not the same, it's called very late, it's almost the opposite.
I'll investigate
solved

@gchoqueux gchoqueux force-pushed the refacto/simple_loading_tile branch from e9aab85 to 3d3be67 Compare October 14, 2025 15:48
@gchoqueux gchoqueux force-pushed the refacto/simple_loading_tile branch 3 times, most recently from eecc503 to 4c86123 Compare December 15, 2025 14:53
@gchoqueux gchoqueux force-pushed the refacto/simple_loading_tile branch 3 times, most recently from 5235375 to 7a3ea9a Compare January 7, 2026 15:34
@Neptilo
Copy link
Contributor

Neptilo commented Jan 16, 2026

Hi! I'm starting to look into the loading processes to get familiar with them, in order to improve them after this simplification is completed. Thanks for the work done so far!
Do you need help fixing the remaining bugs?
What is the display bug you mention in ElevationLayer.anyVisibleData? I can see that changing the first current.source to current?.source already makes a big difference, but I assume you are referring to a deeper bug...

@gchoqueux gchoqueux force-pushed the refacto/simple_loading_tile branch 2 times, most recently from 7a07fe7 to 47507b0 Compare January 20, 2026 16:54
@gchoqueux
Copy link
Contributor Author

gchoqueux commented Jan 20, 2026

Remaining work in this PR

  • finalize the method for verifying data visibility : anyVisibleData vs extentInsideLimit methods
  • rewrite some unit tests
  • finalize tiles property in RasterTile

FAQ

What is the display bug you mention in ElevationLayer.anyVisibleData?

I don't remember exactly i remove the commentary

I can see that changing the first current.source to current?.source, you are referring to a deeper bug ?

I think it's not a bug

the others bugs :

  • wrong tile visibility
  • wrong parent texture update

@gchoqueux
Copy link
Contributor Author

Next steps to move forward on the PR

  • An initial code review by at least 2 reviewers on the architecture and the core aspects of the PR.
    The main code of this PR hasn’t changed for weeks; only minor formatting changes and rebases have been made.

Assistance can be provided on the following points:

  • Validation and finalization of the development of anyVisibleData
  • Rewriting unit tests and improving coverage
  • Help testing this PR on the various itowns examples

@gchoqueux gchoqueux force-pushed the refacto/simple_loading_tile branch from 47507b0 to 5b6ea96 Compare January 30, 2026 14:02
@gchoqueux gchoqueux force-pushed the refacto/simple_loading_tile branch 8 times, most recently from 92e8c4c to a9618c4 Compare February 16, 2026 16:23
@gchoqueux gchoqueux force-pushed the refacto/simple_loading_tile branch from a9618c4 to c581383 Compare February 17, 2026 14:59
Copy link
Contributor

@Desplandis Desplandis left a comment

Choose a reason for hiding this comment

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

The proposed changes are fine by me. It makes the code more easy to understand (e.g. no need to track the changes of layerUpdateState across 4 different files). I did some high-level comments on the code (and some low-level too sorry), those are some questions about the behaviour before and after this PR.

Note that I did not tested it across our examples, nor did I run the tests.

Could you please provide a list of the remaining things to address in this PR?

Comment on lines +92 to +94
if (geometry && !geometry.index) {
throw new Error('Geometry found in cache without index buffer');
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Is this really possible to have a geometry without index here?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

no, i remove this test

Comment on lines +104 to 115
const buffers = computeBuffers(
builder,
{ ...params, center },
cachedBuffers !== undefined
? {
index: cachedBuffers.index.array as
Uint8Array | Uint16Array | Uint32Array,
uv: cachedBuffers.uv.array as Float32Array,
}
: undefined,
);

Copy link
Contributor

Choose a reason for hiding this comment

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

It seems that this code could fail before this PR, are those exceptions catched somewhere?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I not sure there are failures

}
}

export class TileMatrixSetLimits {
Copy link
Contributor

Choose a reason for hiding this comment

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

This greatly simplifies the code in TMSSource!

In the future (maybe for the next hackaton), I will surely try to add a tile grid module similar to openlayer's TileGrid which will incorporates your changes here.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

yes I add news features in TileMatrixSetLimits


update(context, layer, node, parent) {
return updateLayeredMaterialNodeElevation(context, this, node, parent);
anyVisibleData(node) {
Copy link
Contributor

Choose a reason for hiding this comment

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

We should find a better name. x)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

yes,
hasData ?

@@ -1,4 +1,4 @@
import { EMPTY_TEXTURE_ZOOM } from 'Renderer/RasterTile';
import { EMPTY_TEXTURE_ZOOM, RasterTile } from 'Renderer/RasterTile';
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
import { EMPTY_TEXTURE_ZOOM, RasterTile } from 'Renderer/RasterTile';
import { EMPTY_TEXTURE_ZOOM, type RasterTile } from 'Renderer/RasterTile';

}

initFromParent(parent, extents) {
load(requester, view) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Similarly to load, is there a method to RasterTile to "dispose" the textures?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

yes

this.disposeRedrawnTextures(textures);
for (let i = 0, il = textures.length; i < il; ++i) {
this.setTexture(i, textures[i], pitchs[i]);
this.setTexture(i, textures[i], this.tiles[i].offsetToParent(textures[i].extent));
Copy link
Contributor

Choose a reason for hiding this comment

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

So pitches/offsetScales parameters were always offsetToParent of texture extent?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

yes

Comment on lines +328 to +329
// [TEMP] find best place to update uniforms
node.material.layersNeedUpdate = node.material.visible;
Copy link
Contributor

Choose a reason for hiding this comment

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

This is similar to the old behaviour, but I agree that we should reconsider where we should request a new update of the material!


update(context, layer, node) {
if (layer.visible && !layer.freeze && this.anyVisibleData(node)) {
const rasterTile = node.material.getTile(this.id) || this.setupRasterNode(node);
Copy link
Contributor

Choose a reason for hiding this comment

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

So setupRasterNode is an abstract method of RasterLayer

Copy link
Contributor Author

Choose a reason for hiding this comment

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

yes

anyVisibleData(node) {
const current = node.material.getElevationTile()?.layer;
return super.anyVisibleData(node)
&& (current?.source == this.source || this.source.zoom.min > (current?.source.zoom.max || -1));
Copy link
Contributor

Choose a reason for hiding this comment

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

What is the meaning of -1 here?

Copy link
Contributor Author

@gchoqueux gchoqueux Mar 6, 2026

Choose a reason for hiding this comment

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

it's for this.source.zoom.min > -1 would be always true

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.

4 participants