mirror of
https://gitlab.freedesktop.org/cairo/cairo.git
synced 2026-05-09 02:38:07 +02:00
DWriteFactory: Make thread-safe
TODO: add comment about shared factory and concurrent accesses
This commit is contained in:
parent
a13e660512
commit
132b149228
2 changed files with 64 additions and 78 deletions
|
|
@ -180,14 +180,15 @@ private:
|
||||||
|
|
||||||
RefPtr<IWICImagingFactory> WICImagingFactory::mFactoryInstance;
|
RefPtr<IWICImagingFactory> WICImagingFactory::mFactoryInstance;
|
||||||
|
|
||||||
|
cairo_atomic_once_t DWriteFactory::mOnceFactories = CAIRO_ATOMIC_ONCE_INIT;
|
||||||
RefPtr<IDWriteFactory> DWriteFactory::mFactoryInstance;
|
RefPtr<IDWriteFactory> DWriteFactory::mFactoryInstance;
|
||||||
RefPtr<IDWriteFactory1> DWriteFactory::mFactoryInstance1;
|
RefPtr<IDWriteFactory1> DWriteFactory::mFactoryInstance1;
|
||||||
RefPtr<IDWriteFactory2> DWriteFactory::mFactoryInstance2;
|
RefPtr<IDWriteFactory2> DWriteFactory::mFactoryInstance2;
|
||||||
RefPtr<IDWriteFactory3> DWriteFactory::mFactoryInstance3;
|
RefPtr<IDWriteFactory3> DWriteFactory::mFactoryInstance3;
|
||||||
RefPtr<IDWriteFactory4> DWriteFactory::mFactoryInstance4;
|
RefPtr<IDWriteFactory4> DWriteFactory::mFactoryInstance4;
|
||||||
RefPtr<IDWriteFactory8> DWriteFactory::mFactoryInstance8;
|
RefPtr<IDWriteFactory8> DWriteFactory::mFactoryInstance8;
|
||||||
|
cairo_atomic_once_t DWriteFactory::mOnceSystemCollection = CAIRO_ATOMIC_ONCE_INIT;
|
||||||
RefPtr<IDWriteFontCollection> DWriteFactory::mSystemCollection;
|
RefPtr<IDWriteFontCollection> DWriteFactory::mSystemCollection;
|
||||||
RefPtr<IDWriteRenderingParams> DWriteFactory::mDefaultRenderingParams;
|
|
||||||
|
|
||||||
RefPtr<ID2D1Factory> D2DFactory::mFactoryInstance;
|
RefPtr<ID2D1Factory> D2DFactory::mFactoryInstance;
|
||||||
|
|
||||||
|
|
@ -196,8 +197,15 @@ _create_rendering_params(IDWriteRenderingParams *params,
|
||||||
const cairo_font_options_t *options,
|
const cairo_font_options_t *options,
|
||||||
cairo_antialias_t antialias)
|
cairo_antialias_t antialias)
|
||||||
{
|
{
|
||||||
if (!params)
|
RefPtr<IDWriteRenderingParams> default_rendering_params;
|
||||||
params = DWriteFactory::DefaultRenderingParams();
|
HRESULT hr;
|
||||||
|
|
||||||
|
if (!params) {
|
||||||
|
hr = DWriteFactory::Instance()->CreateRenderingParams(&default_rendering_params);
|
||||||
|
assert(SUCCEEDED(hr));
|
||||||
|
params = default_rendering_params.get();
|
||||||
|
}
|
||||||
|
|
||||||
FLOAT gamma = params->GetGamma();
|
FLOAT gamma = params->GetGamma();
|
||||||
FLOAT enhanced_contrast = params->GetEnhancedContrast();
|
FLOAT enhanced_contrast = params->GetEnhancedContrast();
|
||||||
FLOAT clear_type_level = params->GetClearTypeLevel();
|
FLOAT clear_type_level = params->GetClearTypeLevel();
|
||||||
|
|
@ -242,7 +250,6 @@ _create_rendering_params(IDWriteRenderingParams *params,
|
||||||
if (!modified)
|
if (!modified)
|
||||||
return params;
|
return params;
|
||||||
|
|
||||||
HRESULT hr;
|
|
||||||
RefPtr<IDWriteRenderingParams1> params1;
|
RefPtr<IDWriteRenderingParams1> params1;
|
||||||
hr = params->QueryInterface(¶ms1);
|
hr = params->QueryInterface(¶ms1);
|
||||||
if (FAILED(hr)) {
|
if (FAILED(hr)) {
|
||||||
|
|
|
||||||
|
|
@ -39,13 +39,6 @@
|
||||||
#include "dwrite-extra.hpp"
|
#include "dwrite-extra.hpp"
|
||||||
#include "d2d1-extra.hpp"
|
#include "d2d1-extra.hpp"
|
||||||
|
|
||||||
// DirectWrite is not available on all platforms.
|
|
||||||
typedef HRESULT (WINAPI*DWriteCreateFactoryFunc)(
|
|
||||||
DWRITE_FACTORY_TYPE factoryType,
|
|
||||||
REFIID iid,
|
|
||||||
IUnknown **factory
|
|
||||||
);
|
|
||||||
|
|
||||||
/* #cairo_scaled_font_t implementation */
|
/* #cairo_scaled_font_t implementation */
|
||||||
struct _cairo_dwrite_scaled_font {
|
struct _cairo_dwrite_scaled_font {
|
||||||
cairo_scaled_font_t base;
|
cairo_scaled_font_t base;
|
||||||
|
|
@ -63,96 +56,56 @@ class DWriteFactory
|
||||||
public:
|
public:
|
||||||
static RefPtr<IDWriteFactory> Instance()
|
static RefPtr<IDWriteFactory> Instance()
|
||||||
{
|
{
|
||||||
if (!mFactoryInstance) {
|
InitializeFactories();
|
||||||
#ifdef __GNUC__
|
return mFactoryInstance;
|
||||||
#pragma GCC diagnostic push
|
|
||||||
#pragma GCC diagnostic ignored "-Wcast-function-type"
|
|
||||||
#endif
|
|
||||||
HMODULE dwrite = _cairo_win32_load_library_from_system32 (L"dwrite.dll");
|
|
||||||
DWriteCreateFactoryFunc createDWriteFactory = (DWriteCreateFactoryFunc)
|
|
||||||
GetProcAddress(dwrite, "DWriteCreateFactory");
|
|
||||||
#ifdef __GNUC__
|
|
||||||
#pragma GCC diagnostic pop
|
|
||||||
#endif
|
|
||||||
if (createDWriteFactory) {
|
|
||||||
HRESULT hr = createDWriteFactory(
|
|
||||||
DWRITE_FACTORY_TYPE_SHARED,
|
|
||||||
__uuidof(IDWriteFactory),
|
|
||||||
reinterpret_cast<IUnknown**>(&mFactoryInstance));
|
|
||||||
assert(SUCCEEDED(hr));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return mFactoryInstance;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static RefPtr<IDWriteFactory1> Instance1()
|
static RefPtr<IDWriteFactory1> Instance1()
|
||||||
{
|
{
|
||||||
if (!mFactoryInstance1) {
|
InitializeFactories();
|
||||||
if (Instance()) {
|
return mFactoryInstance1;
|
||||||
Instance()->QueryInterface(&mFactoryInstance1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return mFactoryInstance1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static RefPtr<IDWriteFactory2> Instance2()
|
static RefPtr<IDWriteFactory2> Instance2()
|
||||||
{
|
{
|
||||||
if (!mFactoryInstance2) {
|
InitializeFactories();
|
||||||
if (Instance()) {
|
return mFactoryInstance2;
|
||||||
Instance()->QueryInterface(&mFactoryInstance2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return mFactoryInstance2;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static RefPtr<IDWriteFactory3> Instance3()
|
static RefPtr<IDWriteFactory3> Instance3()
|
||||||
{
|
{
|
||||||
if (!mFactoryInstance3) {
|
InitializeFactories();
|
||||||
if (Instance()) {
|
return mFactoryInstance3;
|
||||||
Instance()->QueryInterface(&mFactoryInstance3);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return mFactoryInstance3;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static RefPtr<IDWriteFactory4> Instance4()
|
static RefPtr<IDWriteFactory4> Instance4()
|
||||||
{
|
{
|
||||||
if (!mFactoryInstance4) {
|
InitializeFactories();
|
||||||
if (Instance()) {
|
return mFactoryInstance4;
|
||||||
Instance()->QueryInterface(&mFactoryInstance4);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return mFactoryInstance4;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static RefPtr<IDWriteFactory8> Instance8()
|
static RefPtr<IDWriteFactory8> Instance8()
|
||||||
{
|
{
|
||||||
if (!mFactoryInstance8) {
|
InitializeFactories();
|
||||||
if (Instance()) {
|
|
||||||
Instance()->QueryInterface(&mFactoryInstance8);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return mFactoryInstance8;
|
return mFactoryInstance8;
|
||||||
}
|
}
|
||||||
|
|
||||||
static RefPtr<IDWriteFontCollection> SystemCollection()
|
static RefPtr<IDWriteFontCollection> SystemCollection()
|
||||||
{
|
{
|
||||||
if (!mSystemCollection) {
|
if (_cairo_atomic_init_once_enter (&mOnceSystemCollection)) {
|
||||||
if (Instance()) {
|
HRESULT hr = Instance()->GetSystemFontCollection(&mSystemCollection);
|
||||||
HRESULT hr = Instance()->GetSystemFontCollection(&mSystemCollection);
|
assert(SUCCEEDED(hr));
|
||||||
assert(SUCCEEDED(hr));
|
|
||||||
}
|
_cairo_atomic_init_once_leave (&mOnceSystemCollection);
|
||||||
}
|
}
|
||||||
return mSystemCollection;
|
return mSystemCollection;
|
||||||
}
|
}
|
||||||
|
|
||||||
static RefPtr<IDWriteFontFamily> FindSystemFontFamily(const WCHAR *aFamilyName)
|
static RefPtr<IDWriteFontFamily> FindSystemFontFamily(const WCHAR *aFamilyName)
|
||||||
{
|
{
|
||||||
UINT32 idx;
|
UINT32 idx;
|
||||||
BOOL found;
|
BOOL found;
|
||||||
if (!SystemCollection()) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
SystemCollection()->FindFamilyName(aFamilyName, &idx, &found);
|
SystemCollection()->FindFamilyName(aFamilyName, &idx, &found);
|
||||||
if (!found) {
|
if (!found) {
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
@ -163,25 +116,51 @@ public:
|
||||||
return family;
|
return family;
|
||||||
}
|
}
|
||||||
|
|
||||||
static RefPtr<IDWriteRenderingParams> DefaultRenderingParams()
|
private:
|
||||||
|
static void InitializeFactories()
|
||||||
{
|
{
|
||||||
if (!mDefaultRenderingParams) {
|
if (_cairo_atomic_init_once_enter (&mOnceFactories)) {
|
||||||
if (Instance()) {
|
typedef HRESULT
|
||||||
Instance()->CreateRenderingParams(&mDefaultRenderingParams);
|
(WINAPI *pDWriteCreateFactory_t) (DWRITE_FACTORY_TYPE factoryType,
|
||||||
}
|
REFIID iid,
|
||||||
}
|
IUnknown **factory);
|
||||||
return mDefaultRenderingParams;
|
|
||||||
|
#ifdef __GNUC__
|
||||||
|
#pragma GCC diagnostic push
|
||||||
|
#pragma GCC diagnostic ignored "-Wcast-function-type"
|
||||||
|
#endif
|
||||||
|
HMODULE dwrite = _cairo_win32_load_library_from_system32 (L"dwrite.dll");
|
||||||
|
pDWriteCreateFactory_t pDWriteCreateFactory = (pDWriteCreateFactory_t)
|
||||||
|
GetProcAddress (dwrite, "DWriteCreateFactory");
|
||||||
|
#ifdef __GNUC__
|
||||||
|
#pragma GCC diagnostic pop
|
||||||
|
#endif
|
||||||
|
HRESULT hr = pDWriteCreateFactory (DWRITE_FACTORY_TYPE_SHARED,
|
||||||
|
__uuidof (IDWriteFactory),
|
||||||
|
reinterpret_cast<IUnknown**>(&mFactoryInstance));
|
||||||
|
assert(SUCCEEDED(hr));
|
||||||
|
|
||||||
|
mFactoryInstance->QueryInterface(&mFactoryInstance1);
|
||||||
|
mFactoryInstance->QueryInterface(&mFactoryInstance2);
|
||||||
|
mFactoryInstance->QueryInterface(&mFactoryInstance3);
|
||||||
|
mFactoryInstance->QueryInterface(&mFactoryInstance4);
|
||||||
|
mFactoryInstance->QueryInterface(&mFactoryInstance8);
|
||||||
|
|
||||||
|
_cairo_atomic_init_once_leave (&mOnceFactories);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
static cairo_atomic_once_t mOnceFactories;
|
||||||
static RefPtr<IDWriteFactory> mFactoryInstance;
|
static RefPtr<IDWriteFactory> mFactoryInstance;
|
||||||
static RefPtr<IDWriteFactory1> mFactoryInstance1;
|
static RefPtr<IDWriteFactory1> mFactoryInstance1;
|
||||||
static RefPtr<IDWriteFactory2> mFactoryInstance2;
|
static RefPtr<IDWriteFactory2> mFactoryInstance2;
|
||||||
static RefPtr<IDWriteFactory3> mFactoryInstance3;
|
static RefPtr<IDWriteFactory3> mFactoryInstance3;
|
||||||
static RefPtr<IDWriteFactory4> mFactoryInstance4;
|
static RefPtr<IDWriteFactory4> mFactoryInstance4;
|
||||||
static RefPtr<IDWriteFactory8> mFactoryInstance8;
|
static RefPtr<IDWriteFactory8> mFactoryInstance8;
|
||||||
|
|
||||||
|
static cairo_atomic_once_t mOnceSystemCollection;
|
||||||
static RefPtr<IDWriteFontCollection> mSystemCollection;
|
static RefPtr<IDWriteFontCollection> mSystemCollection;
|
||||||
static RefPtr<IDWriteRenderingParams> mDefaultRenderingParams;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class AutoDWriteGlyphRun : public DWRITE_GLYPH_RUN
|
class AutoDWriteGlyphRun : public DWRITE_GLYPH_RUN
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue