Что происходит, когда мы вызываем IUknown::Release

Например, в следующем коде:

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. В настоящий момент, я думаю, может произойти следующее: указатель освобождается, не затрагивая сам буфер. Мне нужен более сложный ответ, так как мне трудно понять эту концепцию.

1 ответ

Решение

Объект текстуры поддерживает внутренний счетчик количества "ссылок", которые он имеет. Первоначально, когда ваш код запускается, у свопчейна есть указатель на текстуру, поэтому у него счетчик ссылок равен единице.

Когда он возвращает указатель на вас, теперь есть две ссылки на объект.

Обратите внимание, что код внутри swapchain::GetBuffer делает это вручную, вызывая функцию AddRef текстуры перед возвратом указателя на вас.

Поэтому, когда вы вызываете Release all, он уменьшает число ссылок на единицу и затем говорит: "Ах, есть еще одна ссылка, поэтому я больше ничего не буду делать".

Если бы объект цепочки обмена был удален до того, как вы вызвали свой Release для текстуры, он "выпустил бы" свою ссылку на текстуру, поэтому, когда вы вызвали свой Release, он бы уменьшил счетчик ссылок на текстуру до нуля и сказал бы "Ах, никто меня больше не использует, я сам себя удалю!".

Так что, по сути, вы вызываете Release для текстуры, а просто говорите текстуре, что она вам больше не интересна. Он все еще будет храниться в памяти, пока все об этом не скажут.

Другие вопросы по тегам