From 53b000e48d7783ab7753fad62fa70a817dc4432b Mon Sep 17 00:00:00 2001 From: Alexander Frick Date: Tue, 20 Jun 2023 19:43:12 -0500 Subject: [PATCH] M114 stage 2 --- logos/OLD/chromium.svg | 2 +- logos/chromium_logo.svg | 511 +++++++++++++ other/Mac/cdm_registration.cc | 4 + src/chrome/BUILD.gn | 8 +- src/chrome/app/theme/theme_resources.grd | 4 +- src/chrome/common/media/cdm_registration.cc | 4 + .../version_ui/resources/about_version.html | 1 + src/content/gpu/BUILD.gn | 3 +- src/media/base/media_switches.cc | 78 +- src/media/gpu/vaapi/vaapi_wrapper.cc | 676 +++++++++++------- src/media/gpu/vaapi/vaapi_wrapper.h | 63 +- src/net/url_request/url_request_http_job.cc | 2 +- src/third_party/zlib/BUILD.gn | 4 + 13 files changed, 1061 insertions(+), 299 deletions(-) create mode 100644 logos/chromium_logo.svg diff --git a/logos/OLD/chromium.svg b/logos/OLD/chromium.svg index fc76bbc6..fe3ad25a 100644 --- a/logos/OLD/chromium.svg +++ b/logos/OLD/chromium.svg @@ -1 +1 @@ - \ No newline at end of file + diff --git a/logos/chromium_logo.svg b/logos/chromium_logo.svg new file mode 100644 index 00000000..4fda27f6 --- /dev/null +++ b/logos/chromium_logo.svg @@ -0,0 +1,511 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/other/Mac/cdm_registration.cc b/other/Mac/cdm_registration.cc index 547a4d78..614ccea9 100644 --- a/other/Mac/cdm_registration.cc +++ b/other/Mac/cdm_registration.cc @@ -248,6 +248,10 @@ void AddHardwareSecureWidevine(std::vector* cdms) { switches::kLacrosEnablePlatformHevc)) { capability.video_codecs.emplace(media::VideoCodec::kHEVC, kAllProfiles); } +#elif BUILDFLAG(IS_CHROMEOS_ASH) + if (base::FeatureList::IsEnabled(media::kPlatformHEVCDecoderSupport)) { + capability.video_codecs.emplace(media::VideoCodec::kHEVC, kAllProfiles); + } #else capability.video_codecs.emplace(media::VideoCodec::kHEVC, kAllProfiles); #endif // BUILDFLAG(IS_CHROMEOS_LACROS) diff --git a/src/chrome/BUILD.gn b/src/chrome/BUILD.gn index 1b6d05de..6d9ab420 100644 --- a/src/chrome/BUILD.gn +++ b/src/chrome/BUILD.gn @@ -285,9 +285,6 @@ if (!is_android && !is_mac) { # Chromium functionality directly into the executable. ":dependencies", - # For configuring PartitionAlloc - "//base/allocator:buildflags", - # For the sampling profiler. "//chrome/common/profiler", @@ -433,7 +430,6 @@ if (is_win) { ":chrome_dll_manifest", ":chrome_dll_version", ":dependencies", - "//base/allocator:buildflags", "//chrome/app:chrome_dll_resources", "//chrome/app:command_ids", "//chrome/app/theme:chrome_unscaled_resources", @@ -947,6 +943,8 @@ if (is_win) { bundle_data("chrome_framework_resources") { sources = [ + "//ui/gl/resources/angle-metal/gpu_shader_cache.bin", + # This image is used to badge the lock icon in the # authentication dialogs, such as those used for installation # from disk image and Keystone promotion (if so enabled). It @@ -1161,7 +1159,6 @@ if (is_win) { deps = [ ":dependencies", - "//base/allocator:buildflags", "//build:chromeos_buildflags", "//chrome/app:command_ids", "//chrome/app:notification_metrics", @@ -1428,6 +1425,7 @@ group("dependencies") { "//build:branding_buildflags", "//build:chromeos_buildflags", "//chrome/browser", + "//chrome/browser:buildflags", "//chrome/browser/policy:path_parser", "//chrome/child", "//chrome/common", diff --git a/src/chrome/app/theme/theme_resources.grd b/src/chrome/app/theme/theme_resources.grd index 3d4410a9..d8bdbd57 100644 --- a/src/chrome/app/theme/theme_resources.grd +++ b/src/chrome/app/theme/theme_resources.grd @@ -1,4 +1,5 @@ + - @@ -275,6 +275,8 @@ + + diff --git a/src/chrome/common/media/cdm_registration.cc b/src/chrome/common/media/cdm_registration.cc index 547a4d78..614ccea9 100644 --- a/src/chrome/common/media/cdm_registration.cc +++ b/src/chrome/common/media/cdm_registration.cc @@ -248,6 +248,10 @@ void AddHardwareSecureWidevine(std::vector* cdms) { switches::kLacrosEnablePlatformHevc)) { capability.video_codecs.emplace(media::VideoCodec::kHEVC, kAllProfiles); } +#elif BUILDFLAG(IS_CHROMEOS_ASH) + if (base::FeatureList::IsEnabled(media::kPlatformHEVCDecoderSupport)) { + capability.video_codecs.emplace(media::VideoCodec::kHEVC, kAllProfiles); + } #else capability.video_codecs.emplace(media::VideoCodec::kHEVC, kAllProfiles); #endif // BUILDFLAG(IS_CHROMEOS_LACROS) diff --git a/src/components/version_ui/resources/about_version.html b/src/components/version_ui/resources/about_version.html index 7354bcbc..14221b89 100644 --- a/src/components/version_ui/resources/about_version.html +++ b/src/components/version_ui/resources/about_version.html @@ -65,6 +65,7 @@ about:version template page +
+ kAudioRendererAlgorithmStartingCapacityForEncrypted{ + &kAudioRendererAlgorithmParameters, "starting_capacity_for_encrypted", + base::Milliseconds(500)}; + // Prefer FFmpeg to LibVPX for Vp8 decoding with opaque alpha mode. BASE_FEATURE(kFFmpegDecodeOpaqueVP8, "FFmpegDecodeOpaqueVP8", @@ -526,6 +536,12 @@ BASE_FEATURE(kUseMultiPlaneFormatForHardwareVideo, "UseMultiPlaneFormatForHardwareVideo", base::FEATURE_DISABLED_BY_DEFAULT); +// Enables creating single shared image and mailbox for multi-planar formats for +// software video decoders. +BASE_FEATURE(kUseMultiPlaneFormatForSoftwareVideo, + "UseMultiPlaneFormatForSoftwareVideo", + base::FEATURE_DISABLED_BY_DEFAULT); + // Enables binding software video NV12/P010 GMBs as separate shared images. BASE_FEATURE(kMultiPlaneSoftwareVideoSharedImages, "MultiPlaneSoftwareVideoSharedImages", @@ -557,7 +573,7 @@ BASE_FEATURE(kOpenscreenCastStreamingSession, // information on the quality of the session using RTCP logs. BASE_FEATURE(kEnableRtcpReporting, "EnableRtcpReporting", - base::FEATURE_ENABLED_BY_DEFAULT); + base::FEATURE_DISABLED_BY_DEFAULT); // Approach original pre-REC MSE object URL autorevoking behavior, though await // actual attempt to use the object URL for attachment to perform revocation. @@ -703,9 +719,10 @@ BASE_FEATURE(kVaapiVideoDecodeLinux, "VaapiVideoDecoder", base::FEATURE_ENABLED_BY_DEFAULT); +// Temporary fix TODO: Alex313031 BASE_FEATURE(kVaapiVideoDecodeLinuxGL, "VaapiVideoDecodeLinuxGL", - base::FEATURE_ENABLED_BY_DEFAULT); + base::FEATURE_DISABLED_BY_DEFAULT); BASE_FEATURE(kVaapiVideoEncodeLinux, "VaapiVideoEncoder", @@ -748,6 +765,11 @@ BASE_FEATURE(kVaapiVP9Encoder, "VaapiVP9Encoder", base::FEATURE_ENABLED_BY_DEFAULT); +// Enable VA-API hardware encode acceleration for AV1. +BASE_FEATURE(kVaapiAV1Encoder, + "VaapiAV1Encoder", + base::FEATURE_ENABLED_BY_DEFAULT); + // Enable global VA-API lock. Disable this to use lock-free VA-API function // calls for thread safe backends. BASE_FEATURE(kGlobalVaapiLock, @@ -1106,7 +1128,7 @@ BASE_FEATURE(kIncludeIRCamerasInDeviceEnumeration, // Enables software rate controller encoding acceleration for Windows. const base::Feature MEDIA_EXPORT kMediaFoundationUseSoftwareRateCtrl{ - "MediaFoundationUseSoftwareRateCtrl", base::FEATURE_DISABLED_BY_DEFAULT}; + "MediaFoundationUseSoftwareRateCtrl", base::FEATURE_ENABLED_BY_DEFAULT}; // Enables MediaFoundation based video capture BASE_FEATURE(kMediaFoundationVideoCapture, @@ -1218,12 +1240,20 @@ BASE_FEATURE(kAllowClearDolbyVisionInMseWhenPlatformEncryptedDvEnabled, base::FEATURE_ENABLED_BY_DEFAULT); #endif -#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) +#if BUILDFLAG(IS_CHROMEOS_ASH) +// Expose the out-of-process video decoding feature from ash-chrome to +// lacros-chrome through the crosapi. +const base::Feature MEDIA_EXPORT kExposeOutOfProcessVideoDecodingToLacros{ + "ExposeOutOfProcessVideoDecodingToLacros", + base::FEATURE_ENABLED_BY_DEFAULT}; +#endif // BUILDFLAG(IS_CHROMEOS_ASH) + +#if BUILDFLAG(ALLOW_OOP_VIDEO_DECODER) // Spawn utility processes to perform hardware decode acceleration instead of // using the GPU process. const base::Feature MEDIA_EXPORT kUseOutOfProcessVideoDecoding{ "UseOutOfProcessVideoDecoding", base::FEATURE_DISABLED_BY_DEFAULT}; -#endif // BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) +#endif // BUILDFLAG(ALLOW_OOP_VIDEO_DECODER) #if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) // Spawn utility processes to perform hardware encode acceleration instead of @@ -1244,6 +1274,9 @@ BASE_FEATURE(kUseSequencedTaskRunnerForMediaService, "UseSequencedTaskRunnerForMediaService", base::FEATURE_DISABLED_BY_DEFAULT); +// SequencedTaskRunner isn't supported on Windows since the accelerator requires +// a COM STA TaskRunner. +#if !BUILDFLAG(IS_WIN) // Use SequencedTaskRunner for MojoVideoEncodeAcceleratorProvider. BASE_FEATURE(kUseSequencedTaskRunnerForMojoVEAProvider, "UseSequencedTaskRunnerForMojoVEAProvider", @@ -1253,12 +1286,13 @@ BASE_FEATURE(kUseSequencedTaskRunnerForMojoVEAProvider, base::FEATURE_DISABLED_BY_DEFAULT #endif ); +#endif // !BUILDFLAG(IS_WIN) -// Use SequencedTaskRunner for each MojoVideoEncodeAcceleratorService. Replaces +// Use TaskRunner for each MojoVideoEncodeAcceleratorService. Replaces // per-accelerator encoding task runner. -BASE_FEATURE(kUseSequencedTaskRunnerForMojoVEAService, - "UseSequencedTaskRunnerForMojoVEAService", -#if BUILDFLAG(IS_APPLE) +BASE_FEATURE(kUseTaskRunnerForMojoVEAService, + "UseTaskRunnerForMojoVEAService", +#if BUILDFLAG(IS_APPLE) || BUILDFLAG(IS_WIN) base::FEATURE_ENABLED_BY_DEFAULT #else base::FEATURE_DISABLED_BY_DEFAULT @@ -1480,12 +1514,32 @@ bool IsVideoCaptureAcceleratedJpegDecodingEnabled() { #endif } +bool IsMultiPlaneFormatForHardwareVideoEnabled() { + return base::FeatureList::IsEnabled(features::kPassthroughYuvRgbConversion) && + base::FeatureList::IsEnabled(kUseMultiPlaneFormatForHardwareVideo); +} + #if BUILDFLAG(IS_WIN) bool IsMediaFoundationD3D11VideoCaptureEnabled() { return base::FeatureList::IsEnabled(kMediaFoundationD3D11VideoCapture); } #endif +#if BUILDFLAG(ALLOW_OOP_VIDEO_DECODER) +bool IsOutOfProcessVideoDecodingEnabled() { +#if BUILDFLAG(IS_CASTOS) + // The sandbox for OOP-VD was designed assuming that we're not on CastOS (see + // go/oop-vd-sandbox). + // + // TODO(b/210759684): revisit the sandbox to see if this restriction is + // necessary. + return false; +#else + return base::FeatureList::IsEnabled(kUseOutOfProcessVideoDecoding); +#endif +} +#endif // BUILDFLAG(ALLOW_OOP_VIDEO_DECODER) + // Return bitmask of audio formats supported by EDID. uint32_t GetPassthroughAudioFormats() { #if BUILDFLAG(ENABLE_PASSTHROUGH_AUDIO_CODECS) diff --git a/src/media/gpu/vaapi/vaapi_wrapper.cc b/src/media/gpu/vaapi/vaapi_wrapper.cc index 43eeafe7..20eaceae 100644 --- a/src/media/gpu/vaapi/vaapi_wrapper.cc +++ b/src/media/gpu/vaapi/vaapi_wrapper.cc @@ -184,6 +184,110 @@ const char* VaapiFunctionName(VaapiFunctions function) { return kVaapiFunctionNames[static_cast(function)]; } +// This class is a wrapper around its |va_display_| (and its associated +// |va_lock_|) to guarantee mutual exclusion and singleton behaviour. +// +// Users of this class should hold onto a non-null VADisplayStateHandle for as +// long as they need to access any of the VADisplayStateSingleton methods. This +// guarantees that the VADisplayStateSingleton is properly initialized. +// +// Details: +// +// A VADisplayStateSingleton is immutable from the point of view of its users. +// That is, as long as a non-null VADisplayStateHandle exists, the va_display(), +// implementation_type(), and vendor_string() methods always return the same +// values. +// +// It's not strictly necessary to acquire the lock returned by va_lock() before +// calling va_display(), implementation_type(), or vendor_string(). However, on +// older drivers, it maybe necessary to acquire that lock before using the +// VADisplay returned by va_display() on any libva calls. That's because older +// drivers may not guarantee that it's safe to use the same VADisplay +// concurrently. +class VADisplayStateSingleton { + public: + VADisplayStateSingleton(const VADisplayStateSingleton&) = delete; + VADisplayStateSingleton& operator=(const VADisplayStateSingleton&) = delete; + + // This method must be called exactly once before trying to acquire a + // VADisplayStateHandle. + static void PreSandboxInitialization(); + + // If an initialized VADisplayStateSingleton exists, this method returns a + // VADisplayStateHandle to it. Otherwise, it attempts to initialize a + // VADisplayStateSingleton: if successful, it returns a VADisplayStateHandle + // to it; otherwise, it returns a null VADisplayStateHandle. + // + // This method is thread- and sequence- safe. + static VADisplayStateHandle GetHandle(); + + base::Lock* va_lock() const { return &va_lock_; } + VADisplay va_display() const { return va_display_; } + VAImplementation implementation_type() const { return implementation_type_; } + const std::string& vendor_string() const { return va_vendor_string_; } + + private: + friend class base::NoDestructor; + friend class VADisplayStateHandle; + + static VADisplayStateSingleton& GetInstance(); + + VADisplayStateSingleton() = default; + ~VADisplayStateSingleton() = default; + + // If this method returns false, the VADisplayStateSingleton is unchanged. + bool Initialize() EXCLUSIVE_LOCKS_REQUIRED(lock_); + + void OnRefDestroyed(); + + // This lock makes reference counting and initialization/de-initialization + // thread- and sequence-safe. It's independent of |va_lock_| which is only + // used to guard the VADisplay in case the libva backend is not known to be + // thread-safe. + // + // Note: the reason we don't use the same lock for everything is that it's + // perfectly valid for a user to try to acquire a VADisplayStateHandle while + // being in a block where libva calls are being made, so |va_lock_| could + // already be acquired in that situation and trying to acquire it again for + // reference counting would cause a deadlock. + base::Lock lock_; + + // DRM FD used to obtain access to the driver interface by VA. + base::ScopedFD drm_fd_ GUARDED_BY(lock_); + + int refcount_ GUARDED_BY(lock_) = 0; + + // Libva may or may not be thread safe depending on the backend. If not thread + // safe, we have to do locking for it ourselves. Therefore, this lock may need + // to be acquired for the duration of all VA-API calls and for the entire job + // submission sequence in ExecuteAndDestroyPendingBuffers(). + // + // Note: this field is made mutable to be able to mark va_lock() const: that + // way, we convey that that method does not really change the + // VADisplayStateSingleton. It's only mutable so that users of the + // VADisplayStateSingleton can acquire the lock. + // + // TODO(andrescj): maybe it's better to provide an AcquireVALock() method so + // that we control exactly how the lock can be used. + mutable base::Lock va_lock_; + + // Note: the following members are deliberately not annotated with either + // GUARDED_BY(lock_) or GUARDED_BY(va_lock_) because this annotation cannot + // capture the required thread model: these members can't change as long as a + // non-null VADisplayStateHandle exists, and users of VADisplayStateSingleton + // should ensure that a non-null VADisplayStateHandle exists as long as they + // need access to the VADisplayStateSingleton. Therefore, the accessor methods + // don't need to acquire any lock. + + VADisplay va_display_ = nullptr; + + // Enumerated version of vaQueryVendorString(). + VAImplementation implementation_type_ = VAImplementation::kInvalid; + + // String representing a driver acquired by vaQueryVendorString(). + std::string va_vendor_string_; +}; + } // namespace media #define LOG_VA_ERROR_AND_REPORT(va_error, function) \ @@ -253,6 +357,10 @@ media::VAImplementation VendorStringToImplementationType( } bool UseGlobalVaapiLock(media::VAImplementation implementation_type) { + if (!media::VaapiWrapper::allow_disabling_global_lock_) { + return true; + } + // Only iHD and Mesa Gallium are known to be thread safe at the moment. // * Mesa Gallium: b/144877595 // * iHD: crbug.com/1123429. @@ -608,8 +716,7 @@ const ProfileCodecMap& GetProfileCodecMap() { } // Maps a VideoCodecProfile |profile| to a VAProfile, or VAProfileNone. -VAProfile ProfileToVAProfile(VideoCodecProfile profile, - VaapiWrapper::CodecMode mode) { +VAProfile ProfileToVAProfile(VideoCodecProfile profile) { const auto& profiles = GetProfileCodecMap(); const auto& maybe_profile = profiles.find(profile); if (maybe_profile == profiles.end()) @@ -617,15 +724,29 @@ VAProfile ProfileToVAProfile(VideoCodecProfile profile, return maybe_profile->second; } -bool IsVAProfileSupported(VAProfile va_profile) { - const auto& profiles = GetProfileCodecMap(); +bool IsVAProfileSupported(VAProfile va_profile, bool is_encoding) { // VAProfileJPEGBaseline and VAProfileProtected are always recognized but are // not video codecs per se. - return va_profile == VAProfileJPEGBaseline || + if (va_profile == VAProfileJPEGBaseline) { + return true; + } #if BUILDFLAG(IS_CHROMEOS_ASH) - va_profile == VAProfileProtected || + if (va_profile == VAProfileProtected) { + return true; + } #endif - base::Contains(profiles, va_profile, + if (is_encoding) { + constexpr VAProfile kSupportableEncoderProfiles[] = { + VAProfileH264ConstrainedBaseline, + VAProfileH264Main, + VAProfileH264High, + VAProfileVP8Version0_3, + VAProfileVP9Profile0, + VAProfileAV1Profile0, + }; + return base::Contains(kSupportableEncoderProfiles, va_profile); + } + return base::Contains(GetProfileCodecMap(), va_profile, &ProfileCodecMap::value_type::second); } @@ -647,6 +768,11 @@ bool IsBlockedDriver(VaapiWrapper::CodecMode mode, return true; } + if (va_profile == VAProfileAV1Profile0 && + !base::FeatureList::IsEnabled(kVaapiAV1Encoder)) { + return true; + } + if (mode == VaapiWrapper::CodecMode::kEncodeVariableBitrate) { // The rate controller on grunt is not good enough to support VBR encoding, // b/253988139. @@ -661,138 +787,6 @@ bool IsBlockedDriver(VaapiWrapper::CodecMode mode, return false; } -// This class is a wrapper around its |va_display_| (and its associated -// |va_lock_|) to guarantee mutual exclusion and singleton behaviour. -class VADisplayState { - public: - static VADisplayState* Get(); - - VADisplayState(const VADisplayState&) = delete; - VADisplayState& operator=(const VADisplayState&) = delete; - - // Initialize static data before sandbox is enabled. - static void PreSandboxInitialization(); - - bool Initialize(); - VAStatus Deinitialize(); - - base::Lock* va_lock() { return &va_lock_; } - VADisplay va_display() const { return va_display_; } - VAImplementation implementation_type() const { return implementation_type_; } - const std::string& vendor_string() const { return va_vendor_string_; } - - void SetDrmFd(base::PlatformFile fd) { drm_fd_.reset(HANDLE_EINTR(dup(fd))); } - - private: - friend class base::NoDestructor; - - VADisplayState(); - ~VADisplayState() = default; - - // Implementation of Initialize() called only once. - bool InitializeOnce() EXCLUSIVE_LOCKS_REQUIRED(va_lock_); - bool InitializeVaDisplay_Locked() EXCLUSIVE_LOCKS_REQUIRED(va_lock_); - bool InitializeVaDriver_Locked() EXCLUSIVE_LOCKS_REQUIRED(va_lock_); - - int refcount_ GUARDED_BY(va_lock_); - - // Libva may or may not be thread safe depending on the backend. If not thread - // safe, we have to do locking for it ourselves. Therefore, this lock may need - // to be taken for the duration of all VA-API calls and for the entire job - // submission sequence in ExecuteAndDestroyPendingBuffers(). - base::Lock va_lock_; - - // Drm fd used to obtain access to the driver interface by VA. - base::ScopedFD drm_fd_; - - // The VADisplay handle. Valid between Initialize() and Deinitialize(). - VADisplay va_display_; - - // True if vaInitialize() has been called successfully, until Deinitialize(). - bool va_initialized_; - - // Enumerated version of vaQueryVendorString(). Valid after Initialize(). - VAImplementation implementation_type_ = VAImplementation::kInvalid; - - // String representing a driver acquired by vaQueryVendorString(). - std::string va_vendor_string_; -}; - -// static -VADisplayState* VADisplayState::Get() { - static base::NoDestructor display_state; - return display_state.get(); -} - -// static -void VADisplayState::PreSandboxInitialization() { - constexpr char kRenderNodeFilePattern[] = "/dev/dri/renderD%d"; - const char kNvidiaPath[] = "/dev/dri/nvidiactl"; - - // TODO: Is this still needed? - base::File nvidia_file = base::File( - base::FilePath::FromUTF8Unsafe(kNvidiaPath), - base::File::FLAG_OPEN | base::File::FLAG_READ | base::File::FLAG_WRITE); - - // This loop ends on either the first card that does not exist or the first - // render node that is not vgem. - for (int i = 128;; i++) { - base::FilePath dev_path(FILE_PATH_LITERAL( - base::StringPrintf(kRenderNodeFilePattern, i).c_str())); - base::File drm_file = - base::File(dev_path, base::File::FLAG_OPEN | base::File::FLAG_READ | - base::File::FLAG_WRITE); - if (!drm_file.IsValid()) - return; - // Skip the virtual graphics memory manager device. - drmVersionPtr version = drmGetVersion(drm_file.GetPlatformFile()); - if (!version) - continue; - std::string version_name( - version->name, - base::checked_cast(version->name_len)); - drmFreeVersion(version); - if (base::EqualsCaseInsensitiveASCII(version_name, "vgem")) - continue; - VADisplayState::Get()->SetDrmFd(drm_file.GetPlatformFile()); - return; - } -} - -VADisplayState::VADisplayState() - : refcount_(0), va_display_(nullptr), va_initialized_(false) {} - -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) - return false; -#endif - - bool libraries_initialized = IsVaInitialized() && IsVa_drmInitialized(); -#if BUILDFLAG(USE_VAAPI_X11) - libraries_initialized = libraries_initialized && IsVa_x11Initialized(); -#endif - if (!libraries_initialized) - return false; - - // Manual refcounting to ensure the rest of the method is called only once. - if (refcount_++ > 0) - return true; - - const bool success = InitializeOnce(); - UMA_HISTOGRAM_BOOLEAN("Media.VaapiWrapper.VADisplayStateInitializeSuccess", - success); - return success; -} - #if BUILDFLAG(USE_VAAPI_X11) absl::optional GetVADisplayStateX11(const base::ScopedFD& drm_fd) { @@ -837,90 +831,6 @@ absl::optional GetVADisplayState(const base::ScopedFD& drm_fd) { #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 - - if (!display) - return false; - - va_display_ = *display; - if (!vaDisplayIsValid(va_display_)) { - LOG(ERROR) << "Could not get a valid VA display"; - return false; - } - - return true; -} - -bool VADisplayState::InitializeVaDriver_Locked() { - // The VAAPI version. - int major_version, minor_version; - VAStatus va_res = vaInitialize(va_display_, &major_version, &minor_version); - if (va_res != VA_STATUS_SUCCESS) { - VLOGF(1) << "vaInitialize failed: " << vaErrorStr(va_res); - return false; - } - va_vendor_string_ = vaQueryVendorString(va_display_); - DLOG_IF(WARNING, va_vendor_string_.empty()) - << "Vendor string empty or error reading."; - DVLOG(1) << "VAAPI version: " << major_version << "." << minor_version << " " - << va_vendor_string_; - implementation_type_ = VendorStringToImplementationType(va_vendor_string_); - - va_initialized_ = true; - - // The VAAPI version is determined from what is loaded on the system by - // calling vaInitialize(). Since the libva is now ABI-compatible, relax the - // version check which helps in upgrading the libva, without breaking any - // existing functionality. Make sure the system version is not older than - // the version with which the chromium is built since libva is only - // guaranteed to be backward (and not forward) compatible. - if (VA_MAJOR_VERSION > major_version || - (VA_MAJOR_VERSION == major_version && VA_MINOR_VERSION > minor_version)) { - VLOGF(1) << "The system version " << major_version << "." << minor_version - << " should be greater than or equal to " << VA_MAJOR_VERSION - << "." << VA_MINOR_VERSION; - return false; - } - return true; -} - -bool VADisplayState::InitializeOnce() { - // Set VA logging level, unless already set. - constexpr char libva_log_level_env[] = "LIBVA_MESSAGING_LEVEL"; - std::unique_ptr env(base::Environment::Create()); - if (!env->HasVar(libva_log_level_env)) - env->SetVar(libva_log_level_env, "1"); - - if (!InitializeVaDisplay_Locked() || !InitializeVaDriver_Locked()) - return false; - return true; -} - -VAStatus VADisplayState::Deinitialize() { - base::AutoLock auto_lock(va_lock_); - VAStatus va_res = VA_STATUS_SUCCESS; - - if (--refcount_ > 0) - return va_res; - - // Must check if vaInitialize completed successfully, to work around a bug in - // libva. The bug was fixed upstream: - // http://lists.freedesktop.org/archives/libva/2013-July/001807.html - // TODO(mgiuca): Remove this check, and the |va_initialized_| variable, once - // the fix has rolled out sufficiently. - if (va_initialized_ && va_display_) - va_res = vaTerminate(va_display_); - va_initialized_ = false; - va_display_ = nullptr; - return va_res; -} - // Returns all the VAProfiles that the driver lists as supported, regardless of // what Chrome supports or not. std::vector GetSupportedVAProfiles(const base::Lock* va_lock, @@ -1197,12 +1107,14 @@ const VASupportedProfiles::ProfileInfo* VASupportedProfiles::IsProfileSupported( VASupportedProfiles::VASupportedProfiles() : report_error_to_uma_cb_(base::DoNothing()) { - VADisplayState* display_state = VADisplayState::Get(); - if (!display_state->Initialize()) + VADisplayStateHandle display_state = VADisplayStateSingleton::GetHandle(); + if (!display_state) { return; + } VADisplay va_display = display_state->va_display(); - DCHECK(va_display) << "VADisplayState hasn't been properly Initialize()d"; + DCHECK(va_display) + << "VADisplayStateSingleton hasn't been properly initialized"; base::Lock* va_lock = display_state->va_lock(); if (!UseGlobalVaapiLock(display_state->implementation_type())) { @@ -1211,9 +1123,6 @@ VASupportedProfiles::VASupportedProfiles() FillSupportedProfileInfos(va_lock, va_display, display_state->vendor_string()); - - const VAStatus va_res = display_state->Deinitialize(); - VA_LOG_ON_ERROR(va_res, VaapiFunctions::kVATerminate); } void VASupportedProfiles::FillSupportedProfileInfos( @@ -1245,7 +1154,7 @@ void VASupportedProfiles::FillSupportedProfileInfos( continue; if ((mode != VaapiWrapper::kVideoProcess) && - !IsVAProfileSupported(va_profile)) { + !IsVAProfileSupported(va_profile, IsModeEncoding(mode))) { continue; } @@ -1432,7 +1341,18 @@ bool VASupportedProfiles::FillProfileInfo_Locked( // Now work around some driver misreporting for JPEG decoding. if (va_profile == VAProfileJPEGBaseline && entrypoint == VAEntrypointVLD) { - if (VADisplayState::Get()->implementation_type() == + auto va_display_state_handle = VADisplayStateSingleton::GetHandle(); + + // Note: FillProfileInfo_Locked() is called only from + // FillSupportedProfileInfos() which in turn is called only from the + // VASupportedProfiles constructor. This call occurs while a valid + // VADisplayStateHandle exists (because of the check in the constructor). + // That means that at this point, there is an initialized + // VADisplayStateSingleton, so the VADisplayStateSingleton::GetHandle() call + // above must produce a valid handle. + CHECK(va_display_state_handle); + + if (va_display_state_handle->implementation_type() == VAImplementation::kMesaGallium) { // TODO(andrescj): the VAAPI state tracker in mesa does not report // VA_RT_FORMAT_YUV422 as being supported for JPEG decoding. However, it @@ -1512,12 +1432,13 @@ VASupportedImageFormats::GetSupportedImageFormats() const { VASupportedImageFormats::VASupportedImageFormats() : report_error_to_uma_cb_(base::DoNothing()) { - VADisplayState* display_state = VADisplayState::Get(); - if (!display_state->Initialize()) + auto display_state = VADisplayStateSingleton::GetHandle(); + if (!display_state) { return; + } - // Pointer to VADisplayState's members |va_lock_| if using global VA lock or - // the implementation is not thread safe. + // Pointer to VADisplayStateSingleton's |va_lock_| member if using a global VA + // lock or if the implementation is not thread-safe. base::Lock* va_lock = display_state->va_lock(); if (!UseGlobalVaapiLock(display_state->implementation_type())) { va_lock = nullptr; @@ -1526,14 +1447,12 @@ VASupportedImageFormats::VASupportedImageFormats() { base::AutoLockMaybe auto_lock(va_lock); VADisplay va_display = display_state->va_display(); - DCHECK(va_display) << "VADisplayState hasn't been properly initialized"; + DCHECK(va_display) + << "VADisplayStateSingleton hasn't been properly initialized"; if (!InitSupportedImageFormats_Locked(va_lock, va_display)) LOG(ERROR) << "Failed to get supported image formats"; } - - const VAStatus va_res = display_state->Deinitialize(); - VA_LOG_ON_ERROR(va_res, VaapiFunctions::kVATerminate); } bool VASupportedImageFormats::InitSupportedImageFormats_Locked( @@ -1564,7 +1483,17 @@ bool VASupportedImageFormats::InitSupportedImageFormats_Locked( supported_formats_.resize(static_cast(num_image_formats)); // Now work around some driver misreporting. - if (VADisplayState::Get()->implementation_type() == + auto va_display_state_handle = VADisplayStateSingleton::GetHandle(); + + // Note: InitSupportedImageFormats_Locked() is called only from the + // VASupportedImageFormats constructor. This call occurs while a valid + // VADisplayStateHandle exists (because of the check in the constructor). That + // means that at this point, there is an initialized VADisplayStateSingleton, + // so the VADisplayStateSingleton::GetHandle() call above must produce a valid + // handle. + CHECK(va_display_state_handle); + + if (va_display_state_handle->implementation_type() == VAImplementation::kMesaGallium) { // TODO(andrescj): considering that the VAAPI state tracker in mesa can // convert from NV12 to IYUV when doing vaGetImage(), it's reasonable to @@ -1588,7 +1517,8 @@ bool IsLowPowerEncSupported(VAProfile va_profile) { VAProfileH264Main, VAProfileH264High, VAProfileVP9Profile0, - VAProfileVP9Profile2}; + VAProfileAV1Profile0, + }; if (!base::Contains(kSupportedLowPowerEncodeProfiles, va_profile)) return false; @@ -1622,13 +1552,210 @@ bool IsVBREncodingSupported(VAProfile va_profile) { } // namespace +// static +VADisplayStateSingleton& VADisplayStateSingleton::GetInstance() { + static base::NoDestructor va_display_state; + return *va_display_state; +} + +// static +void VADisplayStateSingleton::PreSandboxInitialization() { + VADisplayStateSingleton& va_display_state = GetInstance(); + base::AutoLock lock(va_display_state.lock_); + + constexpr char kRenderNodeFilePattern[] = "/dev/dri/renderD%d"; + const char kNvidiaDriPath[] = "/dev/dri/nvidiactl"; + const char kNvidiaPath[] = "/dev/nvidiactl"; + + // TODO: Is this still needed? + base::File nvidia_file = base::File( + base::FilePath::FromUTF8Unsafe(kNvidiaPath), + base::File::FLAG_OPEN | base::File::FLAG_READ | base::File::FLAG_WRITE); + + // This loop ends on either the first card that does not exist or the first + // render node that is not vgem. + for (int i = 128;; i++) { + base::FilePath dev_path(FILE_PATH_LITERAL( + base::StringPrintf(kRenderNodeFilePattern, i).c_str())); + base::File drm_file = + base::File(dev_path, base::File::FLAG_OPEN | base::File::FLAG_READ | + base::File::FLAG_WRITE); + if (!drm_file.IsValid()) { + return; + } + // Skip the virtual graphics memory manager device. + drmVersionPtr version = drmGetVersion(drm_file.GetPlatformFile()); + if (!version) { + continue; + } + std::string version_name( + version->name, + base::checked_cast(version->name_len)); + drmFreeVersion(version); + if (base::EqualsCaseInsensitiveASCII(version_name, "vgem")) { + continue; + } + va_display_state.drm_fd_ = base::ScopedFD(drm_file.TakePlatformFile()); + return; + } +} + +// static +VADisplayStateHandle VADisplayStateSingleton::GetHandle() { + VADisplayStateSingleton& va_display_state = GetInstance(); + base::AutoLock lock(va_display_state.lock_); + if (va_display_state.refcount_ > 0) { + // There's already an initialized VADisplayStateSingleton. Return a handle + // to it. + CHECK_LT(va_display_state.refcount_, + std::numeric_limits::max()); + va_display_state.refcount_++; + return VADisplayStateHandle(&va_display_state); + } + + if (!va_display_state.drm_fd_.is_valid()) { + VLOGF(1) + << "Either VADisplayStateSingleton::PreSandboxInitialization() hasn't " + "been called or that method failed to find a suitable render node"; + return {}; + } + +#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) { + return {}; + } +#endif + + bool libraries_initialized = IsVaInitialized() && IsVa_drmInitialized(); +#if BUILDFLAG(USE_VAAPI_X11) + libraries_initialized = libraries_initialized && IsVa_x11Initialized(); +#endif + if (!libraries_initialized) { + return {}; + } + + const bool success = va_display_state.Initialize(); + UMA_HISTOGRAM_BOOLEAN("Media.VaapiWrapper.VADisplayStateInitializeSuccess", + success); + return success ? VADisplayStateHandle(&va_display_state) : VADisplayStateHandle(); +} + +bool VADisplayStateSingleton::Initialize() { + // Set VA logging level, unless already set. + constexpr char libva_log_level_env[] = "LIBVA_MESSAGING_LEVEL"; + std::unique_ptr env(base::Environment::Create()); + if (!env->HasVar(libva_log_level_env)) { + env->SetVar(libva_log_level_env, "1"); + } + + absl::optional display = +#if BUILDFLAG(USE_VAAPI_X11) + GetVADisplayStateX11(drm_fd_); +#else + GetVADisplayState(drm_fd_); +#endif + + if (!display) { + return false; + } + VADisplay va_display = *display; + base::ScopedClosureRunner va_display_cleaner_cb(base::BindOnce( + [](VADisplay va_display) { + if (vaDisplayIsValid(va_display)) { + vaTerminate(va_display); + } + }, + va_display)); + + if (!vaDisplayIsValid(va_display)) { + LOG(ERROR) << "Could not get a valid VA display"; + return false; + } + + // The VA-API version. + int major_version, minor_version; + VAStatus va_res = vaInitialize(va_display, &major_version, &minor_version); + if (va_res != VA_STATUS_SUCCESS) { + VLOGF(1) << "vaInitialize failed: " << vaErrorStr(va_res); + return false; + } + + const std::string va_vendor_string = vaQueryVendorString(va_display); + if (va_vendor_string.empty()) { + VLOGF(1) << "vaQueryVendorString returned an empty string"; + return false; + } + DVLOG(1) << "VAAPI version: " << major_version << "." << minor_version << " " + << va_vendor_string; + + const VAImplementation implementation_type = + VendorStringToImplementationType(va_vendor_string); + + // The VAAPI version is determined from what is loaded on the system by + // calling vaInitialize(). Since the libva is now ABI-compatible, relax the + // version check which helps in upgrading the libva, without breaking any + // existing functionality. Make sure the system version is not older than + // the version with which the chromium is built since libva is only + // guaranteed to be backward (and not forward) compatible. + if (VA_MAJOR_VERSION > major_version || + (VA_MAJOR_VERSION == major_version && VA_MINOR_VERSION > minor_version)) { + VLOGF(1) << "The system version " << major_version << "." << minor_version + << " should be greater than or equal to " << VA_MAJOR_VERSION + << "." << VA_MINOR_VERSION; + return false; + } + + std::ignore = va_display_cleaner_cb.Release(); + refcount_ = 1; + va_display_ = va_display; + implementation_type_ = implementation_type; + va_vendor_string_ = va_vendor_string; + return true; +} + +void VADisplayStateSingleton::OnRefDestroyed() { + base::AutoLock lock(lock_); + if (--refcount_ > 0) { + return; + } + + // No more handles to the VADisplayStateSingleton remain. We can clean up. + vaTerminate(va_display_); + va_display_ = nullptr; + implementation_type_ = VAImplementation::kInvalid; + va_vendor_string_ = ""; +} + +VADisplayStateHandle::VADisplayStateHandle() : va_display_state_(nullptr) {} + +VADisplayStateHandle::VADisplayStateHandle( + VADisplayStateSingleton* va_display_state) + : va_display_state_(va_display_state) {} + +VADisplayStateHandle::~VADisplayStateHandle() { + if (va_display_state_) { + va_display_state_->OnRefDestroyed(); + } +} + NativePixmapAndSizeInfo::NativePixmapAndSizeInfo() = default; NativePixmapAndSizeInfo::~NativePixmapAndSizeInfo() = default; // static VAImplementation VaapiWrapper::GetImplementationType() { - return VADisplayState::Get()->implementation_type(); + auto va_display_state_handle = VADisplayStateSingleton::GetHandle(); + return va_display_state_handle + ? va_display_state_handle->implementation_type() + : VAImplementation::kInvalid; } // static @@ -1654,8 +1781,13 @@ scoped_refptr VaapiWrapper::Create( } #endif - scoped_refptr vaapi_wrapper( - new VaapiWrapper(mode, enforce_sequence_affinity)); + auto va_display_state_handle = VADisplayStateSingleton::GetHandle(); + if (!va_display_state_handle) { + return nullptr; + } + + scoped_refptr vaapi_wrapper(new VaapiWrapper( + std::move(va_display_state_handle), mode, enforce_sequence_affinity)); if (vaapi_wrapper->VaInitialize(report_error_to_uma_cb)) { if (vaapi_wrapper->Initialize(va_profile, encryption_scheme)) return vaapi_wrapper; @@ -1672,7 +1804,7 @@ scoped_refptr VaapiWrapper::CreateForVideoCodec( EncryptionScheme encryption_scheme, const ReportErrorToUMACB& report_error_to_uma_cb, bool enforce_sequence_affinity) { - const VAProfile va_profile = ProfileToVAProfile(profile, mode); + const VAProfile va_profile = ProfileToVAProfile(profile); return Create(mode, va_profile, encryption_scheme, report_error_to_uma_cb, enforce_sequence_affinity); } @@ -1947,13 +2079,6 @@ bool VaapiWrapper::IsVppSupportedForJpegDecodedSurfaceToFourCC( if (!IsDecodingSupportedForInternalFormat(VAProfileJPEGBaseline, rt_format)) return false; - // Workaround: for Mesa VAAPI driver, VPP only supports internal surface - // format for 4:2:0 JPEG image. - DCHECK_NE(VAImplementation::kInvalid, GetImplementationType()); - if (GetImplementationType() == VAImplementation::kMesaGallium && - rt_format != VA_RT_FORMAT_YUV420) { - return false; - } return IsVppFormatSupported(fourcc); } @@ -2950,8 +3075,7 @@ bool VaapiWrapper::GetVAEncMaxNumOfRefFrames(VideoCodecProfile profile, size_t* max_ref_frames) { CHECK(!enforce_sequence_affinity_ || sequence_checker_.CalledOnValidSequence()); - const VAProfile va_profile = - ProfileToVAProfile(profile, CodecMode::kEncodeConstantBitrate); + const VAProfile va_profile = ProfileToVAProfile(profile); VAConfigAttrib attrib; attrib.type = VAConfigAttribEncMaxRefFrames; @@ -2970,8 +3094,7 @@ bool VaapiWrapper::GetSupportedPackedHeaders(VideoCodecProfile profile, bool& packed_slice) { CHECK(!enforce_sequence_affinity_ || sequence_checker_.CalledOnValidSequence()); - const VAProfile va_profile = - ProfileToVAProfile(profile, CodecMode::kEncodeConstantBitrate); + const VAProfile va_profile = ProfileToVAProfile(profile); VAConfigAttrib attrib{}; attrib.type = VAConfigAttribEncPackedHeaders; base::AutoLockMaybe auto_lock(va_lock_.get()); @@ -3115,8 +3238,13 @@ bool VaapiWrapper::BlitSurface(const VASurface& va_surface_src, } // static -void VaapiWrapper::PreSandboxInitialization() { - VADisplayState::PreSandboxInitialization(); +bool VaapiWrapper::allow_disabling_global_lock_ = false; + +// static +void VaapiWrapper::PreSandboxInitialization(bool allow_disabling_global_lock) { + allow_disabling_global_lock_ = allow_disabling_global_lock; + + VADisplayStateSingleton::PreSandboxInitialization(); const std::string va_suffix(std::to_string(VA_MAJOR_VERSION + 1)); StubPathMap paths; @@ -3137,10 +3265,16 @@ void VaapiWrapper::PreSandboxInitialization() { static bool result = InitializeStubs(paths); if (!result) { static const char kErrorMsg[] = "Failed to initialize VAAPI libs"; +#if BUILDFLAG(IS_CHROMEOS) + // When Chrome runs on Linux with target_os="chromeos", do not log error + // message without VAAPI libraries. + LOG_IF(ERROR, base::SysInfo::IsRunningOnChromeOS()) << kErrorMsg; +#else LOG(ERROR) << kErrorMsg; +#endif } - // VASupportedProfiles::Get creates VADisplayState and in so doing + // VASupportedProfiles::Get creates VADisplayStateSingleton and in so doing // driver associated libraries are dlopen(), to know: // i965_drv_video.so // hybrid_drv_video.so (platforms that support it) @@ -3148,11 +3282,17 @@ void VaapiWrapper::PreSandboxInitialization() { VASupportedProfiles::Get(); } -VaapiWrapper::VaapiWrapper(CodecMode mode, bool enforce_sequence_affinity) +VaapiWrapper::VaapiWrapper(VADisplayStateHandle va_display_state_handle, + CodecMode mode, + bool enforce_sequence_affinity) : mode_(mode), enforce_sequence_affinity_(enforce_sequence_affinity), - va_lock_(VADisplayState::Get()->va_lock()), - va_display_(nullptr), + va_display_state_handle_(std::move(va_display_state_handle)), + va_lock_(va_display_state_handle_ ? va_display_state_handle_->va_lock() + : nullptr), + va_display_(va_display_state_handle_ + ? va_display_state_handle_->va_display() + : nullptr), va_profile_(VAProfileNone), va_entrypoint_(kVAEntrypointInvalid) {} @@ -3248,9 +3388,6 @@ void VaapiWrapper::Deinitialize() { va_config_id_ = VA_INVALID_ID; va_display_ = nullptr; } - - const VAStatus va_res = VADisplayState::Get()->Deinitialize(); - VA_LOG_ON_ERROR(va_res, VaapiFunctions::kVATerminate); } bool VaapiWrapper::VaInitialize( @@ -3258,20 +3395,13 @@ bool VaapiWrapper::VaInitialize( CHECK(!enforce_sequence_affinity_ || sequence_checker_.CalledOnValidSequence()); report_error_to_uma_cb_ = report_error_to_uma_cb; - if (!VADisplayState::Get()->Initialize()) - return false; DCHECK(va_lock_); if (enforce_sequence_affinity_ && - !UseGlobalVaapiLock(VADisplayState::Get()->implementation_type())) { + !UseGlobalVaapiLock(va_display_state_handle_->implementation_type())) { va_lock_ = nullptr; } - { - base::AutoLockMaybe auto_lock(va_lock_.get()); - va_display_ = VADisplayState::Get()->va_display(); - DCHECK(va_display_) << "VADisplayState hasn't been properly Initialize()d"; - } return true; } diff --git a/src/media/gpu/vaapi/vaapi_wrapper.h b/src/media/gpu/vaapi/vaapi_wrapper.h index c6dfb6d6..528eb557 100644 --- a/src/media/gpu/vaapi/vaapi_wrapper.h +++ b/src/media/gpu/vaapi/vaapi_wrapper.h @@ -54,6 +54,7 @@ class Rect; namespace media { constexpr unsigned int kInvalidVaRtFormat = 0u; +class VADisplayStateSingleton; class VideoFrame; // Enum, function and callback type to allow VaapiWrapper to log errors in VA @@ -97,6 +98,42 @@ enum class VAImplementation { kInvalid, }; +// A VADisplayStateHandle is somewhat like a scoped_refptr for a +// VADisplayStateSingleton (an internal class used to keep track of a singleton +// VADisplay). As long as a non-null VADisplayStateHandle exists, the underlying +// VADisplay is initialized and can be used. When the last non-null +// VADisplayStateHandle is destroyed, the underlying VADisplay is cleaned up. +// +// Unlike a scoped_refptr, a VADisplayStateHandle is move-only. +// +// Note: a VADisplayStateHandle instance is thread- and sequence-safe, but the +// underlying VADisplay may need protection. See the comments for the +// VADisplayStateSingleton documentation. +class VADisplayStateHandle { + public: + // Creates a null VADisplayStateHandle. + VADisplayStateHandle(); + + VADisplayStateHandle(VADisplayStateHandle&& other) = default; + VADisplayStateHandle& operator=(VADisplayStateHandle&& other) = default; + + VADisplayStateHandle(const VADisplayStateHandle&) = delete; + VADisplayStateHandle& operator=(const VADisplayStateHandle&) = delete; + + ~VADisplayStateHandle(); + + VADisplayStateSingleton* operator->() { return va_display_state_; } + + explicit operator bool() const { return !!va_display_state_; } + + private: + friend class VADisplayStateSingleton; + + explicit VADisplayStateHandle(VADisplayStateSingleton* va_display_state); + + raw_ptr va_display_state_; +}; + // This class handles VA-API calls and ensures proper locking of VA-API calls // to libva, the userspace shim to the HW codec driver. The thread safety of // libva depends on the backend. If the backend is not thread-safe, we need to @@ -124,6 +161,11 @@ enum class VAImplementation { class MEDIA_GPU_EXPORT VaapiWrapper : public base::RefCountedThreadSafe { public: + // Whether it's okay or not to try to disable the VA-API global lock on the + // current process. This is intended to be set only once during process + // start-up. + static bool allow_disabling_global_lock_; + enum CodecMode { kDecode, #if BUILDFLAG(IS_CHROMEOS_ASH) @@ -537,14 +579,17 @@ class MEDIA_GPU_EXPORT VaapiWrapper ); // Initialize static data before sandbox is enabled. - static void PreSandboxInitialization(); + static void PreSandboxInitialization( + bool allow_disabling_global_lock = false); // vaDestroySurfaces() a vector or a single VASurfaceID. virtual void DestroySurfaces(std::vector va_surfaces); virtual void DestroySurface(VASurfaceID va_surface_id); protected: - explicit VaapiWrapper(CodecMode mode, bool enforce_sequence_affinity = true); + VaapiWrapper(VADisplayStateHandle va_display_state_handle, + CodecMode mode, + bool enforce_sequence_affinity = true); virtual ~VaapiWrapper(); private: @@ -629,13 +674,21 @@ class MEDIA_GPU_EXPORT VaapiWrapper const bool enforce_sequence_affinity_; base::SequenceCheckerImpl sequence_checker_; - // If using global VA lock, this is a pointer to VADisplayState's member - // |va_lock_|. Guaranteed to be valid for the lifetime of VaapiWrapper. + // This is declared before |va_display_| and |va_lock_| to guarantee their + // validity for as long as the VaapiWrapper is alive. + VADisplayStateHandle va_display_state_handle_; + + // If using a global VA lock, this is a pointer to VADisplayStateSingleton's + // member |va_lock_|. Guaranteed to be valid for the lifetime of the + // VaapiWrapper due to the |va_display_state_handle_| above. raw_ptr va_lock_; + // Guaranteed to be valid for the lifetime of the VaapiWrapper due to the + // |va_display_state_handle_| above. + VADisplay va_display_ GUARDED_BY(va_lock_); + // VA handles. // All valid after successful Initialize() and until Deinitialize(). - VADisplay va_display_ GUARDED_BY(va_lock_); VAConfigID va_config_id_{VA_INVALID_ID}; // Created in CreateContext() or CreateContextAndSurfaces() and valid until // DestroyContext() or DestroyContextAndSurfaces(). diff --git a/src/net/url_request/url_request_http_job.cc b/src/net/url_request/url_request_http_job.cc index f7067881..aa0cf8c9 100644 --- a/src/net/url_request/url_request_http_job.cc +++ b/src/net/url_request/url_request_http_job.cc @@ -29,7 +29,6 @@ #include "base/strings/stringprintf.h" #include "base/task/single_thread_task_runner.h" #include "base/time/time.h" -#include "base/trace_event/trace_event.h" #include "base/types/optional_util.h" #include "base/values.h" #include "build/build_config.h" @@ -44,6 +43,7 @@ #include "net/base/privacy_mode.h" #include "net/base/registry_controlled_domains/registry_controlled_domain.h" #include "net/base/trace_constants.h" +#include "net/base/tracing.h" #include "net/base/url_util.h" #include "net/cert/cert_status_flags.h" #include "net/cert/ct_policy_status.h" diff --git a/src/third_party/zlib/BUILD.gn b/src/third_party/zlib/BUILD.gn index 6371485e..0c6da932 100644 --- a/src/third_party/zlib/BUILD.gn +++ b/src/third_party/zlib/BUILD.gn @@ -515,6 +515,10 @@ if (build_with_chromium) { data = [ "google/test/data/" ] + if (is_ios) { + bundle_deps = [ "google:zlib_pak_bundle_data" ] + } + deps = [ ":zlib", "google:compression_utils",