zxaagds2050 2024-02-19 20:13 采纳率: 5.6%
浏览 73
已结题

C++ WGC截屏 winrt::com_ptr Unmap没有释放内存,如何解决?

C++ WGC截屏 winrt::com_ptr Unmap没有释放内存

m_framePool.FrameArrived([s](winrt::Windows::Graphics::Capture::Direct3D11CaptureFramePool const& sender, winrt::Windows::Foundation::IInspectable const& args)
    {
        tj = tjInitCompress();
        auto newSize = false;
        {
            auto frame = sender.TryGetNextFrame();
            auto frameContentSize = frame.ContentSize();
            if (frameContentSize.Width != m_lastSize.Width || frameContentSize.Height != m_lastSize.Height)
            {
                newSize = true;
                m_lastSize = frameContentSize;
                m_swapChain->ResizeBuffers(2, static_cast<uint32_t>(m_lastSize.Width), static_cast<uint32_t>(m_lastSize.Height), static_cast<DXGI_FORMAT>(DirectXPixelFormat::B8G8R8A8UIntNormalized), 0);
            }

            // copy to swapChain
            {
                auto frameSurface = GetDXGIInterfaceFromObject<ID3D11Texture2D>(frame.Surface());
                com_ptr<ID3D11Texture2D> backBuffer;
                check_hresult(m_swapChain->GetBuffer(0, guid_of<ID3D11Texture2D>(), backBuffer.put_void()));
                m_d3dContext->CopyResource(backBuffer.get(), frameSurface.get());
                DXGI_PRESENT_PARAMETERS presentParameters = { 0 };
                m_swapChain->Present1(1, 0, &presentParameters);
            }

            // copy to mapped texture
            {
                auto frameSurface = GetDXGIInterfaceFromObject<ID3D11Texture2D>(frame.Surface());
                if (!m_mappedTexture || newSize)
                {
                    CreateMappedTexture(frameSurface);
                }
                m_d3dContext->CopyResource(m_mappedTexture.get(), frameSurface.get());
                D3D11_MAPPED_SUBRESOURCE mapInfo;
                HRESULT ret = m_d3dContext->Map(m_mappedTexture.get(), 0, D3D11_MAP_READ, 0, &mapInfo);
                
                m_d3dContext->Unmap(m_mappedTexture.get(), 0);//没有释放内存
            }
        }
        if (newSize)
        {
            m_framePool.Recreate(m_device, DirectXPixelFormat::B8G8R8A8UIntNormalized, 2, m_lastSize);
        }
        tjDestroy(tj);
    });
  • 写回答

10条回答 默认 最新

  • 专家-赤兔[在线] 优质创作者: 编程框架技术领域 2024-02-19 20:14
    关注

    引自免费微信小程序:皆我百晓生

    在上述代码片段中,您提到 m_d3dContext->Unmap(m_mappedTexture.get(), 0); 没有释放内存。实际上,在Direct3D编程中,Unmap 函数并不直接负责释放内存,而是解除对之前映射到应用程序可访问内存空间的显存区域的锁定。当调用 Map 方法时,系统会将 GPU 显存中的资源区域映射到 CPU 可以读写的位置,而 Unmap 是告诉系统应用程序已完成对该区域的访问。

    针对您的问题,确保正确释放映射纹理所占用的显存资源,请检查以下几点:

    1. 确认是否正确管理了 m_mappedTexture 的生命周期:确保在不再需要映射纹理时,适当地释放它。通常,这可以通过在不再使用时调用 Release() 或将其置为 nullptr 来实现。

    2. 避免内存泄漏:确保每次重新创建映射纹理(如 CreateMappedTexture(frameSurface))后,旧的映射纹理已释放。若多次调用 CreateMappedTexture 而未释放之前的资源,可能会导致内存泄露。

    3. 考虑使用智能指针:虽然在提供的代码片段中没有展示这部分内容,但可以考虑使用 winrt::com_ptr<ID3D11Texture2D> 管理 m_mappedTexture 的生命周期,这样当 com_ptr 对象析构时,会自动释放底层资源。

    总之,Unmap 不是释放内存的关键,关键在于正确地创建和销毁映射的 Direct3D 资源。请检查您的代码中与 m_mappedTexture 生命周期管理相关的部分,确保资源得到及时释放。

    评论 编辑记录

报告相同问题?

问题事件

  • 已结题 (查看结题原因) 2月20日
  • 创建了问题 2月19日