Skip to content

Commit 7d543e4

Browse files
authored
Merge pull request #9148 from gadfort/speedup-pins
gui: speedup handling of bpins
2 parents 5d9366d + 5214a73 commit 7d543e4

File tree

9 files changed

+227
-66
lines changed

9 files changed

+227
-66
lines changed

src/gui/src/displayControls.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -462,7 +462,7 @@ DisplayControls::DisplayControls(QWidget* parent)
462462
"Vias",
463463
shape_types_srouting,
464464
Qt::Checked);
465-
makeLeafItem(shape_types_.pins, "Pins", shape_types, Qt::Checked);
465+
makeLeafItem(shape_types_.pins, "Pins", shape_types, Qt::Checked, true);
466466
makeLeafItem(shape_types_.pin_names, "Pin Names", shape_types, Qt::Checked);
467467
shape_types_.pins.visible->setData(
468468
QVariant::fromValue(&shape_types_.pin_names), kDisableRowItemIdx);
@@ -1884,6 +1884,11 @@ bool DisplayControls::areIOPinsVisible() const
18841884
return isModelRowVisible(&shape_types_.pins);
18851885
}
18861886

1887+
bool DisplayControls::areIOPinsSelectable() const
1888+
{
1889+
return isModelRowSelectable(&shape_types_.pins);
1890+
}
1891+
18871892
bool DisplayControls::areIOPinNamesVisible() const
18881893
{
18891894
return isModelRowVisible(&shape_types_.pin_names);

src/gui/src/displayControls.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,7 @@ class DisplayControls : public QDockWidget,
218218
bool areNonPrefTracksVisible() override;
219219

220220
bool areIOPinsVisible() const override;
221+
bool areIOPinsSelectable() const override;
221222
bool areIOPinNamesVisible() const override;
222223
QFont ioPinMarkersFont() const override;
223224

src/gui/src/layoutViewer.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -984,6 +984,24 @@ void LayoutViewer::selectAt(odb::Rect region, std::vector<Selected>& selections)
984984
}
985985
}
986986
}
987+
988+
// Look for BPins
989+
if (options_->areIOPinsVisible() && options_->areIOPinsSelectable()) {
990+
for (auto* layer : block->getTech()->getLayers()) {
991+
if (!options_->isVisible(layer)) {
992+
continue;
993+
}
994+
for (const auto& [box, bpin] : search_.searchBPins(block,
995+
layer,
996+
region.xMin(),
997+
region.yMin(),
998+
region.xMax(),
999+
region.yMax(),
1000+
shape_limit)) {
1001+
selections.push_back(gui_->makeSelected(bpin));
1002+
}
1003+
}
1004+
}
9871005
}
9881006

