Commit 91516900 authored by derat@chromium.org's avatar derat@chromium.org

linux: Cache GetFontRenderParams() results.

Make the Linux implementation of GetFontRenderParams() cache
the ten most recent results to greatly reduce the number of
Fontconfig queries that are performed.

BUG=376077,391830

Review URL: https://codereview.chromium.org/440773003

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@287977 0039d316-1c4b-4281-b951-d872f2087c98
parent fa84b0d4
......@@ -91,6 +91,13 @@ GFX_EXPORT FontRenderParams GetFontRenderParams(
const FontRenderParamsQuery& query,
std::string* family_out);
// Clears GetFontRenderParams()'s cache. Intended to be called by tests that are
// changing Fontconfig's configuration.
// TODO(derat): This is only defined for Linux, but OS_LINUX doesn't seem to be
// set when font_render_params_linux_unittest.cc includes this header. Figure
// out what's going on here.
GFX_EXPORT void ClearFontRenderParamsCacheForTest();
} // namespace gfx
#endif // UI_GFX_FONT_RENDER_PARAMS_H_
......@@ -5,7 +5,12 @@
#include "ui/gfx/font_render_params.h"
#include "base/command_line.h"
#include "base/containers/mru_cache.h"
#include "base/hash.h"
#include "base/logging.h"
#include "base/macros.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "ui/gfx/font.h"
#include "ui/gfx/linux_font_delegate.h"
#include "ui/gfx/switches.h"
......@@ -16,6 +21,13 @@ namespace gfx {
namespace {
// Should cache entries by dropped by the next call to GetFontRenderParams()?
// Used for tests.
bool g_clear_cache_for_test = false;
// Number of recent GetFontRenderParams() results to cache.
const size_t kCacheSize = 10;
// Converts Fontconfig FC_HINT_STYLE to FontRenderParams::Hinting.
FontRenderParams::Hinting ConvertFontconfigHintStyle(int hint_style) {
switch (hint_style) {
......@@ -114,12 +126,40 @@ bool QueryFontconfig(const FontRenderParamsQuery& query,
return true;
}
// Serialize |query| into a string and hash it to a value suitable for use as a
// cache key.
uint32 HashFontRenderParamsQuery(const FontRenderParamsQuery& query) {
return base::Hash(base::StringPrintf("%d|%d|%d|%d|%s",
query.for_web_contents, query.pixel_size, query.point_size, query.style,
JoinString(query.families, ',').c_str()));
}
} // namespace
FontRenderParams GetFontRenderParams(const FontRenderParamsQuery& query,
std::string* family_out) {
if (family_out)
typedef base::MRUCache<uint32, FontRenderParams> Cache;
CR_DEFINE_STATIC_LOCAL(Cache, cache, (kCacheSize));
if (g_clear_cache_for_test) {
cache.Clear();
g_clear_cache_for_test = false;
}
const uint32 hash = HashFontRenderParamsQuery(query);
if (!family_out) {
// The family returned by Fontconfig isn't part of FontRenderParams, so we
// can only return a value from the cache if it wasn't requested.
Cache::const_iterator it = cache.Get(hash);
if (it != cache.end()) {
DVLOG(1) << "Returning cached params for " << hash;
return it->second;
}
} else {
family_out->clear();
}
DVLOG(1) << "Computing params for " << hash
<< (family_out ? " (family requested)" : "");
// Start with the delegate's settings, but let Fontconfig have the final say.
FontRenderParams params;
......@@ -152,7 +192,12 @@ FontRenderParams GetFontRenderParams(const FontRenderParamsQuery& query,
if (family_out && family_out->empty() && !query.families.empty())
*family_out = query.families[0];
cache.Put(hash, params);
return params;
}
void ClearFontRenderParamsCacheForTest() {
g_clear_cache_for_test = true;
}
} // namespace gfx
......@@ -67,6 +67,7 @@ class FontRenderParamsTest : public testing::Test {
CHECK(temp_dir_.CreateUniqueTempDir());
original_font_delegate_ = LinuxFontDelegate::instance();
LinuxFontDelegate::SetInstance(&test_font_delegate_);
ClearFontRenderParamsCacheForTest();
}
virtual ~FontRenderParamsTest() {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment