设计理念
path_storage专门为了减少内存碎片而设计出来的。她采用了块分配
(block allocations)的机制而不是重新分配(reallocates)内存。是否意味着
path_storage可能是由多个块内存组成的,没有详细查看源码!!
应用场景
agg::path_storage作为路径存储器,意味着可以存储多个轨迹路径,
而不单单是一条直线。尝试解释,确实很难。除非有深刻的理解和应用。
例如,现在有三组轨迹路径,任何一条轨迹路径都有很多条直线(可以相连
或者离散)或者各种形状的线条组成。我们可以尝试调用start_new_path
来将这三组轨迹路径整合到一个路径存储器中,知道大家是没有时间查看
源码的,可以说agg::path_storage实际上充当了一个STL中vector数组
的功能,会动态的分配内存和必要时进行动态增长,对于嵌入式的设备,
开销很大。作者也说最好是一个单实例。但是问题随之而来,怎么才能够
绘制某一组轨迹路径,比如第二段。start_new_path会返回即将添加组的
顶点编号,当需要渲染这一组轨迹路径的时候,可以通过ras.add_path的
第二个参数传递进去,一般情况下,都是直接使用ras.add_path(path);
比如start_new_path返回值是100,就可以通过这样子调用:
ras.add_path(path, 100);基本的问题就是需要保存每一段轨迹路径的开始
顶点编号。她的优点在于对于固定的轨迹路径组,提供了很好的容器支持。
源码摘录
template<class VC>
unsigned path_base<VC>::start_new_path()
{
if(!is_stop(m_vertices.last_command()))
{
m_vertices.add_vertex(0.0, 0.0, path_cmd_stop);
}
return m_vertices.total_vertices();
}
源码剖析
start_new_path会为当前的路径提供一个停止的标志。当使用vertex函数
遍历到该停止的标志就会终止添加顶点。然后返回下一个路径开始的索引编号。
agg::path_storage作为路径存储器,意味着可以存储多个轨迹路径,而不单单是一条直线
其中提供了函数start_new_path,可以继续加入其他的路径。
例子
不使用:
agg::path_storage ps;
ps.move_to(20,40);
ps.line_to(40,60);
ps.move_to(120,140);
ps.line_to(140,160);
agg::conv_stroke<agg::path_storage> stroke(ps);
ras.add_path(stroke);
采用情况:
agg::path_storage ps;
int path1 = ps.start_new_path();
ps.move_to(20,40);
ps.line_to(40,60);
int path2 = ps.start_new_path();
ps.move_to(120,140);
ps.line_to(140,160);
agg::conv_stroke<agg::path_storage> stroke(ps);
ras.add_path(stroke,path1);//渲染第一组路径
ras.add_path(stroke,path2);//渲染第二组路径
//ras.add_path(stroke);//尝试替换上面的,对比看看
总结
优点:最小的内存开销而且是最快的。
缺点:无法轻易的移除存储器中的中间部分的路径。没有提供任何的方法,你想啊,这些点都是放在一块连续的内存中的,你可以修改,但是怎么移除,难!
进一步的优化:
根据具体的使用场景,如果预先知道顶点的个数,重构存储器再好不过。你需要做的工作就是重构一下path_storage的容器。查看定义:
typedefpath_base<vertex_block_storage<double> > path_storage;
需要替换掉vertex_block_storage.