DX6 more compatibility.

Michael Karcher wine at mkarcher.dialup.fu-berlin.de
Fri Jun 27 10:57:43 CDT 2008


Am Freitag, den 27.06.2008, 09:13 -0400 schrieb Chris Ahrendt:
> > The problem is that currently, if the application requests a
> > IDirectDrawSurface4 what it gets is a IDirectDrawSurface7. Which is (on
> > the first look) not a issue, as the vtables are compatible (same
> > functions with same signature at same offsets, except for
> > IDirectDrawSurface7 having added some functions at the end), but on the
> > second look, the IDirectDrawSurface7 vtable contains the pointer to the
> > strict AddAttachedSurface, whereas the vtable for IDirectDraw4 must
> > contain a pointer to a relaxed AddAttachedSurface. This we need two
> > different vtables (You can query an IDirectDraw7 and an IDirectDraw4
> > surface on the same object, so a flag in the object does not do,
> > probably[1]) to get the different behaviours. Two different vtables for
> > the same object inherently is thunking.
> I wonder if  there is an easy way to do an API abstraction of some 
> sort... not with a flag perse but like you can in C++ with the different
> instanciations depending upon the parms passed.
If I understand you correctly, you are thinking of C++ templates or
overloaded functions here. They are not comparable, as both are
compile-time polymorphism, while here run-time polymorphism is needed.
If I write "cout << 1", the compiler uses
  std::ostream& operator <<(std::ostream&, int)
and if I write "cout << 1.2", the compiler uses
  std::ostream& operator <<(std::ostream&, double)
These are two different functions, that just happen to have the same
name in the source code. In object code, the mangled names are used,
which are different.

Templates also go along this line: The compiler instantiates the
template with concrete types (so we have std::vector<int> and
std::vector<double>), that just both happen to be instantiated from the
same template, but have nothing in common from the viewpoint of the
linker or runtime-environment.

Run-time polymorphism in C++ (and in COM, DirectDraw is a COM interface)
is implemented via vtables. If you want
IDirectDrawSurface7::AddAttachedSurface to call a different function
than IDirectDirectDrawSurface4::AddAttachedSurface, then the function
pointer at address 0x0c in the vtable for IDirectDrawSurface4 must be
different from the function pointer at address 0x0c in the vtable for
IDirectDrawSurface7. So it is obvious, that two different vtables are
needed.

A COM interface pointer points directly to the vtable pointer of the
interface you requested. So for the even same surface, the IDirectDraw4
interface pointer must be different from the IDirectDraw7 interface
pointer, as the address stored at the destination of the interface
pointer is either the IDirectDraw4 or the IDirectDraw7 vtable address.
So we need two different interface pointers into the same object. As the
core functions need a pointer that points to one defined location in the
object, the methods called via the second vtable have to adjust the
interface pointer they received into the original interface pointer, and
pass it on to the core implementation. And this is where I discovered
what a thunk it: Exactly a function that adjusts the this pointer before
calling the main implementation; these thunks are unavoidable if
functions from one vtable are forwarded to functions belonging to
another vtable implemented by the same object.

>  Then instead of thunking, which is inherently buggy
I don't agree with this statement.

> and tends to be slow,  you use the v7 structure and return it without
> the v7 specific items at the end.
Tables get not returned. Table pointers are included in the COM objects
and pointed to by interface pointers. Using the v7 table for v4 is what
wine currently does, and causes the problem discussed in this thread.

> That way you store one table instead of 2. (again sorry if this is fuzzy
> I am working on no sleep here).
Doesn't work. The fourth entry in that table *either* points to the
strict *or* to the relaxed version of AddAttachedSurface. I might get
around to send a patch on sunday.

Regards,
  Michael Karcher




More information about the wine-devel mailing list