A class creates 1 instance of IDWriteFactory and, when a class is destroyed, is naturally released by calling the Release() method. I started debugging the destruction of class resources and noticed that all DirectX interfaces were freed normally, but IDWriteFactory returned 1, i.e. there is 1 link left. In fact, this happens even in the case when the interface has no links at all, i.e. interface was created but was not used.
Why does this happen and how to fight?
Constructor code:
static D2D1_POINT_2F dpi = { 0, 0 }; if (!m_render_window_handle_ || IsWindow(m_render_window_handle_) != TRUE) { if (UpdateWindow(m_render_window_handle_) == TRUE) { if (IsWindow(m_render_window_handle_) != TRUE) { std::exception("Invalid Window Handle! You cannot continue to create the graphics renderer."); } const LONG l_styles = GetWindowLong(m_render_window_handle_, GWL_STYLE); if (l_styles & WS_MINIMIZE) { ShowWindow(m_render_window_handle_, SW_NORMAL); } } std::exception("Invalid Window Handle! You cannot continue to create the graphics renderer."); } marioka_render_factory_options factory_options; memset(&factory_options, 0, sizeof factory_options); factory_options.debugLevel = #if defined(DEBUG) || defined(_DEBUG) D2D1_DEBUG_LEVEL_INFORMATION; #else D2D1_DEBUG_LEVEL_NONE; #endif; HRESULT result = D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &m_render_factory_); if (FAILED(result)) { throw std::exception("Failed to create Direct2D Factory"); } m_render_factory_->GetDesktopDpi(&dpi.x, &dpi.y); marioka_rect rc; GetClientRect(m_render_window_handle_, &rc); const marioka_size_u size = SizeU(rc.right - rc.left, rc.bottom - rc.top); marioka_render_target_properties render_target_properties; memset(&render_target_properties, 0, sizeof render_target_properties); render_target_properties.type = D2D1_RENDER_TARGET_TYPE_HARDWARE; render_target_properties.pixelFormat.alphaMode = D2D1_ALPHA_MODE_UNKNOWN; render_target_properties.pixelFormat.format = DXGI_FORMAT_B8G8R8A8_UNORM; render_target_properties.usage = D2D1_RENDER_TARGET_USAGE_NONE; render_target_properties.minLevel = D2D1_FEATURE_LEVEL_9; render_target_properties.dpiX = dpi.x; render_target_properties.dpiY = dpi.y; marioka_hwnd_render_target_properties hwnd_render_target_properties; memset(&hwnd_render_target_properties, 0, sizeof hwnd_render_target_properties); hwnd_render_target_properties.hwnd = m_render_window_handle_; hwnd_render_target_properties.pixelSize = size; hwnd_render_target_properties.presentOptions = D2D1_PRESENT_OPTIONS_IMMEDIATELY; result = m_render_factory_->CreateHwndRenderTarget(&render_target_properties, &hwnd_render_target_properties, &m_render_target_); if (FAILED(result)) { m_render_factory_->Release(); m_render_factory_ = nullptr; throw std::exception("Failed to create RenderTarget"); } m_render_target_->SetTransform(Matrix3x2F::Identity()); m_render_target_->SetAntialiasMode(D2D1_ANTIALIAS_MODE_PER_PRIMITIVE); m_render_target_->SetTextAntialiasMode(D2D1_TEXT_ANTIALIAS_MODE_CLEARTYPE); result = DWriteCreateFactory(DWRITE_FACTORY_TYPE_SHARED, __uuidof(m_write_factory_), reinterpret_cast<IUnknown**>(&m_write_factory_)); if(result != S_OK) { m_render_target_->Release(); m_render_target_ = nullptr; m_render_factory_->Release(); m_render_factory_ = nullptr; throw std::exception("Failed to create IDWriteFactory"); } Destructor code:
UINT result = m_render_target_->Release(); m_render_target_ = nullptr; result = m_write_factory_->Release(); m_write_factory_ = nullptr; result = m_render_factory_->Release(); m_render_factory_ = nullptr; m_instances_map_.erase(m_render_window_); m_render_window_ = nullptr; m_render_window_handle_ = nullptr; 

