Changeset 92269 in webkit
- Timestamp:
- Aug 3, 2011 3:48:22 AM (13 years ago)
- Location:
- trunk/Source
- Files:
-
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r92266 r92269 1 2011-08-03 Jeremy Moskovich <jeremy@chromium.org> 2 3 [Chromium] Fix OOP font loading to work on 10.6.6 and above. 4 https://bugs.webkit.org/show_bug.cgi?id=65543 5 6 In 10.6.6 the function used to get the unique ID for an NSFont in the 7 renderer was changed so it fails in the sandbox (it now tries to access 8 the on-disk font file). In order to work around this, we get the font 9 ID from the browser process. 10 11 To speed things up, we introduce 2 levels of caching in WebKit. A font 12 name cache where we can perform a quick lookup without the need for the 13 font id and a font id cache which we can only lookup in after getting 14 the unique ID from the browser process. 15 16 Reviewed by Kenneth Russell. 17 18 No new tests since this is not readily testable. 19 20 * platform/chromium/PlatformBridge.h: 21 * platform/graphics/chromium/CrossProcessFontLoading.h: 22 * platform/graphics/chromium/CrossProcessFontLoading.mm: 23 (WebCore::MemoryActivatedFont::create): 24 (WebCore::MemoryActivatedFont::MemoryActivatedFont): 25 (WebCore::MemoryActivatedFont::~MemoryActivatedFont): 26 1 27 2011-08-03 Hayato Ito <hayato@chromium.org> 2 28 -
trunk/Source/WebCore/platform/chromium/PlatformBridge.h
r91206 r92269 152 152 #endif 153 153 #if OS(DARWIN) 154 static bool loadFont(NSFont* srcFont, ATSFontContainerRef* out);154 static bool loadFont(NSFont* srcFont, ATSFontContainerRef*, uint32_t* fontID); 155 155 #elif OS(UNIX) 156 156 static void getRenderStyleForStrike(const char* family, int sizeAndStyle, FontRenderStyle* result); -
trunk/Source/WebCore/platform/graphics/chromium/CrossProcessFontLoading.h
r66574 r92269 34 34 #import <wtf/RefCounted.h> 35 35 #import <wtf/RetainPtr.h> 36 #import <wtf/text/WTFString.h> 36 37 37 38 typedef struct CGFont* CGFontRef; … … 74 75 public: 75 76 // Use to create a new object, see docs on constructor below. 76 static PassRefPtr<MemoryActivatedFont> create( ATSFontContainerRef srcFontContainerRef, ATSFontContainerRef container);77 static PassRefPtr<MemoryActivatedFont> create(uint32_t fontID, NSFont*, ATSFontContainerRef); 77 78 ~MemoryActivatedFont(); 78 79 … … 88 89 // container - a font container corresponding to an identical font that 89 90 // we loaded cross-process. 90 MemoryActivatedFont( ATSFontContainerRef srcFontContainerRef, ATSFontContainerRef container);91 MemoryActivatedFont(uint32_t fontID, NSFont*, ATSFontContainerRef); 91 92 92 93 ATSFontContainerRef m_fontContainer; 93 94 WTF::RetainPtr<CGFontRef> m_cgFont; 94 95 ATSFontRef m_atsFontRef; 95 ATSFontContainerRef m_srcFontContainerRef; 96 uint32_t m_fontID; 97 WTF::String m_inSandboxHashKey; 96 98 }; 97 99 -
trunk/Source/WebCore/platform/graphics/chromium/CrossProcessFontLoading.mm
r82170 r92269 39 39 namespace { 40 40 41 typedef HashMap<ATSFontContainerRef, MemoryActivatedFont*> FontContainerRefMemoryFontHash; 41 typedef HashMap<uint32, MemoryActivatedFont*> FontContainerRefMemoryFontHash; 42 typedef HashMap<WTF::String, MemoryActivatedFont*> FontNameMemoryFontHash; 42 43 43 44 // On 10.5, font loading is not blocked by the sandbox and thus there is no … … 55 56 } 56 57 57 FontContainerRefMemoryFontHash& fontCacheBySrcFontContainerRef() 58 { 59 DEFINE_STATIC_LOCAL(FontContainerRefMemoryFontHash, srcFontRefCache, ()); 60 return srcFontRefCache; 58 // Caching: 59 // 60 // Requesting a font from the browser process is expensive and so is 61 // "activating" said font. Caching of loaded fonts is complicated by the fact 62 // that it's impossible to get a unique identifier for the on-disk font file 63 // from inside the sandboxed renderer process. 64 // This means that when loading a font we need to round-trip through the browser 65 // process in order to get the unique font file identifer which we might already 66 // have activated and cached. 67 // 68 // In order to save as much work as we can, we maintain 2 levels of caching 69 // for the font data: 70 // 1. A dumb cache keyed by the font name/style (information we can determine 71 // from inside the sandbox). 72 // 2. A smarter cache keyed by the real "unique font id". 73 // 74 // In order to perform a lookup in #2 we need to consult with the browser to get 75 // us the lookup key. While this doesn't save us the font load, it does save 76 // us font activation. 77 // 78 // It's important to remember that existing FontPlatformData objects are already 79 // cached, so a cache miss in the code in this file isn't necessarily so bad. 80 81 FontContainerRefMemoryFontHash& fontCacheByFontID() 82 { 83 DEFINE_STATIC_LOCAL(FontContainerRefMemoryFontHash, srcFontIDCache, ()); 84 return srcFontIDCache; 85 } 86 87 88 FontNameMemoryFontHash& fontCacheByFontName() 89 { 90 DEFINE_STATIC_LOCAL(FontNameMemoryFontHash, srcFontNameCache, ()); 91 return srcFontNameCache; 92 } 93 94 // Given a font specified by |srcFont|, use the information we can query in 95 // the sandbox to construct a key which we hope will be as unique as possible 96 // to the containing font file. 97 WTF::String hashKeyFromNSFont(NSFont* srcFont) 98 { 99 NSFontDescriptor* desc = [srcFont fontDescriptor]; 100 NSFontSymbolicTraits traits = [desc symbolicTraits]; 101 return WTF::String::format("%s %x", [[srcFont fontName] UTF8String], traits); 61 102 } 62 103 … … 86 127 PassRefPtr<MemoryActivatedFont> loadFontFromBrowserProcess(NSFont* nsFont) 87 128 { 129 // First try to lookup in our cache with the limited information we have. 130 WTF::String hashKey = hashKeyFromNSFont(nsFont); 131 RefPtr<MemoryActivatedFont> font(fontCacheByFontName().get(hashKey)); 132 if (font) 133 return font; 134 88 135 ATSFontContainerRef container; 136 uint32_t fontID; 89 137 // Send cross-process request to load font. 90 if (!PlatformBridge::loadFont(nsFont, &container ))138 if (!PlatformBridge::loadFont(nsFont, &container, &fontID)) 91 139 return 0; 92 93 ATSFontContainerRef srcFontContainerRef = fontContainerRefFromNSFont(nsFont); 94 if (!srcFontContainerRef) { 140 141 // Now that we have the fontID from the browser process, we can consult 142 // the ID cache. 143 font = fontCacheByFontID().get(fontID); 144 if (font) { 145 // We can safely discard the new container since we already have the 146 // font in our cache. 147 // FIXME: PlatformBridge::loadFont() should consult the id cache 148 // before activating the font. Then we can save this activate/deactive 149 // dance altogether. 95 150 ATSFontDeactivate(container, 0, kATSOptionFlagsDefault); 96 return 0;97 }98 99 PassRefPtr<MemoryActivatedFont> font = adoptRef(fontCacheBySrcFontContainerRef().get(srcFontContainerRef));100 if (font.get())101 151 return font; 102 103 return MemoryActivatedFont::create(srcFontContainerRef, container); 152 } 153 154 return MemoryActivatedFont::create(fontID, nsFont, container); 104 155 } 105 156 106 157 } // namespace 107 158 108 PassRefPtr<MemoryActivatedFont> MemoryActivatedFont::create( ATSFontContainerRef srcFontContainerRef, ATSFontContainerRef container)109 { 110 MemoryActivatedFont* font = new MemoryActivatedFont( srcFontContainerRef, container);159 PassRefPtr<MemoryActivatedFont> MemoryActivatedFont::create(uint32_t fontID, NSFont* nsFont, ATSFontContainerRef container) 160 { 161 MemoryActivatedFont* font = new MemoryActivatedFont(fontID, nsFont, container); 111 162 if (!font->cgFont()) // Object construction failed. 112 163 { … … 117 168 } 118 169 119 MemoryActivatedFont::MemoryActivatedFont( ATSFontContainerRef srcFontContainerRef, ATSFontContainerRef container)170 MemoryActivatedFont::MemoryActivatedFont(uint32_t fontID, NSFont* nsFont, ATSFontContainerRef container) 120 171 : m_fontContainer(container) 121 172 , m_atsFontRef(kATSFontRefUnspecified) 122 , m_srcFontContainerRef(srcFontContainerRef) 173 , m_fontID(fontID) 174 , m_inSandboxHashKey(hashKeyFromNSFont(nsFont)) 123 175 { 124 176 if (!container) … … 140 192 m_cgFont.adoptCF(CGFontCreateWithPlatformFont(&m_atsFontRef)); 141 193 142 if (!m_cgFont.get()) 143 return; 144 145 // Add ourselves to cache. 146 fontCacheBySrcFontContainerRef().add(m_srcFontContainerRef, this); 194 if (!m_cgFont) 195 return; 196 197 // Add ourselves to caches. 198 fontCacheByFontID().add(fontID, this); 199 fontCacheByFontName().add(m_inSandboxHashKey, this); 147 200 } 148 201 … … 151 204 MemoryActivatedFont::~MemoryActivatedFont() 152 205 { 153 if (m_cgFont .get()) {206 if (m_cgFont) { 154 207 // First remove ourselves from the caches. 155 ASSERT(fontCacheBySrcFontContainerRef().contains(m_srcFontContainerRef)); 208 ASSERT(fontCacheByFontID().contains(m_fontID)); 209 ASSERT(fontCacheByFontName().contains(m_inSandboxHashKey)); 156 210 157 fontCacheBySrcFontContainerRef().remove(m_srcFontContainerRef); 211 fontCacheByFontID().remove(m_fontID); 212 fontCacheByFontName().remove(m_inSandboxHashKey); 158 213 159 214 // Make sure the CGFont is destroyed before its font container. … … 193 248 // Font loading was blocked by the Sandbox. 194 249 m_inMemoryFont = loadFontFromBrowserProcess(outNSFont); 195 if (m_inMemoryFont .get()) {250 if (m_inMemoryFont) { 196 251 cgFont = m_inMemoryFont->cgFont(); 197 252 -
trunk/Source/WebKit/chromium/ChangeLog
r92265 r92269 1 2011-08-03 Jeremy Moskovich <jeremy@chromium.org> 2 3 [Chromium] Fix OOP font loading to work on 10.6.6 and above. 4 https://bugs.webkit.org/show_bug.cgi?id=65543 5 6 In 10.6.6 the function used to get the unique ID for an NSFont in the 7 renderer was changed so it fails in the sandbox (it now tries to access 8 the on-disk font file). In order to work around this, we get the font 9 ID from the browser process. 10 11 To speed things up, we introduce 2 levels of caching in WebKit. A font 12 name cache where we can perform a quick lookup without the need for the 13 font id and a font id cache which we can only lookup in after getting 14 the unique ID from the browser process. 15 16 Reviewed by Kenneth Russell. 17 18 No new tests since this is not readily testable. 19 20 * public/mac/WebSandboxSupport.h: Plumb font ID parameter through. 21 * src/PlatformBridge.cpp: 22 (WebCore::PlatformBridge::loadFont): ditto. 23 1 24 2011-08-03 Pavel Feldman <pfeldman@chromium.org> 2 25 -
trunk/Source/WebKit/chromium/public/mac/WebSandboxSupport.h
r61361 r92269 47 47 // Given an input font - |srcFont| [which can't be loaded due to sandbox 48 48 // restrictions]. Return a font container belonging to an equivalent 49 // font file that can be used to access the font. 49 // font file that can be used to access the font and a unique identifier 50 // corresponding to the on-disk font file. 50 51 // 51 52 // Note that a font container may contain multiple fonts, the caller is … … 56 57 // 57 58 // Returns: true on success, false on error. 58 virtual bool loadFont(NSFont* srcFont, ATSFontContainerRef* out) = 0;59 virtual bool loadFont(NSFont* srcFont, ATSFontContainerRef*, uint32_t* fontID) = 0; 59 60 }; 60 61 -
trunk/Source/WebKit/chromium/src/PlatformBridge.cpp
r91206 r92269 445 445 446 446 #if OS(DARWIN) 447 bool PlatformBridge::loadFont(NSFont* srcFont, ATSFontContainerRef* out)447 bool PlatformBridge::loadFont(NSFont* srcFont, ATSFontContainerRef* container, uint32_t* fontID) 448 448 { 449 449 WebSandboxSupport* ss = webKitClient()->sandboxSupport(); 450 450 if (ss) 451 return ss->loadFont(srcFont, out);451 return ss->loadFont(srcFont, container, fontID); 452 452 453 453 // This function should only be called in response to an error loading a … … 455 455 // This by definition shouldn't happen if there is no sandbox support. 456 456 ASSERT_NOT_REACHED(); 457 *out = 0; 457 *container = 0; 458 *fontID = 0; 458 459 return false; 459 460 }
Note: See TracChangeset
for help on using the changeset viewer.