VirtualBox

Changeset 57010 in vbox


Ignore:
Timestamp:
Jul 19, 2015 11:40:34 PM (10 years ago)
Author:
vboxsync
Message:

vmsvga/ogl: Must destroy shared context on reset and termination, otherwise OpenGL32.dll may take a while to clean up on process termination (at least with ATI drivers).

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/Graphics/DevVGA-SVGA3d-ogl.cpp

    r56947 r57010  
    956956static int  vmsvga3dCreateTexture(PVMSVGA3DSTATE pState, PVMSVGA3DCONTEXT pContext, uint32_t idAssociatedContext, PVMSVGA3DSURFACE pSurface);
    957957static int  vmsvga3dContextDefineOgl(PVGASTATE pThis, uint32_t cid, uint32_t fFlags);
     958static int  vmsvga3dContextDestroyOgl(PVGASTATE pThis, PVMSVGA3DCONTEXT pContext, uint32_t cid);
    958959static void vmsvgaColor2GLFloatArray(uint32_t color, GLfloat *pRed, GLfloat *pGreen, GLfloat *pBlue, GLfloat *pAlpha);
    959960static void vmsvga3dSetPackParams(PVMSVGA3DSTATE pState, PVMSVGA3DCONTEXT pContext, PVMSVGA3DSURFACE pSurface,
     
    18341835            vmsvga3dContextDestroy(pThis, pState->papContexts[i]->id);
    18351836    }
     1837
     1838    if (pState->SharedCtx.id == VMSVGA3D_SHARED_CTX_ID)
     1839        vmsvga3dContextDestroyOgl(pThis, &pState->SharedCtx, VMSVGA3D_SHARED_CTX_ID);
     1840
    18361841    return VINF_SUCCESS;
    18371842}
     
    40224027        int   vertexLeft, vertexRight, vertexTop, vertexBottom;
    40234028
    4024         pRect[i].srcx = RT_MAX(pRect[i].srcx, srcViewPort.x);
    4025         pRect[i].srcy = RT_MAX(pRect[i].srcy, srcViewPort.y);
     4029        pRect[i].srcx = RT_MAX(pRect[i].srcx, (uint32_t)RT_MAX(srcViewPort.x, 0));
     4030        pRect[i].srcy = RT_MAX(pRect[i].srcy, (uint32_t)RT_MAX(srcViewPort.y, 0));
    40264031        pRect[i].x    = RT_MAX(pRect[i].x, pThis->svga.viewport.x) - pThis->svga.viewport.x;
    40274032        pRect[i].y    = RT_MAX(pRect[i].y, pThis->svga.viewport.y) - pThis->svga.viewport.y;
     
    45734578}
    45744579
     4580/**
     4581 * Destroys a 3d context.
     4582 *
     4583 * @returns VBox status code.
     4584 * @param   pThis           VGA device instance data.
     4585 * @param   pContext        The context to destroy.
     4586 * @param   cid             Context id
     4587 */
     4588static int vmsvga3dContextDestroyOgl(PVGASTATE pThis, PVMSVGA3DCONTEXT pContext, uint32_t cid)
     4589{
     4590    PVMSVGA3DSTATE pState = (PVMSVGA3DSTATE)pThis->svga.p3dState;
     4591    AssertReturn(pState, VERR_NO_MEMORY);
     4592    AssertReturn(pContext, VERR_INVALID_PARAMETER);
     4593    AssertReturn(pContext->id == cid, VERR_INVALID_PARAMETER);
     4594    Log(("vmsvga3dContextDestroyOgl id %x\n", cid));
     4595
     4596    VMSVGA3D_SET_CURRENT_CONTEXT(pState, pContext);
     4597
     4598    /* Destroy all leftover pixel shaders. */
     4599    for (uint32_t i = 0; i < pContext->cPixelShaders; i++)
     4600    {
     4601        if (pContext->paPixelShader[i].id != SVGA3D_INVALID_ID)
     4602            vmsvga3dShaderDestroy(pThis, pContext->paPixelShader[i].cid, pContext->paPixelShader[i].id, pContext->paPixelShader[i].type);
     4603    }
     4604    if (pContext->paPixelShader)
     4605        RTMemFree(pContext->paPixelShader);
     4606
     4607    /* Destroy all leftover vertex shaders. */
     4608    for (uint32_t i = 0; i < pContext->cVertexShaders; i++)
     4609    {
     4610        if (pContext->paVertexShader[i].id != SVGA3D_INVALID_ID)
     4611            vmsvga3dShaderDestroy(pThis, pContext->paVertexShader[i].cid, pContext->paVertexShader[i].id, pContext->paVertexShader[i].type);
     4612    }
     4613    if (pContext->paVertexShader)
     4614        RTMemFree(pContext->paVertexShader);
     4615
     4616    if (pContext->state.paVertexShaderConst)
     4617        RTMemFree(pContext->state.paVertexShaderConst);
     4618    if (pContext->state.paPixelShaderConst)
     4619        RTMemFree(pContext->state.paPixelShaderConst);
     4620
     4621    if (pContext->pShaderContext)
     4622    {
     4623        int rc = ShaderContextDestroy(pContext->pShaderContext);
     4624        AssertRC(rc);
     4625    }
     4626
     4627#ifndef VMSVGA3D_OGL_WITH_SHARED_CTX /* This is done on windows - prevents various assertions at runtime, as well as shutdown & reset assertions when destroying surfaces. */
     4628    /* Check for all surfaces that are associated with this context to remove all dependencies */
     4629    for (uint32_t sid = 0; sid < pState->cSurfaces; sid++)
     4630    {
     4631        PVMSVGA3DSURFACE pSurface = pState->papSurfaces[sid];
     4632        if (    pSurface->idAssociatedContext == cid
     4633            &&  pSurface->id == sid)
     4634        {
     4635            int rc;
     4636
     4637            Log(("vmsvga3dContextDestroy: remove all dependencies for surface %x\n", sid));
     4638
     4639            uint32_t            surfaceFlags = pSurface->flags;
     4640            SVGA3dSurfaceFormat format = pSurface->format;
     4641            SVGA3dSurfaceFace   face[SVGA3D_MAX_SURFACE_FACES];
     4642            uint32_t            multisampleCount = pSurface->multiSampleCount;
     4643            SVGA3dTextureFilter autogenFilter = pSurface->autogenFilter;
     4644            SVGA3dSize         *pMipLevelSize;
     4645            uint32_t            cFaces = pSurface->cFaces;
     4646
     4647            pMipLevelSize = (SVGA3dSize *)RTMemAllocZ(pSurface->faces[0].numMipLevels * pSurface->cFaces * sizeof(SVGA3dSize));
     4648            AssertReturn(pMipLevelSize, VERR_NO_MEMORY);
     4649
     4650            for (uint32_t iFace = 0; iFace < pSurface->cFaces; iFace++)
     4651            {
     4652                for (uint32_t i = 0; i < pSurface->faces[0].numMipLevels; i++)
     4653                {
     4654                    uint32_t idx = i + iFace * pSurface->faces[0].numMipLevels;
     4655                    memcpy(&pMipLevelSize[idx], &pSurface->pMipmapLevels[idx].size, sizeof(SVGA3dSize));
     4656                }
     4657            }
     4658            memcpy(face, pSurface->faces, sizeof(pSurface->faces));
     4659
     4660            /* Recreate the surface with the original settings; destroys the contents, but that seems fairly safe since the context is also destroyed. */
     4661            rc = vmsvga3dSurfaceDestroy(pThis, sid);
     4662            AssertRC(rc);
     4663
     4664            rc = vmsvga3dSurfaceDefine(pThis, sid, surfaceFlags, format, face, multisampleCount, autogenFilter, face[0].numMipLevels * cFaces, pMipLevelSize);
     4665            AssertRC(rc);
     4666        }
     4667    }
     4668#endif
     4669
     4670    if (pContext->idFramebuffer != OPENGL_INVALID_ID)
     4671    {
     4672        /* Unbind the object from the framebuffer target. */
     4673        pState->ext.glBindFramebuffer(GL_FRAMEBUFFER, 0 /* back buffer */);
     4674        VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
     4675        pState->ext.glDeleteFramebuffers(1, &pContext->idFramebuffer);
     4676        VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
     4677
     4678        if (pContext->idReadFramebuffer != OPENGL_INVALID_ID)
     4679        {
     4680            pState->ext.glDeleteFramebuffers(1, &pContext->idReadFramebuffer);
     4681            VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
     4682        }
     4683        if (pContext->idDrawFramebuffer != OPENGL_INVALID_ID)
     4684        {
     4685            pState->ext.glDeleteFramebuffers(1, &pContext->idDrawFramebuffer);
     4686            VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
     4687        }
     4688    }
     4689#ifdef RT_OS_WINDOWS
     4690    wglMakeCurrent(pContext->hdc, NULL);
     4691    wglDeleteContext(pContext->hglrc);
     4692    ReleaseDC(pContext->hwnd, pContext->hdc);
     4693
     4694    /* Destroy the window we've created. */
     4695    int rc = vmsvga3dSendThreadMessage(pState->pWindowThread, pState->WndRequestSem, WM_VMSVGA3D_DESTROYWINDOW, (WPARAM)pContext->hwnd, 0);
     4696    AssertRC(rc);
     4697#elif defined(RT_OS_DARWIN)
     4698    vmsvga3dCocoaDestroyViewAndContext(pContext->cocoaView, pContext->cocoaContext);
     4699#elif defined(RT_OS_LINUX)
     4700    glXMakeCurrent(pState->display, None, NULL);
     4701    glXDestroyContext(pState->display, pContext->glxContext);
     4702    XDestroyWindow(pState->display, pContext->window);
     4703#endif
     4704
     4705    memset(pContext, 0, sizeof(*pContext));
     4706    pContext->id = SVGA3D_INVALID_ID;
     4707
     4708    VMSVGA3D_CLEAR_CURRENT_CONTEXT(pState);
     4709    return VINF_SUCCESS;
     4710}
    45754711
    45764712/**
     
    45844720{
    45854721    PVMSVGA3DSTATE pState = (PVMSVGA3DSTATE)pThis->svga.p3dState;
    4586     AssertReturn(pState, VERR_NO_MEMORY);
     4722    AssertReturn(pState, VERR_WRONG_ORDER);
     4723
     4724    /*
     4725     * Resolve the context and hand it to the common worker function.
     4726     */
     4727    if (   cid < pState->cContexts
     4728        && pState->papContexts[cid]->id == cid)
     4729        return vmsvga3dContextDestroyOgl(pThis, pState->papContexts[cid], cid);
    45874730
    45884731    AssertReturn(cid < SVGA3D_MAX_CONTEXT_IDS, VERR_INVALID_PARAMETER);
    4589 
    4590     if (    cid < pState->cContexts
    4591         &&  pState->papContexts[cid]->id == cid)
    4592     {
    4593         PVMSVGA3DCONTEXT pContext = pState->papContexts[cid];
    4594 
    4595         Log(("vmsvga3dContextDestroy id %x\n", cid));
    4596 
    4597         VMSVGA3D_SET_CURRENT_CONTEXT(pState, pContext);
    4598 
    4599         /* Destroy all leftover pixel shaders. */
    4600         for (uint32_t i = 0; i < pContext->cPixelShaders; i++)
    4601         {
    4602             if (pContext->paPixelShader[i].id != SVGA3D_INVALID_ID)
    4603                 vmsvga3dShaderDestroy(pThis, pContext->paPixelShader[i].cid, pContext->paPixelShader[i].id, pContext->paPixelShader[i].type);
    4604         }
    4605         if (pContext->paPixelShader)
    4606             RTMemFree(pContext->paPixelShader);
    4607 
    4608         /* Destroy all leftover vertex shaders. */
    4609         for (uint32_t i = 0; i < pContext->cVertexShaders; i++)
    4610         {
    4611             if (pContext->paVertexShader[i].id != SVGA3D_INVALID_ID)
    4612                 vmsvga3dShaderDestroy(pThis, pContext->paVertexShader[i].cid, pContext->paVertexShader[i].id, pContext->paVertexShader[i].type);
    4613         }
    4614         if (pContext->paVertexShader)
    4615             RTMemFree(pContext->paVertexShader);
    4616 
    4617         if (pContext->state.paVertexShaderConst)
    4618             RTMemFree(pContext->state.paVertexShaderConst);
    4619         if (pContext->state.paPixelShaderConst)
    4620             RTMemFree(pContext->state.paPixelShaderConst);
    4621 
    4622         if (pContext->pShaderContext)
    4623         {
    4624             int rc = ShaderContextDestroy(pContext->pShaderContext);
    4625             AssertRC(rc);
    4626         }
    4627 
    4628 #ifndef VMSVGA3D_OGL_WITH_SHARED_CTX /* This is done on windows - prevents various assertions at runtime, as well as shutdown & reset assertions when destroying surfaces. */
    4629         /* Check for all surfaces that are associated with this context to remove all dependencies */
    4630         for (uint32_t sid = 0; sid < pState->cSurfaces; sid++)
    4631         {
    4632             PVMSVGA3DSURFACE pSurface = pState->papSurfaces[sid];
    4633             if (    pSurface->idAssociatedContext == cid
    4634                 &&  pSurface->id == sid)
    4635             {
    4636                 int rc;
    4637 
    4638                 Log(("vmsvga3dContextDestroy: remove all dependencies for surface %x\n", sid));
    4639 
    4640                 uint32_t            surfaceFlags = pSurface->flags;
    4641                 SVGA3dSurfaceFormat format = pSurface->format;
    4642                 SVGA3dSurfaceFace   face[SVGA3D_MAX_SURFACE_FACES];
    4643                 uint32_t            multisampleCount = pSurface->multiSampleCount;
    4644                 SVGA3dTextureFilter autogenFilter = pSurface->autogenFilter;
    4645                 SVGA3dSize         *pMipLevelSize;
    4646                 uint32_t            cFaces = pSurface->cFaces;
    4647 
    4648                 pMipLevelSize = (SVGA3dSize *)RTMemAllocZ(pSurface->faces[0].numMipLevels * pSurface->cFaces * sizeof(SVGA3dSize));
    4649                 AssertReturn(pMipLevelSize, VERR_NO_MEMORY);
    4650 
    4651                 for (uint32_t iFace = 0; iFace < pSurface->cFaces; iFace++)
    4652                 {
    4653                     for (uint32_t i = 0; i < pSurface->faces[0].numMipLevels; i++)
    4654                     {
    4655                         uint32_t idx = i + iFace * pSurface->faces[0].numMipLevels;
    4656                         memcpy(&pMipLevelSize[idx], &pSurface->pMipmapLevels[idx].size, sizeof(SVGA3dSize));
    4657                     }
    4658                 }
    4659                 memcpy(face, pSurface->faces, sizeof(pSurface->faces));
    4660 
    4661                 /* Recreate the surface with the original settings; destroys the contents, but that seems fairly safe since the context is also destroyed. */
    4662                 rc = vmsvga3dSurfaceDestroy(pThis, sid);
    4663                 AssertRC(rc);
    4664 
    4665                 rc = vmsvga3dSurfaceDefine(pThis, sid, surfaceFlags, format, face, multisampleCount, autogenFilter, face[0].numMipLevels * cFaces, pMipLevelSize);
    4666                 AssertRC(rc);
    4667             }
    4668         }
    4669 #endif
    4670 
    4671         if (pContext->idFramebuffer != OPENGL_INVALID_ID)
    4672         {
    4673             /* Unbind the object from the framebuffer target. */
    4674             pState->ext.glBindFramebuffer(GL_FRAMEBUFFER, 0 /* back buffer */);
    4675             VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
    4676             pState->ext.glDeleteFramebuffers(1, &pContext->idFramebuffer);
    4677             VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
    4678 
    4679             if (pContext->idReadFramebuffer != OPENGL_INVALID_ID)
    4680             {
    4681                 pState->ext.glDeleteFramebuffers(1, &pContext->idReadFramebuffer);
    4682                 VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
    4683             }
    4684             if (pContext->idDrawFramebuffer != OPENGL_INVALID_ID)
    4685             {
    4686                 pState->ext.glDeleteFramebuffers(1, &pContext->idDrawFramebuffer);
    4687                 VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
    4688             }
    4689         }
    4690 #ifdef RT_OS_WINDOWS
    4691         wglMakeCurrent(pContext->hdc, NULL);
    4692         wglDeleteContext(pContext->hglrc);
    4693         ReleaseDC(pContext->hwnd, pContext->hdc);
    4694 
    4695         /* Destroy the window we've created. */
    4696         int rc = vmsvga3dSendThreadMessage(pState->pWindowThread, pState->WndRequestSem, WM_VMSVGA3D_DESTROYWINDOW, (WPARAM)pContext->hwnd, 0);
    4697         AssertRC(rc);
    4698 #elif defined(RT_OS_DARWIN)
    4699         vmsvga3dCocoaDestroyViewAndContext(pContext->cocoaView, pContext->cocoaContext);
    4700 #elif defined(RT_OS_LINUX)
    4701         glXMakeCurrent(pState->display, None, NULL);
    4702         glXDestroyContext(pState->display, pContext->glxContext);
    4703         XDestroyWindow(pState->display, pContext->window);
    4704 #endif
    4705 
    4706         memset(pContext, 0, sizeof(*pContext));
    4707         pContext->id = SVGA3D_INVALID_ID;
    4708 
    4709         VMSVGA3D_CLEAR_CURRENT_CONTEXT(pState);
    4710     }
    4711     else
    4712         AssertFailed();
    4713 
    47144732    return VINF_SUCCESS;
    47154733}
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