Title: [281650] trunk
Revision
281650
Author
[email protected]
Date
2021-08-26 13:44:36 -0700 (Thu, 26 Aug 2021)

Log Message

Drawing small caps web fonts into canvas causes the GPU process to hang
https://bugs.webkit.org/show_bug.cgi?id=229401
<rdar://problem/82282054>

Reviewed by Wenson Hsieh.

Source/WebCore:

Web fonts retain their downloaded data in case they need to send that data to the GPU process
to render into canvas. Small caps fonts are implemented by creating a "derivative" variant font.
When we were creating these derivative fonts, we weren't forwarding this downloaded data to
those new fonts. Without it, the font fails to transfer across IPC.

Test: fast/text/small-caps-canvas.html

* platform/graphics/FontPlatformData.cpp:
(WebCore::makeOptionalFromPointer):
(WebCore::FontPlatformData::FontPlatformData):
* platform/graphics/FontPlatformData.h:
* platform/graphics/HEVCUtilities.cpp:
(WebCore::makeOptionalFromPointer):
* platform/graphics/coretext/FontCoreText.cpp:
(WebCore::createDerivativeFont):
(WebCore::Font::createFontWithoutSynthesizableFeatures const):
(WebCore::Font::platformCreateScaledFont const):
* platform/graphics/coretext/FontPlatformDataCoreText.cpp:
(WebCore::FontPlatformData::FontPlatformData):
* platform/graphics/win/FontPlatformDataCairoWin.cpp:
(WebCore::FontPlatformData::FontPlatformData):
* platform/graphics/win/FontPlatformDataWin.cpp:
(WebCore::FontPlatformData::FontPlatformData):

LayoutTests:

* fast/text/small-caps-canvas-expected.txt: Added.
* fast/text/small-caps-canvas.html: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (281649 => 281650)


--- trunk/LayoutTests/ChangeLog	2021-08-26 20:39:00 UTC (rev 281649)
+++ trunk/LayoutTests/ChangeLog	2021-08-26 20:44:36 UTC (rev 281650)
@@ -1,3 +1,14 @@
+2021-08-26  Myles C. Maxfield  <[email protected]>
+
+        Drawing small caps web fonts into canvas causes the GPU process to hang
+        https://bugs.webkit.org/show_bug.cgi?id=229401
+        <rdar://problem/82282054>
+
+        Reviewed by Wenson Hsieh.
+
+        * fast/text/small-caps-canvas-expected.txt: Added.
+        * fast/text/small-caps-canvas.html: Added.
+
 2021-08-26  Eric Hutchison  <[email protected]>
 
         Update test expectations for webgl tests.

Added: trunk/LayoutTests/fast/text/small-caps-canvas-expected.txt (0 => 281650)


--- trunk/LayoutTests/fast/text/small-caps-canvas-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/fast/text/small-caps-canvas-expected.txt	2021-08-26 20:44:36 UTC (rev 281650)
@@ -0,0 +1,2 @@
+This test makes sure that drawing small caps text into a canvas does not hang the GPU process. This test passes if the test does not time out.
+

Added: trunk/LayoutTests/fast/text/small-caps-canvas.html (0 => 281650)


--- trunk/LayoutTests/fast/text/small-caps-canvas.html	                        (rev 0)
+++ trunk/LayoutTests/fast/text/small-caps-canvas.html	2021-08-26 20:44:36 UTC (rev 281650)
@@ -0,0 +1,38 @@
+<!DOCTYPE html>
+<html>
+<head>
+<style>
+@font-face {
+    font-family: "WebFont";
+    src: url("../../resources/Ahem.ttf") format("truetype");
+}
+</style>
+</head>
+<body>
+This test makes sure that drawing small caps text into a canvas does not hang the GPU process. This test passes if the test does not time out.
+<div><canvas id="canvas" width="200" height="200"></canvas></div>
+<script>
+if (window.testRunner) {
+    testRunner.waitUntilDone();
+    testRunner.dumpAsText();
+}
+let canvas = document.getElementById("canvas");
+let context = canvas.getContext("2d");
+context.font = "small-caps 40px 'WebFont'";
+var count = 0;
+function frame() {
+    if (count == 12) {
+        if (window.testRunner)
+            testRunner.notifyDone();
+    } else {
+        context.fillText("hi", 0, 200);
+        ++count;
+        requestAnimationFrame(frame);
+    }
+}
+document.fonts.entries().next().value.load().then(function() {
+    requestAnimationFrame(frame);
+});
+</script>
+</body>
+</html>

