Files
IfcOpenShell/src/ifcviewer-web/WebViewportHost.h
T
Dion Moult b7f1f1728f ifcviewer-web: expose frame stats and per-model unload/load to the page
The memory work (cache budget, pressure handling, unloadModel) lives in
ViewportCore and so already ran in the wasm, but the page could not see
or use any of it: the web host had no onFrameStats, and there were no
bindings for residency.

- WebViewportHost latches the last FrameStats; ifcv_get_frame_stats_c
  hands them to JS as doubles, and viewer.stats() returns {fps,
  frameTimeMs, objects, triangles, drawCalls, vram{used, capacity,
  budget}, workingSet{chunks, chunksMissing, missingBytes}} — the same
  figures BonsaiViewer's status bar shows. Device-wide VRAM is omitted:
  there is no query for it on web.
- viewer.unloadModel / loadModel / modelUnloaded / modelVramBytes, keyed
  by source id like the other per-model calls.
- The demo page shows a GPU memory line that turns into a "full: N of M
  visible chunks not loaded" notice once a shortfall persists for 3 s,
  and each model's MB with an Unload/Load button.
- memory.spec.mjs covers stats() and the unload/load round trip.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-25 07:42:13 +10:00

70 lines
3.5 KiB
C++

/********************************************************************************
* *
* This file is part of IfcOpenShell. *
* *
* IfcOpenShell is free software: you can redistribute it and/or modify *
* it under the terms of the Lesser GNU General Public License as published by *
* the Free Software Foundation, either version 3.0 of the License, or *
* (at your option) any later version. *
* *
* IfcOpenShell is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* Lesser GNU General Public License for more details. *
* *
* You should have received a copy of the Lesser GNU General Public License *
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
* *
********************************************************************************/
#ifndef WEBVIEWPORTHOST_H
#define WEBVIEWPORTHOST_H
// Web implementation of ViewportHost. ViewportCore owns the wgpu state
// + render path; this class adapts the embedder hooks to a browser
// canvas (surface creation via emdawnwebgpu's canvas-selector extension,
// framebuffer size from the canvas element, requestFrame via
// requestAnimationFrame, quit via emscripten_force_exit). All
// notifications fall through to the base class no-ops for now —
// future iterations route them to DOM events / a status bar.
#include "ViewportHost.h"
#include <string>
class WebViewportHost final : public ViewportHost {
public:
// `canvas_selector` is the CSS selector for the host <canvas> (e.g.
// "#viewer-canvas" — matches the host page (web/ifcviewer.js)). The string is stored;
// it must outlive the host.
explicit WebViewportHost(std::string canvas_selector);
WGPUSurface createSurface(WGPUInstance instance) override;
void framebufferSize(int& width_px, int& height_px) const override;
float dpr() const override;
// Sets request_frame_pending_ so the RAF callback knows to render
// on the next browser tick. The actual frame scheduling is done by
// the main_web.cpp loop; this avoids spamming RAF callbacks when
// multiple sources request a frame in the same tick.
void requestFrame() override;
void quit() override;
// True when ViewportCore has asked for a frame since the last one
// was rendered. The main loop clears this before invoking
// core.render().
bool consumeFrameRequest();
// The most recent per-frame stats (fps, VRAM, working set). Latched
// here so the page can read them whenever it likes (ifcv_get_frame_stats_c)
// instead of being called back every frame across the wasm boundary.
void onFrameStats(const FrameStats& stats) override { last_stats_ = stats; }
const FrameStats& lastFrameStats() const { return last_stats_; }
private:
std::string canvas_selector_;
bool request_frame_pending_ = true; // arm an initial frame
FrameStats last_stats_ = {};
};
#endif // WEBVIEWPORTHOST_H