Skip to content

web: add DRC viewer widget#10135

Merged
maliberty merged 1 commit into
The-OpenROAD-Project:masterfrom
The-OpenROAD-Project-staging:web-drc-viewer
Apr 14, 2026
Merged

web: add DRC viewer widget#10135
maliberty merged 1 commit into
The-OpenROAD-Project:masterfrom
The-OpenROAD-Project-staging:web-drc-viewer

Conversation

@openroad-ci

Copy link
Copy Markdown
Member

Summary

Add a DRC (Design Rule Check) viewer to the web UI with:

  • Server-side handlers for categories, markers, report loading, marker updates, and violation highlighting
  • Client-side DRC widget with category selector, violation tree, load/highlight, and file upload dialog
  • DRC overlay rendering in the tile generator
  • C++ and JS tests for the new functionality

Type of Change

  • New feature

Impact

DRC viewer works

Verification

  • I have verified that the local build succeeds (./etc/Build.sh).
  • I have run the relevant tests and they pass.
  • My code follows the repository's formatting guidelines.
  • I have signed my commits (DCO).

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a comprehensive DRC (Design Rule Check) viewer widget for the web-based GUI, mirroring the functionality of the Qt-based DRCWidget. It includes a new frontend DrcWidget for category selection and violation tree navigation, alongside a backend DRCHandler to manage marker data, report loading, and overlay rendering. While the implementation successfully integrates DRC visualization into the tile-based rendering system, several performance and robustness issues were identified. Specifically, toggling category visibility triggers a flood of individual WebSocket requests, and the backend relies on inefficient ODB marker iterations (getAllMarkers) which can cause significant lag in designs with many violations. Additionally, the report loading logic uses a hardcoded category name, which will cause conflicts when attempting to load multiple reports.

Comment thread src/web/src/drc-widget.js Outdated
Comment on lines +2206 to +2225
odb::dbMarker* DRCHandler::findMarkerById(SessionState& state,
odb::dbChip* chip,
int marker_id)
{
std::lock_guard<std::mutex> lock(state.drc_mutex);
if (state.active_drc_category.empty()) {
return nullptr;
}
odb::dbMarkerCategory* category
= chip->findMarkerCategory(state.active_drc_category.c_str());
if (!category) {
return nullptr;
}
for (odb::dbMarker* marker : category->getAllMarkers()) {
if (static_cast<int>(marker->getId()) == marker_id) {
return marker;
}
}
return nullptr;
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

This function is inefficient for two reasons:

  1. It calls category->getAllMarkers(), which in ODB allocates and populates a new std::vector containing all markers in the hierarchy every time it is called. For large reports, this is expensive.
  2. It does not check if marker_id is valid (e.g., -1 for deselect) before performing the linear scan.

Adding an early exit for invalid IDs and considering a more efficient lookup (like a map in SessionState) would improve responsiveness.

odb::dbMarker* DRCHandler::findMarkerById(SessionState& state,
                                          odb::dbChip* chip,
                                          int marker_id)
{
  if (marker_id < 0) {
    return nullptr;
  }
  std::lock_guard<std::mutex> lock(state.drc_mutex);
  if (state.active_drc_category.empty()) {
    return nullptr;
  }
  odb::dbMarkerCategory* category
      = chip->findMarkerCategory(state.active_drc_category.c_str());
  if (!category) {
    return nullptr;
  }
  for (odb::dbMarker* marker : category->getAllMarkers()) {
    if (static_cast<int>(marker->getId()) == marker_id) {
      return marker;
    }
  }
  return nullptr;
}

white_line});
};

for (odb::dbMarker* marker : category->getAllMarkers()) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Calling getAllMarkers() inside refreshDRCOverlay causes a full iteration and vector allocation every time a single marker's visibility is toggled. For reports with a high volume of violations, this will lead to noticeable lag in the UI. Consider caching the marker list in SessionState when a category is first selected.


odb::dbMarkerCategory* category = nullptr;
if (path.ends_with(".rpt") || path.ends_with(".drc")) {
category = odb::dbMarkerCategory::fromTR(chip, "DRC", path);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The category name "DRC" is hardcoded. If a user attempts to load a second DRC report, odb::dbMarkerCategory::fromTR will attempt to create another category with the same name, which will likely fail or throw an exception because ODB requires unique category names at the same level.

Consider using the filename (stem) to generate a unique category name or checking if the category already exists and prompting the user/overwriting it.

@github-actions

Copy link
Copy Markdown
Contributor

clang-tidy review says "All clean, LGTM! 👍"

Add a DRC (Design Rule Check) viewer to the web UI with:
- Server-side handlers for categories, markers, report loading,
  marker updates, and violation highlighting
- Client-side DRC widget with category selector, violation tree,
  load/highlight, and file upload dialog
- DRC overlay rendering in the tile generator
- C++ and JS tests for the new functionality

Signed-off-by: Matt Liberty <mliberty@precisioninno.com>
@github-actions

Copy link
Copy Markdown
Contributor

clang-tidy review says "All clean, LGTM! 👍"

@maliberty maliberty merged commit 45a537e into The-OpenROAD-Project:master Apr 14, 2026
16 checks passed
@maliberty maliberty deleted the web-drc-viewer branch April 14, 2026 21:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants