场景说明:当添加顶点源到rasterizer的add_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