2 #include "glyph_cache.h"
3 #include "gdipp_lib/lock.h"
4 #include "gdipp_server/global.h"
9 glyph_cache::string_id_type
glyph_cache::get_string_id(const wchar_t *string
, unsigned int count
, bool is_glyph_index
)
11 string_id_type string_id
;
13 MurmurHash3_x64_128(string
, count
* sizeof(wchar_t), is_glyph_index
, &string_id
);
15 MurmurHash3_x86_128(string
, count
* sizeof(wchar_t), is_glyph_index
, &string_id
);
21 glyph_cache::char_id_type
glyph_cache::get_char_id(uint128_t render_trait
, FT_UInt index
, bool is_glyph_index
)
25 * low 64 bits: low 64 bits of render_trait
29 | render_trait (65 - 96 bit) | is_glyph_index | index |
31 char_id_type char_id
= render_trait
;
32 char_id
.second
= (char_id
.second
<< 33) | (static_cast<uint64_t>(is_glyph_index
) << 32) | index
;
36 glyph_cache::~glyph_cache()
38 for (std::map
<char_id_type
, const FT_Glyph
>::const_iterator glyph_iter
= _glyph_store
.begin(); glyph_iter
!= _glyph_store
.end(); ++glyph_iter
)
39 FT_Done_Glyph(glyph_iter
->second
);
41 for (std::map
<uint128_t
, trait_to_run_map
>::const_iterator str_iter
= _glyph_run_store
.begin(); str_iter
!= _glyph_run_store
.end(); ++str_iter
)
43 for (trait_to_run_map::const_iterator trait_iter
= str_iter
->second
.begin(); trait_iter
!= str_iter
->second
.end(); ++trait_iter
)
44 delete trait_iter
->second
;
48 void glyph_cache::initialize()
50 _glyph_run_lru
.resize(min(1 << server_cache_size
, 16777216));
53 const FT_Glyph
glyph_cache::lookup_glyph(char_id_type char_id
) const
55 std::map
<char_id_type
, const FT_Glyph
>::const_iterator glyph_iter
= _glyph_store
.find(char_id
);
56 if (glyph_iter
== _glyph_store
.end())
58 lock
l(lock::SERVER_GLYPH_CACHE
);
59 glyph_iter
= _glyph_store
.find(char_id
);
60 if (glyph_iter
== _glyph_store
.end())
64 return glyph_iter
->second
;
67 bool glyph_cache::store_glyph(char_id_type char_id
, const FT_Glyph glyph
)
69 lock
l(lock::SERVER_GLYPH_CACHE
);
71 const std::pair
<std::map
<char_id_type
, const FT_Glyph
>::const_iterator
, bool> glyph_insert_ret
= _glyph_store
.insert(std::pair
<uint128_t
, const FT_Glyph
>(char_id
, glyph
));
73 return glyph_insert_ret
.second
;
76 const glyph_run
*glyph_cache::lookup_glyph_run(uint128_t string_id
, uint128_t render_trait
) const
78 lock
l(lock::SERVER_GLYPH_RUN_CACHE
);
80 std::map
<uint128_t
, trait_to_run_map
>::const_iterator str_iter
= _glyph_run_store
.find(string_id
);
81 if (str_iter
== _glyph_run_store
.end())
84 trait_to_run_map::const_iterator trait_iter
= str_iter
->second
.find(render_trait
);
85 if (trait_iter
== str_iter
->second
.end())
88 return trait_iter
->second
;
91 bool glyph_cache::store_glyph_run(uint128_t string_id
, uint128_t render_trait
, glyph_run
*a_glyph_run
)
93 lock
l(lock::SERVER_GLYPH_RUN_CACHE
);
98 b_ret
= _glyph_run_lru
.access(string_id
, erased_str
);
101 // the string is evicted from LRU cache
102 // erase all cached glyph run that is under the evicted string ID
104 std::map
<uint128_t
, trait_to_run_map
>::iterator str_iter
= _glyph_run_store
.find(erased_str
);
105 assert(str_iter
!= _glyph_run_store
.end());
107 for (trait_to_run_map::const_iterator trait_iter
= str_iter
->second
.begin(); trait_iter
!= str_iter
->second
.end(); ++trait_iter
)
108 delete trait_iter
->second
;
110 _glyph_run_store
.erase(str_iter
);
113 // after eviction, insert new glyph_run
114 const std::pair
<std::map
<uint128_t
, trait_to_run_map
>::iterator
, bool> str_insert_ret
= _glyph_run_store
.insert(std::pair
<uint128_t
, trait_to_run_map
>(string_id
, trait_to_run_map()));
115 const std::pair
<trait_to_run_map::const_iterator
, bool> trait_insert_ret
= str_insert_ret
.first
->second
.insert(std::pair
<uint128_t
, glyph_run
*>(render_trait
, a_glyph_run
));
117 return trait_insert_ret
.second
;