[poppler] poppler/CairoFontEngine.cc
GitLab Mirror
gitlab-mirror at kemper.freedesktop.org
Wed Sep 2 17:18:09 UTC 2020
poppler/CairoFontEngine.cc | 40 +++++++++++++++++++++-------------------
1 file changed, 21 insertions(+), 19 deletions(-)
New commits:
commit e79cbe0adcf7d1a0dbfc4a77a096d2fbab327f39
Author: Michal <sudolskym at gmail.com>
Date: Wed Sep 2 17:18:06 2020 +0000
evict just font faces owned solely by cache
These are font faces with reference count 1. Their scaled fonts were already evicted from cairo holdover cache. This should be more functionally equivalent to old behaviour except that eviction is done lazily and not eagerly.
diff --git a/poppler/CairoFontEngine.cc b/poppler/CairoFontEngine.cc
old mode 100644
new mode 100755
index 25e241a4..1ae393a3
--- a/poppler/CairoFontEngine.cc
+++ b/poppler/CairoFontEngine.cc
@@ -40,6 +40,7 @@
#include "config.h"
#include <cstring>
+#include <forward_list>
#include "CairoFontEngine.h"
#include "CairoOutputDev.h"
#include "GlobalParams.h"
@@ -178,10 +179,8 @@ static bool _ft_new_face_uncached(FT_Library lib, const char *filename, char *fo
}
#ifdef CAN_CHECK_OPEN_FACES
-static struct _ft_face_data
+struct _ft_face_data
{
- struct _ft_face_data *prev, *next, **head;
-
int fd;
unsigned long hash;
size_t size;
@@ -190,7 +189,20 @@ static struct _ft_face_data
FT_Library lib;
FT_Face face;
cairo_font_face_t *font_face;
-} * _ft_open_faces;
+};
+
+class _FtFaceDataProxy
+{
+ _ft_face_data *_data;
+
+public:
+ _FtFaceDataProxy(_ft_face_data *data) : _data(data) { cairo_font_face_reference(_data->font_face); }
+ _FtFaceDataProxy(_FtFaceDataProxy &&) = delete;
+ ~_FtFaceDataProxy() { cairo_font_face_destroy(_data->font_face); }
+ operator _ft_face_data *() { return _data; }
+};
+
+static thread_local std::forward_list<_FtFaceDataProxy> _local_open_faces;
static unsigned long _djb_hash(const unsigned char *bytes, size_t len)
{
@@ -219,13 +231,6 @@ static void _ft_done_face(void *closure)
{
struct _ft_face_data *data = (struct _ft_face_data *)closure;
- if (data->next)
- data->next->prev = data->prev;
- if (data->prev)
- data->prev->next = data->next;
- else
- _ft_open_faces = data->next;
-
if (data->fd != -1) {
# if defined(__SUNPRO_CC) && defined(__sun) && defined(__SVR4)
munmap((char *)data->bytes, data->size);
@@ -243,7 +248,6 @@ static void _ft_done_face(void *closure)
static bool _ft_new_face(FT_Library lib, const char *filename, char *font_data, int font_data_len, FT_Face *face_out, cairo_font_face_t **font_face_out)
{
- struct _ft_face_data *l;
struct stat st;
struct _ft_face_data tmpl;
@@ -275,7 +279,7 @@ static bool _ft_new_face(FT_Library lib, const char *filename, char *font_data,
tmpl.lib = lib;
tmpl.hash = _djb_hash(tmpl.bytes, tmpl.size);
- for (l = _ft_open_faces; l; l = l->next) {
+ for (_ft_face_data *l : _local_open_faces) {
if (_ft_face_data_equal(l, &tmpl)) {
if (tmpl.fd != -1) {
# if defined(__SUNPRO_CC) && defined(__sun) && defined(__SVR4)
@@ -307,13 +311,8 @@ static bool _ft_new_face(FT_Library lib, const char *filename, char *font_data,
return false;
}
- l = (struct _ft_face_data *)gmallocn(1, sizeof(struct _ft_face_data));
+ struct _ft_face_data *l = (struct _ft_face_data *)gmallocn(1, sizeof(struct _ft_face_data));
*l = tmpl;
- l->prev = nullptr;
- l->next = _ft_open_faces;
- if (_ft_open_faces)
- _ft_open_faces->prev = l;
- _ft_open_faces = l;
l->font_face = cairo_ft_font_face_create_for_ft_face(tmpl.face, FT_LOAD_NO_HINTING | FT_LOAD_NO_BITMAP);
if (cairo_font_face_set_user_data(l->font_face, &_ft_cairo_key, l, _ft_done_face)) {
@@ -322,6 +321,9 @@ static bool _ft_new_face(FT_Library lib, const char *filename, char *font_data,
return false;
}
+ _local_open_faces.remove_if([](_ft_face_data *data) { return cairo_font_face_get_reference_count(data->font_face) == 1; });
+ _local_open_faces.emplace_front(l);
+
*face_out = l->face;
*font_face_out = l->font_face;
return true;
More information about the poppler
mailing list