author Jianhui Dai Tue Nov 15 06:18:04 2022 committer Jianhui Dai Tue Nov 15 06:18:04 2022 [Ozone/Linux] Support VA-API on Linux Ozone/Wayland VA-API supports different display backends [1]. VA/DRM and VA/X11 are used by Chromium at the moment. All Ozone platforms support VA/DRM by default. VA/X11 is supported only on Ozone/X11. This CL renames 'supports_vaapi' to 'supports_vaapi_x11'; it indicates if VA/X11 supported. Linux Ozone/X11 supports both VA/X11 and VA/DRM; Linux Ozone/Wayland supports only VA/DRM. `VaapiPictureFactory` also takes this flag to determine picture creation and downloading mechanism on Linux. [1] https://github.com/intel/libva/blob/master/va/va_backend.h Test: VDA video playback on Linux X11 and Linux Wayland Bug: 1326754,1116701 Change-Id: I6d6bf781833a7752d23dafb2b63112c2fc81b17a diff -up chromium-109.0.5359.124/media/gpu/args.gni.wayland-vaapi chromium-109.0.5359.124/media/gpu/args.gni --- chromium-109.0.5359.124/media/gpu/args.gni.wayland-vaapi 2022-12-14 01:39:52.000000000 +0100 +++ chromium-109.0.5359.124/media/gpu/args.gni 2023-01-05 10:13:08.291403261 +0100 @@ -6,10 +6,14 @@ import("//build/config/chromeos/ui_mode. import("//build/config/ozone.gni") declare_args() { - # Indicates if X11 VA-API-based hardware acceleration is to be used. - # See also the comment near the |use_vaapi| arg. - use_vaapi_x11 = is_linux && ozone_platform_x11 && - (target_cpu == "x86" || target_cpu == "x64") && !is_castos + # Build Chrome support for using VA-API over X11. Note that setting this to true is + # not a guarantee that Chrome will use (or even try to use) VA-API over X11. In + # particular, it is possible to build Chrome with support for VA-API over X11 but + # pick Wayland as the Ozone backend at runtime. In this case, Chrome will try to + # use VA-API over DRM. + support_vaapi_over_x11 = + is_linux && ozone_platform_x11 && + (target_cpu == "x86" || target_cpu == "x64") && !is_castos } declare_args() { @@ -29,8 +33,9 @@ declare_args() { # is typically the case on x86-based ChromeOS devices. # VA-API should also be compiled by default on x11-using linux devices # using x86/x64. - use_vaapi = use_vaapi_x11 || (is_chromeos_lacros && - (target_cpu == "x86" || target_cpu == "x64")) + use_vaapi = + support_vaapi_over_x11 || + (is_chromeos_lacros && (target_cpu == "x86" || target_cpu == "x64")) # Indicates if ChromeOS protected media support exists. This is used # to enable the CDM daemon in Chrome OS as well as support for diff -up chromium-109.0.5359.124/media/gpu/BUILD.gn.wayland-vaapi chromium-109.0.5359.124/media/gpu/BUILD.gn --- chromium-109.0.5359.124/media/gpu/BUILD.gn.wayland-vaapi 2022-12-14 01:39:52.000000000 +0100 +++ chromium-109.0.5359.124/media/gpu/BUILD.gn 2023-01-05 10:13:08.291403261 +0100 @@ -20,7 +20,7 @@ buildflag_header("buildflags") { "USE_VAAPI_IMAGE_CODECS=$use_vaapi_image_codecs", "USE_V4L2_CODEC=$use_v4l2_codec", "USE_LIBV4L2=$use_v4lplugin", - "USE_VAAPI_X11=$use_vaapi_x11", + "SUPPORT_VAAPI_OVER_X11=$support_vaapi_over_x11", ] } diff -up chromium-109.0.5359.124/media/gpu/vaapi/BUILD.gn.wayland-vaapi chromium-109.0.5359.124/media/gpu/vaapi/BUILD.gn --- chromium-109.0.5359.124/media/gpu/vaapi/BUILD.gn.wayland-vaapi 2022-12-14 01:39:52.000000000 +0100 +++ chromium-109.0.5359.124/media/gpu/vaapi/BUILD.gn 2023-01-05 10:13:08.291403261 +0100 @@ -17,7 +17,7 @@ assert(use_vaapi) generate_stubs("libva_stubs") { extra_header = "va_stub_header.fragment" sigs = [ "va.sigs" ] - if (use_vaapi_x11) { + if (support_vaapi_over_x11) { sigs += [ "va_x11.sigs" ] } if (is_chromeos_ash) { @@ -138,7 +138,7 @@ source_set("vaapi") { ] } - if (use_vaapi_x11) { + if (support_vaapi_over_x11) { deps += [ "//ui/gfx/x" ] sources += [ "vaapi_picture_native_pixmap_angle.cc", @@ -214,7 +214,7 @@ source_set("common") { deps += [ "//ui/ozone" ] } - if (use_vaapi_x11) { + if (support_vaapi_over_x11) { deps += [ "//ui/gfx/x" ] } diff -up chromium-109.0.5359.124/media/gpu/vaapi/vaapi_picture_factory.h.wayland-vaapi chromium-109.0.5359.124/media/gpu/vaapi/vaapi_picture_factory.h --- chromium-109.0.5359.124/media/gpu/vaapi/vaapi_picture_factory.h.wayland-vaapi 2022-12-14 01:39:53.000000000 +0100 +++ chromium-109.0.5359.124/media/gpu/vaapi/vaapi_picture_factory.h 2023-01-05 10:13:08.291403261 +0100 @@ -36,7 +36,11 @@ class MEDIA_GPU_EXPORT VaapiPictureFacto kVaapiImplementationAngle, }; +#if BUILDFLAG(SUPPORT_VAAPI_OVER_X11) + explicit VaapiPictureFactory(absl::optional may_use_vaapi_over_x11); +#else VaapiPictureFactory(); +#endif // BUILDFLAG(SUPPORT_VAAPI_OVER_X11) VaapiPictureFactory(const VaapiPictureFactory&) = delete; VaapiPictureFactory& operator=(const VaapiPictureFactory&) = delete; @@ -85,6 +89,11 @@ class MEDIA_GPU_EXPORT VaapiPictureFacto CreatePictureCB create_picture_cb_; bool needs_vpp_for_downloading_ = false; + +#if BUILDFLAG(SUPPORT_VAAPI_OVER_X11) + // See comment in `VaapiWrapper::MayUseVaapiOverX11()`. + absl::optional may_use_vaapi_over_x11_; +#endif // BUILDFLAG(SUPPORT_VAAPI_OVER_X11) }; } // namespace media diff -up chromium-109.0.5359.124/media/gpu/vaapi/vaapi_video_decode_accelerator.cc.wayland-vaapi chromium-109.0.5359.124/media/gpu/vaapi/vaapi_video_decode_accelerator.cc --- chromium-109.0.5359.124/media/gpu/vaapi/vaapi_video_decode_accelerator.cc.wayland-vaapi 2023-01-05 10:13:08.290403251 +0100 +++ chromium-109.0.5359.124/media/gpu/vaapi/vaapi_video_decode_accelerator.cc 2023-01-05 10:13:08.292403271 +0100 @@ -184,7 +184,12 @@ bool VaapiVideoDecodeAccelerator::Initia Client* client) { DCHECK(task_runner_->BelongsToCurrentThread()); +#if BUILDFLAG(SUPPORT_VAAPI_OVER_X11) + vaapi_picture_factory_ = + std::make_unique(VaapiWrapper::MayUseVaapiOverX11()); +#else vaapi_picture_factory_ = std::make_unique(); +#endif // BUILDFLAG(SUPPORT_VAAPI_OVER_X11) if (config.is_encrypted()) { NOTREACHED() << "Encrypted streams are not supported for this VDA"; @@ -1210,7 +1215,7 @@ VaapiVideoDecodeAccelerator::GetSupporte VaapiVideoDecodeAccelerator::BufferAllocationMode VaapiVideoDecodeAccelerator::DecideBufferAllocationMode() { -#if BUILDFLAG(USE_VAAPI_X11) +#if BUILDFLAG(SUPPORT_VAAPI_OVER_X11) // The IMPORT mode is used for Android on Chrome OS, so this doesn't apply // here. DCHECK_NE(output_mode_, VideoDecodeAccelerator::Config::OutputMode::IMPORT); diff -up chromium-109.0.5359.124/media/gpu/vaapi/vaapi_wrapper.h.wayland-vaapi chromium-109.0.5359.124/media/gpu/vaapi/vaapi_wrapper.h --- chromium-109.0.5359.124/media/gpu/vaapi/vaapi_wrapper.h.wayland-vaapi 2022-12-14 01:39:53.000000000 +0100 +++ chromium-109.0.5359.124/media/gpu/vaapi/vaapi_wrapper.h 2023-01-05 10:13:08.292403271 +0100 @@ -36,9 +36,9 @@ #include "third_party/abseil-cpp/absl/types/optional.h" #include "ui/gfx/geometry/size.h" -#if BUILDFLAG(USE_VAAPI_X11) +#if BUILDFLAG(SUPPORT_VAAPI_OVER_X11) #include "ui/gfx/x/xproto.h" // nogncheck -#endif // BUILDFLAG(USE_VAAPI_X11) +#endif // BUILDFLAG(SUPPORT_VAAPI_OVER_X11) namespace gfx { enum class BufferFormat; @@ -186,6 +186,16 @@ class MEDIA_GPU_EXPORT VaapiWrapper VaapiWrapper(const VaapiWrapper&) = delete; VaapiWrapper& operator=(const VaapiWrapper&) = delete; +#if BUILDFLAG(SUPPORT_VAAPI_OVER_X11) + // Returns true if VaapiWrapper instances may use VA-API over X11 and false + // otherwise (VA-API over DRM will be used). If this returns absl::nullopt, + // it's because it was not possible to determine how VA-API may be used. This + // should only be called after PreSandboxInitialization() (which is assumed to + // be called only once during the GPU process startup) and is safe to call + // from any thread. Additionally, this should always return the same value. + static absl::optional MayUseVaapiOverX11(); +#endif + // Returns the supported SVC scalability modes for specified profile. static std::vector GetSupportedScalabilityModes( VideoCodecProfile media_profile, @@ -439,13 +449,13 @@ class MEDIA_GPU_EXPORT VaapiWrapper VASurfaceID va_surface_id, const std::vector>& va_buffers); -#if BUILDFLAG(USE_VAAPI_X11) +#if BUILDFLAG(SUPPORT_VAAPI_OVER_X11) // Put data from |va_surface_id| into |x_pixmap| of size // |dest_size|, converting/scaling to it. [[nodiscard]] bool PutSurfaceIntoPixmap(VASurfaceID va_surface_id, x11::Pixmap x_pixmap, gfx::Size dest_size); -#endif // BUILDFLAG(USE_VAAPI_X11) +#endif // BUILDFLAG(SUPPORT_VAAPI_OVER_X11) // Creates a ScopedVAImage from a VASurface |va_surface_id| and map it into // memory with the given |format| and |size|. If |format| is not equal to the diff -up chromium-109.0.5359.124/media/gpu/vaapi/va_stub_header.fragment.wayland-vaapi chromium-109.0.5359.124/media/gpu/vaapi/va_stub_header.fragment --- chromium-109.0.5359.124/media/gpu/vaapi/va_stub_header.fragment.wayland-vaapi 2022-12-14 01:39:52.000000000 +0100 +++ chromium-109.0.5359.124/media/gpu/vaapi/va_stub_header.fragment 2023-01-05 10:13:08.291403261 +0100 @@ -7,8 +7,8 @@ extern "C" { #include #include -#if BUILDFLAG(USE_VAAPI_X11) +#if BUILDFLAG(SUPPORT_VAAPI_OVER_X11) #include -#endif // BUILDFLAG(USE_VAAPI_X11) +#endif // BUILDFLAG(SUPPORT_VAAPI_OVER_X11) } diff -up chromium-109.0.5359.124/ui/ozone/platform/x11/ozone_platform_x11.cc.wayland-vaapi chromium-109.0.5359.124/ui/ozone/platform/x11/ozone_platform_x11.cc --- chromium-109.0.5359.124/ui/ozone/platform/x11/ozone_platform_x11.cc.wayland-vaapi 2022-12-14 01:40:14.000000000 +0100 +++ chromium-109.0.5359.124/ui/ozone/platform/x11/ozone_platform_x11.cc 2023-01-05 10:13:08.292403271 +0100 @@ -196,7 +196,7 @@ class OzonePlatformX11 : public OzonePla properties->app_modal_dialogs_use_event_blocker = true; properties->fetch_buffer_formats_for_gmb_on_gpu = true; #if BUILDFLAG(IS_LINUX) - properties->supports_vaapi = true; + properties->supports_vaapi_x11 = true; #endif initialised = true; diff -up chromium-109.0.5359.124/ui/ozone/public/ozone_platform.h.wayland-vaapi chromium-109.0.5359.124/ui/ozone/public/ozone_platform.h --- chromium-109.0.5359.124/ui/ozone/public/ozone_platform.h.wayland-vaapi 2022-12-14 01:40:14.000000000 +0100 +++ chromium-109.0.5359.124/ui/ozone/public/ozone_platform.h 2023-01-05 10:13:08.293403281 +0100 @@ -145,12 +145,13 @@ class COMPONENT_EXPORT(OZONE) OzonePlatf bool fetch_buffer_formats_for_gmb_on_gpu = false; #if BUILDFLAG(IS_LINUX) - // TODO(crbug.com/1116701): add vaapi support for other Ozone platforms on - // Linux. At the moment, VA-API Linux implementation supports only X11 - // backend. This implementation must be refactored to support Ozone - // properly. As a temporary solution, VA-API on Linux checks if vaapi is - // supported (which implicitly means that it is Ozone/X11). - bool supports_vaapi = false; + // VA-API supports different display backends. + // See https://github.com/intel/libva/blob/master/va/va_backend.h + // + // VA/DRM and VA/X11 are used by Chromium at the moment. All Ozone platforms + // support VA/DRM by default. `supports_vaapi_x11` indicates if VA/X11 + // supported; it is true only on Ozone/X11 platform. + bool supports_vaapi_x11 = false; #endif // Indicates that the platform allows client applications to manipulate diff -up chromium-109.0.5414.74/media/gpu/vaapi/vaapi_video_decode_accelerator_unittest.cc.orig chromium-109.0.5414.74/media/gpu/vaapi/vaapi_video_decode_accelerator_unittest.cc --- chromium-109.0.5414.74/media/gpu/vaapi/vaapi_video_decode_accelerator_unittest.cc.orig 2023-01-04 20:20:18.000000000 +0100 +++ chromium-109.0.5414.74/media/gpu/vaapi/vaapi_video_decode_accelerator_unittest.cc 2023-01-11 14:31:01.033496121 +0100 @@ -39,6 +39,11 @@ struct TestParams { bool decode_using_client_picture_buffers; }; +#if BUILDFLAG(SUPPORT_VAAPI_OVER_X11) +// TODO: Add it in TestParams to cover Ozone/Wayland. +bool kMayUseVaapiOverX11 = true; +#endif // BUILDFLAG(SUPPORT_VAAPI_OVER_X11) + constexpr int32_t kBitstreamId = 123; constexpr size_t kInputSize = 256; @@ -131,7 +136,13 @@ class MockVaapiPicture : public VaapiPic class MockVaapiPictureFactory : public VaapiPictureFactory { public: +#if BUILDFLAG(SUPPORT_VAAPI_OVER_X11) + explicit MockVaapiPictureFactory(absl::optional may_use_vaapi_over_x11) + : VaapiPictureFactory(may_use_vaapi_over_x11) {} +#else MockVaapiPictureFactory() = default; +#endif // BUILDFLAG(SUPPORT_VAAPI_OVER_X11) + ~MockVaapiPictureFactory() override = default; MOCK_METHOD3(MockCreateVaapiPicture, @@ -165,7 +176,12 @@ class VaapiVideoDecodeAcceleratorTest : bool can_bind_to_sampler) { return true; })), decoder_thread_("VaapiVideoDecodeAcceleratorTestThread"), mock_decoder_(new ::testing::StrictMock), +#if BUILDFLAG(SUPPORT_VAAPI_OVER_X11) + mock_vaapi_picture_factory_( + new MockVaapiPictureFactory(kMayUseVaapiOverX11)), +#else mock_vaapi_picture_factory_(new MockVaapiPictureFactory()), +#endif // BUILDFLAG(SUPPORT_VAAPI_OVER_X11) mock_vaapi_wrapper_(new MockVaapiWrapper(VaapiWrapper::kDecode)), mock_vpp_vaapi_wrapper_(new MockVaapiWrapper(VaapiWrapper::kDecode)), weak_ptr_factory_(this) { @@ -421,14 +437,16 @@ TEST_P(VaapiVideoDecodeAcceleratorTest, mock_vaapi_picture_factory_->GetVaapiImplementation( gl::kGLImplementationEGLGLES2)); -#if BUILDFLAG(USE_VAAPI_X11) - EXPECT_EQ(VaapiPictureFactory::kVaapiImplementationAngle, - mock_vaapi_picture_factory_->GetVaapiImplementation( - gl::kGLImplementationEGLANGLE)); - EXPECT_EQ(VaapiPictureFactory::kVaapiImplementationX11, - mock_vaapi_picture_factory_->GetVaapiImplementation( - gl::kGLImplementationDesktopGL)); -#elif BUILDFLAG(IS_OZONE) +#if BUILDFLAG(SUPPORT_VAAPI_OVER_X11) + if (kMayUseVaapiOverX11) { + EXPECT_EQ(VaapiPictureFactory::kVaapiImplementationAngle, + mock_vaapi_picture_factory_->GetVaapiImplementation( + gl::kGLImplementationEGLANGLE)); + EXPECT_EQ(VaapiPictureFactory::kVaapiImplementationX11, + mock_vaapi_picture_factory_->GetVaapiImplementation( + gl::kGLImplementationDesktopGL)); + } +#else EXPECT_EQ(VaapiPictureFactory::kVaapiImplementationDrm, mock_vaapi_picture_factory_->GetVaapiImplementation( gl::kGLImplementationEGLANGLE)); diff -up chromium-109.0.5414.74/media/gpu/vaapi/vaapi_picture_factory.cc.orig chromium-109.0.5414.74/media/gpu/vaapi/vaapi_picture_factory.cc --- chromium-109.0.5414.74/media/gpu/vaapi/vaapi_picture_factory.cc.orig 2023-01-04 20:20:18.000000000 +0100 +++ chromium-109.0.5414.74/media/gpu/vaapi/vaapi_picture_factory.cc 2023-01-11 14:45:36.405506479 +0100 @@ -13,10 +13,10 @@ #if BUILDFLAG(IS_OZONE) #include "media/gpu/vaapi/vaapi_picture_native_pixmap_ozone.h" #endif // BUILDFLAG(IS_OZONE) -#if BUILDFLAG(USE_VAAPI_X11) +#if BUILDFLAG(SUPPORT_VAAPI_OVER_X11) #include "media/gpu/vaapi/vaapi_picture_native_pixmap_angle.h" #include "media/gpu/vaapi/vaapi_picture_tfp.h" -#endif // BUILDFLAG(USE_VAAPI_X11) +#endif // BUILDFLAG(SUPPORT_VAAPI_OVER_X11) #if defined(USE_EGL) #include "media/gpu/vaapi/vaapi_picture_native_pixmap_egl.h" #endif @@ -42,22 +42,32 @@ } // namespace +#if BUILDFLAG(SUPPORT_VAAPI_OVER_X11) +VaapiPictureFactory::VaapiPictureFactory( + absl::optional may_use_vaapi_over_x11) + : may_use_vaapi_over_x11_(may_use_vaapi_over_x11) { +#else VaapiPictureFactory::VaapiPictureFactory() { +#endif // BUILDFLAG(SUPPORT_VAAPI_OVER_X11) vaapi_impl_pairs_.insert( std::make_pair(gl::kGLImplementationEGLGLES2, VaapiPictureFactory::kVaapiImplementationDrm)); -#if BUILDFLAG(USE_VAAPI_X11) - vaapi_impl_pairs_.insert( - std::make_pair(gl::kGLImplementationEGLANGLE, - VaapiPictureFactory::kVaapiImplementationAngle)); - vaapi_impl_pairs_.insert( - std::make_pair(gl::kGLImplementationDesktopGL, - VaapiPictureFactory::kVaapiImplementationX11)); -#elif BUILDFLAG(IS_OZONE) + +#if BUILDFLAG(SUPPORT_VAAPI_OVER_X11) + CHECK(may_use_vaapi_over_x11_.has_value()); + if (may_use_vaapi_over_x11_.value()) { + vaapi_impl_pairs_.insert( + std::make_pair(gl::kGLImplementationEGLANGLE, + VaapiPictureFactory::kVaapiImplementationAngle)); + vaapi_impl_pairs_.insert( + std::make_pair(gl::kGLImplementationDesktopGL, + VaapiPictureFactory::kVaapiImplementationX11)); + } +#else vaapi_impl_pairs_.insert( std::make_pair(gl::kGLImplementationEGLANGLE, VaapiPictureFactory::kVaapiImplementationDrm)); -#endif +#endif // BUILDFLAG(SUPPORT_VAAPI_OVER_X11) DeterminePictureCreationAndDownloadingMechanism(); } @@ -98,19 +108,19 @@ } uint32_t VaapiPictureFactory::GetGLTextureTarget() { -#if BUILDFLAG(USE_VAAPI_X11) - return GL_TEXTURE_2D; -#else +#if BUILDFLAG(IS_CHROMEOS) return GL_TEXTURE_EXTERNAL_OES; -#endif +#else + return GL_TEXTURE_2D; +#endif // BUILDFLAG(IS_CHROMEOS) } gfx::BufferFormat VaapiPictureFactory::GetBufferFormat() { -#if BUILDFLAG(USE_VAAPI_X11) - return gfx::BufferFormat::RGBX_8888; -#else +#if BUILDFLAG(IS_CHROMEOS) return gfx::BufferFormat::YUV_420_BIPLANAR; -#endif +#else + return gfx::BufferFormat::RGBX_8888; +#endif // BUILDFLAG(IS_CHROMEOS) } void VaapiPictureFactory::DeterminePictureCreationAndDownloadingMechanism() { @@ -118,25 +128,30 @@ #if BUILDFLAG(IS_OZONE) // We can be called without GL initialized, which is valid if we use Ozone. case kVaapiImplementationNone: +#if BUILDFLAG(SUPPORT_VAAPI_OVER_X11) + DCHECK(may_use_vaapi_over_x11_.value_or(false)); +#endif create_picture_cb_ = base::BindRepeating( &CreateVaapiPictureNativeImpl); needs_vpp_for_downloading_ = true; break; #endif // BUILDFLAG(IS_OZONE) -#if BUILDFLAG(USE_VAAPI_X11) +#if BUILDFLAG(SUPPORT_VAAPI_OVER_X11) case kVaapiImplementationX11: + DCHECK(may_use_vaapi_over_x11_.value_or(false)); create_picture_cb_ = base::BindRepeating(&CreateVaapiPictureNativeImpl); // Neither VaapiTFPPicture or VaapiPictureNativePixmapAngle needs the VPP. needs_vpp_for_downloading_ = false; break; case kVaapiImplementationAngle: + DCHECK(may_use_vaapi_over_x11_.value_or(false)); create_picture_cb_ = base::BindRepeating( &CreateVaapiPictureNativeImpl); // Neither VaapiTFPPicture or VaapiPictureNativePixmapAngle needs the VPP. needs_vpp_for_downloading_ = false; break; -#endif // BUILDFLAG(USE_VAAPI_X11) +#endif // BUILDFLAG(SUPPORT_VAAPI_OVER_X11) case kVaapiImplementationDrm: #if BUILDFLAG(IS_OZONE) create_picture_cb_ = base::BindRepeating( diff -up chromium-109.0.5414.74/media/gpu/vaapi/vaapi_wrapper.cc.orig chromium-109.0.5414.74/media/gpu/vaapi/vaapi_wrapper.cc --- chromium-109.0.5414.74/media/gpu/vaapi/vaapi_wrapper.cc.orig 2023-01-04 20:20:18.000000000 +0100 +++ chromium-109.0.5414.74/media/gpu/vaapi/vaapi_wrapper.cc 2023-01-11 15:08:02.721768243 +0100 @@ -62,7 +62,7 @@ #include "ui/gl/gl_bindings.h" #include "ui/gl/gl_implementation.h" -#if BUILDFLAG(USE_VAAPI_X11) +#if BUILDFLAG(SUPPORT_VAAPI_OVER_X11) typedef XID Drawable; extern "C" { @@ -70,7 +70,7 @@ } #include "ui/gfx/x/connection.h" // nogncheck -#endif // BUILDFLAG(USE_VAAPI_X11) +#endif // BUILDFLAG(SUPPORT_VAAPI_OVER_X11) #if BUILDFLAG(IS_OZONE) #include "ui/ozone/public/ozone_platform.h" @@ -84,14 +84,14 @@ using media_gpu_vaapi::kModuleVa; using media_gpu_vaapi::kModuleVa_drm; -#if BUILDFLAG(USE_VAAPI_X11) +#if BUILDFLAG(SUPPORT_VAAPI_OVER_X11) using media_gpu_vaapi::kModuleVa_x11; -#endif // BUILDFLAG(USE_VAAPI_X11) +#endif // BUILDFLAG(SUPPORT_VAAPI_OVER_X11) using media_gpu_vaapi::InitializeStubs; using media_gpu_vaapi::IsVaInitialized; -#if BUILDFLAG(USE_VAAPI_X11) +#if BUILDFLAG(SUPPORT_VAAPI_OVER_X11) using media_gpu_vaapi::IsVa_x11Initialized; -#endif // BUILDFLAG(USE_VAAPI_X11) +#endif // BUILDFLAG(SUPPORT_VAAPI_OVER_X11) using media_gpu_vaapi::IsVa_drmInitialized; using media_gpu_vaapi::StubPathMap; @@ -668,6 +668,12 @@ void SetDrmFd(base::PlatformFile fd) { drm_fd_.reset(HANDLE_EINTR(dup(fd))); } +#if BUILDFLAG(SUPPORT_VAAPI_OVER_X11) + absl::optional MayUseVaapiOverX11() const { + return may_use_vaapi_over_x11_; + } +#endif + private: friend class base::NoDestructor; @@ -690,6 +696,13 @@ // Drm fd used to obtain access to the driver interface by VA. base::ScopedFD drm_fd_; +#if BUILDFLAG(SUPPORT_VAAPI_OVER_X11) + // Whether we'll be possibly using VA-API over Ozone/X11. This should only be + // set (if at all) during the pre-sandbox initialization. If absl::nullopt, + // all calls to Initialize() will return false immediately. + absl::optional may_use_vaapi_over_x11_; +#endif + // The VADisplay handle. Valid between Initialize() and Deinitialize(). VADisplay va_display_; @@ -708,6 +721,15 @@ // static void VADisplayState::PreSandboxInitialization() { +#if BUILDFLAG(SUPPORT_VAAPI_OVER_X11) + if (ui::OzonePlatform::IsInitialized()) { + VADisplayState::Get()->may_use_vaapi_over_x11_ = + ui::OzonePlatform::GetInstance() + ->GetPlatformProperties() + .supports_vaapi_x11; + } +#endif + constexpr char kRenderNodeFilePattern[] = "/dev/dri/renderD%d"; // This loop ends on either the first card that does not exist or the first // render node that is not vgem. @@ -740,20 +762,18 @@ bool VADisplayState::Initialize() { base::AutoLock auto_lock(va_lock_); -#if BUILDFLAG(IS_OZONE) && BUILDFLAG(IS_LINUX) - // TODO(crbug.com/1116701): add vaapi support for other Ozone platforms on - // Linux. See comment in OzonePlatform::PlatformProperties::supports_vaapi - // for more details. This will also require revisiting everything that's - // guarded by USE_VAAPI_X11. For example, if USE_VAAPI_X11 is true, but the - // user chooses the Wayland backend for Ozone at runtime, then many things (if - // not all) that we do for X11 won't apply. - if (!ui::OzonePlatform::GetInstance()->GetPlatformProperties().supports_vaapi) +#if BUILDFLAG(SUPPORT_VAAPI_OVER_X11) + if (!may_use_vaapi_over_x11_.has_value()) return false; #endif bool libraries_initialized = IsVaInitialized() && IsVa_drmInitialized(); -#if BUILDFLAG(USE_VAAPI_X11) - libraries_initialized = libraries_initialized && IsVa_x11Initialized(); +#if BUILDFLAG(SUPPORT_VAAPI_OVER_X11) + // Initialize VA-API X11 display backend for Linux Ozone/X11. + // See comment in OzonePlatform::PlatformProperties::supports_vaapi_x11 for + // more details. + if (may_use_vaapi_over_x11_.value()) + libraries_initialized = libraries_initialized && IsVa_x11Initialized(); #endif if (!libraries_initialized) return false; @@ -768,7 +788,7 @@ return success; } -#if BUILDFLAG(USE_VAAPI_X11) +#if BUILDFLAG(SUPPORT_VAAPI_OVER_X11) absl::optional GetVADisplayStateX11(const base::ScopedFD& drm_fd) { switch (gl::GetGLImplementation()) { @@ -796,13 +816,19 @@ } } -#else +#endif // BUILDFLAG(SUPPORT_VAAPI_OVER_X11) absl::optional GetVADisplayState(const base::ScopedFD& drm_fd) { switch (gl::GetGLImplementation()) { case gl::kGLImplementationEGLGLES2: +#if BUILDFLAG(IS_CHROMEOS) + // GetVADisplayState() should not get called on Linux with Ozone/X11 + // (GetVADisplayStateX11() should get called instead), and we haven't tried + // VA-API decoding on Linux with Ozone/Wayland and anything other than + // native EGL/GLES2. case gl::kGLImplementationEGLANGLE: case gl::kGLImplementationNone: +#endif return vaGetDisplayDRM(drm_fd.get()); default: LOG(WARNING) << "VAAPI video acceleration not available for " @@ -812,18 +838,23 @@ } } -#endif // BUILDFLAG(USE_VAAPI_X11) - bool VADisplayState::InitializeVaDisplay_Locked() { - absl::optional display = -#if BUILDFLAG(USE_VAAPI_X11) - GetVADisplayStateX11(drm_fd_); -#else - GetVADisplayState(drm_fd_); -#endif + absl::optional display; - if (!display) - return false; +#if BUILDFLAG(SUPPORT_VAAPI_OVER_X11) + DCHECK(may_use_vaapi_over_x11_.has_value()); + if (may_use_vaapi_over_x11_.value()) { + display = GetVADisplayStateX11(drm_fd_); + if (!display) + return false; + } +#endif // BUILDFLAG(SUPPORT_VAAPI_OVER_X11) + + if (!display) { + display = GetVADisplayState(drm_fd_); + if (!display) + return false; + } va_display_ = *display; if (!vaDisplayIsValid(va_display_)) { @@ -1656,6 +1687,13 @@ enforce_sequence_affinity); } +#if BUILDFLAG(SUPPORT_VAAPI_OVER_X11) +// static +absl::optional VaapiWrapper::MayUseVaapiOverX11() { + return VADisplayState::Get()->MayUseVaapiOverX11(); +} +#endif + // static std::vector VaapiWrapper::GetSupportedScalabilityModes( VideoCodecProfile media_profile, @@ -2665,12 +2703,13 @@ return Execute_Locked(va_surface_id, va_buffer_ids); } -#if BUILDFLAG(USE_VAAPI_X11) +#if BUILDFLAG(SUPPORT_VAAPI_OVER_X11) bool VaapiWrapper::PutSurfaceIntoPixmap(VASurfaceID va_surface_id, x11::Pixmap x_pixmap, gfx::Size dest_size) { CHECK(!enforce_sequence_affinity_ || sequence_checker_.CalledOnValidSequence()); + CHECK(MayUseVaapiOverX11().value_or(false)); base::AutoLockMaybe auto_lock(va_lock_.get()); VAStatus va_res = vaSyncSurface(va_display_, va_surface_id); @@ -2684,7 +2723,7 @@ VA_SUCCESS_OR_RETURN(va_res, VaapiFunctions::kVAPutSurface, false); return true; } -#endif // BUILDFLAG(USE_VAAPI_X11) +#endif // BUILDFLAG(SUPPORT_VAAPI_OVER_X11) std::unique_ptr VaapiWrapper::CreateVaImage( VASurfaceID va_surface_id, @@ -3086,7 +3125,7 @@ paths[kModuleVa].push_back(std::string("libva.so.") + va_suffix); paths[kModuleVa_drm].push_back(std::string("libva-drm.so.") + va_suffix); -#if BUILDFLAG(USE_VAAPI_X11) +#if BUILDFLAG(SUPPORT_VAAPI_OVER_X11) paths[kModuleVa_x11].push_back(std::string("libva-x11.so.") + va_suffix); #endif #if BUILDFLAG(IS_CHROMEOS_ASH) diff -up chromium-109.0.5414.74/media/gpu/vaapi/vaapi_picture_native_pixmap_ozone.cc.orig chromium-109.0.5414.74/media/gpu/vaapi/vaapi_picture_native_pixmap_ozone.cc --- chromium-109.0.5414.74/media/gpu/vaapi/vaapi_picture_native_pixmap_ozone.cc.orig 2023-01-11 20:45:17.347940426 +0100 +++ chromium-109.0.5414.74/media/gpu/vaapi/vaapi_picture_native_pixmap_ozone.cc 2023-01-11 20:45:58.314670752 +0100 @@ -109,7 +109,7 @@ ui::OzonePlatform* platform = ui::OzonePlatform::GetInstance(); ui::SurfaceFactoryOzone* factory = platform->GetSurfaceFactoryOzone(); gfx::BufferUsage buffer_usage = gfx::BufferUsage::SCANOUT_VDA_WRITE; -#if BUILDFLAG(USE_VAAPI_X11) +#if BUILDFLAG(SUPPORT_VAAPI_OVER_X11) // The 'VaapiVideoDecodeAccelerator' requires the VPP to download the decoded // frame from the internal surface to the allocated native pixmap. // 'SCANOUT_VDA_WRITE' is used for 'YUV_420_BIPLANAR' on ChromeOS; For Linux,