diff --git a/DEPS b/DEPS
index 02e1ec81..645ed689 100644
--- a/DEPS
+++ b/DEPS
@@ -307,7 +307,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling V8
   # and whatever else without interference from each other.
-  'v8_revision': '34248965c12fc846f437770c1a7557e8fabfccd1',
+  'v8_revision': '1264bda1a83fa9dda7db289719d3ba8f0276df89',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling ANGLE
   # and whatever else without interference from each other.
@@ -394,7 +394,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling devtools-frontend
   # and whatever else without interference from each other.
-  'devtools_frontend_revision': '537237ced590b359b9a213bd44ef5b46107d4371',
+  'devtools_frontend_revision': '5c380622f2ea4f74da1623ff2e3f1503f35df1a9',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling libprotobuf-mutator
   # and whatever else without interference from each other.
@@ -418,7 +418,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling feed
   # and whatever else without interference from each other.
-  'dawn_revision': '10aa8bc80bbfef2650adbd4643a007e3efb7708c',
+  'dawn_revision': '02ba88d8c9492dd40a80a46b0ace3bd71377a7a8',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling feed
   # and whatever else without interference from each other.
@@ -818,7 +818,7 @@
 
   'src/clank': {
     'url': Var('chrome_git') + '/clank/internal/apps.git' + '@' +
-    'e1531b3b46bc2d38f1b94d016561b6a322ab764e',
+    '7cfeed2a7b1c9e62c903cc0ccedee4c80068ee2c',
     'condition': 'checkout_android and checkout_src_internal',
   },
 
@@ -1155,7 +1155,7 @@
   # Tools used when building Chrome for Chrome OS. This affects both the Simple
   # Chrome workflow, as well as the chromeos-chrome ebuild.
   'src/third_party/chromite': {
-      'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + 'b101b80fdca8f9a23fa6334cdd1c537b00387b5c',
+      'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + 'c1b9dd4348b384091d021830783be93c1f8f966b',
       'condition': 'checkout_chromeos',
   },
 
@@ -1196,7 +1196,7 @@
     Var('chromium_git') + '/devtools/devtools-frontend' + '@' + Var('devtools_frontend_revision'),
 
   'src/third_party/devtools-frontend-internal': {
-      'url': Var('chrome_git') + '/devtools/devtools-internal.git' + '@' + '9384327dc44ffdc6a5b98783c7614efa75f753ed',
+      'url': Var('chrome_git') + '/devtools/devtools-internal.git' + '@' + 'afdc318b8a2bb8432f1cd082b6b757d58db8e6b5',
     'condition': 'checkout_src_internal',
   },
 
@@ -1841,7 +1841,7 @@
     Var('chromium_git') + '/external/github.com/gpuweb/cts.git' + '@' + 'f20c5f7b8f53904edaa98651d764e1b8305d7c14',
 
   'src/third_party/webrtc':
-    Var('webrtc_git') + '/src.git' + '@' + 'f40443424ea57e794be5e43abc2d8d8f6b7c50b9',
+    Var('webrtc_git') + '/src.git' + '@' + 'd2771c615300866bd0af7d9858b2bf3d48ee9b52',
 
   # Wuffs' canonical repository is at github.com/google/wuffs, but we use
   # Skia's mirror of Wuffs, the same as in upstream Skia's DEPS file.
@@ -1964,7 +1964,7 @@
     'packages': [
       {
         'package': 'chromeos_internal/apps/help_app/app',
-        'version': 'CW27fTSHvRgStZUViK8yKE3FsVCJ4-PlWF8QDdPRUa8C',
+        'version': 'aizdG4iOsGzg1IZfczJxGPyQl8ukEfmaUt3ilSm-7oAC',
       },
     ],
     'condition': 'checkout_chromeos and checkout_src_internal',
@@ -1975,7 +1975,7 @@
     'packages': [
       {
         'package': 'chromeos_internal/apps/media_app/app',
-        'version': 'aTTGvs9hXU5D6I_x64Q5O5avIbAiEWTYfF2pmynh1LQC',
+        'version': '_FrRNH6EvjqO825QuIq2KHIKtIjNMVSkr__PWQStlowC',
       },
     ],
     'condition': 'checkout_chromeos and checkout_src_internal',
@@ -2008,7 +2008,7 @@
     'packages': [
       {
         'package': 'chromeos_internal/apps/projector_app/app',
-        'version': 'Qj7oH5oiJpI9VXefFnB5hiaUKl5_MoXngy6P6Z3c2BQC',
+        'version': 'bUluwhSItRA8oErY7u8EsEn3DhvHiGYygUlw6iZDNAIC',
       },
     ],
     'condition': 'checkout_chromeos and checkout_src_internal',
@@ -4004,7 +4004,7 @@
 
   'src/ios_internal':  {
       'url': Var('chrome_git') + '/chrome/ios_internal.git' + '@' +
-        '1b070c09e79ffad05461f8b098c6ba2cf2ae332d',
+        'cbb1ed74556755d1ddbf1ce8919f333d6dfddb2a',
       'condition': 'checkout_ios and checkout_src_internal',
   },
 
diff --git a/build/config/compiler/BUILD.gn b/build/config/compiler/BUILD.gn
index 9256464..8843b3a 100644
--- a/build/config/compiler/BUILD.gn
+++ b/build/config/compiler/BUILD.gn
@@ -1879,6 +1879,13 @@
           # TODO(https://crbug.com/1490607): Fix and re-enable.
           "-Wno-thread-safety-reference-return",
         ]
+
+        if (llvm_force_head_revision) {
+          cflags_cc += [
+            # TODO(https://crbug.com/1513724): Fix and re-enable.
+            "-Wno-c++11-narrowing-const-reference",
+          ]
+        }
       }
     }
 
diff --git a/chrome/VERSION b/chrome/VERSION
index 56d0568..8afaaf4 100644
--- a/chrome/VERSION
+++ b/chrome/VERSION
@@ -1,4 +1,4 @@
 MAJOR=122
 MINOR=0
-BUILD=6216
+BUILD=6219
 PATCH=0
diff --git a/chrome/android/profiles/arm.newest.txt b/chrome/android/profiles/arm.newest.txt
index 59a382c..c56ef3d 100644
--- a/chrome/android/profiles/arm.newest.txt
+++ b/chrome/android/profiles/arm.newest.txt
@@ -1 +1 @@
-chromeos-chrome-arm-122.0.6213.0_rc-r1-merged.afdo.bz2
+chromeos-chrome-arm-122.0.6217.0_rc-r1-merged.afdo.bz2
diff --git a/chrome/android/profiles/newest.txt b/chrome/android/profiles/newest.txt
index 6f38a23..c2a88430 100644
--- a/chrome/android/profiles/newest.txt
+++ b/chrome/android/profiles/newest.txt
@@ -1 +1 @@
-chromeos-chrome-amd64-122.0.6213.0_rc-r1-merged.afdo.bz2
+chromeos-chrome-amd64-122.0.6217.0_rc-r1-merged.afdo.bz2
diff --git a/chrome/browser/ui/views/permissions/embedded_permission_prompt_base_view.cc b/chrome/browser/ui/views/permissions/embedded_permission_prompt_base_view.cc
index 9581b3da..7279718b 100644
--- a/chrome/browser/ui/views/permissions/embedded_permission_prompt_base_view.cc
+++ b/chrome/browser/ui/views/permissions/embedded_permission_prompt_base_view.cc
@@ -12,10 +12,13 @@
 #include "chrome/browser/ui/views/chrome_layout_provider.h"
 #include "chrome/browser/ui/views/chrome_widget_sublevel.h"
 #include "chrome/browser/ui/views/frame/browser_view.h"
+#include "components/vector_icons/vector_icons.h"
 #include "ui/base/interaction/element_identifier.h"
+#include "ui/base/l10n/l10n_util.h"
 #include "ui/base/metadata/metadata_impl_macros.h"
 #include "ui/base/models/image_model.h"
 #include "ui/base/ui_base_features.h"
+#include "ui/gfx/paint_vector_icon.h"
 #include "ui/views/bubble/bubble_frame_view.h"
 #include "ui/views/controls/button/md_text_button.h"
 #include "ui/views/controls/label.h"
@@ -36,6 +39,8 @@
 
 constexpr int BODY_TOP_MARGIN = 10;
 constexpr int DISTANCE_BUTTON_VERTICAL = 8;
+constexpr int FAVICON_SIZE_IN_PIXEL = 28;
+constexpr int FAVICON_SPACER = 5;
 
 void AddElementIdentifierToLabel(views::Label& label, size_t index) {
   ui::ElementIdentifier id;
@@ -72,6 +77,10 @@
   ShowWidget();
 }
 
+const gfx::VectorIcon& EmbeddedPermissionPromptBaseView::GetIcon() const {
+  return gfx::kNoneIcon;
+}
+
 void EmbeddedPermissionPromptBaseView::CreateWidget() {
   DCHECK(browser_->window());
   views::Widget* widget = views::BubbleDialogDelegateView::CreateBubble(this);
@@ -87,7 +96,22 @@
   }
 
   auto title_container = std::make_unique<views::FlexLayoutView>();
-  title_container->SetOrientation(views::LayoutOrientation::kVertical);
+  title_container->SetOrientation(views::LayoutOrientation::kHorizontal);
+
+  const gfx::VectorIcon& vector_icon = GetIcon();
+
+  if (!vector_icon.is_empty()) {
+    auto icon =
+        std::make_unique<views::ImageView>(ui::ImageModel::FromVectorIcon(
+            vector_icon, ui::kColorIcon, FAVICON_SIZE_IN_PIXEL));
+    icon->SetHorizontalAlignment(views::ImageView::Alignment::kLeading);
+    title_container->AddChildView(std::move(icon));
+
+    // Add space between the icon and the text.
+    auto spacer = std::make_unique<views::View>();
+    spacer->SetPreferredSize(gfx::Size(FAVICON_SPACER, /*height=*/1));
+    title_container->AddChildView(std::move(spacer));
+  }
 
   auto label = std::make_unique<views::Label>(
       GetWindowTitle(), views::style::CONTEXT_DIALOG_BODY_TEXT);
diff --git a/chrome/browser/ui/views/permissions/embedded_permission_prompt_base_view.h b/chrome/browser/ui/views/permissions/embedded_permission_prompt_base_view.h
index f69ca66..233f25b 100644
--- a/chrome/browser/ui/views/permissions/embedded_permission_prompt_base_view.h
+++ b/chrome/browser/ui/views/permissions/embedded_permission_prompt_base_view.h
@@ -102,6 +102,7 @@
   virtual std::vector<RequestLineConfiguration> GetRequestLinesConfiguration()
       const = 0;
   virtual std::vector<ButtonConfiguration> GetButtonsConfiguration() const = 0;
+  const virtual gfx::VectorIcon& GetIcon() const;
 
   base::WeakPtr<EmbeddedPermissionPromptViewDelegate>& delegate() {
     return delegate_;
diff --git a/chrome/browser/ui/views/permissions/embedded_permission_prompt_policy_view.cc b/chrome/browser/ui/views/permissions/embedded_permission_prompt_policy_view.cc
index 31c9296..7a9d738 100644
--- a/chrome/browser/ui/views/permissions/embedded_permission_prompt_policy_view.cc
+++ b/chrome/browser/ui/views/permissions/embedded_permission_prompt_policy_view.cc
@@ -8,6 +8,7 @@
 #include "components/strings/grit/components_strings.h"
 #include "components/vector_icons/vector_icons.h"
 #include "ui/base/l10n/l10n_util.h"
+#include "ui/gfx/paint_vector_icon.h"
 
 EmbeddedPermissionPromptPolicyView::EmbeddedPermissionPromptPolicyView(
     Browser* browser,
@@ -21,39 +22,10 @@
 
 std::u16string EmbeddedPermissionPromptPolicyView::GetAccessibleWindowTitle()
     const {
-  return GetMessageText();
+  return GetWindowTitle();
 }
 
 std::u16string EmbeddedPermissionPromptPolicyView::GetWindowTitle() const {
-  return std::u16string();
-}
-
-void EmbeddedPermissionPromptPolicyView::RunButtonCallback(int button_id) {
-  ButtonType button = GetButtonType(button_id);
-  DCHECK_EQ(button, ButtonType::kPolicyOK);
-
-  if (delegate()) {
-    delegate()->Acknowledge();
-  }
-}
-
-std::vector<EmbeddedPermissionPromptPolicyView::RequestLineConfiguration>
-EmbeddedPermissionPromptPolicyView::GetRequestLinesConfiguration() const {
-  std::vector<RequestLineConfiguration> lines;
-  lines.emplace_back(&vector_icons::kBusinessIcon, GetMessageText());
-
-  return lines;
-}
-
-std::vector<EmbeddedPermissionPromptPolicyView::ButtonConfiguration>
-EmbeddedPermissionPromptPolicyView::GetButtonsConfiguration() const {
-  std::vector<ButtonConfiguration> buttons;
-  buttons.emplace_back(l10n_util::GetStringUTF16(IDS_EMBEDDED_PROMPT_OK_LABEL),
-                       ButtonType::kPolicyOK, ui::ButtonStyle::kTonal);
-  return buttons;
-}
-
-std::u16string EmbeddedPermissionPromptPolicyView::GetMessageText() const {
   auto& requests = delegate()->Requests();
   std::u16string permission_name;
   if (requests.size() == 2) {
@@ -69,3 +41,29 @@
   return l10n_util::GetStringFUTF16(template_id, permission_name,
                                     GetUrlIdentityObject().name);
 }
+
+const gfx::VectorIcon& EmbeddedPermissionPromptPolicyView::GetIcon() const {
+  return vector_icons::kBusinessIcon;
+}
+
+void EmbeddedPermissionPromptPolicyView::RunButtonCallback(int button_id) {
+  ButtonType button = GetButtonType(button_id);
+  DCHECK_EQ(button, ButtonType::kPolicyOK);
+
+  if (delegate()) {
+    delegate()->Acknowledge();
+  }
+}
+
+std::vector<EmbeddedPermissionPromptPolicyView::RequestLineConfiguration>
+EmbeddedPermissionPromptPolicyView::GetRequestLinesConfiguration() const {
+  return {};
+}
+
+std::vector<EmbeddedPermissionPromptPolicyView::ButtonConfiguration>
+EmbeddedPermissionPromptPolicyView::GetButtonsConfiguration() const {
+  std::vector<ButtonConfiguration> buttons;
+  buttons.emplace_back(l10n_util::GetStringUTF16(IDS_EMBEDDED_PROMPT_OK_LABEL),
+                       ButtonType::kPolicyOK, ui::ButtonStyle::kTonal);
+  return buttons;
+}
diff --git a/chrome/browser/ui/views/permissions/embedded_permission_prompt_policy_view.h b/chrome/browser/ui/views/permissions/embedded_permission_prompt_policy_view.h
index 591a70c..7ac39a5 100644
--- a/chrome/browser/ui/views/permissions/embedded_permission_prompt_policy_view.h
+++ b/chrome/browser/ui/views/permissions/embedded_permission_prompt_policy_view.h
@@ -28,6 +28,7 @@
 
   std::u16string GetAccessibleWindowTitle() const override;
   std::u16string GetWindowTitle() const override;
+  const gfx::VectorIcon& GetIcon() const override;
   void RunButtonCallback(int type) override;
 
  protected:
@@ -36,8 +37,6 @@
   std::vector<ButtonConfiguration> GetButtonsConfiguration() const override;
 
  private:
-  std::u16string GetMessageText() const;
-
   // Whether the administrator has "allowed" or "blocked" the particular
   // permission that this prompt is for.
   bool is_permission_allowed_;
diff --git a/chrome/build/android-arm32.pgo.txt b/chrome/build/android-arm32.pgo.txt
index e65f838..96bcae4 100644
--- a/chrome/build/android-arm32.pgo.txt
+++ b/chrome/build/android-arm32.pgo.txt
@@ -1 +1 @@
-chrome-android32-main-1703872780-03ec59eaa790e07f8a6d1dac6f824c679684b915.profdata
+chrome-android32-main-1704002158-1dc8088a53f3f950793aa209c59a049ed672acdf.profdata
diff --git a/chrome/build/android-arm64.pgo.txt b/chrome/build/android-arm64.pgo.txt
index 7f99d9b2..2edbf8c 100644
--- a/chrome/build/android-arm64.pgo.txt
+++ b/chrome/build/android-arm64.pgo.txt
@@ -1 +1 @@
-chrome-android64-main-1703872780-c70b339d48f47f750bb6c45bc84e9970c53602ee.profdata
+chrome-android64-main-1704002158-93f49f8f8790f1b3d073cffc1b3ee59b5cdb1c21.profdata
diff --git a/chrome/build/lacros-arm64.pgo.txt b/chrome/build/lacros-arm64.pgo.txt
index 076b1783..c5e467546 100644
--- a/chrome/build/lacros-arm64.pgo.txt
+++ b/chrome/build/lacros-arm64.pgo.txt
@@ -1 +1 @@
-chrome-chromeos-arm64-generic-main-1703851390-7f26095ece69d641fe82952cbf68aefbe0b17423.profdata
+chrome-chromeos-arm64-generic-main-1703979986-b657a93ed05098a36f0a2d5032cd43f449a347a6.profdata
diff --git a/chrome/build/linux.pgo.txt b/chrome/build/linux.pgo.txt
index 7d55ed4..2f5f8646a 100644
--- a/chrome/build/linux.pgo.txt
+++ b/chrome/build/linux.pgo.txt
@@ -1 +1 @@
-chrome-linux-main-1703872780-fec5052cf17e84aaacb545cf9195ac16ef20eb1a.profdata
+chrome-linux-main-1704002158-9bd112145316e8c8eb0e34bb693001e3fe5c59f5.profdata
diff --git a/chrome/build/win-arm64.pgo.txt b/chrome/build/win-arm64.pgo.txt
index 7fe0eff..3935df02 100644
--- a/chrome/build/win-arm64.pgo.txt
+++ b/chrome/build/win-arm64.pgo.txt
@@ -1 +1 @@
-chrome-win-arm64-main-1703872780-c36ed3d3bf154a099aea64c08fe9700c27d3405c.profdata
+chrome-win-arm64-main-1704002158-d2dd107ad7528b9d953f97210d5f556f0fa9fff1.profdata
diff --git a/chrome/build/win32.pgo.txt b/chrome/build/win32.pgo.txt
index a75b9bb..fa95d64e 100644
--- a/chrome/build/win32.pgo.txt
+++ b/chrome/build/win32.pgo.txt
@@ -1 +1 @@
-chrome-win32-main-1703882975-a90211d78d19d6694d5a55704adcac09936806e9.profdata
+chrome-win32-main-1704002158-ea700f57c86ca0f3eda3400d37695ad9ec7843e0.profdata
diff --git a/chrome/build/win64.pgo.txt b/chrome/build/win64.pgo.txt
index b3dc2d2..08b48de 100644
--- a/chrome/build/win64.pgo.txt
+++ b/chrome/build/win64.pgo.txt
@@ -1 +1 @@
-chrome-win64-main-1703882975-074d85d685e9cef9c5b021840c9ef1bdc4b43fae.profdata
+chrome-win64-main-1704002158-63f0de10fd933dc4e47c73487d0c2a5c119aa886.profdata
diff --git a/chromeos/profiles/arm.afdo.newest.txt b/chromeos/profiles/arm.afdo.newest.txt
index 88d95ed..e699101 100644
--- a/chromeos/profiles/arm.afdo.newest.txt
+++ b/chromeos/profiles/arm.afdo.newest.txt
@@ -1 +1 @@
-chromeos-chrome-arm-none-122-6167.14-1703508819-benchmark-122.0.6213.0-r1-redacted.afdo.xz
+chromeos-chrome-arm-none-122-6167.14-1703508819-benchmark-122.0.6215.0-r1-redacted.afdo.xz
diff --git a/chromeos/profiles/atom.afdo.newest.txt b/chromeos/profiles/atom.afdo.newest.txt
index 5676f1d..420d682 100644
--- a/chromeos/profiles/atom.afdo.newest.txt
+++ b/chromeos/profiles/atom.afdo.newest.txt
@@ -1 +1 @@
-chromeos-chrome-amd64-atom-122-6167.14-1703504610-benchmark-122.0.6213.0-r1-redacted.afdo.xz
+chromeos-chrome-amd64-atom-122-6167.14-1703504610-benchmark-122.0.6216.0-r1-redacted.afdo.xz
diff --git a/clank b/clank
index e1531b3..7cfeed2 160000
--- a/clank
+++ b/clank
@@ -1 +1 @@
-Subproject commit e1531b3b46bc2d38f1b94d016561b6a322ab764e
+Subproject commit 7cfeed2a7b1c9e62c903cc0ccedee4c80068ee2c
diff --git a/components/exo/buffer.cc b/components/exo/buffer.cc
index d588fcf..a45f39f 100644
--- a/components/exo/buffer.cc
+++ b/components/exo/buffer.cc
@@ -847,6 +847,10 @@
 }
 #endif  // BUILDFLAG(USE_ARC_PROTECTED_MEDIA)
 
+base::WeakPtr<Buffer> Buffer::AsWeakPtr() {
+  return weak_ptr_factory_.GetWeakPtr();
+}
+
 SolidColorBuffer::SolidColorBuffer(const SkColor4f& color,
                                    const gfx::Size& size)
     : Buffer(nullptr), color_(color), size_(size) {}
@@ -876,4 +880,8 @@
   return size_;
 }
 
+base::WeakPtr<Buffer> SolidColorBuffer::AsWeakPtr() {
+  return weak_ptr_factory_.GetWeakPtr();
+}
+
 }  // namespace exo
diff --git a/components/exo/buffer.h b/components/exo/buffer.h
index 2f2aea2..397f318 100644
--- a/components/exo/buffer.h
+++ b/components/exo/buffer.h
@@ -30,7 +30,7 @@
 // This class provides the content for a Surface. The mechanism by which a
 // client provides and updates the contents is the responsibility of the client
 // and not defined as part of this class.
-class Buffer : public base::SupportsWeakPtr<Buffer> {
+class Buffer {
  public:
   explicit Buffer(std::unique_ptr<gfx::GpuMemoryBuffer> gpu_memory_buffer);
   Buffer(std::unique_ptr<gfx::GpuMemoryBuffer> gpu_memory_buffer,
@@ -105,6 +105,8 @@
     wait_for_release_delay_ = wait_for_release_delay;
   }
 
+  virtual base::WeakPtr<Buffer> AsWeakPtr();
+
  private:
   class Texture;
 
@@ -224,6 +226,8 @@
 #if BUILDFLAG(USE_ARC_PROTECTED_MEDIA)
   ProtectedBufferState protected_buffer_state_ = ProtectedBufferState::UNKNOWN;
 #endif  // BUILDFLAG(USE_ARC_PROTECTED_MEDIA)
+
+  base::WeakPtrFactory<Buffer> weak_ptr_factory_{this};
 };
 
 class SolidColorBuffer : public Buffer {
@@ -245,9 +249,13 @@
       PerCommitExplicitReleaseCallback per_commit_explicit_release_callback)
       override;
 
+  base::WeakPtr<Buffer> AsWeakPtr() override;
+
  private:
   SkColor4f color_;
   gfx::Size size_;
+
+  base::WeakPtrFactory<SolidColorBuffer> weak_ptr_factory_{this};
 };
 
 }  // namespace exo
diff --git a/content/browser/accessibility/dump_accessibility_tree_browsertest.cc b/content/browser/accessibility/dump_accessibility_tree_browsertest.cc
index 8fb5b41..fe515fe 100644
--- a/content/browser/accessibility/dump_accessibility_tree_browsertest.cc
+++ b/content/browser/accessibility/dump_accessibility_tree_browsertest.cc
@@ -252,16 +252,8 @@
   RunCSSTest(FILE_PATH_LITERAL("display-contents.html"));
 }
 
-// TODO(crbug.com/1367886): De-flake and reenable.
-#if BUILDFLAG(IS_MAC)
-#define MAYBE_AccessibilityCSSDisplayContents \
-  DISABLED_AccessibilityCSSDisplayContents
-#else
-#define MAYBE_AccessibilityCSSDisplayContents \
-  AccessibilityCSSDisplayContents
-#endif
 IN_PROC_BROWSER_TEST_P(YieldingParserDumpAccessibilityTreeTest,
-                       MAYBE_AccessibilityCSSDisplayContents) {
+                       AccessibilityCSSDisplayContents) {
   RunCSSTest(FILE_PATH_LITERAL("display-contents.html"));
 }
 
@@ -3141,10 +3133,12 @@
   RunHtmlTest(FILE_PATH_LITERAL("span.html"));
 }
 
-// TODO(https://crbug.com/1367886): Flaky on asan builder on multiple platforms.
-// This is not fixed by rebuilding the subtree when parsing is complete.
-IN_PROC_BROWSER_TEST_P(DumpAccessibilityTreeTest,
-                       MAYBE_ASAN(AccessibilitySpanLineBreak)) {
+IN_PROC_BROWSER_TEST_P(DumpAccessibilityTreeTest, AccessibilitySpanLineBreak) {
+  RunHtmlTest(FILE_PATH_LITERAL("span-line-break.html"));
+}
+
+IN_PROC_BROWSER_TEST_P(YieldingParserDumpAccessibilityTreeTest,
+                       AccessibilitySpanLineBreak) {
   RunHtmlTest(FILE_PATH_LITERAL("span-line-break.html"));
 }
 
diff --git a/content/test/gpu/gpu_tests/test_expectations/pixel_expectations.txt b/content/test/gpu/gpu_tests/test_expectations/pixel_expectations.txt
index f110f5bd..e9880d0e 100644
--- a/content/test/gpu/gpu_tests/test_expectations/pixel_expectations.txt
+++ b/content/test/gpu/gpu_tests/test_expectations/pixel_expectations.txt
@@ -360,7 +360,6 @@
 # WebGPU interop fails -- pixel color diff
 crbug.com/1395227 [ amd-0x7340 no-clang-coverage release-x64 target-cpu-64 win ] Pixel_WebGPUImportVideoFrameUnaccelerated [ Failure ]
 
-crbug.com/1372144 [ android android-sm-a135m ] Pixel_CanvasDisplaySRGBAccelerated2D [ Failure ]
 crbug.com/1372144 [ android android-sm-a135m ] Pixel_CanvasLowLatencyWebGLAlphaFalse [ Failure ]
 crbug.com/1372141 [ android android-sm-a235m ] Pixel_CanvasLowLatencyWebGLAlphaFalse [ Failure ]
 
diff --git a/ios/google_internal/frameworks/ChromeInternal.framework.dSYM.ios.zip.sha1 b/ios/google_internal/frameworks/ChromeInternal.framework.dSYM.ios.zip.sha1
index 459d026..88b5e88 100644
--- a/ios/google_internal/frameworks/ChromeInternal.framework.dSYM.ios.zip.sha1
+++ b/ios/google_internal/frameworks/ChromeInternal.framework.dSYM.ios.zip.sha1
@@ -1 +1 @@
-172157f789dff862e2e94b2a9760ac20ff27050b
\ No newline at end of file
+948f71f361da485fe7ffed3343c0ffc5362660b5
\ No newline at end of file
diff --git a/ios/google_internal/frameworks/ChromeSSOInternal.framework.dSYM.ios.zip.sha1 b/ios/google_internal/frameworks/ChromeSSOInternal.framework.dSYM.ios.zip.sha1
index ca89720..630a2f0 100644
--- a/ios/google_internal/frameworks/ChromeSSOInternal.framework.dSYM.ios.zip.sha1
+++ b/ios/google_internal/frameworks/ChromeSSOInternal.framework.dSYM.ios.zip.sha1
@@ -1 +1 @@
-7cea44686597875e11cea163697863daaa39eb22
\ No newline at end of file
+18804b8ad2dabc8843f13877e850f7118b8bac64
\ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_internal_dynamic_framework.ios.zip.sha1 b/ios/google_internal/frameworks/chrome_internal_dynamic_framework.ios.zip.sha1
index c31cf76..cdec14a 100644
--- a/ios/google_internal/frameworks/chrome_internal_dynamic_framework.ios.zip.sha1
+++ b/ios/google_internal/frameworks/chrome_internal_dynamic_framework.ios.zip.sha1
@@ -1 +1 @@
-b48bbb9c30472203000c831923ac9214024b5ab5
\ No newline at end of file
+a6a9c13748c4629089fe840c6987e229b1b1be4d
\ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_internal_dynamic_framework.iossimulator.zip.sha1 b/ios/google_internal/frameworks/chrome_internal_dynamic_framework.iossimulator.zip.sha1
index 5c6de1f..bbbc37bfd 100644
--- a/ios/google_internal/frameworks/chrome_internal_dynamic_framework.iossimulator.zip.sha1
+++ b/ios/google_internal/frameworks/chrome_internal_dynamic_framework.iossimulator.zip.sha1
@@ -1 +1 @@
-453090452495c7c5f5a6590aa80eee9773b491f1
\ No newline at end of file
+7d4369e265d3378987fa30c57706fc2083c4672e
\ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.ios.zip.sha1 b/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.ios.zip.sha1
index 1b5a1da..c680f1d 100644
--- a/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.ios.zip.sha1
+++ b/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.ios.zip.sha1
@@ -1 +1 @@
-1dbd47fa98a22ad9810300450acea38a3fdc0b72
\ No newline at end of file
+4c8bcd6052bf1c43c875542654890d67b201eccb
\ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.iossimulator.zip.sha1 b/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.iossimulator.zip.sha1
index 72df7aa..fbfe08e1 100644
--- a/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.iossimulator.zip.sha1
+++ b/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.iossimulator.zip.sha1
@@ -1 +1 @@
-43085eb280c7bd6872efcbe7e1fb3cfd2da2a826
\ No newline at end of file
+5e61d7c703a5f51e0cd9385d54b4b5426dc586fe
\ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_test_internal_dynamic_framework.ios.zip.sha1 b/ios/google_internal/frameworks/chrome_test_internal_dynamic_framework.ios.zip.sha1
index ab36f495..5e7f31d 100644
--- a/ios/google_internal/frameworks/chrome_test_internal_dynamic_framework.ios.zip.sha1
+++ b/ios/google_internal/frameworks/chrome_test_internal_dynamic_framework.ios.zip.sha1
@@ -1 +1 @@
-bb0e02ecad6eb7d840f207ce0d2fc26c828df809
\ No newline at end of file
+4c213a22f3d532d57a666aee850788718478620e
\ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_test_internal_dynamic_framework.iossimulator.zip.sha1 b/ios/google_internal/frameworks/chrome_test_internal_dynamic_framework.iossimulator.zip.sha1
index f8b53f40..6e45b26 100644
--- a/ios/google_internal/frameworks/chrome_test_internal_dynamic_framework.iossimulator.zip.sha1
+++ b/ios/google_internal/frameworks/chrome_test_internal_dynamic_framework.iossimulator.zip.sha1
@@ -1 +1 @@
-1862307a4f573dd64376362730391a9b94188348
\ No newline at end of file
+2a9e57e99f59b2341d73a308415e1796c61a2ead
\ No newline at end of file
diff --git a/ios/google_internal/frameworks/remoting_internal_dynamic_framework.ios.zip.sha1 b/ios/google_internal/frameworks/remoting_internal_dynamic_framework.ios.zip.sha1
index 0d5d0ec..7b206f3 100644
--- a/ios/google_internal/frameworks/remoting_internal_dynamic_framework.ios.zip.sha1
+++ b/ios/google_internal/frameworks/remoting_internal_dynamic_framework.ios.zip.sha1
@@ -1 +1 @@
-a40b9a981f457c7c9583f2ddd4aaf3d12cb742aa
\ No newline at end of file
+ad0dcd9358a177ed0a0d4051eb06b33750d1324d
\ No newline at end of file
diff --git a/ios/google_internal/frameworks/remoting_internal_dynamic_framework.iossimulator.zip.sha1 b/ios/google_internal/frameworks/remoting_internal_dynamic_framework.iossimulator.zip.sha1
index 2d128922..aff8b60e 100644
--- a/ios/google_internal/frameworks/remoting_internal_dynamic_framework.iossimulator.zip.sha1
+++ b/ios/google_internal/frameworks/remoting_internal_dynamic_framework.iossimulator.zip.sha1
@@ -1 +1 @@
-a784e47975a5092be8fe7a787fdd2d5c0b38e044
\ No newline at end of file
+dc9b3b0943e2feb89b0174532aadabdec69207e3
\ No newline at end of file
diff --git a/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.ios.zip.sha1 b/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.ios.zip.sha1
index 0a0f611..24578de1 100644
--- a/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.ios.zip.sha1
+++ b/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.ios.zip.sha1
@@ -1 +1 @@
-530280348b24db1f6c71d0f15c8458024eac4ed2
\ No newline at end of file
+2178e7cc93f83a78dd0bc58e4e0a1a8fd6a8ad10
\ No newline at end of file
diff --git a/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.iossimulator.zip.sha1 b/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.iossimulator.zip.sha1
index 342fa433..9740a50f 100644
--- a/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.iossimulator.zip.sha1
+++ b/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.iossimulator.zip.sha1
@@ -1 +1 @@
-7f95b256f3b74298e30027c0ce043586621520b3
\ No newline at end of file
+88c8aea968e7c4f1146f1a1955aa8f353ee6cb08
\ No newline at end of file
diff --git a/ios_internal b/ios_internal
index 1b070c0..cbb1ed7 160000
--- a/ios_internal
+++ b/ios_internal
@@ -1 +1 @@
-Subproject commit 1b070c09e79ffad05461f8b098c6ba2cf2ae332d
+Subproject commit cbb1ed74556755d1ddbf1ce8919f333d6dfddb2a
diff --git a/net/http/transport_security_state_static.pins b/net/http/transport_security_state_static.pins
index 68cdf115..f303d873 100644
--- a/net/http/transport_security_state_static.pins
+++ b/net/http/transport_security_state_static.pins
@@ -43,9 +43,9 @@
 #   hash function for preloaded entries again (we have already done so once).
 #
 
-# Last updated: 2023-12-28 12:57 UTC
+# Last updated: 2023-12-30 12:56 UTC
 PinsListTimestamp
-1703768232
+1703940966
 
 TestSPKI
 sha256/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=
diff --git a/net/http/transport_security_state_static_pins.json b/net/http/transport_security_state_static_pins.json
index 9f0994ca..3c19bb91 100644
--- a/net/http/transport_security_state_static_pins.json
+++ b/net/http/transport_security_state_static_pins.json
@@ -31,7 +31,7 @@
 // the 'static_spki_hashes' and 'bad_static_spki_hashes' fields in 'pinsets'
 // refer to, and the timestamp at which the pins list was last updated.
 //
-// Last updated: 2023-12-28 12:57 UTC
+// Last updated: 2023-12-30 12:56 UTC
 //
 {
   "pinsets": [
diff --git a/third_party/blink/web_tests/TestExpectations b/third_party/blink/web_tests/TestExpectations
index 802bd22..48560ff 100644
--- a/third_party/blink/web_tests/TestExpectations
+++ b/third_party/blink/web_tests/TestExpectations
@@ -2872,7 +2872,7 @@
 crbug.com/626703 virtual/scalefactor200/external/wpt/css/filter-effects/filter-function/filter-function-repeating-conic-gradient.html [ Failure ]
 crbug.com/626703 virtual/scalefactor200/external/wpt/css/filter-effects/filter-function/filter-function-repeating-linear-gradient.html [ Failure ]
 crbug.com/626703 virtual/scalefactor200/external/wpt/css/filter-effects/filter-function/filter-function-repeating-radial-gradient.html [ Failure ]
-crbug.com/626703 virtual/composite-clip-path-animation/external/wpt/css/css-masking/clip-path/animations/clip-path-xywh-interpolation-001.html [ Failure ]
+crbug.com/626703 [ Debug Mac13-arm64 ] virtual/composite-clip-path-animation/external/wpt/css/css-masking/clip-path/animations/clip-path-xywh-interpolation-001.html [ Failure ]
 crbug.com/626703 external/wpt/editing/crashtests/insertparagraph-in-listitem-in-svg-followed-by-collapsible-spaces.html [ Timeout ]
 crbug.com/626703 [ Mac10.15 ] external/wpt/workers/modules/shared-worker-import-failure.html [ Failure Timeout ]
 crbug.com/626703 [ Mac11 ] external/wpt/fetch/api/cors/cors-keepalive.any.html [ Skip Timeout ]
diff --git a/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_8.json b/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_8.json
index b5fb595..57cab1b 100644
--- a/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_8.json
+++ b/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_8.json
@@ -346089,6 +346089,14 @@
        "627ebc074bf4306cd2d40e5462e35ee1fc036dd7",
        []
       ],
+      "part-dir-expected.txt": [
+       "e209599ec36f462612e7866d423707a2f4f36a7a",
+       []
+      ],
+      "part-lang-expected.txt": [
+       "cd470fb200eaeda5525c18177749e5383b514a75",
+       []
+      ],
       "part-pseudo-ref.html": [
        "aeb724778a78e17b7144c4b7618d49d17ee1e54b",
        []
@@ -346096,6 +346104,10 @@
       "sheet-going-away-002-ref.html": [
        "67841617736730e588f5659fd485fb09a159bd33",
        []
+      ],
+      "state-in-has-expected.txt": [
+       "97c90323f5d849ebd66ce4c5b7379bdbb69fac66",
+       []
       ]
      },
      "is-where-error-recovery-expected.txt": [
@@ -443809,7 +443821,7 @@
      },
      "content-visibility": {
       "animation-display-lock.html": [
-       "7960ba0f59dbaa5f9ce8a7f23b05111d9731c4ed",
+       "0a03768fc358dfc8169f1c91e6ac4935ea5cd6cb",
        [
         null,
         {}
@@ -474872,6 +474884,20 @@
         {}
        ]
       ],
+      "part-dir.html": [
+       "6672d267be3dfd97430a5f5eb63bac2c0e1a48d9",
+       [
+        null,
+        {}
+       ]
+      ],
+      "part-lang.html": [
+       "438098b8ef5b1867261235b21816ed073e091d91",
+       [
+        null,
+        {}
+       ]
+      ],
       "placeholder-shown.html": [
        "71233ed2a28c46930c6e56755676404fa6aaa9f3",
        [
@@ -474907,6 +474933,13 @@
         {}
        ]
       ],
+      "state-in-has.html": [
+       "15dec18feb59392a4e8c5e22224addca1701b92d",
+       [
+        null,
+        {}
+       ]
+      ],
       "subject-has-invalidation-with-display-none-anchor-element.html": [
        "6c87560c691c7ee21f613b531e0209600939e495",
        [
@@ -568872,7 +568905,7 @@
         ]
        ],
        "range.html": [
-        "093c60ba577816355f7934a418d103c6057fc920",
+        "27cc6abe9c1221f66bacb2cebebce08c839f85a2",
         [
          null,
          {}
diff --git a/third_party/blink/web_tests/external/wpt/css/css-contain/content-visibility/animation-display-lock.html b/third_party/blink/web_tests/external/wpt/css/css-contain/content-visibility/animation-display-lock.html
index 7960ba0f5..0a03768 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-contain/content-visibility/animation-display-lock.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-contain/content-visibility/animation-display-lock.html
@@ -52,6 +52,10 @@
   return target;
 }
 
+function waitForEvent(element, eventName) {
+  return new Promise(resolve => element.addEventListener(eventName, resolve, { once: true }));
+}
+
 promise_test(async t => {
   const container = document.getElementById('container');
   const target = createAnimatingElement(t, 'animate');
@@ -73,7 +77,7 @@
                'Animation events do not fire while the animation is ' +
                'running in a display locked subtree');
   container.style.contentVisibility = 'visible';
-  await waitForAnimationFrames(2);
+  await waitForEvent(target, 'animationiteration');
   assert_true(animationIterationEvent,
               'The animationiteration event fires once the animation is ' +
               'no longer display locked');
@@ -171,7 +175,7 @@
 
   animation.currentTime = 1999;
   await animation.ready;
-  await waitForAnimationFrames(2);
+  await waitForEvent(animation, 'finish');
 
   assert_true(animationFinishEvent,
               'Animation event not blocked on display locked subtree if ' +
diff --git a/third_party/blink/web_tests/external/wpt/css/selectors/invalidation/part-dir-expected.txt b/third_party/blink/web_tests/external/wpt/css/selectors/invalidation/part-dir-expected.txt
new file mode 100644
index 0000000..e209599e
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/selectors/invalidation/part-dir-expected.txt
@@ -0,0 +1,7 @@
+This is a testharness.js-based test.
+[FAIL] ::part():dir() invalidation
+  assert_equals: expected "rgb(0, 255, 0)" but got "rgb(255, 0, 0)"
+[FAIL] ::part():dir() invalidation from setAttribute
+  assert_equals: expected "rgb(0, 255, 0)" but got "rgb(255, 0, 0)"
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/external/wpt/css/selectors/invalidation/part-dir.html b/third_party/blink/web_tests/external/wpt/css/selectors/invalidation/part-dir.html
new file mode 100644
index 0000000..6672d26
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/selectors/invalidation/part-dir.html
@@ -0,0 +1,63 @@
+<!doctype html>
+<title>::part():dir() invalidation</title>
+<link rel="author" title="Keith Cirkel" href="mailto:wpt@keithcirkel.co.uk" />
+<link rel="help" href="https://drafts.csswg.org/css-shadow-parts/#part" />
+<link rel="help" href="https://github.com/whatwg/html/pull/8467" />
+<style>
+  my-element::part(inner) {
+    background-color: #ff0000;
+  }
+  my-element::part(inner):dir(ltr) {
+    background-color: #00ff00;
+  }
+  my-element::part(inner):dir(rtl) {
+    background-color: #0000ff;
+  }
+</style>
+<body>
+  <my-element id="subject"></my-element>
+  <script src="/resources/testharness.js"></script>
+  <script src="/resources/testharnessreport.js"></script>
+  <script>
+    const RED = "rgb(255, 0, 0)";
+    const GREEN = "rgb(0, 255, 0)";
+    const BLUE = "rgb(0, 0, 255)";
+    customElements.define(
+      "my-element",
+      class MyElement extends HTMLElement {
+        connectedCallback() {
+          this.attachShadow({
+            mode: "open",
+          }).innerHTML = `<div part="inner">Test</div>`;
+          this.elementInternals = this.attachInternals();
+        }
+
+        get inner() {
+          return this.shadowRoot.querySelector("[part=inner]");
+        }
+      },
+    );
+
+    test((t) => {
+      t.add_cleanup(() => {
+        subject.inner.lang = null;
+      });
+      assert_equals(getComputedStyle(subject.inner).backgroundColor, GREEN);
+      subject.inner.dir = "rtl";
+      assert_equals(getComputedStyle(subject.inner).backgroundColor, BLUE);
+      subject.inner.dir = "ltr";
+      assert_equals(getComputedStyle(subject.inner).backgroundColor, GREEN);
+    }, "::part():dir() invalidation");
+
+    test((t) => {
+      t.add_cleanup(() => {
+        subject.removeAttribute("dir");
+      });
+      assert_equals(getComputedStyle(subject.inner).backgroundColor, GREEN);
+      subject.inner.setAttribute("dir", "rtl");
+      assert_equals(getComputedStyle(subject.inner).backgroundColor, BLUE);
+      subject.inner.removeAttribute("dir");
+      assert_equals(getComputedStyle(subject.inner).backgroundColor, GREEN);
+    }, "::part():dir() invalidation from setAttribute");
+  </script>
+</body>
diff --git a/third_party/blink/web_tests/external/wpt/css/selectors/invalidation/part-lang-expected.txt b/third_party/blink/web_tests/external/wpt/css/selectors/invalidation/part-lang-expected.txt
new file mode 100644
index 0000000..cd470fb2
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/selectors/invalidation/part-lang-expected.txt
@@ -0,0 +1,7 @@
+This is a testharness.js-based test.
+[FAIL] ::part():lang() invalidation
+  assert_equals: expected "rgb(0, 255, 255)" but got "rgb(255, 0, 0)"
+[FAIL] ::part():lang() invalidation from setAttribute
+  assert_equals: expected "rgb(0, 255, 255)" but got "rgb(255, 0, 0)"
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/external/wpt/css/selectors/invalidation/part-lang.html b/third_party/blink/web_tests/external/wpt/css/selectors/invalidation/part-lang.html
new file mode 100644
index 0000000..438098b
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/selectors/invalidation/part-lang.html
@@ -0,0 +1,73 @@
+<!doctype html>
+<title>::part():lang() invalidation</title>
+<link rel="author" title="Keith Cirkel" href="mailto:wpt@keithcirkel.co.uk" />
+<link rel="help" href="https://drafts.csswg.org/css-shadow-parts/#part" />
+<link rel="help" href="https://github.com/whatwg/html/pull/8467" />
+<style>
+  my-element::part(inner) {
+    background-color: #ff0000;
+  }
+  my-element::part(inner):lang(en) {
+    background-color: #00ffff;
+  }
+  my-element::part(inner):lang(en-GB) {
+    background-color: #00ff00;
+  }
+  my-element::part(inner):lang(fr) {
+    background-color: #0000ff;
+  }
+</style>
+<body>
+  <my-element id="subject" lang="en"></my-element>
+  <script src="/resources/testharness.js"></script>
+  <script src="/resources/testharnessreport.js"></script>
+  <script>
+    const RED = "rgb(255, 0, 0)";
+    const GREEN = "rgb(0, 255, 0)";
+    const BLUE = "rgb(0, 0, 255)";
+    const AQUA = "rgb(0, 255, 255)";
+    customElements.define(
+      "my-element",
+      class MyElement extends HTMLElement {
+        connectedCallback() {
+          this.attachShadow({
+            mode: "open",
+          }).innerHTML = `<div part="inner">Test</div>`;
+          this.elementInternals = this.attachInternals();
+        }
+
+        get inner() {
+          return this.shadowRoot.querySelector("[part=inner]");
+        }
+      },
+    );
+
+    test((t) => {
+      t.add_cleanup(() => {
+        subject.inner.removeAttribute("lang");
+      });
+      assert_equals(getComputedStyle(subject.inner).backgroundColor, AQUA);
+      subject.inner.lang = "en-GB";
+      assert_equals(getComputedStyle(subject.inner).backgroundColor, GREEN);
+      subject.inner.lang = "fr";
+      assert_equals(getComputedStyle(subject.inner).backgroundColor, BLUE);
+      subject.inner.lang = "en";
+      assert_equals(getComputedStyle(subject.inner).backgroundColor, AQUA);
+    }, "::part():lang() invalidation");
+
+    test((t) => {
+      t.add_cleanup(() => {
+        subject.inner.removeAttribute("lang");
+      });
+      assert_equals(getComputedStyle(subject.inner).backgroundColor, AQUA);
+      subject.inner.setAttribute("lang", "en-GB");
+      assert_equals(getComputedStyle(subject.inner).backgroundColor, GREEN);
+      subject.inner.setAttribute("lang", "en");
+      assert_equals(getComputedStyle(subject.inner).backgroundColor, AQUA);
+      subject.inner.setAttribute("lang", "fr");
+      assert_equals(getComputedStyle(subject.inner).backgroundColor, BLUE);
+      subject.inner.removeAttribute("lang");
+      assert_equals(getComputedStyle(subject.inner).backgroundColor, AQUA);
+    }, "::part():lang() invalidation from setAttribute");
+  </script>
+</body>
diff --git a/third_party/blink/web_tests/external/wpt/css/selectors/invalidation/state-in-has-expected.txt b/third_party/blink/web_tests/external/wpt/css/selectors/invalidation/state-in-has-expected.txt
new file mode 100644
index 0000000..97c90323
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/selectors/invalidation/state-in-has-expected.txt
@@ -0,0 +1,5 @@
+This is a testharness.js-based test.
+[FAIL] Test :has() invalidation with :state() pseudo-classes
+  assert_equals: expected "rgb(0, 255, 0)" but got "rgb(255, 0, 0)"
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/external/wpt/css/selectors/invalidation/state-in-has.html b/third_party/blink/web_tests/external/wpt/css/selectors/invalidation/state-in-has.html
new file mode 100644
index 0000000..15dec18
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/selectors/invalidation/state-in-has.html
@@ -0,0 +1,58 @@
+<!doctype html>
+<title>:has() invalidation with :state() pseudo-class</title>
+<link rel="author" title="Keith Cirkel" href="mailto:wpt@keithcirkel.co.uk" />
+<link rel="help" href="https://drafts.csswg.org/selectors/#relational" />
+<link rel="help" href="https://github.com/whatwg/html/pull/8467" />
+<style>
+  #subject {
+    background-color: #f00;
+  }
+  #subject:has(:state(--green)) {
+    background-color: #0f0;
+  }
+  #subject:has(:state(--blue)) {
+    background-color: #00f;
+  }
+</style>
+<body>
+  Test :state() pseudo-class invalidation with :has()
+  <div id="subject">
+    <my-element id="child"></my-element>
+  </div>
+  <script src="/resources/testharness.js"></script>
+  <script src="/resources/testharnessreport.js"></script>
+  <script>
+    const RED = "rgb(255, 0, 0)";
+    const GREEN = "rgb(0, 255, 0)";
+    const BLUE = "rgb(0, 0, 255)";
+
+    test(() => {
+      customElements.define(
+        "my-element",
+        class MyElement extends HTMLElement {
+          connectedCallback() {
+            this.elementInternals = this.attachInternals();
+          }
+        },
+      );
+      assert_equals(getComputedStyle(subject).backgroundColor, RED);
+      child.elementInternals.states.add("--green");
+      assert_equals(getComputedStyle(subject).backgroundColor, GREEN);
+      child.elementInternals.states.clear();
+      assert_equals(getComputedStyle(subject).backgroundColor, RED);
+
+      child.elementInternals.states.add("--blue");
+      assert_equals(getComputedStyle(subject).backgroundColor, BLUE);
+      child.elementInternals.states.clear();
+      assert_equals(getComputedStyle(subject).backgroundColor, RED);
+
+      child.elementInternals.states.add("--green");
+      child.elementInternals.states.add("--blue");
+      assert_equals(getComputedStyle(subject).backgroundColor, BLUE);
+      child.elementInternals.states.delete("--blue");
+      assert_equals(getComputedStyle(subject).backgroundColor, GREEN);
+      child.elementInternals.states.delete("--green");
+      assert_equals(getComputedStyle(subject).backgroundColor, RED);
+    }, "Test :has() invalidation with :state() pseudo-classes");
+  </script>
+</body>
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/forms/the-input-element/range.html b/third_party/blink/web_tests/external/wpt/html/semantics/forms/the-input-element/range.html
index 093c60ba..27cc6ab 100644
--- a/third_party/blink/web_tests/external/wpt/html/semantics/forms/the-input-element/range.html
+++ b/third_party/blink/web_tests/external/wpt/html/semantics/forms/the-input-element/range.html
@@ -57,6 +57,10 @@
         "range type support on input element"
       );
 
+      test(function() {
+        assert_equals(getComputedStyle(document.getElementById('range_basic')).overflow, "visible");
+      }, "range overflow styles");
+
       test(
         function() {
           assert_equals(document.getElementById('range_basic').min, "0")
diff --git a/third_party/chromite b/third_party/chromite
index b101b80..c1b9dd4 160000
--- a/third_party/chromite
+++ b/third_party/chromite
@@ -1 +1 @@
-Subproject commit b101b80fdca8f9a23fa6334cdd1c537b00387b5c
+Subproject commit c1b9dd4348b384091d021830783be93c1f8f966b
diff --git a/third_party/dawn b/third_party/dawn
index 10aa8bc..02ba88d 160000
--- a/third_party/dawn
+++ b/third_party/dawn
@@ -1 +1 @@
-Subproject commit 10aa8bc80bbfef2650adbd4643a007e3efb7708c
+Subproject commit 02ba88d8c9492dd40a80a46b0ace3bd71377a7a8
diff --git a/third_party/devtools-frontend-internal b/third_party/devtools-frontend-internal
index 9384327..afdc318 160000
--- a/third_party/devtools-frontend-internal
+++ b/third_party/devtools-frontend-internal
@@ -1 +1 @@
-Subproject commit 9384327dc44ffdc6a5b98783c7614efa75f753ed
+Subproject commit afdc318b8a2bb8432f1cd082b6b757d58db8e6b5
diff --git a/third_party/devtools-frontend/src b/third_party/devtools-frontend/src
index 537237c..5c380622 160000
--- a/third_party/devtools-frontend/src
+++ b/third_party/devtools-frontend/src
@@ -1 +1 @@
-Subproject commit 537237ced590b359b9a213bd44ef5b46107d4371
+Subproject commit 5c380622f2ea4f74da1623ff2e3f1503f35df1a9
diff --git a/third_party/webrtc b/third_party/webrtc
index f404434..d2771c6 160000
--- a/third_party/webrtc
+++ b/third_party/webrtc
@@ -1 +1 @@
-Subproject commit f40443424ea57e794be5e43abc2d8d8f6b7c50b9
+Subproject commit d2771c615300866bd0af7d9858b2bf3d48ee9b52
diff --git a/tools/win/chromeexts/BUILD.gn b/tools/win/chromeexts/BUILD.gn
index 3a42ca4..df1daf6 100644
--- a/tools/win/chromeexts/BUILD.gn
+++ b/tools/win/chromeexts/BUILD.gn
@@ -8,6 +8,10 @@
     "chrome_exts_command.h",
     "chromeexts.cc",
     "chromeexts.def",
+    "commands/crash_info_command.cc",
+    "commands/crash_info_command.h",
+    "commands/gwp_asan_command.cc",
+    "commands/gwp_asan_command.h",
     "commands/hwnd_command.cc",
     "commands/hwnd_command.h",
     "commands/view_command.cc",
@@ -16,6 +20,11 @@
 
   deps = [
     "//base",
+    "//components/gwp_asan/crash_handler",
+    "//components/gwp_asan/crash_handler:crash_proto",
+    "//third_party/crashpad/crashpad/client",
+    "//third_party/crashpad/crashpad/minidump",
+    "//third_party/crashpad/crashpad/snapshot",
     "//ui/views/debug:views_debug",
   ]
 }
diff --git a/tools/win/chromeexts/DEPS b/tools/win/chromeexts/DEPS
index 1ac9c26f..3232c4c 100644
--- a/tools/win/chromeexts/DEPS
+++ b/tools/win/chromeexts/DEPS
@@ -2,4 +2,19 @@
   # Views debug code should avoid relying on //ui/views code to ensure debugger
   # extensions are resillient to version structure changes within the codebase.
   "+ui/views/debug",
+  # Allows dependency to retrieve the crashpad-specific annotations from a
+  # minidump and display them as part of the msedgede crashinfo command.
+  '+third_party/crashpad/crashpad/client/annotation.h',
+  '+third_party/crashpad/crashpad/minidump/minidump_extensions.h',
+  '+third_party/crashpad/crashpad/snapshot/minidump/process_snapshot_minidump.h',
+  '+third_party/crashpad/crashpad/util/file/file_reader.h',
 ]
+
+specific_include_rules = {
+  "gwp_asan_command.h": [
+    "+components/gwp_asan/crash_handler/crash.pb.h",
+  ],
+  "gwp_asan_command.cc": [
+    "+components/gwp_asan/crash_handler/crash_handler.h",
+  ],
+}
diff --git a/tools/win/chromeexts/chrome_exts_command.cc b/tools/win/chromeexts/chrome_exts_command.cc
index 8ac47d3..c72a7cdf 100644
--- a/tools/win/chromeexts/chrome_exts_command.cc
+++ b/tools/win/chromeexts/chrome_exts_command.cc
@@ -44,6 +44,20 @@
   return hr;
 }
 
+HRESULT ChromeExtsCommand::PrintfWithIndent(int indent_level,
+                                            const char* format,
+                                            ...) {
+  for (int i = 0; i < indent_level; i++) {
+    Printf("  ");
+  }
+
+  va_list ap;
+  va_start(ap, format);
+  HRESULT hr = PrintV(format, ap);
+  va_end(ap);
+  return hr;
+}
+
 HRESULT ChromeExtsCommand::PrintV(const char* format, va_list ap) {
   return debug_control_->OutputVaList(DEBUG_OUTPUT_NORMAL, format, ap);
 }
diff --git a/tools/win/chromeexts/chrome_exts_command.h b/tools/win/chromeexts/chrome_exts_command.h
index 64e3f6f..1c7f178 100644
--- a/tools/win/chromeexts/chrome_exts_command.h
+++ b/tools/win/chromeexts/chrome_exts_command.h
@@ -55,6 +55,7 @@
   virtual HRESULT Execute() = 0;
 
   HRESULT Printf(const char* format, ...);
+  HRESULT PrintfWithIndent(int indent_level, const char* format, ...);
   HRESULT PrintV(const char* format, va_list ap);
 
   HRESULT PrintErrorf(const char* format, ...);
diff --git a/tools/win/chromeexts/chromeexts.cc b/tools/win/chromeexts/chromeexts.cc
index 12002ea..6638deb 100644
--- a/tools/win/chromeexts/chromeexts.cc
+++ b/tools/win/chromeexts/chromeexts.cc
@@ -6,6 +6,8 @@
 #include <wrl/client.h>
 
 #include "tools/win/chromeexts/chrome_exts_command.h"
+#include "tools/win/chromeexts/commands/crash_info_command.h"
+#include "tools/win/chromeexts/commands/gwp_asan_command.h"
 #include "tools/win/chromeexts/commands/hwnd_command.h"
 #include "tools/win/chromeexts/commands/view_command.h"
 
@@ -32,6 +34,12 @@
                         "Chrome Windows Debugger Extension\n");
   debug_control->Output(DEBUG_OUTPUT_NORMAL,
                         "hwnd - Displays basic hwnd info.\n");
