diff --git a/src/db/db/dbLayout.cc b/src/db/db/dbLayout.cc index 31eb1ea41..4c629a94d 100644 --- a/src/db/db/dbLayout.cc +++ b/src/db/db/dbLayout.cc @@ -355,6 +355,7 @@ Layout::Layout (db::Manager *manager) m_properties_repository (this), m_guiding_shape_layer (-1), m_waste_layer (-1), + m_error_layer (-1), m_do_cleanup (false), m_editable (db::default_editable_mode ()) { @@ -372,6 +373,7 @@ Layout::Layout (bool editable, db::Manager *manager) m_properties_repository (this), m_guiding_shape_layer (-1), m_waste_layer (-1), + m_error_layer (-1), m_do_cleanup (false), m_editable (editable) { @@ -393,6 +395,7 @@ Layout::Layout (const db::Layout &layout) m_properties_repository (this), m_guiding_shape_layer (-1), m_waste_layer (-1), + m_error_layer (-1), m_do_cleanup (false), m_editable (layout.m_editable) { @@ -458,6 +461,7 @@ Layout::clear () m_guiding_shape_layer = -1; m_waste_layer = -1; + m_error_layer = -1; m_lib_proxy_map.clear (); m_meta_info.clear (); @@ -474,6 +478,7 @@ Layout::operator= (const Layout &d) m_guiding_shape_layer = d.m_guiding_shape_layer; m_waste_layer = d.m_waste_layer; + m_error_layer = d.m_error_layer; m_editable = d.m_editable; m_pcell_ids = d.m_pcell_ids; @@ -1946,6 +1951,19 @@ Layout::get_layer (const db::LayerProperties &lp) } } +unsigned int +Layout::error_layer () const +{ + if (m_error_layer < 0) { + // create the waste layer (since that layer is cached we can do + // this in a "const" fashion. + db::Layout *self = const_cast (this); + self->m_error_layer = (int) self->insert_special_layer (db::LayerProperties ("WASTE")); + } + + return (unsigned int) m_error_layer; +} + unsigned int Layout::waste_layer () const { @@ -2555,8 +2573,15 @@ Layout::restore_proxies (ImportLayerMapping *layer_mapping) } } + bool needs_cleanup = false; for (std::vector::const_iterator p = cold_proxies.begin (); p != cold_proxies.end (); ++p) { - recover_proxy_as ((*p)->cell_index (), (*p)->context_info (), layer_mapping); + if (recover_proxy_as ((*p)->cell_index (), (*p)->context_info (), layer_mapping)) { + needs_cleanup = true; + } + } + + if (needs_cleanup) { + cleanup (); } } diff --git a/src/db/db/dbLayout.h b/src/db/db/dbLayout.h index 69e243b2a..a647e0495 100644 --- a/src/db/db/dbLayout.h +++ b/src/db/db/dbLayout.h @@ -1709,6 +1709,13 @@ public: */ unsigned int waste_layer () const; + /** + * @brief Gets the error layer + * + * The error layer is used to display error messages. + */ + unsigned int error_layer () const; + /** * @brief Set the properties for a specified layer */ @@ -1891,6 +1898,7 @@ private: lib_proxy_map m_lib_proxy_map; int m_guiding_shape_layer; int m_waste_layer; + int m_error_layer; bool m_do_cleanup; bool m_editable; meta_info m_meta_info; diff --git a/src/db/db/dbLibraryManager.cc b/src/db/db/dbLibraryManager.cc index 140c4d12f..80eca6f39 100644 --- a/src/db/db/dbLibraryManager.cc +++ b/src/db/db/dbLibraryManager.cc @@ -183,7 +183,6 @@ LibraryManager::register_lib (Library *library) if (found) { // substitute old_lib = m_libs [l->second]; - m_libs [l->second] = 0; m_lib_by_name.erase (l); } @@ -193,10 +192,19 @@ LibraryManager::register_lib (Library *library) } if (old_lib) { + old_lib->remap_to (library); + + { + // reset the library pointer only after "remap_to" -> this function may need lib_by_id. + tl::MutexLocker locker (&m_lock); + m_libs [old_lib->get_id ()] = 0; + } + old_lib->set_id (std::numeric_limits::max ()); delete old_lib; old_lib = 0; + } // take care of cold referrers - these may not get valid diff --git a/src/db/db/dbLibraryProxy.cc b/src/db/db/dbLibraryProxy.cc index 8401acc48..35e30077f 100644 --- a/src/db/db/dbLibraryProxy.cc +++ b/src/db/db/dbLibraryProxy.cc @@ -159,6 +159,11 @@ LibraryProxy::get_layer_indices (db::Layout &layout, db::ImportLayerMapping *lay // map guiding shape layer m_layer_indices.push_back ((int) layout.guiding_shape_layer ()); + } else if (i == lib->layout ().error_layer ()) { + + // map guiding shape layer + m_layer_indices.push_back ((int) layout.error_layer ()); + } else if (! lib->layout ().is_valid_layer (i) || cell.bbox (i).empty ()) { m_layer_indices.push_back (-1); diff --git a/src/db/db/dbPCellVariant.cc b/src/db/db/dbPCellVariant.cc index a0a5e72d5..3f8f7bdee 100644 --- a/src/db/db/dbPCellVariant.cc +++ b/src/db/db/dbPCellVariant.cc @@ -160,10 +160,8 @@ PCellVariant::update (ImportLayerMapping *layer_mapping) m_display_name = header->declaration ()->get_display_name (m_parameters); } catch (tl::Exception &ex) { tl::error << ex.msg (); - if (! layer_ids.empty ()) { - // put error messages into layout as text objects - shapes (layer_ids [0]).insert (db::Text (ex.msg (), db::Trans ())); - } + // put error messages into layout as text objects on error layer + shapes (layout ()->error_layer ()).insert (db::Text (ex.msg (), db::Trans ())); } // produce the shape parameters on the guiding shape layer so they can be edited diff --git a/src/edt/edt/edtEditorOptionsPages.cc b/src/edt/edt/edtEditorOptionsPages.cc index 9380e9eda..3f33fd310 100644 --- a/src/edt/edt/edtEditorOptionsPages.cc +++ b/src/edt/edt/edtEditorOptionsPages.cc @@ -607,7 +607,7 @@ EditorOptionsInst::setup (lay::Dispatcher *root) if (m_cv_index >= 0 && view ()->cellview (m_cv_index).is_valid ()) { techname = view ()->cellview (m_cv_index)->tech_name (); } - mp_ui->lib_cbx->set_technology_filter (techname, ! techname.empty ()); + mp_ui->lib_cbx->set_technology_filter (techname, true); // cell name std::string s; diff --git a/src/laybasic/laybasic/LayoutViewConfigPage2a.ui b/src/laybasic/laybasic/LayoutViewConfigPage2a.ui index 0864a2e01..2f4e6911a 100644 --- a/src/laybasic/laybasic/LayoutViewConfigPage2a.ui +++ b/src/laybasic/laybasic/LayoutViewConfigPage2a.ui @@ -17,7 +17,7 @@ 6 - + 9 @@ -29,7 +29,7 @@ true - + 9 @@ -47,7 +47,7 @@ 6 - + 0 @@ -84,7 +84,7 @@ 6 - + 0 @@ -122,7 +122,7 @@ 6 - + 0 @@ -220,13 +220,13 @@ - Show PCell guiding shapes + Show PCell guiding and error shapes true - + 9 diff --git a/src/laybasic/laybasic/layMarker.cc b/src/laybasic/laybasic/layMarker.cc index 4fd53b135..ac08e6d95 100644 --- a/src/laybasic/laybasic/layMarker.cc +++ b/src/laybasic/laybasic/layMarker.cc @@ -160,6 +160,21 @@ void render_cell_inst (const db::Layout &layout, const db::CellInstArray &inst, } + { + // render error layer + + db::RecursiveShapeIterator shapes (layout, cell, layout.error_layer ()); + while (! shapes.at_end ()) { + + for (db::CellInstArray::iterator arr = inst.begin (); ! arr.at_end (); ++arr) { + r.draw (*shapes, tr * inst.complex_trans (*arr) * shapes.trans (), fill, contour, 0 /*use vertex for origin*/, text); + } + + ++shapes; + + } + } + // render the origins if (render_origins && vertex) { diff --git a/src/laybasic/laybasic/layRedrawThreadWorker.cc b/src/laybasic/laybasic/layRedrawThreadWorker.cc index e9844b9b7..b63e15b2a 100644 --- a/src/laybasic/laybasic/layRedrawThreadWorker.cc +++ b/src/laybasic/laybasic/layRedrawThreadWorker.cc @@ -359,7 +359,7 @@ RedrawThreadWorker::perform_task (tl::Task *task) } } - // draw the guiding shapes + // draw the guiding and error shapes for (std::set< std::pair >::const_iterator b = m_box_variants.begin (); b != m_box_variants.end (); ++b) { const lay::CellView &cv = m_cellviews [b->second]; @@ -374,8 +374,6 @@ RedrawThreadWorker::perform_task (tl::Task *task) // draw one level more to show the guiding shapes as part of the instance m_to_level += 1; // TODO: modifying this basic setting is a hack! - m_layer = mp_layout->guiding_shape_layer (); - // configure renderer .. mp_renderer->draw_texts (m_text_visible); mp_renderer->draw_properties (false); @@ -384,13 +382,30 @@ RedrawThreadWorker::perform_task (tl::Task *task) mp_renderer->set_font (db::Font (m_text_font)); mp_renderer->apply_text_trans (m_apply_text_trans); + bool f = m_text_lazy_rendering; + try { + + m_text_lazy_rendering = false; + + m_layer = mp_layout->guiding_shape_layer (); iterate_variants (m_redraw_region, cv.cell_index (), trans, &RedrawThreadWorker::draw_layer); iterate_variants (text_redraw_regions, cv.cell_index (), trans, &RedrawThreadWorker::draw_text_layer); + + m_layer = mp_layout->error_layer (); + iterate_variants (m_redraw_region, cv.cell_index (), trans, &RedrawThreadWorker::draw_layer); + iterate_variants (text_redraw_regions, cv.cell_index (), trans, &RedrawThreadWorker::draw_text_layer); + + m_text_lazy_rendering = f; m_to_level -= 1; + } catch (...) { + + m_text_lazy_rendering = f; m_to_level -= 1; + throw; + } }