WINED3D: Fix SetContainer

H. Verbeet hverbeet at gmail.com
Sun Feb 5 13:49:10 CST 2006


When setting the surface/volume container, we should keep a reference
to the container. We don't have to keep a reference to the container's
parent, since the container itself will keep that reference.
Unfortunately that also means we can't write a regression test against
d3d9 for this. Writing a test against wined3d might be possible, but
wouldn't work on Windows. Also, since the container is always a
wined3d object, it should be an IWineD3DBase pointer. This is usefull
for GetContainer, in a later patch.

Changelog:
  - Add/Release references to the container
  - Change the type of the container from IUnknown to IWineD3DBase.
-------------- next part --------------
diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c
index 775066c..ffd7617 100644
--- a/dlls/wined3d/device.c
+++ b/dlls/wined3d/device.c
@@ -725,7 +725,7 @@ HRESULT  WINAPI IWineD3DDeviceImpl_Creat
 
     /** Create and initialise the surface resource **/
     D3DCREATERESOURCEOBJECTINSTANCE(object,Surface,D3DRTYPE_SURFACE, Size)
-    object->container = (IUnknown*) This;
+    IWineD3DSurface_SetContainer((IWineD3DSurface *)object, (IWineD3DBase *)This);
 
     object->currentDesc.Width      = Width;
     object->currentDesc.Height     = Height;
@@ -888,7 +888,7 @@ HRESULT  WINAPI IWineD3DDeviceImpl_Creat
             return hr;
         }
 
-        IWineD3DSurface_SetContainer(object->surfaces[i], (IUnknown *)object);
+        IWineD3DSurface_SetContainer(object->surfaces[i], (IWineD3DBase *)object);
         TRACE("Created surface level %d @ %p\n", i, object->surfaces[i]);
         /* calculate the next mipmap level */
         tmpW = max(1, tmpW >> 1);
@@ -958,7 +958,7 @@ HRESULT WINAPI IWineD3DDeviceImpl_Create
                            (IWineD3DVolume **)&object->volumes[i], pSharedHandle);
 
         /* Set it's container to this object */
-        IWineD3DVolume_SetContainer(object->volumes[i], (IUnknown *)object);
+        IWineD3DVolume_SetContainer(object->volumes[i], (IWineD3DBase *)object);
 
         /* calcualte the next mipmap level */
         tmpW = max(1, tmpW >> 1);
@@ -1076,7 +1076,7 @@ HRESULT WINAPI IWineD3DDeviceImpl_Create
                 *ppCubeTexture = NULL;
                 return hr;
             }
-            IWineD3DSurface_SetContainer(object->surfaces[j][i], (IUnknown *)object);
+            IWineD3DSurface_SetContainer(object->surfaces[j][i], (IWineD3DBase *)object);
             TRACE("Created surface level %d @ %p,\n", i, object->surfaces[j][i]);
         }
         tmpW = max(1, tmpW >> 1);
@@ -1402,7 +1402,7 @@ HRESULT WINAPI IWineD3DDeviceImpl_Create
                              &object->frontBuffer,
                              NULL /* pShared (always null)*/);
     if (object->frontBuffer != NULL)
-        IWineD3DSurface_SetContainer(object->frontBuffer, (IUnknown *)object);
+        IWineD3DSurface_SetContainer(object->frontBuffer, (IWineD3DBase *)object);
     TRACE("calling rendertarget CB\n");
     hr = D3DCB_CreateRenderTarget((IUnknown *) This->parent,
                              object->presentParms.BackBufferWidth,
@@ -1414,7 +1414,7 @@ HRESULT WINAPI IWineD3DDeviceImpl_Create
                              &object->backBuffer,
                              NULL /* pShared (always null)*/);
     if (object->backBuffer != NULL)
-        IWineD3DSurface_SetContainer(object->backBuffer, (IUnknown *)object);
+        IWineD3DSurface_SetContainer(object->backBuffer, (IWineD3DBase *)object);
 
     /* Under directX swapchains share the depth stencil, so only create one depth-stencil */
     if (pPresentationParameters->EnableAutoDepthStencil) {
@@ -1430,7 +1430,7 @@ HRESULT WINAPI IWineD3DDeviceImpl_Create
                                     &This->depthStencilBuffer,
                                     NULL /* pShared (always null)*/  );
             if (This->depthStencilBuffer != NULL)
