[PATCH 1/5] wined3d: Merge the GL and GDI swapchain vtbls.

Henri Verbeet hverbeet at codeweavers.com
Wed Apr 13 12:14:30 CDT 2011


---
 dlls/wined3d/swapchain.c       |  230 ++++++++++++++++++++--------------------
 dlls/wined3d/wined3d_private.h |    9 +-
 2 files changed, 120 insertions(+), 119 deletions(-)

diff --git a/dlls/wined3d/swapchain.c b/dlls/wined3d/swapchain.c
index 990758d..3453a1b 100644
--- a/dlls/wined3d/swapchain.c
+++ b/dlls/wined3d/swapchain.c
@@ -151,6 +151,22 @@ static HRESULT WINAPI IWineD3DBaseSwapChainImpl_SetDestWindowOverride(IWineD3DSw
     return WINED3D_OK;
 }
 
+static HRESULT WINAPI IWineD3DBaseSwapChainImpl_Present(IWineD3DSwapChain *iface,
+        const RECT *src_rect, const RECT *dst_rect, HWND dst_window_override,
+        const RGNDATA *dirty_region, DWORD flags)
+{
+    IWineD3DSwapChainImpl *swapchain = (IWineD3DSwapChainImpl *)iface;
+
+    TRACE("iface %p, src_rect %s, dst_rect %s, dst_window_override %p, dirty_region %p, flags %#x.\n",
+            iface, wine_dbgstr_rect(src_rect), wine_dbgstr_rect(dst_rect),
+            dst_window_override, dirty_region, flags);
+
+    IWineD3DBaseSwapChainImpl_SetDestWindowOverride(iface, dst_window_override);
+
+    return swapchain->swapchain_ops->swapchain_present(swapchain,
+            src_rect, dst_rect, dirty_region, flags);
+}
+
 static HRESULT WINAPI IWineD3DBaseSwapChainImpl_GetFrontBufferData(IWineD3DSwapChain *iface,
         IWineD3DSurface *dst_surface)
 {
@@ -289,6 +305,24 @@ static HRESULT WINAPI IWineD3DBaseSwapChainImpl_GetGammaRamp(IWineD3DSwapChain *
     return WINED3D_OK;
 }
 
+static const IWineD3DSwapChainVtbl IWineD3DSwapChain_Vtbl =
+{
+    IWineD3DBaseSwapChainImpl_QueryInterface,
+    IWineD3DBaseSwapChainImpl_AddRef,
+    IWineD3DBaseSwapChainImpl_Release,
+    IWineD3DBaseSwapChainImpl_GetParent,
+    IWineD3DBaseSwapChainImpl_GetDevice,
+    IWineD3DBaseSwapChainImpl_Present,
+    IWineD3DBaseSwapChainImpl_SetDestWindowOverride,
+    IWineD3DBaseSwapChainImpl_GetFrontBufferData,
+    IWineD3DBaseSwapChainImpl_GetBackBuffer,
+    IWineD3DBaseSwapChainImpl_GetRasterStatus,
+    IWineD3DBaseSwapChainImpl_GetDisplayMode,
+    IWineD3DBaseSwapChainImpl_GetPresentParameters,
+    IWineD3DBaseSwapChainImpl_SetGammaRamp,
+    IWineD3DBaseSwapChainImpl_GetGammaRamp
+};
+
 /* A GL context is provided by the caller */
 static void swapchain_blit(IWineD3DSwapChainImpl *This, struct wined3d_context *context,
         const RECT *src_rect, const RECT *dst_rect)
@@ -416,19 +450,15 @@ static void swapchain_blit(IWineD3DSwapChainImpl *This, struct wined3d_context *
     }
 }
 
-static HRESULT WINAPI IWineD3DSwapChainImpl_Present(IWineD3DSwapChain *iface,
-        const RECT *pSourceRect, const RECT *pDestRect, HWND hDestWindowOverride,
-        const RGNDATA *pDirtyRegion, DWORD flags)
+static HRESULT swapchain_gl_present(IWineD3DSwapChainImpl *swapchain, const RECT *src_rect_in,
+        const RECT *dst_rect_in, const RGNDATA *dirty_region, DWORD flags)
 {
-    IWineD3DSwapChainImpl *This = (IWineD3DSwapChainImpl *)iface;
     const struct wined3d_gl_info *gl_info;
     struct wined3d_context *context;
     RECT src_rect, dst_rect;
     BOOL render_to_fbo;
 
-    IWineD3DBaseSwapChainImpl_SetDestWindowOverride(iface, hDestWindowOverride);
-
-    context = context_acquire(This->device, This->back_buffers[0]);
+    context = context_acquire(swapchain->device, swapchain->back_buffers[0]);
     if (!context->valid)
     {
         context_release(context);
@@ -439,15 +469,15 @@ static HRESULT WINAPI IWineD3DSwapChainImpl_Present(IWineD3DSwapChain *iface,
     gl_info = context->gl_info;
 
     /* Render the cursor onto the back buffer, using our nifty directdraw blitting code :-) */
-    if (This->device->bCursorVisible && This->device->cursorTexture)
+    if (swapchain->device->bCursorVisible && swapchain->device->cursorTexture)
     {
         IWineD3DSurfaceImpl cursor;
         RECT destRect =
         {
-            This->device->xScreenSpace - This->device->xHotSpot,
-            This->device->yScreenSpace - This->device->yHotSpot,
-            This->device->xScreenSpace + This->device->cursorWidth - This->device->xHotSpot,
-            This->device->yScreenSpace + This->device->cursorHeight - This->device->yHotSpot,
+            swapchain->device->xScreenSpace - swapchain->device->xHotSpot,
+            swapchain->device->yScreenSpace - swapchain->device->yHotSpot,
+            swapchain->device->xScreenSpace + swapchain->device->cursorWidth - swapchain->device->xHotSpot,
+            swapchain->device->yScreenSpace + swapchain->device->cursorHeight - swapchain->device->yHotSpot,
         };
         TRACE("Rendering the cursor. Creating fake surface at %p\n", &cursor);
         /* Build a fake surface to call the Blitting code. It is not possible to use the interface passed by
@@ -457,15 +487,15 @@ static HRESULT WINAPI IWineD3DSwapChainImpl_Present(IWineD3DSwapChain *iface,
         memset(&cursor, 0, sizeof(cursor));
         cursor.lpVtbl = &IWineD3DSurface_Vtbl;
         cursor.resource.ref = 1;
-        cursor.resource.device = This->device;
+        cursor.resource.device = swapchain->device;
         cursor.resource.pool = WINED3DPOOL_SCRATCH;
         cursor.resource.format = wined3d_get_format(gl_info, WINED3DFMT_B8G8R8A8_UNORM);
         cursor.resource.resourceType = WINED3DRTYPE_SURFACE;
-        cursor.texture_name = This->device->cursorTexture;
+        cursor.texture_name = swapchain->device->cursorTexture;
         cursor.texture_target = GL_TEXTURE_2D;
         cursor.texture_level = 0;
-        cursor.resource.width = This->device->cursorWidth;
-        cursor.resource.height = This->device->cursorHeight;
+        cursor.resource.width = swapchain->device->cursorWidth;
+        cursor.resource.height = swapchain->device->cursorHeight;
         /* The cursor must have pow2 sizes */
         cursor.pow2Width = cursor.resource.width;
         cursor.pow2Height = cursor.resource.height;
@@ -474,30 +504,29 @@ static HRESULT WINAPI IWineD3DSwapChainImpl_Present(IWineD3DSwapChain *iface,
         /* DDBLT_KEYSRC will cause BltOverride to enable the alpha test with GL_NOTEQUAL, 0.0,
          * which is exactly what we want :-)
          */
-        if (This->presentParms.Windowed) {
-            MapWindowPoints(NULL, This->win_handle, (LPPOINT)&destRect, 2);
-        }
-        IWineD3DSurface_Blt((IWineD3DSurface *)This->back_buffers[0], &destRect, (IWineD3DSurface *)&cursor,
-                NULL, WINEDDBLT_KEYSRC, NULL, WINED3DTEXF_POINT);
+        if (swapchain->presentParms.Windowed)
+            MapWindowPoints(NULL, swapchain->win_handle, (LPPOINT)&destRect, 2);
+        IWineD3DSurface_Blt((IWineD3DSurface *)swapchain->back_buffers[0], &destRect,
+                (IWineD3DSurface *)&cursor, NULL, WINEDDBLT_KEYSRC, NULL, WINED3DTEXF_POINT);
     }
 
-    if (This->device->logo_surface)
+    if (swapchain->device->logo_surface)
     {
         /* Blit the logo into the upper left corner of the drawable. */
-        IWineD3DSurface_BltFast((IWineD3DSurface *)This->back_buffers[0], 0, 0,
-                This->device->logo_surface, NULL, WINEDDBLTFAST_SRCCOLORKEY);
+        IWineD3DSurface_BltFast((IWineD3DSurface *)swapchain->back_buffers[0], 0, 0,
+                swapchain->device->logo_surface, NULL, WINEDDBLTFAST_SRCCOLORKEY);
     }
 
     TRACE("Presenting HDC %p.\n", context->hdc);
 
-    render_to_fbo = This->render_to_fbo;
+    render_to_fbo = swapchain->render_to_fbo;
 
-    if (pSourceRect)
+    if (src_rect_in)
     {
-        src_rect = *pSourceRect;
+        src_rect = *src_rect_in;
         if (!render_to_fbo && (src_rect.left || src_rect.top
-                || src_rect.right != This->presentParms.BackBufferWidth
-                || src_rect.bottom != This->presentParms.BackBufferHeight))
+                || src_rect.right != swapchain->presentParms.BackBufferWidth
+                || src_rect.bottom != swapchain->presentParms.BackBufferHeight))
         {
             render_to_fbo = TRUE;
         }
@@ -506,16 +535,18 @@ static HRESULT WINAPI IWineD3DSwapChainImpl_Present(IWineD3DSwapChain *iface,
     {
         src_rect.left = 0;
         src_rect.top = 0;
-        src_rect.right = This->presentParms.BackBufferWidth;
-        src_rect.bottom = This->presentParms.BackBufferHeight;
+        src_rect.right = swapchain->presentParms.BackBufferWidth;
+        src_rect.bottom = swapchain->presentParms.BackBufferHeight;
     }
 
-    if (pDestRect) dst_rect = *pDestRect;
-    else GetClientRect(This->win_handle, &dst_rect);
+    if (dst_rect_in)
+        dst_rect = *dst_rect_in;
+    else
+        GetClientRect(swapchain->win_handle, &dst_rect);
 
     if (!render_to_fbo && (dst_rect.left || dst_rect.top
-            || dst_rect.right != This->presentParms.BackBufferWidth
-            || dst_rect.bottom != This->presentParms.BackBufferHeight))
+            || dst_rect.right != swapchain->presentParms.BackBufferWidth
+            || dst_rect.bottom != swapchain->presentParms.BackBufferHeight))
     {
         render_to_fbo = TRUE;
     }
@@ -527,31 +558,29 @@ static HRESULT WINAPI IWineD3DSwapChainImpl_Present(IWineD3DSwapChain *iface,
      * Note that FBO_blit from the backbuffer to the frontbuffer cannot solve
      * all these issues - this fails if the window is smaller than the backbuffer.
      */
-    if (!This->render_to_fbo && render_to_fbo && wined3d_settings.offscreen_rendering_mode == ORM_FBO)
+    if (!swapchain->render_to_fbo && render_to_fbo && wined3d_settings.offscreen_rendering_mode == ORM_FBO)
     {
-        surface_load_location(This->back_buffers[0], SFLAG_INTEXTURE, NULL);
-        surface_modify_location(This->back_buffers[0], SFLAG_INDRAWABLE, FALSE);
-        This->render_to_fbo = TRUE;
+        surface_load_location(swapchain->back_buffers[0], SFLAG_INTEXTURE, NULL);
+        surface_modify_location(swapchain->back_buffers[0], SFLAG_INDRAWABLE, FALSE);
+        swapchain->render_to_fbo = TRUE;
     }
 
-    if(This->render_to_fbo)
+    if (swapchain->render_to_fbo)
     {
         /* This codepath should only be hit with the COPY swapeffect. Otherwise a backbuffer-
          * window size mismatch is impossible(fullscreen) and src and dst rectangles are
          * not allowed(they need the COPY swapeffect)
          *
          * The DISCARD swap effect is ok as well since any backbuffer content is allowed after
-         * the swap
-         */
-        if(This->presentParms.SwapEffect == WINED3DSWAPEFFECT_FLIP )
-        {
+         * the swap. */
+        if (swapchain->presentParms.SwapEffect == WINED3DSWAPEFFECT_FLIP)
             FIXME("Render-to-fbo with WINED3DSWAPEFFECT_FLIP\n");
-        }
 
-        swapchain_blit(This, context, &src_rect, &dst_rect);
+        swapchain_blit(swapchain, context, &src_rect, &dst_rect);
     }
 
-    if (This->num_contexts > 1) wglFinish();
+    if (swapchain->num_contexts > 1)
+        wglFinish();
     SwapBuffers(context->hdc); /* TODO: cycle through the swapchain buffers */
 
     TRACE("SwapBuffers called, Starting new frame\n");
@@ -559,12 +588,15 @@ static HRESULT WINAPI IWineD3DSwapChainImpl_Present(IWineD3DSwapChain *iface,
     if (TRACE_ON(fps))
     {
         DWORD time = GetTickCount();
-        This->frames++;
+        ++swapchain->frames;
+
         /* every 1.5 seconds */
-        if (time - This->prev_time > 1500) {
-            TRACE_(fps)("%p @ approx %.2ffps\n", This, 1000.0*This->frames/(time - This->prev_time));
-            This->prev_time = time;
-            This->frames = 0;
+        if (time - swapchain->prev_time > 1500)
+        {
+            TRACE_(fps)("%p @ approx %.2ffps\n",
+                    swapchain, 1000.0 * swapchain->frames / (time - swapchain->prev_time));
+            swapchain->prev_time = time;
+            swapchain->frames = 0;
         }
     }
 
@@ -582,23 +614,23 @@ static HRESULT WINAPI IWineD3DSwapChainImpl_Present(IWineD3DSwapChain *iface,
      * gets a dark background image. If we clear it with a bright ugly color, the game's
      * bug shows up much more than it does on Windows, and the players see single pixels
      * with wrong colors.
-     * (The Max Payne bug has been confirmed on Windows with the debug runtime)
-     */
-    if (FALSE && This->presentParms.SwapEffect == WINED3DSWAPEFFECT_DISCARD) {
+     * (The Max Payne bug has been confirmed on Windows with the debug runtime) */
+    if (FALSE && swapchain->presentParms.SwapEffect == WINED3DSWAPEFFECT_DISCARD)
+    {
         TRACE("Clearing the color buffer with cyan color\n");
 
-        IWineD3DDevice_Clear((IWineD3DDevice *)This->device, 0, NULL,
+        IWineD3DDevice_Clear((IWineD3DDevice *)swapchain->device, 0, NULL,
                 WINED3DCLEAR_TARGET, 0xff00ffff, 1.0f, 0);
     }
 
-    if (!This->render_to_fbo && ((This->front_buffer->flags & SFLAG_INSYSMEM)
-            || (This->back_buffers[0]->flags & SFLAG_INSYSMEM)))
+    if (!swapchain->render_to_fbo && ((swapchain->front_buffer->flags & SFLAG_INSYSMEM)
+            || (swapchain->back_buffers[0]->flags & SFLAG_INSYSMEM)))
     {
         /* Both memory copies of the surfaces are ok, flip them around too instead of dirtifying
          * Doesn't work with render_to_fbo because we're not flipping
          */
-        IWineD3DSurfaceImpl *front = This->front_buffer;
-        IWineD3DSurfaceImpl *back = This->back_buffers[0];
+        IWineD3DSurfaceImpl *front = swapchain->front_buffer;
+        IWineD3DSurfaceImpl *back = swapchain->back_buffers[0];
 
         if(front->resource.size == back->resource.size) {
             DWORD fbflags;
@@ -619,30 +651,28 @@ static HRESULT WINAPI IWineD3DSwapChainImpl_Present(IWineD3DSwapChain *iface,
     }
     else
     {
-        surface_modify_location(This->front_buffer, SFLAG_INDRAWABLE, TRUE);
+        surface_modify_location(swapchain->front_buffer, SFLAG_INDRAWABLE, TRUE);
         /* If the swapeffect is DISCARD, the back buffer is undefined. That means the SYSMEM
          * and INTEXTURE copies can keep their old content if they have any defined content.
          * If the swapeffect is COPY, the content remains the same. If it is FLIP however,
          * the texture / sysmem copy needs to be reloaded from the drawable
          */
-        if (This->presentParms.SwapEffect == WINED3DSWAPEFFECT_FLIP)
-        {
-            surface_modify_location(This->back_buffers[0], SFLAG_INDRAWABLE, TRUE);
-        }
+        if (swapchain->presentParms.SwapEffect == WINED3DSWAPEFFECT_FLIP)
+            surface_modify_location(swapchain->back_buffers[0], SFLAG_INDRAWABLE, TRUE);
     }
 
-    if (This->device->depth_stencil)
+    if (swapchain->device->depth_stencil)
     {
-        if (This->presentParms.Flags & WINED3DPRESENTFLAG_DISCARD_DEPTHSTENCIL
-                || This->device->depth_stencil->flags & SFLAG_DISCARD)
+        if (swapchain->presentParms.Flags & WINED3DPRESENTFLAG_DISCARD_DEPTHSTENCIL
+                || swapchain->device->depth_stencil->flags & SFLAG_DISCARD)
         {
-            surface_modify_ds_location(This->device->depth_stencil, SFLAG_DS_DISCARDED,
-                    This->device->depth_stencil->resource.width,
-                    This->device->depth_stencil->resource.height);
-            if (This->device->depth_stencil == This->device->onscreen_depth_stencil)
+            surface_modify_ds_location(swapchain->device->depth_stencil, SFLAG_DS_DISCARDED,
+                    swapchain->device->depth_stencil->resource.width,
+                    swapchain->device->depth_stencil->resource.height);
+            if (swapchain->device->depth_stencil == swapchain->device->onscreen_depth_stencil)
             {
-                IWineD3DSurface_Release((IWineD3DSurface *)This->device->onscreen_depth_stencil);
-                This->device->onscreen_depth_stencil = NULL;
+                IWineD3DSurface_Release((IWineD3DSurface *)swapchain->device->onscreen_depth_stencil);
+                swapchain->device->onscreen_depth_stencil = NULL;
             }
         }
     }
@@ -653,24 +683,9 @@ static HRESULT WINAPI IWineD3DSwapChainImpl_Present(IWineD3DSwapChain *iface,
     return WINED3D_OK;
 }
 
-static const IWineD3DSwapChainVtbl IWineD3DSwapChain_Vtbl =
+static const struct wined3d_swapchain_ops swapchain_gl_ops =
 {
-    /* IUnknown */
-    IWineD3DBaseSwapChainImpl_QueryInterface,
-    IWineD3DBaseSwapChainImpl_AddRef,
-    IWineD3DBaseSwapChainImpl_Release,
-    /* IWineD3DSwapChain */
-    IWineD3DBaseSwapChainImpl_GetParent,
-    IWineD3DBaseSwapChainImpl_GetDevice,
-    IWineD3DSwapChainImpl_Present,
-    IWineD3DBaseSwapChainImpl_SetDestWindowOverride,
-    IWineD3DBaseSwapChainImpl_GetFrontBufferData,
-    IWineD3DBaseSwapChainImpl_GetBackBuffer,
-    IWineD3DBaseSwapChainImpl_GetRasterStatus,
-    IWineD3DBaseSwapChainImpl_GetDisplayMode,
-    IWineD3DBaseSwapChainImpl_GetPresentParameters,
-    IWineD3DBaseSwapChainImpl_SetGammaRamp,
-    IWineD3DBaseSwapChainImpl_GetGammaRamp
+    swapchain_gl_present,
 };
 
 /* Helper function that blits the front buffer contents to the target window. */
@@ -750,15 +765,11 @@ void x11_copy_to_screen(IWineD3DSwapChainImpl *swapchain, const RECT *rect)
     ReleaseDC(window, dst_dc);
 }
 
-static HRESULT WINAPI IWineGDISwapChainImpl_Present(IWineD3DSwapChain *iface,
-        const RECT *pSourceRect, const RECT *pDestRect, HWND hDestWindowOverride,
-        const RGNDATA *pDirtyRegion, DWORD flags)
+static HRESULT swapchain_gdi_present(IWineD3DSwapChainImpl *swapchain, const RECT *src_rect_in,
+        const RECT *dst_rect_in, const RGNDATA *dirty_region, DWORD flags)
 {
-    IWineD3DSwapChainImpl *swapchain = (IWineD3DSwapChainImpl *)iface;
     IWineD3DSurfaceImpl *front, *back;
 
-    IWineD3DBaseSwapChainImpl_SetDestWindowOverride(iface, hDestWindowOverride);
-
     if (!swapchain->back_buffers)
     {
         WARN("Swapchain doesn't have a backbuffer, returning WINED3DERR_INVALIDCALL\n");
@@ -832,24 +843,9 @@ static HRESULT WINAPI IWineGDISwapChainImpl_Present(IWineD3DSwapChain *iface,
     return WINED3D_OK;
 }
 
-static const IWineD3DSwapChainVtbl IWineGDISwapChain_Vtbl =
+static const struct wined3d_swapchain_ops swapchain_gdi_ops =
 {
-    /* IUnknown */
-    IWineD3DBaseSwapChainImpl_QueryInterface,
-    IWineD3DBaseSwapChainImpl_AddRef,
-    IWineD3DBaseSwapChainImpl_Release,
-    /* IWineD3DSwapChain */
-    IWineD3DBaseSwapChainImpl_GetParent,
-    IWineD3DBaseSwapChainImpl_GetDevice,
-    IWineGDISwapChainImpl_Present,
-    IWineD3DBaseSwapChainImpl_SetDestWindowOverride,
-    IWineD3DBaseSwapChainImpl_GetFrontBufferData,
-    IWineD3DBaseSwapChainImpl_GetBackBuffer,
-    IWineD3DBaseSwapChainImpl_GetRasterStatus,
-    IWineD3DBaseSwapChainImpl_GetDisplayMode,
-    IWineD3DBaseSwapChainImpl_GetPresentParameters,
-    IWineD3DBaseSwapChainImpl_SetGammaRamp,
-    IWineD3DBaseSwapChainImpl_GetGammaRamp,
+    swapchain_gdi_present,
 };
 
 /* Do not call while under the GL lock. */
@@ -879,14 +875,16 @@ HRESULT swapchain_init(IWineD3DSwapChainImpl *swapchain, WINED3DSURFTYPE surface
                 "Please configure the application to use double buffering (1 back buffer) if possible.\n");
     }
 
+    swapchain->lpVtbl = &IWineD3DSwapChain_Vtbl;
+
     switch (surface_type)
     {
         case SURFACE_GDI:
-            swapchain->lpVtbl = &IWineGDISwapChain_Vtbl;
+            swapchain->swapchain_ops = &swapchain_gdi_ops;
             break;
 
         case SURFACE_OPENGL:
-            swapchain->lpVtbl = &IWineD3DSwapChain_Vtbl;
+            swapchain->swapchain_ops = &swapchain_gl_ops;
             break;
 
         case SURFACE_UNKNOWN:
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index 79b7f57..6bd5a87 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -2517,9 +2517,11 @@ struct wined3d_rendertarget_view
 void wined3d_rendertarget_view_init(struct wined3d_rendertarget_view *view,
         struct wined3d_resource *resource, void *parent) DECLSPEC_HIDDEN;
 
-/*****************************************************************************
- * IWineD3DSwapChainImpl implementation structure (extends IUnknown)
- */
+struct wined3d_swapchain_ops
+{
+    HRESULT (*swapchain_present)(struct IWineD3DSwapChainImpl *swapchain, const RECT *src_rect,
+            const RECT *dst_rect, const RGNDATA *dirty_region, DWORD flags);
+};
 
 struct IWineD3DSwapChainImpl
 {
@@ -2529,6 +2531,7 @@ struct IWineD3DSwapChainImpl
 
     void *parent;
     const struct wined3d_parent_ops *parent_ops;
+    const struct wined3d_swapchain_ops *swapchain_ops;
     IWineD3DDeviceImpl *device;
 
     /* IWineD3DSwapChain fields */
-- 
1.7.3.4




More information about the wine-patches mailing list