Skip to content

Commit

Permalink
Merge pull request #15789 from ahocevar/performance-minimal
Browse files Browse the repository at this point in the history
Improve performance of deferred rendering
  • Loading branch information
ahocevar committed May 1, 2024
2 parents d95726b + 5d7f0b0 commit c7d654e
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 23 deletions.
10 changes: 3 additions & 7 deletions src/ol/render/canvas/Executor.js
Expand Up @@ -1175,13 +1175,9 @@ class Executor {
dd = /** @type {number} */ (instruction[2]);
x = pixelCoordinates[d];
y = pixelCoordinates[d + 1];
roundX = (x + 0.5) | 0;
roundY = (y + 0.5) | 0;
if (roundX !== prevX || roundY !== prevY) {
context.moveTo(x, y);
prevX = roundX;
prevY = roundY;
}
context.moveTo(x, y);
prevX = (x + 0.5) | 0;
prevY = (y + 0.5) | 0;
for (d += 2; d < dd; d += 2) {
x = pixelCoordinates[d];
y = pixelCoordinates[d + 1];
Expand Down
38 changes: 28 additions & 10 deletions src/ol/render/canvas/ExecutorGroup.js
Expand Up @@ -365,7 +365,7 @@ class ExecutorGroup {

builderTypes = builderTypes ? builderTypes : ALL;
const maxBuilderTypes = ALL.length;
let i, ii, j, jj, replays, replay;
let i, ii, j, jj, replays;
if (declutterTree) {
zs.reverse();
}
Expand All @@ -374,7 +374,7 @@ class ExecutorGroup {
replays = this.executorsByZIndex_[zIndexKey];
for (j = 0, jj = builderTypes.length; j < jj; ++j) {
const builderType = builderTypes[j];
replay = replays[builderType];
const replay = replays[builderType];
if (replay !== undefined) {
const zIndexContext =
declutterTree === null ? undefined : replay.getZIndexContext();
Expand All @@ -391,14 +391,31 @@ class ExecutorGroup {
// visible outside the current extent when panning
this.clip(context, transform);
}
replay.execute(
context,
scaledCanvasSize,
transform,
viewRotation,
snapToPixel,
declutterTree,
);
if (
!zIndexContext ||
builderType === 'Text' ||
builderType === 'Image'
) {
replay.execute(
context,
scaledCanvasSize,
transform,
viewRotation,
snapToPixel,
declutterTree,
);
} else {
zIndexContext.pushFunction((context) =>
replay.execute(
context,
scaledCanvasSize,
transform,
viewRotation,
snapToPixel,
declutterTree,
),
);
}
if (requireClip) {
context.restore();
}
Expand Down Expand Up @@ -433,6 +450,7 @@ class ExecutorGroup {
zIndexContext.draw(this.renderedContext_); // FIXME Pass clip to replay for temporarily enabling clip
zIndexContext.clear();
});
deferredZIndexContexts[zs[i]].length = 0;
}
}
}
Expand Down
16 changes: 14 additions & 2 deletions src/ol/render/canvas/ZIndexContext.js
Expand Up @@ -66,6 +66,14 @@ class ZIndexContext {
return this;
};

/**
* Push a function that renders to the context directly.
* @param {function(CanvasRenderingContext2D): void} render Function.
*/
pushFunction(render) {
this.instructions_[this.zIndex + this.offset_].push(render);
}

/**
* Get a proxy for CanvasRenderingContext2D which does not support getting state
* (e.g. `context.globalAlpha`, which will return `undefined`). To set state, if it relies on a
Expand All @@ -82,9 +90,13 @@ class ZIndexContext {
*/
draw(context) {
this.instructions_.forEach((instructionsAtIndex) => {
for (let i = 0, ii = instructionsAtIndex.length; i < ii; i += 2) {
for (let i = 0, ii = instructionsAtIndex.length; i < ii; ++i) {
const property = instructionsAtIndex[i];
const instructionAtIndex = instructionsAtIndex[i + 1];
if (typeof property === 'function') {
property(context);
continue;
}
const instructionAtIndex = instructionsAtIndex[++i];
if (typeof (/** @type {*} */ (context)[property]) === 'function') {
/** @type {*} */ (context)[property](...instructionAtIndex);
} else {
Expand Down
14 changes: 10 additions & 4 deletions src/ol/renderer/canvas/VectorTileLayer.js
Expand Up @@ -604,10 +604,15 @@ class CanvasVectorTileLayerRenderer extends CanvasTileLayerRenderer {
const executorGroupZIndexContexts = executorGroups.map(({executorGroup}) =>
executorGroup.getDeferredZIndexContexts(),
);
const zIndexKeys = executorGroupZIndexContexts
.map((zIndexContext) => Object.keys(zIndexContext))
.flat()
.sort(ascending);
const usedZIndices = {};
for (let i = 0, ii = executorGroups.length; i < ii; ++i) {
const executorGroupZindexContext =
executorGroups[i].executorGroup.getDeferredZIndexContexts();
for (const key in executorGroupZindexContext) {
usedZIndices[key] = true;
}
}
const zIndexKeys = Object.keys(usedZIndices).sort(ascending);
zIndexKeys.map(Number).forEach((zIndex) => {
executorGroupZIndexContexts.forEach((zIndexContexts, i) => {
if (!zIndexContexts[zIndex]) {
Expand All @@ -629,6 +634,7 @@ class CanvasVectorTileLayerRenderer extends CanvasTileLayerRenderer {
context.globalAlpha = alpha;
zIndexContext.clear();
});
zIndexContexts[zIndex].length = 0;
});
});
}
Expand Down

0 comments on commit c7d654e

Please sign in to comment.