Commit 9237ba41 authored by Dominik Röttsches's avatar Dominik Röttsches Committed by Commit Bot

Avoid double CTFont creation by passing through data descriptor

The out-of-process font loader, now that it has moved to using
CTFontManagerCreateFontDescriptorFromData, does not need to create a
full CTFontRef anymore, but can instead wrap the out-of-process font
data into a CTFontDescriptorRef built from data. Doing that avoids
creating an extra CTFont copy in font_platform_data_mac, as we can merge
the data descriptor with the cascade list attributes, and only then
create the CTFontRef from it.

Bug: 1033478
Change-Id: I025c265caf472578fd77a11acbc4b23a1d8fffb2
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2013289
Commit-Queue: Dominik Röttsches <drott@chromium.org>
Auto-Submit: Dominik Röttsches <drott@chromium.org>
Reviewed-by: default avatarMatt Falkenhagen <falken@chromium.org>
Reviewed-by: default avatarNico Weber <thakis@chromium.org>
Reviewed-by: default avatarElly Fong-Jones <ellyjones@chromium.org>
Cr-Commit-Position: refs/heads/master@{#735353}
parent 3c8643fc
...@@ -211,13 +211,13 @@ MULTIPROCESS_TEST_MAIN(FontLoadingProcess) { ...@@ -211,13 +211,13 @@ MULTIPROCESS_TEST_MAIN(FontLoadingProcess) {
font_shmem->Clone(mojo::SharedBufferHandle::AccessMode::READ_ONLY); font_shmem->Clone(mojo::SharedBufferHandle::AccessMode::READ_ONLY);
CHECK(shmem_handle.is_valid()); CHECK(shmem_handle.is_valid());
base::ScopedCFTypeRef<CTFontRef> ctfont_base; base::ScopedCFTypeRef<CTFontDescriptorRef> data_descriptor;
CHECK(FontLoader::CTFontRefFromBuffer( CHECK(FontLoader::CTFontDescriptorFromBuffer(
std::move(shmem_handle), font_data_length, ctfont_base.InitializeInto())); std::move(shmem_handle), font_data_length, &data_descriptor));
CHECK(ctfont_base); CHECK(data_descriptor);
base::ScopedCFTypeRef<CTFontRef> sized_ctfont(CTFontCreateCopyWithAttributes( base::ScopedCFTypeRef<CTFontRef> sized_ctfont(
ctfont_base.get(), 16.0, nullptr, nullptr)); CTFontCreateWithFontDescriptor(data_descriptor.get(), 16.0, nullptr));
CHECK(sized_ctfont); CHECK(sized_ctfont);
// Do something with the font to make sure it's loaded. // Do something with the font to make sure it's loaded.
......
...@@ -29,9 +29,10 @@ WebSandboxSupportMac::WebSandboxSupportMac() { ...@@ -29,9 +29,10 @@ WebSandboxSupportMac::WebSandboxSupportMac() {
WebSandboxSupportMac::~WebSandboxSupportMac() = default; WebSandboxSupportMac::~WebSandboxSupportMac() = default;
bool WebSandboxSupportMac::LoadFont(CTFontRef font, bool WebSandboxSupportMac::LoadFont(
CTFontRef* out, CTFontRef font,
uint32_t* font_id) { base::ScopedCFTypeRef<CTFontDescriptorRef>* out_descriptor,
uint32_t* font_id) {
if (!sandbox_support_) if (!sandbox_support_)
return false; return false;
base::ScopedCFTypeRef<CFStringRef> name_ref(CTFontCopyPostScriptName(font)); base::ScopedCFTypeRef<CFStringRef> name_ref(CTFontCopyPostScriptName(font));
...@@ -43,7 +44,7 @@ bool WebSandboxSupportMac::LoadFont(CTFontRef font, ...@@ -43,7 +44,7 @@ bool WebSandboxSupportMac::LoadFont(CTFontRef font,
*font_id > 0 && font_data.is_valid(); *font_id > 0 && font_data.is_valid();
if (!success) { if (!success) {
DLOG(ERROR) << "Bad response from LoadFont() for " << font_name; DLOG(ERROR) << "Bad response from LoadFont() for " << font_name;
*out = nullptr; out_descriptor->reset();
*font_id = 0; *font_id = 0;
return false; return false;
} }
...@@ -55,8 +56,9 @@ bool WebSandboxSupportMac::LoadFont(CTFontRef font, ...@@ -55,8 +56,9 @@ bool WebSandboxSupportMac::LoadFont(CTFontRef font,
// TODO(jeremy): Need to call back into the requesting process to make sure // TODO(jeremy): Need to call back into the requesting process to make sure
// that the font isn't already activated, based on the font id. If it's // that the font isn't already activated, based on the font id. If it's
// already activated, don't reactivate it here - https://crbug.com/72727 . // already activated, don't reactivate it here - https://crbug.com/72727 .
return FontLoader::CTFontRefFromBuffer( return FontLoader::CTFontDescriptorFromBuffer(
std::move(font_data), static_cast<uint32_t>(font_data_size), out); std::move(font_data), static_cast<uint32_t>(font_data_size),
out_descriptor);
} }
SkColor WebSandboxSupportMac::GetSystemColor(blink::MacSystemColorID color_id) { SkColor WebSandboxSupportMac::GetSystemColor(blink::MacSystemColorID color_id) {
......
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
#include <CoreText/CoreText.h> #include <CoreText/CoreText.h>
#include "base/mac/scoped_cftyperef.h"
#include "base/memory/read_only_shared_memory_region.h" #include "base/memory/read_only_shared_memory_region.h"
#include "base/memory/shared_memory_mapping.h" #include "base/memory/shared_memory_mapping.h"
#include "content/common/sandbox_support_mac.mojom.h" #include "content/common/sandbox_support_mac.mojom.h"
...@@ -24,7 +25,9 @@ class WebSandboxSupportMac : public blink::WebSandboxSupport { ...@@ -24,7 +25,9 @@ class WebSandboxSupportMac : public blink::WebSandboxSupport {
~WebSandboxSupportMac() override; ~WebSandboxSupportMac() override;
// blink::WebSandboxSupport: // blink::WebSandboxSupport:
bool LoadFont(CTFontRef font, CTFontRef* out, uint32_t* font_id) override; bool LoadFont(CTFontRef font,
base::ScopedCFTypeRef<CTFontDescriptorRef>* out_descriptor,
uint32_t* font_id) override;
SkColor GetSystemColor(blink::MacSystemColorID color_id) override; SkColor GetSystemColor(blink::MacSystemColorID color_id) override;
private: private:
......
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
#include <memory> #include <memory>
#include "base/callback_forward.h" #include "base/callback_forward.h"
#include "base/mac/scoped_cftyperef.h"
#include "content/common/content_export.h" #include "content/common/content_export.h"
#include "mojo/public/cpp/system/buffer.h" #include "mojo/public/cpp/system/buffer.h"
...@@ -49,19 +50,20 @@ class FontLoader { ...@@ -49,19 +50,20 @@ class FontLoader {
LoadedCallback callback); LoadedCallback callback);
// Given a shared memory buffer containing the raw data for a font file, load // Given a shared memory buffer containing the raw data for a font file, load
// the font and return a CTFontRef. // the font and turn them into a CTFontDescriptor.
// //
// |data| - A shared memory handle pointing to the raw data from a font file. // |data| - A shared memory handle pointing to the raw data from a font file.
// |data_size| - Size of |data|. // |data_size| - Size of |data|.
// //
// On return: // On return:
// returns true on success, false on failure. // returns true on success, false on failure.
// |out| - A CTFontRef corresponding to the designated font. // |out| - A CTFontDescriptorRef corresponding to the designated font buffer.
// The caller is responsible for releasing this value via CFRelease(). // The caller is responsible for releasing this value via CFRelease().
CONTENT_EXPORT CONTENT_EXPORT
static bool CTFontRefFromBuffer(mojo::ScopedSharedBufferHandle font_data, static bool CTFontDescriptorFromBuffer(
uint32_t font_data_size, mojo::ScopedSharedBufferHandle font_data,
CTFontRef* out); uint32_t font_data_size,
base::ScopedCFTypeRef<CTFontDescriptorRef>* out_descriptor);
CONTENT_EXPORT CONTENT_EXPORT
static std::unique_ptr<ResultInternal> LoadFontForTesting( static std::unique_ptr<ResultInternal> LoadFontForTesting(
......
...@@ -141,10 +141,11 @@ void FontLoader::LoadFont(const base::string16& font_name, ...@@ -141,10 +141,11 @@ void FontLoader::LoadFont(const base::string16& font_name,
} }
// static // static
bool FontLoader::CTFontRefFromBuffer(mojo::ScopedSharedBufferHandle font_data, bool FontLoader::CTFontDescriptorFromBuffer(
uint32_t font_data_size, mojo::ScopedSharedBufferHandle font_data,
CTFontRef* out) { uint32_t font_data_size,
*out = NULL; base::ScopedCFTypeRef<CTFontDescriptorRef>* out_descriptor) {
out_descriptor->reset();
mojo::ScopedSharedBufferMapping mapping = font_data->Map(font_data_size); mojo::ScopedSharedBufferMapping mapping = font_data->Map(font_data_size);
if (!mapping) if (!mapping)
return false; return false;
...@@ -152,16 +153,11 @@ bool FontLoader::CTFontRefFromBuffer(mojo::ScopedSharedBufferHandle font_data, ...@@ -152,16 +153,11 @@ bool FontLoader::CTFontRefFromBuffer(mojo::ScopedSharedBufferHandle font_data,
NSData* data = [NSData dataWithBytes:mapping.get() length:font_data_size]; NSData* data = [NSData dataWithBytes:mapping.get() length:font_data_size];
base::ScopedCFTypeRef<CTFontDescriptorRef> data_descriptor( base::ScopedCFTypeRef<CTFontDescriptorRef> data_descriptor(
CTFontManagerCreateFontDescriptorFromData(base::mac::NSToCFCast(data))); CTFontManagerCreateFontDescriptorFromData(base::mac::NSToCFCast(data)));
base::ScopedCFTypeRef<CGDataProviderRef> provider(
CGDataProviderCreateWithCFData(base::mac::NSToCFCast(data)));
if (!provider)
return false;
*out = CTFontCreateWithFontDescriptor(data_descriptor.get(), 0, nullptr);
if (*out == NULL) if (!data_descriptor)
return false; return false;
*out_descriptor = std::move(data_descriptor);
return true; return true;
} }
......
...@@ -8,6 +8,7 @@ include_rules = [ ...@@ -8,6 +8,7 @@ include_rules = [
"+base/location.h", "+base/location.h",
"+base/logging.h", "+base/logging.h",
"+base/macros.h", "+base/macros.h",
"+base/mac/scoped_cftyperef.h",
"+base/memory/ref_counted.h", "+base/memory/ref_counted.h",
"+base/memory/scoped_refptr.h", "+base/memory/scoped_refptr.h",
"+base/memory/weak_ptr.h", "+base/memory/weak_ptr.h",
......
...@@ -31,6 +31,7 @@ ...@@ -31,6 +31,7 @@
#ifndef THIRD_PARTY_BLINK_PUBLIC_PLATFORM_MAC_WEB_SANDBOX_SUPPORT_H_ #ifndef THIRD_PARTY_BLINK_PUBLIC_PLATFORM_MAC_WEB_SANDBOX_SUPPORT_H_
#define THIRD_PARTY_BLINK_PUBLIC_PLATFORM_MAC_WEB_SANDBOX_SUPPORT_H_ #define THIRD_PARTY_BLINK_PUBLIC_PLATFORM_MAC_WEB_SANDBOX_SUPPORT_H_
#include "base/mac/scoped_cftyperef.h"
#include "third_party/blink/public/common/sandbox_support/sandbox_support_mac.h" #include "third_party/blink/public/common/sandbox_support/sandbox_support_mac.h"
#include "third_party/skia/include/core/SkColor.h" #include "third_party/skia/include/core/SkColor.h"
...@@ -44,17 +45,15 @@ class WebSandboxSupport { ...@@ -44,17 +45,15 @@ class WebSandboxSupport {
virtual ~WebSandboxSupport() {} virtual ~WebSandboxSupport() {}
// Given an input font - |srcFont| [which can't be loaded due to sandbox // Given an input font - |srcFont| [which can't be loaded due to sandbox
// restrictions]. Return a font belonging to an equivalent font file // restrictions]. Return a font descriptor based on data belonging to an
// that can be used to access the font and a unique identifier corresponding // equivalent font file that can be used to access the font and a unique
// to the on-disk font file. // identifier corresponding to the on-disk font file.
//
// If this function succeeds, the caller assumes ownership of the |out|
// parameter and must call CFRelease() on the CTFontRef.
// //
// Returns: true on success, false on error. // Returns: true on success, false on error.
virtual bool LoadFont(CTFontRef src_font, virtual bool LoadFont(
CTFontRef* out, CTFontRef src_font,
uint32_t* font_id) = 0; base::ScopedCFTypeRef<CTFontDescriptorRef>* out_descriptor,
uint32_t* font_id) = 0;
// Returns the system's preferred value for a named color. // Returns the system's preferred value for a named color.
virtual SkColor GetSystemColor(MacSystemColorID) = 0; virtual SkColor GetSystemColor(MacSystemColorID) = 0;
......
...@@ -27,7 +27,6 @@ ...@@ -27,7 +27,6 @@
#import <AvailabilityMacros.h> #import <AvailabilityMacros.h>
#include "base/mac/foundation_util.h" #include "base/mac/foundation_util.h"
#include "base/mac/scoped_cftyperef.h"
#include "base/mac/scoped_nsobject.h" #include "base/mac/scoped_nsobject.h"
#include "base/stl_util.h" #include "base/stl_util.h"
#import "third_party/blink/public/platform/mac/web_sandbox_support.h" #import "third_party/blink/public/platform/mac/web_sandbox_support.h"
...@@ -59,10 +58,10 @@ static bool CanLoadInProcess(NSFont* ns_font) { ...@@ -59,10 +58,10 @@ static bool CanLoadInProcess(NSFont* ns_font) {
return ![font_name isEqualToString:@"LastResort"]; return ![font_name isEqualToString:@"LastResort"];
} }
static CTFontDescriptorRef CascadeToLastResortFontDescriptor() { static CFDictionaryRef CascadeToLastResortFontAttributes() {
static CTFontDescriptorRef descriptor; static CFDictionaryRef attributes;
if (descriptor) if (attributes)
return descriptor; return attributes;
base::ScopedCFTypeRef<CTFontDescriptorRef> last_resort( base::ScopedCFTypeRef<CTFontDescriptorRef> last_resort(
CTFontDescriptorCreateWithNameAndSize(CFSTR("LastResort"), 0)); CTFontDescriptorCreateWithNameAndSize(CFSTR("LastResort"), 0));
...@@ -73,13 +72,10 @@ static CTFontDescriptorRef CascadeToLastResortFontDescriptor() { ...@@ -73,13 +72,10 @@ static CTFontDescriptorRef CascadeToLastResortFontDescriptor() {
const void* keys[] = {kCTFontCascadeListAttribute}; const void* keys[] = {kCTFontCascadeListAttribute};
const void* values[] = {values_array}; const void* values[] = {values_array};
base::ScopedCFTypeRef<CFDictionaryRef> attributes(CFDictionaryCreate( attributes = CFDictionaryCreate(
kCFAllocatorDefault, keys, values, base::size(keys), kCFAllocatorDefault, keys, values, base::size(keys),
&kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks)); &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
return attributes;
descriptor = CTFontDescriptorCreateWithAttributes(attributes);
return descriptor;
} }
static sk_sp<SkTypeface> LoadFromBrowserProcess(NSFont* ns_font, static sk_sp<SkTypeface> LoadFromBrowserProcess(NSFont* ns_font,
...@@ -94,19 +90,22 @@ static sk_sp<SkTypeface> LoadFromBrowserProcess(NSFont* ns_font, ...@@ -94,19 +90,22 @@ static sk_sp<SkTypeface> LoadFromBrowserProcess(NSFont* ns_font,
return nullptr; return nullptr;
} }
CTFontRef loaded_ct_font; base::ScopedCFTypeRef<CTFontDescriptorRef> loaded_data_descriptor;
uint32_t font_id; uint32_t font_id;
if (!sandbox_support->LoadFont(base::mac::NSToCFCast(ns_font), if (!sandbox_support->LoadFont(base::mac::NSToCFCast(ns_font),
&loaded_ct_font, &font_id)) { &loaded_data_descriptor, &font_id)) {
// TODO crbug.com/461279: Make this appear in the inspector console? // TODO crbug.com/461279: Make this appear in the inspector console?
DLOG(ERROR) DLOG(ERROR)
<< "Loading user font \"" << [[ns_font familyName] UTF8String] << "Loading user font \"" << [[ns_font familyName] UTF8String]
<< "\" from non system location failed. Corrupt or missing font file?"; << "\" from non system location failed. Corrupt or missing font file?";
return nullptr; return nullptr;
} }
base::ScopedCFTypeRef<CTFontRef> ct_font_base(loaded_ct_font);
base::ScopedCFTypeRef<CTFontRef> ct_font(CTFontCreateCopyWithAttributes( base::ScopedCFTypeRef<CTFontDescriptorRef> data_descriptor_with_cascade(
ct_font_base, text_size, 0, CascadeToLastResortFontDescriptor())); CTFontDescriptorCreateCopyWithAttributes(
loaded_data_descriptor, CascadeToLastResortFontAttributes()));
base::ScopedCFTypeRef<CTFontRef> ct_font(CTFontCreateWithFontDescriptor(
data_descriptor_with_cascade.get(), text_size, 0));
sk_sp<SkTypeface> return_font(SkCreateTypefaceFromCTFont(ct_font)); sk_sp<SkTypeface> return_font(SkCreateTypefaceFromCTFont(ct_font));
if (!return_font.get()) if (!return_font.get())
......
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