From: Douglas Gregor (gregod_at_[hidden])
Date: 2002-05-06 23:51:24


On Sunday 05 May 2002 04:02 pm, you wrote:
> 1. Inclusion any non-trivial algorithm into the pipeline (that supports
> only InputIterator for some reason) will degenerate the whole
> pipeline to InputIterator. Since any pipeline will most probably
> contain at least one such an algorithm, the only type of iterators
> available will be Input one. So, in general there's no need to
> implemen other types, such as RandomAccessIterator.

That's fine, and I expected as much.
 
> 2. I told you not all the truth :-)
[snip]
> Any VertexSource is a multi-path, which consists of a number of
> paths, separated with flag pathflag_stop. It's not quite a vector
> of paths, because in case of a storage it uses only one memory
> pool for all the paths. It allows to reduce the memory overhead and
> to avoid reallocations (class path_storage never reallocs memory).
> The reset_iterator method has an integer argument which has a
> sematics of an abstract ID. When we form the path somehow,
> we in parallel create a vector of attributes and then, when rendering,
> use this argument as an ID to associate a particular path with its
> attribute. I'll illustrate this idea with the SVG syntax:
[snip]

This isn't much different from a more container-like interface where begin()
and end() take the integer argument, e.g.,

struct VertexSource {
  typedef /* implementation-defined */ iterator;

  iterator begin(int pathnum);
  iterator end(int pathnum);
  int numPaths();
};

As for the storage, the iterators can hold pointers to storage in the
VertexSource, or storage can be inside the iterator. Am I correct in assuming
that rendering is a parallelizable process? If it is, then the interface I
gave is perhaps more suitable to parallelization, because if numPaths()
returns N paths, N threads could be spawned and the i-th thread is given the
vertex iterator range [begin(i), end(i)) to render.

> I tried to create as simple interface as possible with keeping
> good flexibility. The example looks very simple, however, it's not
> easy to render it. The basic renderer can draw only polygons and does
> not have a possibility to render strokes, so, we have to use more than
> one pipeline to process it.
>
> struct path_attr
> {
> bool fill;
> bool stroke;
> agg::color fill_color;
> agg::color stroke_color;
> double stroke_width;
> agg::affine_matrix transform;
> unsigned path_id; // This is that very ID mentioned above
> };
>
[snip]
> The key moment is that we can easily afford to use a generic container to
> store the attributes while using it for vertices can seriously affect the
> performance and/or result in great memory overhead with endless
> reallocations. So, I used a custom container with custom access
> mechanism and custom memory allocation strategy.

This depends on the generic container you are using. Sure, std::vector<void*>
or std::list<boost::any> will be horrible, but what about
  boost::tuple<bool, bool, agg::color, agg::color>
shouldn't impose much overhead.

> Maybe graphics is too specific area for BOOST to be generalized in a
> way all other parts are.

I think the area of graphics (at least, this type of graphics) is
generalizable, and I think you have the rendering pipeline idea right.
However, I think there is benefit in reusing existing interfaces (e.g., the
InputIterator concept) for two reasons:
  - The iterator concepts are used in many STL algorithms. Perhaps some of
these algorithms can find reuse in the area of graphics? (Code reuse)
  - The iterator concepts are well-understood, so someone unfamiliar with AGG
can understand its concepts (especially the notion of a pipeline) quickly by
using preexisting knowledge. (Knowledge reuse)

I can't think of any argument against an iterator-centric interface for
vertex sources and transformations, but I'm neither familiar with AGG nor
with graphics.

> I admit I'm not very experienced in BOOST libraries and this is why I'm
> looking for help from BOOST gurus, because it'll take a lot of time
> for me to completely integrate AGG with BOOST. Besides, I wouldn't
> like to restrict AGG with BOOST only, and so, I'd like the low level of
> AGG to be independent on BOOST.

Boost is just a collection of libraries. AGG can become one of those
libraries without depending on any other Boost library.

        Doug