[PATCH 4/8] wined3d: Also store the subresource container type.

Henri Verbeet hverbeet at codeweavers.com
Mon Aug 16 13:00:25 CDT 2010


---
 dlls/wined3d/arb_program_shader.c |    3 ++-
 dlls/wined3d/context.c            |    9 +++++----
 dlls/wined3d/cubetexture.c        |    4 ++--
 dlls/wined3d/device.c             |   12 ++++++------
 dlls/wined3d/surface.c            |   28 +++++++++++-----------------
 dlls/wined3d/surface_base.c       |    2 +-
 dlls/wined3d/swapchain.c          |   10 +++++-----
 dlls/wined3d/swapchain_gdi.c      |    4 ++--
 dlls/wined3d/texture.c            |    4 ++--
 dlls/wined3d/wined3d_private.h    |   22 ++++++++++++++++++++--
 10 files changed, 56 insertions(+), 42 deletions(-)

diff --git a/dlls/wined3d/arb_program_shader.c b/dlls/wined3d/arb_program_shader.c
index ef78227..03443b4 100644
--- a/dlls/wined3d/arb_program_shader.c
+++ b/dlls/wined3d/arb_program_shader.c
@@ -7144,7 +7144,8 @@ HRESULT arbfp_blit_surface(IWineD3DDeviceImpl *device, IWineD3DSurfaceImpl *src_
      * Also beware of the origin difference(top left vs bottom left).
      * Also beware that the front buffer's surface size is screen width x screen height,
      * whereas the real gl drawable size is the size of the window. */
-    dst_swapchain = (dst_surface->Flags & SFLAG_SWAPCHAIN) ? (IWineD3DSwapChainImpl *)dst_surface->container : NULL;
+    dst_swapchain = dst_surface->container.type == WINED3D_CONTAINER_SWAPCHAIN
+            ? dst_surface->container.u.swapchain : NULL;
     if (dst_swapchain && dst_surface == dst_swapchain->front_buffer)
         surface_translate_frontbuffer_coords(dst_surface, context->win_handle, &dst_rect);
 
diff --git a/dlls/wined3d/context.c b/dlls/wined3d/context.c
index d7f2cf3..d94c0ad 100644
--- a/dlls/wined3d/context.c
+++ b/dlls/wined3d/context.c
@@ -1898,7 +1898,6 @@ static struct wined3d_context *findThreadContextForSwapChain(IWineD3DSwapChain *
  *****************************************************************************/
 static struct wined3d_context *FindContext(IWineD3DDeviceImpl *This, IWineD3DSurfaceImpl *target)
 {
-    IWineD3DSwapChain *swapchain = NULL;
     struct wined3d_context *current_context = context_get_current();
     DWORD tid = GetCurrentThreadId();
     struct wined3d_context *context;
@@ -1927,11 +1926,13 @@ static struct wined3d_context *FindContext(IWineD3DDeviceImpl *This, IWineD3DSur
         return current_context;
     }
 
-    if (target->Flags & SFLAG_SWAPCHAIN)
+    if (target->container.type == WINED3D_CONTAINER_SWAPCHAIN)
     {
+        IWineD3DSwapChain *swapchain;
+
         TRACE("Rendering onscreen\n");
 
-        swapchain = (IWineD3DSwapChain *)target->container;
+        swapchain = (IWineD3DSwapChain *)target->container.u.swapchain;
         context = findThreadContextForSwapChain(swapchain, tid);
     }
     else
@@ -2078,7 +2079,7 @@ static void context_validate_onscreen_formats(IWineD3DDeviceImpl *device,
         struct wined3d_context *context, IWineD3DSurfaceImpl *depth_stencil)
 {
     /* Onscreen surfaces are always in a swapchain */
-    IWineD3DSwapChainImpl *swapchain = (IWineD3DSwapChainImpl *)context->current_rt->container;
+    IWineD3DSwapChainImpl *swapchain = context->current_rt->container.u.swapchain;
 
     if (context->render_offscreen || !depth_stencil) return;
     if (match_depth_stencil_format(swapchain->ds_format, depth_stencil->resource.format_desc)) return;
diff --git a/dlls/wined3d/cubetexture.c b/dlls/wined3d/cubetexture.c
index d10da49..acdf4d3 100644
--- a/dlls/wined3d/cubetexture.c
+++ b/dlls/wined3d/cubetexture.c
@@ -127,7 +127,7 @@ static void cubetexture_cleanup(IWineD3DCubeTextureImpl *This)
             surface_set_texture_name(surface, 0, TRUE);
             surface_set_texture_name(surface, 0, FALSE);
             surface_set_texture_target(surface, 0);
-            surface_set_container(surface, NULL);
+            surface_set_container(surface, WINED3D_CONTAINER_NONE, NULL);
             IWineD3DSurface_Release((IWineD3DSurface *)surface);
         }
     }
@@ -558,7 +558,7 @@ HRESULT cubetexture_init(IWineD3DCubeTextureImpl *texture, UINT edge_length, UIN
                 return hr;
             }
 
-            surface_set_container((IWineD3DSurfaceImpl *)surface, (IWineD3DBase *)texture);
+            surface_set_container((IWineD3DSurfaceImpl *)surface, WINED3D_CONTAINER_TEXTURE, (IWineD3DBase *)texture);
             surface_set_texture_target((IWineD3DSurfaceImpl *)surface, cube_targets[j]);
             texture->baseTexture.sub_resources[idx] = (IWineD3DResourceImpl *)surface;
             TRACE("Created surface level %u @ %p.\n", i, surface);
diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c
index ac28226..057c107 100644
--- a/dlls/wined3d/device.c
+++ b/dlls/wined3d/device.c
@@ -804,8 +804,8 @@ HRESULT device_clear_render_targets(IWineD3DDeviceImpl *device, UINT rt_count, I
 
     LEAVE_GL();
 
-    if (wined3d_settings.strict_draw_ordering || ((target->Flags & SFLAG_SWAPCHAIN)
-            && ((IWineD3DSwapChainImpl *)target->container)->front_buffer == target))
+    if (wined3d_settings.strict_draw_ordering || (target->container.type == WINED3D_CONTAINER_SWAPCHAIN
+            && target->container.u.swapchain->front_buffer == target))
         wglFlush(); /* Flush to ensure ordering across contexts. */
 
     context_release(context);
@@ -5651,14 +5651,14 @@ static HRESULT WINAPI IWineD3DDeviceImpl_SetFrontBackBuffers(IWineD3DDevice *ifa
 
         if (swapchain->front_buffer)
         {
-            surface_set_container(swapchain->front_buffer, NULL);
+            surface_set_container(swapchain->front_buffer, WINED3D_CONTAINER_NONE, NULL);
             swapchain->front_buffer->Flags &= ~SFLAG_SWAPCHAIN;
         }
         swapchain->front_buffer = front_impl;
 
         if (front_impl)
         {
-            surface_set_container(front_impl, (IWineD3DBase *)swapchain);
+            surface_set_container(front_impl, WINED3D_CONTAINER_SWAPCHAIN, (IWineD3DBase *)swapchain);
             front_impl->Flags |= SFLAG_SWAPCHAIN;
         }
     }
@@ -5669,7 +5669,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_SetFrontBackBuffers(IWineD3DDevice *ifa
 
         if (swapchain->back_buffers[0])
         {
-            surface_set_container(swapchain->back_buffers[0], NULL);
+            surface_set_container(swapchain->back_buffers[0], WINED3D_CONTAINER_TEXTURE, NULL);
             swapchain->back_buffers[0]->Flags &= ~SFLAG_SWAPCHAIN;
         }
         swapchain->back_buffers[0] = back_impl;
@@ -5681,7 +5681,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_SetFrontBackBuffers(IWineD3DDevice *ifa
             swapchain->presentParms.BackBufferFormat = back_impl->resource.format_desc->format;
             swapchain->presentParms.BackBufferCount = 1;
 
-            surface_set_container(back_impl, (IWineD3DBase *)swapchain);
+            surface_set_container(back_impl, WINED3D_CONTAINER_SWAPCHAIN, (IWineD3DBase *)swapchain);
             back_impl->Flags |= SFLAG_SWAPCHAIN;
         }
         else
diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c
index 20c7685..f9771ba 100644
--- a/dlls/wined3d/surface.c
+++ b/dlls/wined3d/surface.c
@@ -92,20 +92,13 @@ static void surface_cleanup(IWineD3DSurfaceImpl *This)
     resource_cleanup((IWineD3DResource *)This);
 }
 
-void surface_set_container(IWineD3DSurfaceImpl *surface, IWineD3DBase *container)
+void surface_set_container(IWineD3DSurfaceImpl *surface, enum wined3d_container_type type, IWineD3DBase *container)
 {
-    IWineD3DSwapChain *swapchain = NULL;
-
     TRACE("surface %p, container %p.\n", surface, container);
 
-    if (container)
-    {
-        IWineD3DBase_QueryInterface(container, &IID_IWineD3DSwapChain, (void **)&swapchain);
-    }
-    if (swapchain)
+    if (type == WINED3D_CONTAINER_SWAPCHAIN)
     {
         surface->get_drawable_size = get_drawable_size_swapchain;
-        IWineD3DSwapChain_Release(swapchain);
     }
     else
     {
@@ -125,7 +118,8 @@ void surface_set_container(IWineD3DSurfaceImpl *surface, IWineD3DBase *container
         }
     }
 
-    surface->container = container;
+    surface->container.type = type;
+    surface->container.u.base = container;
 }
 
 struct blt_info
@@ -396,7 +390,7 @@ HRESULT surface_init(IWineD3DSurfaceImpl *surface, WINED3DSURFTYPE surface_type,
     }
 
     /* "Standalone" surface. */
-    surface_set_container(surface, NULL);
+    surface_set_container(surface, WINED3D_CONTAINER_NONE, NULL);
 
     surface->currentDesc.Width = width;
     surface->currentDesc.Height = height;
@@ -928,11 +922,11 @@ void surface_set_compatible_renderbuffer(IWineD3DSurfaceImpl *surface, unsigned
 
 GLenum surface_get_gl_buffer(IWineD3DSurfaceImpl *surface)
 {
-    IWineD3DSwapChainImpl *swapchain = (IWineD3DSwapChainImpl *)surface->container;
+    IWineD3DSwapChainImpl *swapchain = surface->container.u.swapchain;
 
     TRACE("surface %p.\n", surface);
 
-    if (!(surface->Flags & SFLAG_SWAPCHAIN))
+    if (surface->container.type != WINED3D_CONTAINER_SWAPCHAIN)
     {
         ERR("Surface %p is not on a swapchain.\n", surface);
         return GL_NONE;
@@ -4359,7 +4353,8 @@ static inline void surface_blt_to_drawable(IWineD3DSurfaceImpl *This, const RECT
         dst_rect = src_rect;
     }
 
-    if ((This->Flags & SFLAG_SWAPCHAIN) && This == ((IWineD3DSwapChainImpl *)This->container)->front_buffer)
+    swapchain = This->container.type == WINED3D_CONTAINER_SWAPCHAIN ? This->container.u.swapchain : NULL;
+    if (swapchain && This == swapchain->front_buffer)
         surface_translate_frontbuffer_coords(This, context->win_handle, &dst_rect);
 
     device->blitter->set_shader((IWineD3DDevice *) device, This);
@@ -4370,7 +4365,6 @@ static inline void surface_blt_to_drawable(IWineD3DSurfaceImpl *This, const RECT
 
     device->blitter->unset_shader((IWineD3DDevice *) device);
 
-    swapchain = (This->Flags & SFLAG_SWAPCHAIN) ? (IWineD3DSwapChainImpl *)This->container : NULL;
     if (wined3d_settings.strict_draw_ordering || (swapchain
             && (This == swapchain->front_buffer || swapchain->num_contexts > 1)))
         wglFlush(); /* Flush to ensure ordering across contexts. */
@@ -4708,10 +4702,10 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_DrawOverlay(IWineD3DSurface *iface) {
 
 BOOL surface_is_offscreen(IWineD3DSurfaceImpl *surface)
 {
-    IWineD3DSwapChainImpl *swapchain = (IWineD3DSwapChainImpl *)surface->container;
+    IWineD3DSwapChainImpl *swapchain = surface->container.u.swapchain;
 
     /* Not on a swapchain - must be offscreen */
-    if (!(surface->Flags & SFLAG_SWAPCHAIN)) return TRUE;
+    if (surface->container.type != WINED3D_CONTAINER_SWAPCHAIN) return TRUE;
 
     /* The front buffer is always onscreen */
     if (surface == swapchain->front_buffer) return FALSE;
diff --git a/dlls/wined3d/surface_base.c b/dlls/wined3d/surface_base.c
index a215176..a7ac270 100644
--- a/dlls/wined3d/surface_base.c
+++ b/dlls/wined3d/surface_base.c
@@ -159,7 +159,7 @@ HRESULT WINAPI IWineD3DBaseSurfaceImpl_GetContainer(IWineD3DSurface* iface, REFI
     }
 
     /* Standalone surfaces return the device as container. */
-    if (This->container) container = This->container;
+    if (This->container.u.base) container = This->container.u.base;
     else container = (IWineD3DBase *)This->resource.device;
 
     TRACE("Relaying to QueryInterface\n");
diff --git a/dlls/wined3d/swapchain.c b/dlls/wined3d/swapchain.c
index 7657552..ea38bf1 100644
--- a/dlls/wined3d/swapchain.c
+++ b/dlls/wined3d/swapchain.c
@@ -48,7 +48,7 @@ static void WINAPI IWineD3DSwapChainImpl_Destroy(IWineD3DSwapChain *iface)
      * the last buffer to be destroyed, FindContext() depends on that. */
     if (This->front_buffer)
     {
-        surface_set_container(This->front_buffer, NULL);
+        surface_set_container(This->front_buffer, WINED3D_CONTAINER_NONE, NULL);
         if (IWineD3DSurface_Release((IWineD3DSurface *)This->front_buffer))
         {
             WARN("(%p) Something's still holding the front buffer (%p).\n",
@@ -63,7 +63,7 @@ static void WINAPI IWineD3DSwapChainImpl_Destroy(IWineD3DSwapChain *iface)
 
         while (i--)
         {
-            surface_set_container(This->back_buffers[i], NULL);
+            surface_set_container(This->back_buffers[i], WINED3D_CONTAINER_NONE, NULL);
             if (IWineD3DSurface_Release((IWineD3DSurface *)This->back_buffers[i]))
                 WARN("(%p) Something's still holding back buffer %u (%p).\n",
                         This, i, This->back_buffers[i]);
@@ -731,7 +731,7 @@ HRESULT swapchain_init(IWineD3DSwapChainImpl *swapchain, WINED3DSURFTYPE surface
         goto err;
     }
 
-    surface_set_container(swapchain->front_buffer, (IWineD3DBase *)swapchain);
+    surface_set_container(swapchain->front_buffer, WINED3D_CONTAINER_SWAPCHAIN, (IWineD3DBase *)swapchain);
     swapchain->front_buffer->Flags |= SFLAG_SWAPCHAIN;
     if (surface_type == SURFACE_OPENGL)
     {
@@ -847,7 +847,7 @@ HRESULT swapchain_init(IWineD3DSwapChainImpl *swapchain, WINED3DSURFTYPE surface
                 goto err;
             }
 
-            surface_set_container(swapchain->back_buffers[i], (IWineD3DBase *)swapchain);
+            surface_set_container(swapchain->back_buffers[i], WINED3D_CONTAINER_SWAPCHAIN, (IWineD3DBase *)swapchain);
             swapchain->back_buffers[i]->Flags |= SFLAG_SWAPCHAIN;
         }
     }
@@ -869,7 +869,7 @@ HRESULT swapchain_init(IWineD3DSwapChainImpl *swapchain, WINED3DSURFTYPE surface
                 goto err;
             }
 
-            surface_set_container(device->auto_depth_stencil, NULL);
+            surface_set_container(device->auto_depth_stencil, WINED3D_CONTAINER_NONE, NULL);
         }
     }
 
diff --git a/dlls/wined3d/swapchain_gdi.c b/dlls/wined3d/swapchain_gdi.c
index a270b81..250485b 100644
--- a/dlls/wined3d/swapchain_gdi.c
+++ b/dlls/wined3d/swapchain_gdi.c
@@ -39,7 +39,7 @@ static void WINAPI IWineGDISwapChainImpl_Destroy(IWineD3DSwapChain *iface)
     /* release the ref to the front and back buffer parents */
     if (This->front_buffer)
     {
-        surface_set_container(This->front_buffer, NULL);
+        surface_set_container(This->front_buffer, WINED3D_CONTAINER_NONE, NULL);
         if (IWineD3DSurface_Release((IWineD3DSurface *)This->front_buffer) > 0)
         {
             WARN("(%p) Something's still holding the front buffer\n",This);
@@ -51,7 +51,7 @@ static void WINAPI IWineGDISwapChainImpl_Destroy(IWineD3DSwapChain *iface)
         UINT i;
         for (i = 0; i < This->presentParms.BackBufferCount; ++i)
         {
-            surface_set_container(This->back_buffers[i], NULL);
+            surface_set_container(This->back_buffers[i], WINED3D_CONTAINER_NONE, NULL);
             if (IWineD3DSurface_Release((IWineD3DSurface *)This->back_buffers[i]))
             {
                 WARN("(%p) Something's still holding the back buffer\n",This);
diff --git a/dlls/wined3d/texture.c b/dlls/wined3d/texture.c
index 7147850..e3c0bb5 100644
--- a/dlls/wined3d/texture.c
+++ b/dlls/wined3d/texture.c
@@ -119,7 +119,7 @@ static void texture_cleanup(IWineD3DTextureImpl *This)
             surface_set_texture_name(surface, 0, TRUE);
             surface_set_texture_name(surface, 0, FALSE);
             surface_set_texture_target(surface, 0);
-            surface_set_container(surface, NULL);
+            surface_set_container(surface, WINED3D_CONTAINER_NONE, NULL);
             IWineD3DSurface_Release((IWineD3DSurface *)surface);
         }
     }
@@ -611,7 +611,7 @@ HRESULT texture_init(IWineD3DTextureImpl *texture, UINT width, UINT height, UINT
             return hr;
         }
 
-        surface_set_container((IWineD3DSurfaceImpl *)surface, (IWineD3DBase *)texture);
+        surface_set_container((IWineD3DSurfaceImpl *)surface, WINED3D_CONTAINER_TEXTURE, (IWineD3DBase *)texture);
         surface_set_texture_target((IWineD3DSurfaceImpl *)surface, texture->target);
         texture->baseTexture.sub_resources[i] = (IWineD3DResourceImpl *)surface;
         TRACE("Created surface level %u @ %p.\n", i, surface);
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index 7f59d24..384af7d 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -2000,6 +2000,23 @@ typedef struct IWineD3DClipperImpl
     HWND hWnd;
 } IWineD3DClipperImpl;
 
+enum wined3d_container_type
+{
+    WINED3D_CONTAINER_NONE = 0,
+    WINED3D_CONTAINER_SWAPCHAIN,
+    WINED3D_CONTAINER_TEXTURE,
+};
+
+struct wined3d_subresource_container
+{
+    enum wined3d_container_type type;
+    union
+    {
+        struct IWineD3DBase *base;
+        struct IWineD3DSwapChainImpl *swapchain;
+        struct IWineD3DBaseTextureImpl *texture;
+    } u;
+};
 
 /*****************************************************************************
  * IWineD3DSurface implementation structure
@@ -2011,7 +2028,7 @@ struct IWineD3DSurfaceImpl
     IWineD3DResourceClass     resource;
 
     /* IWineD3DSurface fields */
-    IWineD3DBase              *container;
+    struct wined3d_subresource_container container;
     WINED3DSURFACET_DESC      currentDesc;
     IWineD3DPaletteImpl       *palette; /* D3D7 style palette handling */
     PALETTEENTRY              *palette9; /* D3D8/9 style palette handling */
@@ -2087,7 +2104,8 @@ void surface_prepare_texture(IWineD3DSurfaceImpl *surface,
         const struct wined3d_gl_info *gl_info, BOOL srgb) DECLSPEC_HIDDEN;
 void surface_set_compatible_renderbuffer(IWineD3DSurfaceImpl *surface,
         unsigned int width, unsigned int height) DECLSPEC_HIDDEN;
-void surface_set_container(IWineD3DSurfaceImpl *surface, IWineD3DBase *container) DECLSPEC_HIDDEN;
+void surface_set_container(IWineD3DSurfaceImpl *surface,
+        enum wined3d_container_type type, IWineD3DBase *container) DECLSPEC_HIDDEN;
 void surface_set_texture_name(IWineD3DSurfaceImpl *surface, GLuint name, BOOL srgb_name) DECLSPEC_HIDDEN;
 void surface_set_texture_target(IWineD3DSurfaceImpl *surface, GLenum target) DECLSPEC_HIDDEN;
 void surface_translate_frontbuffer_coords(IWineD3DSurfaceImpl *surface, HWND window, RECT *rect) DECLSPEC_HIDDEN;
-- 
1.7.1




More information about the wine-patches mailing list