Netlist browser: fixed a segfault on 'unload all'

This commit is contained in:
Matthias Koefferlein 2019-04-28 22:57:06 +02:00
parent 0983ebc854
commit e661bac0a7
10 changed files with 146 additions and 84 deletions

View File

@ -514,6 +514,18 @@ void DeepShapeStore::make_layout (unsigned int layout_index, const db::Recursive
m_layout_map[std::make_pair (si, trans)] = layout_index;
}
static unsigned int init_layer (db::Layout &layout, const db::RecursiveShapeIterator &si)
{
unsigned int layer_index = layout.insert_layer ();
if (si.layout () && si.layer () < si.layout ()->layers ()) {
// try to preserve the layer properties
layout.set_properties (layer_index, si.layout ()->get_properties (si.layer ()));
}
return layer_index;
}
DeepLayer DeepShapeStore::create_polygon_layer (const db::RecursiveShapeIterator &si, double max_area_ratio, size_t max_vertex_count, const db::ICplxTrans &trans)
{
if (max_area_ratio == 0.0) {
@ -528,7 +540,7 @@ DeepLayer DeepShapeStore::create_polygon_layer (const db::RecursiveShapeIterator
db::Layout &layout = m_layouts[layout_index]->layout;
db::HierarchyBuilder &builder = m_layouts[layout_index]->builder;
unsigned int layer_index = layout.insert_layer ();
unsigned int layer_index = init_layer (layout, si);
builder.set_target_layer (layer_index);
// The chain of operators for producing clipped and reduced polygon references
@ -571,7 +583,7 @@ DeepLayer DeepShapeStore::create_custom_layer (const db::RecursiveShapeIterator
db::Layout &layout = m_layouts[layout_index]->layout;
db::HierarchyBuilder &builder = m_layouts[layout_index]->builder;
unsigned int layer_index = layout.insert_layer ();
unsigned int layer_index = init_layer (layout, si);
builder.set_target_layer (layer_index);
// Build the working hierarchy from the recursive shape iterator
@ -624,7 +636,7 @@ DeepLayer DeepShapeStore::create_edge_layer (const db::RecursiveShapeIterator &s
db::Layout &layout = m_layouts[layout_index]->layout;
db::HierarchyBuilder &builder = m_layouts[layout_index]->builder;
unsigned int layer_index = layout.insert_layer ();
unsigned int layer_index = init_layer (layout, si);
builder.set_target_layer (layer_index);
// The chain of operators for producing edges
@ -654,7 +666,7 @@ DeepLayer DeepShapeStore::create_edge_pair_layer (const db::RecursiveShapeIterat
db::Layout &layout = m_layouts[layout_index]->layout;
db::HierarchyBuilder &builder = m_layouts[layout_index]->builder;
unsigned int layer_index = layout.insert_layer ();
unsigned int layer_index = init_layer (layout, si);
builder.set_target_layer (layer_index);
// The chain of operators for producing the edge pairs

View File

@ -52,7 +52,7 @@ namespace db
* description(<text>) - an arbitrary description text [short key: B]
* unit(<unit>) - specifies the database unit [short key: U]
* top(<circuit>) - specifies the name of the top circuit [short key: W]
* layer(<name>) - define a layer [short key: L]
* layer(<name> <source-spec>?) - define a layer [short key: L]
* connect(<layer1> <name> ...) - connects layer1 with the following layers [short key: C]
* global(<layer> <net-name> ...)
* - connects the shapes of the layer with the given global

View File

@ -201,9 +201,21 @@ void LayoutToNetlistStandardReader::do_read (db::LayoutToNetlist *l2n)
} else if (test (skeys::layer_key) || test (lkeys::layer_key)) {
Brace br (this);
std::string layer;
std::string layer, lspec;
read_word_or_quoted (layer);
delete l2n->make_layer (layer);
if (br) {
read_word_or_quoted (lspec);
}
std::auto_ptr<db::Region> region (l2n->make_layer (layer));
if (! lspec.empty ()) {
unsigned int layer_index = l2n->layer_of (*region);
tl::Extractor ex (lspec.c_str ());
db::LayerProperties lp;
lp.read (ex);
l2n->internal_layout ()->set_properties (layer_index, lp);
}
br.done ();
} else if (test (skeys::class_key) || test (lkeys::class_key)) {

View File

@ -123,7 +123,12 @@ void std_writer_impl<Keys>::write (const db::LayoutToNetlist *l2n)
*mp_stream << endl << "# Mask layers" << endl;
}
for (db::Connectivity::layer_iterator l = l2n->connectivity ().begin_layers (); l != l2n->connectivity ().end_layers (); ++l) {
*mp_stream << Keys::layer_key << "(" << name_for_layer (l2n, *l) << ")" << endl;
*mp_stream << Keys::layer_key << "(" << name_for_layer (l2n, *l);
db::LayerProperties lp = ly->get_properties (*l);
if (! lp.is_null ()) {
*mp_stream << " " << tl::to_word_or_quoted_string (lp.to_string ());
}
*mp_stream << ")" << endl;
}
if (! Keys::is_short ()) {

View File

@ -1754,8 +1754,17 @@ NetlistBrowserPage::set_highlight_style (QColor color, int line_width, int verte
void
NetlistBrowserPage::set_view (lay::LayoutView *view, unsigned int cv_index)
{
if (mp_view) {
mp_view->layer_list_changed_event.remove (this, &NetlistBrowserPage::layer_list_changed);
}
mp_view = view;
m_cv_index = cv_index;
if (mp_view) {
mp_view->layer_list_changed_event.add (this, &NetlistBrowserPage::layer_list_changed);
}
update_highlights ();
}
@ -1777,6 +1786,12 @@ NetlistBrowserPage::set_max_shape_count (size_t max_shape_count)
}
}
void
NetlistBrowserPage::layer_list_changed (int)
{
update_highlights ();
}
void
NetlistBrowserPage::anchor_clicked (const QString &a)
{
@ -2052,29 +2067,26 @@ NetlistBrowserPage::show_all (bool f)
void
NetlistBrowserPage::set_l2ndb (db::LayoutToNetlist *database)
{
if (database != mp_database.get ()) {
mp_database.reset (database);
clear_markers ();
highlight_nets (std::vector<const db::Net *> ());
if (! database) {
directory_tree->setModel (0);
return;
}
// NOTE: with the tree as the parent, the tree will take over ownership of the model
NetlistBrowserModel *new_model = new NetlistBrowserModel (directory_tree, database, &m_colorizer);
directory_tree->setModel (new_model);
connect (directory_tree->selectionModel (), SIGNAL (currentChanged (const QModelIndex &, const QModelIndex &)), this, SLOT (current_index_changed (const QModelIndex &)));
connect (directory_tree->selectionModel (), SIGNAL (selectionChanged (const QItemSelection &, const QItemSelection &)), this, SLOT (net_selection_changed ()));
directory_tree->header ()->setSortIndicatorShown (true);
find_text->setText (QString ());
mp_database.reset (database);
clear_markers ();
highlight_nets (std::vector<const db::Net *> ());
if (! database) {
delete directory_tree->model ();
directory_tree->setModel (0);
return;
}
// NOTE: with the tree as the parent, the tree will take over ownership of the model
NetlistBrowserModel *new_model = new NetlistBrowserModel (directory_tree, database, &m_colorizer);
directory_tree->setModel (new_model);
connect (directory_tree->selectionModel (), SIGNAL (currentChanged (const QModelIndex &, const QModelIndex &)), this, SLOT (current_index_changed (const QModelIndex &)));
connect (directory_tree->selectionModel (), SIGNAL (selectionChanged (const QItemSelection &, const QItemSelection &)), this, SLOT (net_selection_changed ()));
directory_tree->header ()->setSortIndicatorShown (true);
find_text->setText (QString ());
}
void
@ -2203,11 +2215,22 @@ NetlistBrowserPage::update_highlights ()
return;
}
const db::Layout &original_layout = mp_view->cellview (m_cv_index)->layout ();
const db::Layout *layout = mp_database->internal_layout ();
if (! layout) {
return;
}
// a map of display properties vs. layer properties
std::map<db::LayerProperties, lay::LayerPropertiesConstIterator> display_by_lp;
for (lay::LayerPropertiesConstIterator lp = mp_view->begin_layers (); ! lp.at_end (); ++lp) {
if (! lp->has_children () && lp->cellview_index () == int (m_cv_index) && lp->layer_index () >= 0 && (unsigned int) lp->layer_index () < original_layout.layers ()) {
display_by_lp.insert (std::make_pair (original_layout.get_properties (lp->layer_index ()), lp));
}
}
// @@@std::map<unsigned int, std::vector<db::DCplxTrans> > tv_by_layer = mp_view->cv_transform_variants_by_layer (m_cv_index);
std::vector<db::DCplxTrans> tv = mp_view->cv_transform_variants (m_cv_index);
@ -2228,7 +2251,8 @@ NetlistBrowserPage::update_highlights ()
const db::Connectivity &conn = mp_database->connectivity ();
for (db::Connectivity::layer_iterator layer = conn.begin_layers (); layer != conn.end_layers (); ++layer) {
// @@@ TODO: how to get the original layer?
db::LayerProperties lp = layout->get_properties (*layer);
std::map<db::LayerProperties, lay::LayerPropertiesConstIterator>::const_iterator display = display_by_lp.find (lp);
db::recursive_cluster_shape_iterator<db::PolygonRef> shapes (mp_database->net_clusters (), *layer, cell_index, cluster_id);
while (! shapes.at_end ()) {
@ -2241,25 +2265,32 @@ NetlistBrowserPage::update_highlights ()
mp_markers.push_back (new lay::Marker (mp_view, m_cv_index));
mp_markers.back ()->set (*shapes, shapes.trans (), tv);
#if 0
// @@@
if (! original.at_end ()) {
mp_markers.back ()->set_line_width (original->width (true));
if (net_color.isValid ()) {
mp_markers.back ()->set_color (net_color);
mp_markers.back ()->set_frame_color (net_color);
} else if (display != display_by_lp.end ()) {
mp_markers.back ()->set_line_width (display->second->width (true));
mp_markers.back ()->set_vertex_size (1);
mp_markers.back ()->set_dither_pattern (original->dither_pattern (true));
if (view ()->background_color ().green () < 128) {
mp_markers.back ()->set_color (original->eff_fill_color_brighter (true, (m_marker_intensity * 255) / 100));
mp_markers.back ()->set_frame_color (original->eff_frame_color_brighter (true, (m_marker_intensity * 255) / 100));
mp_markers.back ()->set_dither_pattern (display->second->dither_pattern (true));
if (mp_view->background_color ().green () < 128) {
mp_markers.back ()->set_color (display->second->eff_fill_color_brighter (true, (m_marker_intensity * 255) / 100));
mp_markers.back ()->set_frame_color (display->second->eff_frame_color_brighter (true, (m_marker_intensity * 255) / 100));
} else {
mp_markers.back ()->set_color (original->eff_fill_color_brighter (true, (-m_marker_intensity * 255) / 100));
mp_markers.back ()->set_frame_color (original->eff_frame_color_brighter (true, (-m_marker_intensity * 255) / 100));
mp_markers.back ()->set_color (display->second->eff_fill_color_brighter (true, (-m_marker_intensity * 255) / 100));
mp_markers.back ()->set_frame_color (display->second->eff_frame_color_brighter (true, (-m_marker_intensity * 255) / 100));
}
} else {
// fallback color
QColor net_color = mp_view->background_color ().green () < 128 ? QColor (Qt::white) : QColor (Qt::black);
mp_markers.back ()->set_color (net_color);
mp_markers.back ()->set_frame_color (net_color);
}
#endif
// @@@
mp_markers.back ()->set_color (net_color);
mp_markers.back ()->set_frame_color (net_color);
// @@@
if (m_marker_line_width >= 0) {
mp_markers.back ()->set_line_width (m_marker_line_width);

View File

@ -214,7 +214,8 @@ private:
*/
class NetlistBrowserPage
: public QFrame,
public Ui::NetlistBrowserPage
public Ui::NetlistBrowserPage,
public tl::Object
{
Q_OBJECT
@ -340,6 +341,7 @@ private:
void highlight_nets (const std::vector<const db::Net *> &nets);
std::vector<const db::Net *> selected_nets ();
void set_color_for_selected_nets (const QColor &color);
void layer_list_changed (int);
};
} // namespace lay

View File

@ -9,15 +9,15 @@ unit(0.001)
# This section lists the mask layers (drawing or derived) and their connections.
# Mask layers
layer(poly)
layer(poly_lbl)
layer(diff_cont)
layer(poly_cont)
layer(metal1)
layer(metal1_lbl)
layer(via1)
layer(metal2)
layer(metal2_lbl)
layer(poly '3/0')
layer(poly_lbl '3/1')
layer(diff_cont '4/0')
layer(poly_cont '5/0')
layer(metal1 '6/0')
layer(metal1_lbl '6/1')
layer(via1 '7/0')
layer(metal2 '8/0')
layer(metal2_lbl '8/1')
layer(psd)
layer(nsd)

View File

@ -10,16 +10,16 @@ unit(0.001)
# Mask layers
layer(rbulk)
layer(nwell)
layer(poly)
layer(poly_lbl)
layer(diff_cont)
layer(poly_cont)
layer(metal1)
layer(metal1_lbl)
layer(via1)
layer(metal2)
layer(metal2_lbl)
layer(nwell '1/0')
layer(poly '3/0')
layer(poly_lbl '3/1')
layer(diff_cont '4/0')
layer(poly_cont '5/0')
layer(metal1 '6/0')
layer(metal1_lbl '6/1')
layer(via1 '7/0')
layer(metal2 '8/0')
layer(metal2_lbl '8/1')
layer(ntie)
layer(psd)
layer(ptie)

View File

@ -2,16 +2,16 @@
W(RINGO)
U(0.001)
L(rbulk)
L(nwell)
L(poly)
L(poly_lbl)
L(diff_cont)
L(poly_cont)
L(metal1)
L(metal1_lbl)
L(via1)
L(metal2)
L(metal2_lbl)
L(nwell '1/0')
L(poly '3/0')
L(poly_lbl '3/1')
L(diff_cont '4/0')
L(poly_cont '5/0')
L(metal1 '6/0')
L(metal1_lbl '6/1')
L(via1 '7/0')
L(metal2 '8/0')
L(metal2_lbl '8/1')
L(ntie)
L(psd)
L(ptie)

View File

@ -1,15 +1,15 @@
#%l2n-klayout
W(RINGO)
U(0.001)
L(poly)
L(poly_lbl)
L(diff_cont)
L(poly_cont)
L(metal1)
L(metal1_lbl)
L(via1)
L(metal2)
L(metal2_lbl)
L(poly '3/0')
L(poly_lbl '3/1')
L(diff_cont '4/0')
L(poly_cont '5/0')
L(metal1 '6/0')
L(metal1_lbl '6/1')
L(via1 '7/0')
L(metal2 '8/0')
L(metal2_lbl '8/1')
L(psd)
L(nsd)
C(poly poly poly_lbl poly_cont)