Changeset 143601 in webkit
- Timestamp:
- Feb 21, 2013 7:44:02 AM (11 years ago)
- Location:
- trunk/Source/WebCore
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r143600 r143601 1 2013-02-21 Andreas Kling <akling@apple.com> 2 3 GlyphPage: Bake per-glyph font data array into same allocation as GlyphPage. 4 5 A hopeful fix for REGRESSION(r143125): ~5% performance hit on Chromium's intl2 page cycler 6 <http://webkit.org/b/108835> 7 8 Reviewed by Antti Koivisto. 9 10 Rewire GlyphPage so that we have to decide at creation time whether there will be a per-glyph 11 array of SimpleFontData* or not. This removes one allocation and one step of indirection for 12 pages with glyphs from mixed fonts. 13 14 * platform/graphics/GlyphPage.h: 15 (WebCore::GlyphPage::createForMixedFontData): 16 (WebCore::GlyphPage::createForSingleFontData): 17 (WebCore::GlyphPage::createCopiedSystemFallbackPage): 18 (WebCore::GlyphPage::~GlyphPage): 19 (WebCore::GlyphPage::glyphDataForIndex): 20 (WebCore::GlyphPage::fontDataForCharacter): 21 (WebCore::GlyphPage::setGlyphDataForIndex): 22 (WebCore::GlyphPage::removeFontDataFromSystemFallbackPage): 23 (WebCore::GlyphPage::GlyphPage): 24 (WebCore::GlyphPage::hasPerGlyphFontData): 25 (GlyphPage): 26 * platform/graphics/GlyphPageTreeNode.cpp: 27 (WebCore::GlyphPageTreeNode::initializePage): 28 1 29 2013-02-21 Xan Lopez <xlopez@rim.com> 2 30 -
trunk/Source/WebCore/platform/graphics/GlyphPage.h
r143137 r143601 54 54 }; 55 55 56 #if COMPILER(MSVC) 57 #pragma warning(push) 58 #pragma warning(disable: 4200) // Disable "zero-sized array in struct/union" warning 59 #endif 60 56 61 // A GlyphPage contains a fixed-size set of GlyphData mappings for a contiguous 57 62 // range of characters in the Unicode code space. GlyphPages are indexed … … 64 69 class GlyphPage : public RefCounted<GlyphPage> { 65 70 public: 66 static PassRefPtr<GlyphPage> create Uninitialized(GlyphPageTreeNode* owner)71 static PassRefPtr<GlyphPage> createForMixedFontData(GlyphPageTreeNode* owner) 67 72 { 68 return adoptRef(new GlyphPage(owner, false)); 73 void* slot = fastMalloc(sizeof(GlyphPage) + sizeof(SimpleFontData*) * GlyphPage::size); 74 return adoptRef(new (slot) GlyphPage(owner)); 69 75 } 70 76 71 static PassRefPtr<GlyphPage> create ZeroedSystemFallbackPage(GlyphPageTreeNode* owner)77 static PassRefPtr<GlyphPage> createForSingleFontData(GlyphPageTreeNode* owner, const SimpleFontData* fontData) 72 78 { 73 return adoptRef(new GlyphPage(owner, true)); 79 ASSERT(fontData); 80 return adoptRef(new GlyphPage(owner, fontData)); 74 81 } 75 82 76 83 PassRefPtr<GlyphPage> createCopiedSystemFallbackPage(GlyphPageTreeNode* owner) const 77 84 { 78 RefPtr<GlyphPage> page = GlyphPage::create Uninitialized(owner);85 RefPtr<GlyphPage> page = GlyphPage::createForMixedFontData(owner); 79 86 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*)); 87 if (hasPerGlyphFontData()) 88 memcpy(page->m_perGlyphFontData, m_perGlyphFontData, sizeof(SimpleFontData*) * GlyphPage::size); 89 else { 90 for (size_t i = 0; i < GlyphPage::size; ++i) { 91 page->m_perGlyphFontData[i] = m_glyphs[i] ? m_fontDataForAllGlyphs : 0; 92 } 84 93 } 85 94 return page.release(); 86 95 } 87 96 88 ~GlyphPage() 89 { 90 if (m_perGlyphFontData) 91 fastFree(m_perGlyphFontData); 92 } 97 ~GlyphPage() { } 93 98 94 99 static const size_t size = 256; // Covers Latin-1 in a single page. … … 104 109 ASSERT_WITH_SECURITY_IMPLICATION(index < size); 105 110 Glyph glyph = m_glyphs[index]; 106 if ( m_perGlyphFontData)111 if (hasPerGlyphFontData()) 107 112 return GlyphData(glyph, m_perGlyphFontData[index]); 108 if (!glyph) 109 return GlyphData(0, 0); 110 return GlyphData(glyph, m_fontDataForAllGlyphs); 113 return GlyphData(glyph, glyph ? m_fontDataForAllGlyphs : 0); 111 114 } 112 115 … … 120 123 { 121 124 unsigned index = indexForCharacter(c); 122 if ( m_perGlyphFontData)125 if (hasPerGlyphFontData()) 123 126 return m_perGlyphFontData[index]; 124 Glyph glyph = m_glyphs[index]; 125 if (!glyph) 126 return 0; 127 return m_fontDataForAllGlyphs; 127 return m_glyphs[index] ? m_fontDataForAllGlyphs : 0; 128 128 } 129 129 … … 139 139 140 140 // GlyphPage getters will always return a null SimpleFontData* for glyph #0 if there's no per-glyph font array. 141 if ( m_perGlyphFontData) {141 if (hasPerGlyphFontData()) { 142 142 m_perGlyphFontData[index] = glyph ? fontData : 0; 143 143 return; 144 144 } 145 145 146 if (!glyph) 147 return; 148 149 // A glyph index without a font data pointer makes no sense. 150 ASSERT(fontData); 151 152 if (!m_fontDataForAllGlyphs) 153 m_fontDataForAllGlyphs = fontData; 154 155 if (m_fontDataForAllGlyphs == fontData) 156 return; 157 158 // This GlyphPage houses glyphs from multiple fonts, transition to an array of SimpleFontData pointers. 159 const SimpleFontData* oldFontData = m_fontDataForAllGlyphs; 160 m_perGlyphFontData = static_cast<const SimpleFontData**>(fastMalloc(size * sizeof(SimpleFontData*))); 161 for (unsigned i = 0; i < size; ++i) 162 m_perGlyphFontData[i] = m_glyphs[i] ? oldFontData : 0; 163 m_perGlyphFontData[index] = fontData; 146 // A single-font GlyphPage already assigned m_fontDataForAllGlyphs in the constructor. 147 ASSERT(!glyph || fontData == m_fontDataForAllGlyphs); 164 148 } 165 149 … … 169 153 } 170 154 171 void clearForFontData(const SimpleFontData* fontData)155 void removeFontDataFromSystemFallbackPage(const SimpleFontData* fontData) 172 156 { 173 if (!m_perGlyphFontData) { 174 if (m_fontDataForAllGlyphs == fontData) { 175 memset(m_glyphs, 0, sizeof(m_glyphs)); 176 m_fontDataForAllGlyphs = 0; 177 } 178 return; 179 } 157 // This method should only be called on the system fallback page, which is never single-font. 158 ASSERT(hasPerGlyphFontData()); 180 159 for (size_t i = 0; i < size; ++i) { 181 160 if (m_perGlyphFontData[i] == fontData) { … … 192 171 193 172 private: 194 GlyphPage(GlyphPageTreeNode* owner, bool clearGlyphs) 195 : m_fontDataForAllGlyphs(0) 196 , m_perGlyphFontData(0) 173 explicit GlyphPage(GlyphPageTreeNode* owner, const SimpleFontData* fontDataForAllGlyphs = 0) 174 : m_fontDataForAllGlyphs(fontDataForAllGlyphs) 197 175 , m_owner(owner) 198 176 { 199 if (clearGlyphs) 200 memset(m_glyphs, 0, sizeof(m_glyphs)); 177 memset(m_glyphs, 0, sizeof(m_glyphs)); 178 if (hasPerGlyphFontData()) 179 memset(m_perGlyphFontData, 0, sizeof(SimpleFontData*) * GlyphPage::size); 201 180 } 202 181 182 bool hasPerGlyphFontData() const { return !m_fontDataForAllGlyphs; } 183 203 184 const SimpleFontData* m_fontDataForAllGlyphs; 204 const SimpleFontData** m_perGlyphFontData;205 206 185 GlyphPageTreeNode* m_owner; 207 186 Glyph m_glyphs[size]; 187 188 // NOTE: This array has (GlyphPage::size) elements if m_fontDataForAllGlyphs is null. 189 const SimpleFontData* m_perGlyphFontData[0]; 208 190 }; 191 192 #if COMPILER(MSVC) 193 #pragma warning(pop) 194 #endif 209 195 210 196 } // namespace WebCore -
trunk/Source/WebCore/platform/graphics/GlyphPageTreeNode.cpp
r143125 r143601 202 202 } 203 203 204 m_page = GlyphPage::createUninitialized(this);205 206 204 // Now that we have a buffer full of characters, we want to get back an array 207 205 // of glyph indices. This part involves calling into the platform-specific … … 210 208 // for only 128 out of 256 characters. 211 209 bool haveGlyphs; 212 if (fontData->isSegmented()) { 210 if (!fontData->isSegmented()) { 211 m_page = GlyphPage::createForSingleFontData(this, static_cast<const SimpleFontData*>(fontData)); 212 haveGlyphs = fill(m_page.get(), 0, GlyphPage::size, buffer, bufferLength, static_cast<const SimpleFontData*>(fontData)); 213 } else { 214 m_page = GlyphPage::createForMixedFontData(this); 213 215 haveGlyphs = false; 214 216 … … 226 228 if (from < static_cast<int>(GlyphPage::size) && to > 0) { 227 229 if (haveGlyphs && !scratchPage) { 228 scratchPage = GlyphPage::create Uninitialized(this);230 scratchPage = GlyphPage::createForMixedFontData(this); 229 231 pageToFill = scratchPage.get(); 230 232 } … … 247 249 } 248 250 } 249 } else 250 haveGlyphs = fill(m_page.get(), 0, GlyphPage::size, buffer, bufferLength, static_cast<const SimpleFontData*>(fontData)); 251 } 251 252 252 253 if (!haveGlyphs) … … 280 281 } else { 281 282 // Combine the parent's glyphs and ours to form a new more complete page. 282 m_page = GlyphPage::create Uninitialized(this);283 m_page = GlyphPage::createForMixedFontData(this); 283 284 284 285 // Overlay the parent page on the fallback page. Check if the fallback font … … 308 309 m_page = parentPage->createCopiedSystemFallbackPage(this); 309 310 else 310 m_page = GlyphPage::create ZeroedSystemFallbackPage(this);311 m_page = GlyphPage::createForMixedFontData(this); 311 312 } 312 313 } … … 370 371 // Prune fall back child (if any) of this font. 371 372 if (m_systemFallbackChild && m_systemFallbackChild->m_page) 372 m_systemFallbackChild->m_page-> clearForFontData(fontData);373 m_systemFallbackChild->m_page->removeFontDataFromSystemFallbackPage(fontData); 373 374 374 375 // Prune any branch that contains this FontData.
Note: See TracChangeset
for help on using the changeset viewer.