Re: Signal dispatching slowed down after upgrade



2011/2/14 BALLABIO GERARDO <GERARDO BALLABIO esterni gruppo mps it>:
> Hi all,
> in the last weekend I upgraded my computer to the new stable version of Debian (version 6.0.0, released a few days ago). After the upgrade, a gtkmm program of mine has become less responsive to the point of being barely usable. Apparently the dispatching of signals is now much slower than it used to be, and when a lot of them are connected (in my program there are more than 100), it becomes very noticeable.

The slowdown is not caused by signal emission, but by modify_bg. If
you write a custom expose handler that draws the cells, the updates
are instantaneous. See the attached file.

Regards, Krzysztof
#include <gtkmm.h>

class Cell : public Gtk::EventBox
{
private:
  int number;
protected:
  sigc::signal<void, int> activate;
  virtual bool on_enter_notify_event(GdkEventCrossing *event)
  { activate.emit(number); return true; }
  virtual bool on_expose_event(GdkEventExpose *event)
  {
    Glib::RefPtr<Gdk::Window> window = get_window();
    if (!window) return true;

    Cairo::RefPtr<Cairo::Context> cr = window->create_cairo_context();
    if(event) {
        cr->rectangle(event->area.x,     event->area.y,
                      event->area.width, event->area.height);
        cr->clip();
    }

    switch(state) {
      case 0:
        cr->set_source_rgb(1, 0, 0);
        break;
      case 1:
        cr->set_source_rgb(0, 1, 0);
        break;
      default:
        cr->set_source_rgb(0, 0, 1);
        break;
    }
    cr->paint();

    return true;
  }
public:
  Cell() {
    add_events(Gdk::ENTER_NOTIFY_MASK | Gdk::EXPOSURE_MASK);
    set_app_paintable(true);
  }
  void set_number(int n) { number = n; }
  sigc::signal<void, int> &signal_activate() { return activate; }
  int state;
};

class MainWindow : public Gtk::Window
{
private:
  static const int rows = 20, cols = 20, cellsize = 20;

  Gtk::Table table;
  Cell cell[rows*cols];
  int active;

  void set_active(int n);
public:
  MainWindow();
};

MainWindow::MainWindow()
{
  set_default_size(cols * cellsize, rows * cellsize);
  add(table);
  table.set_homogeneous(true);
  table.set_row_spacings(2);
  table.set_col_spacings(2);

  // set up cells
  for (int i=0; i<rows*cols; ++i)
    {
      cell[i].set_number(i);
      int irow = i / rows, icol = i % rows;
      table.attach(cell[i], irow, irow + 1, icol, icol + 1);

      // connect signal
      cell[i].signal_activate().connect
	(sigc::mem_fun(*this, &MainWindow::set_active));
    }
  set_active(-rows - 1); // start with no active row nor column

  show_all_children();
}

void MainWindow::set_active(int n)
{
  active = n;

  // update cell colors
  const Gdk::Color colors[] = {
    Gdk::Color("red"), Gdk::Color("green"), Gdk::Color("blue"),
  };
  int arow = active / rows, acol = active % rows;
  for (int i=0; i<rows*cols; ++i)
    {
      int irow = i / rows, icol = i % rows,
	col = (irow == arow ? 1 : 0) + (icol == acol ? 1 : 0);
      
      cell[i].state = col;
      //cell[i].queue_draw();
    }

  // redraw
  queue_draw();
}

int main(int argc, char *argv[])
{
  Gtk::Main kit(argc, argv);
  MainWindow window;
  Gtk::Main::run(window);

  return 0;
}


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]