mirror of https://github.com/KLayout/klayout.git
Reworked the XOR progress UI for better performance.
This commit is contained in:
parent
083e1d75e9
commit
62b59fe71c
|
|
@ -32,6 +32,46 @@
|
|||
namespace ext
|
||||
{
|
||||
|
||||
static inline void merge (size_t &a, size_t b)
|
||||
{
|
||||
if (a == missing_in_a || a == missing_in_a) {
|
||||
// leave a
|
||||
} else if (b == missing_in_a || b == missing_in_a) {
|
||||
a = b;
|
||||
} else {
|
||||
a += b;
|
||||
}
|
||||
}
|
||||
|
||||
static void merge (std::vector<std::vector<size_t> > &a, const std::vector<std::vector<size_t> > &b)
|
||||
{
|
||||
if (a.size () < b.size ()) {
|
||||
a.resize (b.size (), std::vector<size_t> ());
|
||||
}
|
||||
|
||||
std::vector<std::vector<size_t> >::iterator ia = a.begin ();
|
||||
for (std::vector<std::vector<size_t> >::const_iterator ib = b.begin (); ib != b.end (); ++ib, ++ia) {
|
||||
if (ia->size () < ib->size ()) {
|
||||
ia->resize (ib->size (), 0);
|
||||
}
|
||||
std::vector<size_t>::iterator ja = ia->begin ();
|
||||
for (std::vector<size_t>::const_iterator jb = ib->begin (); jb != ib->end (); ++jb, ++ja) {
|
||||
merge (*ja, *jb);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static size_t sum (const std::vector<std::vector<size_t> > &b)
|
||||
{
|
||||
size_t n = 0;
|
||||
for (std::vector<std::vector<size_t> >::const_iterator i = b.begin (); i != b.end (); ++i) {
|
||||
for (std::vector<size_t>::const_iterator j = i->begin (); j != i->end (); ++j) {
|
||||
n += *j;
|
||||
}
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------------------------------
|
||||
// The progress widget class
|
||||
|
||||
|
|
@ -78,7 +118,7 @@ public:
|
|||
return QSize (int (m_tolerance_labels.size ()) * (m_column_width + m_spacing) + m_first_column_width, (m_line_height + m_spacing) * m_max_lines + m_font_height * 2 + m_spacing);
|
||||
}
|
||||
|
||||
void set_results (double dbu, int nx, int ny, const std::map<std::pair<size_t, size_t>, std::map<std::pair<db::LayerProperties, db::Coord>, size_t> > &results, const std::map<db::LayerProperties, size_t> &count_per_layer, const std::vector<db::Coord> &tolerances)
|
||||
void set_results (double dbu, int nx, int ny, const std::map<std::pair<db::LayerProperties, db::Coord>, std::vector<std::vector<size_t> > > &results, const std::map<db::LayerProperties, size_t> &count_per_layer, const std::vector<db::Coord> &tolerances)
|
||||
{
|
||||
m_labels.clear ();
|
||||
m_layer_labels.clear ();
|
||||
|
|
@ -135,45 +175,51 @@ public:
|
|||
|
||||
size_t tot_count = 0;
|
||||
|
||||
for (std::map<std::pair<size_t, size_t>, std::map<std::pair<db::LayerProperties, db::Coord>, size_t> >::const_iterator r = results.begin (); r != results.end (); ++r) {
|
||||
std::map<std::pair<db::LayerProperties, db::Coord>, std::vector<std::vector<size_t> > >::const_iterator rm = results.find (std::make_pair (c->first, *t));
|
||||
if (rm != results.end ()) {
|
||||
|
||||
const std::map<std::pair<db::LayerProperties, db::Coord>, size_t> &rm = r->second;
|
||||
const std::vector<std::vector<size_t> > &counts = rm->second;
|
||||
tot_count = sum (counts);
|
||||
|
||||
std::map<std::pair<db::LayerProperties, db::Coord>, size_t>::const_iterator rl = rm.find (std::make_pair (c->first, *t));
|
||||
if (rl != rm.end ()) {
|
||||
int ix = 0;
|
||||
for (std::vector<std::vector<size_t> >::const_iterator c = counts.begin (); c != counts.end (); ++c, ++ix) {
|
||||
|
||||
tot_count += rl->second;
|
||||
int iy = 0;
|
||||
for (std::vector<size_t>::const_iterator cc = c->begin (); cc != c->end (); ++cc, ++iy) {
|
||||
|
||||
QImage *img = 0;
|
||||
if (rl->second == 0) {
|
||||
img = &m_green_images.back ().back ();
|
||||
} else if (rl->second == missing_in_a) {
|
||||
m_blue_images.back ().back ().fill (Qt::white);
|
||||
} else if (rl->second == missing_in_b) {
|
||||
m_yellow_images.back ().back ().fill (Qt::white);
|
||||
} else {
|
||||
img = &m_red_images.back ().back ();
|
||||
}
|
||||
|
||||
if (img) {
|
||||
if (nx == 0 || ny == 0) {
|
||||
img->fill (Qt::white);
|
||||
QImage *img = 0;
|
||||
if (*cc == 0) {
|
||||
img = &m_green_images.back ().back ();
|
||||
} else if (*cc == missing_in_a) {
|
||||
m_blue_images.back ().back ().fill (Qt::white);
|
||||
} else if (*cc == missing_in_b) {
|
||||
m_yellow_images.back ().back ().fill (Qt::white);
|
||||
} else {
|
||||
img = &m_red_images.back ().back ();
|
||||
}
|
||||
|
||||
int ix = r->first.first;
|
||||
int iy = r->first.second;
|
||||
if (img) {
|
||||
|
||||
int y2 = m_pixmap_size - 1 - (iy * m_pixmap_size + m_pixmap_size / 2) / ny;
|
||||
int y1 = m_pixmap_size - 1 - ((iy + 1) * m_pixmap_size + m_pixmap_size / 2) / ny;
|
||||
int x1 = (ix * m_pixmap_size + m_pixmap_size / 2) / nx;
|
||||
int x2 = ((ix + 1) * m_pixmap_size + m_pixmap_size / 2) / nx;
|
||||
if (nx == 0 || ny == 0) {
|
||||
|
||||
img->fill (Qt::white);
|
||||
|
||||
} else {
|
||||
|
||||
int y2 = m_pixmap_size - 1 - (iy * m_pixmap_size + m_pixmap_size / 2) / ny;
|
||||
int y1 = m_pixmap_size - 1 - ((iy + 1) * m_pixmap_size + m_pixmap_size / 2) / ny;
|
||||
int x1 = (ix * m_pixmap_size + m_pixmap_size / 2) / nx;
|
||||
int x2 = ((ix + 1) * m_pixmap_size + m_pixmap_size / 2) / nx;
|
||||
|
||||
// "draw" the field
|
||||
for (int y = y1; y <= y2 && y >= 0 && y < m_pixmap_size; ++y) {
|
||||
*((uint32_t *) img->scanLine (y)) &= (((1 << x1) - 1) | ~((1 << (x2 + 1)) - 1));
|
||||
}
|
||||
|
||||
// "draw" the field
|
||||
for (int y = y1; y <= y2 && y >= 0 && y < m_pixmap_size; ++y) {
|
||||
*((uint32_t *) img->scanLine (y)) &= (((1 << x1) - 1) | ~((1 << (x2 + 1)) - 1));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -333,17 +379,26 @@ void XORProgress::render_progress (QWidget *widget) const
|
|||
}
|
||||
}
|
||||
|
||||
void XORProgress::set_results (double dbu, int nx, int ny, const std::map<std::pair<size_t, size_t>, std::map<std::pair<db::LayerProperties, db::Coord>, size_t> > &results, const std::map<db::LayerProperties, size_t> &count_per_layer, const std::vector<db::Coord> &tol)
|
||||
void XORProgress::configure (double dbu, int nx, int ny, const std::vector<db::Coord> &tol)
|
||||
{
|
||||
if (m_count_per_layer != count_per_layer) {
|
||||
if (m_tolerances != tol || fabs (m_dbu - dbu) > 1e-6 || m_nx != nx || m_ny != ny) {
|
||||
m_dbu = dbu;
|
||||
m_nx = nx;
|
||||
m_ny = ny;
|
||||
m_results = results;
|
||||
m_tolerances = tol;
|
||||
m_count_per_layer = count_per_layer;
|
||||
m_needs_update = true;
|
||||
}
|
||||
}
|
||||
|
||||
void XORProgress::merge_results (std::map<std::pair<db::LayerProperties, db::Coord>, std::vector<std::vector<size_t> > > &results)
|
||||
{
|
||||
for (std::map<std::pair<db::LayerProperties, db::Coord>, std::vector<std::vector<size_t> > >::const_iterator r = results.begin (); r != results.end (); ++r) {
|
||||
m_needs_update = true;
|
||||
merge (m_results [r->first], r->second);
|
||||
merge (m_count_per_layer [r->first.first], sum (r->second));
|
||||
}
|
||||
|
||||
results.clear ();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -54,10 +54,12 @@ public:
|
|||
|
||||
virtual QWidget *progress_widget () const;
|
||||
virtual void render_progress (QWidget *widget) const;
|
||||
void set_results (double dbu, int nx, int ny, const std::map<std::pair<size_t, size_t>, std::map<std::pair<db::LayerProperties, db::Coord>, size_t> > &results, const std::map<db::LayerProperties, size_t> &count_per_layer, const std::vector<db::Coord> &tol);
|
||||
|
||||
void configure (double dbu, int nx, int ny, const std::vector<db::Coord> &tol);
|
||||
void merge_results (std::map<std::pair<db::LayerProperties, db::Coord>, std::vector<std::vector<size_t> > > &results);
|
||||
|
||||
private:
|
||||
std::map<std::pair<size_t, size_t>, std::map<std::pair<db::LayerProperties, db::Coord>, size_t> > m_results;
|
||||
std::map<std::pair<db::LayerProperties, db::Coord>, std::vector<std::vector<size_t> > > m_results;
|
||||
std::map<db::LayerProperties, size_t> m_count_per_layer;
|
||||
std::vector<db::Coord> m_tolerances;
|
||||
bool m_needs_update;
|
||||
|
|
|
|||
|
|
@ -390,10 +390,8 @@ public:
|
|||
m_rdb (rdb),
|
||||
m_rdb_cell (rdb_cell),
|
||||
m_progress (0),
|
||||
m_update_results (false),
|
||||
m_nx (0), m_ny (0)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
output_mode_t output_mode () const
|
||||
|
|
@ -457,16 +455,21 @@ public:
|
|||
void add_results (const db::LayerProperties &lp, db::Coord tol, size_t n, size_t ix, size_t iy)
|
||||
{
|
||||
QMutexLocker locker (&m_mutex);
|
||||
if (n == missing_in_a || n == missing_in_b) {
|
||||
m_results [std::make_pair (ix, iy)][std::make_pair (lp, tol)] = n;
|
||||
m_count_per_layer [lp] = n;
|
||||
} else {
|
||||
// NOTE: we will not get a "normal" n after missing_in_a or missing_in_b
|
||||
m_results [std::make_pair (ix, iy)][std::make_pair (lp, tol)] += n;
|
||||
m_count_per_layer [lp] += n;
|
||||
|
||||
std::vector<std::vector<size_t> > &cc = m_results [std::make_pair (lp, tol)];
|
||||
if (cc.size () <= ix) {
|
||||
cc.resize (ix + 1, std::vector<size_t> ());
|
||||
}
|
||||
if (cc [ix].size () <= iy) {
|
||||
cc [ix].resize (iy + 1, 0);
|
||||
}
|
||||
|
||||
m_update_results = true;
|
||||
if (n == missing_in_a || n == missing_in_b) {
|
||||
cc[ix][iy] = n;
|
||||
} else {
|
||||
// NOTE: we will not get a "normal" n after missing_in_a or missing_in_b
|
||||
cc[ix][iy] += n;
|
||||
}
|
||||
}
|
||||
|
||||
void update_progress (XORProgress &progress)
|
||||
|
|
@ -475,10 +478,8 @@ public:
|
|||
{
|
||||
QMutexLocker locker (&m_mutex);
|
||||
p = m_progress;
|
||||
if (m_update_results) {
|
||||
progress.set_results (m_dbu, m_nx, m_ny, m_results, m_count_per_layer, m_tolerances);
|
||||
m_update_results = false;
|
||||
}
|
||||
progress.configure (m_dbu, m_nx, m_ny, m_tolerances);
|
||||
progress.merge_results (m_results);
|
||||
}
|
||||
|
||||
progress.set (p, true /*force yield*/);
|
||||
|
|
@ -550,10 +551,8 @@ private:
|
|||
unsigned int m_progress;
|
||||
QMutex m_mutex;
|
||||
std::string m_result_string;
|
||||
bool m_update_results;
|
||||
size_t m_nx, m_ny;
|
||||
std::map<std::pair<size_t, size_t>, std::map<std::pair<db::LayerProperties, db::Coord>, size_t> > m_results;
|
||||
std::map<db::LayerProperties, size_t> m_count_per_layer;
|
||||
std::map<std::pair<db::LayerProperties, db::Coord>, std::vector<std::vector<size_t> > > m_results;
|
||||
};
|
||||
|
||||
class XORTask
|
||||
|
|
|
|||
Loading…
Reference in New Issue