diff options
Diffstat (limited to 'chromium/third_party/blink/renderer/platform/fonts/font_data_cache.cc')
-rw-r--r-- | chromium/third_party/blink/renderer/platform/fonts/font_data_cache.cc | 159 |
1 files changed, 159 insertions, 0 deletions
diff --git a/chromium/third_party/blink/renderer/platform/fonts/font_data_cache.cc b/chromium/third_party/blink/renderer/platform/fonts/font_data_cache.cc new file mode 100644 index 00000000000..060207ea5e5 --- /dev/null +++ b/chromium/third_party/blink/renderer/platform/fonts/font_data_cache.cc @@ -0,0 +1,159 @@ +/* + * Copyright (C) 2013 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "third_party/blink/renderer/platform/fonts/font_data_cache.h" + +#include "build/build_config.h" +#include "third_party/blink/renderer/platform/fonts/simple_font_data.h" + +namespace blink { + +#if !defined(OS_ANDROID) +const unsigned kCMaxInactiveFontData = 250; +const unsigned kCTargetInactiveFontData = 200; +#else +const unsigned kCMaxInactiveFontData = 225; +const unsigned kCTargetInactiveFontData = 200; +#endif + +scoped_refptr<SimpleFontData> FontDataCache::Get(const FontPlatformData* platform_data, + ShouldRetain should_retain, + bool subpixel_ascent_descent) { + if (!platform_data) + return nullptr; + + // TODO: crbug.com/446376 - This should not happen, but we currently + // do not have a reproduction for the crash that an empty typeface() + // causes downstream from here. + if (!platform_data->Typeface()) { + DLOG(ERROR) + << "Empty typeface() in FontPlatformData when accessing FontDataCache."; + return nullptr; + } + + Cache::iterator result = cache_.find(platform_data); + if (result == cache_.end()) { + std::pair<scoped_refptr<SimpleFontData>, unsigned> new_value( + SimpleFontData::Create(*platform_data, nullptr, + subpixel_ascent_descent), + should_retain == kRetain ? 1 : 0); + // The new SimpleFontData takes a copy of the incoming FontPlatformData + // object. The incoming key may be temporary. So, for cache storage, take + // the address of the newly created FontPlatformData that is copied an owned + // by SimpleFontData. + cache_.Set(&new_value.first->PlatformData(), new_value); + if (should_retain == kDoNotRetain) + inactive_font_data_.insert(new_value.first); + return std::move(new_value.first); + } + + if (!result.Get()->value.second) { + DCHECK(inactive_font_data_.Contains(result.Get()->value.first)); + inactive_font_data_.erase(result.Get()->value.first); + } + + if (should_retain == kRetain) { + result.Get()->value.second++; + } else if (!result.Get()->value.second) { + // If shouldRetain is DoNotRetain and count is 0, we want to remove the + // fontData from m_inactiveFontData (above) and re-add here to update LRU + // position. + inactive_font_data_.insert(result.Get()->value.first); + } + + return result.Get()->value.first; +} + +bool FontDataCache::Contains(const FontPlatformData* font_platform_data) const { + return cache_.Contains(font_platform_data); +} + +void FontDataCache::Release(const SimpleFontData* font_data) { + DCHECK(!font_data->IsCustomFont()); + + Cache::iterator it = cache_.find(&(font_data->PlatformData())); + DCHECK_NE(it, cache_.end()); + if (it == cache_.end()) + return; + + DCHECK(it->value.second); + if (!--it->value.second) + inactive_font_data_.insert(it->value.first); +} + +bool FontDataCache::Purge(PurgeSeverity purge_severity) { + if (purge_severity == kForcePurge) + return PurgeLeastRecentlyUsed(INT_MAX); + + if (inactive_font_data_.size() > kCMaxInactiveFontData) + return PurgeLeastRecentlyUsed(inactive_font_data_.size() - + kCTargetInactiveFontData); + + return false; +} + +bool FontDataCache::PurgeLeastRecentlyUsed(int count) { + // Guard against reentry when e.g. a deleted FontData releases its small caps + // FontData. + static bool is_purging; + if (is_purging) + return false; + + is_purging = true; + + Vector<scoped_refptr<SimpleFontData>, 20> font_data_to_delete; + auto end = inactive_font_data_.end(); + auto it = inactive_font_data_.begin(); + for (int i = 0; i < count && it != end; ++it, ++i) { + scoped_refptr<SimpleFontData>& font_data = *it.Get(); + cache_.erase(&(font_data->PlatformData())); + // We should not delete SimpleFontData here because deletion can modify + // m_inactiveFontData. See http://trac.webkit.org/changeset/44011 + font_data_to_delete.push_back(font_data); + } + + if (it == end) { + // Removed everything + inactive_font_data_.clear(); + } else { + for (int i = 0; i < count; ++i) + inactive_font_data_.erase(inactive_font_data_.begin()); + } + + bool did_work = font_data_to_delete.size(); + + font_data_to_delete.clear(); + + is_purging = false; + + return did_work; +} + +} // namespace blink |