Skip to content

Commit d55c309

Browse files
committed
Split rendering and update loop in the renderer.
1 parent 79bd4fb commit d55c309

File tree

4 files changed

+109
-66
lines changed

4 files changed

+109
-66
lines changed

src/components/renderer/Renderer.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ export abstract class Renderer {
6868
}
6969

7070
this.stats.update(time);
71+
this.update(time, deltaTime);
7172

7273
this.render(time, deltaTime, resized);
7374

@@ -79,6 +80,8 @@ export abstract class Renderer {
7980
}
8081
};
8182

83+
abstract update(time: number, deltaTime: number): void;
84+
8285
abstract render(
8386
time: DOMHighResTimeStamp,
8487
deltaTime: DOMHighResTimeStamp,

src/mapviewer/MapViewerRenderer.ts

Lines changed: 79 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,19 +13,46 @@ import { MenuTargetType } from "../rs/MenuEntry";
1313
import { isTouchDevice } from "../util/DeviceUtil";
1414
import { InputManager } from "../util/InputManager";
1515

16+
export class MapViewerRendererStats {
17+
frameStart: number;
18+
interactionsTime: number;
19+
20+
opaquePassTime: number;
21+
opaqueNpcPassTime: number;
22+
transparentPassTime: number;
23+
transparentNpcPassTime: number;
24+
25+
constructor() {
26+
this.frameStart = 0;
27+
this.interactionsTime = 0;
28+
this.opaquePassTime = 0;
29+
this.opaqueNpcPassTime = 0;
30+
this.transparentPassTime = 0;
31+
this.transparentNpcPassTime = 0;
32+
}
33+
};
34+
1635
export abstract class MapViewerRenderer<T extends MapSquare = MapSquare> extends Renderer {
1736
abstract type: RendererType;
1837

19-
mapManager: MapManager<T>;
2038
inputManager: InputManager;
2139

40+
mapManager: MapManager<T>;
41+
mapManagerTime: number;
42+
43+
tickTime: number;
44+
rendererStats: MapViewerRendererStats;
45+
2246
constructor(public mapViewer: MapViewer) {
2347
super();
48+
this.inputManager = mapViewer.inputManager;
2449
this.mapManager = new MapManager(
2550
mapViewer.workerPool.size * 2,
2651
this.queueLoadMap.bind(this),
2752
);
28-
this.inputManager = mapViewer.inputManager;
53+
this.mapManagerTime = 0;
54+
this.tickTime = 0;
55+
this.rendererStats = new MapViewerRendererStats();
2956
}
3057

3158
override async init() {
@@ -36,6 +63,23 @@ export abstract class MapViewerRenderer<T extends MapSquare = MapSquare> extends
3663
this.mapViewer.inputManager.cleanUp();
3764
}
3865

66+
abstract rendererUpdate(): void;
67+
68+
update(time: number, deltaTime: number) {
69+
const camera = this.mapViewer.camera;
70+
71+
this.handleInput(deltaTime);
72+
73+
this.rendererUpdate();
74+
75+
const renderDistance = this.mapViewer.renderDistance;
76+
const frameCount = this.stats.frameCount;
77+
78+
const mapManagerStart = performance.now();
79+
this.mapManager.update(camera, frameCount, renderDistance, this.mapViewer.unloadDistance);
80+
this.mapManagerTime = performance.now() - mapManagerStart;
81+
}
82+
3983
initCache(): void {
4084
this.mapManager.init(
4185
this.mapViewer.cacheLoaders.mapFileIndex,
@@ -53,7 +97,7 @@ export abstract class MapViewerRenderer<T extends MapSquare = MapSquare> extends
5397
return {};
5498
}
5599

56-
queueLoadMap(mapX: number, mapY: number): void {}
100+
queueLoadMap(mapX: number, mapY: number): void { }
57101

58102
handleInput(deltaTime: number) {
59103
this.handleKeyInput(deltaTime);
@@ -195,6 +239,38 @@ export abstract class MapViewerRenderer<T extends MapSquare = MapSquare> extends
195239
override onFrameEnd(): void {
196240
super.onFrameEnd();
197241

242+
const frameTime = performance.now() - this.rendererStats.frameStart;
243+
244+
if (this.mapViewer.inputManager.isKeyDown("KeyH")) {
245+
this.mapViewer.debugText = `MapManager: ${this.mapManagerTime.toFixed(2)}ms`;
246+
}
247+
if (this.mapViewer.inputManager.isKeyDown("KeyJ")) {
248+
this.mapViewer.debugText = `Interactions: ${this.rendererStats.interactionsTime.toFixed(2)}ms`;
249+
}
250+
if (this.mapViewer.inputManager.isKeyDown("KeyK")) {
251+
this.mapViewer.debugText = `Tick: ${this.tickTime.toFixed(2)}ms`;
252+
}
253+
if (this.mapViewer.inputManager.isKeyDown("KeyL")) {
254+
this.mapViewer.debugText = `Opaque Pass: ${this.rendererStats.opaquePassTime.toFixed(2)}ms`;
255+
}
256+
if (this.mapViewer.inputManager.isKeyDown("KeyB")) {
257+
this.mapViewer.debugText = `Opaque Npc Pass: ${this.rendererStats.opaqueNpcPassTime.toFixed(2)}ms`;
258+
}
259+
if (this.mapViewer.inputManager.isKeyDown("KeyN")) {
260+
this.mapViewer.debugText = `Transparent Pass: ${this.rendererStats.transparentPassTime.toFixed(2)}ms`;
261+
}
262+
if (this.mapViewer.inputManager.isKeyDown("KeyM")) {
263+
this.mapViewer.debugText = `Transparent Npc Pass: ${this.rendererStats.transparentNpcPassTime.toFixed(
264+
2,
265+
)}ms`;
266+
}
267+
if (this.mapViewer.inputManager.isKeyDown("KeyV")) {
268+
this.mapViewer.debugText = `Frame Time: ${frameTime.toFixed(2)}ms`;
269+
}
270+
if (this.mapViewer.inputManager.isKeyDown("KeyU")) {
271+
this.mapViewer.debugText = `Frame Time Js: ${this.stats.frameTimeJs.toFixed(2)}ms`;
272+
}
273+
198274
if (window.wallpaperFpsLimit !== undefined) {
199275
this.fpsLimit = window.wallpaperFpsLimit;
200276
}

src/renderer/webgl/WebGLRenderer.ts

Lines changed: 25 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -760,8 +760,13 @@ export class WebGLRenderer extends MapViewerRenderer<WebGLMapSquare> {
760760
this.app.resize(width, height);
761761
}
762762

763+
override rendererUpdate() {
764+
const camera = this.mapViewer.camera;
765+
camera.update(this.app.width, this.app.height);
766+
}
767+
763768
override render(time: number, deltaTime: number, resized: boolean): void {
764-
const frameStart = performance.now();
769+
this.rendererStats.frameStart = performance.now();
765770

766771
const frameCount = this.stats.frameCount;
767772

@@ -807,22 +812,12 @@ export class WebGLRenderer extends MapViewerRenderer<WebGLMapSquare> {
807812
this.resolutionUni[1] = this.app.height;
808813
}
809814

810-
const inputManager = this.mapViewer.inputManager;
811815
const camera = this.mapViewer.camera;
812-
813-
this.handleInput(deltaTime);
814-
815-
camera.update(this.app.width, this.app.height);
816-
817-
const renderDistance = this.mapViewer.renderDistance;
818-
819-
const mapManagerStart = performance.now();
820-
this.mapManager.update(camera, frameCount, renderDistance, this.mapViewer.unloadDistance);
821-
const mapManagerTime = performance.now() - mapManagerStart;
822-
823816
this.cameraPosUni[0] = camera.getPosX();
824817
this.cameraPosUni[1] = camera.getPosZ();
825818

819+
const renderDistance = this.mapViewer.renderDistance;
820+
826821
this.sceneUniformBuffer
827822
.set(0, camera.viewProjMatrix as Float32Array)
828823
.set(1, camera.viewMatrix as Float32Array)
@@ -840,12 +835,13 @@ export class WebGLRenderer extends MapViewerRenderer<WebGLMapSquare> {
840835
const currInteractions = this.interactions[frameCount % this.interactions.length];
841836

842837
const interactionsStart = performance.now();
838+
const inputManager = this.mapViewer.inputManager;
843839
if (!inputManager.isPointerLock()) {
844840
this.prepareInteractions(currInteractions);
845841
} else if (this.hoveredMapIds.size > 0) {
846842
this.hoveredMapIds.clear();
847843
}
848-
const interactionsTime = performance.now() - interactionsStart;
844+
this.rendererStats.interactionsTime = performance.now() - interactionsStart;
849845

850846
if (this.cullBackFace) {
851847
this.app.enable(PicoGL.CULL_FACE);
@@ -864,26 +860,26 @@ export class WebGLRenderer extends MapViewerRenderer<WebGLMapSquare> {
864860

865861
const tickStart = performance.now();
866862
this.tickPass(timeSec, ticksElapsed, clientTicksElapsed);
867-
const tickTime = performance.now() - tickStart;
863+
this.tickTime = performance.now() - tickStart;
868864

869865
const npcDataTextureIndex = this.updateNpcDataTexture();
870866
const npcDataTexture = this.npcDataTextureBuffer[npcDataTextureIndex];
871867

872868
this.app.disable(PicoGL.BLEND);
873869
const opaquePassStart = performance.now();
874870
this.renderOpaquePass();
875-
const opaquePassTime = performance.now() - opaquePassStart;
871+
this.rendererStats.opaquePassTime = performance.now() - opaquePassStart;
876872
const opaqueNpcPassStart = performance.now();
877873
this.renderOpaqueNpcPass(npcDataTextureIndex, npcDataTexture);
878-
const opaqueNpcPassTime = performance.now() - opaqueNpcPassStart;
874+
this.rendererStats.opaqueNpcPassTime = performance.now() - opaqueNpcPassStart;
879875

880876
this.app.enable(PicoGL.BLEND);
881877
const transparentPassStart = performance.now();
882878
this.renderTransparentPass();
883-
const transparentPassTime = performance.now() - transparentPassStart;
879+
this.rendererStats.transparentPassTime = performance.now() - transparentPassStart;
884880
const transparentNpcPassStart = performance.now();
885881
this.renderTransparentNpcPass(npcDataTextureIndex, npcDataTexture);
886-
const transparentNpcPassTime = performance.now() - transparentNpcPassStart;
882+
this.rendererStats.transparentNpcPassTime = performance.now() - transparentNpcPassStart;
887883

888884
// Can't sample from renderbuffer so blit to a texture for sampling.
889885
this.app.readFramebuffer(this.framebuffer);
@@ -934,52 +930,24 @@ export class WebGLRenderer extends MapViewerRenderer<WebGLMapSquare> {
934930
this.frameDrawCall.draw();
935931
}
936932

933+
this.loadPending(timeSec)
934+
}
935+
936+
loadPending(timeSec: number) {
937937
// Load new map squares
938938
const mapData = this.mapsToLoad.shift();
939939
if (mapData && this.isValidMapData(mapData)) {
940940
this.loadMap(
941-
this.mainProgram,
942-
this.mainAlphaProgram,
943-
this.npcProgram,
944-
this.textureArray,
945-
this.textureMaterials,
946-
this.sceneUniformBuffer,
941+
this.mainProgram!,
942+
this.mainAlphaProgram!,
943+
this.npcProgram!,
944+
this.textureArray!,
945+
this.textureMaterials!,
946+
this.sceneUniformBuffer!,
947947
mapData,
948948
timeSec,
949949
);
950950
}
951-
952-
const frameTime = performance.now() - frameStart;
953-
954-
if (this.mapViewer.inputManager.isKeyDown("KeyH")) {
955-
this.mapViewer.debugText = `MapManager: ${mapManagerTime.toFixed(2)}ms`;
956-
}
957-
if (this.mapViewer.inputManager.isKeyDown("KeyJ")) {
958-
this.mapViewer.debugText = `Interactions: ${interactionsTime.toFixed(2)}ms`;
959-
}
960-
if (this.mapViewer.inputManager.isKeyDown("KeyK")) {
961-
this.mapViewer.debugText = `Tick: ${tickTime.toFixed(2)}ms`;
962-
}
963-
if (this.mapViewer.inputManager.isKeyDown("KeyL")) {
964-
this.mapViewer.debugText = `Opaque Pass: ${opaquePassTime.toFixed(2)}ms`;
965-
}
966-
if (this.mapViewer.inputManager.isKeyDown("KeyB")) {
967-
this.mapViewer.debugText = `Opaque Npc Pass: ${opaqueNpcPassTime.toFixed(2)}ms`;
968-
}
969-
if (this.mapViewer.inputManager.isKeyDown("KeyN")) {
970-
this.mapViewer.debugText = `Transparent Pass: ${transparentPassTime.toFixed(2)}ms`;
971-
}
972-
if (this.mapViewer.inputManager.isKeyDown("KeyM")) {
973-
this.mapViewer.debugText = `Transparent Npc Pass: ${transparentNpcPassTime.toFixed(
974-
2,
975-
)}ms`;
976-
}
977-
if (this.mapViewer.inputManager.isKeyDown("KeyV")) {
978-
this.mapViewer.debugText = `Frame Time: ${frameTime.toFixed(2)}ms`;
979-
}
980-
if (this.mapViewer.inputManager.isKeyDown("KeyU")) {
981-
this.mapViewer.debugText = `Frame Time Js: ${this.stats.frameTimeJs.toFixed(2)}ms`;
982-
}
983951
}
984952

985953
tickPass(time: number, ticksElapsed: number, clientTicksElapsed: number): void {

src/renderer/webgpu/WebGPURenderer.ts

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -179,13 +179,9 @@ export class WebGPURenderer extends MapViewerRenderer {
179179
);
180180
}
181181

182-
render(time: number, deltaTime: number, resized: boolean): void {
183-
const camera = this.mapViewer.camera;
184-
185-
this.handleInput(deltaTime);
186-
187-
camera.update(this.canvas.width, this.canvas.height);
182+
rendererUpdate(): void { }
188183

184+
render(time: number, deltaTime: number, resized: boolean): void {
189185
const device = this.device;
190186
const context = this.context;
191187
const pipeline = this.pipeline;

0 commit comments

Comments
 (0)