【问题标题】:What happens when we call IUnknown::Release当我们调用 IUnknown::Release 会发生什么
【发布时间】:2021-02-09 06:13:38
【问题描述】:

例如在下面的代码中:

ID3D11Texture2D* texture2d; 

    HRESULT result = mSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*) &texture2d);//mSwapChain is a swap chain, as obvious

    result = mDevice->CreateRenderTargetView(texture2d, 0, &mTargetView);

    texture2d->Release();

我真的很困惑在调用 release 后交换链中的后台缓冲区会发生什么。目前我认为可能发生的是,指针被释放,而不影响后台缓冲区本身。不过,我需要一个更详细的答案,因为我很难理解这个概念。

【问题讨论】:

标签: directx directx-11


【解决方案1】:

纹理对象维护其拥有的“引用”数量的内部计数。最初,当您的代码启动时,交换链内部有一个指向纹理的指针,因此它的引用计数为 1。

当它返回一个指向你的指针时,现在有两个对该对象的引用。

请注意,swapchain::GetBuffer 内部的代码通过在将指针返回给您之前调用纹理的 AddRef 函数手动执行此操作。

所以当你调用 Release all 时,它会将引用计数减一,然后说“啊,还有一个引用,所以我什么都不做。”

如果交换链对象在您调用纹理之前已被删除,它将“释放”它对纹理的引用,因此当您调用 Release 时,它​​会将纹理的引用计数减少到零,并且会说“啊,没有人再使用我了,我会删除自己!”。

所以基本上你在纹理上调用 Release 只是你告诉纹理你不再对它感兴趣了。在每个人都告诉它之前,它仍然会留在记忆中。

【讨论】:

  • 一个小提示:对于 Direct3D,它使用“延迟销毁”,因此一旦您的资源达到 0 引用计数,它就有资格被销毁,但它可能需要几帧才能真正释放。
猜你喜欢
  • 1970-01-01
  • 2019-12-15
  • 1970-01-01
  • 2013-07-29
  • 1970-01-01
  • 1970-01-01
  • 2016-11-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多