+  debug_control->Output(DEBUG_OUTPUT_NORMAL,
+                        "crashinfo - Displays info from a crashpad dump.\n");
+  debug_control->Output(
+      DEBUG_OUTPUT_NORMAL,
+      "gwpasan - Displays info from a GWP-ASan dump.\n Usage: gwpasan "
+      "\"[<chrome binary path>;<llvm-symbolizer path>]\"");
   return S_OK;
 }
 
@@ -44,3 +52,13 @@
   return tools::win::chromeexts::ChromeExtsCommand::Run<
       tools::win::chromeexts::ViewCommand>(client, args);
 }
+
+HRESULT CALLBACK RunCrashInfoCommand(IDebugClient* client, PCSTR args) {
+  return tools::win::chromeexts::ChromeExtsCommand::Run<
+      tools::win::chromeexts::CrashInfoCommand>(client, args);
+}
+
+HRESULT CALLBACK RunGwpAsanCommand(IDebugClient* client, PCSTR args) {
+  return tools::win::chromeexts::ChromeExtsCommand::Run<
+      tools::win::chromeexts::GwpAsanCommand>(client, args);
+}
diff --git a/tools/win/chromeexts/chromeexts.def b/tools/win/chromeexts/chromeexts.def
index 65264fdf..606a52b 100644
--- a/tools/win/chromeexts/chromeexts.def
+++ b/tools/win/chromeexts/chromeexts.def
@@ -10,3 +10,5 @@
   help
   hwnd = RunHwndCommand
   view = RunViewCommand
