DIB Engine, some summarization

Rolf Kalbermatter r.kalbermatter at hccnet.nl
Sun Feb 11 16:13:15 CST 2007


This is getting a bit long so if you do not have time, then skip this.

I've looked a little more at the issue of a DIB Engine and tried to use the
feedback
so far to get an idea what the possible architecture could be.

First I took a look at how Windows seems to do it currently (excluding
Vista). There
GDI32 is mostly a wrapper around win32k.sys and the different GDI APIs call
mostly
into corresponding NtGdi... functions in win32k.sys.

Those functions do the actual handling and call the according driver that is
attached
to the DC. The interface to the driver is similar to what is done now in
Wine although
not identical. The modern Windows display driver interface uses sometimes
more or less
different functions than the old one as used in Wine.

A driver can either not implement certain functions, only implement them for
its device
specific surfaces, or hook certain calls by returning flags inside the
driver initialization
structure on initialization. Those hook flags tell the GDI engine that the
driver wants to
be called for DIB surfaces too for particular functions and bit depths. The
driver will then
be called for according DIB surfaces too and it can decide to do whatever it
can do best and
for those cases it doesn't know well how to do it, call back into the GDI
engine using an
according Eng... function. This calling back into the GDI engine for hooked
functions is
called punting by MS.

If the driver didn't provide the actual function it will possibly be
simulated by the GDI
engine by calling other driver functions and if the driver didn't hook the
function or didn't
succeed and it is for a DIB surface then the GDI engine itself will call the
according Eng...
function. GDI32 exports most of those Eng... functions too but that are
simply user space
wrappers around the win32k.sys entry points for those functions.

>From a design view it might be interesting to separate the actual GDI engine
into a subpart
that corresponds with the NtGdi... functions in win32k.sys eventhough they
might stay inside
GDI32 for the time being. The actual Eng... functions would be also placed
inside that GDI
engine and are in fact mostly the long awaited DIB engine. Such an
architecture would make
reuse of such a GDI32/win32k combo in other projects fairly easy.
However this NtGdi API is not documented although it is presumably mostly a
mirror of the
GDI API. There are lists of what APIs win32k.sys does export and how many
parameters each
of these functions takes, extracted from the actual win32k.sys file.
Eventhough Windows
keeps them in the win32k.sys kernel I think it would be a good idea to keep
them all in
GDI32 for the time being. If that API is at some time mostly complete and
separation into
its own DLL or something would be desired, this could be done quite easily.
But it is certainly quite a bit tedious to do and would require at least
partly some sort
of clean room reverse engineering and it's not really necessary for a DIB
engine at all
at this point.

There is a little problem with those Eng.. functions however. They are
modeled after the new
NT display driver interface that is in so far different that it does use
partly different
functions and parameters to the old (I assume Win 3.1 display driver)
interface used in Wine
and this is even more or less all documented in the DDK, although the basic
principle between
the Windows driver interface and what Wine does is of course mostly the
same.
I can't really see however how it would be possible to change that interface
to match the 
modern NT display driver interface in a seemless manner as it would mean a
significant
change in winex11.drv, winequartz.drv and the GDI32 (aka win32k.sys) that
would need to
be done mostly in a few big chunks to not completly break everything.

So what would remain is adding the actual Eng... and object access API to
GDI. These APIs
are (all?) documented in the DDK and could be implemented based on MSDN
information alone
together with maybe some test cases. 
The actual driver interface might remain mostly the same as it is now with
some extra
addition to return to the GDI engine extra flags to indicate hooks for DIB
surfaces.
Then implementation of the Eng... functions would have to start and as they
are fleshed
out and work they get integrated into the calling logic one for one. Until
this is
completely done the current separations for DIBs into appstate and
serverstate would
have to remain, so that the X11 driver can still pass them to the X11 server
for
rendering of not implemented DIB engine operations. Once the DIB engine is
finished
(if ever :-) this could be removed as the X11 driver would not anymore hook
any of the DIB 
operations. If winequartz.drv wants to continue hooking DIB operations it
can do so of
course.

To start with, the actual header winddi.h defining most of the Eng.. calls
could be
added as ddk header to Wine. There seems to be a copyright free version of
this header
file from Casper S. Hornstrup that is part of the w32api package.

I have thought about modifying the driver function call array instead as
Alexandre has
pointed out in the past as possible solution instead of adding the actual
Eng... calls
explicitedly into the GDI engine as fall back. But this seems not a good
solution to me.
The driver wants to be informed of graphic operations for device specific
surfaces most
often I would assume and only might want to not get called for device
contexts containing
a dib section. And as some have pointed out winequartz may even want to get
called for
DIBs too. In order to allow for such a dynamic overriding of function
pointers in the
driver function array, that array would have to be allocated dynamically on
a device
context base and I think this would make everything slower, more memory
consuming and
it wouldn't really be easier although I admit that adding Eng.. calls
everywhere and
correctly is quite some work to do.

The issue about network transparency for the display driver would not be an
issue IMO.
Once complete the DIB engine would handle all DIB operations locally and so
no need for
translating direct memory access into remote calls to some display server
would be
necessary. And the blitting of DIBs to the display when necessary would
still be done
through the driver of course so everything would be transparent as far as
the capabilities
of the used display device itself allow for that.

Rolf Kalbermatter




More information about the wine-devel mailing list