-                IWineD3DSurface_SetContainer(This->depthStencilBuffer, (IUnknown *)iface);
+                IWineD3DSurface_SetContainer(This->depthStencilBuffer, (IWineD3DBase *)iface);
         }
 
         /** TODO: A check on width, height and multisample types
diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c
index 793f4e1..81079ae 100644
--- a/dlls/wined3d/surface.c
+++ b/dlls/wined3d/surface.c
@@ -1334,10 +1334,21 @@ extern HRESULT WINAPI IWineD3DSurfaceImp
     return D3D_OK;
 }
 
-HRESULT WINAPI IWineD3DSurfaceImpl_SetContainer(IWineD3DSurface *iface, IUnknown *container) {
+HRESULT WINAPI IWineD3DSurfaceImpl_SetContainer(IWineD3DSurface *iface, IWineD3DBase *container) {
     IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface;
+
+    TRACE("This %p, container %p\n", This, container);
+
+    if (container) {
+        IWineD3DBase_AddRef(container);
+    }
+    if (This->container) {
+        IWineD3DBase_Release(This->container);
+    }
+
     TRACE("Setting container to %p from %p\n", container, This->container);
     This->container = container;
+
     return D3D_OK;
 }
 
diff --git a/dlls/wined3d/volume.c b/dlls/wined3d/volume.c
index 1aec42d..826cef5 100644
--- a/dlls/wined3d/volume.c
+++ b/dlls/wined3d/volume.c
@@ -233,11 +233,22 @@ HRESULT WINAPI IWineD3DVolumeImpl_AddDir
   return D3D_OK;
 }
 
-HRESULT WINAPI IWineD3DVolumeImpl_SetContainer(IWineD3DVolume *iface, IUnknown* container){
-  IWineD3DVolumeImpl *This = (IWineD3DVolumeImpl *)iface;
+HRESULT WINAPI IWineD3DVolumeImpl_SetContainer(IWineD3DVolume *iface, IWineD3DBase* container) {
+    IWineD3DVolumeImpl *This = (IWineD3DVolumeImpl *)iface;
 
-  This->container = container;
-  return D3D_OK;
+    TRACE("This %p, container %p\n", This, container);
+
+    if (container) {
+        IWineD3DBase_AddRef(container);
+    }
+    if (This->container) {
+        IWineD3DBase_Release(This->container);
+    }
+
+    TRACE("Setting container to %p from %p\n", container, This->container);
+    This->container = container;
+
+    return D3D_OK;
 }
 
 HRESULT WINAPI IWineD3DVolumeImpl_LoadTexture(IWineD3DVolume *iface, GLenum gl_level) {
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index fbc3f0b..9ba687c 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -747,7 +747,7 @@ typedef struct IWineD3DVolumeImpl
 
     /* WineD3DVolume Information */
     D3DVOLUME_DESC          currentDesc;
-    IUnknown               *container;
+    IWineD3DBase            *container;
     UINT                    bytesPerPixel;
 
     BOOL                    lockable;
@@ -799,7 +799,7 @@ struct IWineD3DSurfaceImpl
     IWineD3DResourceClass     resource;
 
     /* IWineD3DSurface fields */
-    IUnknown                 *container;
+    IWineD3DBase              *container;
     WINED3DSURFACET_DESC      currentDesc;
 
     UINT                      textureName;
diff --git a/include/wine/wined3d_interface.h b/include/wine/wined3d_interface.h
index c0a0e2d..dac1d3a 100644
--- a/include/wine/wined3d_interface.h
+++ b/include/wine/wined3d_interface.h
@@ -1054,7 +1054,7 @@ DECLARE_INTERFACE_(IWineD3DSurface,IWine
     STDMETHOD(AddDirtyRect)(THIS_ CONST RECT* pRect) PURE;
     STDMETHOD(LoadTexture)(THIS) PURE;
     STDMETHOD(SaveSnapshot)(THIS_ const char *filename) PURE;
-    STDMETHOD(SetContainer)(THIS_ IUnknown *container) PURE;
+    STDMETHOD(SetContainer)(THIS_ IWineD3DBase *container) PURE;
     STDMETHOD(SetPBufferState)(THIS_ BOOL inPBuffer, BOOL  inTexture) PURE;
     STDMETHOD_(void,SetGlTextureDesc)(THIS_ UINT textureName, int target) PURE;
     STDMETHOD_(void,GetGlDesc)(THIS_ glDescriptor **glDescription) PURE;
@@ -1128,7 +1128,7 @@ DECLARE_INTERFACE_(IWineD3DVolume,IWineD
     STDMETHOD(AddDirtyBox)(THIS_ CONST D3DBOX* pDirtyBox) PURE;
     STDMETHOD(CleanDirtyBox)(THIS) PURE;
     STDMETHOD(LoadTexture)(THIS_ UINT gl_level) PURE;
-    STDMETHOD(SetContainer)(THIS_ IUnknown *container) PURE;
+    STDMETHOD(SetContainer)(THIS_ IWineD3DBase *container) PURE;
 };
 #undef INTERFACE
 






More information about the wine-patches mailing list