[cairo] Notes on cairo/win32
Owen Taylor
otaylor at redhat.com
Tue Jan 11 18:59:26 PST 2005
[ 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.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: This is a digitally signed message part
Url : http://lists.freedesktop.org/archives/cairo/attachments/20050111/aad3561e/attachment.pgp
More information about the cairo
mailing list