Modified: trunk/Source/WebCore/ChangeLog (281649 => 281650)


--- trunk/Source/WebCore/ChangeLog	2021-08-26 20:39:00 UTC (rev 281649)
+++ trunk/Source/WebCore/ChangeLog	2021-08-26 20:44:36 UTC (rev 281650)
@@ -1,5 +1,37 @@
 2021-08-26  Myles C. Maxfield  <[email protected]>
 
+        Drawing small caps web fonts into canvas causes the GPU process to hang
+        https://bugs.webkit.org/show_bug.cgi?id=229401
+        <rdar://problem/82282054>
+
+        Reviewed by Wenson Hsieh.
+
+        Web fonts retain their downloaded data in case they need to send that data to the GPU process
+        to render into canvas. Small caps fonts are implemented by creating a "derivative" variant font.
+        When we were creating these derivative fonts, we weren't forwarding this downloaded data to
+        those new fonts. Without it, the font fails to transfer across IPC.
+
+        Test: fast/text/small-caps-canvas.html
+
+        * platform/graphics/FontPlatformData.cpp:
+        (WebCore::makeOptionalFromPointer):
+        (WebCore::FontPlatformData::FontPlatformData):
+        * platform/graphics/FontPlatformData.h:
+        * platform/graphics/HEVCUtilities.cpp:
+        (WebCore::makeOptionalFromPointer):
+        * platform/graphics/coretext/FontCoreText.cpp:
+        (WebCore::createDerivativeFont):
+        (WebCore::Font::createFontWithoutSynthesizableFeatures const):
+        (WebCore::Font::platformCreateScaledFont const):
+        * platform/graphics/coretext/FontPlatformDataCoreText.cpp:
+        (WebCore::FontPlatformData::FontPlatformData):
+        * platform/graphics/win/FontPlatformDataCairoWin.cpp:
+        (WebCore::FontPlatformData::FontPlatformData):
+        * platform/graphics/win/FontPlatformDataWin.cpp:
+        (WebCore::FontPlatformData::FontPlatformData):
+
+2021-08-26  Myles C. Maxfield  <[email protected]>
+
         REGRESSION(r256659): We try to remove fonts from the CSSFontFace which were never added
         https://bugs.webkit.org/show_bug.cgi?id=229535
         <rdar://problem/78857440>

Modified: trunk/Source/WebCore/platform/graphics/FontPlatformData.cpp (281649 => 281650)


--- trunk/Source/WebCore/platform/graphics/FontPlatformData.cpp	2021-08-26 20:39:00 UTC (rev 281649)
+++ trunk/Source/WebCore/platform/graphics/FontPlatformData.cpp	2021-08-26 20:44:36 UTC (rev 281650)
@@ -32,16 +32,22 @@
 {
 }
 
-FontPlatformData::FontPlatformData(float size, bool syntheticBold, bool syntheticOblique, FontOrientation orientation, FontWidthVariant widthVariant, TextRenderingMode textRenderingMode, CreationData* creationData)
+template<typename ValueType> static inline std::optional<ValueType> makeOptionalFromPointer(const ValueType* pointer)
+{
+    if (!pointer)
+        return std::nullopt;
+    return *pointer;
+}
+
+FontPlatformData::FontPlatformData(float size, bool syntheticBold, bool syntheticOblique, FontOrientation orientation, FontWidthVariant widthVariant, TextRenderingMode textRenderingMode, const CreationData* creationData)
     : m_size(size)
     , m_orientation(orientation)
     , m_widthVariant(widthVariant)
     , m_textRenderingMode(textRenderingMode)
