Commit 9e3e799c authored by Stefan Dösinger's avatar Stefan Dösinger Committed by Alexandre Julliard

ddraw: Complex surfaces form a tree.

parent 87544190
......@@ -1797,9 +1797,6 @@ IDirectDrawImpl_CreateNewSurface(IDirectDrawImpl *This,
(*ppSurf)->next_attached = NULL;
(*ppSurf)->first_attached = *ppSurf;
(*ppSurf)->next_complex = NULL;
(*ppSurf)->first_complex = *ppSurf;
/* Needed to re-create the surface on an implementation change */
(*ppSurf)->ImplType = ImplType;
......@@ -1958,10 +1955,10 @@ CreateAdditionalSurfaces(IDirectDrawImpl *This,
{
UINT i, level = 0;
HRESULT hr;
IDirectDrawSurfaceImpl *last = root;
for(i = 0; i < count; i++)
{
IDirectDrawSurfaceImpl *object2 = NULL;
IDirectDrawSurfaceImpl *iterator;
/* increase the mipmap level, but only if a mipmap is created
* In this case, also halve the size
......@@ -1982,12 +1979,9 @@ CreateAdditionalSurfaces(IDirectDrawImpl *This,
return hr;
}
/* Add the new surface to the complex attachment list */
object2->first_complex = root;
object2->next_complex = NULL;
iterator = root;
while(iterator->next_complex) iterator = iterator->next_complex;
iterator->next_complex = object2;
/* Add the new surface to the complex attachment array */
last->complex_array[0] = object2;
last = object2;
/* Remove the (possible) back buffer cap from the new surface description,
* because only one surface in the flipping chain is a back buffer, one
......@@ -2306,6 +2300,7 @@ IDirectDrawImpl_CreateSurface(IDirectDraw7 *iface,
ERR("IDirectDrawImpl_CreateNewSurface failed with %08x\n", hr);
return hr;
}
object->is_complex_root = TRUE;
*Surf = ICOM_INTERFACE(object, IDirectDrawSurface7);
......
......@@ -232,8 +232,18 @@ struct IDirectDrawSurfaceImpl
/* This implementation handles attaching surfaces to other surfaces */
IDirectDrawSurfaceImpl *next_attached;
IDirectDrawSurfaceImpl *first_attached;
IDirectDrawSurfaceImpl *next_complex;
IDirectDrawSurfaceImpl *first_complex;
/* Complex surfaces are organized in a tree, although the tree is degenerated to a list in most cases.
* In mipmap and primary surfaces each level has only one attachment, which is the next surface level.
* Only the cube texture root has 6 surfaces attached, which then have a normal mipmap chain attached
* to them. So hardcode the array to 6, a dynamic array or a list would be an overkill.
*/
#define MAX_COMPLEX_ATTACHED 6
IDirectDrawSurfaceImpl *complex_array[MAX_COMPLEX_ATTACHED];
/* You can't traverse the tree upwards. Only a flag for Surface::Release because its needed there,
* but no pointer to prevent temptations to traverse it in the wrong direction.
*/
BOOL is_complex_root;
/* Surface description, for GetAttachedSurface */
DDSURFACEDESC2 surface_desc;
......
......@@ -379,11 +379,13 @@ IDirect3DDeviceImpl_7_Release(IDirect3DDevice7 *iface)
HeapFree(GetProcessHeap(), 0, This->Handles);
TRACE("Releasing target %p %p\n", This->target, This->ddraw->d3d_target);
/* Release the render target and the WineD3D render target
* (See IDirect3D7::CreateDevice for more comments on this)
*/
IDirectDrawSurface7_Release(ICOM_INTERFACE(This->target, IDirectDrawSurface7));
IDirectDrawSurface7_Release(ICOM_INTERFACE(This->ddraw->d3d_target,IDirectDrawSurface7));
TRACE("Target release done\n");
This->ddraw->d3ddevice = NULL;
......@@ -391,6 +393,7 @@ IDirect3DDeviceImpl_7_Release(IDirect3DDevice7 *iface)
HeapFree(GetProcessHeap(), 0, This);
}
TRACE("Done\n");
return ref;
}
......
......@@ -785,7 +785,7 @@ DestroyCallback(IDirectDrawSurface7 *surf,
* part of a complex compound. They will get released when destroying
* the root
*/
if( (Impl->first_complex != Impl) || (Impl->first_attached != Impl) )
if( (!Impl->is_complex_root) || (Impl->first_attached != Impl) )
return DDENUMRET_OK;
/* Skip our depth stencil surface, it will be released with the render target */
if( Impl == ddraw->DepthStencilBuffer)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment