Extremely bad Cairo performance when drawing many rectangles (C++, gtkmm)

Viewed 254

I have created a CellGrid class for my cellular automaton, and I want to draw that grid using Cairo. The cell_grid.cpp code snippet below is my implementation of the on_draw() function override. For this example, I have set width_ = height_ = 50 and cell_buffer_ is an std::vector with a size of width_ * height_. The vector containts instances of the Cell enum class, which is defined in the cell_grid.hpp snippet below.

The problem is that for some reason, already when drawing just 50*50 or 2 500 rectangles, I get about 2fps. This Cairo implementation is actually a rewrite of an SFML implementation, on which I got about 150fps when drawing 200*100 or 20 000 rectangles. But as far as I know, SFML isn't a viable option in combination with GTK.

cell_grid.hpp snippet

class CellGrid : public Gtk::DrawingArea
{
public:
    enum class Cell : uint8_t //uchar
    {
        Dead = 0,
        Alive = 1
    };
// ...
};

cell_grid.cpp snippet

// ...
bool CellGrid::on_draw(const Cairo::RefPtr<Cairo::Context>& cr)
{
    const Gtk::Allocation allocation = get_allocation();

    const double cell_w = allocation.get_width() / (double)width_;
    const double cell_h = allocation.get_height() / (double)height_;

    for(size_t y = 0; y < height_; y++)
    {
        for(size_t x = 0; x < width_; x++)
        {
            cr->set_line_width(5.0);
            cr->rectangle(x * cell_w, y * cell_h, cell_w, cell_h);
            cr->set_source_rgb(0.5, 0.5, 0.5);
            cr->stroke_preserve();

            cell_buffer_[y * width_ + x] == Cell::Alive ?
                cr->set_source_rgb(1.0, 1.0, 1.0) :
                cr->set_source_rgb(0.1, 0.1, 0.1);

            cr->fill();
        }
    }

    return true;
}
// ...

Thanks in advance!

0 Answers
Related