+    , m_creationData(makeOptionalFromPointer(creationData))
     , m_syntheticBold(syntheticBold)
     , m_syntheticOblique(syntheticOblique)
 {
-    if (creationData)
-        m_creationData = *creationData;
 }
 
 #if !USE(FREETYPE)

Modified: trunk/Source/WebCore/platform/graphics/FontPlatformData.h (281649 => 281650)


--- trunk/Source/WebCore/platform/graphics/FontPlatformData.h	2021-08-26 20:39:00 UTC (rev 281649)
+++ trunk/Source/WebCore/platform/graphics/FontPlatformData.h	2021-08-26 20:44:36 UTC (rev 281650)
@@ -108,14 +108,14 @@
     FontPlatformData(WTF::HashTableDeletedValueType);
     FontPlatformData();
 
-    FontPlatformData(float size, bool syntheticBold, bool syntheticOblique, FontOrientation = FontOrientation::Horizontal, FontWidthVariant = FontWidthVariant::RegularWidth, TextRenderingMode = TextRenderingMode::AutoTextRendering, CreationData* = nullptr);
+    FontPlatformData(float size, bool syntheticBold, bool syntheticOblique, FontOrientation = FontOrientation::Horizontal, FontWidthVariant = FontWidthVariant::RegularWidth, TextRenderingMode = TextRenderingMode::AutoTextRendering, const CreationData* = nullptr);
 
 #if USE(CORE_TEXT)
-    WEBCORE_EXPORT FontPlatformData(RetainPtr<CTFontRef>&&, float size, bool syntheticBold = false, bool syntheticOblique = false, FontOrientation = FontOrientation::Horizontal, FontWidthVariant = FontWidthVariant::RegularWidth, TextRenderingMode = TextRenderingMode::AutoTextRendering, CreationData* = nullptr);
+    WEBCORE_EXPORT FontPlatformData(RetainPtr<CTFontRef>&&, float size, bool syntheticBold = false, bool syntheticOblique = false, FontOrientation = FontOrientation::Horizontal, FontWidthVariant = FontWidthVariant::RegularWidth, TextRenderingMode = TextRenderingMode::AutoTextRendering, const CreationData* = nullptr);
 #endif
 
 #if PLATFORM(WIN)
-    FontPlatformData(GDIObject<HFONT>, float size, bool syntheticBold, bool syntheticOblique, bool useGDI, CreationData* = nullptr);
+    FontPlatformData(GDIObject<HFONT>, float size, bool syntheticBold, bool syntheticOblique, bool useGDI, const CreationData* = nullptr);
 #if USE(CORE_TEXT)
     FontPlatformData(GDIObject<HFONT>, CTFontRef, CGFontRef, float size, bool syntheticBold, bool syntheticOblique, bool useGDI);
 #endif
@@ -123,7 +123,7 @@
     FontPlatformData(GDIObject<HFONT>&&, COMPtr<IDWriteFont>&&, float size, bool syntheticBold, bool syntheticOblique, bool useGDI);
 #endif
 #if USE(CAIRO)
-    FontPlatformData(GDIObject<HFONT>, cairo_font_face_t*, float size, bool bold, bool italic, CreationData* = nullptr);
+    FontPlatformData(GDIObject<HFONT>, cairo_font_face_t*, float size, bool bold, bool italic, const CreationData* = nullptr);
 #endif
 #endif
 
@@ -287,6 +287,8 @@
     FontWidthVariant m_widthVariant { FontWidthVariant::RegularWidth };
     TextRenderingMode m_textRenderingMode { TextRenderingMode::AutoTextRendering };
 
+    // This is conceptually const, but we can't make it actually const,
+    // because FontPlatformData is used as a key in a HashMap.
     std::optional<CreationData> m_creationData;
 
     bool m_syntheticBold { false };

