| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "ui/gfx/font_render_params.h" | 5 #include "ui/gfx/font_render_params.h" |
| 6 | 6 |
| 7 #include <fontconfig/fontconfig.h> | 7 #include <fontconfig/fontconfig.h> |
| 8 | 8 |
| 9 #include "base/command_line.h" | 9 #include "base/command_line.h" |
| 10 #include "base/containers/mru_cache.h" | 10 #include "base/containers/mru_cache.h" |
| (...skipping 11 matching lines...) Expand all Loading... |
| 22 namespace gfx { | 22 namespace gfx { |
| 23 | 23 |
| 24 namespace { | 24 namespace { |
| 25 | 25 |
| 26 #if defined(OS_CHROMEOS) | 26 #if defined(OS_CHROMEOS) |
| 27 // A device scale factor for an internal display (if any) | 27 // A device scale factor for an internal display (if any) |
| 28 // that is used to determine if subpixel positioning should be used. | 28 // that is used to determine if subpixel positioning should be used. |
| 29 float device_scale_factor_for_internal_display = 1.0f; | 29 float device_scale_factor_for_internal_display = 1.0f; |
| 30 #endif | 30 #endif |
| 31 | 31 |
| 32 // Keyed by hashes of FontRenderParamQuery structs from | |
| 33 // HashFontRenderParamsQuery(). | |
| 34 typedef base::MRUCache<uint32, FontRenderParams> Cache; | |
| 35 | |
| 36 // Number of recent GetFontRenderParams() results to cache. | 32 // Number of recent GetFontRenderParams() results to cache. |
| 37 const size_t kCacheSize = 20; | 33 const size_t kCacheSize = 20; |
| 38 | 34 |
| 35 // Cached result from a call to GetFontRenderParams(). |
| 36 struct QueryResult { |
| 37 QueryResult(const FontRenderParams& params, const std::string& family) |
| 38 : params(params), |
| 39 family(family) { |
| 40 } |
| 41 ~QueryResult() {} |
| 42 |
| 43 FontRenderParams params; |
| 44 std::string family; |
| 45 }; |
| 46 |
| 47 // Keyed by hashes of FontRenderParamQuery structs from |
| 48 // HashFontRenderParamsQuery(). |
| 49 typedef base::MRUCache<uint32, QueryResult> Cache; |
| 50 |
| 39 // A cache and the lock that must be held while accessing it. | 51 // A cache and the lock that must be held while accessing it. |
| 40 // GetFontRenderParams() is called by both the UI thread and the sandbox IPC | 52 // GetFontRenderParams() is called by both the UI thread and the sandbox IPC |
| 41 // thread. | 53 // thread. |
| 42 struct SynchronizedCache { | 54 struct SynchronizedCache { |
| 43 SynchronizedCache() : cache(kCacheSize) {} | 55 SynchronizedCache() : cache(kCacheSize) {} |
| 44 | 56 |
| 45 base::Lock lock; | 57 base::Lock lock; |
| 46 Cache cache; | 58 Cache cache; |
| 47 }; | 59 }; |
| 48 | 60 |
| (...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 161 return base::Hash(base::StringPrintf("%d|%d|%d|%d|%s", | 173 return base::Hash(base::StringPrintf("%d|%d|%d|%d|%s", |
| 162 query.for_web_contents, query.pixel_size, query.point_size, query.style, | 174 query.for_web_contents, query.pixel_size, query.point_size, query.style, |
| 163 JoinString(query.families, ',').c_str())); | 175 JoinString(query.families, ',').c_str())); |
| 164 } | 176 } |
| 165 | 177 |
| 166 } // namespace | 178 } // namespace |
| 167 | 179 |
| 168 FontRenderParams GetFontRenderParams(const FontRenderParamsQuery& query, | 180 FontRenderParams GetFontRenderParams(const FontRenderParamsQuery& query, |
| 169 std::string* family_out) { | 181 std::string* family_out) { |
| 170 const uint32 hash = HashFontRenderParamsQuery(query); | 182 const uint32 hash = HashFontRenderParamsQuery(query); |
| 171 if (!family_out) { | 183 SynchronizedCache* synchronized_cache = g_synchronized_cache.Pointer(); |
| 172 // The family returned by Fontconfig isn't part of FontRenderParams, so we | 184 |
| 173 // can only return a value from the cache if it wasn't requested. | 185 { |
| 174 SynchronizedCache* synchronized_cache = g_synchronized_cache.Pointer(); | 186 // Try to find a cached result so Fontconfig doesn't need to be queried. |
| 175 base::AutoLock lock(synchronized_cache->lock); | 187 base::AutoLock lock(synchronized_cache->lock); |
| 176 Cache::const_iterator it = synchronized_cache->cache.Get(hash); | 188 Cache::const_iterator it = synchronized_cache->cache.Get(hash); |
| 177 if (it != synchronized_cache->cache.end()) { | 189 if (it != synchronized_cache->cache.end()) { |
| 178 DVLOG(1) << "Returning cached params for " << hash; | 190 DVLOG(1) << "Returning cached params for " << hash; |
| 179 return it->second; | 191 const QueryResult& result = it->second; |
| 192 if (family_out) |
| 193 *family_out = result.family; |
| 194 return result.params; |
| 180 } | 195 } |
| 181 } else { | 196 } |
| 197 |
| 198 DVLOG(1) << "Computing params for " << hash; |
| 199 if (family_out) |
| 182 family_out->clear(); | 200 family_out->clear(); |
| 183 } | |
| 184 DVLOG(1) << "Computing params for " << hash | |
| 185 << (family_out ? " (family requested)" : ""); | |
| 186 | 201 |
| 187 // Start with the delegate's settings, but let Fontconfig have the final say. | 202 // Start with the delegate's settings, but let Fontconfig have the final say. |
| 188 FontRenderParams params; | 203 FontRenderParams params; |
| 189 const LinuxFontDelegate* delegate = LinuxFontDelegate::instance(); | 204 const LinuxFontDelegate* delegate = LinuxFontDelegate::instance(); |
| 190 if (delegate) | 205 if (delegate) |
| 191 params = delegate->GetDefaultFontRenderParams(); | 206 params = delegate->GetDefaultFontRenderParams(); |
| 192 QueryFontconfig(query, ¶ms, family_out); | 207 QueryFontconfig(query, ¶ms, family_out); |
| 193 if (!params.antialiasing) { | 208 if (!params.antialiasing) { |
| 194 // Cairo forces full hinting when antialiasing is disabled, since anything | 209 // Cairo forces full hinting when antialiasing is disabled, since anything |
| 195 // less than that looks awful; do the same here. Requesting subpixel | 210 // less than that looks awful; do the same here. Requesting subpixel |
| (...skipping 12 matching lines...) Expand all Loading... |
| 208 | 223 |
| 209 // To enable subpixel positioning, we need to disable hinting. | 224 // To enable subpixel positioning, we need to disable hinting. |
| 210 if (params.subpixel_positioning) | 225 if (params.subpixel_positioning) |
| 211 params.hinting = FontRenderParams::HINTING_NONE; | 226 params.hinting = FontRenderParams::HINTING_NONE; |
| 212 } | 227 } |
| 213 | 228 |
| 214 // Use the first family from the list if Fontconfig didn't suggest a family. | 229 // Use the first family from the list if Fontconfig didn't suggest a family. |
| 215 if (family_out && family_out->empty() && !query.families.empty()) | 230 if (family_out && family_out->empty() && !query.families.empty()) |
| 216 *family_out = query.families[0]; | 231 *family_out = query.families[0]; |
| 217 | 232 |
| 218 // Store the computed struct. It's fine if this overwrites a struct that was | 233 { |
| 219 // cached by a different thread in the meantime; the values should be | 234 // Store the result. It's fine if this overwrites a result that was cached |
| 220 // identical. | 235 // by a different thread in the meantime; the values should be identical. |
| 221 SynchronizedCache* synchronized_cache = g_synchronized_cache.Pointer(); | 236 base::AutoLock lock(synchronized_cache->lock); |
| 222 base::AutoLock lock(synchronized_cache->lock); | 237 synchronized_cache->cache.Put(hash, |
| 223 synchronized_cache->cache.Put(hash, params); | 238 QueryResult(params, family_out ? *family_out : std::string())); |
| 239 } |
| 224 | 240 |
| 225 return params; | 241 return params; |
| 226 } | 242 } |
| 227 | 243 |
| 228 void ClearFontRenderParamsCacheForTest() { | 244 void ClearFontRenderParamsCacheForTest() { |
| 229 SynchronizedCache* synchronized_cache = g_synchronized_cache.Pointer(); | 245 SynchronizedCache* synchronized_cache = g_synchronized_cache.Pointer(); |
| 230 base::AutoLock lock(synchronized_cache->lock); | 246 base::AutoLock lock(synchronized_cache->lock); |
| 231 synchronized_cache->cache.Clear(); | 247 synchronized_cache->cache.Clear(); |
| 232 } | 248 } |
| 233 | 249 |
| 234 #if defined(OS_CHROMEOS) | 250 #if defined(OS_CHROMEOS) |
| 235 void SetFontRenderParamsDeviceScaleFactor(float device_scale_factor) { | 251 void SetFontRenderParamsDeviceScaleFactor(float device_scale_factor) { |
| 236 device_scale_factor_for_internal_display = device_scale_factor; | 252 device_scale_factor_for_internal_display = device_scale_factor; |
| 237 } | 253 } |
| 238 #endif | 254 #endif |
| 239 | 255 |
| 240 } // namespace gfx | 256 } // namespace gfx |
| OLD | NEW |