On Fri, 7 Jul 2000, Robert S. Maier wrote:

> John, all your alterations to libxmi sound good, given the fact that you're
> using it in the GGI framework.  But you'd better fix the segfaulting
> problem in mi_spans.c.  I've appended instructions at the end of this
> message.  It looks as if you didn't change mi_spans.c too much, actually.

        Fixed and comitted.  Thanks for the help.
 
> As regards backporting from libXMI, I'm interested in miBlendStage.  I plan
> on keeping libxmi's abstract miPixel datatype, but it may be possible for
> me to add some of your code as an install-time option.

        Sounds great.  Let me know if you need anything.
 
> Too bad you didn't like my reentrant arc drawing functions :-(.  

        Stack-based locking is elegant from a design perspective, but it
is usually too hard to optimize for in a heterogeneous target environment
since it's performance characteristics depend heavily on the compiler
used.  It is also an invitation to stack-smashing exploits, and the code
to check for this type of situation further reduces performance.  Mutexes
can be efficiently implemented with a few lines of ASM code in many target
environments, and the responsibility for optimization devolves to LibGG
instead of LibXMI.

> Actually,
> the X11 XDrawArcs() is non-reentrant.  I'm not sure that's documented
> anywhere, but I thought I had better fix it.  

        IIRC, all the X11 functions in the XFree86 code have been made
threadsafe by this point.  Not sure about XGGI though.

> I developed libxmi so that
> I'd be able to rasterize the vector primitives in GNU libplot (see
> http://www.gnu.org/software/plotutils ). 

        I have played around with plotutils a bit.  Good stuff, although I
suggest a clean separation of the LibXMI and plotutils build systems.

> And libplot is supposed to be
> thread-safe, which means that libxmi needed to be reentrant.  Unless
> I wanted to add mutex-based locking to libxmi, redoing XDrawArcs(), which was
> the only offending function, seemed to be the way to go.

        I understand your reasoning now.  I need to follow the 'GGI way'
in my code though, which is to delegate system-specific primitive
operations to lower level libraries wherever possible for the sake of
platform independence and optimizeability.

> It looks as if you've altered the second stage of the libxmi pipeline
> considerably (the miPaintedSet->miCanvas stage, which I wrote from
> scratch), but you've kept the first stage, which does span-generation,
> almost intact.  

        Correct.  When it comes time to write LibXMI target code for
targets which can directly render polygons, arcs, textures, etc., the
cut-ins will be above the first stage.  The span generation code shouldn't
be seen outside of the 'stubs' (default base acceleration) target, since
span rendering can't be efficiently accelerated past the 'draw flat-shaded
spans as hlines' stage.  And since the primary point of LibGGI-family
libraries is to take advantage of native accelerated graphics, I didn't
see much need to do more than cleanly encapsulate your code.

> In fact it looks as if the `ggi_visual_t vis' you added as
> an argument to each internal function could be pruned back.  

        WAY back |->.

> Right now,
> each function in the first stage draws pixels by invoking the macro
> MI_PAINT_SPANS, which doesn't take `vis' as an argument.  Are you planning
> to change that?

        Thank you for reminding me about those macros.  I think that most
of them will vanish eventually.  The compile-time nature of those macros
means that run-time API cutins (which are the core of the GGI library
system) cannot be implemented at those points.  Macro replacement leads to
better compile-time optimization without indirections in the codepath, but
it isn't worth it if it reduces your ability to take advantage of native
accelerations.  Not _that_ big of a deal, given the relative scarcity of
cut-in points as described above, but it is there.
 
> I think it would be great if we could keep the first stage of our
> respective pipelines more or less in sync.  

        For sure.  That is another reason why I didn't change that code
too much.

> If I ever do a libxmi-2.0, this
> is what I'm thinking about adding to the first stage.
> 
> 1. Support for filling compound polygons, i.e., polygons with holes in
>    them.  (Equivalently, the scan-conversion of Postscript-style compound
>    paths; polygonal ones, anyway.)  This wouldn't be too hard.  Right now,
>    Brian Kelleher's code in mi_plycon.c and mi_plygen.c is used for 
>    filling polygons.  The upgrade path from it is pretty clear.

        This is good.  Many GUI elements (window frames are the obvious
ones) could benefit from this capability.  The ability of the target code
to use features such as stencil masks, transparency, texture blending, etc
to accelerate the drawing of compound polygons would be a clear win.

> 2. Sub-pixel placement of polygon vertices.  libxmi (like the original X11
>    code) already has support for filling convex polygons with
>    floating-point, rather than integer, vertex locations.  (See
>    mi_fplycon.c.)  But it's not exposed in the API: it's used only for 
>    drawing the small polygons we call `line caps' and `line joins'.  
>    A non-convex counterpart would need to be written.
> 
>    The hard part would be adding sub-pixel placement to the drawing (rather
>    than filling) functions.  I've looked at miDrawLines, and I don't think
>    it would be easy.  And I hate even to think about adding it to
>    miDrawArcs...

        This would clash with the rest of GGI, which is based on
integer-addressable physical pixels.  The issue of sub-pixel placement
and/or using floats to represent coordinates has popped up on the GGI list
here a few times in the past, but has not been resolved (at least I found
no sign of resolution on the list archives...).  We won't be able to keep
up with the newest generations of video hardware which use floats (or
fixed point numbers, or combinations of the above) for coordinate
representation unless we deal with this issue eventually, though.  And no
matter what we chose, it would require all existing GGI-using code to be
not just rewritten but re-architected as well.  

        I suspect that a "wrapper" extension library will end up being
required here, which would re-implement all GGI (and extension!)
primitives with its own customized coordinate types.  LibGWT currently
implements a similar scheme to thunk the GGI primitives into
window-friendly form.  This would let us use an infinite number of
different types of coordinate representational systems, singly or in
combination.  It would also be a huge amount of work to write, and I'd
just as soon see how well the approach work with LibGWT first.


> 3. Anti-aliased line drawing.  

        This should be doable by using MI_BLEND_ANTIALIASED.  Different
styles of anti-aliasing could be used, as well as nice clean hardware
accelerated antialiasing.

>    Possibly not so hard, but it would mean
>    equipping every pixel in a span with an intensity value.  And the
>    usefulness of the miPaintedSet abstraction would become doubtful, if
>    a huge number of pixel values are generated by every API function.

        Correct.  Spans lose their usefulness when one departs from the
world of flat shaded everything.
 
> 4. Low-level support for gradient fill.  This would be much easier to
>    add; in fact I've already started work on it.  But again, it doesn't
>    fit very well with the miPaintedSet abstraction.

        MI_BLEND_GRADIENT.

> 5. Drawing better arcs.  Let's face it, miDrawArcs is a horror.  (And
>    if you think it looks bad now, you should see what it looked like before
>    I rearranged and commented the code!)  

        |->.

>    It can't be changed too much
>    because that would break pixel-level compatibility with X11.
>    However, it's just barely possible that it could be extended to 
>    generate wide elliptic arcs whose principal axes aren't aligned with the
>    coordinate axes.  As Foley and van Damm point out, the inner and outer
>    boundary of any wide ellipse is an eighth-order curve.  I believe the
>    reason that miDrawArcs isn't worse than it is (!) is that if the axes
>    are aligned, the order is 4 rather than 8.  If I have a _lot_ of time,
>    I'll think about doing the extension.

        Arcs will always be slow without hardware acceleration.
 
Jon

---
'Cloning and the reprogramming of DNA is the first serious step in 
becoming one with God.'
        - Scientist G. Richard Seed

Reply via email to