1 This is an outline of the architecture. Many details are
2 skipped, but hopefully this is useful.
4 By Andrew Lewycky <andrew@transgaming.com>
5 (with updates by Ove Kåven <ovek@transgaming.com>)
8 * DirectDraw inheritance tree
16 Most of the DirectDraw functionality is implemented in a common base
17 class. Derived classes are responsible for providing display
18 mode functions (Enum, Set, Restore), GetCaps, GetDevice identifier
19 and internal functions called to create primary and backbuffer
22 User provides for DirectDraw capabilities based on drawing to a
23 Wine window. It uses the User DirectDrawSurface implementation
24 for primary and backbuffer surfaces.
26 XVidMode attempt to use the XFree86 VidMode extension to set the
27 display resolution to match the parameters to SetDisplayMode.
29 DGA2 attempt to use the XFree86 DGA 2.x extension to set the
30 display resolution and direct access to the framebuffer, if the
31 full-screen-exclusive cooperative level is used. If not, it just
32 uses the User implementation.
35 * DirectDrawSurface inheritance tree
46 Main provides a very simple base class that does not implement any of
47 the image-related functions. Therefore it does not place any
48 constraints on how the surface data is stored.
50 DIB stores the surface data in a DIB section. It is used by the Main
51 DirectDraw driver to create off-screen surfaces.
53 User implements primary and backbuffer surfaces for the User DirectDraw
54 driver. If it is a primary surface, it will attempt to keep itself
55 synchronized to the window.
57 DGA2 surfaces claims an appropriate section of framebuffer space and
58 lets DIB build its DIB section on top of it.
60 Fake Z-Buffer surfaces are used by Direct3D to indicate that a primary
61 surface has an associated z-buffer. For a first implementation, it
62 doesn't need to store any image data since it is just a placeholder.
64 (Actually 3D programs will rarely use Lock or GetDC on primary
65 surfaces, backbuffers or z-buffers so we may want to arrange for
66 lazy allocation of the DIB sections.)
71 Only the most recent version of an interface needs to be implemented.
72 Other versions are handled by having thunks convert their parameters
73 and call the root version.
75 Not all interface versions have thunks. Some versions could be combined
76 because their parameters were compatible. For example if a structure
77 changes but the structure has a dwSize field, methods using that structure
78 are compatible, as long as the implementation remembers to take the dwSize
81 Interface thunks for Direct3D are more complicated since the paradigm
82 changed between versions.
85 * Logical Object Layout
87 The objects are split into the generic part (essentially the fields for
88 Main) and a private part. This is necessary because some objects
89 can be created with CoCreateInstance, then Initialized later. Only
90 at initialisation time do we know which class to use. Each class
91 except Main declares a Part structure and adds that to its Impl.
93 For example, the DIBTexture DirectDrawSurface implementation looks
96 struct DIBTexture_DirectDrawSurfaceImpl_Part
98 union DIBTexture_data data; /*declared in the real header*/
103 struct DIB_DirectDrawSurfaceImpl_Part dib;
104 struct DIBTexture_DirectDrawSurfaceImpl_Part dibtexture;
105 } DIBTexture_DirectDrawSurfaceImpl;
107 So the DIBTexture surface class is derived from the DIB surface
108 class and it adds one piece of data, a union.
110 Main does not have a Part structure. Its fields are stored in
111 IDirectDrawImpl/IDirectDrawSurfaceImpl.
113 To access private data, one says
115 DIBTexture_DirectDrawSurfaceImpl* priv = This->private;
116 do_something_with(priv->dibtexture.data);
121 Classes have two functions relevant to object creation, Create and
122 Construct. To create a new object, the class' Create function is
123 called. It allocates enough memory for IDirectDrawImpl or
124 IDirectDrawSurfaceImpl as well as the private data for derived
125 classes and then calls Construct.
127 Each class's Construct function calls the base class's Construct,
128 then does the necessary initialization.
130 For example, creating a primary surface with the user ddraw driver
131 calls User_DirectDrawSurface_Create which allocates memory for the
132 object and calls User_DirectDrawSurface_Construct to initialize it.
133 This calls DIB_DirectDrawSurface_Construct which calls
134 Main_DirectDrawSurface_Construct.