I'm using the following pattern to pool D3D objects globally in my application. Is it a good idea (alternatives)? Is it thread-safe?
CComPtr<ID3D11Texture2D> create_texture(const D3D11_TEXTURE2D_DESC& desc)
{
static concurrent_unordered_map<D3D11_TEXTURE2D_DESC,
concurrenct_vector<CComPtr<ID3D11Texture2D>>
d3d_texture2d_desc_hash,
d3d_texture2d_desc_equal_to> pools;
auto& pool = pools[desc];
auto it = std::find_if(pool.begin(), pool.end(), [](const CComPtr<ID3D11Texture2D>& texture)
{
assert(texture);
IUnknown* unknown = texture;
auto ref_count = unknown.AddRef();
if(ref_count != 2)
unknown->Release(); // Only release if we don't want ownership.
return ref_count == 2;
});
CComPtr<ID3D11Texture2D> texture;
if(it != pool.end())
{
texture = *it; // Take ownership.
IUnknown* unknown = texture;
// Release the extra ref-count once we have taken ownership.
#ifndef _DEBUG
unknown->Release();
#else
assert(unknown->Release() == 2);
#endif
}
else
{
HR(get_default_device()->CreateTexture2D(&desc, nullptr, &texture));
pool.push_back(texture);
}
assert(texture);
return texture;
}