From ecf79a9ec271a87221989bb8336eba84d336a274 Mon Sep 17 00:00:00 2001 From: Guillaume Beraudo Date: Tue, 13 Nov 2018 15:41:50 +0100 Subject: [PATCH] First step in uncoupling replay creation and rendering Signed-off-by: Guillaume Beraudo --- src/ol/render/canvas/ImageReplay.js | 1 + src/ol/render/canvas/LineStringReplay.js | 1 + src/ol/render/canvas/PolygonReplay.js | 1 + src/ol/render/canvas/Replay.js | 30 +++++++++++++++++++++-- src/ol/render/canvas/ReplayGroup.js | 24 ++++++++++++++++-- src/ol/render/canvas/TextReplay.js | 20 +++++++++++++++ src/ol/renderer/canvas/VectorLayer.js | 9 +++++-- src/ol/renderer/canvas/VectorTileLayer.js | 7 ++++-- 8 files changed, 85 insertions(+), 8 deletions(-) diff --git a/src/ol/render/canvas/ImageReplay.js b/src/ol/render/canvas/ImageReplay.js index 807ea149c4..e7f921889e 100644 --- a/src/ol/render/canvas/ImageReplay.js +++ b/src/ol/render/canvas/ImageReplay.js @@ -185,6 +185,7 @@ class CanvasImageReplay extends CanvasReplay { this.rotateWithView_ = undefined; this.rotation_ = undefined; this.width_ = undefined; + return super.finish(); } /** diff --git a/src/ol/render/canvas/LineStringReplay.js b/src/ol/render/canvas/LineStringReplay.js index 57822418ae..8aed895832 100644 --- a/src/ol/render/canvas/LineStringReplay.js +++ b/src/ol/render/canvas/LineStringReplay.js @@ -97,6 +97,7 @@ class CanvasLineStringReplay extends CanvasReplay { } this.reverseHitDetectionInstructions(); this.state = null; + return super.finish(); } /** diff --git a/src/ol/render/canvas/PolygonReplay.js b/src/ol/render/canvas/PolygonReplay.js index 1175a58fde..6d9c87b007 100644 --- a/src/ol/render/canvas/PolygonReplay.js +++ b/src/ol/render/canvas/PolygonReplay.js @@ -192,6 +192,7 @@ class CanvasPolygonReplay extends CanvasReplay { coordinates[i] = snap(coordinates[i], tolerance); } } + return super.finish(); } /** diff --git a/src/ol/render/canvas/Replay.js b/src/ol/render/canvas/Replay.js index 079f60575a..6b2b871057 100644 --- a/src/ol/render/canvas/Replay.js +++ b/src/ol/render/canvas/Replay.js @@ -28,6 +28,16 @@ import { } from '../../transform.js'; +/** + * @typedef {Object} SerializableInstructions + * @property {Array<*>} instructions The rendering instructions. + * @property {Array<*>} hitDetectionInstructions The rendering hit detection instructions. + * @property {Array} coordinates The array of all coordinates. + * @property {!Object} textStates The text states (decluttering). + * @property {!Object} fillStates The fill states (decluttering). + * @property {!Object} strokeStates The stoke states (decluttering). + */ + /** * @type {import("../../extent.js").Extent} */ @@ -169,6 +179,16 @@ class CanvasReplay extends VectorContext { } + /** + * Recreate replays and populate them using the provided instructions. + * @param {SerializableInstructions} instructions The serializable instructions + */ + replaceInstructions(instructions) { + this.instructions = instructions.instructions; + this.hitDetectionInstructions = instructions.hitDetectionInstructions; + this.coordinates = instructions.coordinates; + } + /** * @param {CanvasRenderingContext2D} context Context. * @param {import("../../coordinate.js").Coordinate} p1 1st point of the background box. @@ -456,9 +476,15 @@ class CanvasReplay extends VectorContext { } /** - * FIXME empty description for jsdoc + * @return {Object} the serializable instructions. */ - finish() {} + finish() { + return { + instructions: this.instructions, + hitDetectionInstructions: this.hitDetectionInstructions, + coordinates: this.coordinates + }; + } /** * @private diff --git a/src/ol/render/canvas/ReplayGroup.js b/src/ol/render/canvas/ReplayGroup.js index fa7aaaf89d..6e52ee59a8 100644 --- a/src/ol/render/canvas/ReplayGroup.js +++ b/src/ol/render/canvas/ReplayGroup.js @@ -150,6 +150,22 @@ class CanvasReplayGroup extends ReplayGroup { context.clip(); } + /** + * Recreate replays and populate them using the provided instructions. + * @param {!Object>} allInstructions The serializable instructions + */ + replaceInstructions(allInstructions) { + this.replaysByZIndex_ = {}; + for (const zIndex in allInstructions) { + const instructionByZindex = allInstructions[zIndex]; + for (const replayType in instructionByZindex) { + const instructions = instructionByZindex[replayType]; + const replay = this.getReplay(zIndex, replayType); + replay.replaceInstructions(instructions); + } + } + } + /** * @param {Array} replays Replays. * @return {boolean} Has replays of the provided types. @@ -167,15 +183,19 @@ class CanvasReplayGroup extends ReplayGroup { } /** - * FIXME empty description for jsdoc + * @return {!Object>} The serializable instructions */ finish() { + const replaysInstructions = {}; for (const zKey in this.replaysByZIndex_) { + replaysInstructions[zKey] = replaysInstructions[zKey] || {}; const replays = this.replaysByZIndex_[zKey]; for (const replayKey in replays) { - replays[replayKey].finish(); + const replayInstructions = replays[replayKey].finish(); + replaysInstructions[zKey][replayKey] = replayInstructions; } } + return replaysInstructions; } /** diff --git a/src/ol/render/canvas/TextReplay.js b/src/ol/render/canvas/TextReplay.js index e740f4a122..eb7203f86f 100644 --- a/src/ol/render/canvas/TextReplay.js +++ b/src/ol/render/canvas/TextReplay.js @@ -126,7 +126,27 @@ class CanvasTextReplay extends CanvasReplay { this.widths_ = {}; labelCache.prune(); + } + /** + * @inheritdoc + */ + finish() { + const instructions = super.finish(); + instructions.textStates = this.textStates; + instructions.fillStates = this.fillStates; + instructions.strokeStates = this.strokeStates; + return instructions; + } + + /** + * @inheritdoc + */ + replaceInstructions(instructions) { + super.replaceInstructions(instructions); + this.textStates = instructions.textStates; + this.fillStates = instructions.fillStates; + this.strokeStates = instructions.strokeStates; } /** diff --git a/src/ol/renderer/canvas/VectorLayer.js b/src/ol/renderer/canvas/VectorLayer.js index 6864bda9c9..ea7666c134 100644 --- a/src/ol/renderer/canvas/VectorLayer.js +++ b/src/ol/renderer/canvas/VectorLayer.js @@ -480,13 +480,18 @@ class CanvasVectorLayerRenderer extends CanvasLayerRenderer { } else { vectorSource.forEachFeatureInExtent(extent, render); } - replayGroup.finish(); + + const replayGroupInstructions = replayGroup.finish(); + const renderingReplayGroup = new CanvasReplayGroup( + getRenderTolerance(resolution, pixelRatio), extent, resolution, + pixelRatio, vectorSource.getOverlaps(), this.declutterTree_, vectorLayer.getRenderBuffer()); + renderingReplayGroup.replaceInstructions(replayGroupInstructions); this.renderedResolution_ = resolution; this.renderedRevision_ = vectorLayerRevision; this.renderedRenderOrder_ = vectorLayerRenderOrder; this.renderedExtent_ = extent; - this.replayGroup_ = replayGroup; + this.replayGroup_ = renderingReplayGroup; this.replayGroupChanged = true; return true; diff --git a/src/ol/renderer/canvas/VectorTileLayer.js b/src/ol/renderer/canvas/VectorTileLayer.js index 2e608ea9d2..f20fd72eab 100644 --- a/src/ol/renderer/canvas/VectorTileLayer.js +++ b/src/ol/renderer/canvas/VectorTileLayer.js @@ -226,8 +226,11 @@ class CanvasVectorTileLayerRenderer extends CanvasTileLayerRenderer { render.call(this, feature); } } - replayGroup.finish(); - sourceTile.setReplayGroup(layer, tile.tileCoord.toString(), replayGroup); + const replayGroupInstructions = replayGroup.finish(); + const renderingReplayGroup = new CanvasReplayGroup(0, sharedExtent, resolution, + pixelRatio, source.getOverlaps(), this.declutterTree_, layer.getRenderBuffer()); + renderingReplayGroup.replaceInstructions(replayGroupInstructions); + sourceTile.setReplayGroup(layer, tile.tileCoord.toString(), renderingReplayGroup); } replayState.renderedRevision = revision; replayState.renderedRenderOrder = renderOrder;