+  crashinfo = RunCrashInfoCommand
+  gwpasan = RunGwpAsanCommand
diff --git a/tools/win/chromeexts/commands/crash_info_command.cc b/tools/win/chromeexts/commands/crash_info_command.cc
new file mode 100644
index 0000000..8c05473
--- /dev/null
+++ b/tools/win/chromeexts/commands/crash_info_command.cc
@@ -0,0 +1,289 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "tools/win/chromeexts/commands/crash_info_command.h"
+
+#include <dbgeng.h>
+#include <windows.h>
+
+#include <cstring>
+#include <ctime>
+#include <vector>
+
+#include "base/strings/stringprintf.h"
+#include "base/strings/sys_string_conversions.h"
+#include "third_party/crashpad/crashpad/client/annotation.h"
+#include "third_party/crashpad/crashpad/minidump/minidump_extensions.h"
+#include "third_party/crashpad/crashpad/snapshot/minidump/process_snapshot_minidump.h"
+
+namespace tools {
+namespace win {
+namespace chromeexts {
+
+namespace {
+
+template <typename T, size_t N>
+constexpr size_t countof(T const (&)[N]) {
+  return N;
+}
+
+// Get a readable string to represent a process integrity level.
+const char* ProcessIntegrityString(ULONG32 integrity_level) {
+  if (integrity_level < SECURITY_MANDATORY_LOW_RID) {
+    return "Untrusted";
+  }
+  if (integrity_level < SECURITY_MANDATORY_MEDIUM_RID) {
+    return "Low";
+  }
+  if (integrity_level < SECURITY_MANDATORY_MEDIUM_PLUS_RID) {
+    return "Medium";
+  }
+  if (integrity_level < SECURITY_MANDATORY_HIGH_RID) {
+    return "Medium Plus";
+  }
+  if (integrity_level < SECURITY_MANDATORY_SYSTEM_RID) {
+    return "High";
+  }
+  if (integrity_level < SECURITY_MANDATORY_PROTECTED_PROCESS_RID) {
+    return "System";
+  }
+  return "Protected Process";
+}
+
+}  // namespace
+
+CrashInfoCommand::CrashInfoCommand() = default;
+
+CrashInfoCommand::~CrashInfoCommand() = default;
+
+HRESULT CrashInfoCommand::Execute() {
+  ULONG debuggee_class;
+  ULONG debuggee_qualifier;
+  GetDebugClientAs<IDebugControl>()->GetDebuggeeType(&debuggee_class,
+                                                     &debuggee_qualifier);
+
+  // If the debug target is a minidump, it may be a crashpad dump.
+  bool crashpad_dump = debuggee_class == DEBUG_CLASS_USER_WINDOWS &&
+                       debuggee_qualifier == DEBUG_USER_WINDOWS_SMALL_DUMP;
+
+  crashpad::MinidumpCrashpadInfo info;
+  HRESULT hr;
+  size_t bytes_read;
+
+  if (crashpad_dump) {
+    // Read the crashpad stream to verify this is a crashpad dump.
+    hr = GetDebugClientAs<IDebugClient5>()->QueryInterface(
+        IID_PPV_ARGS(&debug_advanced_));
+    if (FAILED(hr)) {
+      PrintErrorf("QI for IDebugAdvanced3: %08X\n", hr);
+      return hr;
+    }
+
+    hr = ReadFromDumpStream(
+        crashpad::MinidumpStreamType::kMinidumpStreamTypeCrashpadInfo, 0,
+        sizeof(info), &info, &bytes_read);
+    if (hr == E_NOINTERFACE) {
+      // The request returns E_NOINTERFACE when the requested stream
+      // type isn't found.
+      crashpad_dump = false;
+    } else if (FAILED(hr)) {
+      PrintErrorf("Reading crashpad info: %08X\n", hr);
+      return hr;
+    }
+  }
+
+  if (!crashpad_dump) {
+    PrintErrorf("This doesn't look like a crashpad dump.\n");
+    return S_OK;
+  }
+
+  Printf("CrashpadInfo version: %d\n", info.version);
+  Printf("Report ID: %s\n", info.report_id.ToString().c_str());
+  Printf("Client ID: %s\n", info.client_id.ToString().c_str());
+
+  DisplayMiscInfo();
+  DisplayAnnotations();
+
+  return S_OK;
+}
+
+void CrashInfoCommand::DisplayAnnotations() {
+  // Find the dump file and re-open it directly.  Reading by streams doesn't
+  // allow access to the extra data written by crashpad at the end of many
+  // streams.
+  std::unique_ptr<crashpad::FileReaderInterface> dump_file_reader =
+      OpenDumpFileReader();
+  if (!dump_file_reader) {
+    PrintErrorf("Failed to open dump reader\n");
+    return;
+  }
+  crashpad::ProcessSnapshotMinidump snapshot;
+  if (!snapshot.Initialize(dump_file_reader.get())) {
+    PrintErrorf("Failed to construct process snapshot\n");
+    return;
+  }
+  Printf("\nDump annotations:\n\n");
+  Printf("Process annotations:\n");
+  for (const auto& kv : snapshot.AnnotationsSimpleMap()) {
+    PrintfWithIndent(1, "%s = %s\n", kv.first.c_str(), kv.second.c_str());
+  }
+  constexpr char kModuleHeader[] = "Annotations for module: %s\n";
+  for (const crashpad::ModuleSnapshot* module : snapshot.Modules()) {
+    bool printed_header = false;
+    if (module->AnnotationsSimpleMap().size() > 0) {
+      Printf(kModuleHeader, module->Name().c_str());
+      printed_header = true;
+      for (const auto& kv : module->AnnotationsSimpleMap()) {
+        PrintfWithIndent(1, "%s = %s\n", kv.first.c_str(), kv.second.c_str());
+      }
+    }
+    if (module->AnnotationsVector().size() > 0) {
+      if (!printed_header) {
+        Printf(kModuleHeader, module->Name().c_str());
+        printed_header = true;
+      }
+      PrintfWithIndent(1, "vector:\n");
+      for (std::string annotation : module->AnnotationsVector()) {
+        PrintfWithIndent(2, "%s\n", annotation.c_str());
+      }
+    }
+    if (module->AnnotationObjects().size() > 0) {
+      if (!printed_header) {
+        Printf(kModuleHeader, module->Name().c_str());
+        printed_header = true;
+      }
+      for (const crashpad::AnnotationSnapshot& annotation :
+           module->AnnotationObjects()) {
+        PrintfWithIndent(1, "%s = ", annotation.name.c_str());
+        if (annotation.type ==
+            static_cast<uint16_t>(crashpad::Annotation::Type::kString)) {
+          std::string value(
+              reinterpret_cast<const char*>(annotation.value.data()),
+              annotation.value.size());
+          Printf("%s\n", value.c_str());
+        } else if (annotation.type >
+                   static_cast<uint16_t>(
+                       crashpad::Annotation::Type::kUserDefinedStart)) {
+          Printf("user defined - type: %d, size: %d\n",
+                 annotation.type -
+                     static_cast<uint16_t>(
+                         crashpad::Annotation::Type::kUserDefinedStart),
+                 annotation.value.size());
+        }
+      }
+    }
+  }
+}
+
+void CrashInfoCommand::DisplayMiscInfo() {
+  HRESULT hr;
+  size_t bytes_read;
+  MINIDUMP_MISC_INFO_5 misc_info;
+  memset(&misc_info, 0, sizeof(misc_info));
+  hr = ReadFromDumpStream(
+      crashpad::MinidumpStreamType::kMinidumpStreamTypeMiscInfo, 0,
+      sizeof(misc_info), &misc_info, &bytes_read);
+  if (FAILED(hr)) {
+    PrintErrorf("Reading misc info: %08X\n", hr);
+    return;
+  }
+
+  if (misc_info.Flags1 & MINIDUMP_MISC1_PROCESS_ID) {
+    Printf("Process ID: %ld\n", misc_info.ProcessId);
+  }
+  if (misc_info.Flags1 & MINIDUMP_MISC1_PROCESS_TIMES) {
+    time_t create_time = misc_info.ProcessCreateTime;
+    Printf("Create time: %s", std::ctime(&create_time));
+    Printf("User time: %us\n", misc_info.ProcessUserTime);
+    Printf("Kernel time: %us\n", misc_info.ProcessKernelTime);
+  }
+  if (misc_info.Flags1 & MINIDUMP_MISC1_PROCESSOR_POWER_INFO) {
+    Printf("ProcessorMaxMhz: %u\n", misc_info.ProcessorMaxMhz);
+    Printf("ProcessorCurrentMhz: %u\n", misc_info.ProcessorCurrentMhz);
+    Printf("ProcessorMhzLimit: %u\n", misc_info.ProcessorMhzLimit);
+    Printf("ProcessorMaxIdleState: %u\n", misc_info.ProcessorMaxIdleState);
+    Printf("ProcessorCurrentIdleState: %u\n", misc_info.ProcessorMaxIdleState);
+  }
+  if (misc_info.Flags1 & MINIDUMP_MISC3_PROCESS_INTEGRITY) {
+    Printf("ProcessIntegrityLevel: %s\n",
+           ProcessIntegrityString(misc_info.ProcessIntegrityLevel));
+  }
+  if (misc_info.Flags1 & MINIDUMP_MISC3_PROCESS_EXECUTE_FLAGS) {
+    Printf("ProcessExcecuteFlags: 0x%08x\n",
+           ProcessIntegrityString(misc_info.ProcessExecuteFlags));
+  }
+  if (misc_info.Flags1 & MINIDUMP_MISC3_PROTECTED_PROCESS) {
+    Printf("ProtectedProcess: 0x%08x\n",
+           ProcessIntegrityString(misc_info.ProcessExecuteFlags));
+  }
+  if (misc_info.Flags1 & MINIDUMP_MISC3_TIMEZONE) {
+    Printf("Standard Time Zone: %s\n",
+           base::SysWideToNativeMB(
+               std::wstring(misc_info.TimeZone.StandardName,
+                            countof(misc_info.TimeZone.StandardName)))
+               .c_str());
+    Printf("Daylight Time Zone: %s\n",
+           base::SysWideToNativeMB(
+               std::wstring(misc_info.TimeZone.DaylightName,
+                            countof(misc_info.TimeZone.DaylightName)))
+               .c_str());
+  }
+  if (misc_info.Flags1 & MINIDUMP_MISC4_BUILDSTRING) {
+    Printf("BuildString: %s\n",
+           base::SysWideToNativeMB(std::wstring(misc_info.BuildString,
+                                                countof(misc_info.BuildString)))
+               .c_str());
+    Printf("DbgBldStr: %s\n",
+           base::SysWideToNativeMB(
+               std::wstring(misc_info.DbgBldStr, countof(misc_info.DbgBldStr)))
+               .c_str());
+  }
+  if (misc_info.Flags1 & MINIDUMP_MISC5_PROCESS_COOKIE) {
+    Printf("Process Cookie: 0x%08x\n", misc_info.ProcessCookie);
+  }
+}
+
+std::unique_ptr<crashpad::FileReaderInterface>
+CrashInfoCommand::OpenDumpFileReader() {
+  ULONG64 wide_dump_file_handle;
+  ULONG dump_type;
+  HRESULT hr = GetDebugClientAs<IDebugClient5>()->GetDumpFile(
+      0, nullptr, 0, nullptr, &wide_dump_file_handle, &dump_type);
+  if (FAILED(hr)) {
+    PrintErrorf("getting dump file handle: %08x\n", hr);
+    return nullptr;
+  }
+
+  crashpad::FileHandle dump_file_handle =
+      reinterpret_cast<crashpad::FileHandle>(wide_dump_file_handle);
+  return std::make_unique<crashpad::WeakFileHandleFileReader>(dump_file_handle);
+}
+
+HRESULT CrashInfoCommand::ReadFromDumpStream(uint32_t stream_type,
+                                             uint64_t offset,
+                                             size_t max_read,
+                                             void* bytes,
+                                             size_t* bytes_read) {
+  *bytes_read = 0;
+
+  DEBUG_READ_USER_MINIDUMP_STREAM request;
+  memset(&request, 0, sizeof(request));
+  request.StreamType = stream_type;
+  request.Offset = offset;
+  request.Buffer = bytes;
+  request.BufferSize = max_read;
+
+  HRESULT hr =
+      debug_advanced_->Request(DEBUG_REQUEST_READ_USER_MINIDUMP_STREAM,
+                               &request, sizeof(request), nullptr, 0, nullptr);
+  if (SUCCEEDED(hr)) {
+    *bytes_read = request.BufferUsed;
+  }
+
+  return hr;
+}
+
+}  // namespace chromeexts
+}  // namespace win
+}  // namespace tools
diff --git a/tools/win/chromeexts/commands/crash_info_command.h b/tools/win/chromeexts/commands/crash_info_command.h
new file mode 100644
index 0000000..49d0fb7
--- /dev/null
+++ b/tools/win/chromeexts/commands/crash_info_command.h
@@ -0,0 +1,44 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef TOOLS_WIN_CHROMEEXTS_COMMANDS_CRASH_INFO_COMMAND_H_
+#define TOOLS_WIN_CHROMEEXTS_COMMANDS_CRASH_INFO_COMMAND_H_
+
+#include "third_party/crashpad/crashpad/util/file/file_reader.h"
+#include "tools/win/chromeexts/chrome_exts_command.h"
+
+namespace tools {
+namespace win {
+namespace chromeexts {
+
+class CrashInfoCommand : public ChromeExtsCommand {
+ public:
+  CrashInfoCommand();
+  ~CrashInfoCommand() override;
+
+  CrashInfoCommand(const CrashInfoCommand&) = delete;
+  CrashInfoCommand& operator=(const CrashInfoCommand&) = delete;
+
+ protected:
+  HRESULT Execute() override;
+
+  void DisplayAnnotations();
+  void DisplayMiscInfo();
+
+  std::unique_ptr<crashpad::FileReaderInterface> OpenDumpFileReader();
+  HRESULT ReadFromDumpStream(uint32_t stream_type,
+                             uint64_t offset,
+                             size_t max_read,
+                             void* bytes,
+                             size_t* bytes_read);
+
+ private:
+  ComPtr<IDebugAdvanced3> debug_advanced_;
+};
+
+}  // namespace chromeexts
+}  // namespace win
+}  // namespace tools
+
+#endif  // TOOLS_WIN_CHROMEEXTS_COMMANDS_CRASH_INFO_COMMAND_H_
diff --git a/tools/win/chromeexts/commands/gwp_asan_command.cc b/tools/win/chromeexts/commands/gwp_asan_command.cc
new file mode 100644
index 0000000..6c712fb
--- /dev/null
+++ b/tools/win/chromeexts/commands/gwp_asan_command.cc
@@ -0,0 +1,432 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "tools/win/chromeexts/commands/gwp_asan_command.h"
+
+#include <dbgeng.h>
+#include <windows.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <fstream>
+#include <istream>
+#include <string>
+#include <vector>
+
+#include "base/json/json_reader.h"
+#include "base/strings/string_util.h"
+#include "base/strings/stringprintf.h"
+#include "base/strings/sys_string_conversions.h"
+#include "base/values.h"
+#include "components/gwp_asan/crash_handler/crash_handler.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
+
+namespace tools {
+namespace win {
+namespace chromeexts {
+
+GwpAsanCommand::GwpAsanCommand() = default;
+
+GwpAsanCommand::~GwpAsanCommand() = default;
+
+HRESULT GwpAsanCommand::InitPlatformID() {
+  ULONG win32_major, win32_minor;
+  return GetDebugClientAs<IDebugControl4>()->GetSystemVersionValues(
+      &platform_id_, &win32_major, &win32_minor, nullptr, nullptr);
+}
+
+HRESULT GwpAsanCommand::Execute() {
+  ULONG debuggee_class;
+  ULONG debuggee_qualifier;
+  GetDebugClientAs<IDebugControl4>()->GetDebuggeeType(&debuggee_class,
+                                                      &debuggee_qualifier);
+
+  // If the debug target is a minidump, it may be a GWP-ASan dump.
+  bool gwp_asan_dump = debuggee_class == DEBUG_CLASS_USER_WINDOWS &&
+                       debuggee_qualifier == DEBUG_USER_WINDOWS_SMALL_DUMP;
+
+  gwp_asan::Crash info;
+  std::vector<char> buffer;
+  HRESULT hr;
+
+  if (gwp_asan_dump) {
+    hr = ReadFromDumpStream(gwp_asan::internal::kGwpAsanMinidumpStreamType,
+                            &buffer, 0);
+    if (hr == E_NOINTERFACE) {
+      // The request returns E_NOINTERFACE when the requested stream
+      // type isn't found.
+      gwp_asan_dump = false;
+    } else if (FAILED(hr)) {
+      PrintErrorf("Reading GWP-ASan info: %08X\n", hr);
+      return hr;
+    }
+  }
+
+  if (!gwp_asan_dump) {
+    PrintErrorf("No GWP-ASan dump available.\n");
+    return S_OK;
+  }
+
+  hr = InitPlatformID();
+  if (FAILED(hr)) {
+    PrintErrorf("Cannot determine the Platform");
+    return hr;
+  }
+
+  ComPtr<IDebugControl3> debug_control3;
+  hr = GetDebugClientAs<IDebugControl4>()->QueryInterface(
+      IID_PPV_ARGS(&debug_control3));
+  if (FAILED(hr)) {
+    PrintErrorf("QI for IDebugControl3: %08X\n", hr);
+    return hr;
+  }
+  hr = debug_control3->IsPointer64Bit();
+  if (hr == S_FALSE) {
+    Printf("Warning: GWP-ASan stream is not reliable for 32-bit\n");
+  } else if (FAILED(hr)) {
+    PrintErrorf("Cannot determine if effective processor uses 64 bit or not\n");
+    return hr;
+  }
+
+  hr = GetDebugClientAs<IDebugControl4>()->QueryInterface(
+      IID_PPV_ARGS(&debug_symbols_));
+  if (FAILED(hr)) {
+    PrintErrorf("QI for IDebugSymbols3: %08X\n", hr);
+    return hr;
+  }
+
+  membuf stream_buffer(&buffer[0], &buffer[0] + buffer.size());
+  std::istream istream_buffer(&stream_buffer);
+  info.ParseFromIstream(&istream_buffer);
+
+  Printf("\n");
+  if (info.has_missing_metadata()) {
+    if (info.missing_metadata()) {
+      Printf("Missing metadata in GWP-ASan dump\n");
+    }
+  }
+  if (info.has_internal_error()) {
+    Printf("%-50s%s\n", "Internal error:", info.internal_error().c_str());
+  }
+  if (info.has_allocation()) {
+    Printf("%-50s%d\n", "Allocation stack trace size:",
+           info.allocation().stack_trace_size());
+  }
+  if (info.has_deallocation()) {
+    Printf("%-50s%d\n", "Deallocation stack trace size:",
+           info.deallocation().stack_trace_size());
+  }
+  if (info.has_allocation_address()) {
+    Printf("%-50s%I64x\n", "Allocation address:", info.allocation_address());
+  }
+  if (info.has_allocation_size()) {
+    Printf("%-50s%I64x\n", "Allocation size:", info.allocation_size());
+  }
+  if (info.has_error_type()) {
+    PrintErrorType(info.error_type());
+  }
+  if (info.has_region_start()) {
+    Printf("%-50s%I64x\n", "Region start:", info.region_start());
+  }
+  if (info.has_region_size()) {
+    Printf("%-50s%I64x\n", "Region size:", info.region_size());
+  }
+  if (info.has_free_invalid_address()) {
+    Printf("%-50s%x\n", "Free invalid address:", info.free_invalid_address());
+  }
+  if (info.has_allocator()) {
+    Printf("%-50s", "Allocator Type:");
+    switch (info.allocator()) {
+      case gwp_asan::Crash_Allocator_MALLOC:
+        Printf("Malloc\n");
+        break;
+      case gwp_asan::Crash_Allocator_PARTITIONALLOC:
+        Printf("PartitionAlloc\n");
+        break;
+    }
+  }
+
+  ULONG64 base_address = 0;
+  hr = GetBaseAddress(&base_address);
+  if (hr == S_OK) {
+    Printf("%-50s%I64x\n", "Base address:", base_address);
+  }
+
+  if (info.has_allocation()) {
+    gwp_asan::Crash_AllocationInfo allocation = info.allocation();
+    Printf("%-50s%I64u\n", "Allocation Thread ID:", allocation.thread_id());
+    Printf("\nAllocation Stack Trace:\n\n");
+    if (FAILED(SymbolizeStackTrace(allocation, &base_address))) {
+      Printf("Error in Symbolizing Stack Trace");
+    }
+  }
+
+  if (info.has_deallocation()) {
+    gwp_asan::Crash_AllocationInfo deallocation = info.deallocation();
+    Printf("%-50s%I64u\n", "Deallocation Thread ID:", deallocation.thread_id());
+    Printf("\nDeallocation Stack Trace:\n\n");
+    if (FAILED(SymbolizeStackTrace(deallocation, &base_address))) {
+      Printf("Error in Symbolizing Stack Trace\n");
+    }
+  }
+
+  Printf("\nEnd\n");
+
+  return S_OK;
+}
+
+void GwpAsanCommand::PrintErrorType(const int& error_type) {
+  Printf("%-50s", "Error type:");
+  switch (error_type) {
+    case gwp_asan::Crash::USE_AFTER_FREE:
+      Printf("Use After Free");
+      break;
+    case gwp_asan::Crash::BUFFER_UNDERFLOW:
+      Printf("Buffer Underflow");
+      break;
+    case gwp_asan::Crash::BUFFER_OVERFLOW:
+      Printf("Buffer Overflow");
+      break;
+    case gwp_asan::Crash::DOUBLE_FREE:
+      Printf("Double Free");
+      break;
+    case gwp_asan::Crash::UNKNOWN:
+      Printf("Unknown");
+      break;
+    case gwp_asan::Crash::FREE_INVALID_ADDRESS:
+      Printf("Free Invalid Address");
+      break;
+    case gwp_asan::Crash::LIGHTWEIGHT_USE_AFTER_FREE:
+      Printf("Lightweight Use After Free");
+      break;
+  }
+  Printf("\n");
+}
+
+HRESULT GwpAsanCommand::GetBaseAddress(ULONG64* base_address) {
+  PCSTR module_name = "chrome";
+  ULONG index;
+
+  // For MacOS
+  if (platform_id_ == 33025) {
+    module_name = "Google_Chrome_Framework";
+  }
+
+  return debug_symbols_->GetModuleByModuleName(module_name, 0, &index,
+                                               base_address);
+}
+
+HRESULT GwpAsanCommand::UseWinDbgSymbolize(uint64_t* stack_address,
+                                           int stack_trace_size) {
+  int METHOD_SIZE = 1024;
+  char method_name[METHOD_SIZE], file_name[METHOD_SIZE];
+  std::string file_name_str;
+  ULONG line;
+  size_t position;
+  HRESULT hr;
+
+  for (int i = 0; i < stack_trace_size; i++) {
+    hr = debug_symbols_->GetNameByOffset(stack_address[i], method_name,
+                                         METHOD_SIZE, nullptr, nullptr);
+    if (SUCCEEDED(hr)) {
+      Printf("%d\t0x%I64x\t%s", i, stack_address[i], method_name);
+    } else {
+      Printf("%d\t0x%I64x\t", i, stack_address[i]);
+    }
+
+    hr = debug_symbols_->GetLineByOffset(stack_address[i], &line, file_name,
+                                         METHOD_SIZE, nullptr, nullptr);
+    if (SUCCEEDED(hr)) {
+      file_name_str = std::string(file_name);
+      position = file_name_str.find("\\src\\");
+      if (position != std::string::npos) {
+        file_name_str = file_name_str.substr(position + 5, std::string::npos);
+      }
+      position = file_name_str.find("../../");
+      if (position != std::string::npos) {
+        file_name_str = file_name_str.substr(position + 6, std::string::npos);
+      }
+      base::ReplaceChars(base::StringPiece(file_name_str.c_str()), "\\", "/",
+                         &file_name_str);
+      Printf(" at %s:%d", file_name_str.c_str(), line);
+    }
+    Printf("\n");
+  }
+  Printf("\n");
+  return S_OK;
+}
+
+HRESULT GwpAsanCommand::SymbolizeStackTrace(
+    gwp_asan::Crash_AllocationInfo& allocation,
+    ULONG64* base_address) {
+  int stack_trace_size = allocation.stack_trace_size();
+  uint64_t* stack_address = allocation.mutable_stack_trace()->mutable_data();
+
+  if (platform_id_ == VER_PLATFORM_WIN32_NT || platform_id_ == 33025) {
+    return UseWinDbgSymbolize(stack_address, stack_trace_size);
+  }
+
+  std::vector<std::string> stack_offset_addresses;
+  std::string hexstring;
+  char hex[15];
+  uint64_t base = *base_address >> 32;
+  uint64_t offset;
+
+  for (int i = 0; i < stack_trace_size; i++) {
+    if ((base & stack_address[i] >> 32) == base) {
+      offset = stack_address[i] - *base_address;
+      snprintf(hex, sizeof(hex), "0x%I64x", offset);
+      std::string hex_address = std::string(hex);
+      hexstring += " " + hex_address;
+      stack_offset_addresses.push_back(hex_address);
+    } else {
+      snprintf(hex, sizeof(hex), "0x%I64x", stack_address[i]);
+      stack_offset_addresses.push_back(std::string(hex));
+    }
+  }
+
+  std::string json_string;
+  ReadSymbols(hexstring, &json_string);
+  if (json_string.empty()) {
+    PrintErrorf("Cannot Symbolize stack trace\n");
+    return E_FAIL;
+  }
+
+  absl::optional<base::Value> symbolized_json =
+      base::JSONReader::Read(base::StringPiece(json_string));
+  if (!symbolized_json.has_value() && !symbolized_json->is_list()) {
+    return E_FAIL;
+  }
+
+  base::Value::List& address_list = symbolized_json->GetList();
+  if (address_list.empty()) {
+    return E_FAIL;
+  }
+
+  std::map<std::string, base::Value::List*> address_symbol_map;
+  for (size_t i = 0; i < address_list.size(); i++) {
+    address_symbol_map[address_list[i].GetDict().Find("Address")->GetString()] =
+        address_list[i].GetDict().FindList("Symbol");
+  }
+
+  for (size_t i = 0; i < stack_offset_addresses.size(); i++) {
+    if (address_symbol_map.find(stack_offset_addresses[i]) ==
+        address_symbol_map.end()) {
+      Printf("#%d\t%s\n", i, stack_offset_addresses[i].c_str());
+      continue;
+    }
+
+    base::Value::List& symbol_list =
+        *(address_symbol_map[stack_offset_addresses[i]]);
+    base::Value& symbol = symbol_list[symbol_list.size() - 1];
+    const char* function_name =
+        symbol.GetDict().Find("FunctionName")->GetString().c_str();
+    const char* file_name =
+        symbol.GetDict().Find("FileName")->GetString().c_str();
+    int line_number = symbol.GetDict().Find("Line")->GetInt();
+    Printf("#%d\t%s\t%s at %s:%d\n", i, stack_offset_addresses[i].c_str(),
+           function_name, file_name, line_number);
+  }
+  return S_OK;
+}
+
+HRESULT GwpAsanCommand::ReadSymbols(std::string hexstring,
+                                    std::string* json_string) {
+  char buffer[128];
+  FILE* output;
+  auto argv = command_line().argv();
+  if (argv.empty()) {
+    return E_FAIL;
+  }
+
+  std::wstring wstr = argv.at(0);
+  int size_needed = WideCharToMultiByte(CP_UTF8, 0, &wstr[0], (int)wstr.size(),
+                                        NULL, 0, NULL, NULL);
+  std::string str(size_needed, 0);
+  WideCharToMultiByte(CP_UTF8, 0, &wstr[0], (int)wstr.size(), &str[0],
+                      size_needed, NULL, NULL);
+
+  std::string command_line_arg = str;
+
+  ULONG64 position = command_line_arg.find(";");
+  if (position == std::string::npos) {
+    PrintErrorf("Pass in format <binary path>;<llvm symbolizer path>\n");
+    return E_FAIL;
+  }
+  std::string chrome_path = command_line_arg.substr(0, position);
+  std::ifstream chrome(chrome_path.c_str());
+  if (!chrome.is_open()) {
+    return E_FAIL;
+  }
+
+  std::string llvm_symbolizer_path =
+      command_line_arg.substr(position + 1, command_line_arg.length());
+  std::ifstream llvm_symbolizer(llvm_symbolizer_path.c_str());
+  if (!llvm_symbolizer.is_open()) {
+    return E_FAIL;
+  }
+
+  std::string command = llvm_symbolizer_path + " " + "--obj=\"" + chrome_path +
+                        "\" " + "--output-style=JSON " + hexstring;
+
+  if ((output = _popen(command.c_str(), "r")) == nullptr) {
+    PrintErrorf("Cannot Read Symbols %s\n", command.c_str());
+    return E_FAIL;
+  }
+  while (fgets(buffer, sizeof(buffer), output)) {
+    *json_string += std::string(buffer);
+  }
+  if (!feof(output)) {
+    PrintErrorf("Failed to read the pipe to the end.\n");
+    return E_FAIL;
+  }
+  return S_OK;
+}
+
+HRESULT GwpAsanCommand::ReadFromDumpStream(uint32_t stream_type,
+                                           std::vector<char>* buffer,
+                                           uint64_t offset) {
+  char temp_buffer[128];
+  bool data_read = false;
+
+  DEBUG_READ_USER_MINIDUMP_STREAM request;
+  memset(&request, 0, sizeof(request));
+  request.StreamType = stream_type;
+  request.Buffer = temp_buffer;
+  request.BufferSize = sizeof(temp_buffer);
+  request.Offset = 0;
+
+  // Read the GWP-ASan stream to verify this is a GWP-ASan dump.
+  ComPtr<IDebugAdvanced3> debug_advanced;
+  HRESULT hr = GetDebugClientAs<IDebugControl4>()->QueryInterface(
+      IID_PPV_ARGS(&debug_advanced));
+  if (FAILED(hr)) {
+    PrintErrorf("QI for IDebugAdvanced3: %08X\n", hr);
+    return hr;
+  }
+
+  do {
+    hr =
+        debug_advanced->Request(DEBUG_REQUEST_READ_USER_MINIDUMP_STREAM,
+                                &request, sizeof(request), nullptr, 0, nullptr);
+
+    if (hr == S_OK || hr == S_FALSE) {
+      buffer->insert(buffer->end(), temp_buffer,
+                     temp_buffer + request.BufferUsed);
+
+      request.Offset = request.Offset + request.BufferUsed;
+      data_read = true;
+    }
+  } while (SUCCEEDED(hr));
+
+  if (hr == E_INVALIDARG && data_read) {
+    return S_OK;
+  }
+  PrintErrorf("Failed To read the dump stream\n");
+  return hr;
+}
+
+}  // namespace chromeexts
+}  // namespace win
+}  // namespace tools
diff --git a/tools/win/chromeexts/commands/gwp_asan_command.h b/tools/win/chromeexts/commands/gwp_asan_command.h
new file mode 100644
index 0000000..0f0d9d6
--- /dev/null
+++ b/tools/win/chromeexts/commands/gwp_asan_command.h
@@ -0,0 +1,51 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef TOOLS_WIN_CHROMEEXTS_COMMANDS_GWP_ASAN_COMMAND_H_
+#define TOOLS_WIN_CHROMEEXTS_COMMANDS_GWP_ASAN_COMMAND_H_
+
+#include <streambuf>
+
+#include "components/gwp_asan/crash_handler/crash.pb.h"
+#include "third_party/crashpad/crashpad/util/file/file_reader.h"
+#include "tools/win/chromeexts/chrome_exts_command.h"
+
+namespace tools {
+namespace win {
+namespace chromeexts {
+
+struct membuf : std::streambuf {
+  membuf(char* begin, char* end) { this->setg(begin, begin, end); }
+
+  membuf() {}
+};
+
+class GwpAsanCommand : public ChromeExtsCommand {
+ public:
+  GwpAsanCommand();
+  ~GwpAsanCommand() override;
+
+ protected:
+  HRESULT Execute() override;
+  HRESULT InitPlatformID();
+  HRESULT ReadFromDumpStream(uint32_t stream_type,
+                             std::vector<char>* buffer,
+                             uint64_t offset);
+  HRESULT GetBaseAddress(ULONG64* base_address);
+  HRESULT UseWinDbgSymbolize(uint64_t* stack_address, int stack_trace_size);
+  HRESULT SymbolizeStackTrace(gwp_asan::Crash_AllocationInfo& allocation,
+                              ULONG64* base_address);
+  HRESULT ReadSymbols(std::string hexstring, std::string* json_string);
+  void PrintErrorType(const int& error_type);
+
+ private:
+  ComPtr<IDebugSymbols3> debug_symbols_;
+  ULONG platform_id_{0};
+};
+
+}  // namespace chromeexts
+}  // namespace win
+}  // namespace tools
+
+#endif  // TOOLS_WIN_CHROMEEXTS_COMMANDS_GWP_ASAN_COMMAND_H_
diff --git a/ui/ozone/platform/drm/gpu/drm_overlay_plane.cc b/ui/ozone/platform/drm/gpu/drm_overlay_plane.cc
index 47bb8039..afe3fa4 100644
--- a/ui/ozone/platform/drm/gpu/drm_overlay_plane.cc
+++ b/ui/ozone/platform/drm/gpu/drm_overlay_plane.cc
@@ -27,17 +27,18 @@
 
 }  // namespace
 
