[PATCH 5/5] d3d8: The "forwardReference" field in struct d3d8_surface is always a texture, if set.

Henri Verbeet hverbeet at codeweavers.com
Tue Aug 12 04:11:04 CDT 2014


---
 dlls/d3d8/d3d8_private.h |   12 ++----
 dlls/d3d8/device.c       |   12 +-----
 dlls/d3d8/surface.c      |  107 ++++++++++++++++++++--------------------------
 3 files changed, 51 insertions(+), 80 deletions(-)

diff --git a/dlls/d3d8/d3d8_private.h b/dlls/d3d8/d3d8_private.h
index 27394ea..74f96ef 100644
--- a/dlls/d3d8/d3d8_private.h
+++ b/dlls/d3d8/d3d8_private.h
@@ -228,16 +228,12 @@ struct d3d8_surface
     struct d3d8_resource resource;
     struct wined3d_surface *wined3d_surface;
     IDirect3DDevice8 *parent_device;
-
-    /* The surface container */
-    IUnknown                    *container;
-
-    /* If set forward refcounting to this object */
-    IUnknown                    *forwardReference;
+    IUnknown *container;
+    struct d3d8_texture *texture;
 };
 
-void surface_init(struct d3d8_surface *surface, struct wined3d_surface *wined3d_surface,
-        struct d3d8_device *device, const struct wined3d_parent_ops **parent_ops) DECLSPEC_HIDDEN;
+void surface_init(struct d3d8_surface *surface, IUnknown *container_parent,
+        struct wined3d_surface *wined3d_surface, const struct wined3d_parent_ops **parent_ops) DECLSPEC_HIDDEN;
 struct d3d8_surface *unsafe_impl_from_IDirect3DSurface8(IDirect3DSurface8 *iface) DECLSPEC_HIDDEN;
 
 struct d3d8_vertexbuffer
