场景说明:当添加顶点源到rasterizeradd_path接口的时候,实际上需要考虑顶点源可能占用的cell的总数,目前cell_block_limit in agg_rasterizer_cells_aa.h的限制是1024,这种情况下,有必要在添加一定数量的顶点源之后,即使调用render_scanline函数进行渲染到画布上!!该问题已经在项目中重现,不能够说是bug,而是一种设计的策略,避免申请内存不足,同时也避免产生内存碎片。

如下是网址:http://comments.gmane.org/gmane.comp.graphics.agg/5861

for()

{

add_path();

render_scanline();

}

 

for()

{

add_path()

}

render_scanline();

说明:

   I ran into a limit in Antigrain a while back, I think it wasthecell_block_limit in agg_rasterizer_cells_aa.h;if not, it was something verysimilar.

问题说明:

I'm trying to draw a tree with agg.

 

It worked well with a tree with a smallnumber of vertices, but it starts to malfunction if the number of vertices isgreater than 7000.

 

I thought it was a memory problem but gotnothing with valgrind or duma.

 

Is it a bug of agg? or simply i'm doingwrong?

 

My code looks like this:

 

 using pixfmt_type = agg::pixfmt_rgba32;

 using renbase_type = agg::renderer_base<pixfmt_type>;

 using renderer_type =agg::renderer_scanline_aa_solid<renbase_type>;

 using scanline_type = agg::scanline_u8;

 using rasterizer_type = agg::rasterizer_scanline_aa<>;

 

 template <class Ras, class Scanline, class Ren, class Tree>

 void draw_edge(Ras& __ras, Scanline& __sl, Ren& __ren, constTree& __tree)

  {

   __ras.reset();

   for_each_edge_from_tree {

     agg::path_storage path;

     agg::conv_stroke<agg::path_storage> stroke(path);

     stroke.width(1);

 

     path.move_to(from.x(), from.y());

     path.line_to(to.x(),   to.y());

     __ras.add_path(stroke);

    }

   __ren.color(gray);

   agg::render_scanlines(__ras, __sl, __ren);

  }

 

 template <class Ras, class Scanline, class Ren, class Tree>

 void draw_vertex(Ras& __ras, Scanline& __sl, Ren& __ren,const Tree& __tree)

  {

   __ras.reset();

   for_each_vertex_from_tree {

     agg::ellipse ell(state.x(), state.y(), 1.5, 1.5);

     __ras.add_path(ell);

    }

   __ren.color(black);

   agg::render_scanlines(__ras, __sl, __ren);

  }

解决问题的方案:

It seems like a bug of agg, since I'm using64 bit linux system.

 

I changed the drawer to callrender_scalines() for each 1000

add_path()s, and now it works well with alarge number of edges.

 

template <class Ras, class Scanline,class Ren, class Tree>

 void draw_edge(Ras& __ras, Scanline& __sl, Ren& __ren, constTree& __tree)

  {

   __ren.color(gray);

   __ras.reset();

 

   std::size_t count = 0;

   for_each_edge_from_tree {

      agg::path_storage path;

     agg::conv_stroke<agg::path_storage> stroke(path);

     stroke.width(1);

 

     path.move_to(from.x(), from.y());

     path.line_to(to.x(),   to.y());

     __ras.add_path(stroke);

 

     if(++count > 1000) {

       agg::render_scanlines(__ras, __sl, __ren);

       __ras.reset();

       count = 0;

     }

    }

   agg::render_scanlines(__ras, __sl, __ren);

  }

 

一些解释:

a) I would try to run under 64-bit OS firstto make sure there is enough memory

 

b) I would put a breakpoint into therasterizer cells allocator. Maybe it returns NULL and agg just silently passes(didn't check, can't tell, just where I would start)

 

The problem:

 

Agg doesn't merge cells while rendering,basically each cell (you can see a cell as an anti-aliased pixel) generated bythe rasterizer is added to a cell array. This means that the rasterizer itselfneeds more and more memory if you start adding vertices without sweeping (sweepis the last rasterization step which fills up spans into a scanline container).

摘自:http://comments.gmane.org/gmane.comp.graphics.agg/5861