-DrmOverlayPlane::DrmOverlayPlane(const scoped_refptr<DrmFramebuffer>& buffer,
-                                 std::unique_ptr<gfx::GpuFence> gpu_fence)
-    : buffer(buffer),
-      plane_transform(gfx::OVERLAY_TRANSFORM_NONE),
-      damage_rect(buffer->size()),
-      display_bounds(gfx::Point(), buffer->size()),
-      crop_rect(0, 0, 1, 1),
-      enable_blend(false),
-      gpu_fence(std::move(gpu_fence)) {}
+DrmOverlayPlane DrmOverlayPlane::TestPlane(
+    const scoped_refptr<DrmFramebuffer>& buffer,
+    gfx::ColorSpace color_space,
+    std::unique_ptr<gfx::GpuFence> gpu_fence) {
+  return DrmOverlayPlane(buffer, color_space, 0, gfx::OVERLAY_TRANSFORM_NONE,
+                         gfx::Rect(buffer->size()),
+                         gfx::Rect(gfx::Point(), buffer->size()),
+                         gfx::RectF(0, 0, 1, 1), false, std::move(gpu_fence));
+}
 
 DrmOverlayPlane::DrmOverlayPlane(const scoped_refptr<DrmFramebuffer>& buffer,
+                                 const gfx::ColorSpace& color_space,
                                  int z_order,
                                  gfx::OverlayTransform plane_transform,
                                  const gfx::Rect& damage_rect,
@@ -46,6 +47,7 @@
                                  bool enable_blend,
                                  std::unique_ptr<gfx::GpuFence> gpu_fence)
     : buffer(buffer),
+      color_space(color_space),
       z_order(z_order),
       plane_transform(plane_transform),
       damage_rect(damage_rect),
