Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion src/gui/src/displayControls.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -462,7 +462,7 @@ DisplayControls::DisplayControls(QWidget* parent)
"Vias",
shape_types_srouting,
Qt::Checked);
makeLeafItem(shape_types_.pins, "Pins", shape_types, Qt::Checked);
makeLeafItem(shape_types_.pins, "Pins", shape_types, Qt::Checked, true);
makeLeafItem(shape_types_.pin_names, "Pin Names", shape_types, Qt::Checked);
shape_types_.pins.visible->setData(
QVariant::fromValue(&shape_types_.pin_names), kDisableRowItemIdx);
Expand Down Expand Up @@ -1884,6 +1884,11 @@ bool DisplayControls::areIOPinsVisible() const
return isModelRowVisible(&shape_types_.pins);
}

bool DisplayControls::areIOPinsSelectable() const
{
return isModelRowSelectable(&shape_types_.pins);
}

bool DisplayControls::areIOPinNamesVisible() const
{
return isModelRowVisible(&shape_types_.pin_names);
Expand Down
1 change: 1 addition & 0 deletions src/gui/src/displayControls.h
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,7 @@ class DisplayControls : public QDockWidget,
bool areNonPrefTracksVisible() override;

bool areIOPinsVisible() const override;
bool areIOPinsSelectable() const override;
bool areIOPinNamesVisible() const override;
QFont ioPinMarkersFont() const override;

Expand Down
18 changes: 18 additions & 0 deletions src/gui/src/layoutViewer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -984,6 +984,24 @@ void LayoutViewer::selectAt(odb::Rect region, std::vector<Selected>& selections)
}
}
}

// Look for BPins
if (options_->areIOPinsVisible() && options_->areIOPinsSelectable()) {
for (auto* layer : block->getTech()->getLayers()) {
if (!options_->isVisible(layer)) {
continue;
}
for (const auto& [box, bpin] : search_.searchBPins(block,
layer,
region.xMin(),
region.yMin(),
region.xMax(),
region.yMax(),
shape_limit)) {
selections.push_back(gui_->makeSelected(bpin));
}
}
}
}

if (options_->areRulersVisible() && options_->areRulersSelectable()) {
Expand Down
1 change: 1 addition & 0 deletions src/gui/src/options.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ class Options
virtual bool areNonPrefTracksVisible() = 0;

virtual bool areIOPinsVisible() const = 0;
virtual bool areIOPinsSelectable() const = 0;
virtual bool areIOPinNamesVisible() const = 0;
virtual QFont ioPinMarkersFont() const = 0;

Expand Down
1 change: 1 addition & 0 deletions src/gui/src/painter.h
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,7 @@ class GuiPainter : public Painter
void drawPolygon(const std::vector<odb::Point>& points) override
{
QPolygon poly;
poly.reserve(points.size());
for (const auto& pt : points) {
poly.append(QPoint(pt.x(), pt.y()));
}
Expand Down
153 changes: 92 additions & 61 deletions src/gui/src/renderThread.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,16 @@
#include <exception>
#include <iterator>
#include <mutex>
#include <optional>
#include <set>
#include <string>
#include <utility>
#include <vector>

#include "boost/geometry/geometry.hpp"
#include "boost/geometry/index/parameters.hpp"
#include "boost/geometry/index/predicates.hpp"
#include "boost/geometry/index/rtree.hpp"
#include "gui/gui.h"
#include "layoutViewer.h"
#include "odb/db.h"
Expand Down Expand Up @@ -1265,7 +1269,7 @@ void RenderThread::drawChip(QPainter* painter,

utl::Timer inst_access_points;
if (viewer_->options_->areAccessPointsVisible()) {
drawAccessPoints(gui_painter, insts);
drawAccessPoints(gui_painter, block, bounds, insts);
}
debugPrint(logger_, GUI, "draw", 1, "access points {}", inst_access_points);

Expand Down Expand Up @@ -1438,6 +1442,8 @@ void RenderThread::drawNetTracks(Painter& painter, odb::dbTechLayer* layer)
}

void RenderThread::drawAccessPoints(Painter& painter,
odb::dbBlock* block,
const odb::Rect& bounds,
const std::vector<odb::dbInst*>& insts)
{
const int shape_limit = viewer_->shapeSizeLimit();
Expand Down Expand Up @@ -1481,11 +1487,18 @@ void RenderThread::drawAccessPoints(Painter& painter,
}
}
}
for (auto term : viewer_->getBlock()->getBTerms()) {
if (restart_) {
break;
}
for (auto pin : term->getBPins()) {

odb::dbTech* tech = block->getTech();
for (odb::dbTechLayer* layer : tech->getLayers()) {
for (const auto& [box, pin] : viewer_->search_.searchBPins(block,
layer,
bounds.xMin(),
bounds.yMin(),
bounds.xMax(),
bounds.yMax())) {
if (restart_) {
break;
}
for (auto ap : pin->getAccessPoints()) {
draw(ap, {});
}
Expand Down Expand Up @@ -1531,16 +1544,17 @@ void RenderThread::drawModuleView(QPainter* painter,

void RenderThread::setupIOPins(odb::dbBlock* block, const odb::Rect& bounds)
{
pins_.clear();
if (!viewer_->options_->areIOPinsVisible()) {
pin_draw_names_ = false;
return;
}

const auto die_area = block->getDieArea();
const auto die_width = die_area.dx();
const auto die_height = die_area.dy();

if (viewer_->options_->areIOPinNamesVisible()) {
pin_draw_names_ = viewer_->options_->areIOPinNamesVisible();
if (pin_draw_names_) {
const double scale_factor
= 0.02; // 4 Percent of bounds is used to draw pin-markers
const int die_max_dim
Expand All @@ -1551,15 +1565,6 @@ void RenderThread::setupIOPins(odb::dbBlock* block, const odb::Rect& bounds)
pin_font_ = viewer_->options_->ioPinMarkersFont();
const QFontMetrics font_metrics(pin_font_);

QString largest_text;
for (auto pin : block->getBTerms()) {
QString current_text = QString::fromStdString(pin->getName());
if (font_metrics.boundingRect(current_text).width()
> font_metrics.boundingRect(largest_text).width()) {
largest_text = std::move(current_text);
}
}

const int vertical_gap
= (viewer_->geometry().height()
- viewer_->getBounds().dy() * viewer_->pixels_per_dbu_)
Expand All @@ -1574,59 +1579,71 @@ void RenderThread::setupIOPins(odb::dbBlock* block, const odb::Rect& bounds)
- std::ceil(pin_max_size_) * viewer_->pixels_per_dbu_; // in pixels

int font_size = pin_font_.pointSize();
int largest_text_width = font_metrics.boundingRect(largest_text).width();
const int drawing_font_size = 6; // in points

// when the size is minimum the text won't be drawn
const int minimum_font_size = drawing_font_size - 1;

while (largest_text_width > available_space) {
if (font_size == minimum_font_size) {
int largest_text_width = 0;
std::set<odb::dbBTerm*> checked;
odb::dbTech* tech = block->getTech();
for (odb::dbTechLayer* layer : tech->getLayers()) {
if (restart_) {
return;
}
if (font_size <= minimum_font_size) {
break;
}
font_size -= 1;
pin_font_.setPointSize(font_size);
QFontMetrics current_font_metrics(pin_font_);
largest_text_width
= current_font_metrics.boundingRect(largest_text).width();
for (const auto& [box, pin] :
viewer_->search_.searchBPins(block,
layer,
bounds.xMin(),
bounds.yMin(),
bounds.xMax(),
bounds.yMax())) {
if (restart_) {
return;
}
odb::dbBTerm* bterm = pin->getBTerm();
if (checked.find(bterm) != checked.end()) {
continue;
}
checked.insert(bterm);

QString current_text = QString::fromStdString(pin->getName());
const int text_width = font_metrics.boundingRect(current_text).width();
largest_text_width = std::max(text_width, largest_text_width);
while (largest_text_width > available_space) {
if (font_size <= minimum_font_size) {
break;
}
font_size -= 1;
pin_font_.setPointSize(font_size);
QFontMetrics current_font_metrics(pin_font_);
largest_text_width
= current_font_metrics.boundingRect(current_text).width();
}

if (font_size <= minimum_font_size) {
break;
}
}
}

// draw names of pins when text height is at least 6 pts
pin_draw_names_ = font_size >= drawing_font_size;
} else {
pin_draw_names_ = false;
}

for (odb::dbBTerm* term : block->getBTerms()) {
if (restart_) {
break;
}
if (!viewer_->isNetVisible(term->getNet())) {
continue;
}
for (odb::dbBPin* pin : term->getBPins()) {
odb::dbPlacementStatus status = pin->getPlacementStatus();
if (!status.isPlaced()) {
continue;
}
for (odb::dbBox* box : pin->getBoxes()) {
if (!box) {
continue;
}

pins_[box->getTechLayer()].emplace_back(term, box);
}
}
}
}

void RenderThread::drawIOPins(Painter& painter,
odb::dbBlock* block,
const odb::Rect& bounds,
odb::dbTechLayer* layer)
{
const auto& pins = pins_[layer];
if (pins.empty()) {
if (!viewer_->options_->areIOPinsVisible()
|| !viewer_->options_->areIOPinNamesVisible()) {
return;
Comment on lines +1645 to 1647
Copy link
Contributor

Choose a reason for hiding this comment

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

high

This check incorrectly prevents IO pin markers from being drawn if pin names are not visible. The visibility of pin markers is controlled by areIOPinsVisible(), while the visibility of names is handled by the pin_draw_names_ flag later in the code. The || !viewer_->options_->areIOPinNamesVisible() part of the condition should be removed to ensure markers are drawn whenever IO pins are set to be visible, regardless of the name visibility setting.

  if (!viewer_->options_->areIOPinsVisible()) {

}

Expand Down Expand Up @@ -1659,10 +1676,11 @@ void RenderThread::drawIOPins(Painter& painter,

// RTree used to search for overlapping shapes and decide if rotation of
// text is needed.
bgi::rtree<odb::Rect, bgi::quadratic<16>> pin_text_spec_shapes;
using PinShapeTree = bgi::rtree<odb::Rect, bgi::quadratic<16>>;
PinShapeTree pin_text_spec_shapes;
struct PinText
{
odb::Rect rect;
std::optional<odb::Rect> rect;
bool can_rotate;
std::string text;
odb::Point pt;
Expand All @@ -1673,14 +1691,23 @@ void RenderThread::drawIOPins(Painter& painter,
painter.setPen(layer);
painter.setBrush(layer);

for (const auto& [term, box] : pins) {
std::vector<odb::Rect> pin_text_spec_shape_rects;
for (const auto& [box, pin] : viewer_->search_.searchBPins(block,
layer,
bounds.xMin(),
bounds.yMin(),
bounds.xMax(),
bounds.yMax())) {
if (restart_) {
break;
}
const auto pin_dir = term->getIoType();

Point pin_center((box->xMin() + box->xMax()) / 2,
(box->yMin() + box->yMax()) / 2);
odb::dbBTerm* term = pin->getBTerm();
if (!viewer_->options_->isNetVisible(term->getNet())) {
continue;
}

const Point pin_center = box->getBox().center();

auto dist_to_left = std::abs(box->xMin() - die_area.xMin());
auto dist_to_right = std::abs(box->xMax() - die_area.xMax());
Expand Down Expand Up @@ -1716,6 +1743,7 @@ void RenderThread::drawIOPins(Painter& painter,

// select marker
const std::vector<Point>* template_points = &bi_marker;
const auto pin_dir = term->getIoType();
if (pin_dir == odb::dbIoType::INPUT) {
template_points = &in_marker;
} else if (pin_dir == odb::dbIoType::OUTPUT) {
Expand All @@ -1724,6 +1752,7 @@ void RenderThread::drawIOPins(Painter& painter,

// make new marker based on pin location
std::vector<Point> marker;
marker.reserve(template_points->size());
for (const auto& pt : *template_points) {
Point new_pt = pt;
xfm.apply(new_pt);
Expand Down Expand Up @@ -1766,13 +1795,15 @@ void RenderThread::drawIOPins(Painter& painter,
pin_specs.text);
text_rect.bloat(text_margin, text_rect);
pin_specs.rect = text_rect;
pin_text_spec_shapes.insert(pin_specs.rect);
} else {
pin_specs.rect = odb::Rect();
pin_text_spec_shape_rects.push_back(text_rect);
}
pin_text_spec.push_back(std::move(pin_specs));
}
}
if (!pin_text_spec_shape_rects.empty()) {
pin_text_spec_shapes = PinShapeTree(pin_text_spec_shape_rects.begin(),
pin_text_spec_shape_rects.end());
}

painter.setPen(layer);
auto color = painter.getPenColor();
Expand All @@ -1787,10 +1818,10 @@ void RenderThread::drawIOPins(Painter& painter,

bool do_rotate = false;
auto anchor = pin.anchor;
if (pin.can_rotate) {
if (pin_text_spec_shapes.qbegin(bgi::intersects(pin.rect)
if (pin.can_rotate && pin.rect) {
if (pin_text_spec_shapes.qbegin(bgi::intersects(*pin.rect)
&& bgi::satisfies([&](const auto& other) {
return !bg::equals(other, pin.rect);
return !bg::equals(other, *pin.rect);
}))
!= pin_text_spec_shapes.qend()) {
// adjust anchor
Expand Down
5 changes: 2 additions & 3 deletions src/gui/src/renderThread.h
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,8 @@ class RenderThread : public QThread
const odb::Rect& bounds,
odb::dbTechLayer* layer);
void drawAccessPoints(Painter& painter,
odb::dbBlock* block,
const odb::Rect& bounds,
const std::vector<odb::dbInst*>& insts);
void drawRouteGuides(Painter& painter, odb::dbTechLayer* layer);
void drawNetTracks(Painter& painter, odb::dbTechLayer* layer);
Expand Down Expand Up @@ -167,9 +169,6 @@ class RenderThread : public QThread
QFont pin_font_;
bool pin_draw_names_ = false;
double pin_max_size_ = 0.0;
std::map<odb::dbTechLayer*,
std::vector<std::pair<odb::dbBTerm*, odb::dbBox*>>>
pins_;
};

} // namespace gui
Loading
Loading