Notes on cairo/win32



[ Most of this is generic Cairo stuff, but I also refer quite a bit
  to GTK+ in this mail because that's the use case I'm thinking about ]

I spent most of today looking at Cairo on win32; didn't actually write
any code for Cairo/Win32, but did a fair bit of experimentation with
build environments and GDI+.

There are basically four approaches we could take to implementing
Cairo on Windows.

 1. Implement it mostly as images on top of GDI. There are a few
    things we can use GDI for ... over alpha blending of images, solid
    fills, and (Over) text, but we'd mostly have a software only
    implementation.

    Because so much has to be done in software, we'd likely want to
    use DIB's for offscreen surfaces, so even the GDI based operations
    would be in software.

    Being mostly in software doesn't mean horribly slow, though
    performance on older machines won't be wonderful.

    (Note that with the GTK+ Windows theme engine, a lot of the
    drawing will be done native and not go through Cairo.)

 2. Implement it on top of GDI+. The GDI+ model is somewhat richer
    than the GDI model... it adds antialiased primitives, and "Over"
    compositing of those primitives, though considerable amounts of
    the Cairo API would have to be done manually.

    Clips are bilevel in GDI+, and compositing is only "Over". It's
    not clear how you would do something like draw an image clipped by
    an antialiased mask; quite possibly it just isn't possible.

    So, like the GDI backend, the GDI+ backend would have to be able
    to fall back to software in almost any place.

    The early trapezoidization in Cairo might pose problems for this
    backend ... it's not clear that taking a path, converting it to a
    set of trapezoids, converting it back to a path, then rasterizing
    however GDI+ does internally is going to be especially efficient.

    Perhaps the biggest advantage of using GDI+ over GDI is that for
    the subset of uses that can be fully reprented within the GDI+
    model, Windows would be able to do an optimal printing.

    Fallbacks for screen display are straightforward; when an
    operation is encountered that can't be handled by GDI+, we just
    need to get the pixels from the destination, draw, and put
    back. Much like we do for xlib currently. If we use DIB's for
    GdkPixmap when appropriate (always?) then efficiency should be OK.

    Fallbacks for printers are harder, much as has been discussed
    earlier for PS output. I think a metafile based approach is right;
    record the drawing operations for a page keeping track of what
    areas will need fallbacks, and when the page is shown, redo the
    drawing based on what was calculated earlier.

    There are some build issues with using GDI+ ... GDI+ is not yet
    part of the basic API supported by mingw, and while I was able to
    get GDI examples to build with the GDI+ headers from the Win32
    Platform/SDK with a little work, the platform/SDK is a huge
    download to require. (Though only needed for people building from
    source.) There's an incomplete patch that was posted to the mingw
    list for adding it, but that's a long ways from working, and a
    clean room reimplementation of the GDI+ wrapper classes looks
    conceptually hard to do. Perhaps the best approach would be to use
    the "flat" C API, while that's not supported by Microsoft, the API
    is locked since the C++ API is just a set of header files around
    it. There is no C++ code actually in the DLL. Redoing the header
    files for the flat API should be pretty easy.

    Finally, GDI+ is not natively present on Windows98, Windows/ME or
    Win2k. There's a redistributable version of the DLL that it
    *might* be possible to bundle into an downloadable installer if
    you put an extra click-through screen ahead of it.

 3. Implement it on top of OpenGL. OpenGL is a much closer fit to
    hardware capabilities than GDI+, and so there is a better chance
    of hardware acceleration. There's a good start on this with glitz,
    and I believe Tor even did an initial port of that work to WGL.

    But there are considerable difficulties with OpenGL.  OpenGL
    drivers are somewhat second-class citizens on Windows, and even
    two good drivers may not render everything the same. Many
    different levels of support (no shaders? old fragment programs?
    New high-level shading language? How many texture units?)  have to
    be handled.

    Most OpenGL is used in a single isolated context on the screen or
    even full-screen. It's not clear that drivers (especially for
    low-end hardware) are going to do good things if GTK+ started
    using OpenGL for drawing every menu. Another thing to consider is
    that since we are doing widget drawing through the WinXP theme API
    when drawing in GTK+, we are going to be mixing GL with GDI, which
    could be a problem.

    Text is difficult. Exactly consistency with text drawn through the
    GDI is needed. The simple approach is to draw text into a DIB
    white-on-black, copy that into a texture, and use it as a
    mask. But that means that the most time-critical drawing operation
    of all is the least accelerated.

    And printing isn't handled at all. An OpenGL backend would have to
    be augmented with a GDI or GDI+ backend for printing.

 4. Implement it on top of Direct3D. This has most of the same
    advantages as OpenGL with some extra benefits: Direct3D is (if I
    recall correctly) how Microsoft is accelerating Longhorn 2D
    drawing, Direct3D drivers are almost always better than OpenGL
    drivers on Windows, and the API is probably better suited to our
    purpose to begin with ... lower level and less abstract.

    But it also has some of the disadvantages as OpenGL.  Consistency
    of rendering may be a problem, some drivers may not like Direct3D
    being used on all windows, text is hard, and printing is not there
    at all.

    Direct3D does have some convenience functions for drawing text,
    but they don't look up to handling the full set of Uniscribe
    output that we'll be dealing with.

If I had to take a guess at the right direction, it's to go on top of
GDI+ for now (with heavy image fallbacks), and look at writing a
Direct3D backend later.

Attachment: signature.asc
Description: This is a digitally signed message part



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]