9891007
if (options_->areRulersVisible() && options_->areRulersSelectable()) {

src/gui/src/options.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ class Options
5656
virtual bool areNonPrefTracksVisible() = 0;
5757

5858
virtual bool areIOPinsVisible() const = 0;
59+
virtual bool areIOPinsSelectable() const = 0;
5960
virtual bool areIOPinNamesVisible() const = 0;
6061
virtual QFont ioPinMarkersFont() const = 0;
6162

src/gui/src/painter.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,7 @@ class GuiPainter : public Painter
135135
void drawPolygon(const std::vector<odb::Point>& points) override
136136
{
137137
QPolygon poly;
138+
poly.reserve(points.size());
138139
for (const auto& pt : points) {
139140
poly.append(QPoint(pt.x(), pt.y()));
140141
}

src/gui/src/renderThread.cpp

Lines changed: 92 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,16 @@
1313
#include <exception>
1414
#include <iterator>
1515
#include <mutex>
16+
#include <optional>
1617
#include <set>
1718
#include <string>
1819
#include <utility>
1920
#include <vector>
2021

2122
#include "boost/geometry/geometry.hpp"
23+
#include "boost/geometry/index/parameters.hpp"
24+
#include "boost/geometry/index/predicates.hpp"
25+
#include "boost/geometry/index/rtree.hpp"
2226
#include "gui/gui.h"
2327
#include "layoutViewer.h"
2428
#include "odb/db.h"
@@ -1265,7 +1269,7 @@ void RenderThread::drawChip(QPainter* painter,
12651269

12661270
utl::Timer inst_access_points;
12671271
if (viewer_->options_->areAccessPointsVisible()) {
1268-
drawAccessPoints(gui_painter, insts);
1272+
drawAccessPoints(gui_painter, block, bounds, insts);
12691273
}
12701274
debugPrint(logger_, GUI, "draw", 1, "access points {}", inst_access_points);
12711275

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

14401444
void RenderThread::drawAccessPoints(Painter& painter,
1445+
odb::dbBlock* block,
1446+
const odb::Rect& bounds,
14411447
const std::vector<odb::dbInst*>& insts)
14421448
{
14431449
const int shape_limit = viewer_->shapeSizeLimit();
@@ -1481,11 +1487,18 @@ void RenderThread::drawAccessPoints(Painter& painter,
14811487
}
14821488
}
14831489
}
1484-
for (auto term : viewer_->getBlock()->getBTerms()) {
1485-
if (restart_) {
1486-
break;
1487-
}
1488-
for (auto pin : term->getBPins()) {
1490+
1491+
odb::dbTech* tech = block->getTech();
1492+
for (odb::dbTechLayer* layer : tech->getLayers()) {
1493+
for (const auto& [box, pin] : viewer_->search_.searchBPins(block,
1494+
layer,
1495+
bounds.xMin(),
1496+
bounds.yMin(),
1497+
bounds.xMax(),
1498+
bounds.yMax())) {
1499+
if (restart_) {
1500+
break;
1501+
}
14891502
for (auto ap : pin->getAccessPoints()) {
14901503
draw(ap, {});
14911504
}
@@ -1531,16 +1544,17 @@ void RenderThread::drawModuleView(QPainter* painter,
15311544

15321545
void RenderThread::setupIOPins(odb::dbBlock* block, const odb::Rect& bounds)
15331546
{
1534-
pins_.clear();
15351547
if (!viewer_->options_->areIOPinsVisible()) {
1548+
pin_draw_names_ = false;
15361549
return;
15371550
}
15381551

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

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

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-
15631568
const int vertical_gap
15641569
= (viewer_->geometry().height()
15651570
- viewer_->getBounds().dy() * viewer_->pixels_per_dbu_)
@@ -1574,59 +1579,71 @@ void RenderThread::setupIOPins(odb::dbBlock* block, const odb::Rect& bounds)
15741579
- std::ceil(pin_max_size_) * viewer_->pixels_per_dbu_; // in pixels
15751580

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

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

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

15941633
// draw names of pins when text height is at least 6 pts
15951634
pin_draw_names_ = font_size >= drawing_font_size;
15961635
} else {
15971636
pin_draw_names_ = false;
15981637
}
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-
}
16211638
}
16221639

16231640
void RenderThread::drawIOPins(Painter& painter,
16241641
odb::dbBlock* block,
16251642
const odb::Rect& bounds,
16261643
odb::dbTechLayer* layer)
16271644
{
1628-
const auto& pins = pins_[layer];
1629-
if (pins.empty()) {
1645+
if (!viewer_->options_->areIOPinsVisible()
1646+
|| !viewer_->options_->areIOPinNamesVisible()) {
16301647
return;
16311648
}
16321649

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

16601677
// RTree used to search for overlapping shapes and decide if rotation of
16611678
// text is needed.
1662-
bgi::rtree<odb::Rect, bgi::quadratic<16>> pin_text_spec_shapes;
1679+
using PinShapeTree = bgi::rtree<odb::Rect, bgi::quadratic<16>>;
1680+
PinShapeTree pin_text_spec_shapes;
16631681
struct PinText
16641682
{
1665-
odb::Rect rect;
1683+
std::optional<odb::Rect> rect;
16661684
bool can_rotate;
16671685
std::string text;
16681686
odb::Point pt;
@@ -1673,14 +1691,23 @@ void RenderThread::drawIOPins(Painter& painter,
16731691
painter.setPen(layer);
16741692
painter.setBrush(layer);
16751693

1676-
for (const auto& [term, box] : pins) {
1694+
std::vector<odb::Rect> pin_text_spec_shape_rects;
1695+
for (const auto& [box, pin] : viewer_->search_.searchBPins(block,
1696+
layer,
1697+
bounds.xMin(),
1698+
bounds.yMin(),
1699+
bounds.xMax(),
1700+
bounds.yMax())) {
16771701
if (restart_) {
16781702
break;
16791703
}
1680-
const auto pin_dir = term->getIoType();
16811704

1682-
Point pin_center((box->xMin() + box->xMax()) / 2,
1683-
(box->yMin() + box->yMax()) / 2);
1705+
odb::dbBTerm* term = pin->getBTerm();
1706+
if (!viewer_->options_->isNetVisible(term->getNet())) {
1707+
continue;
1708+
}
1709+
1710+
const Point pin_center = box->getBox().center();
16841711

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

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

17251753
// make new marker based on pin location
17261754
std::vector<Point> marker;
1755+
marker.reserve(template_points->size());
17271756
for (const auto& pt : *template_points) {
17281757
Point new_pt = pt;
17291758
xfm.apply(new_pt);
@@ -1766,13 +1795,15 @@ void RenderThread::drawIOPins(Painter& painter,
17661795
pin_specs.text);
17671796
text_rect.bloat(text_margin, text_rect);
17681797
pin_specs.rect = text_rect;
1769-
pin_text_spec_shapes.insert(pin_specs.rect);
1770-
} else {
1771-
pin_specs.rect = odb::Rect();
1798+
pin_text_spec_shape_rects.push_back(text_rect);
17721799
}
17731800
pin_text_spec.push_back(std::move(pin_specs));
17741801
}
17751802
}
1803+
if (!pin_text_spec_shape_rects.empty()) {
1804+
pin_text_spec_shapes = PinShapeTree(pin_text_spec_shape_rects.begin(),
1805+
pin_text_spec_shape_rects.end());
1806+
}
17761807

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

17881819
bool do_rotate = false;
17891820
auto anchor = pin.anchor;
1790-
if (pin.can_rotate) {
1791-
if (pin_text_spec_shapes.qbegin(bgi::intersects(pin.rect)
1821+
if (pin.can_rotate && pin.rect) {
1822+
if (pin_text_spec_shapes.qbegin(bgi::intersects(*pin.rect)
17921823
&& bgi::satisfies([&](const auto& other) {
1793-
return !bg::equals(other, pin.rect);
1824+
return !bg::equals(other, *pin.rect);
17941825
}))
17951826
!= pin_text_spec_shapes.qend()) {
17961827
// 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)