diff --git a/dlls/d3d8/device.c b/dlls/d3d8/device.c
index 2ee2094..3ee43f0 100644
--- a/dlls/d3d8/device.c
+++ b/dlls/d3d8/device.c
@@ -918,7 +918,6 @@ static HRESULT d3d8_device_create_surface(struct d3d8_device *device, UINT width
 
     sub_resource = wined3d_texture_get_sub_resource(texture, 0);
     surface_impl = wined3d_resource_get_parent(sub_resource);
-    surface_impl->forwardReference = NULL;
     surface_impl->parent_device = &device->IDirect3DDevice8_iface;
     *surface = &surface_impl->IDirect3DSurface8_iface;
     IDirect3DSurface8_AddRef(*surface);
@@ -2940,7 +2939,6 @@ static HRESULT CDECL device_parent_surface_created(struct wined3d_device_parent
         void *container_parent, struct wined3d_surface *surface, void **parent,
         const struct wined3d_parent_ops **parent_ops)
 {
-    struct d3d8_device *device = device_from_device_parent(device_parent);
     struct d3d8_surface *d3d_surface;
 
     TRACE("device_parent %p, container_parent %p, surface %p, parent %p, parent_ops %p.\n",
@@ -2949,17 +2947,10 @@ static HRESULT CDECL device_parent_surface_created(struct wined3d_device_parent
     if (!(d3d_surface = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*d3d_surface))))
         return E_OUTOFMEMORY;
 
-    surface_init(d3d_surface, surface, device, parent_ops);
+    surface_init(d3d_surface, container_parent, surface, parent_ops);
     *parent = d3d_surface;
     TRACE("Created surface %p.\n", d3d_surface);
 
-    d3d_surface->container = container_parent;
-    IDirect3DDevice8_Release(d3d_surface->parent_device);
-    d3d_surface->parent_device = NULL;
-
-    IDirect3DSurface8_Release(&d3d_surface->IDirect3DSurface8_iface);
-    d3d_surface->forwardReference = container_parent;
-
     return D3D_OK;
 }
 
@@ -3008,7 +2999,6 @@ static HRESULT CDECL device_parent_create_swapchain_surface(struct wined3d_devic
     wined3d_texture_decref(texture);
 
     d3d_surface = wined3d_surface_get_parent(*surface);
-    d3d_surface->forwardReference = NULL;
     d3d_surface->parent_device = &device->IDirect3DDevice8_iface;
 
     return hr;
diff --git a/dlls/d3d8/surface.c b/dlls/d3d8/surface.c
index 9768946..d20d791 100644
--- a/dlls/d3d8/surface.c
+++ b/dlls/d3d8/surface.c
@@ -50,69 +50,60 @@ static HRESULT WINAPI d3d8_surface_QueryInterface(IDirect3DSurface8 *iface, REFI
 static ULONG WINAPI d3d8_surface_AddRef(IDirect3DSurface8 *iface)
 {
     struct d3d8_surface *surface = impl_from_IDirect3DSurface8(iface);
+    ULONG refcount;
 
     TRACE("iface %p.\n", iface);
 
-    if (surface->forwardReference)
+    if (surface->texture)
     {
-        /* Forward refcounting */
-        TRACE("Forwarding to %p.\n", surface->forwardReference);
-        return IUnknown_AddRef(surface->forwardReference);
+        TRACE("Forwarding to %p.\n", surface->texture);
+        return IDirect3DBaseTexture8_AddRef(&surface->texture->IDirect3DBaseTexture8_iface);
     }
-    else
-    {
-        /* No container, handle our own refcounting */
-        ULONG ref = InterlockedIncrement(&surface->resource.refcount);
 
-        TRACE("%p increasing refcount to %u.\n", iface, ref);
+    refcount = InterlockedIncrement(&surface->resource.refcount);
+    TRACE("%p increasing refcount to %u.\n", iface, refcount);
 
-        if (ref == 1)
-        {
-            if (surface->parent_device)
-                IDirect3DDevice8_AddRef(surface->parent_device);
-            wined3d_mutex_lock();
-            wined3d_surface_incref(surface->wined3d_surface);
-            wined3d_mutex_unlock();
-        }
-
-        return ref;
+    if (refcount == 1)
+    {
+        if (surface->parent_device)
+            IDirect3DDevice8_AddRef(surface->parent_device);
+        wined3d_mutex_lock();
+        wined3d_surface_incref(surface->wined3d_surface);
+        wined3d_mutex_unlock();
     }
+
+    return refcount;
 }
 
 static ULONG WINAPI d3d8_surface_Release(IDirect3DSurface8 *iface)
 {
     struct d3d8_surface *surface = impl_from_IDirect3DSurface8(iface);
+    ULONG refcount;
 
     TRACE("iface %p.\n", iface);
 
-    if (surface->forwardReference)
+    if (surface->texture)
     {
-        /* Forward refcounting */
-        TRACE("Forwarding to %p.\n", surface->forwardReference);
-        return IUnknown_Release(surface->forwardReference);
+        TRACE("Forwarding to %p.\n", surface->texture);
+        return IDirect3DBaseTexture8_Release(&surface->texture->IDirect3DBaseTexture8_iface);
     }
-    else
-    {
-        /* No container, handle our own refcounting */
-        ULONG ref = InterlockedDecrement(&surface->resource.refcount);
 
-        TRACE("%p decreasing refcount to %u.\n", iface, ref);
+    refcount = InterlockedDecrement(&surface->resource.refcount);
+    TRACE("%p decreasing refcount to %u.\n", iface, refcount);
 
-        if (!ref)
-        {
-            IDirect3DDevice8 *parent_device = surface->parent_device;
+    if (!refcount)
+    {
+        IDirect3DDevice8 *parent_device = surface->parent_device;
 
-            /* Implicit surfaces are destroyed with the device, not if refcount reaches 0. */
-            wined3d_mutex_lock();
-            wined3d_surface_decref(surface->wined3d_surface);
-            wined3d_mutex_unlock();
+        wined3d_mutex_lock();
+        wined3d_surface_decref(surface->wined3d_surface);
+        wined3d_mutex_unlock();
 
-            if (parent_device)
-                IDirect3DDevice8_Release(parent_device);
-        }
-
-        return ref;
+        if (parent_device)
+            IDirect3DDevice8_Release(parent_device);
     }
+
+    return refcount;
 }
 
 static HRESULT WINAPI d3d8_surface_GetDevice(IDirect3DSurface8 *iface, IDirect3DDevice8 **device)
@@ -121,22 +112,8 @@ static HRESULT WINAPI d3d8_surface_GetDevice(IDirect3DSurface8 *iface, IDirect3D
 
     TRACE("iface %p, device %p.\n", iface, device);
 
-    if (surface->forwardReference)
-    {
-        IDirect3DResource8 *resource;
-        HRESULT hr;
-
-        hr = IUnknown_QueryInterface(surface->forwardReference, &IID_IDirect3DResource8, (void **)&resource);
-        if (SUCCEEDED(hr))
-        {
-            hr = IDirect3DResource8_GetDevice(resource, device);
-            IDirect3DResource8_Release(resource);
-
-            TRACE("Returning device %p.\n", *device);
-        }
-
-        return hr;
-    }
+    if (surface->texture)
+        return IDirect3DBaseTexture8_GetDevice(&surface->texture->IDirect3DBaseTexture8_iface, device);
 
     *device = surface->parent_device;
     IDirect3DDevice8_AddRef(*device);
@@ -311,15 +288,23 @@ static const struct wined3d_parent_ops d3d8_surface_wined3d_parent_ops =
     surface_wined3d_object_destroyed,
 };
 
-void surface_init(struct d3d8_surface *surface, struct wined3d_surface *wined3d_surface,
-        struct d3d8_device *device, const struct wined3d_parent_ops **parent_ops)
+void surface_init(struct d3d8_surface *surface, IUnknown *container_parent,
+        struct wined3d_surface *wined3d_surface, const struct wined3d_parent_ops **parent_ops)
 {
+    IDirect3DBaseTexture8 *texture;
+
     surface->IDirect3DSurface8_iface.lpVtbl = &d3d8_surface_vtbl;
     d3d8_resource_init(&surface->resource);
-    wined3d_surface_incref(wined3d_surface);
+    surface->resource.refcount = 0;
     surface->wined3d_surface = wined3d_surface;
-    surface->parent_device = &device->IDirect3DDevice8_iface;
-    IDirect3DDevice8_AddRef(surface->parent_device);
+    surface->container = container_parent;
+
+    if (container_parent && SUCCEEDED(IUnknown_QueryInterface(container_parent,
+            &IID_IDirect3DBaseTexture8, (void **)&texture)))
+    {
+        surface->texture = unsafe_impl_from_IDirect3DBaseTexture8(texture);
+        IDirect3DBaseTexture8_Release(texture);
+    }
 
     *parent_ops = &d3d8_surface_wined3d_parent_ops;
 }
-- 
1.7.10.4




More information about the wine-patches mailing list