[WASAPI] fix stream types and frequencies enumeration
[xbmc.git] / xbmc / guilib / GUIFontCache.cpp
blob170b95332d8a85140f80269b29adaf52688a9b10
1 /*
2 * Copyright (C) 2005-2018 Team Kodi
3 * This file is part of Kodi - https://kodi.tv
5 * SPDX-License-Identifier: GPL-2.0-or-later
6 * See LICENSES/README.md for more information.
7 */
9 #include "GUIFontTTF.h"
10 #include "windowing/GraphicContext.h"
12 #include <stdint.h>
13 #include <vector>
15 using namespace std::chrono_literals;
17 namespace
19 constexpr auto FONT_CACHE_TIME_LIMIT = 1000ms;
22 template<class Position, class Value>
23 class CGUIFontCacheImpl
25 struct EntryList
27 using HashMap = std::multimap<size_t, std::unique_ptr<CGUIFontCacheEntry<Position, Value>>>;
28 using HashIter = typename HashMap::iterator;
29 using AgeMap = std::multimap<std::chrono::steady_clock::time_point, HashIter>;
31 ~EntryList() { Flush(); }
33 HashIter Insert(size_t hash, std::unique_ptr<CGUIFontCacheEntry<Position, Value>> v)
35 auto r(hashMap.insert(typename HashMap::value_type(hash, std::move(v))));
36 if (r->second)
37 ageMap.insert(typename AgeMap::value_type(r->second->m_lastUsed, r));
39 return r;
41 void Flush()
43 ageMap.clear();
44 hashMap.clear();
46 typename HashMap::iterator FindKey(CGUIFontCacheKey<Position> key)
48 CGUIFontCacheHash<Position> hashGen;
49 CGUIFontCacheKeysMatch<Position> keyMatch;
50 auto range = hashMap.equal_range(hashGen(key));
51 for (auto ret = range.first; ret != range.second; ++ret)
53 if (keyMatch(ret->second->m_key, key))
55 return ret;
59 return hashMap.end();
61 void UpdateAge(HashIter it, std::chrono::steady_clock::time_point now)
63 auto range = ageMap.equal_range(it->second->m_lastUsed);
64 for (auto ageit = range.first; ageit != range.second; ++ageit)
66 if (ageit->second == it)
68 ageMap.erase(ageit);
69 ageMap.insert(typename AgeMap::value_type(now, it));
70 it->second->m_lastUsed = now;
71 return;
76 HashMap hashMap;
77 AgeMap ageMap;
80 EntryList m_list;
81 CGUIFontCache<Position, Value>* m_parent;
83 public:
84 explicit CGUIFontCacheImpl(CGUIFontCache<Position, Value>* parent) : m_parent(parent) {}
85 Value& Lookup(const CGraphicContext& context,
86 Position& pos,
87 const std::vector<KODI::UTILS::COLOR::Color>& colors,
88 const vecText& text,
89 uint32_t alignment,
90 float maxPixelWidth,
91 bool scrolling,
92 std::chrono::steady_clock::time_point now,
93 bool& dirtyCache);
94 void Flush();
97 template<class Position, class Value>
98 CGUIFontCacheEntry<Position, Value>::~CGUIFontCacheEntry()
100 delete &m_key.m_colors;
101 delete &m_key.m_text;
102 m_value.clear();
105 template<class Position, class Value>
106 void CGUIFontCacheEntry<Position, Value>::Assign(const CGUIFontCacheKey<Position>& key,
107 std::chrono::steady_clock::time_point now)
109 m_key.m_pos = key.m_pos;
110 m_key.m_colors.assign(key.m_colors.begin(), key.m_colors.end());
111 m_key.m_text.assign(key.m_text.begin(), key.m_text.end());
112 m_key.m_alignment = key.m_alignment;
113 m_key.m_maxPixelWidth = key.m_maxPixelWidth;
114 m_key.m_scrolling = key.m_scrolling;
115 m_matrix = key.m_matrix;
116 m_key.m_scaleX = key.m_scaleX;
117 m_key.m_scaleY = key.m_scaleY;
118 m_lastUsed = now;
119 m_value.clear();
122 template<class Position, class Value>
123 CGUIFontCache<Position, Value>::CGUIFontCache(CGUIFontTTF& font)
124 : m_impl(std::make_unique<CGUIFontCacheImpl<Position, Value>>(this)), m_font(font)
128 template<class Position, class Value>
129 CGUIFontCache<Position, Value>::~CGUIFontCache() = default;
131 template<class Position, class Value>
132 Value& CGUIFontCache<Position, Value>::Lookup(const CGraphicContext& context,
133 Position& pos,
134 const std::vector<KODI::UTILS::COLOR::Color>& colors,
135 const vecText& text,
136 uint32_t alignment,
137 float maxPixelWidth,
138 bool scrolling,
139 std::chrono::steady_clock::time_point now,
140 bool& dirtyCache)
142 if (!m_impl)
143 m_impl = std::make_unique<CGUIFontCacheImpl<Position, Value>>(this);
145 return m_impl->Lookup(context, pos, colors, text, alignment, maxPixelWidth, scrolling, now,
146 dirtyCache);
149 template<class Position, class Value>
150 Value& CGUIFontCacheImpl<Position, Value>::Lookup(
151 const CGraphicContext& context,
152 Position& pos,
153 const std::vector<KODI::UTILS::COLOR::Color>& colors,
154 const vecText& text,
155 uint32_t alignment,
156 float maxPixelWidth,
157 bool scrolling,
158 std::chrono::steady_clock::time_point now,
159 bool& dirtyCache)
161 const CGUIFontCacheKey<Position> key(
162 pos, const_cast<std::vector<KODI::UTILS::COLOR::Color>&>(colors), const_cast<vecText&>(text),
163 alignment, maxPixelWidth, scrolling, context.GetGUIMatrix(), context.GetGUIScaleX(),
164 context.GetGUIScaleY());
166 auto i = m_list.FindKey(key);
167 if (i == m_list.hashMap.end())
169 // Cache miss
170 dirtyCache = true;
171 std::unique_ptr<CGUIFontCacheEntry<Position, Value>> entry;
173 if (!m_list.ageMap.empty())
175 const auto duration =
176 std::chrono::duration_cast<std::chrono::milliseconds>(now - m_list.ageMap.begin()->first);
177 if (duration > FONT_CACHE_TIME_LIMIT)
179 entry = std::move(m_list.ageMap.begin()->second->second);
180 m_list.hashMap.erase(m_list.ageMap.begin()->second);
181 m_list.ageMap.erase(m_list.ageMap.begin());
185 // add new entry
186 CGUIFontCacheHash<Position> hashgen;
187 if (!entry)
188 entry = std::make_unique<CGUIFontCacheEntry<Position, Value>>(*m_parent, key, now);
189 else
190 entry->Assign(key, now);
191 return m_list.Insert(hashgen(key), std::move(entry))->second->m_value;
193 else
195 // Cache hit
196 // Update the translation arguments so that they hold the offset to apply
197 // to the cached values (but only in the dynamic case)
198 pos.UpdateWithOffsets(i->second->m_key.m_pos, scrolling);
200 // Update time in entry and move to the back of the list
201 m_list.UpdateAge(i, now);
203 dirtyCache = false;
205 return i->second->m_value;
209 template<class Position, class Value>
210 void CGUIFontCache<Position, Value>::Flush()
212 m_impl->Flush();
215 template<class Position, class Value>
216 void CGUIFontCacheImpl<Position, Value>::Flush()
218 m_list.Flush();
221 template CGUIFontCache<CGUIFontCacheStaticPosition, CGUIFontCacheStaticValue>::CGUIFontCache(
222 CGUIFontTTF& font);
223 template CGUIFontCache<CGUIFontCacheStaticPosition, CGUIFontCacheStaticValue>::~CGUIFontCache();
224 template CGUIFontCacheEntry<CGUIFontCacheStaticPosition,
225 CGUIFontCacheStaticValue>::~CGUIFontCacheEntry();
226 template CGUIFontCacheStaticValue& CGUIFontCache<
227 CGUIFontCacheStaticPosition,
228 CGUIFontCacheStaticValue>::Lookup(const CGraphicContext& context,
229 CGUIFontCacheStaticPosition&,
230 const std::vector<KODI::UTILS::COLOR::Color>&,
231 const vecText&,
232 uint32_t,
233 float,
234 bool,
235 std::chrono::steady_clock::time_point,
236 bool&);
237 template void CGUIFontCache<CGUIFontCacheStaticPosition, CGUIFontCacheStaticValue>::Flush();
239 template CGUIFontCache<CGUIFontCacheDynamicPosition, CGUIFontCacheDynamicValue>::CGUIFontCache(
240 CGUIFontTTF& font);
241 template CGUIFontCache<CGUIFontCacheDynamicPosition, CGUIFontCacheDynamicValue>::~CGUIFontCache();
242 template CGUIFontCacheEntry<CGUIFontCacheDynamicPosition,
243 CGUIFontCacheDynamicValue>::~CGUIFontCacheEntry();
244 template CGUIFontCacheDynamicValue& CGUIFontCache<
245 CGUIFontCacheDynamicPosition,
246 CGUIFontCacheDynamicValue>::Lookup(const CGraphicContext& context,
247 CGUIFontCacheDynamicPosition&,
248 const std::vector<KODI::UTILS::COLOR::Color>&,
249 const vecText&,
250 uint32_t,
251 float,
252 bool,
253 std::chrono::steady_clock::time_point,
254 bool&);
255 template void CGUIFontCache<CGUIFontCacheDynamicPosition, CGUIFontCacheDynamicValue>::Flush();
257 void CVertexBuffer::clear()
259 if (m_font)
260 m_font->DestroyVertexBuffer(*this);