Commit 9583705f authored by hshi's avatar hshi Committed by Commit bot

VAAPI Wrapper: refactor management of drm file

Make sure we use the same file in all instances of VaapiWrapper.

Define a refcounted global instance of VADisplayState that is only initialized
(via vaInitialize()) once and destroyed upon release of the last refcount.
This ensures a single drm_intel_bufmgr per fd, and avoids the double-close
problem as seen in bug 464628.

Pipe a PreSandboxInitialization to open the render node before starting sandbox.

After this CL the VEA/VDA unittests need to invoke the PreSandboxInitialization
as well.

BUG=475250
TEST=verify HW video works on link (check histograms) and VDA/VEA unittests

Review URL: https://codereview.chromium.org/1137483002

Cr-Commit-Position: refs/heads/master@{#329410}
parent a26ccdf9
This diff is collapsed.
......@@ -134,9 +134,6 @@ class CONTENT_EXPORT VaapiWrapper {
gfx::Size dest_size);
#endif // USE_X11
// Returns true if the VAAPI version is less than the specified version.
bool VAAPIVersionLessThan(int major, int minor);
// Get a VAImage from a VASurface and map it into memory. The size and format
// are derived from the surface. Use GetVaImage() instead if |format| or
// |size| are different from surface internal representation. The VAImage
......@@ -191,6 +188,9 @@ class CONTENT_EXPORT VaapiWrapper {
VASurfaceID va_surface_id_dest,
const gfx::Size& dest_size);
// Initialize static data before sandbox is enabled.
static void PreSandboxInitialization();
private:
struct ProfileInfo {
VAProfile va_profile;
......@@ -209,6 +209,51 @@ class CONTENT_EXPORT VaapiWrapper {
std::vector<ProfileInfo> supported_profiles_[kCodecModeMax];
};
class VADisplayState {
public:
VADisplayState();
~VADisplayState();
// |va_lock_| must be held on entry.
bool Initialize(VAStatus* status);
void Deinitialize(VAStatus* status);
base::Lock* va_lock() { return &va_lock_; }
VADisplay va_display() const { return va_display_; }
#if defined(USE_OZONE)
void SetDrmFd(base::PlatformFile fd);
#endif // USE_OZONE
private:
friend class base::LazyInstance<VADisplayState>;
// Returns true if the VAAPI version is less than the specified version.
bool VAAPIVersionLessThan(int major, int minor);
// Protected by |va_lock_|.
int refcount_;
// Libva is not thread safe, so we have to do locking for it ourselves.
// This lock is to be taken for the duration of all VA-API calls and for
// the entire job submission sequence in ExecuteAndDestroyPendingBuffers().
base::Lock va_lock_;
#if defined(USE_OZONE)
// Drm fd used to obtain access to the driver interface by VA.
base::ScopedFD drm_fd_;
#endif // USE_OZONE
// The VADisplay handle.
VADisplay va_display_;
// The VAAPI version.
int major_version_, minor_version_;
// True if vaInitialize has been called successfully.
bool va_initialized_;
};
VaapiWrapper();
bool Initialize(CodecMode mode, VAProfile va_profile);
......@@ -269,16 +314,15 @@ class CONTENT_EXPORT VaapiWrapper {
static VAProfile ProfileToVAProfile(media::VideoCodecProfile profile,
CodecMode mode);
// Libva is not thread safe, so we have to do locking for it ourselves.
// This lock is to be taken for the duration of all VA-API calls and for
// the entire job submission sequence in ExecuteAndDestroyPendingBuffers().
base::Lock va_lock_;
// Pointer to VADisplayState's member |va_lock_|. Guaranteed to be valid for
// the lifetime of VaapiWrapper.
base::Lock* va_lock_;
// Allocated ids for VASurfaces.
std::vector<VASurfaceID> va_surface_ids_;
// The VAAPI version.
int major_version_, minor_version_;
// Singleton instance of VADisplayState.
static base::LazyInstance<VADisplayState> va_display_state_;
// VA handles.
// All valid after successful Initialize() and until Deinitialize().
......@@ -287,8 +331,6 @@ class CONTENT_EXPORT VaapiWrapper {
// Created for the current set of va_surface_ids_ in CreateSurfaces() and
// valid until DestroySurfaces().
VAContextID va_context_id_;
// True if vaInitialize has been called successfully.
bool va_initialized_;
// Data queued up for HW codec, to be committed on next execution.
std::vector<VABufferID> pending_slice_bufs_;
......@@ -308,11 +350,6 @@ class CONTENT_EXPORT VaapiWrapper {
VAContextID va_vpp_context_id_;
VABufferID va_vpp_buffer_id_;
#if defined(USE_OZONE)
// Drm file used to obtain access to the driver interface by VA.
base::File drm_file_;
#endif // USE_OZONE
// Singleton variable to store supported profile information for encode and
// decode.
static base::LazyInstance<LazyProfileInfos> profile_infos_;
......
......@@ -1638,6 +1638,10 @@ int main(int argc, char **argv) {
ui::OzonePlatform::InitializeForUI();
#endif
#if defined(OS_CHROMEOS) && defined(ARCH_CPU_X86_FAMILY)
content::VaapiWrapper::PreSandboxInitialization();
#endif
content::g_env =
reinterpret_cast<content::VideoDecodeAcceleratorTestEnvironment*>(
testing::AddGlobalTestEnvironment(
......
......@@ -31,6 +31,7 @@
#endif
#if defined(ARCH_CPU_X86_FAMILY)
#include "content/common/gpu/media/vaapi_video_encode_accelerator.h"
#include "content/common/gpu/media/vaapi_wrapper.h"
#endif // defined(ARCH_CPU_X86_FAMILY)
#else
#error The VideoEncodeAcceleratorUnittest is not supported on this platform.
......@@ -1431,6 +1432,10 @@ int main(int argc, char** argv) {
LOG(FATAL) << "Unexpected switch: " << it->first << ":" << it->second;
}
#if defined(OS_CHROMEOS) && defined(ARCH_CPU_X86_FAMILY)
content::VaapiWrapper::PreSandboxInitialization();
#endif
content::g_env =
reinterpret_cast<content::VideoEncodeAcceleratorTestEnvironment*>(
testing::AddGlobalTestEnvironment(
......
......@@ -321,7 +321,6 @@ void GpuProcessPolicy::InitGpuBrokerProcess(
const std::vector<BrokerFilePermission>& permissions_extra) {
static const char kDriRcPath[] = "/etc/drirc";
static const char kDriCard0Path[] = "/dev/dri/card0";
static const char kDriRenderNode0Path[] = "/dev/dri/renderD128";
static const char kDevShm[] = "/dev/shm/";
CHECK(broker_process_ == NULL);
......@@ -329,7 +328,6 @@ void GpuProcessPolicy::InitGpuBrokerProcess(
// All GPU process policies need these files brokered out.
std::vector<BrokerFilePermission> permissions;
permissions.push_back(BrokerFilePermission::ReadWrite(kDriCard0Path));
permissions.push_back(BrokerFilePermission::ReadWrite(kDriRenderNode0Path));
permissions.push_back(BrokerFilePermission::ReadOnly(kDriRcPath));
if (!IsChromeOS()) {
permissions.push_back(
......
......@@ -62,6 +62,10 @@
#include "content/common/sandbox_mac.h"
#endif
#if defined(OS_CHROMEOS) && defined(ARCH_CPU_X86_FAMILY)
#include "content/common/gpu/media/vaapi_wrapper.h"
#endif
#if defined(SANITIZER_COVERAGE)
#include <sanitizer/common_interface_defs.h>
#include <sanitizer/coverage_interface.h>
......@@ -218,6 +222,10 @@ int GpuMain(const MainFunctionParams& parameters) {
// commandline switches.
GetGpuInfoFromCommandLine(gpu_info, command_line);
#if defined(OS_CHROMEOS) && defined(ARCH_CPU_X86_FAMILY)
VaapiWrapper::PreSandboxInitialization();
#endif
// Warm up resources that don't need access to GPUInfo.
if (WarmUpSandbox(command_line)) {
#if defined(OS_LINUX)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment