Skip to content

Commit d743d3e

Browse files
committed
gui: save bpins in tree and limit bounding box calls
Signed-off-by: Peter Gadfort <[email protected]>
1 parent c71fb38 commit d743d3e

File tree

4 files changed

+196
-62
lines changed

4 files changed

+196
-62
lines changed

src/gui/src/renderThread.cpp

Lines changed: 88 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -1265,7 +1265,7 @@ void RenderThread::drawChip(QPainter* painter,
12651265

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

@@ -1438,6 +1438,8 @@ void RenderThread::drawNetTracks(Painter& painter, odb::dbTechLayer* layer)
14381438
}
14391439

14401440
void RenderThread::drawAccessPoints(Painter& painter,
1441+
odb::dbBlock* block,
1442+
const odb::Rect& bounds,
14411443
const std::vector<odb::dbInst*>& insts)
14421444
{
14431445
const int shape_limit = viewer_->shapeSizeLimit();
@@ -1481,11 +1483,18 @@ void RenderThread::drawAccessPoints(Painter& painter,
14811483
}
14821484
}
14831485
}
1484-
for (auto term : viewer_->getBlock()->getBTerms()) {
1485-
if (restart_) {
1486-
break;
1487-
}
1488-
for (auto pin : term->getBPins()) {
1486+
1487+
odb::dbTech* tech = block->getTech();
1488+
for (odb::dbTechLayer* layer : tech->getLayers()) {
1489+
for (const auto& [box, pin] : viewer_->search_.searchBPins(block,
1490+
layer,
1491+
bounds.xMin(),
1492+
bounds.yMin(),
1493+
bounds.xMax(),
1494+
bounds.yMax())) {
1495+
if (restart_) {
1496+
break;
1497+
}
14891498
for (auto ap : pin->getAccessPoints()) {
14901499
draw(ap, {});
14911500
}
@@ -1531,16 +1540,17 @@ void RenderThread::drawModuleView(QPainter* painter,
15311540

15321541
void RenderThread::setupIOPins(odb::dbBlock* block, const odb::Rect& bounds)
15331542
{
1534-
pins_.clear();
15351543
if (!viewer_->options_->areIOPinsVisible()) {
1544+
pin_draw_names_ = false;
15361545
return;
15371546
}
15381547

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

1543-
if (viewer_->options_->areIOPinNamesVisible()) {
1552+
pin_draw_names_ = viewer_->options_->areIOPinNamesVisible();
1553+
if (pin_draw_names_) {
15441554
const double scale_factor
15451555
= 0.02; // 4 Percent of bounds is used to draw pin-markers
15461556
const int die_max_dim
@@ -1551,15 +1561,6 @@ void RenderThread::setupIOPins(odb::dbBlock* block, const odb::Rect& bounds)
15511561
pin_font_ = viewer_->options_->ioPinMarkersFont();
15521562
const QFontMetrics font_metrics(pin_font_);
15531563

1554-
QString largest_text;
1555-
for (auto pin : block->getBTerms()) {
1556-
QString current_text = QString::fromStdString(pin->getName());
1557-
if (font_metrics.boundingRect(current_text).width()
1558-
> font_metrics.boundingRect(largest_text).width()) {
1559-
largest_text = std::move(current_text);
1560-
}
1561-
}
1562-
15631564
const int vertical_gap
15641565
= (viewer_->geometry().height()
15651566
- viewer_->getBounds().dy() * viewer_->pixels_per_dbu_)
@@ -1574,59 +1575,73 @@ void RenderThread::setupIOPins(odb::dbBlock* block, const odb::Rect& bounds)
15741575
- std::ceil(pin_max_size_) * viewer_->pixels_per_dbu_; // in pixels
15751576

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

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

1583-
while (largest_text_width > available_space) {
1584-
if (font_size == minimum_font_size) {
1583+
int largest_text_width = 0;
1584+
std::set<odb::dbBTerm*> checked;
1585+
odb::dbTech* tech = block->getTech();
1586+
for (odb::dbTechLayer* layer : tech->getLayers()) {
1587+
if (restart_) {
1588+
return;
1589+
}
1590+
if (font_size <= minimum_font_size) {
15851591
break;
15861592
}
1587-
font_size -= 1;
1588-
pin_font_.setPointSize(font_size);
1589-
QFontMetrics current_font_metrics(pin_font_);
1590-
largest_text_width
1591-
= current_font_metrics.boundingRect(largest_text).width();
1593+
for (const auto& [box, pin] :
1594+
viewer_->search_.searchBPins(block,
1595+
layer,
1596+
bounds.xMin(),
1597+
bounds.yMin(),
1598+
bounds.xMax(),
1599+
bounds.yMax())) {
1600+
if (restart_) {
1601+
return;
1602+
}
1603+
odb::dbBTerm* bterm = pin->getBTerm();
1604+
if (checked.find(bterm) != checked.end()) {
1605+
continue;
1606+
}
1607+
checked.insert(bterm);
1608+
1609+
QString current_text = QString::fromStdString(pin->getName());
1610+
int text_width = font_metrics.boundingRect(current_text).width();
1611+
if (text_width > largest_text_width) {
1612+
largest_text_width = text_width;
1613+
}
1614+
while (largest_text_width > available_space) {
1615+
if (font_size <= minimum_font_size) {
1616+
break;
1617+
}
1618+
font_size -= 1;
1619+
pin_font_.setPointSize(font_size);
1620+
QFontMetrics current_font_metrics(pin_font_);
1621+
largest_text_width
1622+
= current_font_metrics.boundingRect(current_text).width();
1623+
}
1624+
1625+
if (font_size <= minimum_font_size) {
1626+
break;
1627+
}
1628+
}
15921629
}
15931630

15941631
// draw names of pins when text height is at least 6 pts
15951632
pin_draw_names_ = font_size >= drawing_font_size;
15961633
} else {
15971634
pin_draw_names_ = false;
15981635
}
1599-
1600-
for (odb::dbBTerm* term : block->getBTerms()) {
1601-
if (restart_) {
1602-
break;
1603-
}
1604-
if (!viewer_->isNetVisible(term->getNet())) {
1605-
continue;
1606-
}
1607-
for (odb::dbBPin* pin : term->getBPins()) {
1608-
odb::dbPlacementStatus status = pin->getPlacementStatus();
1609-
if (!status.isPlaced()) {
1610-
continue;
1611-
}
1612-
for (odb::dbBox* box : pin->getBoxes()) {
1613-
if (!box) {
1614-
continue;
1615-
}
1616-
1617-
pins_[box->getTechLayer()].emplace_back(term, box);
1618-
}
1619-
}
1620-
}
16211636
}
16221637

16231638
void RenderThread::drawIOPins(Painter& painter,
16241639
odb::dbBlock* block,
16251640
const odb::Rect& bounds,
16261641
odb::dbTechLayer* layer)
16271642
{
1628-
const auto& pins = pins_[layer];
1629-
if (pins.empty()) {
1643+
if (!viewer_->options_->areIOPinsVisible()
1644+
|| !viewer_->options_->areIOPinNamesVisible()) {
16301645
return;
16311646
}
16321647

@@ -1659,10 +1674,11 @@ void RenderThread::drawIOPins(Painter& painter,
16591674

16601675
// RTree used to search for overlapping shapes and decide if rotation of
16611676
// text is needed.
1662-
bgi::rtree<odb::Rect, bgi::quadratic<16>> pin_text_spec_shapes;
1677+
using PinShapeTree = bgi::rtree<odb::Rect, bgi::quadratic<16>>;
1678+
PinShapeTree pin_text_spec_shapes;
16631679
struct PinText
16641680
{
1665-
odb::Rect rect;
1681+
std::optional<odb::Rect> rect;
16661682
bool can_rotate;
16671683
std::string text;
16681684
odb::Point pt;
@@ -1673,11 +1689,21 @@ void RenderThread::drawIOPins(Painter& painter,
16731689
painter.setPen(layer);
16741690
painter.setBrush(layer);
16751691

1676-
for (const auto& [term, box] : pins) {
1692+
std::vector<odb::Rect> pin_text_spec_shape_rects;
1693+
for (const auto& [box, pin] : viewer_->search_.searchBPins(block,
1694+
layer,
1695+
bounds.xMin(),
1696+
bounds.yMin(),
1697+
bounds.xMax(),
1698+
bounds.yMax())) {
16771699
if (restart_) {
16781700
break;
16791701
}
1680-
const auto pin_dir = term->getIoType();
1702+
1703+
odb::dbBTerm* term = pin->getBTerm();
1704+
if (!viewer_->options_->isNetVisible(term->getNet())) {
1705+
continue;
1706+
}
16811707

16821708
Point pin_center((box->xMin() + box->xMax()) / 2,
16831709
(box->yMin() + box->yMax()) / 2);
@@ -1716,6 +1742,7 @@ void RenderThread::drawIOPins(Painter& painter,
17161742

17171743
// select marker
17181744
const std::vector<Point>* template_points = &bi_marker;
1745+
const auto pin_dir = term->getIoType();
17191746
if (pin_dir == odb::dbIoType::INPUT) {
17201747
template_points = &in_marker;
17211748
} else if (pin_dir == odb::dbIoType::OUTPUT) {
@@ -1724,6 +1751,7 @@ void RenderThread::drawIOPins(Painter& painter,
17241751

17251752
// make new marker based on pin location
17261753
std::vector<Point> marker;
1754+
marker.reserve(template_points->size());
17271755
for (const auto& pt : *template_points) {
17281756
Point new_pt = pt;
17291757
xfm.apply(new_pt);
@@ -1766,13 +1794,15 @@ void RenderThread::drawIOPins(Painter& painter,
17661794
pin_specs.text);
17671795
text_rect.bloat(text_margin, text_rect);
17681796
pin_specs.rect = text_rect;
1769-
pin_text_spec_shapes.insert(pin_specs.rect);
1770-
} else {
1771-
pin_specs.rect = odb::Rect();
1797+
pin_text_spec_shape_rects.push_back(text_rect);
17721798
}
17731799
pin_text_spec.push_back(std::move(pin_specs));
17741800
}
17751801
}
1802+
if (!pin_text_spec_shape_rects.empty()) {
1803+
pin_text_spec_shapes = PinShapeTree(pin_text_spec_shape_rects.begin(),
1804+
pin_text_spec_shape_rects.end());
1805+
}
17761806

17771807
painter.setPen(layer);
17781808
auto color = painter.getPenColor();
@@ -1788,9 +1818,9 @@ void RenderThread::drawIOPins(Painter& painter,
17881818
bool do_rotate = false;
17891819
auto anchor = pin.anchor;
17901820
if (pin.can_rotate) {
1791-
if (pin_text_spec_shapes.qbegin(bgi::intersects(pin.rect)
1821+
if (pin_text_spec_shapes.qbegin(bgi::intersects(*pin.rect)
17921822
&& bgi::satisfies([&](const auto& other) {
1793-
return !bg::equals(other, pin.rect);
1823+
return !bg::equals(other, *pin.rect);
17941824
}))
17951825
!= pin_text_spec_shapes.qend()) {
17961826
// adjust anchor

src/gui/src/renderThread.h

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,8 @@ class RenderThread : public QThread
127127
const odb::Rect& bounds,
128128
odb::dbTechLayer* layer);
129129
void drawAccessPoints(Painter& painter,
130+
odb::dbBlock* block,
131+
const odb::Rect& bounds,
130132
const std::vector<odb::dbInst*>& insts);
131133
void drawRouteGuides(Painter& painter, odb::dbTechLayer* layer);
132134
void drawNetTracks(Painter& painter, odb::dbTechLayer* layer);
@@ -167,9 +169,6 @@ class RenderThread : public QThread
167169
QFont pin_font_;
168170
bool pin_draw_names_ = false;
169171
double pin_max_size_ = 0.0;
170-
std::map<odb::dbTechLayer*,
171-
std::vector<std::pair<odb::dbBTerm*, odb::dbBox*>>>
172-
pins_;
173172
};
174173

175174
} // namespace gui

0 commit comments

Comments
 (0)