DWriteFactory: Release resources on library unload

We can release all cached DWrite objects
This commit is contained in:
Luca Bacci 2026-03-09 12:32:50 +01:00
parent 6bb69c6488
commit 61dc0938bf
4 changed files with 42 additions and 0 deletions

View file

@ -2437,3 +2437,9 @@ _cairo_dwrite_scaled_font_create_win32_scaled_font (cairo_scaled_font_t *scaled_
*new_font = font;
return CAIRO_INT_STATUS_SUCCESS;
}
void
cairo_win32_dwrite_finalize ()
{
DWriteFactory::Finalize();
}

View file

@ -121,6 +121,24 @@ public:
return family;
}
static void Finalize()
{
/* Loader-lock-safe */
if (_cairo_atomic_init_once_check (&mOnceSystemCollection)) {
cairo_win32_async_com_release (mSystemCollection.forget().drop());
}
if (_cairo_atomic_init_once_check (&mOnceFactories)) {
cairo_win32_async_com_release (mFactoryInstance.forget().drop());
cairo_win32_async_com_release (mFactoryInstance1.forget().drop());
cairo_win32_async_com_release (mFactoryInstance2.forget().drop());
cairo_win32_async_com_release (mFactoryInstance3.forget().drop());
cairo_win32_async_com_release (mFactoryInstance4.forget().drop());
cairo_win32_async_com_release (mFactoryInstance8.forget().drop());
}
}
private:
static void InitializeFactories()
{

View file

@ -45,6 +45,7 @@
#include "cairo-win32.h"
#include <windows.h>
#include <unknwn.h>
#define WIN32_FONT_LOGICAL_SCALE 32
@ -243,6 +244,9 @@ typedef DWORD (__stdcall *stdcall_free_func_t) (void *);
void
cairo_win32_async_stdcall_free (stdcall_free_func_t func, void *data);
void
cairo_win32_async_com_release (IUnknown *iface_ptr);
typedef struct {
HDC hdc;
cairo_bool_t free_hdc;
@ -277,6 +281,9 @@ cairo_int_status_t
_cairo_dwrite_scaled_font_create_win32_scaled_font (cairo_scaled_font_t *scaled_font,
cairo_scaled_font_t **new_font);
void
cairo_win32_dwrite_finalize (void);
#endif /* CAIRO_HAS_DWRITE_FONT */
CAIRO_END_DECLS

View file

@ -115,6 +115,15 @@ cairo_win32_async_stdcall_free (stdcall_free_func_t func, void *data)
QueueUserWorkItem (func, data, WT_EXECUTEDEFAULT);
}
void
cairo_win32_async_com_release (IUnknown *iface_ptr)
{
if (iface_ptr) {
QueueUserWorkItem ((void *) iface_ptr->lpVtbl->Release,
iface_ptr, WT_EXECUTEDEFAULT);
}
}
static void
cairo_win32_initialize (void)
{
@ -125,6 +134,8 @@ cairo_win32_initialize (void)
static void
cairo_win32_finalize (void)
{
cairo_win32_dwrite_finalize ();
cairo_win32_thread_data_finalize ();
CAIRO_MUTEX_FINALIZE ();
}