diff --git a/DEPS b/DEPS
index 6a99295..e3b320c 100644
--- a/DEPS
+++ b/DEPS
@@ -40,7 +40,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling Skia
   # and whatever else without interference from each other.
-  'skia_revision': 'ae9718f1d40556ed5a49e616dbe54087f4d0d546',
+  'skia_revision': '32342f032e1dfd133040324f851f0365f9d4cb51',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling V8
   # and whatever else without interference from each other.
diff --git a/chromecast/renderer/cast_content_renderer_client.cc b/chromecast/renderer/cast_content_renderer_client.cc
index 57089ad..2092aa1 100644
--- a/chromecast/renderer/cast_content_renderer_client.cc
+++ b/chromecast/renderer/cast_content_renderer_client.cc
@@ -26,6 +26,7 @@
 #include "services/service_manager/public/cpp/interface_provider.h"
 #include "third_party/WebKit/public/platform/WebColor.h"
 #include "third_party/WebKit/public/web/WebFrameWidget.h"
+#include "third_party/WebKit/public/web/WebRuntimeFeatures.h"
 #include "third_party/WebKit/public/web/WebSettings.h"
 #include "third_party/WebKit/public/web/WebView.h"
 
@@ -98,9 +99,6 @@
     blink::WebFrameWidget* web_frame_widget = render_view->GetWebFrameWidget();
     web_frame_widget->setBaseBackgroundColor(kColorBlack);
 
-    // Settings for ATV (Android defaults are not what we want):
-    webview->settings()->setMediaControlsOverlayPlayButtonEnabled(false);
-
     // Disable application cache as Chromecast doesn't support off-line
     // application running.
     webview->settings()->setOfflineWebApplicationCacheEnabled(false);
@@ -148,5 +146,11 @@
   return false;
 }
 
+void CastContentRendererClient::
+    SetRuntimeFeaturesDefaultsBeforeBlinkInitialization() {
+  // Settings for ATV (Android defaults are not what we want).
+  blink::WebRuntimeFeatures::enableMediaControlsOverlayPlayButton(false);
+}
+
 }  // namespace shell
 }  // namespace chromecast
diff --git a/chromecast/renderer/cast_content_renderer_client.h b/chromecast/renderer/cast_content_renderer_client.h
index ecc58a1..8f6aba4 100644
--- a/chromecast/renderer/cast_content_renderer_client.h
+++ b/chromecast/renderer/cast_content_renderer_client.h
@@ -43,6 +43,7 @@
                       bool render_frame_has_played_media_before,
                       const base::Closure& closure) override;
   bool AllowMediaSuspend() override;
+  void SetRuntimeFeaturesDefaultsBeforeBlinkInitialization() override;
 
  protected:
   CastContentRendererClient();
diff --git a/content/browser/frame_host/navigator_impl.cc b/content/browser/frame_host/navigator_impl.cc
index 07f3cc9..b2533a8 100644
--- a/content/browser/frame_host/navigator_impl.cc
+++ b/content/browser/frame_host/navigator_impl.cc
@@ -685,7 +685,8 @@
 
   // After setting the last committed origin, reset the feature policy in the
   // RenderFrameHost to a blank policy based on the parent frame.
-  render_frame_host->ResetFeaturePolicy();
+  if (did_navigate && !is_navigation_within_page)
+    render_frame_host->ResetFeaturePolicy();
 
   // Send notification about committed provisional loads. This notification is
   // different from the NAV_ENTRY_COMMITTED notification which doesn't include
diff --git a/content/browser/frame_host/navigator_impl_unittest.cc b/content/browser/frame_host/navigator_impl_unittest.cc
index 41e14e77..c5b35f16 100644
--- a/content/browser/frame_host/navigator_impl_unittest.cc
+++ b/content/browser/frame_host/navigator_impl_unittest.cc
@@ -1240,4 +1240,49 @@
   EXPECT_EQ(speculative_rfh, main_test_rfh());
 }
 
