Commit c93da092 authored by Oliver Stieber's avatar Oliver Stieber Committed by Alexandre Julliard

Changed swapchains held by the device from an array to a linked

list. Also provide a notification function that that the swapchain can be removed when it is released.
parent 2431a644
...@@ -337,26 +337,35 @@ ULONG WINAPI IWineD3DDeviceImpl_Release(IWineD3DDevice *iface) { ...@@ -337,26 +337,35 @@ ULONG WINAPI IWineD3DDeviceImpl_Release(IWineD3DDevice *iface) {
if (((IWineD3DImpl *)This->wineD3D)->dxVersion > 8) { /*We don't create a state block in d3d8 yet*/ if (((IWineD3DImpl *)This->wineD3D)->dxVersion > 8) { /*We don't create a state block in d3d8 yet*/
/* NOTE: You must release the parent if the object was created via a callback /* NOTE: You must release the parent if the object was created via a callback
** ***************************/ ** ***************************/
int i;
IUnknown* swapChainParent; IUnknown* swapChainParent;
/* Release all of the swapchains, except the implicit swapchain (#0) */ /* NOTE: Don't release swapchain 0 here, it's 'special' */
for(i = 1; i < This->numberOfSwapChains; i++) { SwapChainList *nextSwapchain = This->swapchains;
/* TODO: don't access swapchains[x] directly! */ if (nextSwapchain != NULL) {
IWineD3DSwapChain_Release(This->swapchains[i]); nextSwapchain = nextSwapchain->next;
} else {
WARN("Expected to find the implicite swapchain\n");
}
/* release all the other swapchains */
while (nextSwapchain != NULL) {
SwapChainList *prevSwapchain = nextSwapchain;
nextSwapchain = nextSwapchain->next;
IWineD3DSwapChain_Release(prevSwapchain->swapchain);
/* NOTE: no need to free the list element, it will be done by the release callback
HeapFree(GetProcessHeap(), 0, prevSwapchain); */
} }
if (This->stateBlock != NULL) { if (This->stateBlock != NULL) {
IWineD3DStateBlock_Release((IWineD3DStateBlock *)This->stateBlock); IWineD3DStateBlock_Release((IWineD3DStateBlock *)This->stateBlock);
} }
if (This->swapchains[0] != NULL) { if (This->swapchains != NULL) {
/* Swapchain 0 is special because it's created in startup with a hanging parent, so we have to release its parent now */ /* Swapchain 0 is special because it's created in startup with a hanging parent, so we have to release it's parent now */
/* TODO: don't access swapchains[x] directly!, check that there are no-more swapchains left for this device! */ IWineD3DSwapChain_GetParent(This->swapchains->swapchain, &swapChainParent);
IWineD3DSwapChain_GetParent(This->swapchains[0], &swapChainParent);
IUnknown_Release(swapChainParent); /* once for the get parent */ IUnknown_Release(swapChainParent); /* once for the get parent */
if (IUnknown_Release(swapChainParent) > 0) { /* the second time for when it was created */ if (IUnknown_Release(swapChainParent) > 0) { /* the second time for when it was created */
FIXME("(%p) Something's still holding the implicit swapchain\n",This); FIXME("(%p) Something's still holding the implicite swapchain\n", This);
} }
} }
...@@ -1302,22 +1311,22 @@ HRESULT WINAPI IWineD3DDeviceImpl_CreateAdditionalSwapChain(IWineD3DDevice* ifac ...@@ -1302,22 +1311,22 @@ HRESULT WINAPI IWineD3DDeviceImpl_CreateAdditionalSwapChain(IWineD3DDevice* ifac
checkGLcall("glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SEPARATE_SPECULAR_COLOR);"); checkGLcall("glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SEPARATE_SPECULAR_COLOR);");
/* switch back to the original context (unless it was zero)*/ /* switch back to the original context (unless it was zero)*/
if (This->numberOfSwapChains != 0) { if (This->swapchains != NULL) {
/** TODO: restore the context and drawable **/ /** TODO: restore the context and drawable **/
glXMakeCurrent(object->display, oldDrawable, oldContext); glXMakeCurrent(object->display, oldDrawable, oldContext);
} }
LEAVE_GL(); LEAVE_GL();
/* TODO: move this off into a linked list implementation! (add swapchain, remove swapchain or something along those lines) */ { /* Finally add the swapchain to the end of the devices' swapchain list */
#if 0 SwapChainList **nextSwapchain;
IListOperator *listOperator; nextSwapchain = &This->swapchains;
IListStore_CreateListOperator(This->swapchainStore, &listOperator); while(*nextSwapchain != NULL) {
IListOperator_Append(listOperator, (void *)object); nextSwapchain = &((*nextSwapchain)->next);
IListOperator_Release(listOperator); }
#endif (*nextSwapchain) = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*This->swapchains));
(*nextSwapchain)->swapchain = (IWineD3DSwapChain *)object;
This->swapchains[This->numberOfSwapChains++] = (IWineD3DSwapChain *)object; }
TRACE("Set swapchain to %p\n", object); TRACE("Set swapchain to %p\n", object);
} else { /* something went wrong so clean up */ } else { /* something went wrong so clean up */
IUnknown* bufferParent; IUnknown* bufferParent;
...@@ -1353,29 +1362,46 @@ HRESULT WINAPI IWineD3DDeviceImpl_CreateAdditionalSwapChain(IWineD3DDevice* ifac ...@@ -1353,29 +1362,46 @@ HRESULT WINAPI IWineD3DDeviceImpl_CreateAdditionalSwapChain(IWineD3DDevice* ifac
/** NOTE: These are ahead of the other getters and setters to save using a forward declaration **/ /** NOTE: These are ahead of the other getters and setters to save using a forward declaration **/
UINT WINAPI IWineD3DDeviceImpl_GetNumberOfSwapChains(IWineD3DDevice *iface) { UINT WINAPI IWineD3DDeviceImpl_GetNumberOfSwapChains(IWineD3DDevice *iface) {
IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface; IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
unsigned int numberOfSwapChains = 0;
SwapChainList *swapchain;
/* TODO: move over to using a linked list. */ swapchain = This->swapchains;
TRACE("(%p) returning %d\n", This, This->numberOfSwapChains); /* itterate through the list to get a count */
return This->numberOfSwapChains; while (swapchain != NULL) {
swapchain = swapchain->next;
numberOfSwapChains++;
}
TRACE("(%p) returning %d\n", This, numberOfSwapChains);
return numberOfSwapChains;
} }
HRESULT WINAPI IWineD3DDeviceImpl_GetSwapChain(IWineD3DDevice *iface, UINT iSwapChain, IWineD3DSwapChain **pSwapChain) { HRESULT WINAPI IWineD3DDeviceImpl_GetSwapChain(IWineD3DDevice *iface, UINT iSwapChain, IWineD3DSwapChain **pSwapChain) {
IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface; IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
SwapChainList *swapchain;
HRESULT hr = D3DERR_INVALIDCALL;
swapchain = This->swapchains;
TRACE("(%p) : swapchain %d \n", This, iSwapChain); TRACE("(%p) : swapchain %d \n", This, iSwapChain);
if(iSwapChain >= IWineD3DDeviceImpl_GetNumberOfSwapChains(iface) || iSwapChain < 0) {
*pSwapChain = NULL;
return D3DERR_INVALIDCALL;
}else{
/** TODO: move off to a linked list implementation **/
*pSwapChain = This->swapchains[iSwapChain];
}
/* TODO: move over to using stores and linked lists. */ TRACE("(%p) Finding swapchain %d\n", This, iSwapChain);
while (iSwapChain > 0 && swapchain != NULL) {
swapchain = swapchain->next;
iSwapChain--;
}
if (iSwapChain > 0 || swapchain == NULL) {
FIXME("(%p) Unable to find swapchain %d\n", This, iSwapChain);
*pSwapChain = NULL;
} else {
/** TODO: move off to a linkesList implementation **/
*pSwapChain = swapchain->swapchain;
IWineD3DSwapChain_AddRef(*pSwapChain); IWineD3DSwapChain_AddRef(*pSwapChain);
hr = D3D_OK;
}
TRACE("(%p) returning %p\n", This, *pSwapChain); TRACE("(%p) returning %p\n", This, *pSwapChain);
return D3D_OK; return hr;
} }
HRESULT WINAPI IWineD3DDeviceImpl_Reset(IWineD3DDevice* iface, WINED3DPRESENT_PARAMETERS* pPresentationParameters) { HRESULT WINAPI IWineD3DDeviceImpl_Reset(IWineD3DDevice* iface, WINED3DPRESENT_PARAMETERS* pPresentationParameters) {
...@@ -5938,6 +5964,44 @@ void WINAPI IWineD3DDeviceImpl_ResourceReleased(IWineD3DDevice *iface, IWineD3DR ...@@ -5938,6 +5964,44 @@ void WINAPI IWineD3DDeviceImpl_ResourceReleased(IWineD3DDevice *iface, IWineD3DR
} }
/** This function is to be called by the swapchain when it is released and it's ref = 0
*****************************************************/
void WINAPI IWineD3DDeviceImpl_SwapChainReleased(IWineD3DDevice *iface, IWineD3DSwapChain *swapChain){
IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *) iface;
SwapChainList **nextSwapchain;
nextSwapchain = &This->swapchains;
/* Check to see if the swapchian is being used as the render target */
if (This->renderTarget != NULL) {
IWineD3DSurface *swapchainBackBuffer;
IWineD3DSwapChain_GetBackBuffer(swapChain, 0 ,( D3DBACKBUFFER_TYPE) 0, &swapchainBackBuffer);
if (This->renderTarget == swapchainBackBuffer) {
/* Don't know what to do, so warn and carry on as usual (which in this case leaves the renderterget in limbo) */
FIXME("Atempting to release a swapchain that is currently beuing used as a render target, behaviour is undefined\n");
}
}
/* Go through the swapchain list and try to find the swapchain being released */
while(*nextSwapchain != NULL && (*nextSwapchain)->swapchain != swapChain) {
nextSwapchain = &(*nextSwapchain)->next;
}
/* Check to see if we found the swapchain */
if (NULL != *nextSwapchain) {
/* We found the swapchain so remove it from the list */
TRACE("(%p) releasing swapchain(%p)\n", iface, swapChain);
HeapFree(GetProcessHeap(), 0 , *nextSwapchain);
*nextSwapchain = (*nextSwapchain)->next;
} else {
/* We didn't find the swapchain on the list, this can only heppen because of a programming error in wined3d */
FIXME("(%p) Attempting to release a swapchain (%p) that hasn't been stored\n", iface, swapChain);
}
TRACE("swapchain (%p) released\n", swapChain);
return;
}
/********************************************************** /**********************************************************
* IWineD3DDevice VTbl follows * IWineD3DDevice VTbl follows
**********************************************************/ **********************************************************/
...@@ -6074,6 +6138,7 @@ const IWineD3DDeviceVtbl IWineD3DDevice_Vtbl = ...@@ -6074,6 +6138,7 @@ const IWineD3DDeviceVtbl IWineD3DDevice_Vtbl =
IWineD3DDeviceImpl_GetFrontBufferData, IWineD3DDeviceImpl_GetFrontBufferData,
/*** Internal use IWineD3DDevice methods ***/ /*** Internal use IWineD3DDevice methods ***/
IWineD3DDeviceImpl_SetupTextureStates, IWineD3DDeviceImpl_SetupTextureStates,
IWineD3DDeviceImpl_SwapChainReleased,
/*** object tracking ***/ /*** object tracking ***/
IWineD3DDeviceImpl_ResourceReleased IWineD3DDeviceImpl_ResourceReleased
}; };
......
...@@ -87,6 +87,11 @@ ULONG WINAPI IWineD3DSwapChainImpl_Release(IWineD3DSwapChain *iface) { ...@@ -87,6 +87,11 @@ ULONG WINAPI IWineD3DSwapChainImpl_Release(IWineD3DSwapChain *iface) {
TRACE("(%p) : ReleaseRef to %ld\n", This, refCount); TRACE("(%p) : ReleaseRef to %ld\n", This, refCount);
if (refCount == 0) { if (refCount == 0) {
IUnknown* bufferParent; IUnknown* bufferParent;
/* tell the device that we've been released */
IWineD3DDevice_SwapChainReleased((IWineD3DDevice *)This->wineD3DDevice, iface);
/* release the ref to the front and back buffer parents */
IWineD3DSurface_GetParent(This->frontBuffer, &bufferParent); IWineD3DSurface_GetParent(This->frontBuffer, &bufferParent);
IUnknown_Release(bufferParent); /* once for the get parent */ IUnknown_Release(bufferParent); /* once for the get parent */
if(IUnknown_Release(bufferParent) > 0){ if(IUnknown_Release(bufferParent) > 0){
...@@ -108,7 +113,6 @@ ULONG WINAPI IWineD3DSwapChainImpl_Release(IWineD3DSwapChain *iface) { ...@@ -108,7 +113,6 @@ ULONG WINAPI IWineD3DSwapChainImpl_Release(IWineD3DSwapChain *iface) {
all others are crated by the caller, so releasing the parent should cause all others are crated by the caller, so releasing the parent should cause
the child to be released, not the other way around! the child to be released, not the other way around!
*/ */
/* TODO: notify the device that this swapchain doesn't exist any more */
HeapFree(GetProcessHeap(), 0, This); HeapFree(GetProcessHeap(), 0, This);
} }
return refCount; return refCount;
......
...@@ -51,9 +51,6 @@ ...@@ -51,9 +51,6 @@
#define MAX_CLIPPLANES D3DMAXUSERCLIPPLANES #define MAX_CLIPPLANES D3DMAXUSERCLIPPLANES
#define MAX_LEVELS 256 #define MAX_LEVELS 256
/* Swap chains */
#define MAX_SWAPCHAINS 256
/* Used for CreateStateBlock */ /* Used for CreateStateBlock */
#define NUM_SAVEDPIXELSTATES_R 35 #define NUM_SAVEDPIXELSTATES_R 35
#define NUM_SAVEDPIXELSTATES_T 18 #define NUM_SAVEDPIXELSTATES_T 18
...@@ -379,6 +376,10 @@ typedef struct IWineD3DImpl ...@@ -379,6 +376,10 @@ typedef struct IWineD3DImpl
extern const IWineD3DVtbl IWineD3D_Vtbl; extern const IWineD3DVtbl IWineD3D_Vtbl;
typedef struct SwapChainList {
IWineD3DSwapChain *swapchain;
struct SwapChainList *next;
} SwapChainList;
/** Hacked out start of a context manager!! **/ /** Hacked out start of a context manager!! **/
typedef struct glContext { typedef struct glContext {
...@@ -455,9 +456,7 @@ typedef struct IWineD3DDeviceImpl ...@@ -455,9 +456,7 @@ typedef struct IWineD3DDeviceImpl
UINT adapterNo; UINT adapterNo;
D3DDEVTYPE devType; D3DDEVTYPE devType;
/* TODO: Replace with a linked list */ SwapChainList *swapchains;
IWineD3DSwapChain *swapchains[MAX_SWAPCHAINS]; /* no-one wil ever need more that MAX_SWAPCHAINS swapchains */
int numberOfSwapChains;
ResourceList *resources; /* a linked list to track resources created by the device */ ResourceList *resources; /* a linked list to track resources created by the device */
......
...@@ -388,6 +388,7 @@ DECLARE_INTERFACE_(IWineD3DDevice,IUnknown) ...@@ -388,6 +388,7 @@ DECLARE_INTERFACE_(IWineD3DDevice,IUnknown)
STDMETHOD(GetFrontBufferData)(THIS_ UINT iSwapChain,struct IWineD3DSurface* pSurface) PURE; STDMETHOD(GetFrontBufferData)(THIS_ UINT iSwapChain,struct IWineD3DSurface* pSurface) PURE;
/*** Internal use IWineD3Device methods ***/ /*** Internal use IWineD3Device methods ***/
STDMETHOD_(void, SetupTextureStates)(THIS_ DWORD Stage, DWORD Flags); STDMETHOD_(void, SetupTextureStates)(THIS_ DWORD Stage, DWORD Flags);
STDMETHOD_(void, SwapChainReleased)(THIS_ struct IWineD3DSwapChain *swapChain);
/*** object tracking ***/ /*** object tracking ***/
STDMETHOD_(void, ResourceReleased)(THIS_ struct IWineD3DResource *resource); STDMETHOD_(void, ResourceReleased)(THIS_ struct IWineD3DResource *resource);
}; };
...@@ -516,6 +517,7 @@ DECLARE_INTERFACE_(IWineD3DDevice,IUnknown) ...@@ -516,6 +517,7 @@ DECLARE_INTERFACE_(IWineD3DDevice,IUnknown)
#define IWineD3DDevice_GetRenderTargetData(p,a,b) (p)->lpVtbl->GetRenderTargetData(p,a,b) #define IWineD3DDevice_GetRenderTargetData(p,a,b) (p)->lpVtbl->GetRenderTargetData(p,a,b)
#define IWineD3DDevice_GetFrontBufferData(p,a,b) (p)->lpVtbl->GetFrontBufferData(p,a,b) #define IWineD3DDevice_GetFrontBufferData(p,a,b) (p)->lpVtbl->GetFrontBufferData(p,a,b)
#define IWineD3DDevice_SetupTextureStates(p,a,b) (p)->lpVtbl->SetupTextureStates(p,a,b) #define IWineD3DDevice_SetupTextureStates(p,a,b) (p)->lpVtbl->SetupTextureStates(p,a,b)
#define IWineD3DDevice_SwapChainReleased(p,a) (p)->lpVtbl->SwapChainReleased(p,a)
#define IWineD3DDevice_ResourceReleased(p,a) (p)->lpVtbl->ResourceReleased(p,a) #define IWineD3DDevice_ResourceReleased(p,a) (p)->lpVtbl->ResourceReleased(p,a)
#endif #endif
......
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