Modified: trunk/Source/WebCore/platform/graphics/HEVCUtilities.cpp (281649 => 281650)


--- trunk/Source/WebCore/platform/graphics/HEVCUtilities.cpp	2021-08-26 20:39:00 UTC (rev 281649)
+++ trunk/Source/WebCore/platform/graphics/HEVCUtilities.cpp	2021-08-26 20:44:36 UTC (rev 281650)
@@ -106,7 +106,7 @@
     return parameters;
 }
 
-template<typename ValueType> inline std::optional<ValueType> makeOptionalFromPointer(const ValueType* pointer)
+template<typename ValueType> static inline std::optional<ValueType> makeOptionalFromPointer(const ValueType* pointer)
 {
     if (!pointer)
         return std::nullopt;

Modified: trunk/Source/WebCore/platform/graphics/coretext/FontCoreText.cpp (281649 => 281650)


--- trunk/Source/WebCore/platform/graphics/coretext/FontCoreText.cpp	2021-08-26 20:39:00 UTC (rev 281649)
+++ trunk/Source/WebCore/platform/graphics/coretext/FontCoreText.cpp	2021-08-26 20:44:36 UTC (rev 281650)
@@ -395,7 +395,7 @@
 }
 #endif
 
-static RefPtr<Font> createDerivativeFont(CTFontRef font, float size, FontOrientation orientation, CTFontSymbolicTraits fontTraits, bool syntheticBold, bool syntheticItalic)
+static RefPtr<Font> createDerivativeFont(CTFontRef font, float size, FontOrientation orientation, CTFontSymbolicTraits fontTraits, bool syntheticBold, bool syntheticItalic, FontWidthVariant fontWidthVariant, TextRenderingMode textRenderingMode, const FontPlatformData::CreationData* creationData)
 {
     if (!font)
         return nullptr;
@@ -409,7 +409,7 @@
 
     bool usedSyntheticBold = (fontTraits & kCTFontBoldTrait) && !(scaledFontTraits & kCTFontTraitBold);
     bool usedSyntheticOblique = (fontTraits & kCTFontItalicTrait) && !(scaledFontTraits & kCTFontTraitItalic);
-    FontPlatformData scaledFontData(font, size, usedSyntheticBold, usedSyntheticOblique, orientation);
+    FontPlatformData scaledFontData(font, size, usedSyntheticBold, usedSyntheticOblique, orientation, fontWidthVariant, textRenderingMode, creationData);
 
     return Font::create(scaledFontData);
 }
@@ -549,7 +549,7 @@
     float size = m_platformData.size();
     CTFontSymbolicTraits fontTraits = CTFontGetSymbolicTraits(m_platformData.font());
     RetainPtr<CTFontRef> ctFont = createCTFontWithoutSynthesizableFeatures(m_platformData.font());
-    return createDerivativeFont(ctFont.get(), size, m_platformData.orientation(), fontTraits, m_platformData.syntheticBold(), m_platformData.syntheticOblique());
+    return createDerivativeFont(ctFont.get(), size, m_platformData.orientation(), fontTraits, m_platformData.syntheticBold(), m_platformData.syntheticOblique(), m_platformData.widthVariant(), m_platformData.textRenderingMode(), m_platformData.creationData() ? &m_platformData.creationData().value() : nullptr);
 }
 
 RefPtr<Font> Font::platformCreateScaledFont(const FontDescription&, float scaleFactor) const
@@ -559,7 +559,7 @@
     RetainPtr<CTFontDescriptorRef> fontDescriptor = adoptCF(CTFontCopyFontDescriptor(m_platformData.font()));
     RetainPtr<CTFontRef> scaledFont = adoptCF(CTFontCreateWithFontDescriptor(fontDescriptor.get(), size, nullptr));
 