+// Feature Policy: Test that the feature policy is reset when navigating pages
+// within a site.
+TEST_F(NavigatorTestWithBrowserSideNavigation,
+       FeaturePolicySameSiteNavigation) {
+  const GURL kUrl1("http://www.chromium.org/");
+  const GURL kUrl2("http://www.chromium.org/Home");
+
+  contents()->NavigateAndCommit(kUrl1);
+
+  // Check the feature policy before navigation.
+  FeaturePolicy* original_feature_policy =
+      main_test_rfh()->get_feature_policy();
+  ASSERT_TRUE(original_feature_policy);
+
+  // Navigate to the new URL.
+  contents()->NavigateAndCommit(kUrl2);
+
+  // Check the feature policy after navigation.
+  FeaturePolicy* final_feature_policy = main_test_rfh()->get_feature_policy();
+  ASSERT_TRUE(final_feature_policy);
+  ASSERT_NE(original_feature_policy, final_feature_policy);
+}
+
+// Feature Policy: Test that the feature policy is not reset when navigating
+// within a page.
+TEST_F(NavigatorTestWithBrowserSideNavigation,
+       FeaturePolicyFragmentNavigation) {
+  const GURL kUrl1("http://www.chromium.org/");
+  const GURL kUrl2("http://www.chromium.org/#Home");
+
+  contents()->NavigateAndCommit(kUrl1);
+
+  // Check the feature policy before navigation.
+  FeaturePolicy* original_feature_policy =
+      main_test_rfh()->get_feature_policy();
+  ASSERT_TRUE(original_feature_policy);
+
+  // Navigate to the new URL.
+  contents()->NavigateAndCommit(kUrl2);
+
+  // Check the feature policy after navigation.
+  FeaturePolicy* final_feature_policy = main_test_rfh()->get_feature_policy();
+  ASSERT_EQ(original_feature_policy, final_feature_policy);
+}
+
 }  // namespace content
diff --git a/content/child/runtime_features.cc b/content/child/runtime_features.cc
index c4073ed..28608481 100644
--- a/content/child/runtime_features.cc
+++ b/content/child/runtime_features.cc
@@ -45,6 +45,7 @@
   // Android does not yet support SystemMonitor.
   WebRuntimeFeatures::enableOnDeviceChange(false);
   WebRuntimeFeatures::enableMediaSession(true);
+  WebRuntimeFeatures::enableMediaControlsOverlayPlayButton(true);
 #else  // defined(OS_ANDROID)
   WebRuntimeFeatures::enableNavigatorContentUtils(true);
   if (base::FeatureList::IsEnabled(
diff --git a/content/renderer/render_view_impl.cc b/content/renderer/render_view_impl.cc
index 85a9fa91..09fd4bb6 100644
--- a/content/renderer/render_view_impl.cc
+++ b/content/renderer/render_view_impl.cc
@@ -1025,7 +1025,6 @@
   web_view->setIgnoreViewportTagScaleLimits(prefs.force_enable_zoom);
   settings->setAutoZoomFocusedNodeToLegibleScale(true);
   settings->setDoubleTapToZoomEnabled(prefs.double_tap_to_zoom_enabled);
-  settings->setMediaControlsOverlayPlayButtonEnabled(true);
   settings->setMediaPlaybackRequiresUserGesture(
       prefs.user_gesture_required_for_media_playback);
   settings->setMediaPlaybackGestureWhitelistScope(
diff --git a/third_party/WebKit/LayoutTests/media/controls/video-overlay-play-button.html b/third_party/WebKit/LayoutTests/media/controls/video-overlay-play-button.html
new file mode 100644
index 0000000..9534c57a
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/media/controls/video-overlay-play-button.html
@@ -0,0 +1,54 @@
+<!DOCTYPE html>
+<title>Test that the overlay play button respects the controls attribute.</title>
+<script src='../../resources/testharness.js'></script>
+<script src='../../resources/testharnessreport.js'></script>
+<script src='../media-file.js'></script>
+<script src='../media-controls.js'></script>
+<body>
+<script>
+async_test(function(t) {
+  var mediaControlsOverlayPlayButtonValue =
+      internals.runtimeFlags.mediaControlsOverlayPlayButtonEnabled;
+  internals.runtimeFlags.mediaControlsOverlayPlayButtonEnabled = true;
+
+  t.add_cleanup(() => {
+    internals.runtimeFlags.mediaControlsOverlayPlayButtonEnabled =
+        mediaControlsOverlayPlayButtonValue;
+  });
+
+  // Add video dynamically, since otherwise the controls are created, but
+  // hidden, before the setting is set, causing the setting to be ignored.
+  var video = document.createElement('video');
+  document.body.appendChild(video);
+
+  video.controls = true;
+  var button = mediaControlsButton(video, 'overlay-play-button')
+  assert_equals(getComputedStyle(button).display, 'flex');
+
+  var watcher = new EventWatcher(t, video, ['loadeddata', 'play', 'pause']);
+  watcher.wait_for('loadeddata').then(t.step_func(function() {
+    video.play();
+    return watcher.wait_for('play');
+  })).then(t.step_func(function() {
+    assert_equals(getComputedStyle(button).display, 'none');
+    video.pause();
+    return watcher.wait_for('pause');
+  })).then(t.step_func(function() {
+    assert_equals(getComputedStyle(button).display, 'flex');
+    video.controls = false;
+    assert_equals(getComputedStyle(button).display, 'none');
+    video.play();
+    return watcher.wait_for('play');
+  })).then(t.step_func(function() {
+    assert_equals(getComputedStyle(button).display, 'none');
+    video.pause();
+    return watcher.wait_for('pause');
+  })).then(t.step_func_done(function() {
+    assert_equals(getComputedStyle(button).display, 'none');
+    video.controls = true;
+    assert_equals(getComputedStyle(button).display, 'flex');
+  }));
+
+  video.src = findMediaFile('video', '../content/test');
+});
+</script>
diff --git a/third_party/WebKit/LayoutTests/media/video-controls-overlay-play-button.html b/third_party/WebKit/LayoutTests/media/video-controls-overlay-play-button.html
deleted file mode 100644
index e9e8f32..0000000
--- a/third_party/WebKit/LayoutTests/media/video-controls-overlay-play-button.html
+++ /dev/null
@@ -1,47 +0,0 @@
-<!DOCTYPE html>
-<title>Test that the overlay play button respects the controls attribute.</title>
-<script src="../resources/testharness.js"></script>
-<script src="../resources/testharnessreport.js"></script>
-<script src="media-file.js"></script>
-<script src="media-controls.js"></script>
-<body>
-<script>
-async_test(function(t) {
-    internals.settings.setMediaControlsOverlayPlayButtonEnabled(true);
-
-    // Add video dynamically, since otherwise the controls are created, but
-    // hidden, before the setting is set, causing the setting to be ignored.
-    var video = document.createElement("video");
-    document.body.appendChild(video);
-
-    video.controls = true;
-    var button = mediaControlsButton(video, "overlay-play-button")
-    assert_equals(getComputedStyle(button).display, "flex");
-
-    var watcher = new EventWatcher(t, video, ["loadeddata", "play", "pause"]);
-    watcher.wait_for("loadeddata").then(t.step_func(function() {
-        video.play();
-        return watcher.wait_for("play");
-    })).then(t.step_func(function() {
-        assert_equals(getComputedStyle(button).display, "none");
-        video.pause();
-        return watcher.wait_for("pause");
-    })).then(t.step_func(function() {
-        assert_equals(getComputedStyle(button).display, "flex");
-        video.controls = false;
-        assert_equals(getComputedStyle(button).display, "none");
-        video.play();
-        return watcher.wait_for("play");
-    })).then(t.step_func(function() {
-        assert_equals(getComputedStyle(button).display, "none");
-        video.pause();
-        return watcher.wait_for("pause");
-    })).then(t.step_func_done(function() {
-        assert_equals(getComputedStyle(button).display, "none");
-        video.controls = true;
-        assert_equals(getComputedStyle(button).display, "flex");
-    }));
-
-    video.src = findMediaFile("video", "content/test");
-});
-</script>
\ No newline at end of file
diff --git a/third_party/WebKit/Source/core/frame/Settings.json5 b/third_party/WebKit/Source/core/frame/Settings.json5
index c32d7ef..ea068413 100644
--- a/third_party/WebKit/Source/core/frame/Settings.json5
+++ b/third_party/WebKit/Source/core/frame/Settings.json5
@@ -216,10 +216,6 @@
     },
 
     {
-      name: "mediaControlsOverlayPlayButtonEnabled",
-      initial: false,
-    },
-    {
       name: "mediaPlaybackRequiresUserGesture",
       initial: false,
     },
diff --git a/third_party/WebKit/Source/core/html/shadow/MediaControls.cpp b/third_party/WebKit/Source/core/html/shadow/MediaControls.cpp
index 087b101..be254c1 100644
--- a/third_party/WebKit/Source/core/html/shadow/MediaControls.cpp
+++ b/third_party/WebKit/Source/core/html/shadow/MediaControls.cpp
@@ -222,8 +222,7 @@
   MediaControlOverlayEnclosureElement* overlayEnclosure =
       MediaControlOverlayEnclosureElement::create(*this);
 
-  if (document().settings() &&
-      document().settings()->getMediaControlsOverlayPlayButtonEnabled()) {
+  if (RuntimeEnabledFeatures::mediaControlsOverlayPlayButtonEnabled()) {
     MediaControlOverlayPlayButtonElement* overlayPlayButton =
         MediaControlOverlayPlayButtonElement::create(*this);
     m_overlayPlayButton = overlayPlayButton;
@@ -338,6 +337,35 @@
           *this, MediaControlToggleClosedCaptionsButtonElement::create(*this)));
 }
 
+Node::InsertionNotificationRequest MediaControls::insertedInto(
+    ContainerNode* root) {
+  if (!mediaElement().isConnected())
+    return HTMLDivElement::insertedInto(root);
+
+  // TODO(mlamouri): we should show the controls instead of having
+  // HTMLMediaElement do it.
+
+  // m_windowEventListener doesn't need to be re-attached as it's only needed
+  // when a menu is visible.
+  m_mediaEventListener->attach();
+  if (m_orientationLockDelegate)
+    m_orientationLockDelegate->attach();
+
+  return HTMLDivElement::insertedInto(root);
+}
+
+void MediaControls::removedFrom(ContainerNode*) {
+  DCHECK(!mediaElement().isConnected());
+
+  // TODO(mlamouri): we hide show the controls instead of having
+  // HTMLMediaElement do it.
+
+  m_windowEventListener->stop();
+  m_mediaEventListener->detach();
+  if (m_orientationLockDelegate)
+    m_orientationLockDelegate->detach();
+}
+
 void MediaControls::reset() {
   EventDispatchForbiddenScope::AllowUserAgentEvents allowEventsInShadow;
   BatchedControlUpdate batch(this);
@@ -688,27 +716,6 @@
   return contains(relatedTarget->toNode());
 }
 
-void MediaControls::onInsertedIntoDocument() {
-  // TODO(mlamouri): we should show the controls instead of having
-  // HTMLMediaElement do it.
-
-  // m_windowEventListener doesn't need to be re-attached as it's only needed
-  // when a menu is visible.
-  m_mediaEventListener->attach();
-  if (m_orientationLockDelegate)
-    m_orientationLockDelegate->attach();
-}
-
-void MediaControls::onRemovedFromDocument() {
-  // TODO(mlamouri): we hide show the controls instead of having
-  // HTMLMediaElement do it.
-
-  m_windowEventListener->stop();
-  m_mediaEventListener->detach();
-  if (m_orientationLockDelegate)
-    m_orientationLockDelegate->detach();
-}
-
 void MediaControls::onVolumeChange() {
   m_muteButton->updateDisplayType();
   m_volumeSlider->setVolume(mediaElement().muted() ? 0
diff --git a/third_party/WebKit/Source/core/html/shadow/MediaControls.h b/third_party/WebKit/Source/core/html/shadow/MediaControls.h
index c38bf9d..5ced7c1 100644
--- a/third_party/WebKit/Source/core/html/shadow/MediaControls.h
+++ b/third_party/WebKit/Source/core/html/shadow/MediaControls.h
@@ -44,6 +44,10 @@
 
   HTMLMediaElement& mediaElement() const { return *m_mediaElement; }
 
+  // Node override.
+  Node::InsertionNotificationRequest insertedInto(ContainerNode*) override;
+  void removedFrom(ContainerNode*) override;
+
   void reset();
 
   void show();
@@ -166,8 +170,6 @@
   bool containsRelatedTarget(Event*);
 
   // Methods called by MediaControlsMediaEventListener.
-  void onInsertedIntoDocument();
-  void onRemovedFromDocument();
   void onVolumeChange();
   void onFocusIn();
   void onTimeUpdate();
diff --git a/third_party/WebKit/Source/core/html/shadow/MediaControlsMediaEventListener.cpp b/third_party/WebKit/Source/core/html/shadow/MediaControlsMediaEventListener.cpp
index 76d680d..070f17b 100644
--- a/third_party/WebKit/Source/core/html/shadow/MediaControlsMediaEventListener.cpp
+++ b/third_party/WebKit/Source/core/html/shadow/MediaControlsMediaEventListener.cpp
@@ -14,18 +14,13 @@
 MediaControlsMediaEventListener::MediaControlsMediaEventListener(
     MediaControls* mediaControls)
     : EventListener(CPPEventListenerType), m_mediaControls(mediaControls) {
-  // These events are always active because they are needed in order to attach
-  // or detach the whole controls.
-  mediaElement().addEventListener(EventTypeNames::DOMNodeInsertedIntoDocument,
-                                  this, false);
-  mediaElement().addEventListener(EventTypeNames::DOMNodeRemovedFromDocument,
-                                  this, false);
-
   if (mediaElement().isConnected())
     attach();
 }
 
 void MediaControlsMediaEventListener::attach() {
+  DCHECK(mediaElement().isConnected());
+
   mediaElement().addEventListener(EventTypeNames::volumechange, this, false);
   mediaElement().addEventListener(EventTypeNames::focusin, this, false);
   mediaElement().addEventListener(EventTypeNames::timeupdate, this, false);
@@ -50,6 +45,8 @@
 }
 
 void MediaControlsMediaEventListener::detach() {
+  DCHECK(!mediaElement().isConnected());
+
   m_mediaControls->document().removeEventListener(
       EventTypeNames::fullscreenchange, this, false);
 
@@ -71,14 +68,6 @@
 void MediaControlsMediaEventListener::handleEvent(
     ExecutionContext* executionContext,
     Event* event) {
-  if (event->type() == EventTypeNames::DOMNodeInsertedIntoDocument) {
-    m_mediaControls->onInsertedIntoDocument();
-    return;
-  }
-  if (event->type() == EventTypeNames::DOMNodeRemovedFromDocument) {
-    m_mediaControls->onRemovedFromDocument();
-    return;
-  }
   if (event->type() == EventTypeNames::volumechange) {
     m_mediaControls->onVolumeChange();
     return;
diff --git a/third_party/WebKit/Source/core/html/shadow/MediaControlsOrientationLockDelegate.cpp b/third_party/WebKit/Source/core/html/shadow/MediaControlsOrientationLockDelegate.cpp
index f29c4c5e..71d89b3 100644
--- a/third_party/WebKit/Source/core/html/shadow/MediaControlsOrientationLockDelegate.cpp
+++ b/third_party/WebKit/Source/core/html/shadow/MediaControlsOrientationLockDelegate.cpp
@@ -69,6 +69,8 @@
 }
 
 void MediaControlsOrientationLockDelegate::attach() {
+  DCHECK(videoElement().isConnected());
+
   document().addEventListener(EventTypeNames::fullscreenchange, this, true);
   videoElement().addEventListener(EventTypeNames::webkitfullscreenchange, this,
                                   true);
@@ -76,6 +78,8 @@
 }
 
 void MediaControlsOrientationLockDelegate::detach() {
+  DCHECK(!videoElement().isConnected());
+
   document().removeEventListener(EventTypeNames::fullscreenchange, this, true);
   videoElement().removeEventListener(EventTypeNames::webkitfullscreenchange,
                                      this, true);
diff --git a/third_party/WebKit/Source/platform/RuntimeEnabledFeatures.json5 b/third_party/WebKit/Source/platform/RuntimeEnabledFeatures.json5
index ec378cd..1022cc5 100644
--- a/third_party/WebKit/Source/platform/RuntimeEnabledFeatures.json5
+++ b/third_party/WebKit/Source/platform/RuntimeEnabledFeatures.json5
@@ -1025,6 +1025,10 @@
     {
       name: "BlockLegacySubresources",
       status: "experimental",
+    },
+    {
+      name: "MediaControlsOverlayPlayButton",
+      settable_from_internals: true,
     }
   ],
 }
diff --git a/third_party/WebKit/Source/platform/fonts/Font.cpp b/third_party/WebKit/Source/platform/fonts/Font.cpp
index 1f4cc61b..e858b675 100644
--- a/third_party/WebKit/Source/platform/fonts/Font.cpp
+++ b/third_party/WebKit/Source/platform/fonts/Font.cpp
@@ -203,11 +203,7 @@
 
   FontCachePurgePreventer purgePreventer;
 
-  GlyphData emphasisGlyphData;
-  if (!getEmphasisMarkGlyphData(mark, emphasisGlyphData))
-    return;
-
-  ASSERT(emphasisGlyphData.fontData);
+  const auto emphasisGlyphData = getEmphasisMarkGlyphData(mark);
   if (!emphasisGlyphData.fontData)
     return;
 
@@ -491,36 +487,19 @@
                                       fallbackPriority);
 }
 
-bool Font::getEmphasisMarkGlyphData(const AtomicString& mark,
-                                    GlyphData& glyphData) const {
+GlyphData Font::getEmphasisMarkGlyphData(const AtomicString& mark) const {
   if (mark.isEmpty())
-    return false;
+    return GlyphData();
 
   TextRun emphasisMarkRun(mark, mark.length());
-  TextRunPaintInfo emphasisPaintInfo(emphasisMarkRun);
-  GlyphBuffer glyphBuffer;
-  buildGlyphBuffer(emphasisPaintInfo, glyphBuffer);
-
-  if (glyphBuffer.isEmpty())
-    return false;
-
-  ASSERT(glyphBuffer.fontDataAt(0));
-  glyphData.fontData =
-      glyphBuffer.fontDataAt(0)->emphasisMarkFontData(m_fontDescription).get();
-  glyphData.glyph = glyphBuffer.glyphAt(0);
-
-  return true;
+  return CachingWordShaper(*this).emphasisMarkGlyphData(emphasisMarkRun);
 }
 
 int Font::emphasisMarkAscent(const AtomicString& mark) const {
   FontCachePurgePreventer purgePreventer;
 
-  GlyphData markGlyphData;
-  if (!getEmphasisMarkGlyphData(mark, markGlyphData))
-    return 0;
-
+  const auto markGlyphData = getEmphasisMarkGlyphData(mark);
   const SimpleFontData* markFontData = markGlyphData.fontData;
-  ASSERT(markFontData);
   if (!markFontData)
     return 0;
 
@@ -530,12 +509,8 @@
 int Font::emphasisMarkDescent(const AtomicString& mark) const {
   FontCachePurgePreventer purgePreventer;
 
-  GlyphData markGlyphData;
-  if (!getEmphasisMarkGlyphData(mark, markGlyphData))
-    return 0;
-
+  const auto markGlyphData = getEmphasisMarkGlyphData(mark);
   const SimpleFontData* markFontData = markGlyphData.fontData;
-  ASSERT(markFontData);
   if (!markFontData)
     return 0;
 
@@ -545,12 +520,8 @@
 int Font::emphasisMarkHeight(const AtomicString& mark) const {
   FontCachePurgePreventer purgePreventer;
 
-  GlyphData markGlyphData;
-  if (!getEmphasisMarkGlyphData(mark, markGlyphData))
-    return 0;
-
+  const auto markGlyphData = getEmphasisMarkGlyphData(mark);
   const SimpleFontData* markFontData = markGlyphData.fontData;
-  ASSERT(markFontData);
   if (!markFontData)
     return 0;
 
diff --git a/third_party/WebKit/Source/platform/fonts/Font.h b/third_party/WebKit/Source/platform/fonts/Font.h
index 6afe042..88b85de 100644
--- a/third_party/WebKit/Source/platform/fonts/Font.h
+++ b/third_party/WebKit/Source/platform/fonts/Font.h
@@ -182,7 +182,7 @@
                        const FloatPoint&,
                        float deviceScaleFactor) const;
 
-  bool getEmphasisMarkGlyphData(const AtomicString&, GlyphData&) const;
+  GlyphData getEmphasisMarkGlyphData(const AtomicString&) const;
 
   bool computeCanShapeWordByWord() const;
 
diff --git a/third_party/WebKit/Source/platform/fonts/SimpleFontData.h b/third_party/WebKit/Source/platform/fonts/SimpleFontData.h
index 73f6a3e..3594351 100644
--- a/third_party/WebKit/Source/platform/fonts/SimpleFontData.h
+++ b/third_party/WebKit/Source/platform/fonts/SimpleFontData.h
@@ -48,7 +48,8 @@
 // given
 // character.
 struct GlyphData {
-  GlyphData(Glyph g = 0, const SimpleFontData* f = 0) : glyph(g), fontData(f) {}
+  GlyphData(Glyph g = 0, const SimpleFontData* f = nullptr)
+      : glyph(g), fontData(f) {}
   Glyph glyph;
   const SimpleFontData* fontData;
 };
diff --git a/third_party/WebKit/Source/platform/fonts/shaping/CachingWordShaper.cpp b/third_party/WebKit/Source/platform/fonts/shaping/CachingWordShaper.cpp
index f6ab60ad..1a0ddd1 100644
--- a/third_party/WebKit/Source/platform/fonts/shaping/CachingWordShaper.cpp
+++ b/third_party/WebKit/Source/platform/fonts/shaping/CachingWordShaper.cpp
@@ -146,4 +146,12 @@
   return buffer.runFontData();
 }
 
+GlyphData CachingWordShaper::emphasisMarkGlyphData(
+    const TextRun& emphasisMarkRun) const {
+  ShapeResultBuffer buffer;
+  shapeResultsForRun(shapeCache(), &m_font, emphasisMarkRun, &buffer);
+
+  return buffer.emphasisMarkGlyphData(m_font.m_fontDescription);
+}
+
 };  // namespace blink
diff --git a/third_party/WebKit/Source/platform/fonts/shaping/CachingWordShaper.h b/third_party/WebKit/Source/platform/fonts/shaping/CachingWordShaper.h
index bf17fa12..30dce35 100644
--- a/third_party/WebKit/Source/platform/fonts/shaping/CachingWordShaper.h
+++ b/third_party/WebKit/Source/platform/fonts/shaping/CachingWordShaper.h
@@ -32,7 +32,6 @@
 #include "wtf/Allocator.h"
 #include "wtf/PassRefPtr.h"
 #include "wtf/Vector.h"
-#include <tuple>
 
 namespace blink {
 
@@ -73,6 +72,8 @@
 
   Vector<ShapeResultBuffer::RunFontData> runFontData(const TextRun&) const;
 
+  GlyphData emphasisMarkGlyphData(const TextRun&) const;
+
  private:
   ShapeCache* shapeCache() const;
 
diff --git a/third_party/WebKit/Source/platform/fonts/shaping/ShapeResultBuffer.cpp b/third_party/WebKit/Source/platform/fonts/shaping/ShapeResultBuffer.cpp
index a093da6..7eec345a 100644
--- a/third_party/WebKit/Source/platform/fonts/shaping/ShapeResultBuffer.cpp
+++ b/third_party/WebKit/Source/platform/fonts/shaping/ShapeResultBuffer.cpp
@@ -497,4 +497,21 @@
   return fontData;
 }
 
+GlyphData ShapeResultBuffer::emphasisMarkGlyphData(
+    const FontDescription& fontDescription) const {
+  for (const auto& result : m_results) {
+    for (const auto& run : result->m_runs) {
+      DCHECK(run->m_fontData);
+      if (run->m_glyphData.isEmpty())
+        continue;
+
+      return GlyphData(
+          run->m_glyphData[0].glyph,
+          run->m_fontData->emphasisMarkFontData(fontDescription).get());
+    }
+  }
+
+  return GlyphData();
+}
+
 }  // namespace blink
diff --git a/third_party/WebKit/Source/platform/fonts/shaping/ShapeResultBuffer.h b/third_party/WebKit/Source/platform/fonts/shaping/ShapeResultBuffer.h
index fb94c45..7a99ead 100644
--- a/third_party/WebKit/Source/platform/fonts/shaping/ShapeResultBuffer.h
+++ b/third_party/WebKit/Source/platform/fonts/shaping/ShapeResultBuffer.h
@@ -15,6 +15,7 @@
 namespace blink {
 
 struct CharacterRange;
+class FontDescription;
 class GlyphBuffer;
 struct GlyphData;
 class TextRun;
@@ -65,6 +66,8 @@
 
   Vector<RunFontData> runFontData() const;
 
+  GlyphData emphasisMarkGlyphData(const FontDescription&) const;
+
  private:
   static CharacterRange getCharacterRangeInternal(
       const Vector<RefPtr<const ShapeResult>, 64>&,
diff --git a/third_party/WebKit/Source/web/WebRuntimeFeatures.cpp b/third_party/WebKit/Source/web/WebRuntimeFeatures.cpp
index 8fc301e..501ab3b 100644
--- a/third_party/WebKit/Source/web/WebRuntimeFeatures.cpp
+++ b/third_party/WebKit/Source/web/WebRuntimeFeatures.cpp
@@ -392,4 +392,8 @@
   RuntimeEnabledFeatures::setVideoFullscreenOrientationLockEnabled(enable);
 }
 
+void WebRuntimeFeatures::enableMediaControlsOverlayPlayButton(bool enable) {
+  RuntimeEnabledFeatures::setMediaControlsOverlayPlayButtonEnabled(enable);
+}
+
 }  // namespace blink
diff --git a/third_party/WebKit/Source/web/WebSettingsImpl.cpp b/third_party/WebKit/Source/web/WebSettingsImpl.cpp
index ff5ac4d2..30777b980 100644
--- a/third_party/WebKit/Source/web/WebSettingsImpl.cpp
+++ b/third_party/WebKit/Source/web/WebSettingsImpl.cpp
@@ -621,10 +621,6 @@
   m_settings->setShouldRespectImageOrientation(enabled);
 }
 
-void WebSettingsImpl::setMediaControlsOverlayPlayButtonEnabled(bool enabled) {
-  m_settings->setMediaControlsOverlayPlayButtonEnabled(enabled);
-}
-
 void WebSettingsImpl::setMediaPlaybackRequiresUserGesture(bool required) {
   m_settings->setMediaPlaybackRequiresUserGesture(required);
 }
diff --git a/third_party/WebKit/Source/web/WebSettingsImpl.h b/third_party/WebKit/Source/web/WebSettingsImpl.h
index 95178e0..4508d26 100644
--- a/third_party/WebKit/Source/web/WebSettingsImpl.h
+++ b/third_party/WebKit/Source/web/WebSettingsImpl.h
@@ -120,7 +120,6 @@
   void setMainFrameClipsContent(bool) override;
   void setMainFrameResizesAreOrientationChanges(bool) override;
   void setMaxTouchPoints(int) override;
-  void setMediaControlsOverlayPlayButtonEnabled(bool) override;
   void setMediaPlaybackRequiresUserGesture(bool) override;
   void setMediaPlaybackGestureWhitelistScope(const WebString&) override;
   void setPresentationRequiresUserGesture(bool) override;
diff --git a/third_party/WebKit/public/web/WebRuntimeFeatures.h b/third_party/WebKit/public/web/WebRuntimeFeatures.h
index c1188d3b..9e685b5b 100644
--- a/third_party/WebKit/public/web/WebRuntimeFeatures.h
+++ b/third_party/WebKit/public/web/WebRuntimeFeatures.h
@@ -146,6 +146,7 @@
   BLINK_EXPORT static void enableSendBeaconThrowForBlobWithNonSimpleType(bool);
   BLINK_EXPORT static void enableBackgroundVideoTrackOptimization(bool);
   BLINK_EXPORT static void enableVideoFullscreenOrientationLock(bool);
+  BLINK_EXPORT static void enableMediaControlsOverlayPlayButton(bool);
 
  private:
   WebRuntimeFeatures();
diff --git a/third_party/WebKit/public/web/WebSettings.h b/third_party/WebKit/public/web/WebSettings.h
index 70fe7252..9d9aaaff 100644
--- a/third_party/WebKit/public/web/WebSettings.h
+++ b/third_party/WebKit/public/web/WebSettings.h
@@ -198,7 +198,6 @@
   virtual void setMainFrameClipsContent(bool) = 0;
   virtual void setMainFrameResizesAreOrientationChanges(bool) = 0;
   virtual void setMaxTouchPoints(int) = 0;
-  virtual void setMediaControlsOverlayPlayButtonEnabled(bool) = 0;
   virtual void setMediaPlaybackRequiresUserGesture(bool) = 0;
   virtual void setMediaPlaybackGestureWhitelistScope(const WebString&) = 0;
   virtual void setPresentationRequiresUserGesture(bool) = 0;