@@ -60,6 +62,7 @@
     std::unique_ptr<gfx::GpuFence> gpu_fence)
     : DrmOverlayPlane(
           buffer,
+          overlay_plane_data.color_space,
           overlay_plane_data.z_order,
           absl::get<gfx::OverlayTransform>(overlay_plane_data.plane_transform),
           overlay_plane_data.damage_rect,
@@ -76,16 +79,17 @@
 
 // static
 DrmOverlayPlane DrmOverlayPlane::Error() {
-  return DrmOverlayPlane(nullptr, 0, gfx::OVERLAY_TRANSFORM_INVALID,
-                         gfx::Rect(), gfx::Rect(), gfx::RectF(),
+  return DrmOverlayPlane(nullptr, gfx::ColorSpace(), 0,
+                         gfx::OVERLAY_TRANSFORM_INVALID, gfx::Rect(),
+                         gfx::Rect(), gfx::RectF(),
                          /* enable_blend */ true, /* gpu_fence */ nullptr);
 }
 
 bool DrmOverlayPlane::operator<(const DrmOverlayPlane& plane) const {
-  return std::tie(z_order, damage_rect, display_bounds, crop_rect,
+  return std::tie(z_order, color_space, damage_rect, display_bounds, crop_rect,
                   plane_transform) <
-         std::tie(plane.z_order, plane.damage_rect, plane.display_bounds,
-                  plane.crop_rect, plane.plane_transform);
+         std::tie(plane.z_order, plane.color_space, plane.damage_rect,
+                  plane.display_bounds, plane.crop_rect, plane.plane_transform);
 }
 
 // static
@@ -101,8 +105,8 @@
 }
 
 DrmOverlayPlane DrmOverlayPlane::Clone() const {
-  return DrmOverlayPlane(buffer, z_order, plane_transform, damage_rect,
-                         display_bounds, crop_rect, enable_blend,
+  return DrmOverlayPlane(buffer, color_space, z_order, plane_transform,
+                         damage_rect, display_bounds, crop_rect, enable_blend,
                          CloneGpuFence(gpu_fence));
 }
 
@@ -110,6 +114,7 @@
   auto dict = std::move(context).WriteDictionary();
 
   dict.Add("framebuffer_id", buffer ? buffer->framebuffer_id() : -1);
+  dict.Add("color_space", color_space.ToString());
   dict.Add("z_order", z_order);
   dict.Add("plane_transform", plane_transform);
   dict.Add("damage_rect", damage_rect.ToString());
diff --git a/ui/ozone/platform/drm/gpu/drm_overlay_plane.h b/ui/ozone/platform/drm/gpu/drm_overlay_plane.h
index f33a4fa3a..57a6813 100644
--- a/ui/ozone/platform/drm/gpu/drm_overlay_plane.h
+++ b/ui/ozone/platform/drm/gpu/drm_overlay_plane.h
@@ -11,6 +11,7 @@
 #include "base/functional/bind.h"
 #include "base/memory/scoped_refptr.h"
 #include "third_party/perfetto/include/perfetto/tracing/traced_value_forward.h"
+#include "ui/gfx/color_space.h"
 #include "ui/gfx/geometry/rect.h"
 #include "ui/gfx/geometry/rect_f.h"
 #include "ui/gfx/overlay_plane_data.h"
@@ -28,11 +29,14 @@
 typedef std::vector<DrmOverlayPlane> DrmOverlayPlaneList;
 
 struct DrmOverlayPlane {
-  // Simpler constructor for the primary plane.
-  explicit DrmOverlayPlane(const scoped_refptr<DrmFramebuffer>& buffer,
-                           std::unique_ptr<gfx::GpuFence> gpu_fence);
+  // Simpler constructor for tests.
+  static DrmOverlayPlane TestPlane(
+      const scoped_refptr<DrmFramebuffer>& buffer,
+      gfx::ColorSpace color_space = gfx::ColorSpace::CreateSRGB(),
+      std::unique_ptr<gfx::GpuFence> gpu_fence = nullptr);
 
   DrmOverlayPlane(const scoped_refptr<DrmFramebuffer>& buffer,
+                  const gfx::ColorSpace& color_space,
                   int z_order,
                   gfx::OverlayTransform plane_transform,
                   const gfx::Rect& damage_rect,
@@ -66,6 +70,7 @@
       const std::vector<DrmOverlayPlane>& planes);
 
   scoped_refptr<DrmFramebuffer> buffer;
+  gfx::ColorSpace color_space;
   int z_order = 0;
   gfx::OverlayTransform plane_transform;
   gfx::Rect damage_rect;
diff --git a/ui/ozone/platform/drm/gpu/drm_overlay_validator.cc b/ui/ozone/platform/drm/gpu/drm_overlay_validator.cc
index 1350fa5..9c7a327 100644
--- a/ui/ozone/platform/drm/gpu/drm_overlay_validator.cc
+++ b/ui/ozone/platform/drm/gpu/drm_overlay_validator.cc
@@ -93,7 +93,7 @@
   scoped_refptr<DrmFramebuffer> buffer =
       GetBufferForPageFlipTest(window_, param, &reusable_buffers);
 
-  return DrmOverlayPlane(buffer, param.plane_z_order,
+  return DrmOverlayPlane(buffer, param.color_space, param.plane_z_order,
                          absl::get<gfx::OverlayTransform>(param.transform),
                          gfx::ToNearestRect(param.display_rect),
                          gfx::ToNearestRect(param.display_rect),
diff --git a/ui/ozone/platform/drm/gpu/drm_overlay_validator_unittest.cc b/ui/ozone/platform/drm/gpu/drm_overlay_validator_unittest.cc
index e8ef9303..7c881f8 100644
--- a/ui/ozone/platform/drm/gpu/drm_overlay_validator_unittest.cc
+++ b/ui/ozone/platform/drm/gpu/drm_overlay_validator_unittest.cc
@@ -91,7 +91,7 @@
     CommitRequest commit_request;
 
     DrmOverlayPlaneList modeset_planes;
-    modeset_planes.emplace_back(CreateBuffer(), nullptr);
+    modeset_planes.push_back(DrmOverlayPlane::TestPlane(CreateBuffer()));
 
     controller->GetModesetProps(&commit_request, modeset_planes, kDefaultMode,
                                 /*enable_vrr=*/false);
@@ -260,10 +260,10 @@
 
   scoped_refptr<DrmFramebuffer> drm_framebuffer = CreateOverlayBuffer(
       GetFourCCFormatFromBufferFormat(params.format), params.buffer_size);
-  plane_list_.emplace_back(std::move(drm_framebuffer), params.plane_z_order,
-                           absl::get<gfx::OverlayTransform>(params.transform),
-                           gfx::Rect(), gfx::ToNearestRect(params.display_rect),
-                           params.crop_rect, true, nullptr);
+  plane_list_.emplace_back(
+      std::move(drm_framebuffer), params.color_space, params.plane_z_order,
+      absl::get<gfx::OverlayTransform>(params.transform), gfx::Rect(),
+      gfx::ToNearestRect(params.display_rect), params.crop_rect, true, nullptr);
 }
 
 void MAYBE_DrmOverlayValidatorTest::TearDown() {
diff --git a/ui/ozone/platform/drm/gpu/drm_window_unittest.cc b/ui/ozone/platform/drm/gpu/drm_window_unittest.cc
index 3199f06..d2467744 100644
--- a/ui/ozone/platform/drm/gpu/drm_window_unittest.cc
+++ b/ui/ozone/platform/drm/gpu/drm_window_unittest.cc
@@ -226,7 +226,7 @@
 
 TEST_F(MAYBE_DrmWindowTest, CheckPageflipSuccessOnSuccessfulSwap) {
   DrmOverlayPlaneList planes;
-  planes.emplace_back(CreateBuffer(), nullptr);
+  planes.push_back(DrmOverlayPlane::TestPlane(CreateBuffer()));
 
   // Window was re-sized, so the expectation is to re-create the buffers first.
   DrmWindow* window = screen_manager_->GetWindow(kDefaultWidgetHandle);
@@ -260,7 +260,7 @@
 
 TEST_F(MAYBE_DrmWindowTest, CheckPageflipFailureOnFailedSwap) {
   DrmOverlayPlaneList planes;
-  planes.emplace_back(CreateBuffer(), nullptr);
+  planes.push_back(DrmOverlayPlane::TestPlane(CreateBuffer()));
 
   // Window was re-sized, so the expectation is to re-create the buffers first.
   DrmWindow* window = screen_manager_->GetWindow(kDefaultWidgetHandle);
diff --git a/ui/ozone/platform/drm/gpu/hardware_display_controller_unittest.cc b/ui/ozone/platform/drm/gpu/hardware_display_controller_unittest.cc
index d2416b1..3cf6e3f4 100644
--- a/ui/ozone/platform/drm/gpu/hardware_display_controller_unittest.cc
+++ b/ui/ozone/platform/drm/gpu/hardware_display_controller_unittest.cc
@@ -280,7 +280,7 @@
 
 TEST_F(MAYBE_HardwareDisplayControllerTest, CheckModesettingResult) {
   DrmOverlayPlaneList modeset_planes;
-  modeset_planes.emplace_back(CreateBuffer(), nullptr);
+  modeset_planes.push_back(DrmOverlayPlane::TestPlane(CreateBuffer()));
 
   EXPECT_TRUE(ModesetWithPlanes(modeset_planes));
   EXPECT_FALSE(
@@ -289,7 +289,7 @@
 
 TEST_F(MAYBE_HardwareDisplayControllerTest, CrtcPropsAfterModeset) {
   DrmOverlayPlaneList modeset_planes;
-  modeset_planes.emplace_back(CreateBuffer(), nullptr);
+  modeset_planes.push_back(DrmOverlayPlane::TestPlane(CreateBuffer()));
   EXPECT_TRUE(ModesetWithPlanes(modeset_planes));
 
   ScopedDrmObjectPropertyPtr crtc_props =
@@ -316,7 +316,7 @@
 
 TEST_F(MAYBE_HardwareDisplayControllerTest, ConnectorPropsAfterModeset) {
   DrmOverlayPlaneList modeset_planes;
-  modeset_planes.emplace_back(CreateBuffer(), nullptr);
+  modeset_planes.push_back(DrmOverlayPlane::TestPlane(CreateBuffer()));
   EXPECT_TRUE(ModesetWithPlanes(modeset_planes));
 
   ScopedDrmObjectPropertyPtr connector_props =
@@ -340,7 +340,7 @@
 TEST_F(MAYBE_HardwareDisplayControllerTest,
        BadLinkStatusConnectorPropsAfterModeset) {
   DrmOverlayPlaneList modeset_planes;
-  modeset_planes.emplace_back(CreateBuffer(), nullptr);
+  modeset_planes.push_back(DrmOverlayPlane::TestPlane(CreateBuffer()));
   EXPECT_TRUE(ModesetWithPlanes(modeset_planes));
 
   ScopedDrmObjectPropertyPtr bad_link_connector_props =
@@ -357,7 +357,9 @@
 TEST_F(MAYBE_HardwareDisplayControllerTest, PlanePropsAfterModeset) {
   const FakeFenceFD fake_fence_fd;
   DrmOverlayPlaneList modeset_planes;
-  modeset_planes.emplace_back(CreateBuffer(), fake_fence_fd.GetGpuFence());
+  modeset_planes.push_back(
+      DrmOverlayPlane::TestPlane(CreateBuffer(), gfx::ColorSpace::CreateSRGB(),
+                                 fake_fence_fd.GetGpuFence()));
   EXPECT_TRUE(ModesetWithPlanes(modeset_planes));
 
   ScopedDrmObjectPropertyPtr plane_props =
@@ -444,7 +446,7 @@
 
 TEST_F(MAYBE_HardwareDisplayControllerTest, FenceFdValueChange) {
   DrmOverlayPlaneList modeset_planes;
-  DrmOverlayPlane plane(CreateBuffer(), nullptr);
+  DrmOverlayPlane plane(DrmOverlayPlane::TestPlane(CreateBuffer()));
   modeset_planes.push_back(plane.Clone());
   EXPECT_TRUE(ModesetWithPlanes(modeset_planes));
 
@@ -498,7 +500,7 @@
 
 TEST_F(MAYBE_HardwareDisplayControllerTest, CheckDisableResetsProps) {
   DrmOverlayPlaneList modeset_planes;
-  modeset_planes.emplace_back(CreateBuffer(), nullptr);
+  modeset_planes.push_back(DrmOverlayPlane::TestPlane(CreateBuffer()));
   EXPECT_TRUE(ModesetWithPlanes(modeset_planes));
 
   // Test props values after disabling.
@@ -606,11 +608,11 @@
 
 TEST_F(MAYBE_HardwareDisplayControllerTest, CheckStateAfterPageFlip) {
   DrmOverlayPlaneList modeset_planes;
-  modeset_planes.emplace_back(CreateBuffer(), nullptr);
+  modeset_planes.push_back(DrmOverlayPlane::TestPlane(CreateBuffer()));
   EXPECT_TRUE(ModesetWithPlanes(modeset_planes));
   EXPECT_EQ(1, drm_->get_commit_count());
 
-  DrmOverlayPlane page_flip_plane(CreateBuffer(), nullptr);
+  DrmOverlayPlane page_flip_plane(DrmOverlayPlane::TestPlane(CreateBuffer()));
   std::vector<DrmOverlayPlane> page_flip_planes;
   page_flip_planes.push_back(page_flip_plane.Clone());
 
@@ -634,16 +636,17 @@
   drm_->set_set_crtc_expectation(false);
 
   DrmOverlayPlaneList modeset_planes;
-  modeset_planes.emplace_back(CreateBuffer(), nullptr);
+  modeset_planes.push_back(DrmOverlayPlane::TestPlane(CreateBuffer()));
   EXPECT_FALSE(ModesetWithPlanes(modeset_planes));
 }
 
 TEST_F(MAYBE_HardwareDisplayControllerTest, CheckOverlayPresent) {
   DrmOverlayPlaneList planes;
-  planes.emplace_back(CreateBuffer(), nullptr);
-  planes.emplace_back(CreateOverlayBuffer(), 1, gfx::OVERLAY_TRANSFORM_NONE,
-                      gfx::Rect(), gfx::Rect(kOverlaySize),
-                      gfx::RectF(kDefaultModeSizeF), true, nullptr);
+  planes.push_back(DrmOverlayPlane::TestPlane(CreateBuffer()));
+  planes.emplace_back(CreateOverlayBuffer(), gfx::ColorSpace::CreateSRGB(), 1,
+                      gfx::OVERLAY_TRANSFORM_NONE, gfx::Rect(),
+                      gfx::Rect(kOverlaySize), gfx::RectF(kDefaultModeSizeF),
+                      true, nullptr);
 
   EXPECT_TRUE(ModesetWithPlanes(planes));
   EXPECT_EQ(1, drm_->get_commit_count());
@@ -660,10 +663,11 @@
 
 TEST_F(MAYBE_HardwareDisplayControllerTest, CheckOverlayTestMode) {
   DrmOverlayPlaneList planes;
-  planes.emplace_back(CreateBuffer(), nullptr);
-  planes.emplace_back(CreateOverlayBuffer(), 1, gfx::OVERLAY_TRANSFORM_NONE,
-                      gfx::Rect(), gfx::Rect(kOverlaySize),
-                      gfx::RectF(kDefaultModeSizeF), true, nullptr);
+  planes.push_back(DrmOverlayPlane::TestPlane(CreateBuffer()));
+  planes.emplace_back(CreateOverlayBuffer(), gfx::ColorSpace::CreateSRGB(), 1,
+                      gfx::OVERLAY_TRANSFORM_NONE, gfx::Rect(),
+                      gfx::Rect(kOverlaySize), gfx::RectF(kDefaultModeSizeF),
+                      true, nullptr);
 
   EXPECT_TRUE(ModesetWithPlanes(planes));
   EXPECT_EQ(1, drm_->get_commit_count());
@@ -694,9 +698,10 @@
 
 TEST_F(MAYBE_HardwareDisplayControllerTest, AcceptUnderlays) {
   DrmOverlayPlaneList planes;
-  planes.emplace_back(CreateBuffer(), nullptr);
-  planes.emplace_back(CreateBuffer(), -1, gfx::OVERLAY_TRANSFORM_NONE,
-                      gfx::Rect(), gfx::Rect(kDefaultModeSize),
+  planes.push_back(DrmOverlayPlane::TestPlane(CreateBuffer()));
+  planes.emplace_back(CreateBuffer(), gfx::ColorSpace::CreateSRGB(), -1,
+                      gfx::OVERLAY_TRANSFORM_NONE, gfx::Rect(),
+                      gfx::Rect(kDefaultModeSize),
                       gfx::RectF(kDefaultModeSizeF), true, nullptr);
 
   EXPECT_TRUE(ModesetWithPlanes(planes));
@@ -712,7 +717,7 @@
       drm_.get(), secondary_crtc_, drm_->connector_property(1).id));
 
   DrmOverlayPlaneList planes;
-  planes.emplace_back(CreateBuffer(), nullptr);
+  planes.push_back(DrmOverlayPlane::TestPlane(CreateBuffer()));
 
   EXPECT_TRUE(ModesetWithPlanes(planes));
   EXPECT_EQ(1, drm_->get_commit_count());
@@ -738,7 +743,7 @@
       drm_.get(), secondary_crtc_, drm_->connector_property(1).id));
 
   DrmOverlayPlaneList planes;
-  planes.emplace_back(CreateBuffer(), nullptr);
+  planes.push_back(DrmOverlayPlane::TestPlane(CreateBuffer()));
   EXPECT_TRUE(ModesetWithPlanes(planes));
 
   SchedulePageFlip(DrmOverlayPlane::Clone(planes));
@@ -780,7 +785,7 @@
 
 TEST_F(MAYBE_HardwareDisplayControllerTest, PlaneStateAfterDestroyingCrtc) {
   DrmOverlayPlaneList planes;
-  planes.emplace_back(CreateBuffer(), nullptr);
+  planes.push_back(DrmOverlayPlane::TestPlane(CreateBuffer()));
   EXPECT_TRUE(ModesetWithPlanes(planes));
 
   SchedulePageFlip(std::move(planes));
@@ -808,7 +813,7 @@
       drm_.get(), secondary_crtc_, drm_->connector_property(1).id));
 
   DrmOverlayPlaneList planes;
-  planes.emplace_back(CreateBuffer(), nullptr);
+  planes.push_back(DrmOverlayPlane::TestPlane(CreateBuffer()));
   EXPECT_TRUE(ModesetWithPlanes(planes));
 
   SchedulePageFlip(DrmOverlayPlane::Clone(planes));
@@ -853,7 +858,7 @@
 
 TEST_F(MAYBE_HardwareDisplayControllerTest, ModesetWhilePageFlipping) {
   DrmOverlayPlaneList planes;
-  planes.emplace_back(CreateBuffer(), nullptr);
+  planes.push_back(DrmOverlayPlane::TestPlane(CreateBuffer()));
   EXPECT_TRUE(ModesetWithPlanes(planes));
 
   SchedulePageFlip(DrmOverlayPlane::Clone(planes));
@@ -867,11 +872,11 @@
 TEST_F(MAYBE_HardwareDisplayControllerTest,
        FailPageFlippingWithNoSavingModeset) {
   DrmOverlayPlaneList modeset_planes;
-  modeset_planes.emplace_back(CreateBuffer(), nullptr);
+  modeset_planes.push_back(DrmOverlayPlane::TestPlane(CreateBuffer()));
   ASSERT_TRUE(ModesetWithPlanes(modeset_planes));
 
   std::vector<DrmOverlayPlane> page_flip_planes;
-  page_flip_planes.emplace_back(CreateBuffer(), nullptr);
+  page_flip_planes.push_back(DrmOverlayPlane::TestPlane(CreateBuffer()));
 
   // Page flip fails, so a GPU process self-destruct sequence is initiated.
   drm_->set_commit_expectation(false);
@@ -886,11 +891,11 @@
 
 TEST_F(MAYBE_HardwareDisplayControllerTest, FailPageFlippingWithSavingModeset) {
   DrmOverlayPlaneList modeset_planes;
-  modeset_planes.emplace_back(CreateBuffer(), nullptr);
+  modeset_planes.push_back(DrmOverlayPlane::TestPlane(CreateBuffer()));
   ASSERT_TRUE(ModesetWithPlanes(modeset_planes));
 
   std::vector<DrmOverlayPlane> page_flip_planes;
-  page_flip_planes.emplace_back(CreateBuffer(), nullptr);
+  page_flip_planes.push_back(DrmOverlayPlane::TestPlane(CreateBuffer()));
 
   // Page flip fails, so a GPU process self-destruct sequence is initiated.
   drm_->set_commit_expectation(false);
@@ -904,7 +909,7 @@
 
   // A modeset event occurs and prevents the GPU process from crashing.
   modeset_planes.clear();
-  modeset_planes.emplace_back(CreateBuffer(), nullptr);
+  modeset_planes.push_back(DrmOverlayPlane::TestPlane(CreateBuffer()));
   ASSERT_TRUE(ModesetWithPlanes(modeset_planes));
 
   // Ensure self-destruct time runs out without process death.
@@ -914,7 +919,7 @@
 TEST_F(MAYBE_HardwareDisplayControllerTest,
        RecreateBuffersOnOldPlanesPageFlipFailure) {
   DrmOverlayPlaneList planes;
-  planes.emplace_back(CreateBuffer(), nullptr);
+  planes.push_back(DrmOverlayPlane::TestPlane(CreateBuffer()));
   ASSERT_TRUE(ModesetWithPlanes(planes));
 
   // Page flip fails due to planes being allocated prior to the last modeset.
@@ -928,7 +933,7 @@
   // Next page flip passes, so the GPU process is safe.
   drm_->set_commit_expectation(true);
   planes.clear();
-  planes.emplace_back(CreateBuffer(), nullptr);
+  planes.push_back(DrmOverlayPlane::TestPlane(CreateBuffer()));
   SchedulePageFlip(std::move(planes));
 
   // Ensure self-destruct time runs out without process death.
@@ -941,12 +946,13 @@
 
 TEST_F(MAYBE_HardwareDisplayControllerTest, CheckNoPrimaryPlaneOnFlip) {
   DrmOverlayPlaneList modeset_planes;
-  modeset_planes.emplace_back(CreateBuffer(), nullptr);
+  modeset_planes.push_back(DrmOverlayPlane::TestPlane(CreateBuffer()));
   EXPECT_TRUE(ModesetWithPlanes(modeset_planes));
 
   std::vector<DrmOverlayPlane> page_flip_planes;
-  page_flip_planes.emplace_back(CreateBuffer(), 1, gfx::OVERLAY_TRANSFORM_NONE,
-                                gfx::Rect(), gfx::Rect(kDefaultModeSize),
+  page_flip_planes.emplace_back(CreateBuffer(), gfx::ColorSpace::CreateSRGB(),
+                                1, gfx::OVERLAY_TRANSFORM_NONE, gfx::Rect(),
+                                gfx::Rect(kDefaultModeSize),
                                 gfx::RectF(0, 0, 1, 1), true, nullptr);
   SchedulePageFlip(std::move(page_flip_planes));
 
@@ -957,20 +963,23 @@
 
 TEST_F(MAYBE_HardwareDisplayControllerTest, PageFlipWithUnassignablePlanes) {
   DrmOverlayPlaneList modeset_planes;
-  modeset_planes.emplace_back(CreateBuffer(), nullptr);
+  modeset_planes.push_back(DrmOverlayPlane::TestPlane(CreateBuffer()));
   ASSERT_TRUE(ModesetWithPlanes(modeset_planes));
 
   {
     std::vector<DrmOverlayPlane> page_flip_planes;
-    page_flip_planes.emplace_back(
-        CreateBuffer(), 1, gfx::OVERLAY_TRANSFORM_NONE, gfx::Rect(),
-        gfx::Rect(kDefaultModeSize), gfx::RectF(0, 0, 1, 1), true, nullptr);
-    page_flip_planes.emplace_back(
-        CreateBuffer(), 1, gfx::OVERLAY_TRANSFORM_NONE, gfx::Rect(),
-        gfx::Rect(kDefaultModeSize), gfx::RectF(0, 0, 1, 1), true, nullptr);
-    page_flip_planes.emplace_back(
-        CreateBuffer(), 1, gfx::OVERLAY_TRANSFORM_NONE, gfx::Rect(),
-        gfx::Rect(kDefaultModeSize), gfx::RectF(0, 0, 1, 1), true, nullptr);
+    page_flip_planes.emplace_back(CreateBuffer(), gfx::ColorSpace::CreateSRGB(),
+                                  1, gfx::OVERLAY_TRANSFORM_NONE, gfx::Rect(),
+                                  gfx::Rect(kDefaultModeSize),
+                                  gfx::RectF(0, 0, 1, 1), true, nullptr);
+    page_flip_planes.emplace_back(CreateBuffer(), gfx::ColorSpace::CreateSRGB(),
+                                  1, gfx::OVERLAY_TRANSFORM_NONE, gfx::Rect(),
+                                  gfx::Rect(kDefaultModeSize),
+                                  gfx::RectF(0, 0, 1, 1), true, nullptr);
+    page_flip_planes.emplace_back(CreateBuffer(), gfx::ColorSpace::CreateSRGB(),
+                                  1, gfx::OVERLAY_TRANSFORM_NONE, gfx::Rect(),
+                                  gfx::Rect(kDefaultModeSize),
+                                  gfx::RectF(0, 0, 1, 1), true, nullptr);
     SchedulePageFlip(std::move(page_flip_planes));
   }
 
@@ -985,7 +994,7 @@
 
 TEST_F(MAYBE_HardwareDisplayControllerTest, SomePlaneAssignmentFailuresAreOk) {
   DrmOverlayPlaneList modeset_planes;
-  modeset_planes.emplace_back(CreateBuffer(), nullptr);
+  modeset_planes.push_back(DrmOverlayPlane::TestPlane(CreateBuffer()));
   ASSERT_TRUE(ModesetWithPlanes(modeset_planes));
 
   constexpr int kUnassignableFlips = 3;
@@ -994,14 +1003,17 @@
     {
       std::vector<DrmOverlayPlane> page_flip_planes;
       page_flip_planes.emplace_back(
-          CreateBuffer(), 1, gfx::OVERLAY_TRANSFORM_NONE, gfx::Rect(),
-          gfx::Rect(kDefaultModeSize), gfx::RectF(0, 0, 1, 1), true, nullptr);
+          CreateBuffer(), gfx::ColorSpace::CreateSRGB(), 1,
+          gfx::OVERLAY_TRANSFORM_NONE, gfx::Rect(), gfx::Rect(kDefaultModeSize),
+          gfx::RectF(0, 0, 1, 1), true, nullptr);
       page_flip_planes.emplace_back(
-          CreateBuffer(), 1, gfx::OVERLAY_TRANSFORM_NONE, gfx::Rect(),
-          gfx::Rect(kDefaultModeSize), gfx::RectF(0, 0, 1, 1), true, nullptr);
+          CreateBuffer(), gfx::ColorSpace::CreateSRGB(), 1,
+          gfx::OVERLAY_TRANSFORM_NONE, gfx::Rect(), gfx::Rect(kDefaultModeSize),
+          gfx::RectF(0, 0, 1, 1), true, nullptr);
       page_flip_planes.emplace_back(
-          CreateBuffer(), 1, gfx::OVERLAY_TRANSFORM_NONE, gfx::Rect(),
-          gfx::Rect(kDefaultModeSize), gfx::RectF(0, 0, 1, 1), true, nullptr);
+          CreateBuffer(), gfx::ColorSpace::CreateSRGB(), 1,
+          gfx::OVERLAY_TRANSFORM_NONE, gfx::Rect(), gfx::Rect(kDefaultModeSize),
+          gfx::RectF(0, 0, 1, 1), true, nullptr);
       SchedulePageFlip(std::move(page_flip_planes));
     }
     drm_->RunCallbacks();
@@ -1016,8 +1028,9 @@
     {
       std::vector<DrmOverlayPlane> page_flip_planes;
       page_flip_planes.emplace_back(
-          CreateBuffer(), 1, gfx::OVERLAY_TRANSFORM_NONE, gfx::Rect(),
-          gfx::Rect(kDefaultModeSize), gfx::RectF(0, 0, 1, 1), true, nullptr);
+          CreateBuffer(), gfx::ColorSpace::CreateSRGB(), 1,
+          gfx::OVERLAY_TRANSFORM_NONE, gfx::Rect(), gfx::Rect(kDefaultModeSize),
+          gfx::RectF(0, 0, 1, 1), true, nullptr);
       SchedulePageFlip(std::move(page_flip_planes));
     }
     drm_->RunCallbacks();
@@ -1035,15 +1048,16 @@
 TEST_F(MAYBE_HardwareDisplayControllerTest,
        CrashOnTooManyFlakyPlaneAssignments) {
   DrmOverlayPlaneList modeset_planes;
-  modeset_planes.emplace_back(CreateBuffer(), nullptr);
+  modeset_planes.push_back(DrmOverlayPlane::TestPlane(CreateBuffer()));
   ASSERT_TRUE(ModesetWithPlanes(modeset_planes));
 
   auto do_successful_flip = [&]() {
     {
       std::vector<DrmOverlayPlane> page_flip_planes;
       page_flip_planes.emplace_back(
-          CreateBuffer(), 1, gfx::OVERLAY_TRANSFORM_NONE, gfx::Rect(),
-          gfx::Rect(kDefaultModeSize), gfx::RectF(0, 0, 1, 1), true, nullptr);
+          CreateBuffer(), gfx::ColorSpace::CreateSRGB(), 1,
+          gfx::OVERLAY_TRANSFORM_NONE, gfx::Rect(), gfx::Rect(kDefaultModeSize),
+          gfx::RectF(0, 0, 1, 1), true, nullptr);
       SchedulePageFlip(std::move(page_flip_planes));
     }
     drm_->RunCallbacks();
@@ -1056,14 +1070,17 @@
     {
       std::vector<DrmOverlayPlane> page_flip_planes;
       page_flip_planes.emplace_back(
-          CreateBuffer(), 1, gfx::OVERLAY_TRANSFORM_NONE, gfx::Rect(),
-          gfx::Rect(kDefaultModeSize), gfx::RectF(0, 0, 1, 1), true, nullptr);
+          CreateBuffer(), gfx::ColorSpace::CreateSRGB(), 1,
+          gfx::OVERLAY_TRANSFORM_NONE, gfx::Rect(), gfx::Rect(kDefaultModeSize),
+          gfx::RectF(0, 0, 1, 1), true, nullptr);
       page_flip_planes.emplace_back(
-          CreateBuffer(), 1, gfx::OVERLAY_TRANSFORM_NONE, gfx::Rect(),
-          gfx::Rect(kDefaultModeSize), gfx::RectF(0, 0, 1, 1), true, nullptr);
+          CreateBuffer(), gfx::ColorSpace::CreateSRGB(), 1,
+          gfx::OVERLAY_TRANSFORM_NONE, gfx::Rect(), gfx::Rect(kDefaultModeSize),
+          gfx::RectF(0, 0, 1, 1), true, nullptr);
       page_flip_planes.emplace_back(
-          CreateBuffer(), 1, gfx::OVERLAY_TRANSFORM_NONE, gfx::Rect(),
-          gfx::Rect(kDefaultModeSize), gfx::RectF(0, 0, 1, 1), true, nullptr);
+          CreateBuffer(), gfx::ColorSpace::CreateSRGB(), 1,
+          gfx::OVERLAY_TRANSFORM_NONE, gfx::Rect(), gfx::Rect(kDefaultModeSize),
+          gfx::RectF(0, 0, 1, 1), true, nullptr);
       SchedulePageFlip(std::move(page_flip_planes));
     }
     drm_->RunCallbacks();
@@ -1098,15 +1115,16 @@
 TEST_F(MAYBE_HardwareDisplayControllerTest,
        CrashOnTooManyFailedPlaneAssignments) {
   DrmOverlayPlaneList modeset_planes;
-  modeset_planes.emplace_back(CreateBuffer(), nullptr);
+  modeset_planes.push_back(DrmOverlayPlane::TestPlane(CreateBuffer()));
   ASSERT_TRUE(ModesetWithPlanes(modeset_planes));
 
   auto do_successful_flip = [&]() {
     {
       std::vector<DrmOverlayPlane> page_flip_planes;
       page_flip_planes.emplace_back(
-          CreateBuffer(), 1, gfx::OVERLAY_TRANSFORM_NONE, gfx::Rect(),
-          gfx::Rect(kDefaultModeSize), gfx::RectF(0, 0, 1, 1), true, nullptr);
+          CreateBuffer(), gfx::ColorSpace::CreateSRGB(), 1,
+          gfx::OVERLAY_TRANSFORM_NONE, gfx::Rect(), gfx::Rect(kDefaultModeSize),
+          gfx::RectF(0, 0, 1, 1), true, nullptr);
       SchedulePageFlip(std::move(page_flip_planes));
     }
     drm_->RunCallbacks();
@@ -1119,14 +1137,17 @@
     {
       std::vector<DrmOverlayPlane> page_flip_planes;
       page_flip_planes.emplace_back(
-          CreateBuffer(), 1, gfx::OVERLAY_TRANSFORM_NONE, gfx::Rect(),
-          gfx::Rect(kDefaultModeSize), gfx::RectF(0, 0, 1, 1), true, nullptr);
+          CreateBuffer(), gfx::ColorSpace::CreateSRGB(), 1,
+          gfx::OVERLAY_TRANSFORM_NONE, gfx::Rect(), gfx::Rect(kDefaultModeSize),
+          gfx::RectF(0, 0, 1, 1), true, nullptr);
       page_flip_planes.emplace_back(
-          CreateBuffer(), 1, gfx::OVERLAY_TRANSFORM_NONE, gfx::Rect(),
-          gfx::Rect(kDefaultModeSize), gfx::RectF(0, 0, 1, 1), true, nullptr);
+          CreateBuffer(), gfx::ColorSpace::CreateSRGB(), 1,
+          gfx::OVERLAY_TRANSFORM_NONE, gfx::Rect(), gfx::Rect(kDefaultModeSize),
+          gfx::RectF(0, 0, 1, 1), true, nullptr);
       page_flip_planes.emplace_back(
-          CreateBuffer(), 1, gfx::OVERLAY_TRANSFORM_NONE, gfx::Rect(),
-          gfx::Rect(kDefaultModeSize), gfx::RectF(0, 0, 1, 1), true, nullptr);
+          CreateBuffer(), gfx::ColorSpace::CreateSRGB(), 1,
+          gfx::OVERLAY_TRANSFORM_NONE, gfx::Rect(), gfx::Rect(kDefaultModeSize),
+          gfx::RectF(0, 0, 1, 1), true, nullptr);
       SchedulePageFlip(std::move(page_flip_planes));
     }
     drm_->RunCallbacks();
@@ -1153,7 +1174,7 @@
 
 TEST_F(MAYBE_HardwareDisplayControllerTest, AddCrtcMidPageFlip) {
   DrmOverlayPlaneList planes;
-  planes.emplace_back(CreateBuffer(), nullptr);
+  planes.push_back(DrmOverlayPlane::TestPlane(CreateBuffer()));
   EXPECT_TRUE(ModesetWithPlanes(planes));
 
   SchedulePageFlip(std::move(planes));
@@ -1168,7 +1189,7 @@
 
 TEST_F(MAYBE_HardwareDisplayControllerTest, RemoveCrtcMidPageFlip) {
   DrmOverlayPlaneList planes;
-  planes.emplace_back(CreateBuffer(), nullptr);
+  planes.push_back(DrmOverlayPlane::TestPlane(CreateBuffer()));
   EXPECT_TRUE(ModesetWithPlanes(planes));
 
   SchedulePageFlip(std::move(planes));
@@ -1185,12 +1206,13 @@
   InitializeDrmDevice(/* use_atomic= */ true);
 
   DrmOverlayPlaneList planes;
-  planes.emplace_back(CreateBuffer(), nullptr);
+  planes.push_back(DrmOverlayPlane::TestPlane(CreateBuffer()));
   EXPECT_TRUE(ModesetWithPlanes(planes));
 
-  planes.emplace_back(CreateOverlayBuffer(), 1, gfx::OVERLAY_TRANSFORM_NONE,
-                      gfx::Rect(), gfx::Rect(kOverlaySize),
-                      gfx::RectF(kDefaultModeSizeF), true, nullptr);
+  planes.emplace_back(CreateOverlayBuffer(), gfx::ColorSpace::CreateSRGB(), 1,
+                      gfx::OVERLAY_TRANSFORM_NONE, gfx::Rect(),
+                      gfx::Rect(kOverlaySize), gfx::RectF(kDefaultModeSizeF),
+                      true, nullptr);
   SchedulePageFlip(std::move(planes));
   drm_->RunCallbacks();
   EXPECT_EQ(gfx::SwapResult::SWAP_ACK, last_swap_result_);
@@ -1209,7 +1231,7 @@
 TEST_F(MAYBE_HardwareDisplayControllerTest, PageflipAfterModeset) {
   DrmOverlayPlaneList planes;
   scoped_refptr<DrmFramebuffer> buffer = CreateBuffer();
-  planes.emplace_back(buffer, nullptr);
+  planes.push_back(DrmOverlayPlane::TestPlane(buffer));
   EXPECT_TRUE(ModesetWithPlanes(planes));
 
   for (const auto& plane : planes) {
@@ -1231,7 +1253,7 @@
 TEST_F(MAYBE_HardwareDisplayControllerTest, PageflipBeforeModeset) {
   DrmOverlayPlaneList planes;
   scoped_refptr<DrmFramebuffer> buffer = CreateBuffer();
-  planes.emplace_back(buffer, nullptr);
+  planes.push_back(DrmOverlayPlane::TestPlane(buffer));
   EXPECT_TRUE(ModesetWithPlanes(planes));
 
   SchedulePageFlip(DrmOverlayPlane::Clone(planes));
@@ -1260,8 +1282,8 @@
 
 TEST_F(MAYBE_HardwareDisplayControllerTest, MultiplePlanesModeset) {
   DrmOverlayPlaneList modeset_planes;
-  modeset_planes.emplace_back(CreateBuffer(), nullptr);
-  modeset_planes.emplace_back(CreateBuffer(), nullptr);
+  modeset_planes.push_back(DrmOverlayPlane::TestPlane(CreateBuffer()));
+  modeset_planes.push_back(DrmOverlayPlane::TestPlane(CreateBuffer()));
   ASSERT_TRUE(ModesetWithPlanes(modeset_planes));
   EXPECT_EQ(drm_->plane_manager()
                 ->GetCrtcStateForCrtcId(primary_crtc_)
@@ -1279,11 +1301,11 @@
   InitializeDrmDevice(/*use_atomic=*/true, /*movable_planes=*/1);
 
   DrmOverlayPlaneList modeset_planes;
-  modeset_planes.emplace_back(CreateBuffer(), nullptr);
+  modeset_planes.push_back(DrmOverlayPlane::TestPlane(CreateBuffer()));
   EXPECT_TRUE(ModesetWithPlanes(modeset_planes));
   EXPECT_EQ(1, drm_->get_commit_count());
 
-  DrmOverlayPlane page_flip_plane(CreateBuffer(), nullptr);
+  DrmOverlayPlane page_flip_plane(DrmOverlayPlane::TestPlane(CreateBuffer()));
   std::vector<DrmOverlayPlane> page_flip_planes;
   page_flip_planes.push_back(page_flip_plane.Clone());
   page_flip_planes.push_back(page_flip_plane.Clone());
@@ -1308,14 +1330,15 @@
   InitializeDrmDevice(/*use_atomic=*/true, /*movable_planes=*/1);
 
   DrmOverlayPlaneList modeset_planes;
-  modeset_planes.emplace_back(CreateBuffer(), nullptr);
+  modeset_planes.push_back(DrmOverlayPlane::TestPlane(CreateBuffer()));
   EXPECT_TRUE(ModesetWithPlanes(modeset_planes));
   EXPECT_EQ(1, drm_->get_commit_count());
 
   // InitializeDrmDevice created 2 crtcs with 2 planes, plus a movable plane.
   // Try to fill 'em up:
   auto flip_all_planes = [&]() {
-    DrmOverlayPlane page_flip_plane(CreateBuffer(), nullptr);
+    DrmOverlayPlane page_flip_plane(DrmOverlayPlane::TestPlane(CreateBuffer()));
+
     std::vector<DrmOverlayPlane> page_flip_planes;
     page_flip_planes.push_back(page_flip_plane.Clone());
     page_flip_planes.push_back(page_flip_plane.Clone());
@@ -1345,9 +1368,9 @@
   InitializeDrmDevice(/*use_atomic=*/true, /*movable_planes=*/1);
 
   DrmOverlayPlaneList modeset_planes;
-  modeset_planes.emplace_back(CreateBuffer(), nullptr);
-  modeset_planes.emplace_back(CreateBuffer(), nullptr);
-  modeset_planes.emplace_back(CreateBuffer(), nullptr);
+  modeset_planes.push_back(DrmOverlayPlane::TestPlane(CreateBuffer()));
+  modeset_planes.push_back(DrmOverlayPlane::TestPlane(CreateBuffer()));
+  modeset_planes.push_back(DrmOverlayPlane::TestPlane(CreateBuffer()));
 
   HardwareDisplayPlane* movable_plane = GetMovableOverlays()[0];
   movable_plane->set_in_use(true);
@@ -1376,9 +1399,9 @@
       drm_, secondary_crtc_, drm_->connector_property(1).id));
 
   DrmOverlayPlaneList modeset_planes;
-  modeset_planes.emplace_back(CreateBuffer(), nullptr);
-  modeset_planes.emplace_back(CreateBuffer(), nullptr);
-  modeset_planes.emplace_back(CreateBuffer(), nullptr);
+  modeset_planes.push_back(DrmOverlayPlane::TestPlane(CreateBuffer()));
+  modeset_planes.push_back(DrmOverlayPlane::TestPlane(CreateBuffer()));
+  modeset_planes.push_back(DrmOverlayPlane::TestPlane(CreateBuffer()));
 
   EXPECT_FALSE(ModesetWithPlanes(modeset_planes))
       << "Should not modeset when two CRTCs both need the movable overlay "
@@ -1391,9 +1414,9 @@
 
   {
     DrmOverlayPlaneList flip_planes;
-    flip_planes.emplace_back(CreateBuffer(), nullptr);
-    flip_planes.emplace_back(CreateBuffer(), nullptr);
-    flip_planes.emplace_back(CreateBuffer(), nullptr);
+    flip_planes.push_back(DrmOverlayPlane::TestPlane(CreateBuffer()));
+    flip_planes.push_back(DrmOverlayPlane::TestPlane(CreateBuffer()));
+    flip_planes.push_back(DrmOverlayPlane::TestPlane(CreateBuffer()));
     SchedulePageFlip(std::move(flip_planes));
     drm_->RunCallbacks();
     EXPECT_TRUE(last_presentation_feedback_.failed())
@@ -1402,8 +1425,8 @@
 
   {
     DrmOverlayPlaneList flip_planes;
-    flip_planes.emplace_back(CreateBuffer(), nullptr);
-    flip_planes.emplace_back(CreateBuffer(), nullptr);
+    flip_planes.push_back(DrmOverlayPlane::TestPlane(CreateBuffer()));
+    flip_planes.push_back(DrmOverlayPlane::TestPlane(CreateBuffer()));
     SchedulePageFlip(std::move(flip_planes));
     drm_->RunCallbacks();
     EXPECT_FALSE(last_presentation_feedback_.failed())
@@ -1414,9 +1437,9 @@
   EXPECT_TRUE(removed_crtc);
   {
     DrmOverlayPlaneList flip_planes;
-    flip_planes.emplace_back(CreateBuffer(), nullptr);
-    flip_planes.emplace_back(CreateBuffer(), nullptr);
-    flip_planes.emplace_back(CreateBuffer(), nullptr);
+    flip_planes.push_back(DrmOverlayPlane::TestPlane(CreateBuffer()));
+    flip_planes.push_back(DrmOverlayPlane::TestPlane(CreateBuffer()));
+    flip_planes.push_back(DrmOverlayPlane::TestPlane(CreateBuffer()));
     SchedulePageFlip(std::move(flip_planes));
     drm_->RunCallbacks();
     EXPECT_FALSE(last_presentation_feedback_.failed())
@@ -1433,9 +1456,9 @@
       drm_, secondary_crtc_, drm_->connector_property(1).id));
 
   DrmOverlayPlaneList modeset_planes;
-  modeset_planes.emplace_back(CreateBuffer(), nullptr);
-  modeset_planes.emplace_back(CreateBuffer(), nullptr);
-  modeset_planes.emplace_back(CreateBuffer(), nullptr);
+  modeset_planes.push_back(DrmOverlayPlane::TestPlane(CreateBuffer()));
+  modeset_planes.push_back(DrmOverlayPlane::TestPlane(CreateBuffer()));
+  modeset_planes.push_back(DrmOverlayPlane::TestPlane(CreateBuffer()));
 
   EXPECT_TRUE(ModesetWithPlanes(modeset_planes))
       << "Should be able modeset with two CRTCs and two movable planes.";
diff --git a/ui/ozone/platform/drm/gpu/hardware_display_plane_manager_unittest.cc b/ui/ozone/platform/drm/gpu/hardware_display_plane_manager_unittest.cc
index e920f551..f051a7a 100644
--- a/ui/ozone/platform/drm/gpu/hardware_display_plane_manager_unittest.cc
+++ b/ui/ozone/platform/drm/gpu/hardware_display_plane_manager_unittest.cc
@@ -112,7 +112,7 @@
     HardwareDisplayPlaneList* state) {
   DrmOverlayPlaneList assigns;
   scoped_refptr<DrmFramebuffer> xrgb_buffer = CreateBuffer(kDefaultBufferSize);
-  assigns.emplace_back(xrgb_buffer, nullptr);
+  assigns.push_back(DrmOverlayPlane::TestPlane(xrgb_buffer));
   PerformPageFlip(crtc_idx, state, assigns);
 }
 
@@ -206,7 +206,7 @@
     // Check all 3 connectors exist
     for (size_t i = 0; i < connector_and_crtc_count; ++i) {
       DrmOverlayPlaneList overlays;
-      overlays.emplace_back(fake_buffer_, nullptr);
+      overlays.push_back(DrmOverlayPlane::TestPlane(fake_buffer_));
 
       CrtcCommitRequest request = CrtcCommitRequest::EnableCrtcRequest(
           fake_drm_->crtc_property(i).id, fake_drm_->connector_property(i).id,
@@ -231,21 +231,21 @@
     fake_drm_->plane_manager()->BeginFrame(&state);
     {
       DrmOverlayPlaneList overlays;
-      overlays.emplace_back(fake_buffer_, nullptr);
+      overlays.push_back(DrmOverlayPlane::TestPlane(fake_buffer_));
       commit_request.push_back(CrtcCommitRequest::EnableCrtcRequest(
           fake_drm_->crtc_property(0).id, kConnectorIdBase, kDefaultMode,
           gfx::Point(), &state, std::move(overlays), /*enable_vrr=*/false));
     }
     {
       DrmOverlayPlaneList overlays;
-      overlays.emplace_back(fake_buffer_, nullptr);
+      overlays.push_back(DrmOverlayPlane::TestPlane(fake_buffer_));
       commit_request.push_back(CrtcCommitRequest::EnableCrtcRequest(
           fake_drm_->crtc_property(1).id, kConnectorIdBase + 1, kDefaultMode,
           gfx::Point(), &state, std::move(overlays), /*enable_vrr=*/false));
     }
     {
       DrmOverlayPlaneList overlays;
-      overlays.emplace_back(fake_buffer_, nullptr);
+      overlays.push_back(DrmOverlayPlane::TestPlane(fake_buffer_));
       commit_request.push_back(CrtcCommitRequest::EnableCrtcRequest(
           fake_drm_->crtc_property(2).id, kConnectorIdBase + 3, kDefaultMode,
           gfx::Point(), &state, std::move(overlays), /*enable_vrr=*/false));
@@ -307,7 +307,7 @@
   fake_drm_->set_set_crtc_expectation(false);
 
   HardwareDisplayPlaneList state;
-  DrmOverlayPlane plane(fake_buffer_, nullptr);
+  DrmOverlayPlane plane(DrmOverlayPlane::TestPlane(fake_buffer_));
   CommitRequest commit_request;
 
   DrmOverlayPlaneList overlays;
@@ -339,7 +339,7 @@
 
 TEST_P(HardwareDisplayPlaneManagerLegacyTest, SinglePlaneAssignment) {
   DrmOverlayPlaneList assigns;
-  assigns.emplace_back(fake_buffer_, nullptr);
+  assigns.push_back(DrmOverlayPlane::TestPlane(fake_buffer_));
 
   auto drm_state = MockDrmDevice::MockDrmState::CreateStateWithDefaultObjects(
       /*crtc_count=*/2, /*planes_per_crtc=*/1);
@@ -352,7 +352,7 @@
 
 TEST_P(HardwareDisplayPlaneManagerLegacyTest, AddCursor) {
   DrmOverlayPlaneList assigns;
-  assigns.emplace_back(fake_buffer_, nullptr);
+  assigns.push_back(DrmOverlayPlane::TestPlane(fake_buffer_));
 
   auto drm_state = MockDrmDevice::MockDrmState::CreateStateWithDefaultObjects(
       /*crtc_count=*/2, /*planes_per_crtc=*/1);
@@ -370,7 +370,7 @@
 
 TEST_P(HardwareDisplayPlaneManagerLegacyTest, BadCrtc) {
   DrmOverlayPlaneList assigns;
-  assigns.emplace_back(fake_buffer_, nullptr);
+  assigns.push_back(DrmOverlayPlane::TestPlane(fake_buffer_));
 
   auto drm_state = MockDrmDevice::MockDrmState::CreateStateWithDefaultObjects(
       /*crtc_count=*/2, /*planes_per_crtc=*/1);
@@ -382,8 +382,8 @@
 
 TEST_P(HardwareDisplayPlaneManagerLegacyTest, NotEnoughPlanes) {
   DrmOverlayPlaneList assigns;
-  assigns.emplace_back(fake_buffer_, nullptr);
-  assigns.emplace_back(fake_buffer_, nullptr);
+  assigns.push_back(DrmOverlayPlane::TestPlane(fake_buffer_));
+  assigns.push_back(DrmOverlayPlane::TestPlane(fake_buffer_));
 
   auto drm_state = MockDrmDevice::MockDrmState::CreateStateWithDefaultObjects(
       /*crtc_count=*/2, /*planes_per_crtc=*/1);
@@ -395,7 +395,7 @@
 
 TEST_P(HardwareDisplayPlaneManagerLegacyTest, MultipleCrtcs) {
   DrmOverlayPlaneList assigns;
-  assigns.emplace_back(fake_buffer_, nullptr);
+  assigns.push_back(DrmOverlayPlane::TestPlane(fake_buffer_));
 
   auto drm_state = MockDrmDevice::MockDrmState::CreateStateWithDefaultObjects(
       /*crtc_count=*/2, /*planes_per_crtc=*/1);
@@ -410,8 +410,8 @@
 
 TEST_P(HardwareDisplayPlaneManagerLegacyTest, MultiplePlanesAndCrtcs) {
   DrmOverlayPlaneList assigns;
-  assigns.emplace_back(fake_buffer_, nullptr);
-  assigns.emplace_back(fake_buffer_, nullptr);
+  assigns.push_back(DrmOverlayPlane::TestPlane(fake_buffer_));
+  assigns.push_back(DrmOverlayPlane::TestPlane(fake_buffer_));
 
   auto drm_state = MockDrmDevice::MockDrmState::CreateStateWithDefaultObjects(
       /*crtc_count=*/2, /*planes_per_crtc=*/2);
@@ -428,7 +428,7 @@
   DrmOverlayPlaneList assigns;
   scoped_refptr<DrmFramebuffer> buffer =
       CreateBufferWithFormat(kDefaultBufferSize, DRM_FORMAT_NV12);
-  assigns.emplace_back(buffer, nullptr);
+  assigns.push_back(DrmOverlayPlane::TestPlane(buffer));
 
   auto drm_state = MockDrmDevice::MockDrmState::CreateStateWithDefaultObjects(
       /*crtc_count=*/2, /*planes_per_crtc=*/1);
@@ -441,7 +441,7 @@
       &state_, assigns, fake_drm_->crtc_property(0).id));
   assigns.clear();
   scoped_refptr<DrmFramebuffer> xrgb_buffer = CreateBuffer(kDefaultBufferSize);
-  assigns.emplace_back(xrgb_buffer, nullptr);
+  assigns.push_back(DrmOverlayPlane::TestPlane(xrgb_buffer));
   fake_drm_->plane_manager()->BeginFrame(&state_);
   EXPECT_TRUE(fake_drm_->plane_manager()->AssignOverlayPlanes(
       &state_, assigns, fake_drm_->crtc_property(0).id));
@@ -464,7 +464,7 @@
   HardwareDisplayPlaneList state;
   CommitRequest commit_request;
   DrmOverlayPlaneList overlays;
-  overlays.emplace_back(fake_buffer_, nullptr);
+  overlays.push_back(DrmOverlayPlane::TestPlane(fake_buffer_));
 
   commit_request.push_back(CrtcCommitRequest::EnableCrtcRequest(
       fake_drm_->crtc_property(0).id, fake_drm_->connector_property(0).id,
@@ -506,7 +506,7 @@
   HardwareDisplayPlaneList state;
   CommitRequest commit_request;
   DrmOverlayPlaneList overlays;
-  overlays.emplace_back(fake_buffer_, nullptr);
+  overlays.push_back(DrmOverlayPlane::TestPlane(fake_buffer_));
   commit_request.push_back(CrtcCommitRequest::EnableCrtcRequest(
       fake_drm_->crtc_property(0).id, fake_drm_->connector_property(0).id,
       kDefaultMode, gfx::Point(), &state, std::move(overlays),
@@ -550,7 +550,7 @@
   {
     CommitRequest commit_request;
     DrmOverlayPlaneList overlays;
-    overlays.emplace_back(fake_buffer_, nullptr);
+    overlays.push_back(DrmOverlayPlane::TestPlane(fake_buffer_));
     commit_request.push_back(CrtcCommitRequest::EnableCrtcRequest(
         fake_drm_->crtc_property(0).id, fake_drm_->connector_property(0).id,
         kDefaultMode, gfx::Point(), &state, std::move(overlays),
@@ -607,7 +607,7 @@
   {
     CommitRequest commit_request;
     DrmOverlayPlaneList overlays;
-    overlays.emplace_back(fake_buffer_, nullptr);
+    overlays.push_back(DrmOverlayPlane::TestPlane(fake_buffer_));
     commit_request.push_back(CrtcCommitRequest::EnableCrtcRequest(
         fake_drm_->crtc_property(0).id, fake_drm_->connector_property(0).id,
         kDefaultMode, gfx::Point(), &state, std::move(overlays),
@@ -628,7 +628,7 @@
   {
     CommitRequest commit_request;
     DrmOverlayPlaneList overlays;
-    overlays.emplace_back(fake_buffer_, nullptr);
+    overlays.push_back(DrmOverlayPlane::TestPlane(fake_buffer_));
     commit_request.push_back(CrtcCommitRequest::EnableCrtcRequest(
         fake_drm_->crtc_property(0).id, fake_drm_->connector_property(0).id,
         kDefaultMode, gfx::Point(), &state, std::move(overlays),
@@ -648,8 +648,8 @@
 
 TEST_P(HardwareDisplayPlaneManagerAtomicTest, MultiplePlaneAssignment) {
   DrmOverlayPlaneList assigns;
-  assigns.emplace_back(fake_buffer_, nullptr);
-  assigns.emplace_back(fake_buffer_, nullptr);
+  assigns.push_back(DrmOverlayPlane::TestPlane(fake_buffer_));
+  assigns.push_back(DrmOverlayPlane::TestPlane(fake_buffer_));
 
   auto drm_state = MockDrmDevice::MockDrmState::CreateStateWithDefaultObjects(
       /*crtc_count=*/2, /*planes_per_crtc=*/2);
@@ -662,8 +662,8 @@
 
 TEST_P(HardwareDisplayPlaneManagerAtomicTest, MultiplePlanesAndCrtcs) {
   DrmOverlayPlaneList assigns;
-  assigns.emplace_back(fake_buffer_, nullptr);
-  assigns.emplace_back(fake_buffer_, nullptr);
+  assigns.push_back(DrmOverlayPlane::TestPlane(fake_buffer_));
+  assigns.push_back(DrmOverlayPlane::TestPlane(fake_buffer_));
 
   auto drm_state = MockDrmDevice::MockDrmState::CreateStateWithDefaultObjects(
       /*crtc_count=*/2, /*planes_per_crtc=*/2);
@@ -680,8 +680,8 @@
   DrmOverlayPlaneList assigns;
   scoped_refptr<DrmFramebuffer> buffer = CreateBuffer(gfx::Size(1, 1));
 
-  assigns.emplace_back(fake_buffer_, nullptr);
-  assigns.emplace_back(buffer, nullptr);
+  assigns.push_back(DrmOverlayPlane::TestPlane(fake_buffer_));
+  assigns.push_back(DrmOverlayPlane::TestPlane(buffer));
 
   auto drm_state = MockDrmDevice::MockDrmState::CreateStateWithDefaultObjects(
       /*crtc_count=*/2, /*planes_per_crtc=*/1);
@@ -713,8 +713,8 @@
   scoped_refptr<DrmFramebuffer> primary_buffer =
       CreateBuffer(kDefaultBufferSize);
   scoped_refptr<DrmFramebuffer> overlay_buffer = CreateBuffer(gfx::Size(1, 1));
-  assigns.emplace_back(primary_buffer, nullptr);
-  assigns.emplace_back(overlay_buffer, nullptr);
+  assigns.push_back(DrmOverlayPlane::TestPlane(primary_buffer));
+  assigns.push_back(DrmOverlayPlane::TestPlane(overlay_buffer));
   HardwareDisplayPlaneList hdpl;
 
   scoped_refptr<PageFlipRequest> page_flip_request =
@@ -725,7 +725,7 @@
   EXPECT_TRUE(
       fake_drm_->plane_manager()->Commit(&hdpl, page_flip_request, nullptr));
   assigns.clear();
-  assigns.emplace_back(primary_buffer, nullptr);
+  assigns.push_back(DrmOverlayPlane::TestPlane(primary_buffer));
   fake_drm_->plane_manager()->BeginFrame(&hdpl);
   EXPECT_TRUE(fake_drm_->plane_manager()->AssignOverlayPlanes(
       &hdpl, assigns, fake_drm_->crtc_property(0).id));
@@ -747,8 +747,8 @@
   scoped_refptr<DrmFramebuffer> primary_buffer =
       CreateBuffer(kDefaultBufferSize);
   scoped_refptr<DrmFramebuffer> overlay_buffer = CreateBuffer(gfx::Size(1, 1));
-  assigns.emplace_back(primary_buffer, nullptr);
-  assigns.emplace_back(overlay_buffer, nullptr);
+  assigns.push_back(DrmOverlayPlane::TestPlane(primary_buffer));
+  assigns.push_back(DrmOverlayPlane::TestPlane(overlay_buffer));
   HardwareDisplayPlaneList hdpl;
 
   scoped_refptr<PageFlipRequest> page_flip_request =
@@ -759,7 +759,7 @@
   EXPECT_TRUE(
       fake_drm_->plane_manager()->Commit(&hdpl, page_flip_request, nullptr));
   EXPECT_TRUE(fake_drm_->plane_manager()->planes().front()->in_use());
-  assigns.emplace_back(overlay_buffer, nullptr);
+  assigns.push_back(DrmOverlayPlane::TestPlane(overlay_buffer));
 
   fake_drm_->plane_manager()->BeginFrame(&hdpl);
   // Assign overlay planes will fail since there aren't enough planes.
@@ -780,8 +780,8 @@
   scoped_refptr<DrmFramebuffer> primary_buffer =
       CreateBuffer(kDefaultBufferSize);
   scoped_refptr<DrmFramebuffer> overlay_buffer = CreateBuffer(gfx::Size(1, 1));
-  assigns.emplace_back(primary_buffer, nullptr);
-  assigns.emplace_back(overlay_buffer, nullptr);
+  assigns.push_back(DrmOverlayPlane::TestPlane(primary_buffer));
+  assigns.push_back(DrmOverlayPlane::TestPlane(overlay_buffer));
   HardwareDisplayPlaneList hdpl;
 
   scoped_refptr<PageFlipRequest> page_flip_request =
@@ -808,11 +808,14 @@
   fake_drm_->InitializeState(drm_state, use_atomic_);
 
   DrmOverlayPlaneList single_assign;
-  single_assign.emplace_back(CreateBuffer(kDefaultBufferSize), nullptr);
+  single_assign.push_back(
+      DrmOverlayPlane::TestPlane(CreateBuffer(kDefaultBufferSize)));
 
   DrmOverlayPlaneList overlay_assigns;
-  overlay_assigns.emplace_back(CreateBuffer(kDefaultBufferSize), nullptr);
-  overlay_assigns.emplace_back(CreateBuffer(kDefaultBufferSize), nullptr);
+  overlay_assigns.push_back(
+      DrmOverlayPlane::TestPlane(CreateBuffer(kDefaultBufferSize)));
+  overlay_assigns.push_back(
+      DrmOverlayPlane::TestPlane(CreateBuffer(kDefaultBufferSize)));
 
   HardwareDisplayPlaneList hdpl;
 
@@ -848,7 +851,7 @@
 
 TEST_P(HardwareDisplayPlaneManagerAtomicTest, MultipleFrames) {
   DrmOverlayPlaneList assigns;
-  assigns.emplace_back(fake_buffer_, nullptr);
+  assigns.push_back(DrmOverlayPlane::TestPlane(fake_buffer_));
 
   auto drm_state = MockDrmDevice::MockDrmState::CreateStateWithDefaultObjects(
       /*crtc_count=*/2, /*planes_per_crtc=*/2);
@@ -870,7 +873,7 @@
 
 TEST_P(HardwareDisplayPlaneManagerAtomicTest, MultipleFramesDifferentPlanes) {
   DrmOverlayPlaneList assigns;
-  assigns.emplace_back(fake_buffer_, nullptr);
+  assigns.push_back(DrmOverlayPlane::TestPlane(fake_buffer_));
 
   auto drm_state = MockDrmDevice::MockDrmState::CreateStateWithDefaultObjects(
       /*crtc_count=*/2, /*planes_per_crtc=*/2);
@@ -894,11 +897,12 @@
   fake_drm_->InitializeState(drm_state, /*use_atomic=*/true);
 
   DrmOverlayPlaneList assigns;
-  assigns.emplace_back(fake_buffer_, nullptr);
+  assigns.push_back(DrmOverlayPlane::TestPlane(fake_buffer_));
 
   DrmOverlayPlaneList assigns_with_overlay;
-  assigns_with_overlay.emplace_back(fake_buffer_, nullptr);
-  assigns_with_overlay.emplace_back(CreateBuffer(gfx::Size(1, 1)), nullptr);
+  assigns_with_overlay.push_back(DrmOverlayPlane::TestPlane(fake_buffer_));
+  assigns_with_overlay.push_back(
+      DrmOverlayPlane::TestPlane(CreateBuffer(gfx::Size(1, 1))));
 
   auto get_overlay_owner = [&]() {
     for (const auto& plane : fake_drm_->plane_manager()->planes()) {
@@ -944,8 +948,9 @@
   fake_drm_->InitializeState(drm_state, /*use_atomic=*/true);
 
   DrmOverlayPlaneList assigns_with_overlay;
-  assigns_with_overlay.emplace_back(fake_buffer_, nullptr);
-  assigns_with_overlay.emplace_back(CreateBuffer(gfx::Size(1, 1)), nullptr);
+  assigns_with_overlay.push_back(DrmOverlayPlane::TestPlane(fake_buffer_));
+  assigns_with_overlay.push_back(
+      DrmOverlayPlane::TestPlane(CreateBuffer(gfx::Size(1, 1))));
 
   auto get_overlay_owner = [&]() {
     for (const auto& plane : fake_drm_->plane_manager()->planes()) {
@@ -980,8 +985,9 @@
   fake_drm_->InitializeState(drm_state, /*use_atomic=*/true);
 
   DrmOverlayPlaneList assigns_with_overlay;
-  assigns_with_overlay.emplace_back(fake_buffer_, nullptr);
-  assigns_with_overlay.emplace_back(CreateBuffer(gfx::Size(1, 1)), nullptr);
+  assigns_with_overlay.push_back(DrmOverlayPlane::TestPlane(fake_buffer_));
+  assigns_with_overlay.push_back(
+      DrmOverlayPlane::TestPlane(CreateBuffer(gfx::Size(1, 1))));
 
   auto get_overlay_owner = [&]() {
     for (const auto& plane : fake_drm_->plane_manager()->planes()) {
@@ -1229,9 +1235,9 @@
   fake_drm_->InitializeState(drm_state, use_atomic_);
 
   DrmOverlayPlaneList assigns1;
-  assigns1.emplace_back(fake_buffer_, nullptr);
+  assigns1.push_back(DrmOverlayPlane::TestPlane(fake_buffer_));
   DrmOverlayPlaneList assigns2;
-  assigns2.emplace_back(fake_buffer2, nullptr);
+  assigns2.push_back(DrmOverlayPlane::TestPlane(fake_buffer2));
 
   fake_drm_->plane_manager()->BeginFrame(&state_);
   EXPECT_TRUE(fake_drm_->plane_manager()->AssignOverlayPlanes(
@@ -1447,17 +1453,21 @@
 
   DrmOverlayPlaneList CreatePlanesWithoutFences() {
     DrmOverlayPlaneList planes;
-    planes.emplace_back(CreateBuffer(kDefaultBufferSize), nullptr);
-    planes.emplace_back(CreateBuffer(kDefaultBufferSize), nullptr);
+    planes.push_back(
+        DrmOverlayPlane::TestPlane(CreateBuffer(kDefaultBufferSize)));
+    planes.push_back(
+        DrmOverlayPlane::TestPlane(CreateBuffer(kDefaultBufferSize)));
     return planes;
   }
 
   DrmOverlayPlaneList CreatePlanesWithFences() {
     DrmOverlayPlaneList planes;
-    planes.emplace_back(CreateBuffer(kDefaultBufferSize),
-                        fake_fence_fd1_.GetGpuFence());
-    planes.emplace_back(CreateBuffer(kDefaultBufferSize),
-                        fake_fence_fd2_.GetGpuFence());
+    planes.push_back(DrmOverlayPlane::TestPlane(
+        CreateBuffer(kDefaultBufferSize), gfx::ColorSpace::CreateSRGB(),
+        fake_fence_fd1_.GetGpuFence()));
+    planes.push_back(DrmOverlayPlane::TestPlane(
+        CreateBuffer(kDefaultBufferSize), gfx::ColorSpace::CreateSRGB(),
+        fake_fence_fd2_.GetGpuFence()));
     return planes;
   }
 
@@ -1561,7 +1571,7 @@
     scoped_refptr<DrmFramebuffer> framebuffer_original =
         DrmFramebuffer::AddFramebuffer(fake_drm_, buffer.get(),
                                        kDefaultBufferSize, {}, true);
-    assigns.emplace_back(framebuffer_original, nullptr);
+    assigns.push_back(DrmOverlayPlane::TestPlane(framebuffer_original));
     assigns.back().plane_transform =
         gfx::OVERLAY_TRANSFORM_ROTATE_CLOCKWISE_270;
 
@@ -1589,7 +1599,7 @@
     scoped_refptr<DrmFramebuffer> framebuffer_non_original =
         DrmFramebuffer::AddFramebuffer(fake_drm_, buffer.get(),
                                        kDefaultBufferSize, {}, false);
-    assigns.emplace_back(framebuffer_non_original, nullptr);
+    assigns.push_back(DrmOverlayPlane::TestPlane(framebuffer_non_original));
     assigns.back().plane_transform =
         gfx::OVERLAY_TRANSFORM_ROTATE_CLOCKWISE_270;
     EXPECT_FALSE(fake_drm_->plane_manager()->AssignOverlayPlanes(
@@ -1604,7 +1614,7 @@
 
   {
     DrmOverlayPlaneList assigns;
-    assigns.emplace_back(fake_buffer_, nullptr);
+    assigns.push_back(DrmOverlayPlane::TestPlane(fake_buffer_));
 
     fake_drm_->plane_manager()->BeginFrame(&state_);
     EXPECT_TRUE(fake_drm_->plane_manager()->AssignOverlayPlanes(
@@ -1622,7 +1632,7 @@
 
   {
     DrmOverlayPlaneList assigns;
-    assigns.emplace_back(fake_buffer_, 0,
+    assigns.emplace_back(fake_buffer_, gfx::ColorSpace::CreateSRGB(), 0,
                          gfx::OverlayTransform::OVERLAY_TRANSFORM_NONE,
                          gfx::Rect(), gfx::Rect(kDefaultBufferSize),
                          gfx::RectF(0, 0, .5, 1), false, nullptr);
@@ -1643,7 +1653,7 @@
 
   {
     DrmOverlayPlaneList assigns;
-    assigns.emplace_back(fake_buffer_, 0,
+    assigns.emplace_back(fake_buffer_, gfx::ColorSpace::CreateSRGB(), 0,
                          gfx::OverlayTransform::OVERLAY_TRANSFORM_NONE,
                          gfx::Rect(), gfx::Rect(kDefaultBufferSize),
                          gfx::RectF(0, 0, .999, .501), false, nullptr);
@@ -1698,7 +1708,7 @@
       DRM_FORMAT_XRGB8888, kDefaultBufferSize, GBM_BO_USE_SCANOUT);
   scoped_refptr<DrmFramebuffer> framebuffer = DrmFramebuffer::AddFramebuffer(
       drm_device, buffer.get(), kDefaultBufferSize);
-  DrmOverlayPlane overlay(framebuffer, nullptr);
+  DrmOverlayPlane overlay(DrmOverlayPlane::TestPlane(framebuffer));
   overlay.enable_blend = true;
   plane_manager->SetPlaneData(&plane_list, &hw_plane, overlay, 1, gfx::Rect());
   EXPECT_EQ(hw_plane.framebuffer(), framebuffer->framebuffer_id());
diff --git a/ui/ozone/platform/drm/gpu/screen_manager.cc b/ui/ozone/platform/drm/gpu/screen_manager.cc
index 68bf522..d839dd3f 100644
--- a/ui/ozone/platform/drm/gpu/screen_manager.cc
+++ b/ui/ozone/platform/drm/gpu/screen_manager.cc
@@ -924,7 +924,13 @@
   }
 
   DrmOverlayPlaneList modeset_planes;
-  modeset_planes.emplace_back(framebuffer, nullptr);
+  modeset_planes.emplace_back(framebuffer, gfx::ColorSpace::CreateSRGB(),
+                              /*z_order=*/0, gfx::OVERLAY_TRANSFORM_NONE,
+                              /*damage_rect=*/gfx::Rect(framebuffer->size()),
+                              /*display_bounds=*/gfx::Rect(framebuffer->size()),
+                              /*crop_rect=*/gfx::RectF(0, 0, 1, 1),
+                              /*enable_blend=*/false,
+                              /*gpu_fence=*/nullptr);
   return modeset_planes;
 }
 
diff --git a/ui/ozone/platform/drm/gpu/screen_manager_unittest.cc b/ui/ozone/platform/drm/gpu/screen_manager_unittest.cc
index 7ecde05..983817c 100644
--- a/ui/ozone/platform/drm/gpu/screen_manager_unittest.cc
+++ b/ui/ozone/platform/drm/gpu/screen_manager_unittest.cc
@@ -1259,7 +1259,7 @@
   scoped_refptr<DrmFramebuffer> buffer =
       CreateBuffer(DRM_FORMAT_XRGB8888, GetPrimaryBounds().size());
   DrmOverlayPlaneList planes;
-  planes.emplace_back(buffer, nullptr);
+  planes.push_back(DrmOverlayPlane::TestPlane(buffer));
   window->SchedulePageFlip(std::move(planes), base::DoNothing(),
                            base::DoNothing());
   screen_manager_->AddWindow(1, std::move(window));
@@ -1293,7 +1293,7 @@
   auto buffer = CreateBufferWithModifier(
       DRM_FORMAT_XRGB8888, I915_FORMAT_MOD_X_TILED, GetPrimaryBounds().size());
   DrmOverlayPlaneList planes;
-  planes.emplace_back(buffer, nullptr);
+  planes.push_back(DrmOverlayPlane::TestPlane(buffer));
   window->SchedulePageFlip(std::move(planes), base::DoNothing(),
                            base::DoNothing());
   screen_manager_->AddWindow(1, std::move(window));
@@ -1615,7 +1615,7 @@
   scoped_refptr<DrmFramebuffer> buffer =
       CreateBuffer(DRM_FORMAT_XRGB8888, GetPrimaryBounds().size());
   DrmOverlayPlaneList planes;
-  planes.emplace_back(buffer, nullptr);
+  planes.push_back(DrmOverlayPlane::TestPlane(buffer));
   window->SchedulePageFlip(std::move(planes), base::DoNothing(),
                            base::DoNothing());
   screen_manager_->AddWindow(1, std::move(window));
@@ -1655,8 +1655,8 @@
   scoped_refptr<DrmFramebuffer> overlay =
       CreateBuffer(DRM_FORMAT_XRGB8888, GetPrimaryBounds().size());
   DrmOverlayPlaneList planes;
-  planes.emplace_back(primary, nullptr);
-  planes.emplace_back(overlay, nullptr);
+  planes.push_back(DrmOverlayPlane::TestPlane(primary));
+  planes.push_back(DrmOverlayPlane::TestPlane(overlay));
   window->SchedulePageFlip(std::move(planes), base::DoNothing(),
                            base::DoNothing());
   screen_manager_->AddWindow(1, std::move(window));
@@ -1695,7 +1695,7 @@
   scoped_refptr<DrmFramebuffer> buffer =
       CreateBuffer(DRM_FORMAT_XRGB8888, GetPrimaryBounds().size());
   DrmOverlayPlaneList planes;
-  planes.emplace_back(buffer, nullptr);
+  planes.push_back(DrmOverlayPlane::TestPlane(buffer));
   window->SchedulePageFlip(std::move(planes), base::DoNothing(),
                            base::DoNothing());
   screen_manager_->AddWindow(1, std::move(window));
@@ -1737,8 +1737,8 @@
   scoped_refptr<DrmFramebuffer> overlay =
       CreateBuffer(DRM_FORMAT_XRGB8888, GetPrimaryBounds().size());
   DrmOverlayPlaneList planes;
-  planes.emplace_back(primary, nullptr);
-  planes.emplace_back(overlay, nullptr);
+  planes.push_back(DrmOverlayPlane::TestPlane(primary));
+  planes.push_back(DrmOverlayPlane::TestPlane(overlay));
   window->SchedulePageFlip(std::move(planes), base::DoNothing(),
                            base::DoNothing());
   screen_manager_->AddWindow(1, std::move(window));
@@ -1785,8 +1785,8 @@
   scoped_refptr<DrmFramebuffer> overlay =
       CreateBuffer(DRM_FORMAT_XRGB8888, GetPrimaryBounds().size());
   DrmOverlayPlaneList planes;
-  planes.emplace_back(primary, nullptr);
-  planes.emplace_back(overlay, nullptr);
+  planes.push_back(DrmOverlayPlane::TestPlane(primary));
+  planes.push_back(DrmOverlayPlane::TestPlane(overlay));
   window->SchedulePageFlip(std::move(planes), base::DoNothing(),
                            base::DoNothing());
   screen_manager_->AddWindow(1, std::move(window));
@@ -1836,8 +1836,8 @@
   scoped_refptr<DrmFramebuffer> overlay =
       CreateBuffer(DRM_FORMAT_XRGB8888, GetPrimaryBounds().size());
   DrmOverlayPlaneList planes;
-  planes.emplace_back(primary, nullptr);
-  planes.emplace_back(overlay, nullptr);
+  planes.push_back(DrmOverlayPlane::TestPlane(primary));
+  planes.push_back(DrmOverlayPlane::TestPlane(overlay));
   window->SchedulePageFlip(std::move(planes), base::DoNothing(),
                            base::DoNothing());
   screen_manager_->AddWindow(1, std::move(window));
@@ -1905,10 +1905,10 @@
   // The movable plane will be associated with the first display:
   {
     DrmOverlayPlaneList planes;
-    planes.emplace_back(
-        CreateBuffer(DRM_FORMAT_XRGB8888, GetPrimaryBounds().size()), nullptr);
-    planes.emplace_back(
-        CreateBuffer(DRM_FORMAT_XRGB8888, GetPrimaryBounds().size()), nullptr);
+    planes.push_back(DrmOverlayPlane::TestPlane(
+        CreateBuffer(DRM_FORMAT_XRGB8888, GetPrimaryBounds().size())));
+    planes.push_back(DrmOverlayPlane::TestPlane(
+        CreateBuffer(DRM_FORMAT_XRGB8888, GetPrimaryBounds().size())));
     screen_manager_->GetWindow(1)->SchedulePageFlip(
         std::move(planes), base::DoNothing(), base::DoNothing());
     drm_->RunCallbacks();
@@ -1969,10 +1969,10 @@
   // The movable plane will be associated with the first display:
   {
     DrmOverlayPlaneList planes;
-    planes.emplace_back(
-        CreateBuffer(DRM_FORMAT_XRGB8888, GetPrimaryBounds().size()), nullptr);
-    planes.emplace_back(
-        CreateBuffer(DRM_FORMAT_XRGB8888, GetPrimaryBounds().size()), nullptr);
+    planes.push_back(DrmOverlayPlane::TestPlane(
+        CreateBuffer(DRM_FORMAT_XRGB8888, GetPrimaryBounds().size())));
+    planes.push_back(DrmOverlayPlane::TestPlane(
+        CreateBuffer(DRM_FORMAT_XRGB8888, GetPrimaryBounds().size())));
     screen_manager_->GetWindow(1)->SchedulePageFlip(
         std::move(planes), base::DoNothing(), base::DoNothing());
     drm_->RunCallbacks();
diff --git a/ui/ozone/platform/drm/test/vkms_tests.cc b/ui/ozone/platform/drm/test/vkms_tests.cc
index bab61808..7a99a43 100644
--- a/ui/ozone/platform/drm/test/vkms_tests.cc
+++ b/ui/ozone/platform/drm/test/vkms_tests.cc
@@ -133,8 +133,9 @@
       /*flags=*/0, &buffer, &framebuffer);
 
   auto planes = std::vector<ui::DrmOverlayPlane>();
-  planes.emplace_back(framebuffer,
-                      std::make_unique<gfx::GpuFence>(gfx::GpuFenceHandle()));
+  planes.push_back(ui::DrmOverlayPlane::TestPlane(
+      framebuffer, gfx::ColorSpace::CreateSRGB(),
+      std::make_unique<gfx::GpuFence>(gfx::GpuFenceHandle())));
 
   base::RunLoop run_loop;
   auto submission_callback =
diff --git a/v8 b/v8
index 3424896..1264bda 160000
--- a/v8
+++ b/v8
@@ -1 +1 @@
-Subproject commit 34248965c12fc846f437770c1a7557e8fabfccd1
+Subproject commit 1264bda1a83fa9dda7db289719d3ba8f0276df89