-    return createDerivativeFont(scaledFont.get(), size, m_platformData.orientation(), fontTraits, m_platformData.syntheticBold(), m_platformData.syntheticOblique());
+    return createDerivativeFont(scaledFont.get(), size, m_platformData.orientation(), fontTraits, m_platformData.syntheticBold(), m_platformData.syntheticOblique(), m_platformData.widthVariant(), m_platformData.textRenderingMode(), m_platformData.creationData() ? &m_platformData.creationData().value() : nullptr);
 }
 
 float Font::platformWidthForGlyph(Glyph glyph) const

Modified: trunk/Source/WebCore/platform/graphics/coretext/FontPlatformDataCoreText.cpp (281649 => 281650)


--- trunk/Source/WebCore/platform/graphics/coretext/FontPlatformDataCoreText.cpp	2021-08-26 20:39:00 UTC (rev 281649)
+++ trunk/Source/WebCore/platform/graphics/coretext/FontPlatformDataCoreText.cpp	2021-08-26 20:44:36 UTC (rev 281650)
@@ -35,7 +35,7 @@
 
 namespace WebCore {
 
-FontPlatformData::FontPlatformData(RetainPtr<CTFontRef>&& font, float size, bool syntheticBold, bool syntheticOblique, FontOrientation orientation, FontWidthVariant widthVariant, TextRenderingMode textRenderingMode, CreationData* creationData)
+FontPlatformData::FontPlatformData(RetainPtr<CTFontRef>&& font, float size, bool syntheticBold, bool syntheticOblique, FontOrientation orientation, FontWidthVariant widthVariant, TextRenderingMode textRenderingMode, const CreationData* creationData)
     : FontPlatformData(size, syntheticBold, syntheticOblique, orientation, widthVariant, textRenderingMode, creationData)
 {
     ASSERT_ARG(font, font);

Modified: trunk/Source/WebCore/platform/graphics/win/FontPlatformDataCairoWin.cpp (281649 => 281650)


--- trunk/Source/WebCore/platform/graphics/win/FontPlatformDataCairoWin.cpp	2021-08-26 20:39:00 UTC (rev 281649)
+++ trunk/Source/WebCore/platform/graphics/win/FontPlatformDataCairoWin.cpp	2021-08-26 20:44:36 UTC (rev 281650)
@@ -60,7 +60,7 @@
         m_isSystemFont = !wcscmp(faceName, L"Lucida Grande");
 }
 
-FontPlatformData::FontPlatformData(GDIObject<HFONT> font, cairo_font_face_t* fontFace, float size, bool bold, bool oblique, CreationData* creationData)
+FontPlatformData::FontPlatformData(GDIObject<HFONT> font, cairo_font_face_t* fontFace, float size, bool bold, bool oblique, const CreationData* creationData)
     : FontPlatformData(size, bold, oblique, FontOrientation::Horizontal, FontWidthVariant::RegularWidth, TextRenderingMode::AutoTextRendering, creationData)
 {
     m_font = SharedGDIObject<HFONT>::create(WTFMove(font));

Modified: trunk/Source/WebCore/platform/graphics/win/FontPlatformDataWin.cpp (281649 => 281650)


--- trunk/Source/WebCore/platform/graphics/win/FontPlatformDataWin.cpp	2021-08-26 20:39:00 UTC (rev 281649)
+++ trunk/Source/WebCore/platform/graphics/win/FontPlatformDataWin.cpp	2021-08-26 20:44:36 UTC (rev 281650)
@@ -41,7 +41,7 @@
 
 namespace WebCore {
 
-FontPlatformData::FontPlatformData(GDIObject<HFONT> font, float size, bool bold, bool oblique, bool useGDI, CreationData* creationData)
+FontPlatformData::FontPlatformData(GDIObject<HFONT> font, float size, bool bold, bool oblique, bool useGDI, const CreationData* creationData)
     : FontPlatformData(size, bold, oblique, FontOrientation::Horizontal, FontWidthVariant::RegularWidth, TextRenderingMode::AutoTextRendering, creationData)
 {
     m_font = SharedGDIObject<HFONT>::create(WTFMove(font));
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to