[PATCH 6/8] wined3d: Avoid IWineD3DSurface_GetContainer().

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


---
 dlls/wined3d/context.c     |    8 +--
 dlls/wined3d/surface.c     |  139 ++++++++++++++++++++------------------------
 dlls/wined3d/surface_gdi.c |   18 +++---
 3 files changed, 73 insertions(+), 92 deletions(-)

diff --git a/dlls/wined3d/context.c b/dlls/wined3d/context.c
index d94c0ad..f80ab4f 100644
--- a/dlls/wined3d/context.c
+++ b/dlls/wined3d/context.c
@@ -114,12 +114,10 @@ static void context_destroy_fbo(struct wined3d_context *context, GLuint *fbo)
 /* GL locking is done by the caller */
 static void context_apply_attachment_filter_states(IWineD3DSurfaceImpl *surface, DWORD location)
 {
-    IWineD3DBaseTextureImpl *texture_impl;
-
     /* Update base texture states array */
-    if (SUCCEEDED(IWineD3DSurface_GetContainer((IWineD3DSurface *)surface,
-            &IID_IWineD3DBaseTexture, (void **)&texture_impl)))
+    if (surface->container.type == WINED3D_CONTAINER_TEXTURE)
     {
+        IWineD3DBaseTextureImpl *texture_impl = surface->container.u.texture;
         IWineD3DDeviceImpl *device = surface->resource.device;
         BOOL update_minfilter = FALSE;
         BOOL update_magfilter = FALSE;
@@ -161,8 +159,6 @@ static void context_apply_attachment_filter_states(IWineD3DSurfaceImpl *surface,
             IWineD3DDeviceImpl_MarkStateDirty(device, STATE_SAMPLER(texture_impl->baseTexture.sampler));
         }
 
-        IWineD3DBaseTexture_Release((IWineD3DBaseTexture *)texture_impl);
-
         if (update_minfilter || update_magfilter)
         {
             GLenum target, bind_target;
diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c
index d264e18..760eadf 100644
--- a/dlls/wined3d/surface.c
+++ b/dlls/wined3d/surface.c
@@ -288,7 +288,6 @@ static inline void surface_get_rect(IWineD3DSurfaceImpl *This, const RECT *rect_
 /* GL locking and context activation is done by the caller */
 void draw_textured_quad(IWineD3DSurfaceImpl *src_surface, const RECT *src_rect, const RECT *dst_rect, WINED3DTEXTUREFILTERTYPE Filter)
 {
-    IWineD3DBaseTextureImpl *texture;
     struct blt_info info;
 
     surface_get_blt_info(src_surface->texture_target, src_rect, src_surface->pow2Width, src_surface->pow2Height, &info);
@@ -333,12 +332,12 @@ void draw_textured_quad(IWineD3DSurfaceImpl *src_surface, const RECT *src_rect,
 
     /* We changed the filtering settings on the texture. Inform the
      * container about this to get the filters reset properly next draw. */
-    if (SUCCEEDED(IWineD3DSurface_GetContainer((IWineD3DSurface *)src_surface, &IID_IWineD3DBaseTexture, (void **)&texture)))
+    if (src_surface->container.type == WINED3D_CONTAINER_TEXTURE)
     {
+        IWineD3DBaseTextureImpl *texture = src_surface->container.u.texture;
         texture->baseTexture.texture_rgb.states[WINED3DTEXSTA_MAGFILTER] = WINED3DTEXF_POINT;
         texture->baseTexture.texture_rgb.states[WINED3DTEXSTA_MINFILTER] = WINED3DTEXF_POINT;
         texture->baseTexture.texture_rgb.states[WINED3DTEXSTA_MIPFILTER] = WINED3DTEXF_NONE;
-        IWineD3DBaseTexture_Release((IWineD3DBaseTexture *)texture);
     }
 }
 
@@ -955,8 +954,6 @@ GLenum surface_get_gl_buffer(IWineD3DSurfaceImpl *surface)
 /* Slightly inefficient way to handle multiple dirty rects but it works :) */
 void surface_add_dirty_rect(IWineD3DSurfaceImpl *surface, const RECT *dirty_rect)
 {
-    IWineD3DBaseTexture *baseTexture = NULL;
-
     TRACE("surface %p, dirty_rect %s.\n", surface, wine_dbgstr_rect(dirty_rect));
 
     if (!(surface->Flags & SFLAG_INSYSMEM) && (surface->Flags & SFLAG_INTEXTURE))
@@ -980,12 +977,10 @@ void surface_add_dirty_rect(IWineD3DSurfaceImpl *surface, const RECT *dirty_rect
     }
 
     /* if the container is a basetexture then mark it dirty. */
-    if (SUCCEEDED(IWineD3DSurface_GetContainer((IWineD3DSurface *)surface,
-            &IID_IWineD3DBaseTexture, (void **)&baseTexture)))
+    if (surface->container.type == WINED3D_CONTAINER_TEXTURE)
     {
-        TRACE("Passing to container\n");
-        IWineD3DBaseTexture_SetDirty(baseTexture, TRUE);
-        IWineD3DBaseTexture_Release(baseTexture);
+        TRACE("Passing to container.\n");
+        IWineD3DBaseTexture_SetDirty((IWineD3DBaseTexture *)surface->container.u.texture, TRUE);
     }
 }
 
@@ -1068,19 +1063,19 @@ static ULONG WINAPI IWineD3DSurfaceImpl_Release(IWineD3DSurface *iface)
 
 void surface_internal_preload(IWineD3DSurfaceImpl *surface, enum WINED3DSRGB srgb)
 {
-    /* TODO: check for locks */
     IWineD3DDeviceImpl *device = surface->resource.device;
-    IWineD3DBaseTexture *baseTexture = NULL;
 
-    TRACE("(%p)Checking to see if the container is a base texture\n", surface);
-    if (SUCCEEDED(IWineD3DSurface_GetContainer((IWineD3DSurface *)surface,
-            &IID_IWineD3DBaseTexture, (void **)&baseTexture)))
+    TRACE("iface %p, srgb %#x.\n", surface, srgb);
+
+    if (surface->container.type == WINED3D_CONTAINER_TEXTURE)
+    {
+        IWineD3DBaseTextureImpl *texture = surface->container.u.texture;
+
+        TRACE("Passing to container.\n");
+        texture->baseTexture.internal_preload((IWineD3DBaseTexture *)texture, srgb);
+    }
+    else
     {
-        IWineD3DBaseTextureImpl *tex_impl = (IWineD3DBaseTextureImpl *)baseTexture;
-        TRACE("Passing to container\n");
-        tex_impl->baseTexture.internal_preload(baseTexture, srgb);
-        IWineD3DBaseTexture_Release(baseTexture);
-    } else {
         struct wined3d_context *context = NULL;
 
         TRACE("(%p) : About to load surface\n", surface);
@@ -1165,8 +1160,8 @@ BOOL surface_init_sysmem(IWineD3DSurfaceImpl *surface)
     return TRUE;
 }
 
-static void WINAPI IWineD3DSurfaceImpl_UnLoad(IWineD3DSurface *iface) {
-    IWineD3DBaseTexture *texture = NULL;
+static void WINAPI IWineD3DSurfaceImpl_UnLoad(IWineD3DSurface *iface)
+{
     IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *) iface;
     IWineD3DDeviceImpl *device = This->resource.device;
     const struct wined3d_gl_info *gl_info;
@@ -1219,19 +1214,16 @@ static void WINAPI IWineD3DSurfaceImpl_UnLoad(IWineD3DSurface *iface) {
     list_init(&This->renderbuffers);
     This->current_renderbuffer = NULL;
 
-    /* If we're in a texture, the texture name belongs to the texture. Otherwise,
-     * destroy it
-     */
-    IWineD3DSurface_GetContainer(iface, &IID_IWineD3DBaseTexture, (void **) &texture);
-    if(!texture) {
+    /* If we're in a texture, the texture name belongs to the texture.
+     * Otherwise, destroy it. */
+    if (This->container.type != WINED3D_CONTAINER_TEXTURE)
+    {
         ENTER_GL();
         glDeleteTextures(1, &This->texture_name);
         This->texture_name = 0;
         glDeleteTextures(1, &This->texture_name_srgb);
         This->texture_name_srgb = 0;
         LEAVE_GL();
-    } else {
-        IWineD3DBaseTexture_Release(texture);
     }
 
     context_release(context);
@@ -1555,11 +1547,9 @@ static void surface_prepare_texture_internal(IWineD3DSurfaceImpl *surface,
 /* Context activation is done by the caller. */
 void surface_prepare_texture(IWineD3DSurfaceImpl *surface, const struct wined3d_gl_info *gl_info, BOOL srgb)
 {
-    IWineD3DBaseTextureImpl *texture;
-
-    if (SUCCEEDED(IWineD3DSurface_GetContainer((IWineD3DSurface *)surface,
-            &IID_IWineD3DBaseTexture, (void **)&texture)))
+    if (surface->container.type == WINED3D_CONTAINER_TEXTURE)
     {
+        IWineD3DBaseTextureImpl *texture = surface->container.u.texture;
         UINT sub_count = texture->baseTexture.level_count * texture->baseTexture.layer_count;
         UINT i;
 
@@ -1571,8 +1561,6 @@ void surface_prepare_texture(IWineD3DSurfaceImpl *surface, const struct wined3d_
             surface_prepare_texture_internal(s, gl_info, srgb);
         }
 
-        IWineD3DBaseTexture_Release((IWineD3DBaseTexture *)texture);
-
         return;
     }
 
@@ -1736,20 +1724,18 @@ lock_end:
 
     if (Flags & (WINED3DLOCK_NO_DIRTY_UPDATE | WINED3DLOCK_READONLY)) {
         /* Don't dirtify */
-    } else {
-        IWineD3DBaseTexture *pBaseTexture;
-        /**
-         * Dirtify on lock
-         * as seen in msdn docs
-         */
+    }
+    else
+    {
         surface_add_dirty_rect(This, pRect);
 
-        /** Dirtify Container if needed */
-        if (SUCCEEDED(IWineD3DSurface_GetContainer(iface, &IID_IWineD3DBaseTexture, (void **)&pBaseTexture))) {
-            TRACE("Making container dirty\n");
-            IWineD3DBaseTexture_SetDirty(pBaseTexture, TRUE);
-            IWineD3DBaseTexture_Release(pBaseTexture);
-        } else {
+        if (This->container.type == WINED3D_CONTAINER_TEXTURE)
+        {
+            TRACE("Making container dirty.\n");
+            IWineD3DBaseTexture_SetDirty((IWineD3DBaseTexture *)This->container.u.texture, TRUE);
+        }
+        else
+        {
             TRACE("Surface is standalone, no need to dirty the container\n");
         }
     }
@@ -1946,15 +1932,15 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_UnlockRect(IWineD3DSurface *iface) {
         FIXME("Depth Stencil buffer locking is not implemented\n");
     } else {
         /* The rest should be a normal texture */
-        IWineD3DBaseTextureImpl *impl;
         /* Check if the texture is bound, if yes dirtify the sampler to force a re-upload of the texture
          * Can't load the texture here because PreLoad may destroy and recreate the gl texture, so sampler
          * states need resetting
          */
-        if(IWineD3DSurface_GetContainer(iface, &IID_IWineD3DBaseTexture, (void **)&impl) == WINED3D_OK) {
-            if (impl->baseTexture.bindCount)
-                IWineD3DDeviceImpl_MarkStateDirty(device, STATE_SAMPLER(impl->baseTexture.sampler));
-            IWineD3DBaseTexture_Release((IWineD3DBaseTexture *) impl);
+        if (This->container.type == WINED3D_CONTAINER_TEXTURE)
+        {
+            IWineD3DBaseTextureImpl *texture = This->container.u.texture;
+            if (texture->baseTexture.bindCount)
+                IWineD3DDeviceImpl_MarkStateDirty(device, STATE_SAMPLER(texture->baseTexture.sampler));
         }
     }
 
@@ -2549,16 +2535,16 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_LoadTexture(IWineD3DSurface *iface, BO
 }
 
 /* Context activation is done by the caller. */
-static void WINAPI IWineD3DSurfaceImpl_BindTexture(IWineD3DSurface *iface, BOOL srgb) {
-    /* TODO: check for locks */
+static void WINAPI IWineD3DSurfaceImpl_BindTexture(IWineD3DSurface *iface, BOOL srgb)
+{
     IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface;
-    IWineD3DBaseTexture *baseTexture = NULL;
 
-    TRACE("(%p)Checking to see if the container is a base texture\n", This);
-    if (IWineD3DSurface_GetContainer(iface, &IID_IWineD3DBaseTexture, (void **)&baseTexture) == WINED3D_OK) {
-        TRACE("Passing to container\n");
-        IWineD3DBaseTexture_BindTexture(baseTexture, srgb);
-        IWineD3DBaseTexture_Release(baseTexture);
+    TRACE("iface %p, srgb %#x.\n", iface, srgb);
+
+    if (This->container.type == WINED3D_CONTAINER_TEXTURE)
+    {
+        TRACE("Passing to container.\n");
+        IWineD3DBaseTexture_BindTexture((IWineD3DBaseTexture *)This->container.u.texture, srgb);
     }
     else
     {
@@ -2779,11 +2765,12 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_Flip(IWineD3DSurface *iface, IWineD3DS
          */
     }
 
-    IWineD3DSurface_GetContainer(iface, &IID_IWineD3DSwapChain, (void **) &swapchain);
-    if(!swapchain) {
+    if (This->container.type != WINED3D_CONTAINER_SWAPCHAIN)
+    {
         ERR("Flipped surface is not on a swapchain\n");
         return WINEDDERR_NOTFLIPPABLE;
     }
+    swapchain = This->container.u.swapchain;
 
     /* Just overwrite the swapchain presentation interval. This is ok because only ddraw apps can call Flip,
      * and only d3d8 and d3d9 apps specify the presentation interval
@@ -3025,8 +3012,8 @@ static void fb_copy_to_texture_hwstretch(IWineD3DSurfaceImpl *dst_surface, IWine
             wined3d_gl_min_mip_filter(minMipLookup, Filter, WINED3DTEXF_NONE));
     checkGLcall("glTexParameteri");
 
-    IWineD3DSurface_GetContainer((IWineD3DSurface *)src_surface, &IID_IWineD3DSwapChain, (void **)&src_swapchain);
-    if (src_swapchain) IWineD3DSwapChain_Release((IWineD3DSwapChain *)src_swapchain);
+    if (src_surface->container.type == WINED3D_CONTAINER_SWAPCHAIN)
+        src_swapchain = src_surface->container.u.swapchain;
     if (!src_swapchain || src_surface == src_swapchain->back_buffers[0])
     {
         src = backup ? backup : src_surface->texture_name;
@@ -3384,8 +3371,10 @@ static HRESULT IWineD3DSurfaceImpl_BltOverride(IWineD3DSurfaceImpl *dst_surface,
         WARN("Destination is in sysmem, rejecting gl blt\n");
         return WINED3DERR_INVALIDCALL;
     }
-    IWineD3DSurface_GetContainer((IWineD3DSurface *)dst_surface, &IID_IWineD3DSwapChain, (void **)&dstSwapchain);
-    if (dstSwapchain) IWineD3DSwapChain_Release((IWineD3DSwapChain *)dstSwapchain);
+
+    if (dst_surface->container.type == WINED3D_CONTAINER_SWAPCHAIN)
+        dstSwapchain = dst_surface->container.u.swapchain;
+
     if (src_surface)
     {
         if (src_surface->resource.pool == WINED3DPOOL_SYSTEMMEM)
@@ -3393,8 +3382,9 @@ static HRESULT IWineD3DSurfaceImpl_BltOverride(IWineD3DSurfaceImpl *dst_surface,
             WARN("Src is in sysmem, rejecting gl blt\n");
             return WINED3DERR_INVALIDCALL;
         }
-        IWineD3DSurface_GetContainer((IWineD3DSurface *)src_surface, &IID_IWineD3DSwapChain, (void **)&srcSwapchain);
-        if (srcSwapchain) IWineD3DSwapChain_Release((IWineD3DSwapChain *)srcSwapchain);
+
+        if (src_surface->container.type == WINED3D_CONTAINER_SWAPCHAIN)
+            srcSwapchain = src_surface->container.u.swapchain;
     }
 
     /* Early sort out of cases where no render target is used */
@@ -4266,7 +4256,6 @@ void surface_load_ds_location(IWineD3DSurfaceImpl *surface, struct wined3d_conte
 
 void surface_modify_location(IWineD3DSurfaceImpl *surface, DWORD flag, BOOL persistent)
 {
-    IWineD3DBaseTexture *texture;
     IWineD3DSurfaceImpl *overlay;
 
     TRACE("surface %p, location %s, persistent %#x.\n",
@@ -4290,12 +4279,10 @@ void surface_modify_location(IWineD3DSurfaceImpl *surface, DWORD flag, BOOL pers
         if (((surface->Flags & SFLAG_INTEXTURE) && !(flag & SFLAG_INTEXTURE))
                 || ((surface->Flags & SFLAG_INSRGBTEX) && !(flag & SFLAG_INSRGBTEX)))
         {
-            if (SUCCEEDED(IWineD3DSurface_GetContainer((IWineD3DSurface *)surface,
-                    &IID_IWineD3DBaseTexture, (void **)&texture)))
+            if (surface->container.type == WINED3D_CONTAINER_TEXTURE)
             {
                 TRACE("Passing to container.\n");
-                IWineD3DBaseTexture_SetDirty(texture, TRUE);
-                IWineD3DBaseTexture_Release(texture);
+                IWineD3DBaseTexture_SetDirty((IWineD3DBaseTexture *)surface->container.u.texture, TRUE);
             }
         }
         surface->Flags &= ~SFLAG_LOCATIONS;
@@ -4314,12 +4301,10 @@ void surface_modify_location(IWineD3DSurfaceImpl *surface, DWORD flag, BOOL pers
     {
         if ((surface->Flags & (SFLAG_INTEXTURE | SFLAG_INSRGBTEX)) && (flag & (SFLAG_INTEXTURE | SFLAG_INSRGBTEX)))
         {
-            if (SUCCEEDED(IWineD3DSurface_GetContainer((IWineD3DSurface *)surface,
-                    &IID_IWineD3DBaseTexture, (void **)&texture)))
+            if (surface->container.type == WINED3D_CONTAINER_TEXTURE)
             {
                 TRACE("Passing to container\n");
-                IWineD3DBaseTexture_SetDirty(texture, TRUE);
-                IWineD3DBaseTexture_Release(texture);
+                IWineD3DBaseTexture_SetDirty((IWineD3DBaseTexture *)surface->container.u.texture, TRUE);
             }
         }
         surface->Flags &= ~flag;
diff --git a/dlls/wined3d/surface_gdi.c b/dlls/wined3d/surface_gdi.c
index 6ef7c6b..bd1b775 100644
--- a/dlls/wined3d/surface_gdi.c
+++ b/dlls/wined3d/surface_gdi.c
@@ -167,7 +167,6 @@ static HRESULT WINAPI
 IWineGDISurfaceImpl_UnlockRect(IWineD3DSurface *iface)
 {
     IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface;
-    IWineD3DSwapChainImpl *swapchain = NULL;
     TRACE("(%p)\n", This);
 
     if (!(This->Flags & SFLAG_LOCKED))
@@ -177,13 +176,13 @@ IWineGDISurfaceImpl_UnlockRect(IWineD3DSurface *iface)
     }
 
     /* Tell the swapchain to update the screen */
-    if (SUCCEEDED(IWineD3DSurface_GetContainer(iface, &IID_IWineD3DSwapChain, (void **)&swapchain)))
+    if (This->container.type == WINED3D_CONTAINER_SWAPCHAIN)
     {
+        IWineD3DSwapChainImpl *swapchain = This->container.u.swapchain;
         if (This == swapchain->front_buffer)
         {
             x11_copy_to_screen(swapchain, &This->lockedRect);
         }
-        IWineD3DSwapChain_Release((IWineD3DSwapChain *) swapchain);
     }
 
     This->Flags &= ~SFLAG_LOCKED;
@@ -210,18 +209,20 @@ IWineGDISurfaceImpl_Flip(IWineD3DSurface *iface,
                          IWineD3DSurface *override,
                          DWORD Flags)
 {
-    IWineD3DSwapChainImpl *swapchain = NULL;
+    IWineD3DSurfaceImpl *surface = (IWineD3DSurfaceImpl *)iface;
+    IWineD3DSwapChainImpl *swapchain;
     HRESULT hr;
 
-    if(FAILED(IWineD3DSurface_GetContainer(iface, &IID_IWineD3DSwapChain, (void **)&swapchain)))
+    if (surface->container.type != WINED3D_CONTAINER_SWAPCHAIN)
     {
         ERR("Flipped surface is not on a swapchain\n");
         return WINEDDERR_NOTFLIPPABLE;
     }
 
+    swapchain = surface->container.u.swapchain;
     hr = IWineD3DSwapChain_Present((IWineD3DSwapChain *)swapchain,
             NULL, NULL, swapchain->win_handle, NULL, 0);
-    IWineD3DSwapChain_Release((IWineD3DSwapChain *) swapchain);
+
     return hr;
 }
 
@@ -349,7 +350,6 @@ static HRESULT WINAPI IWineGDISurfaceImpl_RealizePalette(IWineD3DSurface *iface)
     RGBQUAD col[256];
     IWineD3DPaletteImpl *pal = This->palette;
     unsigned int n;
-    IWineD3DSwapChainImpl *swapchain;
     TRACE("(%p)\n", This);
 
     if (!pal) return WINED3D_OK;
@@ -368,13 +368,13 @@ static HRESULT WINAPI IWineGDISurfaceImpl_RealizePalette(IWineD3DSurface *iface)
     /* Update the image because of the palette change. Some games like e.g Red Alert
        call SetEntries a lot to implement fading. */
     /* Tell the swapchain to update the screen */
-    if (SUCCEEDED(IWineD3DSurface_GetContainer(iface, &IID_IWineD3DSwapChain, (void **)&swapchain)))
+    if (This->container.type == WINED3D_CONTAINER_SWAPCHAIN)
     {
+        IWineD3DSwapChainImpl *swapchain = This->container.u.swapchain;
         if (This == swapchain->front_buffer)
         {
             x11_copy_to_screen(swapchain, NULL);
         }
-        IWineD3DSwapChain_Release((IWineD3DSwapChain *) swapchain);
     }
 
     return WINED3D_OK;
-- 
1.7.1




More information about the wine-patches mailing list