Chris Morgan | 5a6d231 | 2004-03-20 19:23:56 +0000 | [diff] [blame] | 1 | <chapter id="ddraw"> |
| 2 | <title>Outline of DirectDraw Architecture</title> |
| 3 | |
| 4 | <para> |
| 5 | This is an outline of the architecture. Many details are |
| 6 | skipped, but hopefully this is useful. |
| 7 | </para> |
| 8 | |
| 9 | <sect1 id="ddinheritance"> |
| 10 | <title>DirectDraw inheritance tree</title> |
| 11 | <programlisting> |
| 12 | Main |
| 13 | | |
| 14 | User |
| 15 | |-----------\ |
| 16 | XVidMode DGA2 |
| 17 | </programlisting> |
| 18 | <para> |
| 19 | Most of the DirectDraw functionality is implemented in a common base |
| 20 | class. Derived classes are responsible for providing display |
| 21 | mode functions (Enum, Set, Restore), GetCaps, GetDevice identifier |
| 22 | and internal functions called to create primary and backbuffer |
| 23 | surfaces. |
| 24 | </para> |
| 25 | <para> |
| 26 | User provides for DirectDraw capabilities based on drawing to a |
| 27 | Wine window. It uses the User DirectDrawSurface implementation |
| 28 | for primary and backbuffer surfaces. |
Rudolf Kastl | 33d9a97 | 2004-03-22 20:40:23 +0000 | [diff] [blame] | 29 | </para> |
Chris Morgan | 5a6d231 | 2004-03-20 19:23:56 +0000 | [diff] [blame] | 30 | <para> |
| 31 | XVidMode attempt to use the XFree86 VidMode extension to set the |
| 32 | display resolution to match the parameters to SetDisplayMode. |
| 33 | </para> |
| 34 | <para> |
| 35 | DGA2 attempt to use the XFree86 DGA 2.x extension to set the |
| 36 | display resolution and direct access to the framebuffer, if the |
| 37 | full-screen-exclusive cooperative level is used. If not, it just |
| 38 | uses the User implementation. |
| 39 | </para> |
| 40 | </sect1> |
| 41 | <sect1 id="ddsurfaceinheritance"> |
| 42 | <title>DirectDrawSurface inheritance tree</title> |
| 43 | <programlisting> |
| 44 | Main |
| 45 | |--------------\ |
| 46 | | | |
| 47 | DIB Fake Z-Buffer |
| 48 | | |
| 49 | |------\---------\ |
| 50 | | | | |
| 51 | User DGA2 DIBTexture |
| 52 | </programlisting> |
| 53 | <para> |
| 54 | Main provides a very simple base class that does not implement any of |
| 55 | the image-related functions. Therefore it does not place any |
| 56 | constraints on how the surface data is stored. |
| 57 | </para> |
| 58 | <para> |
| 59 | DIB stores the surface data in a DIB section. It is used by the Main |
| 60 | DirectDraw driver to create off-screen surfaces. |
| 61 | </para> |
| 62 | <para> |
| 63 | User implements primary and backbuffer surfaces for the User DirectDraw |
| 64 | driver. If it is a primary surface, it will attempt to keep itself |
| 65 | synchronized to the window. |
| 66 | </para> |
| 67 | <para> |
| 68 | DGA2 surfaces claims an appropriate section of framebuffer space and |
| 69 | lets DIB build its DIB section on top of it. |
| 70 | </para> |
| 71 | <para> |
| 72 | Fake Z-Buffer surfaces are used by Direct3D to indicate that a primary |
| 73 | surface has an associated z-buffer. For a first implementation, it |
| 74 | doesn't need to store any image data since it is just a placeholder. |
| 75 | </para> |
| 76 | <para> |
| 77 | (Actually 3D programs will rarely use Lock or GetDC on primary |
| 78 | surfaces, backbuffers or z-buffers so we may want to arrange for |
| 79 | lazy allocation of the DIB sections.) |
| 80 | </para> |
| 81 | </sect1> |
| 82 | |
| 83 | <sect1 id="interfacethunks"> |
| 84 | <title>Interface Thunks</title> |
| 85 | <para> |
| 86 | Only the most recent version of an interface needs to be implemented. |
| 87 | Other versions are handled by having thunks convert their parameters |
| 88 | and call the root version. |
| 89 | </para> |
| 90 | <para> |
| 91 | Not all interface versions have thunks. Some versions could be combined |
| 92 | because their parameters were compatible. For example if a structure |
| 93 | changes but the structure has a dwSize field, methods using that structure |
| 94 | are compatible, as long as the implementation remembers to take the dwSize |
| 95 | into account. |
| 96 | </para> |
| 97 | <para> |
| 98 | Interface thunks for Direct3D are more complicated since the paradigm |
| 99 | changed between versions. |
| 100 | </para> |
| 101 | </sect1> |
| 102 | |
| 103 | <sect1 id="logicalobjectlayout"> |
| 104 | <title>Logical Object Layout</title> |
| 105 | <para> |
| 106 | The objects are split into the generic part (essentially the fields for |
| 107 | Main) and a private part. This is necessary because some objects |
| 108 | can be created with CoCreateInstance, then Initialized later. Only |
| 109 | at initialization time do we know which class to use. Each class |
| 110 | except Main declares a Part structure and adds that to its Impl. |
| 111 | </para> |
| 112 | <para> |
| 113 | For example, the DIBTexture DirectDrawSurface implementation looks |
| 114 | like this: |
| 115 | </para> |
| 116 | <programlisting> |
| 117 | struct DIBTexture_DirectDrawSurfaceImpl_Part |
| 118 | { |
| 119 | union DIBTexture_data data; /*declared in the real header*/ |
| 120 | }; |
| 121 | |
| 122 | typedef struct |
| 123 | { |
| 124 | struct DIB_DirectDrawSurfaceImpl_Part dib; |
| 125 | struct DIBTexture_DirectDrawSurfaceImpl_Part dibtexture; |
| 126 | } DIBTexture_DirectDrawSurfaceImpl; |
| 127 | </programlisting> |
| 128 | <para> |
| 129 | So the DIBTexture surface class is derived from the DIB surface |
| 130 | class and it adds one piece of data, a union. |
| 131 | </para> |
| 132 | <para> |
| 133 | Main does not have a Part structure. Its fields are stored in |
| 134 | IDirectDrawImpl/IDirectDrawSurfaceImpl. |
| 135 | </para> |
| 136 | <para> |
| 137 | To access private data, one says |
| 138 | </para> |
| 139 | <programlisting> |
| 140 | DIBTexture_DirectDrawSurfaceImpl* priv = This->private; |
| 141 | do_something_with(priv->dibtexture.data); |
| 142 | </programlisting> |
| 143 | </sect1> |
| 144 | |
| 145 | <sect1 id="creatingobject"> |
| 146 | <title>Creating Objects</title> |
| 147 | <para> |
| 148 | Classes have two functions relevant to object creation, Create and |
| 149 | Construct. To create a new object, the class' Create function is |
| 150 | called. It allocates enough memory for IDirectDrawImpl or |
| 151 | IDirectDrawSurfaceImpl as well as the private data for derived |
| 152 | classes and then calls Construct. |
| 153 | </para> |
| 154 | <para> |
| 155 | Each class's Construct function calls the base class's Construct, |
| 156 | then does the necessary initialization. |
| 157 | </para> |
| 158 | <para> |
| 159 | For example, creating a primary surface with the user ddraw driver |
| 160 | calls User_DirectDrawSurface_Create which allocates memory for the |
| 161 | object and calls User_DirectDrawSurface_Construct to initialize it. |
| 162 | This calls DIB_DirectDrawSurface_Construct which calls |
| 163 | Main_DirectDrawSurface_Construct. |
| 164 | </para> |
| 165 | </sect1> |
| 166 | </chapter> |
| 167 | |
| 168 | <!-- Keep this comment at the end of the file |
| 169 | Local variables: |
| 170 | mode: sgml |
| 171 | sgml-parent-document:("wine-devel.sgml" "set" "book" "chapter" "") |
| 172 | End: |
| 173 | --> |