06-shared-ft-face.patch (12607B)
1 # HG changeset patch 2 # User Jonathan Kew <jkew@mozilla.com> 3 # Date 1713888724 -3600 4 # Tue Apr 23 17:12:04 2024 +0100 5 # Node ID 575933bf80efb0d5f1f9c1cb257837b62c75c64e 6 # Parent ccbfe29b41b8479213bb9f22f6eb22e01879ad7c 7 Apply cairo/06-shared-ft-face.patch (with update in cairo-ft-font.c) 8 9 diff --git a/gfx/cairo/cairo/src/cairo-ft-font.c b/gfx/cairo/cairo/src/cairo-ft-font.c 10 --- a/gfx/cairo/cairo/src/cairo-ft-font.c 11 +++ b/gfx/cairo/cairo/src/cairo-ft-font.c 12 @@ -113,6 +113,24 @@ 13 */ 14 #define MAX_OPEN_FACES 10 15 16 +extern void mozilla_AddRefSharedFTFace(void* aContext); 17 +extern void mozilla_ReleaseSharedFTFace(void* aContext, void* aOwner); 18 +/* Returns true if the face's state has been modified by another owner. */ 19 +extern int mozilla_LockSharedFTFace(void* aContext, void* aOwner); 20 +extern void mozilla_UnlockSharedFTFace(void* aContext); 21 +extern FT_Error mozilla_LoadFTGlyph(FT_Face aFace, uint32_t aGlyphIndex, int32_t aFlags); 22 +extern void mozilla_LockFTLibrary(FT_Library aLibrary); 23 +extern void mozilla_UnlockFTLibrary(FT_Library aLibrary); 24 + 25 +#define CAIRO_FT_LOCK(unscaled) \ 26 + ((unscaled)->face_context \ 27 + ? (void)mozilla_LockSharedFTFace((unscaled)->face_context, NULL) \ 28 + : (void)CAIRO_MUTEX_LOCK((unscaled)->mutex)) 29 +#define CAIRO_FT_UNLOCK(unscaled) \ 30 + ((unscaled)->face_context \ 31 + ? mozilla_UnlockSharedFTFace((unscaled)->face_context) \ 32 + : (void)CAIRO_MUTEX_UNLOCK((unscaled)->mutex)) 33 + 34 /** 35 * SECTION:cairo-ft 36 * @Title: FreeType Fonts 37 @@ -166,6 +184,7 @@ struct _cairo_ft_unscaled_font { 38 39 cairo_bool_t from_face; /* was the FT_Face provided by user? */ 40 FT_Face face; /* provided or cached face */ 41 + void *face_context; 42 43 /* only set if from_face is false */ 44 char *filename; 45 @@ -351,7 +370,9 @@ static void 46 _cairo_hash_table_remove (font_map->hash_table, 47 &unscaled->base.hash_entry); 48 49 - if (! unscaled->from_face) 50 + if (unscaled->from_face) 51 + mozilla_ReleaseSharedFTFace (unscaled->face_context, unscaled); 52 + else 53 _font_map_release_face_lock_held (font_map, unscaled); 54 55 _cairo_ft_unscaled_font_fini (unscaled); 56 @@ -410,7 +431,8 @@ static void 57 cairo_bool_t from_face, 58 char *filename, 59 int id, 60 - FT_Face face) 61 + FT_Face face, 62 + void *face_context) 63 { 64 uintptr_t hash; 65 66 @@ -418,6 +440,7 @@ static void 67 key->filename = filename; 68 key->id = id; 69 key->face = face; 70 + key->face_context = face_context; 71 72 hash = _cairo_hash_string (filename); 73 /* the constants are just arbitrary primes */ 74 @@ -453,7 +476,8 @@ static cairo_status_t 75 cairo_bool_t from_face, 76 const char *filename, 77 int id, 78 - FT_Face face) 79 + FT_Face face, 80 + void *face_context) 81 { 82 _cairo_unscaled_font_init (&unscaled->base, 83 &cairo_ft_unscaled_font_backend); 84 @@ -462,7 +486,7 @@ static cairo_status_t 85 86 if (from_face) { 87 unscaled->from_face = TRUE; 88 - _cairo_ft_unscaled_font_init_key (unscaled, TRUE, NULL, id, face); 89 + _cairo_ft_unscaled_font_init_key (unscaled, TRUE, NULL, id, face, face_context); 90 91 92 unscaled->have_color = FT_HAS_COLOR (face) != 0; 93 @@ -489,12 +513,13 @@ static cairo_status_t 94 95 unscaled->from_face = FALSE; 96 unscaled->face = NULL; 97 + unscaled->face_context = NULL; 98 99 filename_copy = strdup (filename); 100 if (unlikely (filename_copy == NULL)) 101 return _cairo_error (CAIRO_STATUS_NO_MEMORY); 102 103 - _cairo_ft_unscaled_font_init_key (unscaled, FALSE, filename_copy, id, NULL); 104 + _cairo_ft_unscaled_font_init_key (unscaled, FALSE, filename_copy, id, NULL, NULL); 105 106 unscaled->have_color_set = FALSE; 107 } 108 @@ -543,7 +568,8 @@ static int 109 unscaled_a->from_face == unscaled_b->from_face) 110 { 111 if (unscaled_a->from_face) 112 - return unscaled_a->face == unscaled_b->face; 113 + return unscaled_a->face == unscaled_b->face && 114 + unscaled_a->face_context == unscaled_b->face_context; 115 116 if (unscaled_a->filename == NULL && unscaled_b->filename == NULL) 117 return TRUE; 118 @@ -564,6 +590,7 @@ static cairo_status_t 119 char *filename, 120 int id, 121 FT_Face font_face, 122 + void *face_context, 123 cairo_ft_unscaled_font_t **out) 124 { 125 cairo_ft_unscaled_font_t key, *unscaled; 126 @@ -574,7 +601,7 @@ static cairo_status_t 127 if (unlikely (font_map == NULL)) 128 return _cairo_error (CAIRO_STATUS_NO_MEMORY); 129 130 - _cairo_ft_unscaled_font_init_key (&key, from_face, filename, id, font_face); 131 + _cairo_ft_unscaled_font_init_key (&key, from_face, filename, id, font_face, face_context); 132 133 /* Return existing unscaled font if it exists in the hash table. */ 134 unscaled = _cairo_hash_table_lookup (font_map->hash_table, 135 @@ -591,7 +618,7 @@ static cairo_status_t 136 goto UNWIND_FONT_MAP_LOCK; 137 } 138 139 - status = _cairo_ft_unscaled_font_init (unscaled, from_face, filename, id, font_face); 140 + status = _cairo_ft_unscaled_font_init (unscaled, from_face, filename, id, font_face, face_context); 141 if (unlikely (status)) 142 goto UNWIND_UNSCALED_MALLOC; 143 144 @@ -601,6 +628,8 @@ static cairo_status_t 145 if (unlikely (status)) 146 goto UNWIND_UNSCALED_FONT_INIT; 147 148 + mozilla_AddRefSharedFTFace (face_context); 149 + 150 DONE: 151 _cairo_ft_unscaled_font_map_unlock (); 152 *out = unscaled; 153 @@ -653,16 +682,17 @@ static cairo_status_t 154 155 DONE: 156 return _cairo_ft_unscaled_font_create_internal (font_face != NULL, 157 - filename, id, font_face, 158 + filename, id, font_face, NULL, 159 out); 160 } 161 #endif 162 163 static cairo_status_t 164 _cairo_ft_unscaled_font_create_from_face (FT_Face face, 165 + void *face_context, 166 cairo_ft_unscaled_font_t **out) 167 { 168 - return _cairo_ft_unscaled_font_create_internal (TRUE, NULL, face->face_index, face, out); 169 + return _cairo_ft_unscaled_font_create_internal (TRUE, NULL, face->face_index, face, face_context, out); 170 } 171 172 static cairo_bool_t 173 @@ -690,12 +720,16 @@ static cairo_bool_t 174 */ 175 if (unscaled->faces && unscaled->faces->unscaled == NULL) { 176 assert (unscaled->faces->next == NULL); 177 + CAIRO_FT_LOCK (unscaled); 178 cairo_font_face_destroy (&unscaled->faces->base); 179 + CAIRO_FT_UNLOCK (unscaled); 180 } 181 + mozilla_ReleaseSharedFTFace (unscaled->face_context, unscaled); 182 } else { 183 _font_map_release_face_lock_held (font_map, unscaled); 184 } 185 unscaled->face = NULL; 186 + unscaled->face_context = NULL; 187 188 _cairo_ft_unscaled_font_map_unlock (); 189 190 @@ -724,7 +758,13 @@ static cairo_warn FT_Face 191 FT_Face face = NULL; 192 FT_Error error; 193 194 - CAIRO_MUTEX_LOCK (unscaled->mutex); 195 + if (unscaled->face_context) { 196 + if (!mozilla_LockSharedFTFace (unscaled->face_context, unscaled)) { 197 + unscaled->have_scale = FALSE; 198 + } 199 + } else { 200 + CAIRO_FT_LOCK (unscaled); 201 + } 202 unscaled->lock_count++; 203 204 if (unscaled->face) 205 @@ -759,7 +799,7 @@ static cairo_warn FT_Face 206 if (error) 207 { 208 unscaled->lock_count--; 209 - CAIRO_MUTEX_UNLOCK (unscaled->mutex); 210 + CAIRO_FT_UNLOCK (unscaled); 211 _cairo_error_throw (_cairo_ft_to_cairo_error (error)); 212 return NULL; 213 } 214 @@ -784,7 +824,7 @@ static void 215 216 unscaled->lock_count--; 217 218 - CAIRO_MUTEX_UNLOCK (unscaled->mutex); 219 + CAIRO_FT_UNLOCK (unscaled); 220 } 221 222 223 @@ -3997,19 +4037,21 @@ static cairo_bool_t 224 * font_face <------- unscaled 225 */ 226 227 - if (font_face->unscaled && 228 - font_face->unscaled->from_face && 229 - font_face->next == NULL && 230 - font_face->unscaled->faces == font_face && 231 - CAIRO_REFERENCE_COUNT_GET_VALUE (&font_face->unscaled->base.ref_count) > 1) 232 - { 233 - _cairo_unscaled_font_destroy (&font_face->unscaled->base); 234 - font_face->unscaled = NULL; 235 - 236 - return FALSE; 237 - } 238 - 239 if (font_face->unscaled) { 240 + CAIRO_FT_LOCK (font_face->unscaled); 241 + 242 + if (font_face->unscaled->from_face && 243 + font_face->next == NULL && 244 + font_face->unscaled->faces == font_face && 245 + CAIRO_REFERENCE_COUNT_GET_VALUE (&font_face->unscaled->base.ref_count) > 1) 246 + { 247 + CAIRO_FT_UNLOCK (font_face->unscaled); 248 + _cairo_unscaled_font_destroy (&font_face->unscaled->base); 249 + font_face->unscaled = NULL; 250 + 251 + return FALSE; 252 + } 253 + 254 cairo_ft_font_face_t *tmp_face = NULL; 255 cairo_ft_font_face_t *last_face = NULL; 256 257 @@ -4028,6 +4070,7 @@ static cairo_bool_t 258 last_face = tmp_face; 259 } 260 261 + CAIRO_FT_UNLOCK (font_face->unscaled); 262 _cairo_unscaled_font_destroy (&font_face->unscaled->base); 263 font_face->unscaled = NULL; 264 } 265 @@ -4101,6 +4144,24 @@ static cairo_font_face_t * 266 return abstract_face; 267 } 268 269 +static void 270 +_cairo_ft_font_face_lock (void *abstract_face) 271 +{ 272 + cairo_ft_font_face_t *font_face = abstract_face; 273 + if (font_face->unscaled) { 274 + CAIRO_FT_LOCK (font_face->unscaled); 275 + } 276 +} 277 + 278 +static void 279 +_cairo_ft_font_face_unlock (void *abstract_face) 280 +{ 281 + cairo_ft_font_face_t *font_face = abstract_face; 282 + if (font_face->unscaled) { 283 + CAIRO_FT_UNLOCK (font_face->unscaled); 284 + } 285 +} 286 + 287 const cairo_font_face_backend_t _cairo_ft_font_face_backend = { 288 CAIRO_FONT_TYPE_FT, 289 #if CAIRO_HAS_FC_FONT 290 @@ -4110,7 +4171,11 @@ const cairo_font_face_backend_t _cairo_f 291 #endif 292 _cairo_ft_font_face_destroy, 293 _cairo_ft_font_face_scaled_font_create, 294 - _cairo_ft_font_face_get_implementation 295 + _cairo_ft_font_face_get_implementation, 296 +/* 297 + _cairo_ft_font_face_lock, 298 + _cairo_ft_font_face_unlock 299 +*/ 300 }; 301 302 #if CAIRO_HAS_FC_FONT 303 @@ -4153,6 +4218,8 @@ static cairo_font_face_t * 304 { 305 cairo_ft_font_face_t *font_face, **prev_font_face; 306 307 + CAIRO_FT_LOCK (unscaled); 308 + 309 /* Looked for an existing matching font face */ 310 for (font_face = unscaled->faces, prev_font_face = &unscaled->faces; 311 font_face; 312 @@ -4174,15 +4241,19 @@ static cairo_font_face_t * 313 * from owner to ownee. */ 314 font_face->unscaled = unscaled; 315 _cairo_unscaled_font_reference (&unscaled->base); 316 - return &font_face->base; 317 - } else 318 - return cairo_font_face_reference (&font_face->base); 319 + } else { 320 + cairo_font_face_reference (&font_face->base); 321 + } 322 + 323 + CAIRO_FT_UNLOCK (unscaled); 324 + return &font_face->base; 325 } 326 } 327 328 /* No match found, create a new one */ 329 font_face = _cairo_malloc (sizeof (cairo_ft_font_face_t)); 330 if (unlikely (!font_face)) { 331 + CAIRO_FT_UNLOCK (unscaled); 332 _cairo_error_throw (CAIRO_STATUS_NO_MEMORY); 333 return (cairo_font_face_t *)&_cairo_font_face_nil; 334 } 335 @@ -4209,6 +4280,7 @@ static cairo_font_face_t * 336 337 _cairo_font_face_init (&font_face->base, &_cairo_ft_font_face_backend); 338 339 + CAIRO_FT_UNLOCK (unscaled); 340 return &font_face->base; 341 } 342 343 @@ -4570,14 +4642,16 @@ cairo_ft_font_face_create_for_pattern (F 344 cairo_font_face_t * 345 cairo_ft_font_face_create_for_ft_face (FT_Face face, 346 int load_flags, 347 - unsigned int synth_flags) 348 + unsigned int synth_flags, 349 + void *face_context) 350 { 351 cairo_ft_unscaled_font_t *unscaled; 352 cairo_font_face_t *font_face; 353 cairo_ft_options_t ft_options; 354 cairo_status_t status; 355 356 - status = _cairo_ft_unscaled_font_create_from_face (face, &unscaled); 357 + status = _cairo_ft_unscaled_font_create_from_face (face, face_context, 358 + &unscaled); 359 if (unlikely (status)) 360 return (cairo_font_face_t *)&_cairo_font_face_nil; 361 362 @@ -4729,7 +4803,7 @@ cairo_ft_scaled_font_lock_face (cairo_sc 363 * opportunity for creating deadlock. This is obviously unsafe, 364 * but as documented, the user must add manual locking when using 365 * this function. */ 366 - CAIRO_MUTEX_UNLOCK (scaled_font->unscaled->mutex); 367 + CAIRO_FT_UNLOCK (scaled_font->unscaled); 368 369 return face; 370 } 371 @@ -4762,7 +4836,7 @@ cairo_ft_scaled_font_unlock_face (cairo_ 372 * cairo_ft_scaled_font_lock_face, so we have to acquire it again 373 * as _cairo_ft_unscaled_font_unlock_face expects it to be held 374 * when we call into it. */ 375 - CAIRO_MUTEX_LOCK (scaled_font->unscaled->mutex); 376 + CAIRO_FT_LOCK (scaled_font->unscaled); 377 378 _cairo_ft_unscaled_font_unlock_face (scaled_font->unscaled); 379 } 380 diff --git a/gfx/cairo/cairo/src/cairo-ft.h b/gfx/cairo/cairo/src/cairo-ft.h 381 --- a/gfx/cairo/cairo/src/cairo-ft.h 382 +++ b/gfx/cairo/cairo/src/cairo-ft.h 383 @@ -55,7 +55,8 @@ CAIRO_BEGIN_DECLS 384 cairo_public cairo_font_face_t * 385 cairo_ft_font_face_create_for_ft_face (FT_Face face, 386 int load_flags, 387 - unsigned int synth_flags); 388 + unsigned int synth_flags, 389 + void *face_context); 390 391 /** 392 * cairo_ft_synthesize_t: