VirtualBox

Ignore:
Timestamp:
Aug 24, 2012 11:19:31 AM (12 years ago)
Author:
vboxsync
Message:

wddm/3d: fix app crashes on shut down

Location:
trunk/src/VBox/Additions/WINNT/Graphics/Wine/wined3d
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Additions/WINNT/Graphics/Wine/wined3d/device.c

    r42516 r42971  
    19581958    }
    19591959
     1960    if (This->swapchains)
     1961    {
    19601962    HeapFree(GetProcessHeap(), 0, This->swapchains);
    19611963    This->swapchains = NULL;
    19621964    This->NumberOfSwapChains = 0;
     1965    }
     1966    else
     1967    {
     1968        Assert(!This->NumberOfSwapChains);
     1969    }
    19631970
    19641971    for (i = 0; i < This->NumberOfPalettes; i++) HeapFree(GetProcessHeap(), 0, This->palettes[i]);
     
    70057012    IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *) iface;
    70067013    int i;
     7014    IWineD3DSwapChain **pvOldBuf = This->swapchains;
     7015
    70077016    for (i = 0; i < This->NumberOfSwapChains; ++i)
    70087017    {
     
    70427051            context_destroy(This, This->contexts[0]);
    70437052        }
    7044     }
     7053        This->swapchains = NULL;
     7054    }
     7055
     7056    if (pvOldBuf)
     7057        HeapFree(GetProcessHeap(), 0, pvOldBuf);
     7058
    70457059    return WINED3D_OK;
    70467060}
  • trunk/src/VBox/Additions/WINNT/Graphics/Wine/wined3d/swapchain.c

    r42499 r42971  
    6262}
    6363
    64 VOID swapchain_invalidate(IWineD3DSwapChainImpl *pSwapchain)
     64static VOID swapchain_cleanup_rt_refs(IWineD3DSwapChainImpl *pSwapchain, IWineD3DSurface *rt, int iBb)
     65{
     66    IWineD3DDeviceImpl *device = pSwapchain->device;
     67    struct wined3d_context *context;
     68    UINT i;
     69    for (i = 0; i < device->numContexts; ++i)
     70    {
     71        context = device->contexts[i];
     72
     73        if (rt == context->current_rt)
     74        {
     75            context->current_rt = NULL;
     76        }
     77    }
     78
     79    if (device->NumberOfSwapChains)
     80    {
     81        IWineD3DSwapChainImpl *pDefaultSwapchain = (IWineD3DSwapChainImpl*)device->swapchains[0];
     82        for (i = 0; i < device->adapter->gl_info.limits.buffers; ++i)
     83        {
     84            if (device->render_targets[i] == rt)
     85            {
     86                IWineD3DSurface *newRt;
     87                if (i)
     88                    newRt = NULL;
     89                else if (iBb == -1) /* front buffer */
     90                    newRt = pDefaultSwapchain->frontBuffer;
     91                else
     92                    newRt = pDefaultSwapchain->backBuffer ? pDefaultSwapchain->backBuffer[0] : pDefaultSwapchain->frontBuffer;
     93
     94                IWineD3DDevice_SetRenderTarget((IWineD3DDevice*)device, i, newRt, TRUE);
     95            }
     96        }
     97    }
     98}
     99
     100static VOID swapchain_cleanup_refs(IWineD3DSwapChainImpl *pSwapchain)
    65101{
    66102    /* first make sure the swapchain is not used by anyone */
     
    76112            context->currentSwapchain = NULL;
    77113        }
    78 
    79         if (pSwapchain->frontBuffer == context->current_rt)
    80         {
    81             context->current_rt = NULL;
    82         }
    83         else if (pSwapchain->backBuffer)
    84         {
    85             UINT j;
    86             for (j = 0; j < pSwapchain->presentParms.BackBufferCount; ++j)
    87             {
    88                 if (pSwapchain->backBuffer[j] == context->current_rt)
    89                 {
    90                     context->current_rt = NULL;
    91                     break;
    92                 }
    93             }
    94         }
    95     }
     114    }
     115
     116    if (pSwapchain->frontBuffer)
     117        swapchain_cleanup_rt_refs(pSwapchain, pSwapchain->frontBuffer, -1);
     118
     119    if (pSwapchain->backBuffer)
     120    {
     121        UINT j;
     122        for (j = 0; j < pSwapchain->presentParms.BackBufferCount; ++j)
     123        {
     124            swapchain_cleanup_rt_refs(pSwapchain, pSwapchain->backBuffer[j], j);
     125        }
     126    }
     127}
     128
     129static VOID swapchain_invalidate(IWineD3DSwapChainImpl *pSwapchain)
     130{
     131    swapchain_cleanup_refs(pSwapchain);
    96132
    97133    pSwapchain->win_handle = NULL;
     
    105141{
    106142    IWineD3DSwapChainImpl *This = (IWineD3DSwapChainImpl *)iface;
    107     WINED3DDISPLAYMODE mode;
    108143    unsigned int i;
    109144
     
    111146
    112147    IWineD3DSwapChain_SetGammaRamp(iface, 0, &This->orig_gamma);
     148
     149#ifdef VBOX_WITH_WDDM
     150    /* first remove swapchain from a list to ensure context is properly acquired
     151     * & gl resources are properly cleared on last swapchain destruction */
     152    IWineD3DDevice_RemoveSwapChain((IWineD3DDevice*)This->device, (IWineD3DSwapChain*)This);
     153
     154    swapchain_cleanup_refs(This);
     155#endif
    113156
    114157    /* Release the swapchain's draw buffers. Make sure This->backBuffer[0] is
     
    154197        This->presentRt = NULL;
    155198    }
    156 #endif
    157 
     199
     200    if(This->win_handle) {
     201        VBoxExtWndDestroy(This->win_handle, This->hDC);
     202        swapchain_invalidate(This);
     203    }
     204    else
     205    {
     206        WARN("null win info");
     207    }
     208#else
    158209    IWineD3DDevice_RemoveSwapChain((IWineD3DDevice*)This->device, (IWineD3DSwapChain*)This);
    159210    if (!This->device->NumberOfSwapChains)
     
    165216         */
    166217        if(This->presentParms.Windowed == FALSE && This->presentParms.AutoRestoreDisplayMode) {
     218            WINED3DDISPLAYMODE mode;
    167219            mode.Width = This->orig_width;
    168220            mode.Height = This->orig_height;
     
    172224        }
    173225    }
    174 #ifdef VBOX_WITH_WDDM
    175     if(This->win_handle) {
    176         VBoxExtWndDestroy(This->win_handle, This->hDC);
    177         swapchain_invalidate(This);
    178     }
    179     else
    180     {
    181         WARN("null win info");
    182     }
    183 #else
     226
    184227    HeapFree(GetProcessHeap(), 0, This->context);
    185228#endif
     229
    186230    HeapFree(GetProcessHeap(), 0, This);
    187231}
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette