web: add self-contained static HTML timing report (web_save_report)#10087
web: add self-contained static HTML timing report (web_save_report)#10087openroad-ci wants to merge 2 commits intoThe-OpenROAD-Project:masterfrom
Conversation
Add a `web_save_report` Tcl command that generates a standalone HTML timing report reusing the exact same JS/CSS as the live web viewer. Architecture: The static report substitutes the WebSocket server with a cache layer. WebSocketManager gains a `fromCache(cache)` factory that serves pre-computed responses from `window.__STATIC_CACHE__` embedded in the HTML. Cached request types include tech, bounds, timing_report, slack_histogram, chart_filters, and tile PNGs. Uncached requests (select, tcl_eval, etc.) reject gracefully. All 18 JS source files plus a vendored GoldenLayout bundle are concatenated by embed_report_assets.py into a single <script> block. Each file is wrapped in an IIFE to isolate const/let declarations; exported symbols are forwarded to outer-scope vars. Layout view: Tiles are pre-rendered at a fixed Leaflet zoom level using the existing generateTile() infrastructure. The tile layer returns data URIs from cache instead of creating blob URLs, ensuring compatibility with file:// origins. Leaflet zoom is locked to the cached level; pan is allowed. Timing path overlay: Per-path overlay PNGs are pre-rendered via renderOverlayPng() (colored rects + flight lines on a transparent background). When a timing path is selected, the cache drives a Leaflet ImageOverlay to display the highlight. Display controls, timing tables, slack histograms, and clock tree all work identically to the live viewer since they run the same widget code against cached data. Files: - websocket-manager.js: fromCache(), _cacheRequest(), isStaticMode - main.js: __STATIC_CACHE__ detection, zoom lock, overlay setup - embed_report_assets.py: IIFE wrapping, export-block handling - web.cpp: saveReport() with tile/overlay/JSON cache generation - web.tcl/web.i/web.h: web_save_report command plumbing - tile_generator.cpp/h: renderOverlayPng() for path highlights - websocket-tile-layer.js: data URI support alongside blob URLs - golden-layout.min.js: vendored ESM bundle from esm.sh - BUILD/CMakeLists.txt: embed pipeline with all JS files Signed-off-by: Matt Liberty <mliberty@precisioninno.com>
There was a problem hiding this comment.
Code Review
This pull request introduces the ability to generate a self-contained HTML timing report. This involves embedding JavaScript and CSS assets into a C++ file, serializing various timing data (paths, histograms, filters), and rendering map tiles and path overlays directly into the HTML. The WebSocketManager and related JavaScript components were updated to support a static cache mode for these reports. Review comments highlight the need to value-initialize TileVisibility objects in src/web/src/web.cpp and src/web/src/tile_generator.cpp to prevent non-deterministic behavior. Additionally, the output file for the report should be opened earlier in src/web/src/web.cpp to improve efficiency, and layer names embedded in JavaScript string literals in the same file require proper escaping to avoid invalid JavaScript. Finally, file operations in src/web/src/embed_report_assets.py should explicitly specify UTF-8 encoding for better portability.
|
clang-tidy review says "All clean, LGTM! 👍" |
|
@oharboe please give it a try. |
- Open output file before expensive rendering to fail fast on bad paths - Escape tile cache keys with json_escape() for valid JavaScript output - Specify encoding='utf-8' in embed_report_assets.py for portability Signed-off-by: Matt Liberty <mliberty@precisioninno.com>
|
clang-tidy review says "All clean, LGTM! 👍" |
|
Summary
Add a
web_save_reportTcl command that generates a standalone HTML timing report reusing the exact same JS/CSS as the live web viewer.Type of Change
Impact
Architecture:
The static report substitutes the WebSocket server with a cache
layer. WebSocketManager gains a
fromCache(cache)factory thatserves pre-computed responses from
window.__STATIC_CACHE__embedded in the HTML. Cached request types include tech, bounds,
timing_report, slack_histogram, chart_filters, and tile PNGs.
Uncached requests (select, tcl_eval, etc.) reject gracefully.
All 18 JS source files plus a vendored GoldenLayout bundle are
concatenated by embed_report_assets.py into a single <script>
block. Each file is wrapped in an IIFE to isolate const/let
declarations; exported symbols are forwarded to outer-scope vars.
Layout view:
Tiles are pre-rendered at a fixed Leaflet zoom level using the
existing generateTile() infrastructure. The tile layer returns
data URIs from cache instead of creating blob URLs, ensuring
compatibility with file:// origins. Leaflet zoom is locked to
the cached level; pan is allowed.
Timing path overlay:
Per-path overlay PNGs are pre-rendered via renderOverlayPng()
(colored rects + flight lines on a transparent background).
When a timing path is selected, the cache drives a Leaflet
ImageOverlay to display the highlight.
Display controls, timing tables, slack histograms, and clock tree all work identically to the live viewer since they run the same widget code against cached data.
Files:
Verification
./etc/Build.sh).Related Issues
[Link issues here]