Changeset 143125 in webkit
- Timestamp:
- Feb 17, 2013 12:17:42 AM (11 years ago)
- Location:
- trunk/Source/WebCore
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r143124 r143125 1 2013-02-17 Andreas Kling <akling@apple.com> 2 3 Optimize GlyphPage for case where all glyphs are available in the same font. 4 <http://webkit.org/b/108835> 5 <rdar://problem/13157042> 6 7 Reviewed by Antti Koivisto. 8 9 Let GlyphPage begin optimistically assuming that all its glyphs will be represented in 10 the same SimpleFontData*. In this (very common) case, only keep a single SimpleFontData*. 11 12 If glyphs from multiple fonts are mixed in one page, an array of per-glyph SimpleFontData* 13 is allocated transparently. 14 15 This was landed before with some bogus branch prediction hints and didn't fare well on 16 page cyclers (intl2 specifically.) These have been removed this time around, and will 17 hopefully be regression-free. 18 19 4.98 MB progression on Membuster3. 20 21 * platform/graphics/GlyphPageTreeNode.cpp: 22 (WebCore::GlyphPageTreeNode::initializePage): 23 * platform/graphics/GlyphPage.h: 24 (WebCore::GlyphPage::createUninitialized): 25 (WebCore::GlyphPage::createZeroedSystemFallbackPage): 26 (WebCore::GlyphPage::createCopiedSystemFallbackPage): 27 28 There are now three ways of constructing a GlyphPage, two of them are only used for 29 creating system fallback pages. 30 31 (WebCore::GlyphPage::setGlyphDataForIndex): 32 33 Hold off creating a SimpleFontData* array until we're sure there are two different 34 SimpleFontData* backing the glyphs in this page. 35 We don't store font data for glyph #0, instead we let the getters always return null for it. 36 37 (WebCore::GlyphPage::~GlyphPage): 38 39 Free the SimpleFontData* array if needed. 40 41 (WebCore::GlyphPage::glyphDataForCharacter): 42 (WebCore::GlyphPage::glyphDataForIndex): 43 (WebCore::GlyphPage::fontDataForCharacter): 44 45 The font data for glyph #0 is always a null pointer now. 46 47 (WebCore::GlyphPage::clearForFontData): 48 49 Updated for new storage format. 50 51 * rendering/svg/SVGTextRunRenderingContext.cpp: 52 (WebCore::SVGTextRunRenderingContext::glyphDataForCharacter): 53 54 Fix bug where non-zero glyph was temporarily associated with null font data, 55 which triggered the new assertion in setGlyphDataForIndex(). 56 1 57 2013-02-16 Andreas Kling <akling@apple.com> 2 58 -
trunk/Source/WebCore/platform/graphics/GlyphPage.h
r142897 r143125 1 1 /* 2 * Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved.2 * Copyright (C) 2006, 2007, 2008, 2013 Apple Inc. All rights reserved. 3 3 * Copyright (C) Research In Motion Limited 2011. All rights reserved. 4 4 * … … 34 34 #include <wtf/PassRefPtr.h> 35 35 #include <wtf/RefCounted.h> 36 #include <wtf/RefPtr.h> 36 37 #include <wtf/unicode/Unicode.h> 37 38 … … 63 64 class GlyphPage : public RefCounted<GlyphPage> { 64 65 public: 65 static PassRefPtr<GlyphPage> create(GlyphPageTreeNode* owner) 66 { 67 return adoptRef(new GlyphPage(owner)); 66 static PassRefPtr<GlyphPage> createUninitialized(GlyphPageTreeNode* owner) 67 { 68 return adoptRef(new GlyphPage(owner, false)); 69 } 70 71 static PassRefPtr<GlyphPage> createZeroedSystemFallbackPage(GlyphPageTreeNode* owner) 72 { 73 return adoptRef(new GlyphPage(owner, true)); 74 } 75 76 PassRefPtr<GlyphPage> createCopiedSystemFallbackPage(GlyphPageTreeNode* owner) const 77 { 78 RefPtr<GlyphPage> page = GlyphPage::createUninitialized(owner); 79 memcpy(page->m_glyphs, m_glyphs, sizeof(m_glyphs)); 80 page->m_fontDataForAllGlyphs = m_fontDataForAllGlyphs; 81 if (m_perGlyphFontData) { 82 page->m_perGlyphFontData = static_cast<const SimpleFontData**>(fastMalloc(size * sizeof(SimpleFontData*))); 83 memcpy(page->m_perGlyphFontData, m_perGlyphFontData, size * sizeof(SimpleFontData*)); 84 } 85 return page.release(); 86 } 87 88 ~GlyphPage() 89 { 90 if (m_perGlyphFontData) 91 fastFree(m_perGlyphFontData); 68 92 } 69 93 … … 73 97 GlyphData glyphDataForCharacter(UChar32 c) const 74 98 { 75 unsigned index = indexForCharacter(c); 76 return GlyphData(m_glyphs[index], m_glyphFontData[index]); 99 return glyphDataForIndex(indexForCharacter(c)); 77 100 } 78 101 … … 80 103 { 81 104 ASSERT_WITH_SECURITY_IMPLICATION(index < size); 82 return GlyphData(m_glyphs[index], m_glyphFontData[index]); 105 Glyph glyph = m_glyphs[index]; 106 if (!glyph) 107 return GlyphData(0, 0); 108 if (m_perGlyphFontData) 109 return GlyphData(glyph, m_perGlyphFontData[index]); 110 return GlyphData(glyph, m_fontDataForAllGlyphs); 83 111 } 84 112 … … 91 119 const SimpleFontData* fontDataForCharacter(UChar32 c) const 92 120 { 93 return m_glyphFontData[indexForCharacter(c)];121 return glyphDataForIndex(indexForCharacter(c)).fontData; 94 122 } 95 123 … … 99 127 } 100 128 101 void setGlyphDataForIndex(unsigned index, Glyph g , const SimpleFontData* f)129 void setGlyphDataForIndex(unsigned index, Glyph glyph, const SimpleFontData* fontData) 102 130 { 103 131 ASSERT_WITH_SECURITY_IMPLICATION(index < size); 104 m_glyphs[index] = g; 105 m_glyphFontData[index] = f; 132 m_glyphs[index] = glyph; 133 134 // GlyphPage getters will always return a null SimpleFontData* for glyph #0, so don't worry about the pointer for them. 135 if (!glyph) 136 return; 137 138 // A glyph index without a font data pointer makes no sense. 139 ASSERT(fontData); 140 141 if (m_perGlyphFontData) { 142 m_perGlyphFontData[index] = fontData; 143 return; 144 } 145 146 if (!m_fontDataForAllGlyphs) 147 m_fontDataForAllGlyphs = fontData; 148 149 if (m_fontDataForAllGlyphs == fontData) 150 return; 151 152 // This GlyphPage houses glyphs from multiple fonts, transition to an array of SimpleFontData pointers. 153 const SimpleFontData* oldFontData = m_fontDataForAllGlyphs; 154 m_perGlyphFontData = static_cast<const SimpleFontData**>(fastMalloc(size * sizeof(SimpleFontData*))); 155 for (unsigned i = 0; i < size; ++i) 156 m_perGlyphFontData[i] = oldFontData; 157 m_perGlyphFontData[index] = fontData; 106 158 } 107 159 … … 110 162 setGlyphDataForIndex(index, glyphData.glyph, glyphData.fontData); 111 163 } 112 113 void copyFrom(const GlyphPage& other)114 {115 memcpy(m_glyphs, other.m_glyphs, sizeof(m_glyphs));116 memcpy(m_glyphFontData, other.m_glyphFontData, sizeof(m_glyphFontData));117 }118 119 void clear()120 {121 memset(m_glyphs, 0, sizeof(m_glyphs));122 memset(m_glyphFontData, 0, sizeof(m_glyphFontData));123 }124 164 125 165 void clearForFontData(const SimpleFontData* fontData) 126 166 { 167 if (!m_perGlyphFontData) { 168 if (m_fontDataForAllGlyphs == fontData) { 169 memset(m_glyphs, 0, sizeof(m_glyphs)); 170 m_fontDataForAllGlyphs = 0; 171 } 172 return; 173 } 127 174 for (size_t i = 0; i < size; ++i) { 128 if (m_ glyphFontData[i] == fontData) {175 if (m_perGlyphFontData[i] == fontData) { 129 176 m_glyphs[i] = 0; 130 m_ glyphFontData[i] = 0;177 m_perGlyphFontData[i] = 0; 131 178 } 132 179 } … … 139 186 140 187 private: 141 GlyphPage(GlyphPageTreeNode* owner) 142 : m_owner(owner) 143 { 144 } 145 146 // Separate arrays, rather than array of GlyphData, to save space. 188 GlyphPage(GlyphPageTreeNode* owner, bool clearGlyphs) 189 : m_fontDataForAllGlyphs(0) 190 , m_perGlyphFontData(0) 191 , m_owner(owner) 192 { 193 if (clearGlyphs) 194 memset(m_glyphs, 0, sizeof(m_glyphs)); 195 } 196 197 const SimpleFontData* m_fontDataForAllGlyphs; 198 const SimpleFontData** m_perGlyphFontData; 199 200 GlyphPageTreeNode* m_owner; 147 201 Glyph m_glyphs[size]; 148 const SimpleFontData* m_glyphFontData[size];149 150 GlyphPageTreeNode* m_owner;151 202 }; 152 203 153 204 } // namespace WebCore 154 205 155 #endif // GlyphPage TreeNode_h206 #endif // GlyphPage_h -
trunk/Source/WebCore/platform/graphics/GlyphPageTreeNode.cpp
r142897 r143125 201 201 } 202 202 } 203 204 m_page = GlyphPage::create (this);203 204 m_page = GlyphPage::createUninitialized(this); 205 205 206 206 // Now that we have a buffer full of characters, we want to get back an array … … 226 226 if (from < static_cast<int>(GlyphPage::size) && to > 0) { 227 227 if (haveGlyphs && !scratchPage) { 228 scratchPage = GlyphPage::create (this);228 scratchPage = GlyphPage::createUninitialized(this); 229 229 pageToFill = scratchPage.get(); 230 230 } … … 280 280 } else { 281 281 // Combine the parent's glyphs and ours to form a new more complete page. 282 m_page = GlyphPage::create (this);282 m_page = GlyphPage::createUninitialized(this); 283 283 284 284 // Overlay the parent page on the fallback page. Check if the fallback font … … 301 301 } 302 302 } else { 303 m_page = GlyphPage::create(this);304 303 // System fallback. Initialized with the parent's page here, as individual 305 304 // entries may use different fonts depending on character. If the Font … … 307 306 // ask the system for the best font to use and fill that glyph in for us. 308 307 if (parentPage) 309 m_page ->copyFrom(*parentPage);308 m_page = parentPage->createCopiedSystemFallbackPage(this); 310 309 else 311 m_page ->clear();310 m_page = GlyphPage::createZeroedSystemFallbackPage(this); 312 311 } 313 312 } -
trunk/Source/WebCore/rendering/svg/SVGTextRunRenderingContext.cpp
r142897 r143125 231 231 // Even though our GlyphPage contains an entry for eg. glyph "a", it's not compatible. So we have to temporarily 232 232 // remove the glyph data information from the GlyphPage, and retry the lookup, which handles font fallbacks correctly. 233 page->setGlyphDataForCharacter(character, glyphData.glyph, 0);233 page->setGlyphDataForCharacter(character, 0, 0); 234 234 235 235 // Assure that the font fallback glyph selection worked, aka. the fallbackGlyphData font data is not the same as before.
Note: See TracChangeset
for help on using the changeset viewer.